|
![]() |
Salve a tutti. Spero di far cosa gradita nel condividere un robottino che ho appena finito di costruire.
Di Bot con il Ping ce ne sono tanti, forse con tutorial e display meno per cui, senza pretesa, vi illustro quello che sono riuscito a fare. Come obiettivo mi sono dato quello di voler realizzare un robottino che evitasse gli ostacoli, da cui l'utilizzo del Ping, che avesse una maggiore autonomia (e meno scocciature di ricaricare sempre le stilo) e di visualizzare su un display la distanza rilevata dell'ostacolo.
Il tutorial è più indirizzato per i principianti ma comunque con conoscenze di elettronica e programmazione dell'Arduino. |
Lista Materiali
1- Arduino UNO o compatibile
2- Struttura Octagon Livello 1
1- Ping))) sensor della Parallax
2- Servomotore rotazione 360° - nel mio caso HSR-1425SCR
2- Ruota da 6 cm con gomma antiscivolo
1- Servomotore standard per il Ping (nel mio caso non necessario ma si può implementare)
4- Distanziali da PCB da 4 cm
2- Protoshield per i servi, batterie e Display ed aggiunte (http://www.robot-italy.com/product_info.php?products_id=879 o altri siti)
1- Display LCD 16x2 compatibile HD44780
1- Portabatterie 9v
1- Lipo 2s 1200mah 7,4v
1- UBEC 5,4/6V
1- Ruotino pivottante
1- Pezzo di millefori per lo shield del Display
1- Striscia di strip per gli shield
Realizzazione ServoShield
Come prima cosa cominciamo dagli shield. Perchè ho scelto questa strada?. Quando è necessario collegare diversi servi, un sensore, batterie etc, ovviamente ci sono parecchi PIN per i segnali da utilizzare oltre all'alimentazione e la massa. Normalmente i vari robottini vengono affiancati da una breadboard per consentire di gestire il tutto a scapito però di un sacco di fili in giro che magari ogni tanto si staccano e comunque danno sempre una senzazione di "casino". Un shield da sovrappore all'Arduino semplifica il tutto e rende più pratiche le connessioni. Come sapete per i servi o motorini ce ne sono già in commercio diversi e funzionali, es quello dell'Adafruit o Sparkfun, in ogni caso la realizzazione in casa è molto semplice e poco costosa, la protoshield che vi ho elencato adesso costa 3 €, se ci aggiungete qualche strip e dei fili non superate 4 €.
![]() |
![]() |
![]() |
![]() |
Come potete vedere dalle prime due foto si saldano diverse file da tre di piedini (io ne ho fatte 6, ma si possono aggiungere diverse in più), ogni piedino corrisponde ai tre poli dei servi e del sensore (segnale, 5v, gnd). Dopodichè saldate in parallelo (terza foto) i 5v (piedino centrale) e GND (nella foto il filo blu) e collegate quest'ultimi al connettore per alimentazione, in questo modo tutto quello che collegherete alla fila dei piedini sarà alimentato insieme. Per il pin del segnale potete decidere ,se sapete già in partenza (come nel mio caso) a quale pin corrisponde, saldare direttamente un filo al pin corrispondente, oppure se desiderate gestirlo di volta in volta basta aggiungere (seconda foto) una fila di strip femmine per collegare con un filo al pin desiderato. Nel caso sopra ho aggiunto anche un pulsante di reset e un led collegato direttamente al pin 13 dell'Arduino .
Realizzazione LCDShield
Tralascio ovviamente, in quante troverete decine di tutorials, su come si connette un display all'Arduino es: http://arduino.cc/en/Tutorial/LiquidCrystal, ribadisco invece, se si vuole adottare la possibilità di inserirlo nel progetto, che occorre ridurre il numero di fili in giro che in questo caso sono parecchi. Quindi possiamo anche qui realizzare uno shield che può venire utile per altri progetti con l'Arduino.
![]() |
![]() |
![]() |
![]() |
Dei 16 pin di un Display, solamente 12 sono necessari per il nostro scopo. Se osservate la prima e la terza foto occorre ritagliare una millefori che ci servirà, oltre che da supporto per il display, da "ponte" di collegamento con i pin dell'Arduino. Quindi cosa dobbiamo fare, saldare (io l'ho saldata leggermente inclinata, come da foto2, per poter leggere meglio il display) una strip femmina di 16 piedini alla millefori, far partire da ogni pin che si utilizza (lo vediamo più avanti) un filo saldato direttamente al pin corrispondente della protoshield, che andremo poi a sovrapporre all'Arduino e sopra questo shield (ultima foto) metteremo quello realizzato per i servi con zero fili visibili.
Schema e collegamenti
LCD PIN 1 - > GND
LCD PIN 2 - > 5v
LCD PIN 3 - > PIN centrale potenziometro (per regolazione contrasto) aggiungendo +5v e GND agli altri due PIN
LCD PIN 4(RS) - > Arduino PIN 3
LCD PIN 5(RW) - > GND
LCD PIN 6(EN) - > Arduino PIN 4
LCD PIN 11(DB4) - > Arduino PIN 5
LCD PIN 12(DB5) - > Arduino PIN 6
LCD PIN 13(DB6) - > Arduino PIN 11
LCD PIN 13(DB7) - > Arduino PIN 12
LCD PIN 15 - > 5v
LCD PIN 16 - > GND
Segnale Servomotore che attua sensore ultrasonico - > Arduino PIN 10
Segnale sensore ultrasonico - > Arduino PIN 7
+ LED - > Arduino PIN 13
- LED - > Arduino GND
Servomotore sinistro - > Arduino PIN 9
Servomotore destro - > Arduino PIN 8
| Al primo Octagon ho inserito due servi con rotazione a 360, un supporto per la pila a 9v, ed ho attaccato, lo so... da schifo, una lipo. | Ho scelto questo sistema perchè, chi usa le lipo per modellismo lo sa bene, mi piace tener monitorata la tensione residua per evitare di danneggiare la pila, per cui con il nastro adesivo posso rimuoverla facilmente. |
![]() |
![]() |
| Perchè due alimentazioni, qui si possono incrociare diverse opinioni, in ogni caso credo che sia meglio tenere sempre divisa la logica (Arduino) dai motori per evitare interferenze. | Dove vedete il bullone ho messo un ruotino pivottante e due contrappesi in quanto era leggermente sbilanciato sul davanti. Nella foto qui sopra potete vedere la parte inferiore. |
![]() |
![]() |
Ho realizzato un vano per il servo del Ping, quattro fori per fissare l'Arduino e ho posizionato fissandolo con una fascetta l'UBEC che vedete a sinistra e destra delle due foto. Per chi non lo conoscesse serve in pratica a regolare la tensione di uscita della pila, in quanto la lipo ha una tensione di 7,4 v, mentre i servi hanno una tensione di conduzione che va da 4,8v a 6. Si possono usare anche dei diodi od altro.
![]() |
![]() |
![]() |
![]() |
L'alimentazione del display io l'ho messa sotto quella dei servi in quanto gestita da una batteria più capiente. Questa è una foto del Display in funzione
Il codice
Piccola premessa, troverete decine di varianti su come far funzionare il PING, in sostanza il funzionamento concreto del sensore ha luogo nel ciclo loop() che implementa il protocollo di funzionamento del componente PING. In base alle sue specifiche si può controllare il funzionamento del sensore tramite una serie di impulsi. In sintesi si può dire che si utilizza un pin digitale per misurare un pin analogico. Improvement: se volete fare i fighi potete anche inserire un sensore di temperatura tipo TMP36 per migliorare la lettura, questo perchè come sapete il suono viaggia ad una velocità di 343 m/s, questo valore però non è assoluto in quanto dipende anche dalla temperatura dell'aria, la bibliografia riporta questa relazione tra la velocità del suono (C) e la temperatura dell'aria (t) C= 331,5 + (0,6 * t) , conoscendo la temperatura (e qui ci aiuta il sensore) possiamo eventualmente inserire poche righe di codice per implementare la lettura.
#include Servo.h
#include Liquidcrystal.h
LiquidCrystal lcd(3, 4, 5, 6, 11, 12);
Servo PingServo;
Servo LeftServo;
Servo RightServo;
int ultraSoundSignal = 7; // Ultrasound signal pin
int val = 0;
int val2 = 0;
int ultrasoundValue = 0;
int timecount = 0; // Echo counter
int ledPin = 13; // LED connected to digital pin 13
void setup(){
lcd.begin(16, 2);
Serial.begin (9600);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
LeftServo.attach(8);
RightServo.attach(9);
PingServo.attach(10);
pinMode(ledPin, OUTPUT);
}
void moveServoLeftTo(int angle, int duration){
// comanda il servo a muoversi per un dato angolo e per un dato numero di millisecondi
LeftServo.write(angle);
for( ; duration > 0; duration -= 20){ // ciclo per il numero specificato di millisecondi sottraendo 20ms ogni iterazione
delay(20);
}
}
void moveServoRightTo(int angle, int duration){
RightServo.write(angle);
for( ; duration > 0; duration -= 20){
delay(20);
}
}
void loop() {
// Funzioni Ping)))
timecount = 0;
val = 0;
pinMode(ultraSoundSignal, OUTPUT); // Switch signalpin to output
digitalWrite(ultraSoundSignal, LOW); // Send low pulse
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignal, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignal, LOW); // Holdoff
pinMode(ultraSoundSignal, INPUT); // Switch signalpin to input
val = digitalRead(ultraSoundSignal); // Append signal value to val
while(val == LOW) { // Loop until pin reads a high value
val = digitalRead(ultraSoundSignal);
}
while(val == HIGH) { // Loop until pin reads a high value
val = digitalRead(ultraSoundSignal);
timecount = timecount +1; // Count echo pulse time
}
ultrasoundValue = timecount; // Append echo pulse time to ultrasoundValue
lcd.clear();
cd.setCursor(0,0);
lcd.print("OBSTACLE cm ");
lcd.print(timecount/10);
delay(200);
if(timecount > 0){
digitalWrite(ledPin, HIGH);
// Servo functions:
if(ultrasoundValue > 500){
moveServoLeftTo(45,50); // muove il servo sinistro di 45 gradi per 500 millisecondi
moveServoRightTo(180,50);
}
if(ultrasoundValue < 500){
moveServoLeftTo(180,40);
moveServoRightTo(180,40);
}
if(ultrasoundValue < 100){
moveServoLeftTo(180,100);
moveServoRightTo(45,100);
}
}
//------------------------------------------------------------------------------
Piccola accortezza, non lasciare mai lipo connessa all'ubec senza utilizzarla, quest'ultimo continua a drenare corrente e si scarica rovinandosi.
Spero di essere stato chiaro e utile. A presto e grazie della visione.
















