Robot Beginner Kit – l’evoluzione

Qualche tempo fa ho pubblicato tre articoli su come costruire il tuo primo robot partendo da un kit in vendita su internet: Robot Beginner Kit.

beginner robot kit II

questo articolo è stato così tanto apprezzato che ho deciso di far evolvere il robot con una serie di tutorial che possano aiutarti a sviluppare qualcosa di più divertente con pochi componenti aggiuntivi.

Se non conosci il robot ecco i tre articoli su come costruirlo:

  1. Robot Beginner Kit con Arduino – il montaggio
  2. Robot Beginner Kit con Arduino – l’elettronica
  3. Robot Beginner Kit con Arduino – il primo sketch

La prima evoluzione riguarda la parte “cognitiva” del robot, lo sketch precedente si limitava a individuare l’ostacolo e a girare sempre nella stessa direzione:

con le modifiche che apporterai al robot potrai valutare da quale lato lo spazio di manovra è migliore e in funzione di questa informazione girare a destra o a sinistra, risparmiando manovre e batteria 🙂 Il divertimento dura di più.

Modifica Hardware

Ne ho fatte 2, la prima riguarda il sensore che ho posizionato su di un mini servo, puoi prendre quello che esce dallo starter kit di arduino o acquistarne uno.

Ho scelto un miniservo sia perché non ho bisogno di grande forza, il sensore pesa pochi grammi, sia perché in questo modo il sensore non si solleva troppo rispetto al robot, l’ideale sarebbe poterlo fissare alla base inferiore e non a quella superiore, lascio a te l’ulteriore modifica hardware.

beginner robot kit

La seconda modifica riguarda la disposizione delle schede e l’aggiunta di una mini breadboard, anche questa contenuta nello starter kit, il cui scopo è solo quello di fare da zoccolo per l’alimentazione non essendoci abbastanza pin per alimentare da arduino il servo, i motori ed il sensore:

beginner robot kit - alto

Lo sketch

/*
 * Beginner Robot Kit - II evoluzione cognitiva
 *
 * Autore: Mauro Alfieri
 * Tw: @mauroalfieri
 */

#include <Servo.h>

#define PWMA 3
#define PWMB 5
#define AIN1 4
#define AIN2 7
#define BIN1 8
#define BIN2 12
#define STBY 2

#define motoreA 0
#define motoreB 0
#define AVANTI  0
#define INDIETRO  0
#define SENSIBILITA 200
#define pinTesta 11

int SHIR = A5;
int grad[] = {90,0,180};
int distanza = 0;
int direzione = 0;

Servo testa;

void setup()
{
  pinMode( STBY,OUTPUT );
  pinMode( PWMA,OUTPUT );
  pinMode( PWMB,OUTPUT );
  pinMode( AIN1,OUTPUT );
  pinMode( AIN2,OUTPUT );
  pinMode( BIN1,OUTPUT );
  pinMode( BIN2,OUTPUT );

  pinMode( SHIR,INPUT );

  digitalWrite( STBY,HIGH );

  testa.attach(pinTesta);
  testa.write(90);
}

