Introducció a la robòtica en trenta-una classes/Vint-i-vuitè dia: automatitzem moviments del braç robòtic

Un vídeo d’exemple:

Avui hem afegit les memòries que havíem dit al robot, per tal que pugui aprendre moviments i repetir-los, tal com fan els braços robòtics a Les fàbriques. Hem afegit dues tecles a l’aplicació del telèfon: una que memoritza la posició on ens trobem cada vegada que es prem, i una que en prémer-la fá que es vagin repetint els moviments apresos indefinidament. Primer, anem al app inventor i hi afegim una tecla amb el text memoritzar i una amb el text repetir. Anem a blocks, inserim onbuttonmemclick, i a dins callbluetoothclient.sendtext.M. per a la tecla repetir, fem enviar una R. Ho passen al telèfon. Hem abreujat, ja que en les classes anteriors hi ha el pas a pas de com assignar les funcions a les tecles. Obrim l’editor Arduino, i afegim el codi per a la memorització i repetició. Hi veiem coses noves. Per exemple, per a memoritzar fins a 50 passos de programa, hem creat una matriu de 50 posicions per a cadascun dels motors. Això es fa amb els claudàtors: memA[50], memB[50].... Realment serien 51, ja que les variables comencen indexant per zero.

El programa:

#include <Servo.h>
Servo servoA;
Servo servoB;
Servo servoC;
Servo servoD;
int memA[50]; // assignem 50 posicions per a desar fins a 50 passos de programa al servo A
int memB[50]; // 50 per al servo B
int memC[50]; // 50 per al C
int memD[50]; // 50 per al D
int posA, posB, posC, posD;
int objA, objB, objC, objD;
int pas, pasFinal;
char mode; // A serà automàtic i M manual

void setup() {
    Serial.begin(9600);
    servoA.attach(A0);
    servoB.attach(A1);
    servoC.attach(A2);
    servoD.attach(A3);
    posA=1500; posB=1500; posC=1500; posD=1500; // de 700 a 2300, centre a 1500
    objA=1500; objB=1500; objC=1500; objD=1500;
    pas=0;
    mode='M';pasFinal=0;
}

void loop() {
    if (Serial.available()){
        char ordre=Serial.read();
        if (ordre=='A'){
            objA=Serial.parseInt();
        }
        if (ordre=='B'){
            objB=Serial.parseInt();
        }
        if (ordre=='C'){
            objC=Serial.parseInt();
        }
        if (ordre=='D'){
            objD=Serial.parseInt();
        }
        if (ordre=='M'){
            memA[pas]=posA;memB[pas]=posB;memC[pas]=posC;memD[pas]=posD;
            pas=pas+1;
        }
        if (ordre=='R'){
            mode='A';
            pasFinal=pas-1;
            pas=0;
        }
        ordre='0'; // netegem per no repetir
    }
    // fi interpretació ordres inici moviments suaus
    if (objA>posA){
        posA++;
        servoA.writeMicroseconds(posA);
    }
    if (objA<posA){
        posA--;
        servoA.writeMicroseconds(posA);
    }
    if (objB>posB){
        posB++;
        servoB.writeMicroseconds(posB);
    }
    if (objB<posB){
        posB--;
        servoB.writeMicroseconds(posB);
    }
    if (objC>posC){
        posC++;
        servoC.writeMicroseconds(posC);
    }
    if (objC<posC){
        posC--;
        servoC.writeMicroseconds(posC);
    }
    if (objD>posD){
        posD++;
        servoD.writeMicroseconds(posD);
    }
    if (objD<posD){
        posD--;
        servoD.writeMicroseconds(posD);
    }
    delay(5); // retard per a suavitzar els moviments
    if((posA==objA)&&(posB==objB)&&(posC==objC)&&(posD==objD)&&(mode=='A')){
        objA=memA[pas]; objB=memB[pas]; objC=memC[pas]; objD=memD[pas];
        pas++;
        if (pas>pasFinal){pas=0;}
    }
}