Con questo articolo vi presento il mio progetto per il Rover 5 della Dagu.
Mauro ha già utilizzato questa piattaforma in abbinamento al controllo remoto WiRC ma io vorrei realizzare la mia versione utilizzando una connessione bluetooth e applicazioni scritte da me.
La scheda scelta è la Leonardo con socket XBee della DFRobot. Si tratta di una Arduino Leonardo con integrato il socket per ospitare i moduli XBee e quindi mi permette di risparmiare un “piano” per gli shield e di poter cambiare in futuro il modulo per la connessione.
Il progetto prevede l’uso di una webcam per la visione remota montata su un servo che permetta l’inclinazione verso l’alto e il basso della camera. La trasmissione del video sarà effettuata con un TP-Link MR3020 opportunamente modificato.
HARDWARE Rover 5 BT
La prima cosa che ho fatto è la sistemazione dei cavi perché il Rover 5 viene consegnato con cavi e connettori piuttosto ingombranti. Ho dato un’occhiata al post di Mauro e fatto le stesse modifiche accorciando i cavi del positivo che vanno dal motore all’induttanza e i cavi del negativo. Per comodità ne ho approfittato per congiungere i cavi dei motori sullo stesso lato. Inoltre, visto che i due lati, se alimentati con la stessa polarità, si muovono in direzioni opposte ho “scambiato” i colori dell’ultimo tratto di cavo di un lato. In questo modo i cavi sono già pronti per il collegamento allo shield senza dovermi preoccupare del loro verso.
La base per tutte le componenti è realizzata da un foglio di plexiglas, economico e facile da lavorare. Ho guadagnato un po’ di spazio in larghezza per alloggiare il pacco batterie fornito con il rover e quello supplementare per servo e router. Inizialmente preferisco avere le alimentazioni a portata di mano per non dover smontare tutto ogni volta che dovrò ricaricare o cambiare le batterie. Una volta terminato farò in modo da ricaricare il rover tramite una presa dedicata e\o utilizzerò batterie LiPo.
Proverò sicuramente a spostare la posizione della Leonardo per poter abbassare il router comunque non ho ancora fissato nulla quindi ogni suggerimento è ben accolto 🙂
SOFTWARE
Lo sketch per Arduino dovrebbe essere piuttosto semplice. Il socket della Leonardo XBee viene visto come una seriale quindi con una opportuna lettura e interpretazione dei comandi ricevuti potrò comandare i motori e il servo.
Nella prima versione non saranno montati accessori ma si può pensare ad un sensore di distanza come “paraurti” nel caso non si veda l’ostatolo davanti o dietro al robot, sensori di temperatura o gps per inviare dati e posizione all’app di comando o programmare un percorso da ripetere, “vibrisse” basate sulle antenne del BeetleBot per evitare di incastrare il rover in spazi troppo bassi, una pinza per afferrare oggetti…
Per quanto riguarda l’applicazione per il comando del robot sono in lizza 3 sistemi diversi: IOS, Android, Windows desktop e mobile
Ognuno ha i suoi pro e contro, vediamo quali sono:
IOS:
PRO: Ampia diffusione di dispositivi tutti uguali, posso pubblicare app sullo store
CONTRO: Sistema operativo blindato e compatibilità con il modulo bluetooth tutta da verificare
Android:
PRO: Sistema operativo più permissivo per il collegamento bluetooth.
CONTRO: Grande varietà di versioni hardware e software in circolazione.
Win desktop:
PRO: L’ambiente di sviluppo lo uso giornalmente per lavoro
CONTRO: Non proprio portatile.
Win mobile:
PRO: L’ambiente di sviluppo e il linguaggio per Windows phone sono fondamentalmente quelli che uso tutti i giorni
CONTRO: Il device di “casa” è della Moglie ^_^
Per ora è tutto, nel prossimo articolo collauderò la comunicazione bluetooth.
8 commenti
Vai al modulo dei commenti
Ciao Mauro, non è la prima volta che ti sento ma quando non so dove sbattere la testa mi dico…. e chiedere a Mauro?
Ti spiego in breve. Devo controllare un brandeggio per antenna satellitare con Arduino Nano, un modulo BT HC-05 impostato a 38400 e un Galaxy S3(Android 4.3). Per i dati inviati dal cellulare, nessun problema, Arduino risponde correttamente, forse perche viene inviata un comando alla volta. Per i dati inviati da Arduino invece io formo un pacchetto (stringa) di 30 caratteri, e precisamente 6 pacchetti da 5 caratteri contenente direzione, elevazione, skew, livello segnale, ecc. (ti allego codice)
strDir = “”; strDir += dirOut; strDir += ” “; strDir = strDir.substring(0,5); // direzione
strElev = “”; strElev += int(elevOut); strElev += ” “; strElev = strElev.substring(0,5); // elevazione
strSkew = “”; strSkew += int(skewOut); strSkew += ” “; strSkew = strSkew.substring(0,5); // skew
strLev = “”; strLev += int(levelSF); strLev += ” “; strLev = strLev.substring(0,5); // livello segnale
strPot = “”; strPot += int(posPot); strPot += ” “; strPot = strPot.substring(0,5); // posizione rotazione
strOS = “”; strOS += int(oldState); strOS += ” “; strOS = strOS.substring(0,5); // stato manuale/autom.
stringBT =”” + strDir + strElev + strSkew + strLev + strPot + strOS ; // lunghezza stringa 30 caratteri
mySerial.print(stringBT); // invia dati alla Seriale BT
Questa stringa, viene divisa in ricezione nuovamente in 6 pacchetti per inserire i dati nelle rispattive label.
Il problema è che alla connessione del BT, non sempre i dati sono nell’ordine giusto in quanto mi arrivano proprio mischiati da Arduino. Come si può fare per inviare o ricevere i dati rigorosamente in ordine?
Anche perchè se la trasmissione si avvia correttamente, e questo succede sempre dal secondo tentativo, poi funziona tutto benissimo.
Spero di essermi spiegato e che tu mi possa aiutare oppure indicare qualcuno che tratti l’argomento.
Grazie, Domenico.
Ciao, inizio a risponderti io…
Che valori possono assumere le variabili dirOut, elevOut ecc?
Il codice del commento viene formattato e sembra esserci solo uno spazio ma effettivamente ne hai messi 5.
Comunque la prima assegnazione a vuoto e la successiva concatenazione puoi evitarla valorizzando subito la variabile stringa così:
strDir=dirOut + ” “; // tra le virgolette ci sono 5 spazi
strDir=strDir.substring(0,5);
Per evitare problemi con la larghezza fissa potresti concatenare i valori separandoli con caratteri come : e ; creando una stringa con anche i nomi dei valori
stringBT =”dir:” + dirOut + “;elev:”+elevOut+”;” // aggiungi gli parametri
Quindi su android puoi dividere la stringa in vettori con il metodo split. Prima per ; ottenendo le coppie nome:valore e quindi per :
In questo modo non ti devi nemmeno preoccupare dell’ordine in cui le ricevi.
Ciao Bruno, velocissimo !!!
Allora dirOut(0/359), elevOut(90/10), Skew(-10/+10), levelSF(0/100), posPot(0/359), oldState(1/0).
Gli spazi sono 5 anche se 4 bastavano.
Ti ringrazio per i suggerimenti, più tardi, mi studio cosa mi hai detto, provo e ti faccio sapere.
Ottimizzazione del codice a parte, non capisco perche una volta funzionava bene, poi, forse causa il cambiamento dei valori di delay() dopo l’ invio dei dati è iniziato il difetto.
Dopo mySerial.print(stringBT); ho messo dalay(100), la seriale è il BT HC_05 sono impostati a 38400 ma anche provando valori più alti, a parte il rallentamento dei comandi, non cambia niente.
Per ora, Grazie.
Come mai usi la delay?
Se è per attendere l’invio dei dati credo convenga usare il metodo flush così da attendere l’effettivo invio di tutta la stringa.
Ciao Bruno, ho provato come mi hai detto tu, ecco il codice e i risultati
strDir = String(dirOut) + ” “; strDir = strDir.substring(0,5); // 5 spazi tra virgolette
strElev = String(int(elevOut)) + ” “; strElev = strElev.substring(0,5);
strSkew = String(int(skewOut)) + ” “; strSkew = strSkew.substring(0,5);
strLev = String(int(levelSF)) + ” “; strLev = strLev.substring(0,5);
strPot = String(int(posPot)) + ” “; strPot = strPot.substring(0,5);
strOS = String(int(oldState)) + ” “; strOS = strOS.substring(0,5);
/*
stringBT = “dir:” + String(dirOut) + “;elev:” + String(int(elevOut)) + “;skew:” ;
stringBT = stringBT + String(int(skewOut)) + “;lev:” + String(int(levelSF)) + “;pot:” ;
stringBT = stringBT + String(int(posPot)) + “;state:” + String(int(oldState)) ;
*/
stringBT = strDir + strElev + strSkew + strLev + strPot + strOS ; // lunghezza stringa 30 caratteri
mySerial.print(stringBT); // invia dati alla Seriale BT
//Serial.print(“stringBT = “);
//Serial.println(stringBT);
//Serial.println(” “);
delay(150); // ritardo 150 ms. (necessario, importante !!!)
questo il risultato e va bene: (i punti sono spazi)
stringBT = 321..52…0….2….182..0
questo il risultato del codice commentato e mi andrebbe benissimo, devo solo capire come splittare la stringa in arrivo. Io non mastico Java e il programma per il cellulare l’ho fatto con MitAppinventor2 (roba da bambini…puzzle). Vedrò di documentarmi, se hai qualche guida, tutorial o simili (possibilmente in italiano), mi farebbe comodo.
stringBT = dir:320;elev:53;skew:0;lev:2;pot:183;state:0
Il delay(150) dopo il mySerial.print, se lo tolgo, sul cellulare non ricevo più nulla. Il metodo flush, pensavo servisse a svuotare il buffer e tra l’altro sembra che sulla IDE 1.0… non funzioni, infatti vedo che per svuotarlo, invece di Serial.flush(), usano questo sistema.
< codice rimosso in automatico >
ma secondo me non funziona neanche questo, ho provato ad inserire il codice prima del mySerial.print senza riscontrare nessun cambiamento, ma forse sbaglio qualcosa io oppure il buffer non c’entra nulla.
Se risolvo, ti faccio sapere, ciao e grazie.
La flush, con l’ultima ide, dovrebbe far attendere il codice arduino fino a quando la trasmissione non è completa e quindi potresti eliminare la delay.
Ho sbirciato il sistema MIT App Inventor e c’è una split. A naso selezionando split at any potresti ottenere le coppie…ma non riesco ad attaccare il blocco stringa ^_^
Allora… ho provato a mettere mySerial.flush() dopo l’invio delle stringa, come da tua indicazione e come spiegato nella documentazione della IDE 1.05 ma inchioda tutto, sul Galaxy i valori che arrivano non cambiano più, oppure girano all’impazzata. Ho quindi rimesso il delay(150) che al 90% delle volte parte bene e poi non dà problemi. Ho provato anche a mettere flush e dopo delay e sembra che flush non serva a niente.
Ho visto che nel Text blocks di AppInventor c’è l’occorrente per la gestione delle stringhe e proverò. Ne approfitto per chiederti un’altra cosa. Mi piacerebbe che all’avvio dell’applicazione Android il display rimanesse sempre acceso (come succede per il navigatore) e venisse avviato il GPS per poi disattivare tutto all’uscita ma non so se si può fare e quali istruzioni dare.
Sei l’unica mia speranza, ciao, Domenico.
Non ho idea se quel sistema permetta di lavorare con il gps, i dati iniziano ad essere più complessi viste che normalmente si ottiene un oggetto con le proprie proprietà e non semplici numeri e stringhe. Prova a cercare dei tutorial.