Go Down

Topic: Problemi con un servo motore. (Read 1 time) previous topic - next topic

secondsky

Jan 12, 2011, 01:53 am Last Edit: Jan 12, 2011, 10:22 am by secondsky Reason: 1
Ciao a tutti, stasera ho iniziato a testare il mio arduino uno con firefly (http://www.fireflyexperiments.com), un programma che permette di usarlo con rhinoceros.

Così ho potuto usare degli slider tramite computer per vedere di preciso che frequenze inviavo a un servomotore (E-Flite S60) e mi sono reso conto che da 0 a 16 non si muoveva, tanto che una volta arrivato a finecorsa, a 179, non aveva compiuto i 180 gradi di rotazione ma era rimasto sensibilmente indietro.

Per il resto, superata quella soglia, rispondeva bene ai comandi.

Da cosa può dipendere la cosa?

Grazie

uwefed

scusami, stai parlando di motori passo passo come nel titolo o di servo come nel testo?
Ciao Uwe

secondsky

Di un servo... mi sono sbagliato nel titolo... che scemo...

uwefed

Tu stai usando la libreria servo?
Ciao Uwe

secondsky

Si certo, il codice l'avevo solo copiato e incollato, non era uno script mio ma quello rilasciato con firefly.
E comunque la rotazione inferiore ai 180° succede anche quando lo uso normalmente col codice di esempio di arduino e il potenziometro... davvero non capisco...

secondsky

Per essere sicuro ho modificato lo script KNOB in modo che stampasse anche i risultati di input e output.
Effettivamente pur ricevendo dal potenziometro l'input anche in prossimità del finecorsa e scalandolo per il servo correttamente (almeno questo viene stampato), questo non si muove fino a poco prima dei 20 gradi.
Dunque ho provato a scalare anche da 0 a 20 invece che da 0 a 179, per essere sicuro che il potenziometro sfruttasse tutta la corsa per "zoommare" su quei valori molto bassi ma il discorso non cambia, non si muove.
Dunque può essere o che il mio arduino non riesca a trasmettere quelle frequenze così basse anche se creda di farlo, siccome stampa i valori, o che il servo abbia una soglia sotto la quale è insensibile, del resto è costato 10 euro.

Potrei provare a verificare l'output di arduino connettendo un output a un input analogico ad esempio?

Qualcuno ha altre idee sul perché del problema?
20 gradi non sono pochi...

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int potpin = 0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin

void setup()
{
 myservo.attach(13);  // attaches the servo on pin 9 to the servo object
 Serial.begin(9600);
}

void loop()
{
 val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
 val = map(val, 0, 1023, 0, 179);     // scale it to use it with the servo (value between 0 and 180)
 myservo.write(val);                  // sets the servo position according to the scaled value
 Serial.print("sensor = " );                      
 Serial.print(potpin);
 Serial.print("servo output = " );                      
 Serial.println(val);  
 delay(15);    
}

lesto

stai facendo gli stessi errori di questa discussione: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1294921317
compiti per casa?  ;D
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

secondsky

Grazie del link, adesso me lo leggo e cerco un po' di venirne a capo.
Ma vale anche per la prova col potenziometro?

lesto

#8
Jan 13, 2011, 08:13 pm Last Edit: Jan 13, 2011, 08:13 pm by lestofante Reason: 1
woops sorry ho fatto un pò di confusione :-)
comunque verificherei i valori in uscita dal potenziometro
se continua a non funzionare proverei ad andare di PWM (analogWrite, occhio che non è compatibile con la libreria Servo.h)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

secondsky

Quelli credo siano corretti perché il serial print li indica e map li converte, solo che fino a 18-20 non si muove il servo.
Io vorrei verificare quelli in uscita da arduino piuttosto, non so se possa farlo arduino stesso connettendo un pin in uscita ad uno in entrata e confrontando i valori.

lesto

si può fare ma non esiste un comando apposito...
per fare una cosa fatta bene bisogna giocare con gli interrupt, e non è concetto da poco.
Però una cosa grezza è:colleghi il pin di output con uno di input digitale, fai un loop bello scarno, che continua a leggere la durata del segnale digitale alto(in MICROsecondi). il problema è che i comandi Serial son talmente lenti che ti sfaserebbero le letture. quindi prima fai tipo la media di 100 letture (2ms durata max ppm*100letture=200ms tra una serial e l'altra, è ancora poco, fai 500  ;D) e poi stampi a video il risultato.
così hai l'ampiezza del segnale PPM, che dovrebbe essere compresa tra 500 (min) e 2000(max) circa (dalla mia ricevente x servi leggo valori da 800 a 1900)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

lesto

uhh stavo spulciando gli sketch, ed ecco cosa è saltato fuori:
Quote

unsigned long signalLenght[8];
boolean channel[8];
unsigned long signalStart[8];

void setup()
{
 Serial.begin(9600);
 pinMode(11, OUTPUT);
 Serial.print("DDRD");
 Serial.println(DDRD, BIN);
 Serial.print("DDRB");
 Serial.println(DDRB, BIN);
 digitalWrite(11, HIGH);
 int i;
 for (i=0; i<8;i++){
   channel = true;
   signalStart=0;
   signalLenght=0;
 }
 //DDRB = B11111111;
 //PORTB=B11111111;
}

long conta=0;
long lastConta=0;
int loopN=0;
void loop()
{
 loopN++;
 leggiRicevente();
 if (loopN>=1000){
   Serial.println(signalLenght[7]);
   Serial.println(conta);
   Serial.println(lastConta);
   Serial.println();
   loopN=0;
 }
}


void leggiRicevente(){
 byte mask;
 unsigned long t;
 byte data=0;
 data |= PINB;
 int i=0;
 t=micros();
 for (mask = 00000001; mask>0; mask <<= 1) { //iterate through bit mask
//    Serial.print(i);
//    Serial.print(" ");
   if (data & mask){ // if bitwise AND resolves to true
     if ( !channel ){
       signalStart=t;
       channel=true;
       
     }
     if (i==7)
       conta++;
   }else{ //if bitwise and resolves to false
     if (i==7 && conta!=0){
       lastConta=conta;
       conta=0;
     }
     if ( channel ){
       signalLenght=t-signalStart;
       channel=false;
       
     }
     /*    
     if ( channel==true )
       channelDuration=channelBegin-time;
       channel==false;
     */
     
   }
   i++;
 }
}


credo che funga, non so  ;)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Go Up