piccolo robot (HC-SR04 e SERVO 360)

Da qualche tempo sto lavorando alla realizzazione di un robottino relativamente semplice (non per me a quanto pare…) come progetto scolastico.
Ormai ho già fatto tante prove di programmi ma essendo più o meno alle prime armi mi trovo in difficoltà nella programmazione dei movimenti che deve effettuare.
Il prototipo è composto da:
1 scheda arduino UNO
1 sensore ultrasuoni HC-SR04
1 servo motore da 180° posto sotto il sensore ultrasuoni
2 servo motori da 360° ( FS5106R )
1 breadboard

  • come libreria utilizzo “Servo”
    Il robottino in questione (di cui caricherò l’immagine qui sotto) deve:
  • all’accensione effettuare una scansione avanti a se e se non trova ostacoli troppo vicini procedere.
  • non appena incontra un ostacolo ad una distanza “pericolosa” deve fermarsi. A questo punto deve fare due scansioni con il sensore ad ultrasuoni: una a destra e l altra a sinistra.
  • ora dove il sensore rileva la distanza maggiore il robottino deve girarsi verso quella direzione e andare sempre dritto sino a ripetere il ciclo.
    Spero di essermi spiegato adeguatamente.
    Per quanto riguarda il programma, devo ancora completare la parte che fa ruotare il robottino a destra o sinistra, ma non so come fare. Inoltre non sono sicuro che tutto funzioni come dovrebbe e se qualcuno ha pazienza per vedere il tutto un attimo mi aiuterebbe davvero molto.
    Qui carico il programma che ho realizzato.
#include <Servo.h>
Servo motoresx; //motore sinistro
Servo motoredx; //motore destro
Servo motoreultra; //motore ultrasuoni
int angoloinizialeultra = 90; // angolo che deve avere il motore dell' ultrasuoni quando il robot va avanti dritto
int dxultra = 0; // angolo quando il motoreultra gira a destra
int sxultra = 180; // angolo quando il motoreultra gira a sinistra
int triggerPort=2; //porta ultrasuoni
int echoPort=3; //porta ultrasuon
//angolo di riposo dei servi delle ruote
#define RIPOSOS 93
#define RIPOSOD 93
#define value1
#define value2
#define value3
void setup() {
  Serial.begin(9600);
  //motori ruote
motoresx.attach(7); // Attacca il servo sinistro al pin 7
motoredx.attach(8); // Attacca il servo destro al pin 8
//motore ultrasuoni
motoreultra.attach(9); // Attacca il servo degli ultrasuoni al pin 9
motoreultra.write(90); // metti il servo degli ultrasuoni dritto
//Pin ultrasuoni
pinMode( triggerPort, OUTPUT ); // viene impostato il pin digitale 2 di Arduino come uscita 
pinMode( echoPort, INPUT ); // viene impostato il pin digitale 3 di Arduino come ingresso
}
void loop()
{
fermaServi();
calcolodistanza1();
if (value1 <= 25)
{
  ruotamotoreultra0 ();
  calcolodistanza2();
  delay(1500);
  ruotamotoreultra180 ();
  calcolodistanza3();
  delay(1500);
  motoreultra.write(angoloinizialeultra);
  if (value2 > value3)
  {
    ruotaServisx();
    delay(500);
    sempreDritto();
  }
  else
  {
    ruotaServidx()
    delay(500);
    sempreDritto();
  }
}
else
{
  sempreDritto();
}
}
void calcolodistanza1() //calcola la distanza con il motoreultra su 90°
{
//porta bassa l'uscita del trigger
digitalWrite( triggerPort, LOW );
 
//invia un impulso di 10microsec su trigger
digitalWrite( triggerPort, HIGH );
delayMicroseconds( 10 );
digitalWrite( triggerPort, LOW );
 
long duration1 = pulseIn( echoPort, HIGH );
 
long value1 = 0.034 * duration / 2; //calcola la distanza che c'è dall'oggetto 
}
void calcolodistanza2() //calcola la distanza con il motoreultra su 0°
{
  //porta bassa l'uscita del trigger
digitalWrite( triggerPort, LOW );
 
//invia un impulso di 10microsec su trigger
digitalWrite( triggerPort, HIGH );
delayMicroseconds( 10 );
digitalWrite( triggerPort, LOW );
 
long duration2 = pulseIn( echoPort, HIGH );
 
long value2 = 0.034 * duration / 2; //calcola la distanza che c'è dall'oggetto 
}
void calcolodistanza3() //calcola la distanza con il motoreultra su 180°
{
  //porta bassa l'uscita del trigger
digitalWrite( triggerPort, LOW );
 
//invia un impulso di 10microsec su trigger
digitalWrite( triggerPort, HIGH );
delayMicroseconds( 10 );
digitalWrite( triggerPort, LOW );
 
long duration3 = pulseIn( echoPort, HIGH );
 
long value3 = 0.034 * duration / 2; //calcola la distanza che c'è dall'oggetto 
}
void sempreDritto()
{
motoresx.write(RIPOSOS + 80); // fai andare il robot dritto
motoredx.write(RIPOSOD - 80); // fai andare il robot dritto
}
void ruotamotoreultra0 ()
{
  motoreultra.write(dxultra);
}
void ruotamotoreultra180 ()
{
  motoreultra.write(sxultra);
}

