Rover arduino – il progetto di Pasquale

Il rover arduino che ti mostro oggi è un progetto realizzato da Pasquale un appassionato Makers che ha partecipato all’ultima edizione del mio corso robotico in aula.

Rover arduino

Posso affermare con fierezza che il corso è stato un’esperienza formativa non solo per Pasquale ma anche per tutti tutti i partecipanti che hanno condiviso le proprie esperienze.

Come ogni corso anche io come docente ho appreso nuove possibilità ed idee.

Tra le idee proposte al corso c’è senza dubbio quella che Pasquale ha proposto e realizzato nelle settimane successive.

Componenti per costruire il rover arduino

Il rover arduino ha richiesto i seguenti componenti:

  • n.1 arduino uno
  • n. 1 motorshield fe
  • n. 2 scheda con relè 5 volt ( ad esempio due di queste )
  • n.1 un mini servo
  • n.1 led di illuminazione anteriore
  • n.2 led di illuminazione posteriore
  • n.1 sensore ultrasuoni sr04
  • n.1 fotoresistenza da 20Kohm
  • n.1 cicalino piezoelettrico
  • n.1 base per rover Leo-WI

La scelta dei componenti puoi leggermente modificarla, ad esempio sostituendo la Motor Shield Fe con una Motor Shield già assemblata per non dover eseguire le saldature di componenti smd.

Le funzioni del rover arduino

In questo progetto Pasquale ha voluto provare il controlo dei motori, del sensore e delle luci per cui il rover arduino che ha realizzato usa il sensore SR04 per rilevare la distanza dagli ostacoli ed a circa 25cm da un ostacolo ferma il robot per iniziare le manovre in grado di evitare l’ostacolo.

Il robot è dotato di 2 gruppi di led, uno anteriore montato sul miniservo ed uno posteriore di segnalazione di retromarcia.

In pratica quando il rover arduino rileva un ostacolo si ferma e fa ruotare il faro montato sul mini servo attivando la fase di manovra che provvede ad accendere i led posteriori con un relay.

Rover arduino frontale

La fotoresistenza rileva la soglia di luminosità e provvede ad accendere il led anteriore, tramite un relay, se la luce non è sufficente. E’ senza dubbio una opzione che Pasquale ha voluto realizzare in attesa di dotare questo robot di una webcam.

Lo sketch del rover arduino

Ecco lo sketch realizzato da Pasquale per il suo rover arduino:

#define motoreA 0
#define motoreB 0
#define AVANTI  0
#define INDIETRO  0
#define fotoresistenza A2
#define luci 12
#define retromarcia 9
#define beep 3

#include <Servo.h>

//Standard PWM DC control
int PWMA = 6;
int PWMB = 11;
int DIRA = 7;
int DIRB = 8;
int steerPin = 10;  // this is Servo 1 on the motor shield

Servo steerServo;
unsigned long duration, inches;
int indec, cmdec;
int inchconv = 147; // ratio between puls width and inches
int cmconv = 59; // ratio between pulse width and cm
String s1, s2, s3;
int  triggerPort = A0; // Analog pin 0 used for the Ping Pin (Trig)
int echoPort = A1; // Analog pin 1 used for the Echo Pin (Echo)

int steerCentre = 80;  // set this to be dead ahead setting (or adjust servo horn mounting)

void setup()
{
  pinMode( PWMA,OUTPUT );
  pinMode( PWMB,OUTPUT );
  pinMode( DIRA,OUTPUT );
  pinMode( DIRB,OUTPUT );
  pinMode( triggerPort,OUTPUT );
  pinMode( luci,OUTPUT );
  pinMode( beep,OUTPUT );

  pinMode( echoPort, INPUT);
  pinMode(A2,INPUT);  

  steerServo.attach(steerPin, 1000, 2000);
  sterza(0);

  Serial.begin(9600); // Inizializzo la comunicazione seriale
  Serial.println( "Sensore ultrasuoni: ");
}

void loop()
{
  int cm, lcm, rcm;
  avanti(200);
  delay(200);
  cm = distanza();
  if(cm < 25)
  {
    alt();
    sterza(-90);
    lcm = distanza();
    sterza(90);
    rcm = distanza();
    sterza(0);
    if (lcm < rcm)
      sterza(-00);
    else
      sterza(00);

    gira(180);
    delay(700);
    sterza(0);
  }

  int val = analogRead(fotoresistenza);
  Serial.println(val, DEC);

  if(val<700) {
     digitalWrite(luci,LOW);
  } else {
     digitalWrite(luci,HIGH);
  }
}

