conservare la posizione del servo

salve, comando un servo inviando la posizione in numero tramite il serial monitor di arduino uno e il servo raggiunge la posizione, solo che dopo averla raggiunta ritorna automaticamente in quella iniziale come posso fargli mantenere l’ultima posizione comunicata finchè non ne comunico una nuova?
questo e il codice che ho utilizzato:
#include <Servo.h>

Servo servoMotor2;

int grad1 ;
int gradMin=0;
int gradMax=180;

int servoPin2 = 2;

void setup() {
servoMotor2.attach(servoPin2);
Serial.begin(9600);

}

void loop()
{

grad1 = Serial.read();
Serial.println("Gradi: " + grad1);

if (grad1 < gradMin) { grad1 = gradMin; }
if (grad1 > gradMax) { grad1 = gradMax; }
servoMotor2.write( grad1 );
delay(250);
}

Penso che l'errore stia nel fatto che una volta che lui legge il tuo input da tastiera , ad esempio 90, effettua l'operazione:

Servo.write(90);

Ma al loop successivo quando effettua l'istruzione

grad1 = Serial.read();

prova a cambiare il tutto con:

if (Serial.available()>0)grad1 = Serial.read();

In questo modo cambia la variabile grad1 solo se c'e' un'altro valore disponibile in Seriale!!!

ciao,

fab.

p.s. Dai un'occhiata qui per maggiori info su Serial.Available() http://www.arduino.cc/en/Serial/Available

p.p.s. EDIT: Quando inserisci un codice in un messaggio cerca di racchiuderlo nei Tag [] code , cosi' e' piu' leggibile.

Ciao.!!!

niente ritorna a 0 gradi , dovrei continuare ad comunicare al servo la posizione altrimenti questo si resetta

il consiglio che ti ha dato f.schiano è giusto. Tu sul monitor seriale cosa gli mandi?

Potresti provare con l'inserimento subito dopo il servo.write() dell'istruzione:

grad1=servo.read()

E dovrebbe salvarti il valore in cui e' arrivato!

Poi, in accoppiata con l'if serial.available()>0 non dovrebbe cambiarti la posizione del servo finquando non gli dai un altro comando dalla seriale.

P.s. Il servo che stai comandando non e' a rotazione continua vero?

Ciao!!!

Due cose che mi vengono in mente, che potresti provare (ma non so se risolvono questo "problema")

  • Nel setup() mettici una inizializzazione della posizione del servo : servo2.write(0);
  • prova a cambiare il pin a cui hai attaccato il servo, ad esempio mettilo al pin 8-9 (mi pare debbano essere pwm)

Inoltre prova a non usare la Seriale come input ma definisci delle variabili e vedi se il servo si ferma. Potrebbe essere un problema di valori letti dalla seriale, infatti se non erro la funzione Serial.Read() ti restituisce un byte, mentre tu dovresti mettere all'interno del Servo.Write() un intero (di questo non ne sono sicuro pero' . dai un;occhiata in giro)

Ciao,

Fab.

la seriale è in ASCII, e Serial.read() restituisce un char. Esempio:

se scrivi "90" Arduino riceverà i cararatteri "9" e "0" e non il numero 90.

Le strade sono 2:

1) mandi un singolo carattere guardando sulla tabella ascii quanto vale in decimale (ma i primi 32 te li giochi perchè sono speciali)

2) usi una delle varie funzioni che fanno la conversione da stringa di caratteri ad intero, tipo atoi(). 2-bis) se vai in panico perchè non sai ancora usare una stringa o un array di caratteri allora adotta la semplice tecnica di togliere 48 al carattere ricevuto, esempio sempre per 90:

numero = (char1 - 48) * 10 + (char2 - 48);

sopra 99 ti servirà un'altra cifra.

f.schiano:
Potresti provare con l’inserimento subito dopo il servo.write() dell’istruzione:

grad1=servo.read()

E dovrebbe salvarti il valore in cui e’ arrivato!

Poi, in accoppiata con l’if serial.available()>0 non dovrebbe cambiarti la posizione del servo finquando non gli dai un altro comando dalla seriale.