void fermaServi()
{
motoresx.write(RIPOSOS); // ferma ruota sinistra
motoredx.write(RIPOSOD); // ferma ruota destra
}
void ruotaServidx()
{


}
void ruotaServisx()
{

 
}

Grazie in anticipo.

Come ti ho già scritto in QUESTO post, ti chiedo di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il REGOLAMENTO ... Grazie.

Guglielmo

Vabene ora provvedo scusa

Fatto tutto

Lollo9906: Fatto tutto

Guglielmo

Ciao,
un pò di corsa , ma visto che tempo fa per gioco avevo fatto qualcosa di simile e mi sembrava funzionare, ti posto il programmino.
Vedi tu se puoi prendere spunto e completare il tuo.
Ciao, Arrigo

  #include "Ultrasonic.h"
  #include <Wire.h>
  #include <WProgram.h>
  #include <OneWire.h>
  #include <Servo.h>
  #define LEDa 3    // PWM dal pin digitale 3 motore 1   
  #define LEDb 5   // PWM dal pin digitale 5 motore 2

 Servo myservo;  // oggetto servo per controllare il servo
 int pos=90 ;    // variabile per memorizzare la posizione del servo

 Ultrasonic ultrasonic(6,7); // pin di comunicazione 
   int val=0;
   int val_dx1=0;
   int val_dx2=0;
   int val_sx1=0;
   int val_sx2=0;
   int val_dx=0;
   int val_sx=0; 
   int alarmPin = 13;
 
//============================================================== 
 void setup() 
   { 
  myservo.attach(9);  //  servo è collegato al pin 9

  pinMode(LEDa, OUTPUT);    
  pinMode(LEDb, OUTPUT); 
  pinMode(alarmPin, OUTPUT);
//  Serial.begin(9600); 
   Wire.begin();  
    for(pos; pos < 90; pos += 1)  
     {                                 
    myservo.write(pos);              
    delay(25);                       
     } 
    for(pos; pos > 90; pos -= 1)  
     {                                   
    myservo.write(pos);              
    delay(25);
     }    
    delay(100);    

   }
//==============================================================  
void loop() 
  { 
   
    val=ultrasonic.Ranging(CM);delay(200);  
 /*   
    for(pos; pos < 90; pos += 1)  
     {                                 
    myservo.write(pos);              
    delay(25);                       
     } 
    for(pos; pos > 90; pos -= 1)  
     {                                   
    myservo.write(pos);              
    delay(25);
     }    
    delay(100);    

    val=ultrasonic.Ranging(CM);delay(100);
    val=ultrasonic.Ranging(CM);delay(100);   
   */
    if(val<=60){
    analogWrite(LEDa, 0);
    analogWrite(LEDb, 0);
    delay(500);
    for(pos; pos > 30; pos -= 1)   
     {                                   
    myservo.write(pos);             
    delay(25);                        
     } 
    val_dx1=ultrasonic.Ranging(CM);delay(500); 
 
    for(pos; pos <60; pos += 1)   
     {                                   
    myservo.write(pos);             
    delay(25);                        
     } 
    val_dx2=ultrasonic.Ranging(CM);delay(500); 

   val_dx = max(val_dx1, val_dx2);

    for(pos; pos < 150; pos += 1)   
     {                                 
    myservo.write(pos);              
    delay(25);                       
     } 
    val_sx1=ultrasonic.Ranging(CM);delay(500); 

    for(pos; pos > 120; pos -= 1)   
     {                                 
    myservo.write(pos);              
    delay(25);                       
     } 
    val_sx2=ultrasonic.Ranging(CM);delay(500); 
  
   for(pos; pos < 90; pos += 1)  
     {                                 
    myservo.write(pos);              
    delay(25);                       
     } 
    for(pos; pos > 90; pos -= 1)  
     {                                   
    myservo.write(pos);              
    delay(25);
     }    
    delay(100);    
  
    val_sx = max(val_sx1, val_sx2);
    val_dx = max(val_dx1, val_dx2);
    delay(2000);      
 
  if ( val_dx < val_sx && (val_dx>60||val_sx>60) )
      {
     analogWrite(LEDa, 200);
     analogWrite(LEDb, 0);
     delay(300);
      }
   if ( val_dx>val_sx && (val_dx>60||val_sx>60) )
      { 
     analogWrite(LEDa, 0);
     analogWrite(LEDb, 200);
     delay(300);           
      }     
    }
   else   
      { 
    myservo.write(90);     
   analogWrite(LEDa, 200);
   analogWrite(LEDb, 200); 
   delay (300);
     }  
   }

