Problema Arduino uno R3 e sensori di flessione

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-

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

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

leo72:
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 ImageShack - Best place for all of your image hosting and image sharing needs ;
ImageShack - Best place for all of your image hosting and image sharing needs

map non limita il valore della variabile, devi usare costrain. (constrain() - Arduino Reference)

Esempio

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

PaoloP:
map non limita il valore della variabile, devi usare costrain. (constrain() - Arduino Reference)

Esempio

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 ...

Prova cosi

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?

PaoloP:
Prova cosi

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 MEGA 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"

La funzione map serve per convertire una scala di valori in altra basandosi sui valori minimi e massimi.
La funzione è lineare ed è questa:

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. :wink:

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...

Puoi provare questo?

#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

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.

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.

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.

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

Visto che voglio conoscere solo i valori massimo e minimi dei sensori, prova questo.

#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?

PaoloP:
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?

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 ...

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

Da questi valori non che l'escursione è molto piccola.
Hai esteso e richiuso completamente la mano mentre scorrevano i numeri?

Comunque, se quei valori sono giusti, li devi usare per la funzione map.
per ogni dito avrai

gradi = map(val, minimo valore registrato, massimo valore registrato, 0, 180);
servo1.write(gradi);

ovvero

gradi = map(val, 244, 252, 0, 180);
servo1.write(gradi);

Una volta sistemati il minimo e massimo dei sensori nella funzione map, devi sistemare il minimo e il massimo dei servi.
I servi che escursione hanno in gradi (non ho potuto vedere il filmato perche non ho il codec giusto, stanotte a casa lo guardo) 90°, 120° o 180°

Dai che passo passo risolviamo. :grin:

Giusto per curiosita', a livello hardware che sensori usi ?

il range è di 180 gradi. spero di risolvere in fretta domani ho un video musicale da girare te ne sarei grato :grin:

Etemenanki:
Giusto per curiosita', a livello hardware che sensori usi ?

http://www.robot-italy.com/it/flex-sensor-2-2.html utilizzo questi
XD

I sensori li hai collegati direttamente o sono amplificati come consiglia il datasheet?

Puoi riprovare il mio sketch (quello senza i servo) per vedere il massimo e i minimi che ricavi.
Apri prima il serial monitor e muovi un paio di volte la mano estentendola al massimo e poi richiudendola.
Poi sul serial monitor blocca lo scorrimento automatico e copia gli ultimi valori.

Se l'escursione dei sevi è di 180, i parametri per map sono 0 e 180, quindi bisogna solo stabilire i limiti dei sensori.