problema con braccio robotico

salve a tutti, sono nuovo nel forum, sono uno studente e con arduino me la cavo abbastanza.

ho un braccio robotico comandato da arduino uno, e con 6 potenziometri riesco a comandarlo perfettamente, poi ho pensato che anzichè usare i potenziometri sarebbe stato interessante usare due jaypad per comandare 4 di questi servi, sono riuscito anche in questo però il problema è che i joypad tornano sempre nella loro posizione centrale e quindi anche i servi ritornano nella loro posizione iniziale. mi chiedevo se è possibile che io sposto la leva in una posizione, premo un pulsante e arduino memorizzi la posizione in modo che anche lasciando la leva il braccio rimanga in quella posizione, per poi premerlo ancora e far tornare il braccio alla sua posizione normale.

grazie

peppe

Buonasera, essendo il tuo primo post, nel rispetto del regolamento (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD ([u]spiegando bene quali conoscenze hai di elettronica e di programmazione[/u] ... possibilmente [u]evitando[/u] di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Qui una serie di link utili, [u]NON[/u] necessariamente inerenti alla tua domanda: - serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections - pinout delle varie schede by xxxPighi: Pinout - link [u]generali[/u] utili: Link Utili

ciao :slight_smile:

certo si può fare :slight_smile:

hai già una parte di codice già scritta da postare, così possiamo darti una mano in base a quello che hai già fatto tu?

PS per postare il programma utilizza il tasto CODE </> :slight_smile:

MD

certo, questo è il programma del braccio, io avevo provato con la libreria eeprom.h ma non sono riuscito

#include <Braccio.h>
#include <Servo.h>


Servo base; //elenco servomotori
Servo shoulder;
Servo elbow;
Servo wrist_rot;
Servo wrist_ver;
Servo gripper;

int const potPin1= A0; // pin ingresso analogico
int vertPin1 = A3; // pin ingresso analogico
int horzPin1 = A4; // pin ingresso analogico
int const potPin6 = A5; // pin ingresso analogico
int horzPin = A1; // pin ingresso analogico per joypad orizzontale
int vertPin = A2; // pin ingresso analogico per joypad verticale
int potVal1; // variabile del valore dell'ingresso analogico 
int horzVal; // variabile del valore dell'ingresso analogico del joypad orizzontale
int vertVal; // variabile del valore dell'ingresso analogico del joypad verticale
int horzVal1; // variabile del valore dell'ingresso analogico
int vertVal1; // variabile del valore dell'ingresso analogico
int potVal6; // variabile del valore dell'ingresso analogico
int m1; // angolo motore m1
int m2; // angolo motore m2
int m3;  // angolo motore m3
int m4;  // angolo motore m4
int m5;  // angolo motore m5
int m6;  // angolo motore m6
void setup() {  
  //Inizializzazione delle funzioni e impostare le posizioni iniziali del Braccio
  //Tutti i servomotori devono essere nella posizione di "sicurezza":
  //Base (M1):90 gradi
  //Spalla (M2): 45 gradi
  //Gomito (M3): 180 gradi
  //Polso verticale (M4): 180 gradi
  //Polso rotatorio (M5): 90 gradi
  //Pinze (M6): 10 gradi
  Braccio.begin();

Serial.begin(9600); //inizializzazione velocità di trasmissione della porta seriale
}

void loop() {

potVal1 = analogRead(potPin1); // lettura ingresso analogico A0

m1 = map(potVal1, 0, 1023, 0, 179); // lettura valori analogici in gradi dei servomotori
Serial.print("m1: "); // lettura e rappresentazione valore di m1
Serial.print(m1);

horzVal = analogRead(horzPin); // lettura ingresso analogico joypad orizzontale A1

m2 = map(horzVal, 0, 1023, 0, 179); // lettura valori analogici in gradi dei servomotori
Serial.print(", m2: "); // lettura e rappresentazione valore di m2
Serial.print(m2);

vertVal = analogRead(vertPin); // lettura ingresso analogico joypad verticale A2

m3 = map(vertVal, 0, 1023, 0, 179); // lettura valori analogici in gradi dei servomotori
Serial.print(", m3: "); // lettura e rappresentazione valore di m3
Serial.print(m3);

vertVal1 = analogRead(vertPin1); // lettura ingresso analogico joypad verticale A3

m4 = map(vertVal1, 0, 1023, 0, 179); // lettura valori analogici in gradi dei servomotori
Serial.print(", m4: "); // lettura e rappresentazione valore di m4
Serial.print(m4);

horzVal1 = analogRead(horzPin1); // lettura ingresso analogico joypad orizzontale A4

m5 = map(horzVal1, 0, 1023, 0, 179); // lettura valori analogici in gradi dei servomotori
Serial.print(", m5: "); // lettura e rappresentazione valore di m5
Serial.print(m5);

potVal6 = analogRead(potPin6); // lettura ingresso analogico A5

m6 = map(potVal6, 0, 1023, 10, 72); // lettura valori analogici in gradi dei servomotori
Serial.print(", m6: "); // lettura e rappresentazione valore di m6
Serial.println(m6);
  
  /*.
Passo di ritardo: secondi dopo l'azionamento di un servomotore, tra 10 e 30 millisecondi
   M1=gradi base. Valori da 0 a 180
   M2=gradi spalla. Valori da 0 a 165
   M3=gradi gomito.valori da 0 a 180
   M4=gradi polso verticale. Valori da 0 a 180
   M5=gradi polso rotatorio. Valori da 0 a 180
   M6=gradi pinze. Valori da 10 a 73. 10: pinze aperte, 73: pinze chiuse.
  */
  
  // il braccio è allineato verso l'alto e le pinze sono chiuse
                     //(ritardo valori, M1, M2, M3, M4, M5, M6);
  Braccio.ServoMovement(10,         m1, m2, m3, m4, m5,  m6); // lettura valori per l'azionamento dei servomotori 
  
}

Premetto che quello che ti suggerisco non ho potuto provarlo. Sta a te vedere se funziona.

Devi definire una variabile boolean (ad es. flag) che può assumere i valori true o false.

Nel setup inizializzi la variabile a true.

Supponendo che tu abbia definito un 'button' collegato a un pin in INPUT_PULLUP, nel loop aggiungi un

if (digitalRead(button) == LOW) {
 flag = !flag;
 delay(1000);
}

Il ritardo serve per prendere in considerazione una sola pressione del pulsante alla volta.

Poi modifica l'istruzione

 Braccio.ServoMovement(10,         m1, m2, m3, m4, m5,  m6); // lettura valori per l'azionamento dei servomotori

Cosi

 if (flag) {
   Braccio.ServoMovement(10,         m1, m2, m3, m4, m5,  m6); // lettura valori per l'azionamento dei servomotori 
 }

Dovresti ottenere che l'istruzione che fa muovere il braccio viene eseguita solo se flag è true, mentre se è false l'istruzione non viene eseguita e il braccio resta fermo nella posizione che ha raggiunto quando hai premuto il pulsante.

Ciao, P.

Il delay(1000) ti blocca tutto quanto per un secondo ogni volta che lo esegui ... il che significa che probabilmente per il 99% del tempo lo sketch sara' bloccato ... per i rimbalzi si usa il debounce hardware ... quello software potra' anche essere un bell'esercizio didattico (specie se si riesce a farlo con millis), ma nella pratica, e soprattutto quando ci sono piu ingressi, diventa una cosa assurda ...

Poi, quello che dovresti fare, e' leggere se i joystick si spostano, ed usare questo dato per incrementare e decrementare dei contatori, che daranno la posizione ai motori ... e non dire al motore di raggiungere la posizione letta ... perche' in quel modo, e' ovvio che quando il joystick ritorna al centro, ci ritorna anche il motore ...

Esempio, fai un map della lettura 0 1023 0 6 ... cosi, finche' il valore e' 3, sai che il joystick e' al centro e non fai nulla ... quando diventa minore di 3, decrementi il contatore della posizione di quell'asse, quando e' maggiore lo incrementi ... ho usato 6 per avere 7 archi di cerchio, in cui il centrale ha una certa estensione, in modo da avere un minimo di isteresi sulla corsa ... se serve piu spazio si riduce, se serve meno si incrementa ...