Servomotore smette di funzionare

Ciao, ho un problema con un progetto che sto facendo per scuola: sto costruendo un veicolo in grado di muoversi autonomamente o essere telecomandato. Esso consiste in: una macchina telecomanda privata elettronica sulla quale ho messo le mie componenti, controllata da arduino MEGA2560 con scheda motori di adafruit (afmotor shield) e xbee per comunicare. Mentre per il controllo uso arduino diecimila at168 ( non sono sicuro della versione poiché faceva parte di un kit proposto da un università ma con pochi dettagli tecnici sulla scheda) con un xbee e un joystick tipo Playstation ( solo il controller per pollice). Il problema sorge quando passo dalla modalità telecomandata a quella manuale: il servomotore, che uso per orientare un sensore di distanza a ultrasuoni, non si muove più: sento ancora la resistenza che va se provo a spostarmi manualmente ma non sembra più ubbidire quando richiamo servo.write(90). Ora sono su cellulare ma vi invio il link del forum internazionale dove ho messo il codice.
Grazie mille in anticipo, cordiali saluti, propilot

la parte di codice è la seguente:

void loop() // questa è la funzione principale, simile al task main() di NXT. Il suo funzionamento è comparabile a quello di un ciclo while(true)
{
  spia=leggiseriale();
  motor.setSpeed(data[3]);//serialcom[3]);//viene impostata la velocità di default inviata dalla stazione di terra
  if(spia==0)/*se la modalità scelta dall'utente è quella automatica si avvia la prima parte della funzione main, altrimenti la seconda*/
  {
    Serial.print("funzione avanti"); //test per eventuali bug
    distFD=ping(); //viene aggiornata la distanza avanti
    while(distFD>30)//&&(emerg==0)) //questa funzione fa andare avanti la macchina fintanto che la distanza è maggiore di 30 centimetri
                  //emerg ha problemi, di conseguenza lo elimino dalla funzione, eventualmente posso collegarlo al tasto reset.
    {
      Serial.print(distFD); //test della funzione ping
      //tempodopo=millis(); //millis misura il tempo passato dall'inizio dell'esecuzione del programma (si attiva subito dopo che viene eseguito il bootloader)
      //if(tempodopo-tempoprima>1000) //se tra un intervllo di tempo e quello precedente è passato un secondo viene fatto il controllo della direzione di casa
      //{
        //cercacasa(); //si esegue la scansione a infrarossi
        //tempoprima=tempodopo; //il vecchio intervallo di tempo viene sostituito dal tempo attuale
      //}
      distFD=ping(); //viene aggiornata la distanza avanti
      Serial.print(srange.read());//test seriale per bug
      spia=leggiseriale();//controllo della modalità inviata dal telecomando
      if(spia==1){break;}//se il telecomando segnala l'ordine comando via radio si esce dalla fuunzione
      Serial.print("AVANTI A TUTTA \n");
      motor.run(FORWARD);
      delay(10);
    }
    Serial.print("fuori"); //test di uscita dalla funzione attuale
    motor.run(RELEASE); //frenata dei motori
    direzione();//viene scelta la direzione di marcia
  }
  if(spia==1)//!!!IL PROBLEMA SORGE ENTRANDO IN QUESTA PARTE DI CODICE!!!la macchina riceve l'ordine di passare alla modalità telecomandata
  {
    while(spia==1)//viene mantenuta questa modalità fintanto che spia ha come valore 1
    {
      percentualech1=data[1];
      percentualech2=data[2];
      //percentualech1=map(percentualech1,0,255,0,100);
      //percentualech2=map(percentualech2,0,255,0,100);
      if((percentualech2>138)&&(percentualech2<256))
      {
        motor.run(BACKWARD);
        percentualech2=map(percentualech2,128,255,0,255);
        motor.setSpeed(percentualech2);
      }
      else if((percentualech2<118)&&(percentualech2>-1))
      {
        motor.run(FORWARD);
        percentualech2=map(percentualech2,128,0,0,255);
        motor.setSpeed(percentualech2);
      }
      else
      {
        motor.run(RELEASE);
      }
      if((percentualech1>-1)&&(percentualech1<256))
      {
        percentualech1=map(percentualech1,0,255,410,570);
        resetdirezione(percentualech1);
      }
      /*if(percentualech1>138)
      {
        percentualech1=map(percentualech1,128,255,490,570);
        resetdirezione(percentualech1);
      }
      else if(percentualech1<118)
      {
        percentualech1=map(percentualech1,0,128,490,570);
        resetdirezione(percentualech1);
      }
      else
      {
        resetdirezione(490);
      }*/
      spia=leggiseriale();
    }
    //motorrot.setSpeed(200);
    motor.setSpeed(serialcom[3]);
  }
  Serial.print(srange.read());
  delay(1000);
  srange.detach();
  srange.attach(9);
}

