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;}
}
}