ultimo aggiornamento 23 novembre 2014 |
|
Prima di passare alla descrizione dei programmi da installare che sono due uno per il Robot e uno per la stazione di controllo, è opportuno soffermarsi su alcuni problemi incontrati durante la realizzazione del programma per la stazione di controllo. Questi non si erano evidenziati nelle prime fasi poiché era previsto solamente un flusso di dati semplice, come l’invio di un solo carattere e con una direzione che era dalla Scheda Arduino Esplora verso la scheda Arduino Nano. I problemi si sono verificati quando si è tentato di inviare dei dati, come la telemetria dei sensori, dal robot verso la scheda esplora.
Primo problema – Velocità di trasmissione
I moduli bluetooth utilizzati
permettono una velocità massima di 115200 bps, che è tra l’altro il valore
impostato di default.
Ora, se questo valore può andare bene per collegamenti semplici con la UART
implementata in hardware sul chip. presente sulla scheda, i problemi si
presentano quando si utilizza una seriale UART creata per via software, per cui
un primo passo per evitare questo problema è stato ridurre a 9600 bps la
velocità.
Secondo problema - Particolarità del processore della scheda Arduino Esplora
Il processore della scheda
Arduino Esplora è un ATMEGA32U4 che è lo stesso della scheda Leonardo,
una delle sue particolarità è che ha già a bordo un’interfaccia USB.
Questo ha due implicazioni importanti: il costo più contenuto e che è in grado
di operare in qualsiasi modalità USB.
Ciò significa che si possono creare delle Human Interface Device ( HID ) , come
mouse e tastiere e stampanti.
Per il collegamento del modulo Bluetooth con il processore, si sono utilizzati i
due pin digitali disponibili connessi alle porte D3 e D11.
Per la creazione della porta virtuale si sono utilizzati il pin 11 come RX e il pin 3 come TX.
SoftwareSerial mySerial(11, 3); // Definizione RX, TX per collegamento
Questa è la sola configurazione possibile in quanto, come riportato nella pagina del sito Arduino che descrive i vari comandi della libreria Software Serial, sono riportate le seguenti limitazioni note
Non tutti i pin della Leonardo supportano il cambio di interrupts, solo i seguenti possono essere usati come RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
Conversione dei valori ricevuti dal robot.
Altro problema è stato quello di come inviare e come decodificare poi i dati
ricevuti dal robot.
La soluzione utilizzata, ha previsto sul robot la creazione di una funzione che,
dopo aver letto i vari sensori e convertiti a seconda del tipo, li invia alla
seriale tramite dei comandi Serial.println()
; se il valore da inviare è decimale,
questo viene prima moltiplicato per 10, in modo da inviare sempre un numero
intero.
/*Trasmissione telemetria*/ void telemetria() { led_on (); //Preparazione dei valori float vbatt = (analogRead(vbat)*((readVcc()/1000.0)/1024)); int batteria = vbatt*10; int fotocellula = analogRead(foto); // lettura grezza dall'adc int reading = analogRead(temp); float voltage = (reading * 5.0) / 1024; int tempC=((voltage - 0.5) * 100)*(-1); int temperatura = tempC *10; distance = Dist.getDistanceCentimeter(); //Invio valori verso stazione di comando Serial.println (batteria); Serial.println (fotocellula); Serial.println (temperatura); Serial.println (distance); Serial.print ("F"); led_off (); } |
Sulla Stazione di controllo, il comando utilizzato per decodificare i valori
ricevuti, utilizza la funzione mySerial.parseInt()
che restituisce il primo
numero intero dal buffer seriale. Caratteri che non sono numeri interi (o il
segno meno) sono saltati. mySerial.parseInt()
termina con il primo carattere che
non è una cifra.
Per ricreare i valori decimali si è nuovamente diviso il valore per 10,
successivamente si è utilizzato il comando sprintf()
che permette di creare una
stringa con la giusta formattazione e con i valori calcolati, per esempio :
sprintf(tensione1,"%d.%d V",iBattVoltage,dBattVoltage);
Tensione1 è il nome della stringa in uscita.
"%d.%d V" è il formato della stringa formato dalla prima cifra (nel nostro caso
il valore assunto da iBattVoltage), dal “punto”, dalla seconda cifra (nel nostro
caso il valore assunto da dBattVoltage)
Programma Stazione di controllo
Il programma per la stazione di controllo denominato Robot_Littlebot_controller.ino, può essere riassunto nelle seguenti funzioni:
Caricamento delle librerie
Definizione delle varabili e della porta seriale virtuale
Assegnazione del carattere inviato al robot in base al tasto premuto
Impostazione del modulo bluetooth come Master con assegnazione del codice del modulo slave.
Impostazione del display
Ciclo di lettura del joystick e dei tasti con invio al robot del codice corrispondente nel caso il tasto premuto sia il numero 1 o il numero 3 viene riportato sul display il valore aggiornato della telemetria.
Il joystick ha la
funzione di muovere il robot nelle quattro direzioni, mentre i tasti assumono la
seguente funzione:
1 - emissione suono
3 - accensione/spegnimento faro frontale
2-4 rotazione servo frontale
Il collegamento
bluetooth della scheda Arduino Esplora è effettuato impostando il modulo come
Master (vedere anche la pagina
Scheda Arduino Esplora e collegamento modulo Bluetooth)
Per fare questo, occorre inviare al modulo alcuni comandi che sono presenti
nella sezione setup del programma.
Dopo aver impostato la velocità di trasmissione della seriale a 115200 bps (che
è quella di default del modulo), viene inviato il comando per entrare in
command mode rappresentato da print (“$$$”) a cui deve seguire una breve
pausa.
mySerial.begin(115200);
mySerial.print("$");
mySerial.print("$");
mySerial.print("$");
delay(100);
Quindi, s’invia il
comando println(“SM,1”) che imposta il modulo come Master.
A questo punto indichiamo a quale modulo deve connettersi mediante il comando
println("C, <address>) dove <address> deve essere sostituito dal
codice MAC del vostro modulo slave, questo numero si trova scritto sull’esterno
del modulo, ed è formato da 12 cifre.
mySerial.println("SM,1");
delay(100);
//inserire il codice MAC del modulo Slave
mySerial.println("C,000666644021");
delay(100);
Dopo una nuova pausa impostiamo il valore della velocità di trasmissione a 9600
con il comando
mySerial.println("U,9600,N");
che cambia
temporaneamente il baudrate a 9600, no parity, questo alla prossima riaccensione
del modulo si riporterà al valore di 115200.
Si trasmetterà quindi il comando println("---") che permette l’uscita dal
Command Mode, dopo un’ulteriore pausa con il comando
mySerial.begin(9600);
Si inizializza nuovamente la seriale di collegamento con il bluetooth a 9600.
Sotto le righe di codice corrispondenti:
mySerial.begin(115200);
mySerial.print("$");
mySerial.print("$");
mySerial.print("$");
delay(100);
mySerial.println("SM,1");
delay(100);
//inserire il codice MAC del proprio modulo Slave
mySerial.println("C,000666644021");
delay(100);
mySerial.println("U,9600,N"); // Cambia temporaneamente il baudrate a 9600, no parity
mySerial.println("---"); //Uscita command mode
delay (100);
mySerial.begin(9600); // Reinizializza la seriale bluetooth 9600
delay (100);
Per il resto, il programma dovrebbe essere sufficientemente commentato da comprenderne le funzioni.
Nota sul funzionamento.
Una nota per chi utilizzerà il programma: nonostante tutte le prove e i vari tentativi di correzione, per un perfetto funzionamento del programma, occorre compiere due reset consecutivi della scheda Arduino Esplora, tramite il tasto presente sulla scheda stessa, affinché il programma funzioni correttamente.
Programma robot
Il programma per il robot
denominato Robot_Littlebot_robot.ino
è una
versione più completa di quello già utilizzato per
testare la scheda.
Per il comando del robot sono disponibili i seguenti comandi:i
Lettura tensione batteria;
Lettura temperatura da Sensore LM35
Lettura distanza da sensore GP2D120X;
Lettura luminosità da fotoresistenza;
Emissione di un Beep dal buzzer;
Accensione/spegnimento faro;
Accensione/spegnimento led sul Modulo Arduino Nano
Servo frontale a destra
Servo frontale a sinistra
Servo frontale al centro
Robot avanti
Robot indietro
Robot a SX
Robot a DX
Robot fermo
Trasmette telemetria
I comandi disponibili sono accessibili inviando i seguenti comandi:
b - Legge tensione della batteria
t - Legge temperatura
d - Legge distanza
l - Legge luminosità
s - Emette un “BIP"
k - Accende il faro (se acceso lo spegne)
n - Accende led
m - Spegne led
p -> Servo a DX
i -> Servo a SX
o -> Servo al centro;
8 -> Robot avanti;
2 -> Robot indietro;
4 -> Robot a SX;
6 -> Robot a DX;
0 -> Robot fermo;
q -> Trasmette telemetria;
Se s’invia il comando "h", si avrà l’elenco delle opzioni.
Alcune particolarità del programma
Il programma utilizza una libreria denominata
DistanceGP2Y0A21YK.h scritta da Jeroen Doggen che può essere scaricata al
seguente link
E’ possibile modificare la velocità del robot modificando il valore della
variabile vel che, attualmente, è impostata al valore di 100.
#define vel 100 //velocità dei motori
il valore può variare teoricamente tra 0 e 255 ma se è troppo basso, i motori
non ruoteranno.
Questo perché i motori sono controllati in PWM (Pulse Width
Modulation). Con questo sistema, la velocità del motore non viene
regolata variando la tensione, ma variando il tempo durante il quale, l'intera
tensione di alimentazione viene applicata ai terminali del motore.
Per l’impostazione del modulo bluetooth che in questo caso sarà impostato come
SLAVE, si segue una procedura simile a quella vista per la stazione di
controllo, l’unica variazione è che il comando in questo caso sarà:
Serial.println("SM,0");
che imposta appunto il modulo come Slave.
Ecco in dettaglio la parte di programma:
Serial.begin(115200); //imposta la porta di comunicazione con il modulo Serial.print("$"); Serial.print("$"); Serial.print("$"); delay(100); Serial.println("SM,0"); // Imposta il modulo come slave delay(100); Serial.println("U,9600,N") // Cambia temporaneamente il baudrate // a 9600, no parity delay(100); Serial.println("---"); //Uscita command mode delay(100); Serial.begin(9600); // Reinizializza la seriale bluetooth 9600 |
Nota:
II modulo Bluetooth comunica con Arduino Nano attraverso la porta hardware UART,
la stessa porta è anche utilizzata dall'IDE Arduino per effettuare il download
del firmware.
Esiste quindi, un accesso contemporaneo alla risorsa e chiaramente le due cose
non possono funzionare insieme.
Quando si deve programmare la scheda Arduino NANO, occorre rimuovere il modulo
Bluetooth, effettuare il download, inserire nuovamente il modulo Bluetooth ed
infine accendere la scheda.
Listato programma stazione di controllo
// caricamento librerie #include <SoftwareSerial.h> #include <SPI.h> #include <Esplora.h> #include <TFT.h> //Definizione variabile di servizio int iBattVoltage = 0; int dBattVoltage = 0; char tensione1 [10]; int itemperatura = 0; int dtemperatura = 0; char temperatura1 [10]; char fotocellula1[10]; char distanza1[10]; boolean buttonStates[8]; SoftwareSerial mySerial(11, 3); // Definizione RX, TX per collegamento // Modulo bluetooth /* Questa matrice contiene i nomi dei pulsanti che sono letti. Più tardi, nello sketch, questi nomi saranno usati con il metodo Esplora.readButton (x), dove x è uno di questi pulsanti. */ const byte buttons[] = { JOYSTICK_DOWN, // Indietro JOYSTICK_LEFT, // Sinistra JOYSTICK_UP, // Avanti JOYSTICK_RIGHT,// Destra SWITCH_RIGHT, // Servo destra SWITCH_LEFT, // Servo sinistra SWITCH_UP, // Accende faro SWITCH_DOWN, // Suono }; /* Questo array dice qaule carattere inviare a seconda del tasto premuto. */ const char keystrokes[] = { '2', // Indietro '4', // Sinistra '8', // Avanti '6', // Destra 'i', // Servo DX 'p', // Servo Sx 'k', // Gestione faro 'q' // Bip }; // Impostazione del programma void setup() { Serial.begin(115200); //Imposta il modulo BlueSMiRF SILVER come MASTER //e setta il numera MAC del ricevente slave mySerial.begin(115200); mySerial.print("$"); mySerial.print("$"); mySerial.print("$"); delay(100); mySerial.println("SM,1"); delay(100); //inserire il codice MAC del modulo Slave mySerial.println("C,000666644021"); delay(100); mySerial.println("U,9600,N"); // Cambia temporaneamente il baudrate a 9600, no parity mySerial.println("---"); //Uscita command mode delay (100); mySerial.begin(9600); // Reinizializza la seriale bluetooth 9600 delay (100); //------------------- Esplora.tone(500, 150); mySerial.setTimeout(200); EsploraTFT.begin(); EsploraTFT.background(0,0,0); //sfondo nero EsploraTFT.setTextSize(2); EsploraTFT.stroke(0,255,0); //colore del testo verde EsploraTFT.text("Comando Robot",0,0); EsploraTFT.stroke(255,0,0); //colore del testo rosso EsploraTFT.text("LittleBot",25,25); EsploraTFT.setTextSize(1); EsploraTFT.stroke(255,255,255); //colore del testo bianco EsploraTFT.text("By adrirobot - ver. 1.0",10,45); EsploraTFT.stroke(0,255,255); //colore del testo cyano EsploraTFT.text("JOYSTICK -Direzione",0,80); EsploraTFT.text("SWITCH 1 -Accensione faro",0,90); EsploraTFT.text("SWITCH 2-4-SX-DX Servo",0,100); EsploraTFT.text("SWITCH 3 -Emissione suono",0,110); Esplora.tone(500, 150); delay (2000); //pausa per mostrare i comandi EsploraTFT.stroke(0,0,0); EsploraTFT.fill(0,0,0); EsploraTFT.rect(0,80, 200, 7); //Cancellazione valore EsploraTFT.rect(0,90, 200, 7); EsploraTFT.rect(0,100, 200, 7); EsploraTFT.rect(0,110, 200, 7); EsploraTFT.setTextSize(2); EsploraTFT.stroke(0,255,255); //colore del testo ciano EsploraTFT.text("Telemetria",20,60); EsploraTFT.setTextSize(1); EsploraTFT.stroke(0,255,0); //colore del testo verde EsploraTFT.text("Batteria :",0,90); EsploraTFT.text("Luminosita' :",0,100); EsploraTFT.text("Temperatura :",0,110); EsploraTFT.text("Distanza :",0,120); Esplora.tone(800, 300); } /* Dopo che il setup () è finito, questo codice viene eseguito in modo continuo. Qui controlliamo costantemente lo stato dei pulsanti e del Joystick. */ void loop() // LOOP di lettura tasti e invio carattere { // Lettura pulsanti: for (byte thisButton=0; thisButton<8; thisButton++) { boolean lastState = buttonStates[thisButton]; boolean newState = Esplora.readButton(buttons[thisButton]); if (lastState != newState) { // Il tasto è cambiato! /* La biblioteca Keyboard consente di di riconoscere "pressione" e "rilascio" dei tasti come due azioni distinte. Queste azioni possono essere legati ai pulsanti che stiamo azionando. */ if (newState == PRESSED) { mySerial.print(keystrokes[thisButton]); } else if (newState == RELEASED) { mySerial.print("0"); } } // Memorizza il nuovo stato del pulsante, in modo da poter percepire successivamente la differenza buttonStates[thisButton] = newState; telemetria (); //stampa telemetria su display } delay(50); //Leggera attesa tra un controllo e l'altro. } void telemetria () { while (mySerial.available()>1) { //Lettura valori int BatteryValue = mySerial.parseInt(); int luce = mySerial.parseInt(); int temperatura = mySerial.parseInt(); int distanza = mySerial.parseInt(); int www = mySerial.parseInt();//valore non utilizzato //Preparazione valori per stampa su display //Tensione batteria Robot float fBattVoltage = ((BatteryValue/10.0)-5); iBattVoltage = (int)fBattVoltage; // Unita' valore della tensione dBattVoltage = (fBattVoltage-iBattVoltage)*10; // Decimali valore della tensione sprintf(tensione1,"%d.%d V",iBattVoltage,dBattVoltage); Serial.print("Tensione batteria: "); Serial.println(tensione1); //Valore luminosita' sprintf(fotocellula1,"%d",luce); Serial.print("Valore Luce: "); Serial.println(fotocellula1); //Valore temperatura float ftemperatura = (temperatura/10.0); itemperatura = (int)ftemperatura; // Unita' valore della tensione dtemperatura = (ftemperatura-itemperatura)*10; // Decimali valore della tensione sprintf(temperatura1,"%d.%d C",itemperatura,dtemperatura); Serial.print("Temperatura: "); Serial.println(temperatura1); //Valore distanza // char distanzaStr[5]; //Asseganzione a char sprintf(distanza1,"%d cm",distanza); Serial.print("Distanza: "); Serial.println(distanza1); //Stampa valori su display EsploraTFT.stroke(0,0,0);//colore nero EsploraTFT.fill(0,0,0); EsploraTFT.rect(100,90, 40, 7); //Cancellazione valore EsploraTFT.rect(100,100, 40, 7); EsploraTFT.rect(100,110, 40, 7); EsploraTFT.rect(100,120, 40, 7); EsploraTFT.stroke(255,255,0); //colore del testo giallo EsploraTFT.text(tensione1, 100, 90); EsploraTFT.text(fotocellula1, 100, 100); EsploraTFT.text(temperatura1,100,110); EsploraTFT.text(distanza1,100,120); Esplora.tone(800, 150); // Dati completati } } |
#include <DistanceGP2Y0A21YK.h> //Gestione sensore infrarosso /* Pin Digitali */ #define buzzer 2 #define PWMA 3 #define AIN1 5 #define AIN2 4 #define PWMB 9 #define BIN1 7 #define BIN2 8 #define STBY 6 #define servo_pin 11 #define luce 12 #define ledpin 13 /*Pin analogici*/ #define vbat 1 #define foto 0 #define temp 2 #define sharp 7 /*Definizione variabili*/ #define vel 100 //velocità dei motori int servo1 = 1250; //test servo tilt position (0 to 180) int minPulse1= 600; // posizione minima 0° int maxPulse1= 2400; // posizione massima 180° int turnRate1= 100; // ruota di 10° alla volta int pulseWidth1; // servo pulse width int centerServo1; DistanceGP2Y0A21YK Dist; int distance; int val = 0; //faro void setup() { //Impostazione del modulo bluetooth Serial.begin(115200); //imposta la porta di comunicazione con il modulo Serial.print("$"); Serial.print("$"); Serial.print("$"); delay(100); Serial.println("SM,0"); // Imposta il modulo come slave delay(100); Serial.println("U,9600,N") // Cambia temporaneamente il baudrate // a 9600, no parity delay(100); Serial.println("---"); //Uscita command mode delay(100); Serial.begin(9600); // Reinizializza la seriale bluetooth 9600 delay (200); //Impostazione pin pinMode(PWMA,OUTPUT); pinMode(AIN1,OUTPUT); pinMode(AIN2,OUTPUT); pinMode(PWMB,OUTPUT); pinMode(BIN1,OUTPUT); pinMode(BIN2,OUTPUT); pinMode(STBY,OUTPUT); pinMode(luce, OUTPUT); pinMode(ledpin, OUTPUT); pinMode(servo_pin, OUTPUT); robot_accendi(); servo_center(); Dist.begin(sharp); } void loop() { while (Serial.available() < 1) { } // Attesa sino a quando riceve un carattere char val = Serial.read(); // Legge il carattere dal modulo Bluetooth e lo salva nella variabile val switch(val) // Esegue i comandi in base al carattere ricevuto { case 'p':// Se il carattere ricevuto è 'i' esegue la routine servo a DX servo_dx(); break; case 'i':// Se il carattere ricevuto è 'i' esegue la routine servo a DX servo_sx(); break; case 'o':// Se il carattere ricevuto è 'l' esegue la routine servo al centro servo_center(); break; case '8':// Se il carattere ricevuto è '8' esegue la routine Robot avanti robot_avanti (); break; case '2'://Se il carattere ricevuto è '2' esegue la routine Robot indietro robot_indietro (); break; case '4'://Se il carattere ricevuto è '4' esegue la routine Robot sinistra robot_sinistra (); break; case '6'://Se il carattere ricevuto è '6' esegue la routine Robot destra robot_destra (); break; case 'k'://Se il carattere ricevuto è 'k' Accende/spegene faro frontale faro (); telemetria (); break; case 'l'://Se il carattere ricevuto è 'l' Legge la fotocellula leggi_luce (); break; case 's'://Se il carattere ricevuto è 's' Emette un suono tone (buzzer,500,500); break; case 'q'://Se il carattere ricevuto è 'q' Trasmette i dati dei sensori tone (buzzer,500,500); telemetria(); break; case 't'://Se il carattere ricevuto è 't' Legge temperatura tramite LM35 temperatura (); break; case 'b'://Se il carattere ricevuto è 'b' Legge tensione della batteria batteria (); break; case 'd'://Se il carattere ricevuto è 'd' Legge la distanza di un'oggetto dal sensore distanza (); break; case 'n'://Se il carattere ricevuto è 'n' accende il led di segnalazione led_on (); break; case 'm'://Se il carattere ricevuto è 'm' spegne il led di segnalazione led_off (); break; case '0'://Se il carattere ricevuto è '0' esegue la routine Robot fermo stop(); break; case 'h'://Se il carattere ricevuto è 'h' esegue la routine HELP help(); break; default: stop(); // Ferma il robot break; } } void stop (void) { digitalWrite (AIN1,HIGH); digitalWrite (AIN2,HIGH); analogWrite(PWMA,vel); digitalWrite (BIN1,HIGH); digitalWrite (BIN2,HIGH); analogWrite(PWMB,vel); } void robot_indietro () { digitalWrite (AIN1,HIGH); digitalWrite (AIN2,LOW); analogWrite(PWMA,vel); digitalWrite (BIN1,HIGH); digitalWrite (BIN2,LOW); analogWrite(PWMB,vel); delay (200); } void robot_avanti () { digitalWrite (AIN1,LOW); digitalWrite (AIN2,HIGH); analogWrite(PWMA,vel); digitalWrite (BIN1,LOW); digitalWrite (BIN2,HIGH); analogWrite(PWMB,vel); delay (200); } void robot_destra () { digitalWrite (AIN1,HIGH); digitalWrite (AIN2,LOW); analogWrite(PWMA,vel); digitalWrite (BIN1,LOW); digitalWrite (BIN2,HIGH); analogWrite(PWMB,vel); delay (200); } void robot_sinistra () { digitalWrite (AIN1,LOW); digitalWrite (AIN2,HIGH); analogWrite(PWMA,vel); digitalWrite (BIN1,HIGH); digitalWrite (BIN2,LOW); analogWrite(PWMB,vel); delay (200); } void robot_accendi () { digitalWrite(STBY,HIGH); } void robot_spegni() { digitalWrite(STBY,LOW); } /* Muove il servo a destra*/ void servo_dx() { pulseWidth1 = pulseWidth1 - turnRate1; if (pulseWidth1 < minPulse1) { pulseWidth1 = minPulse1; } digitalWrite(servo_pin, HIGH); delayMicroseconds(pulseWidth1); digitalWrite(servo_pin, LOW); delay(20); } /* Muove il servo a Sinistra*/ void servo_sx() { pulseWidth1 = pulseWidth1 + turnRate1; if (pulseWidth1 > maxPulse1) { pulseWidth1 = maxPulse1; } digitalWrite(servo_pin, HIGH); delayMicroseconds(pulseWidth1); digitalWrite(servo_pin, LOW); delay(20); } /* Posiziona il servo in centro*/ void servo_center() { centerServo1 = maxPulse1 - ((maxPulse1 - minPulse1)/2); pulseWidth1 = centerServo1; digitalWrite(servo_pin, HIGH); delayMicroseconds(pulseWidth1); digitalWrite(servo_pin, LOW); delay(20); } /* Accensione led segnalazione*/ void faro() { if (digitalRead(luce) == HIGH) // il led era acceso? { digitalWrite(luce,LOW); // lo spengo Serial.println("Led spento"); } else // il led era spento { digitalWrite(luce,HIGH); // lo accendo Serial.println("Led acceso"); } } /* Accensione led segnalazione*/ void led_on() { digitalWrite(ledpin, HIGH); // sets the LED on } /* Spegnimento led segnalazione*/ void led_off() { digitalWrite(ledpin, LOW); // sets the LED off } /* Lettura della tensione della batteria*/ void batteria () { float vbatt = (analogRead(vbat)*((readVcc()/1000.0)/1024)); Serial.print("Tensione batteria: "); Serial.print (vbatt,1); Serial.println (" V"); } /* Legge la temperatura */ void temperatura () { /* Lettura sensore */ int reading = analogRead(temp); float voltage = (reading * 5.0) / 1024; int tempC=((voltage - 0.5) * 100)*(-1); Serial.print("Temperatura: "); Serial.print(tempC,1); Serial.println(" gradi C"); } /* Verifica funzionamento fotocellula */ void leggi_luce () { float lettura_foto = analogRead(foto); // lettura grezza dall'adc Serial.print("Valore luce = "); Serial.println(lettura_foto,0); //stampiamo il valore } /* Lettura distanza*/ void distanza() { distance = Dist.getDistanceCentimeter(); Serial.print("Distanza in centimetri: "); Serial.println(distance); } /*Trasmissione telemetria*/ void telemetria() { led_on (); //Preparazione dei valori float vbatt = (analogRead(vbat)*((readVcc()/1000.0)/1024)); int batteria = vbatt*10; int fotocellula = analogRead(foto); // lettura grezza dall'adc int reading = analogRead(temp); float voltage = (reading * 5.0) / 1024; int tempC=((voltage - 0.5) * 100)*(-1); int temperatura = tempC *10; distance = Dist.getDistanceCentimeter(); //Invio valori verso stazione di comando Serial.println (batteria); Serial.println (fotocellula); Serial.println (temperatura); Serial.println (distance); Serial.print ("F"); led_off (); } /* HELP*/ void help() { Serial.print("\nComandi robot "); Serial.print("\nh -> Questo elenco"); Serial.print("\nb -> Tensione della batteria"); Serial.print("\nt -> Temperatura"); Serial.print("\nd -> Legge distanza"); Serial.print("\nl -> Legge luminosita'"); Serial.print("\ns -> Emette un BIP"); Serial.print("\nk -> Accende il faro"); Serial.print("\nj -> Spegne il faro"); Serial.print("\np -> Servo a DX"); Serial.print("\ni -> Servo a SX"); Serial.print("\no -> Servo al centro"); Serial.print("\n8 -> Robot avanti"); Serial.print("\n2 -> Robot indietro"); Serial.print("\n4 -> Robot a SX"); Serial.print("\n6 -> Robot a DX"); Serial.print("\n0 -> Robot fermo"); Serial.print("\nn -> Accende led"); Serial.print("\nm -> Spegne led"); Serial.print("\nq -> Trasmette telemetria"); } /* Routine per rendere la letture ADC più accurata su Arduino tratta dal sito http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/ */ long readVcc() { long result; // Read 1.1V reference against AVcc ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); delay(2); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Convert while (bit_is_set(ADCSRA,ADSC)); result = ADCL; result |= ADCH<<8; result = 1126400L / result; // Back-calculate AVcc in mV return result; } |
Elenco revisioni | |
23/11/2014 | Emissione preliminare |