Non é buona educazione postare un problema 2 volte in un forum.
Quello che manca sono gli sketch e un schema elettrico o almeno dove sono collegati i vari componenti. Alcune foto aiutano.
Ciao Uwe

Lo so ma era su quello internazionale e mi hanno consigliato di andare a postarlo su quello italiano (via messaggio privato). Tecnicamente è come postare su due forum diversi. Comunque farò in modo di mettere anche gli schemi elettrici eccetera

Uwe è il Moderatore della sezione Italiana (ma anche di quella Tedesca) del Forum, che devi considerare unico; in effetti dovresti eliminare il Topic aperto sulla sezione internazionale. Inoltre dovresti prenderti la briga di riscrivere tutto in Italiano, quindi riedita il post in cui hai messo il link e scrivici i dettagli del tuo problema, poi allega schema e sketch e vedrai che qualcosa esce fuori. :wink:

Perfetto, non ne avevo idea, e in effetti è la prima volta che sono su un forum. Farò in modo di rimediare: appena ho sottomano il computer cancello il post e vi fornisco tutti gli elementi :slight_smile: grazie mille per l aiuto

ok, a dopo :slight_smile:

propilot01:
Lo so ma era su quello internazionale e mi hanno consigliato di andare a postarlo su quello italiano (via messaggio privato). ...

Forse anche perché tutti i commenti nel sketch li hai fatti in italino.
Ciao Uwe

Ciao, finalmente posso caricare tutti i dati. Ho già provveduto a cancellare l'altro post e ora metto qui dati e foto. I dettagli generali sono già presenti sopra. In merito ai commenti ho una precisazione da fare: ogni tanto angolature e commenti non coincidono perchè a causa di come è fatto e montato il servo i gradi che metto come input in arduino sono sfasati di 5° nella realtà ( e i commenti si riferiscono a questa). Spero i dati siano sufficienti, se caso carico ogni altro elemento necessario. Il problema sorge quando si passa dalla modalità automatica (2° parte del codice in void loop) alla modalità manuale. Quindi il servomotore funziona solo se uso fin da subito la modalità automatica.

ctrl_xbee_usbcom_send_finale.ino (1023 Bytes)

ctrl_robot_HC_SR04_test_serialmov_v1_7_4_2_sus.ino (12.2 KB)

Allora, due consigli: senza creare nuovi post, vai in modifica di quello precedente (pulsante modify in alto...) elimina le foto e ricaricale con una risoluzione massima di 800x600, altrimenti ci vuole un mese per caricarle. lo sketch a cui fai riferimento (errore tra manuale e automatico), mettilo in forma testuale nel post tra i tag code e /code, altrimenti non è apribile da pate di chi non ha le lib che hai usato. Devi rendere la vita facile al Forum :wink:

