Go Down

Topic: Problema Arduino uno R3 e sensori di flessione (Read 14453 times) previous topic - next topic

-DATA-

buonasera a tutti
Mi chiamo Marco(-DATA-) ho 16 anni e sono alle prime armi con questo tipo di scheda, ho acquistato una arduino uno R3 per il progetto di un mano animatronica pilotata da un guanto sul quale sono applicati dei sensori di flessione ho creato un circuito su una millefori, un circuito molto seplice, posto , la foto,
il mio problema è che collegado il tutto allarduino e alimetando l'arduino stessa con un alimentatore a tensione variabile dai 3V ai 12V e collegando l'arduino al pc, la mano non risponde correttamente ai comandi: i servo montati sono gli HXT900 , ora non capisco perchè questi servo abbiano come degli spasmi omeglio come se la tensione mancasse e poi tornasse con un continuo movimento anche se minimo di questi servo e quindi delle dita che sono collegate. Non credo che l'errore sia dovuto ad hardware e quindi posto qui in mio script così che qualcuno possa autarmi a trovare magari una stringa che generi questo effetto molto fastidioso sui servo, noto anche che l'arduino mi si sconnette automaticamnete dal pc una volta che chiuduo tutte le dita o che compio dei movimenti continui, in piu vorrei anche mi fosse chiarita un po' la funzione map, come bisogna regolarla?? grazie mille a tutti
-IL MIO CODICE-
Code: [Select]
#include <Servo.h>

// Dichiarazione servo
Servo servo1; 
Servo servo2; 
Servo servo3;
Servo servo4;
Servo servo5;
int flex1 = 5;  // ingresso analogico per sensori di flessione
int flex2 = 4;
int flex3 = 3;
int flex4 = 2;
int flex5 = 1;
int val;         // lettura valori sensori
void setup()
{
  Serial.begin(9600);  //connessione pc e arduino
  servo1.attach(6);  //  pollice
  servo2.attach(5);  // indice
  servo3.attach(3);  //medio
  servo4.attach(4);  //anulare
  servo5.attach(2); //mignolo
}

void loop()
{
  val = analogRead(flex1);              // valore sensore letto e appreso                  POLLICE
  Serial.println(val);                           // elaorazione valore sensore
  val = map(val, 50, 600, -150, 600);     // scala parametri sensori servo
  servo1.write(val);                        // lettura parametri
  delay(15);                           
  val = analogRead(flex2);             
  Serial.println(val);                     
  val = map(val, 50, 200, -300, 200);                                                      //INDICE   
  servo2.write(val);                       
  delay(15);       
  val = analogRead(flex3);               
  Serial.println(val);                 
  val = map(val, 50, 600, -100, 600); //.................................................  MEDIO
  servo3.write(val);                   
  delay(15); 
  val = analogRead(flex4);             
  Serial.println(val);                 
  val = map(val, 50, 500, -250, 600);                                                      //ANULARE
  servo4.write(val);                   
  delay(15); 
  val = analogRead(flex5); 
  Serial.println(val);                 
  val = map(val, 30, 300, -150, 200); //.................................................  MIGNOLO
  servo5.write(val);                   
  delay(15); 
}

leo72

Hai provato intanto a separare l'alimentazione dell'Arduino da quella dei motori?
Hai lo schema elettrico (potrebbe aiutare a capire il problema)?

-DATA-


Hai provato intanto a separare l'alimentazione dell'Arduino da quella dei motori?
Hai lo schema elettrico (potrebbe aiutare a capire il problema)?


si, ho provato ma credo che alimentando i servo da usb tramite arduino non generi energi sufficente per farli muovere in aniera corretta... posto l'immagine della millefori http://imageshack.us/photo/my-images/15/gkeq.jpg/ ;
http://imageshack.us/photo/my-images/69/3sjb.jpg/

PaoloP