P.s. Il servo che stai comandando non e’ a rotazione continua vero?

Ciao!!!

il servo che sto usando e un 9 kg monza ssa120m (standard servo) e non puo fare più di un giro senno il potenziometro si rompe

io non essendo un esperto di arduino non so bene se si possa fare però in via programmatica agirei così:

sotto alla dichiarazione di variabili globali aggiungerei un ulteriore variabile:

int curpos

poi nel tuo loop testerei se ci sono nuovi valori da comunicare al servo con quel

if(Serial.avvaiable() > 0) {
 grad1 = [readnewposition value]
 curpos = grad1
else {
 grad1 = curpos
}

[eventual value control and trimming]
[write grad1]

in questo modo se hai posizioni nuove le aggiorni al servo altrimenti mantieni la precedente e il servo non dovrebbe resettarsi…

spero di essere stato utile

Ciao!

[quote author=Federico Vanzati link=topic=82065.msg618182#msg618182 date=1323345199] la seriale è in ASCII, e Serial.read() restituisce un char. Esempio:

se scrivi "90" Arduino riceverà i cararatteri "9" e "0" e non il numero 90.

Le strade sono 2:

1) mandi un singolo carattere guardando sulla tabella ascii quanto vale in decimale (ma i primi 32 te li giochi perchè sono speciali)

2) usi una delle varie funzioni che fanno la conversione da stringa di caratteri ad intero, tipo atoi(). 2-bis) se vai in panico perchè non sai ancora usare una stringa o un array di caratteri allora adotta la semplice tecnica di togliere 48 al carattere ricevuto, esempio sempre per 90:

numero = (char1 - 48) * 10 + (char2 - 48);

sopra 99 ti servirà un'altra cifra. [/quote] o provato ed ai ragione con i vostri suggerimento adesso mi raggiunge una posizione dai1 ai 9° se gli invio 145 mi fa 1 poi 4 e 5 e la conserva... non gli si puo far leggere 3 numeri dalla seriale? magari inviando 001 030 180 aspetta 3 cifre e compone il numero?

o “sistemato” cosi credo, il codice il problema adesso e comunicargli numeri a piu cifre, idee?

#include <Servo.h>
 
 Servo servoMotor9;

 
 
 int valore ;
 int valoreMin=0;
 int valoreMax=180;
 
 int servoPin9 = 13;

 
 void setup() {
   servoMotor9.attach(servoPin9);
  Serial.begin(9600);
  servoMotor9.write(0);
  delay(1000);
  servoMotor9.write(180);
  delay(1000);
  servoMotor9.write(0);
  delay(1000);
  
 } 
 
 void loop()
 {
  
   if (Serial.available()>0)valore = Serial.read();
   Serial.println("Gradi: " + valore);
  
   if (valore < valoreMin) { valore = valoreMin; }
   if (valore > valoreMax) { valore = valoreMax; }
   servoMotor9.write( valore ); 
   valore = servoMotor9.read(); 
 delay(500);
 }

qualche risposta la trovi al reply #6.

giusto per toccare con mano, col codice che ti metto sotto prova a mandare prima una ‘A’ e poi una ‘a’.

#include <Servo.h>
 
 Servo servoMotor9;

 int valore ;
 
 int servoPin9 = 13;

 
 void setup() {
   servoMotor9.attach(servoPin9);
  Serial.begin(9600);
  servoMotor9.write(0);
 } 
 
 void loop()
 {
  
   if (Serial.available()>0)
     valore = Serial.read();

   Serial.println("Gradi: " + valore);

   servoMotor9.write( valore ); 
 }

PS: anche per f.schiano. i servo da modellismo non funzionano in pwm quindi puoi collegarli a qualisiasi pin.

[quote author=Federico Vanzati link=topic=82065.msg618341#msg618341 date=1323359266] PS: anche per f.schiano. i servo da modellismo non funzionano in pwm quindi puoi collegarli a qualisiasi pin. [/quote]

Ah ok Grazie... Infatti avevo detto che non ne ero sicuro :) !

Ciao.