P.S. LED = motore; non sparare sull’autore :slight_smile: Ciao

Ciao Arrigo ci do un occhiata molto volentieri grazie mille. :) Ma in che senso non sparare sull'autore?

Lollo9906:
Ciao Arrigo ci do un occhiata molto volentieri grazie mille. :slight_smile:
Ma in che senso non sparare sull’autore?

se osservi i motori sono chiamati LED e la costruzione del programma non è il massimo, ma andava in giro
poi è rimasto lì causa impegni più seri.
ciao, Arrigo

xarrigo: se osservi i motori sono chiamati LED e la costruzione del programma non è il massimo, ma andava in giro poi è rimasto lì causa impegni più seri. ciao, Arrigo

aaah ok ok non avevo inteso grazie :D ciao

Ciao. Sono di nuovo qua... non sono ancora riuscito a far funzionare il robottino.. Probabilmente perchè sono ancora alle prime armi e non me intendo abbastanza, ma non ho ancora capito come fare. Ho fatto un po di ricerche su internet e ho trovato un altro robot che fa le stesse cose che servono a me (in campo di movimenti), ma utilizza un altro tipo di sensore ultrasuoni e io purtroppo non riesco ad implementare il mio al posto di quello (il mio è il: HC-SR04 ). Questo è il link del video che mostra come dovrebbe muoversi il mio robottino per chi vuole vedere: https://www.youtube.com/watch?v=amFyzDqFEJc Se qualcuno ha pazienza di aiutarmi gliene sarei molto grato grazie. Ciao Lollo.

Ciao, io ho usato proprio quel sensore e includendo la libreria va che è una scheggia. Negli esempi della ultrasonic cìèi quello per il test dello 04 Prova a vedere se riesci a leggere una distanza, quando hai fatto questa lettura il resto è in discesa, sono solo degli if ;) ciao,Arrigo

ciao, per l’estate ho messo in pausa questo progetto ma adesso è ora di riprenderlo.
Sono arrivato a creare questo “programma” (che giustamente non funziona) e non ho idea di cosa ci sia di sbagliato. Io più di cosi non so che fare… ho bisogno di una mano. :sob:
Scusate eventuali errori stupidi e grazie per chi mi aiuterà.

#include <Servo.h>
#include <Ultrasonic.h>

Servo SX; //motore sinistro
Servo DX; //motore destro

#define avanti  0
#define giraSx  1
int stato = avanti;   // 0 = vai avanti (DEFAULT), 1 = gira a sinistra

#define TRIGGER_PIN  12 //trigger pin collegato al pin 12
#define ECHO_PIN     13 //echo pin collegato al pin 13
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);

const int tempoLoop = 20;          // un periodo di 20 ms = una frequenza di 50Hz
unsigned long ritardoLoop = 0;

int distanza;               // distanza rilevata dal sensore
int minimaDistanza = 30;    // distanza di soglia a cui il robot deve cambiare direzione
unsigned long tempoRotazioneSx = 1100;  // 1,1 secondi (circa) per effettuare una rotazione di 90°

void setup()
{
  Serial.begin(9600);
  DX.attach(9); //motore destro collegato al pin 9
  SX.attach(10); //motore sinistro collegato al pin 10

}

void loop()
{
  if (millis() - ritardoLoop >= tempoLoop)
  {
    letturaSensoreUltrasuoni(); // legge e memorizza la distanza misurata

    movimentiRobot();

    ritardoLoop = millis();
  }

}

