Dolcino è un robottino a costo minimo, sviluppato per consentire alle scuole , ai privati, alle associazioni, di partecipare alla Robocup Rescue Line Under 14 con piena possibilità di successo senza impegnare una cifra esagerata.
Il fatto che possa partecipare alla gara di Rescue Line è importante perché consente la possibilità di cimentarsi in una competizione, e quindi di partecipare ad un evento collettivo di socializzazione e confronto, ma il robot può essere usato per mille altre missioni, avventure, esperimenti.
E’ un progetto pubblico, e ogni suggerimento è benvenuto per migliorarlo. L’idea è quella di rendere possibile a chiunque la costruzione del robot, con mezzi economici irrisori, e comprendendo ogni fase del funzionamento e della costruzione.
Il kit base
Il kit sul sito di Hobbyking
4 motori demoltiplicati indipendenti e 4 ruote su una piattaforma in plastica con montanti in metallo. Niente di che, qualità cinese, ma prezzo ottimo e dato che i motori lavorano tutti il robottino è in grado di salire rampe anche piuttosto inclinate.
Le piattaforme in plastica, avendo un sacco di fori, possono benissimo ospitare la scheda col microcontrollore e i vari sensori.
Il Micro
Non poteva che essere un Arduino Uno. E’ il più diffuso, il più supportato dalla comunità, il più economico.E’ italiano, di quella Italia che lavora studia condivide e crea, non di quella che gira col portatilino con su la mela e si vanta di essere fruitrice passiva di tecnologia.
Lo Shield
Potevamo farne a meno, ok, ma visto l’esorbitante costo di 1 euro ce lo siamo permessi:
abbiamo preso un Sensor Shield.
Ci viene molto comodo per saldarci i fili o inserire dei connettori in modo da rendere le connessioni coi motori e coi sensori più affidabili.
Di questo tipo di Shield ce ne sono moltissimi, e tutti a prezzi ridicoli.Prendete quello che più vi piace e che vi sembra più comodo per i collegamenti.
Il ponte H
Il ponte H è un L9110S, che costa qualcosa più di mezzo euro. Non sopporta correnti elevate, ma riesce onestamente a muovere i nostri motorini cinesi avanti e indietro.
Ogni chip (ne ha 2) gestisce un motore, quindi visto il costo irrisorio possiamo mettere 2 di questi ponti per alimentare ogni motore singolarmente.
Abbiamo scelto di montare 2 chip su dolcino e di cortocircuitare i segnali che vanno rispettivamente ai motori di destra ed a quelli di sinistra. In questo modo raddoppiamo la potenza dissipabile dai ponti H.
Abbiamo scelto di pilotare ogni coppia di motori (coppia di destra , e coppia di sinistra) con due PIN di Arduino capaci di lavorare in PWM.
Rispettivamente i PIN 5 e 6 a sinistra e 9 e 10 a destra.
Il chip L9110S si comporta così: fa girare i motori quando c’è una differenza di fase tra i due pin. Quindi per farlo avanzare con un valore di velocità da me scelto metto a 0 il valore di analogWrite ad una porta , e invece imposto un valore di analogWrite diverso da zero sull’ altra.
Per far girare il motore all’indietro inverto i valori di analogWrite alle due porte.
Per far fermare il motore ho due opzioni: se porto entrambe le porte al valore logico zero (analogWrite 0), il motore si arresta dolcemente, se invece porto entrambe le porte ad un valore logico 1 (analogWrite 1) il motore si arresta in modo brusco.
Ecco qui sotto lo sketch di prova per testare il funzionamento del ponte H. Dopo aver dichiarato i PIN in OUTPUT nel setup() ci sono nel loop alcune semplici istruzioni per mandare il robot a destra, a sinistra, avanti e indietro. E’ molto probabile che la diversità dei motori che equipaggiano il vostro robottino causi un avanzamento non rettilineo quando i motori di destra e di sinistra sono pilotati con gli stessi valori. Cercate di trovare sperimentalmente dei valori che correggano il problema.
int velocita=140; void setup() { pinMode(5,OUTPUT); pinMode(6,OUTPUT); pinMode(9,OUTPUT); pinMode(10,OUTPUT); } void loop() { //avanti piano con un motore analogWrite(5,velocita); analogWrite(6,0); delay(1000); //fermo dolcemente digitalWrite(6,LOW); digitalWrite(5,LOW); delay(3000); //avanti piano con altro motore; analogWrite(9,velocita); analogWrite(10,0); delay(1000); //fermo dolcemente digitalWrite(10,LOW); digitalWrite(9,LOW); delay(3000); //avanti piano con due motori; analogWrite(5,velocita); analogWrite(6,0); analogWrite(9,velocita); analogWrite(10,0); delay(1000); //fermo bruscamente digitalWrite(5,HIGH); digitalWrite(6,HIGH); digitalWrite(9,HIGH); digitalWrite(10,HIGH); delay(3000); //indietro piano con due motori; analogWrite(5,0); analogWrite(6,velocita); analogWrite(9,0); analogWrite(10,velocita); delay(1000); //fermo bruscamente digitalWrite(5,HIGH); digitalWrite(6,HIGH); digitalWrite(9,HIGH); digitalWrite(10,HIGH); delay(3000); }
I sensori di linea e colore
Il sensore RGB
Pagina di Adafruit a cui trovare il sensore
Lo stesso su Aliexpress
Collegamenti: si attaccano
VIN= ai 5V di Arduino
GND= a GND di Arduino
SDA= al piedino SDA di Arduino (A5 su Arduino UNO)
SCK= al piedino SCK di Arduino (A4 su Arduino UNO)
Il multiplexer
Il sensore di colore che abbiamo si comporta egregiamente,ha una libreria già scritta da Adafruit, ed ha bisogno solo di due fili per trasferire i dati ricevuti ad Arduino. Non è però perfetto. Il difetto che ha è che il suo indirizzo I²C non è modificabile. Avendo bisogno assoluto di 2 sensori, e avendo questi lo stesso indirizzo, ho bisogno di un dispositivo aggiuntivo che apra la comunicazione alternativamente verso l’uno o verso l’altro. Questo dispositivo si chiama multiplexer.
Il multiplexer è il chip CD4052B (si trova ovunque al prezzo di una 0,2 Euro)
Il Multiplexer su Aliexpress
PDF col datasheet del 4052
E’ un dispositivo che accetta e commuta 4 coppie di fili. A noi bastano 2 coppie.
Scegliamo arbitrariamente i canali zero e 1.
Questo sotto è lo sketch di Arduino basato sulla libreria Adafruit per gestire il sensore RGB. Il Pin scelto per attivare i canali 0 o 1 del multiplexer è il 13
#include #include "Adafruit_TCS34725.h" Adafruit_TCS34725 tcs = Adafruit_TCS34725(); void setup(void) { Serial.begin(9600); pinMode(13,OUTPUT); digitalWrite(13,1); if (tcs.begin()) { Serial.println("Found sensor"); } else { Serial.println("No TCS34725 found ... check your connections"); while (1); } digitalWrite(13,0); if (tcs.begin()) { Serial.println("Found sensor"); } else { Serial.println("No TCS34725 found ... check your connections"); while (1); } } void loop(void) { digitalWrite(13,1); uint16_t r, g, b, c, colorTemp, lux; tcs.getRawData(&r, &g, &b, &c); if ((g*1.4)>(r+b)) { Serial.println("verde a sinistra"); } delay(10); digitalWrite(13,0); tcs.getRawData(&r, &g, &b, &c); if ((g*1.4)>(r+b)) { Serial.println("verde a destra"); } delay(10); }
Il montaggio dei sensori sul robot
Il sensore di distanza
Come sensore di distanza usiamo il noto HC-SR04.
E’ molto economico,abbastanza preciso,facilissimo da gestire (ha solo 4 pin dei quali 2 sono per l’alimentazione elettrica e 2 (Echo e Trigger) per il segnale), e c’è una bellissima libreria per Arduino: NewPing. Con questa libreria non serve fare niente più che caricare il programma di esempio e cambiare i pin a cui è connesso il sensore. Siccome noi lo abbiamo connesso ai piedini 8 (Trigger) ed 11 (Echo), ed ecco di conseguenza qui sotto il codice editato per il funzionamento.
#include #define TRIGGER_PIN 8 // pin connesso al trigger pin. #define ECHO_PIN 11 // pin connesso all' echo pin. #define MAX_DISTANCE 200 // Massima distanza misurabile (in centimetri). NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); void setup() { Serial.begin(115200); // Apri il serial monitor a 115200 baud. } void loop() { delay(50);//Attendi 50ms tra i ping (circa 20 ping/sec).29ms è il minimo. Serial.print("Ping: "); Serial.print(sonar.ping_cm()); // chiedi distanza in cm e visualizzala Serial.println("cm"); }
Due conti
13(kit)+4(Arduino)+1(Shield)+1,5(2 Hbridge)+8(Sensori RGB)+1(Sensore dist) =28 Euro
Esempio Seguilinea
#include “Adafruit_TCS34725.h”
Adafruit_TCS34725 tcs = Adafruit_TCS34725();
float costantesinistra=1.5;
int limiteluce=55 ;
int velocita=130;
int lucedestra,lucesinistra;
void setup()
{
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
Serial.begin(9600);
pinMode(13,OUTPUT);
digitalWrite(13,1);
if (tcs.begin())
{
Serial.println(“Found sensor 1”);
}
else
{
Serial.println(“No TCS34725 found … check your connections”);
while (1);
}
digitalWrite(13,0);
if (tcs.begin())
{
Serial.println(“Found sensor 0”);
}
else
{
Serial.println(“No TCS34725 found … check your connections”);
while (1);
}
}
void sinistra()
{
//ruote di destra in avanti
analogWrite(5,velocita);
analogWrite(6,0);
//ruote di sinistra indietro
analogWrite(9,0);
analogWrite(10,velocita);
delay(25);
}
void destra()
{
//ruote di sinistra in avanti
analogWrite(9,velocita);
analogWrite(10,0);
//ruote di destra indietro
analogWrite(5,0);
analogWrite(6,velocita);
delay(25);
}
void dritto()
{
analogWrite(5,velocita-40);
analogWrite(6,0);
analogWrite(9,velocita-40);
analogWrite(10,0);
delay(20);
}
void indietro()
{
analogWrite(5,0);
analogWrite(6,velocita);
analogWrite(9,0);
analogWrite(10,velocita);
delay(80);
}
void stopsoft()
{
digitalWrite(6,LOW);
digitalWrite(5,LOW);
digitalWrite(9,LOW);
digitalWrite(10,LOW);
delay(2);
}
void stophard()
{
digitalWrite(5,HIGH);
digitalWrite(6,HIGH);
digitalWrite(9,HIGH);
digitalWrite(10,HIGH);
delay(100);
}
void loop()
{
// delay(1000);
digitalWrite(13,1);
uint16_t r, g, b, c, colorTemp, lux;
tcs.getRawData(&r, &g, &b, &c);
lucesinistra=c*costantesinistra;
Serial.print(“S”);
Serial.println(lucesinistra);
if ((g*1.4)>(r+b))
{
Serial.println(“verde a sinistra”);
}
delay(10);
digitalWrite(13,0);
tcs.getRawData(&r, &g, &b, &c);
lucedestra=c;
Serial.print(“D”);
Serial.println(lucedestra);
if ((g*1.4)>(r+b))
{
Serial.println(“verde a destra”);
}
delay(10);
if (lucedestra<=limiteluce)
{
destra();
stopsoft();
Serial.println(“destra”);
}
if (lucesinistra<=limiteluce)
{
sinistra();
stopsoft();
Serial.println(“sinistra”);
}
if ((lucedestra>limiteluce) && (lucesinistra>limiteluce))
{
dritto();
stopsoft();
Serial.println(“dritto”);
}
//sinistra();
//stopsoft();
//destra();
//stopsoft();
//dritto();
//stophard();
//indietro();
//stophard();
}