void loop()
{

  int dist = analogRead(SHIR);

  if ( dist > SENSIBILITA ) { 
    int direz = valutaDirezione();

    if ( direz == 1 ) { giraD(); }
    if ( direz == 0 ) { avanti(); }
    if ( direz == 2 ) { giraS(); }
  }
  else { avanti(); }

}
void avanti()
{
    digitalWrite( AIN1,HIGH );
    digitalWrite( AIN2,LOW );
    digitalWrite( BIN1,HIGH );
    digitalWrite( BIN2,LOW );

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

void indietro()
{
    digitalWrite( AIN1,LOW );
    digitalWrite( AIN2,HIGH );
    digitalWrite( BIN1,LOW );
    digitalWrite( BIN2,HIGH );

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

void alt()
{
    analogWrite( PWMA,50 );
    analogWrite( PWMB,50 );

    digitalWrite( AIN1,LOW );
    digitalWrite( AIN2,LOW );
    digitalWrite( BIN1,LOW );
    digitalWrite( BIN2,LOW );
}

void giraD()
{
  // STOP x 1/2 sec
  alt();
  delay( 500 );

  // INDIETRO x 1/2 secondo
  indietro();
  delay( 500 );

  // STOP x 1/2 sec
  alt();
  delay( 500 );

  // Gira Destra
  digitalWrite( AIN1,HIGH );
  digitalWrite( AIN2,LOW );
  digitalWrite( BIN1,LOW );
  digitalWrite( BIN2,HIGH );

  analogWrite( PWMA,100 );
  analogWrite( PWMB,100 );

  delay( 300 );
}

void giraS()
{
  // STOP x 1/2 sec
  alt();
  delay( 500 );

  // INDIETRO x 1/2 secondo
  indietro();
  delay( 500 );

  // STOP x 1/2 sec
  alt();
  delay( 500 );

  // Gira Sinistra
  digitalWrite( AIN1,LOW );
  digitalWrite( AIN2,HIGH );
  digitalWrite( BIN1,HIGH );
  digitalWrite( BIN2,LOW );

  analogWrite( PWMA,100 );
  analogWrite( PWMB,100 );

  delay( 300 );
}

int valutaDirezione() {
  alt();
  for ( int g=0; g<3; g++)
  {      
      testa.write( grad[g] );
      delay(1000);
      int val = analogRead(A5);

      if (distanza > val )
      {
        direzione = g;
      }
      distanza = val;
  }
  testa.write(90);
  return direzione;
}

Le modifiche fatto alla sketch riguardano un po’ tutto il listato, eccole linea per linea, non ti spiegherò le funzioni che già conosci o puoi rileggere negli articoli precedenti:

linea 08: includi la libreria Servo.h che utilizzerai per controllare il servo;

linea 11: modifica il pin a cui è collegato il PWMB, collegalo al pin 5 per non andare in conflitto con la libreria del servo;

linea 23: aggiungi la definizione del pin a cui colleghi il servo, io consiglio il pin 11;

linea 26: definisci un array di interi i cui valori indicano i gradi a cui il servo deve portarsi per eseguire le rilevazioni delle distanze;

linea 27-28: definisci due variabili di tipo integer assegnando il valore 0;

linea 30: inizializza un oggetto di tipo Servo, nell’esempio io l’ho chiamato testa in quanto ho immaginato che il sensore fosse posizionato sulla testa del robot 🙂

linee 46-47: indica all’oggetto testa quale è il pin a cui è collegato il servo (linea 46) e imposta a 90° ossia nella posizione centrale il servo con l’uso del metodo write;

La funzione loop() subisce una piccola modifica, all’interno dell’if che confronta la distanza tra robot ed oggetto rispetto al valore di SENSIBILITA impostato elimina il solo richiamo alla funzione gira e aggiungi le linee 56-60 il cui significato è:

linea 56: richiama una funzione nuova definita alle linee 150-166, il cui scopo è valutare la distanza di un oggetto secondo i punti in gradi definiti alla linea 26, vedrai cosa fa nelle prossime righe, per adesso ti interessa sapere che questa funzione ritorna un valore che può essere 0,1 o 2 secondo il lato con l’oggetto a maggiore distanza, quindi il lato verso cui dirigersi.

linea 58: se il risultato della linea precedente è 1 vuol dire che lo spazio maggiore, oggetto più lontano, è a destra e quindi richiama la dunzione giraD(), gira a destra;

linea 59: se il valore ritornato dalla linea 56 è 0 l’ostacolo più lontano è difronte, quindi va avanti;

linea 60: se il valore ritornato dalla linea 56 è 2 l’ostacolo più lontano è sainistra e quindi richiamo la funzione giraS(), gira a sinistra;

Le funzioni avanti(), indietro(), alt() restano invariate.

La funzione gira devi sdoppiarla ed a ciascuna copia aggiungere ina D ed una S nel nome, indicano Destra e Sinistra. Siccome il robot girava sempre a sinistra la giraS() resta invariata, mentre la giraD() vanno invertiti i comandi nelle linee 113-116 in modo che il robot possa girare a Destra.

La funzione cuore del nuovo sketch è la valutaDirezione() il cui compito è verificare in quale direzione far girare il robot in funzione della distanza che lo separa dall’oggetto più lontano:

linea 151: ferma i motori per eseguire la valorazione;

linea 152: inizia un ciclo di da 0 a 2 ( g < 3 ) in quanto la grandezza dell’array grad[] definito alla linea 26 è di 3 valori, se aggiungi più valori angolari ricordati di modificare la condizione del ciclo e il valore restituito;

linea 154: fa ruotare la testa del robot dei gradi definiti nell’array grad[ g ] dove g varia ad ogni ciclo;

linea 155: attende un secondo, prima di rilevare il valore, è un tempo arbitrario e ti serve per essere sicuro che il servo sia giunto in posizione e che la testa non stia vibrando evitando false misurazioni;

linea 156: verifica il valore rilevato dal sensore e lo immagazzina nella variabile val;

linea 158: confronta il valore della variabile distanza, la prima volta vale 0 come impostato alla linea 27, con val, il valore rilevato alla linea 156, se la distanza dell’oggetto è maggiore di quella rilevata la condizione è verificata;

linea 160: assegna alla variabile direzione definita alla linea 28, il valore dell’indica g in questo momento, sarà questo valore ad indicare alla funzione loop() in che direzione spostarsi, secondo queste regole:

  • g=0 -> grad[g]=90 -> davanti c’è l’oggetto più lontano;
  • g=1 -> grad[g]=0 -> a destra c’è l’oggetto più lontano;
  • g=2 -> grad[g]=180 ->  sinistra c’è l’oggetto più lontano;

linea 162: assegna il valore letto dal sensore alla variabile distanza questo comporta che al prossimo ciclo di for il valore distanza sarà quello letto al ciclo precedente, quindi il confronto alla linea 158 sarà tra la distanza rilevata al ciclo precedente e quella rilevata al ciclo attuale;

linea 164: posiziona la testa al centro, 90°;

linea 165: ritorna il valore impostato nella variabile direzione in modo che il loop(9 possa decidere dove spostare il robot.

Ecco un esempio del robot in azione:

Buon divertimento !!!

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

Permanent link to this article: https://www.mauroalfieri.it/elettronica/robot-beginner-kit-evoluzione.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.