void sterza(int angle)
{
  steerServo.write(steerCentre + angle);
  delay(800);
}

int distanza()
{
  int rval;
  //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 duration = pulseIn( echoPort, HIGH );

  long r = 0.036 * duration / 2;

  Serial.print( "durata: " );
  Serial.print( duration );
  Serial.print( " , " );
  Serial.print( "distanza: " );

  //dopo 38ms è fuori dalla portata del sensore
  if( duration > 38000 ) Serial.println( "fuori portata");
  else { Serial.print( r ); Serial.println( "cm" );}
   if (duration == 0)
      duration = 1000;

  rval = microsecondsToCentimeters(duration);
  return rval;
}

void avanti(int spd)
{
  digitalWrite( retromarcia,LOW);
  digitalWrite( DIRA,LOW );
  digitalWrite( DIRB,HIGH );

  analogWrite( PWMA,spd );
  analogWrite( PWMB,spd );
}

void indietro()
{
  disgitalWrite( retromarcia,HIGH );
  digitalWrite( beep,HIGH );
  digitalWrite( DIRA,HIGH );
  digitalWrite( DIRB,LOW );

  analogWrite( PWMA,150 );
  analogWrite( PWMB,150 );
  delay (300); 

  digitalWrite(beep,LOW );
  delay (300);
  digitalWrite(beep,HIGH );
  delay (300);
  digitalWrite(beep,LOW );
  delay (300);
  digitalWrite(beep,HIGH );
  delay (300);
  digitalWrite(beep,LOW );
}

void alt()
{
  analogWrite( PWMA,0 );
  analogWrite( PWMB,0 );
}

void gira(int spd)
{
  alt();
  delay( 200 );

  indietro();
  delay( 500 );

  alt();
  delay( 200 );

  // Gira
  digitalWrite( DIRA,HIGH );
  digitalWrite( DIRB,HIGH );

  analogWrite( PWMA,spd);
  analogWrite( PWMB,spd);

  delay( 800 );
}

long microsecondsToCentimeters(long microseconds)
{
 return microseconds / cmconv;
}

avrai notato che le linee 001-008 definiscono una serie di costanti tra cui: fotoresistenza  cui è collegato l’omonimo componente elettrico, luci e retromarcia ai cui pin sono connessi i due relay rispettivamente connessi al led anteriore e posteriore ed infine beep a cui è collegato un cicalino;

linee 013-016: definisci i pin a cui sono collegate le uscite PWM e DIR di ciascun motore;

linea 017: definisci la variabile steerPin a cui è collegato il mini servo;

linea 019: definisci l’istanza della classe Servo che utilizzerai per controllare il miniservo;

linea 020: definisci due variabili di tipo unsigned long ossia di dimensione 4 byte ( 32 bit ) con range da 0 a 4,294,967,295 che utilizzi per la gestione del sensore di distanza;

linee 021-024: definisci alcune variabili di tipo integer e string che ti serviranno per definire la distanza rilevata dal sensore e convertirla da pollici ( inch ) in centimetri ( cm );

linee 025-026: definisci a quali pin sono connessi i terminali trigger ed echo del sensore SR04, se non sai cosa siano questi segnali ti consiglio di leggere il datasheet del sensore;

linea 028: imposta a 80 il valore in gradi relativo alla posizione iniziale in cui portare il servo;

linee 032-038: imposta tutti i pin che utilizzerai per controllare il rover arduino in modalità OUTPUT;

linee 040-041: imposta tutti i pin che utilizzerai come INPUT;

linee 043: associa all’istanza servo il pin a cui è connesso il mini servo;

linea 044: imposta la rotazione del servo a 0, vedrai alle linee 084-088 perchè il servo resta a metà della sua corsa;

linea 052: ad ogni ciclo di loop() imposta delle variabili di tipo integer che usi nel loop stesso e solo nella funzione loop();

linea 053: procedi in avanti a velocità 200, vedrai dopo come questo sia possibile;

linea 054: attendi 200 millisecond 1/5 di secondo;

linea 055: misura la distanza degli oggetti dal sensore, assegnando tale distanza alla variabile cm definita aa linea 052;