void letturaSensoreUltrasuoni ()
{
  int cm;
  long microsec = ultrasonic.timing();
  cm = ultrasonic.convert(microsec, Ultrasonic::CM); //converte in centimetri
  Serial.print(", CM: ");
  Serial.print(cm); //stampa su monitor seriale il valore in cm
  distanza = cm;
}
void movimentiRobot ()
{
  if (stato == avanti)
  {
    if (distanza > minimaDistanza || distanza < 0) // la distanza rileata può assumere valori negativi se non è presente nessun ostacolo di fronte perciò "distanza < 0"
    {
      // vai avanti
      DX.write(180);
      SX.write(0);
    }
    else // se ci sono oggetti di fronte gira a sinistra
    {
      stato = giraSx;
    }
  }
  else if (stato == giraSx) // viene rilavato un ostacolo, il robot gira a sinistra
  {
    unsigned long tempoRotazioneSx = 1100;         // ci voglion circa 1,1 secondi per ruotare di 90°
    unsigned long tempoInizioRotazione = millis(); // memorizziamo l'istante in cui incomincia la rotazione

    while ((millis() - tempoInizioRotazione) < tempoRotazioneSx) // il robot ruota a sinistra fino a quando non sono passati 1,1 secondi
    {
      // gira a sinistra
      DX.write(180);
      SX.write(180);
    }
    stato = avanti;
  }
}

Ho modificato ancora il programma e nel post precedente l ho sostituito, quello che c'è ora è quello nuovo perchè ho modificato il post, ma lo stesso non funziona come dovrebbe... nessuno può aiutarmi?

Ciao! Anche io sto realizzando qualcosa di simile... io posso darti consiglio su come ho fatto io a fare girare il robottino ma è ancora qualcosa di sperimentale... in pratica faccio andare le tutte le ruote all'indietro tranne quella opposta alla direzione in cui voglio virare.. a me funziona anche abbastanza anche se vorrei cercare qualcosa per farlo girare più velocemente...nel tuo caso hai solo due ruote??

Ciao, ho letto il tuo post questa mattina :D e ho visto che usando la funzione millis ti sei tolto alcuni problemi, allora l ho provata pure io... ma non è cambiato nulla :slightly_frowning_face: . Non capisco dove sia il problema. I due servo che uso per far muovere le ruote inizialmente girano in modo da far svoltare il robot verso sinistra (la ruota sinistra pero gira più lentamente della destra e non so per quale motivo). Se io però do una piccola spinta dalla parte opposta sempre al quel servo, inizia a girare in avanti andando tipo a singhiozzo ma alla stessa velocità dell altro... Davvero, non capisco come poter risolvere sto problema. Ciao grazie per avermi risposto Lorenzo.

come mai utilizzi dei servo e non dei motori dc? io li uso, non li ho pagati tanto e fanno il loro lavoro… i servo da quanto letto servono per fare movimenti più “precisi” nel senso che tieni conto che io li uso per far muovere un sensorino… poi dipende anche da che servo sono ecco

Utilizzo i servo perchè prima di iniziare questo progetto avevo fatto alcune ricerche su intenet, giusto per farmi un idea, e il primo che avevo trovato utilizzava dei servomotori a 360 come motori delle ruote ma un sensore ultrasuoni diverso e più costoso. Allora mi sono personalizzato il suo progetto...o almeno ci ho provato... ma sembra che qualsiasi cosa faccia questi servo non mi "ascoltino". Anche io inizialmente avevo intenzione di mettere un mini servo per poter scansionare l'ambiente intorno, ma prima volevo risolvere questo problema di movimento base. E forse hai ragione, è meglio usare i motori dc... pero non va giù questa cosa. Sarei proprio curioso di capire perchè non funzionano. :slightly_frowning_face:

ma sai secondo me dove si sbaglia? al servo devi dare ogni volta l'angolo in pasto! quindi lui farà movimenti fino a 360° ovvero un giro di ruota ... al 361° deve iniziare il giro 2 ... ovvero un nuovo giro che cominci da 1°

Ma io sapevo che con i servo 360 se scrivi " nomeservo.write(0);" gira in un verso e se metti "nomeservo.write(180);" gira nell'altro. Però magari sto sbagliando io in tutto il resto del programma. Questa mattina ho trovato un ragazzo su un sito, che ha fatto un progetto praticamente identico al mio (servo 360 e HC-SR04) in cui varia solo il programma che fa leggere la distanza al sensore. Giustamente a lui funziona e a me no... comincio a pensare che i servo abbiano qualche problema :(

Dipende forse se sono servo "a 360 gradi" con il blocco, oppure servo "free running", cioe' liberi di girare in un senso o nell'altro ? ... hai controllato ?