map non limita il valore della variabile, devi usare costrain. (http://arduino.cc/en/Reference/Constrain)

Esempio
Code: [Select]
val = costrain(analogRead(flex1), 50 ,600);              // valore sensore letto e appreso                  POLLICE
Serial.println(val);                           // elaorazione valore sensore limitato tra 50 e 600
val = map(val, 50, 600, -150, 600);     // scala parametri sensori servo
servo1.write(val);                        // lettura parametri
delay(15);

-DATA-


map non limita il valore della variabile, devi usare costrain. (http://arduino.cc/en/Reference/Constrain)

Esempio
Code: [Select]
val = costrain(analogRead(flex1), 50 ,600);              // valore sensore letto e appreso                  POLLICE
Serial.println(val);                           // elaorazione valore sensore limitato tra 50 e 600
val = map(val, 50, 600, -150, 600);     // scala parametri sensori servo
servo1.write(val);                        // lettura parametri
delay(15);



non capisco come utilizzare costrain inserendo la stringa che mi hai modificato mi da altri errori che cercando di risolvere generano altri errori, non mi ci ritorvo prorpio e il problema persite ...

PaoloP

#5
Sep 03, 2013, 11:00 am Last Edit: Sep 03, 2013, 11:09 am by PaoloP Reason: 1
Prova cosi
Code: [Select]
val = analogRead(flex1);              // valore sensore letto e appreso                  POLLICE
Serial.println(val);                           // elaborazione valore sensore
val = costrain(val, 50, 600);              // limita la variabile tra 50 e 600
val = map(val, 50, 600,  0, 180);     // scala parametri sensori servo
servo1.write(val);                        // lettura parametri
delay(15);    


si capisce meglio.

P.S.
Servo.write accetta valori tra 0 e 180, quindi le tue map sono errate.

P.S.2
Hai calcolato i valori minimo e massimo dei sensori di flessione per ogni dito?
Sono quelli presenti nella funzione map?

-DATA-


Prova cosi
Code: [Select]
val = analogRead(flex1);              // valore sensore letto e appreso                  POLLICE
Serial.println(val);                           // elaborazione valore sensore
val = costrain(val, 50, 600);              // limita la variabile tra 50 e 600
val = map(val, 50, 600,  0, 180);     // scala parametri sensori servo
servo1.write(val);                        // lettura parametri
delay(15);    


si capisce meglio.

P.S.
Servo.write accetta valori tra 0 e 180, quindi le tue map sono errate.


non risolvo neanche così   =(  le map saranno errate ma sembrerebbero funzionare in effetti non sono a cososcenzaa dell'ulitlizzo di map e quindi i valori scritti sono frutto di test e test, una calibrazione meccanica e di codice che è riuscita a fare il lavoro che vi posto nel video https://mega.co.nz/#!xJtTWDjT!Sdg7-U1FCyn6_X0Nuq6nNXXOP7VOoUvY9qdziN90170 ma come si puo notare i servo non rispondono correttamente e il dispositivo si disconnette automaticamente dal pc una volta che tengo il "pugno chiuso"

PaoloP

#7
Sep 03, 2013, 12:37 pm Last Edit: Sep 03, 2013, 12:43 pm by PaoloP Reason: 1
La funzione map serve per convertire una scala di valori in altra basandosi sui valori minimi e massimi.
La funzione è lineare ed è questa:
Code: [Select]
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}


Essendo un tipo long e non unsigned long può restituire valori negativi e non ha il controllo sul limiti.

Adesso non ho tempo per visionare il filmato... lo guardo più tardi.  ;)

-DATA-

e come potrei modificare il mio codice?? una cosa infatti che non capisco è perchè esendo tutti i motori uguali e allo stesso range se mettto map uguali rispondono in maniera differente...

PaoloP

#9
Sep 03, 2013, 05:08 pm Last Edit: Sep 03, 2013, 05:11 pm by PaoloP Reason: 1
Puoi provare questo?

Code: [Select]
#include <Servo.h>

// Dichiarazione servo
Servo servo1;  
Servo servo2;  
Servo servo3;
Servo servo4;
Servo servo5;

const byte flex1 = A5;  // ingresso analogico per sensori di flessione
const byte flex2 = A4;
const byte flex3 = A3;
const byte flex4 = A2;
const byte flex5 = A1;
int val;         // lettura valori sensori
int gradi;      // gradi posizione servo

unsigned int max1, max2, max3, max4, max5;
unsigned int min1, min2, min3, min4, min5;

void setup()
{
 delay(500);
 Serial.begin(9600);  //connessione pc e arduino

 servo1.attach(6);  //  pollice
 servo2.attach(5);  // indice
 servo3.attach(3);  //medio
 servo4.attach(4);  //anulare
 servo5.attach(2); //mignolo

 max1 = max2 = max3 = max4 = max5 = 0;
 min1 = min2 = min3 = min4 = min5 = 1024;
} //End Setup

void loop()
{
 val = analogRead(flex1);              // valore sensore letto e appreso                  POLLICE
 max1 = max(val, max1);
 min1 = min(val, min1);
 Serial.println(val);
 Serial.print(F("Pollice --> Min: "));
 Serial.print(min1);
 Serial.print(F("  Max: "));
 Serial.println(max1);
 gradi = map(val, 0, 1023, 0, 180);     // scala parametri sensori servo
 servo1.write(gradi);                        // lettura parametri
 delay(15);                          

 val = analogRead(flex2);              
 max2 = max(val, max2);
 min2 = min(val, min2);
 Serial.println(val);
 Serial.print(F("Indice --> Min: "));
 Serial.print(min2);
 Serial.print(F("  Max: "));
 Serial.println(max2);                      
 gradi = map(val, 0, 1023, 0, 180);                                                      //INDICE    
 servo2.write(gradi);                      
 delay(15);

 val = analogRead(flex3);              
 max3 = max(val, max3);
 min3 = min(val, min3);
 Serial.println(val);
 Serial.print(F("Medio --> Min: "));
 Serial.print(min3);
 Serial.print(F("  Max: "));
 Serial.println(max3);
 gradi = map(val, 0, 1023, 0, 180); //.................................................  MEDIO
 servo3.write(gradi);                    
 delay(15);  

 val = analogRead(flex4);              
 max4 = max(val, max4);
 min4 = min(val, min4);
 Serial.println(val);
 Serial.print(F("Anulare --> Min: "));
 Serial.print(min4);
 Serial.print(F("  Max: "));
 Serial.println(max4);
 gradi = map(val, 0, 1023, 0, 180);                                                      //ANULARE
 servo4.write(gradi);                    
 delay(15);  

 val = analogRead(flex5);  
 max5 = max(val, max5);
 min5 = min(val, min5);
 Serial.println(val);
 Serial.print(F("Mignolo --> Min: "));
 Serial.print(min5);
 Serial.print(F("  Max: "));
 Serial.println(max5);
 Serial.println(val);                
 gradi = map(val, 0, 1023, 0, 180); //.................................................  MIGNOLO
 servo5.write(gradi);                    
 delay(15);  

  Serial.println(F(" "));    
} // End Loop

-DATA-

no, non funziona neanche così  =( , i servo non rispondono con il codice che hai postato, o meglio si muovono di pochissimo ma non abbastanza da far chiudere le dita.ho ripristinato il mio codice ma il probema persiste e l'arduino si disconnette automaticamente dal pc dopo un medio utilizzo.

PaoloP

Col mio codice, apri il serial monito e leggi i valori minimo e massimo per ogni dito.
Vorrei farmi un idea dei valori restituiti dal sensore a flessione.

Dopo aver aperto e chiuso la mano un paio di volte, prendi gli ultimi valori stampati.

-DATA-

#12
Sep 03, 2013, 05:46 pm Last Edit: Sep 03, 2013, 05:48 pm by -DATA- Reason: 1

Col mio codice, apri il serial monito e leggi i valori minimo e massimo per ogni dito.
Vorrei farmi un idea dei valori restituiti dal sensore a flessione.

Dopo aver aperto e chiuso la mano un paio di volte, prendi gli ultimi valori stampati.


con il tuo codice la mano è in una posizione differente da quella iniziale e si disconnette frequentemente in monitor seriale appena lo apro mi rifersce dei valori ma senza fermarsi e quindi mi risulta impossibile postarti gli ultimi valori

PaoloP

Visto che voglio conoscere solo i valori massimo e minimi dei sensori, prova questo.
Code: [Select]
#include <Servo.h>

// Dichiarazione servo
Servo servo1; 
Servo servo2; 
Servo servo3;
Servo servo4;
Servo servo5;

const byte flex1 = A5;  // ingresso analogico per sensori di flessione
const byte flex2 = A4;
const byte flex3 = A3;
const byte flex4 = A2;
const byte flex5 = A1;
int val;         // lettura valori sensori
int gradi;      // gradi posizione servo

unsigned int max1, max2, max3, max4, max5;
unsigned int min1, min2, min3, min4, min5;

void setup()
{
  delay(500);
  Serial.begin(9600);  //connessione pc e arduino

  servo1.attach(6);  //  pollice
  servo2.attach(5);  // indice
  servo3.attach(3);  //medio
  servo4.attach(4);  //anulare
  servo5.attach(2); //mignolo

  max1 = max2 = max3 = max4 = max5 = 0;
  min1 = min2 = min3 = min4 = min5 = 1024;
} //End Setup

void loop()
{
  val = analogRead(flex1);              // valore sensore letto e appreso                  POLLICE
  max1 = max(val, max1);
  min1 = min(val, min1);
  Serial.println(val);
  Serial.print(F("Pollice --> Min: "));
  Serial.print(min1);
  Serial.print(F("  Max: "));
  Serial.println(max1);
  gradi = map(val, 0, 1023, 0, 180);     // scala parametri sensori servo
  //servo1.write(gradi);                        // lettura parametri
  delay(15);                           

  val = analogRead(flex2);             
  max2 = max(val, max2);
  min2 = min(val, min2);
  Serial.println(val);
  Serial.print(F("Indice --> Min: "));
  Serial.print(min2);
  Serial.print(F("  Max: "));
  Serial.println(max2);                     
  gradi = map(val, 0, 1023, 0, 180);                                                      //INDICE   
  //servo2.write(gradi);                       
  delay(15);

  val = analogRead(flex3);               
  max3 = max(val, max3);
  min3 = min(val, min3);
  Serial.println(val);
  Serial.print(F("Medio --> Min: "));
  Serial.print(min3);
  Serial.print(F("  Max: "));
  Serial.println(max3);
  gradi = map(val, 0, 1023, 0, 180); //.................................................  MEDIO
  //servo3.write(gradi);                   
  delay(15); 

  val = analogRead(flex4);             
  max4 = max(val, max4);
  min4 = min(val, min4);
  Serial.println(val);
  Serial.print(F("Anulare --> Min: "));
  Serial.print(min4);
  Serial.print(F("  Max: "));
  Serial.println(max4);
  gradi = map(val, 0, 1023, 0, 180);                                                      //ANULARE
  //servo4.write(gradi);                   
  delay(15); 

  val = analogRead(flex5); 
  max5 = max(val, max5);
  min5 = min(val, min5);
  Serial.println(val);
  Serial.print(F("Mignolo --> Min: "));
  Serial.print(min5);
  Serial.print(F("  Max: "));
  Serial.println(max5);
  Serial.println(val);                 
  gradi = map(val, 0, 1023, 0, 180); //.................................................  MIGNOLO
  //servo5.write(gradi);                   
  delay(15); 

  Serial.println(F(" ------------------------------- "));     
} // End Loop


Ho commentato le funzioni del servo quindi la mano non si muove.
Puoi postare un gruppo di valori massimi e minimi?

-DATA-

#14
Sep 03, 2013, 05:57 pm Last Edit: Sep 04, 2013, 09:44 am by leo72 Reason: 1

Visto che voglio conoscere solo i valori massimo e minimi dei sensori, prova questo.
Ho commentato le funzioni del servo quindi la mano non si muove.
Puoi postare un gruppo di valori massimi e minimi?


Code: [Select]
248
Pollice --> Min: 248  Max: 249
327
Indice --> Min: 327  Max: 327
152
Medio --> Min: 145  Max: 152
158
Anulare --> Min: 153  Max: 158
282
Mignolo --> Min: 271  Max: 282
282
-------------------------------
251
Pollice --> Min: 248  Max: 251
329
Indice --> Min: 327  Max: 329
252
Medio --> Min: 145  Max: 252
324
Anulare --> Min: 153  Max: 324
311
Mignolo --> Min: 271  Max: 311
311
-------------------------------
249
Pollice --> Min: 248  Max: 251
330
Indice --> Min: 327  Max: 330
254
Medio --> Min: 145  Max: 254
324
Anulare --> Min: 153  Max: 324
311
Mignolo --> Min: 271  Max: 311
311
-------------------------------
250
Pollice --> Min: 248  Max: 251
330
Indice --> Min: 327  Max: 330
139
Medio --> Min: 139  Max: 254
260
Anulare --> Min: 153  Max: 324
311
Mignolo --> Min: 271  Max: 311
311
-------------------------------
246
Pollice --> Min: 246  Max: 251
308
Indice --> Min: 308  Max: 330
105
Medio --> Min: 105  Max: 254
223
Anulare --> Min: 153  Max: 324
310
Mignolo --> Min: 271  Max: 311
310
-------------------------------
244
Pollice --> Min: 244  Max: 251
302
Indice --> Min: 302  Max: 330
109
Medio --> Min: 105  Max: 254
241
Anulare --> Min: 153  Max: 324
311
Mignolo --> Min: 271  Max: 311
311
-------------------------------
250
Pollice --> Min: 244  Max: 251
329
Indice --> Min: 302  Max: 330
255
Medio --> Min: 105  Max: 255
326
Anulare --> Min: 153  Max: 326
311
Mignolo --> Min: 271  Max: 311
311
-------------------------------
250
Pollice --> Min: 244  Max: 251
330
Indice --> Min: 302  Max: 330
254
Medio --> Min: 105  Max: 255
326
Anulare --> Min: 153  Max: 326
312
Mignolo --> Min: 271  Max: 312
312
-------------------------------
252
Pollice --> Min: 244  Max: 252
233
Indice --> Min: 233  Max: 330
166
Medio --> Min: 105  Max: 255
298
Anulare --> Min: 153  Max: 326
309
Mignolo --> Min: 271  Max: 312
309



questi sono alcuni gruppi che sono riuscito a prendere, ho saltato la prima chiusura totale della mano.
Vorrei ricordare che sto lavorando con un alimentatore esterno attaccato all'ingresso della arduino e cavo usb
ho notato comunque che il monitor seriale mi produce valori anche se non tocco i sensori ...

Go Up