linea 056: se la distanza misurata è inferiore a 25cm allora esegui quanto riportato tra le paretesi graffe;

linee 058-067: servono a far ruotare il mini servo in funzione della distanza rilevata dal sensore, in questa versione del rover non hanno valore, se non quello di far ruotare la luce, ma Pasquale le ha già previste per futuri sviluppi in cui il sensore sarà collegato al servo e il rover arduino eseguirà delle valutazioni di distanza prima di girare;

linea 069: richiama la funzione gira() a cui passa il valore 180, vedrai dopo perchè;

linee 070-071: attendi 700 millisecondi dopo la fine della funzione gira e riporta il servo in posizione 0;

linee 074-081: leggi il valore rilevato dalla fotoresistenza e confrontalo con 700 ( soglia definita da Pasquale ) al superamento della quale accendi il led collegato al pin luci definito alla linea 006;

linee 084-088: definisci la funzione sterza() che accetta come valore in INPUT i gradi a cui muovere il servo partendo dalla posizione iniziale. La linea 086 infatti definisce il valore in gradi di posizione del servo come il risultato dell’operazione: (steerCentre + angle) ossia ( 80 + valore passato ) in modo che se passi alla funzione 0 avrai il servo in posizione 80° se passi alla funzione 90 => ( 80 + 90 ) = 170° e così per tutti gli angoli che passi;

linee 090-118: definisci la funzione distanza() il cui compito è rilevare la distanza tra il sensore e gli oggetti che si pongono davanti. Il suo funzionamento è complesso per cui ti rimando alla lettura del datasheet per capire come indirizzare correttamente i valori di trigger e leggere quelli di echo;

linee 120-128: definisci la funzione avanti() che accetta come valore la velocità a cui vuoi procedere. Al suo interno la linea 122 spegne i led di retromarcia se fosse accesso; le linee 123 e 124 impostano la direzione del robot una contraria all’altra in quanto stiamo parlando di un sistema motorio cingolato in cui se i cingoli ruotassero nella medesima direzione il robot arduino girerebbe su se stesso; le linee 126-127: definiscono la velocità in PWM;

linee 132-135: accendi le luci di retromarcia, porta alto il pin a cui è connesso il cicalino e imposta la direzione del rover arduino contraria a quella definita nella direzione avanti();

linee 137-139: imposta la velocità di rotazione dei motori a 150 come segnale PWM ( un po’ più di metà ) e mantienila per 300 millisecondi;

linee 141-149: porta l0uscita legata al pin del buzzer da BASSA ad ALTA a BASSA ecc.. per emettere un suono con intermittenza di 300 millisecondi.

linee 152-156: definisci la funzione alt() mediante cui il rover arduino si ferma, per farlo poni a 0 il valore dei PWM relativi ad entrambi i motori;

linea 158: definsci la funzione gira() ossia la funzione a cui è affidata la manovra quando un oggetto si trova a meno di 25cm dal robot arduino;

linee 160-161: ferma i motori richiamando la funzione alt() e attendi 200 millisecondi prima di procedere oltre;

linee 163-164: richiama la funzione indietro() ed attendi 500 millisecondi dalla sua conclusione, non essendoci nella funzione indietro() un alt() i motori continueranno a girare nel senso impostato anche dopo la fine della funzione indietro() per i successivi 500 millisecondi impostati alla linea 164 portando il tempo di retromarcia a 2 secondi netti;

linee 166-167: ferma i motori e attendi 200 millisecondi prima di eseguire altre operazioni;

linee 170-171: imposta ad HIGH entrambi i pin di direzione del rover, questa impostazione consente al robot di girare su se stesso facendo ruotare i cingoli nella medesima direzione;

linee 173-174: imposta la velocità dei motori al valore indicato come parametro della fnzione gira();

linea 176: attendi 800 millisecondi, tempo durante il quale il robot arduino gira su se stesso.

Il video realizzato da Pasquale

Pasquale ha realizzato un video in cui mostra il suo rover arduino sia in presenza di luce che in condizioni di scarsa luminosità con la luce anteriore accesa:

Continua così Pasquale !!!

Prima di inserire un commento, per favore, leggi il regolamento

Permanent link to this article: https://www.mauroalfieri.it/elettronica/rover-arduino.html

Lascia un commento

Your email address will not be published.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.