Argh! io mi sto perdendo, scusatemi tantissimo ma tra cose di scuola e questo problema sto impazzendo. Mi sono letto le regole che avete appena postato. ora so cosa fare per il prossimo post! in merito al mio problema avrei un ipotesi: se io blocco void loop() un po a lungo (faccio eseguire a lungo un ciclo while all'interno di loop) potrei creare dei problemi? potrebbe essere che mi si bloccano alcune parti perchè eseguo una sola volta void loop? Appena ci entro il codice fa partire un ciclo while, di conseguenza blocco l'esecuzione di loop() che si riattiva solo quando passo dalla manuale (seconda parte del codice) alla modalità automatica (finisce la manuale, finisco il codice in void loop e quello riparte dall'inizio, momento in cui sorge il problema). Per le immagini, come ieri, aspetto di essere a casa e poi le ricarico.
Comunque ho provato a cercare una possibile soluzione ovunque: forum, google, altri forum,...
Grazie mille di tutto, e scusatemi per aver creato tutti questi problemi!!!

la void loop si esegue automaticamente all'infinito, semmai io proverei ad invertire la situazione facendo partire prima una modalità e poi l'altra e viceversa (magari invertendo temporaneamente i codici del while

Ciao!
Ho provato ancora un po di cose: invertire il codice, togliere i while e tenere gli if (spia==0,1) ma il problema persiste, tornando sempre nello stesso momento. A questo punto è più che confermato che si tratta della parte di codice "automatica" che causa l'errore. Che voi sappiate la funzione map può causare problemi di questo genere? perchè sembra essere l'unica funzione che compare solo in questa parte di codice e non nelle altre.

Ora sono in vacanza 2 settimane e provo un po a vedere che succede.

Buona serata Pro

Ciao,
innanzitutto buon natale e buone feste a tutti. Mi è venuta un idea ma volevo consultarono prima con voi. :slight_smile: è accertato che l errore compare solo dopo la seconda esecuzione del codice, quindi, anche a costo di essere un po' grezzo e brutale, potrei usare il watchdog per reset tare la scheda riavviando la macchina così che non entra in errore?

Buone feste,

Pro

il WD è uno strumento potente ma anche pericoloso; visto che hai identificato nel software il problema non capisco perché tu non debba cercare di risolvere il problema software; ci vuole un po' di pazienza, ma secondo me devi semplificare al massimo le funzioni al passaggio e poi implementarle nuovamente in modo sequenziale così capisci dove sta il problema.

Tu usi una funzione leggiseriale() per leggere il valore da assegnare alla variabile spia.
Ma tale funzione come comunica? Sulla seriale normale? Come? Wireless?
Perché vedo anche che tu usi la seriale come debug. Non è che forse si danno noia le due trasmissioni? Hai provato a togliere tutti gli if ed i while ed a mandare il robot solo in modalità manuale?

Il fatto è che non so più dove guardare: da quello che vedo io non c'è niente che possa fare interferenza :S non so veramente più cosa fare. Comunque oggi provo di nuovo a eliminare la parte del codice che fa interferenza e aggiungere mano a mano le funzioni :slight_smile: . Avevo pensato al WD come possibile soluzione ma se mi dici così, eviterò di usarlo
Per la seriale: la serial3 comunica usando un xbee serie 1, mentre la serial usa la normale USB leggiseriale legge i dati dall' xBee (s3). Avevo pensato alla possibilità che creassero problemi ma non ho pensato a togliere quella di debug. In ogni caso entrambe le modalità funzionano ( sempre, l unico problema è che il servo è immobile) :slight_smile:

Scusa, ma dici di usare 2 seriali. Se usi un Arduino Diecimila con Atmega168, la seriale hardware è una sola, per cui l'altra dev'essere sicuramente di tipo software.
Ora, che tipo di seriale software usi? Se usi una vecchia versione, essa è bloccante in ricezione. Forse i problemi potrebbero nascere da questo.

Inoltre, l'Atmega168 ha 1024 byte di memoria. Potrebbe essere che hai esaurito la Ram libera? Hai fatto un controllo per verificare l'occupazione di memoria del tuo sketch?

Il problema è sulla scheda della macchina: una arduino MEGA2560 R3. Comunque sull'altra scheda uso una porta software fatta con softwareserial. A proposito dell errore della macchina: ho isolato il problema: sembra proprio essere causato dalla funzione map()ho cancellato tutto il codice e mantenendo ogni pezzo singolarmente l unico che sembra dare errore è quello di map nella parte di codice con spia==1

propilot01:
Il problema è sulla scheda della macchina: una arduino MEGA2560 R3.

Avevo capito l'inverso, che cioè sulla macchina ci fosse la Diecimila.

Comunque sull'altra scheda uso una porta software fatta con softwareserial. A proposito dell errore della macchina: ho isolato il problema: sembra proprio essere causato dalla funzione map()ho cancellato tutto il codice e mantenendo ogni pezzo singolarmente l unico che sembra dare errore è quello di map nella parte di codice con spia==1

Prova ad usare una variabile tampone invece che assegnare il risultato di map alla stessa variabile che passi alla funzione.
Potrebbe essere un problema di valori fuori range? Sei certo delle conversioni che effettui, che non ti portino ad avere situazioni in cui il servo non si muove perché il codice dice di non muoverlo?

Effettivamente potrebbe essere un ottima idea quella di usare un altra variabile, e per la variabile fuori range ho usato un if con la condizione che il numero preso in considerazione sia nel range corretto. Il problema maggiore rimane nel fatto che il servo si muove in base a un numero pre impostato e non in base a una variabile (uso servo.write(45) e non p.es servo.write(variabile) ). Ciò che mietete più in crisi è che la funzione che crea problemi non tocca minimamente il servo, e oltretutto se provo a muoversi manualmente non si sposta, indicando il fatto che è attivo :slight_smile: