Nella puntata precedente abbiamo configurato due moduli XBee con l’aiuto di X-CTU, Arduino e un saldatore. Ora è tempo di farli parlare!
La configurazione attuale sfrutterà XBee come fosse un collegamento via cavo (sfrutteremo, in sostanza, le funzionalità di modem del modulo): i due Arduino potranno scambiarsi informazioni via radio con la stessa semplicità di un collegamento ‘fisico’. In questo primo esempio la comunicazione sarà punto a punto: lasceremo le tecniche di broadcasting al test successivo.
Con chi vuoi parlare?
A questo punto, qualche informazione sul sistema di indirizzi del protocollo ZigBee è d’obbligo. In realtà, a voler fare i puristi, dovremmo dire che il layer di indirizzamento di basso livello o MAC, Medium Access Control, fa parte dello stadard IEEE 802.14.4, mentre ZigBee costituisce uno stack costruito al di sopra di tale standard, ma siccome l’importante è che funzioni….who cares! Detto questo, ogni modulo possiede:
- un indirizzo esteso a 64 bit (extended address), analogo al MAC address di una scheda di rete. Non esistono (almeno in teoria) due moduli con lo stesso indirizzo esteso;
- un indirizzo di rete a 16 bit (network address), assegnato dal coordinatore nel momento in cui il modulo viene associato ad una rete e che è univoco solo all’interno della rete stessa.
- un nome descrittivo (node identifier), non obbligatorio, che può essere assegnato manualmente per facilitare l’identificazione di ciascun nodo. Ovviamente non c’è alcuna garanzia di univocità.
Esiste poi un ulteriore parametro di indirizzamento, chiamato Personal Area Network (PAN) ID di 64 bit che sarà inizializzato con un codice numerico che identifichi la rete a cui il modulo stesso si potrà associare. Due (o più) moduli si potranno parlare tra loro solo se appartenenti alla stessa rete, ovvero solo se configurati con lo stesso PAN ID.
Ci sarebbe infine un ultimo (inteso come più basso) livello, puramente fisico, che è il canale: prima ancora di parlare di indirizzi è necessario che all’interno di una rete venga utilizzata la medesima frequenza di trasmissione per tutti i moduli. Il coordinatore, nel momento in cui si attiva per la creazione della rete, identifica autonomamente un canale (ovvero una frequenza) che dovrà essere utilizzata da tutta la rete. Dal momento che tutto ciò avviene senza che sia necessario il nostro intervento, faremo allegramente finta di dimenticarcene.
Ma, in pratica, di tutti questi parametri di indirizzamento, cosa è davvero importante?
Nel nostro primo test, visto che la comunicazione avverrà da punto a punto, ogni nodo dovrà conoscere quale è il nodo verso cui indirizzare la comunicazione, quindi ciascun modulo dovrà avere lo stesso PAN ID e dovrà conoscere l’indirizzo del modulo ‘ricevente’. Nel paragrafo successivo vedremo come ottenere tutto ciò.
Si inizia a capirci qualcosa
Il primissimo esperimento ha come obiettivo la verifica che effettivamente i due moduli si parlino. Condizione di partenza:
- un primo modulo configurato come coordinatore collegato con una scheda Arduino secondo lo schema visto nella puntata precedente (Arduino deve essere inizializato con uno sketch vuoto, come già visto);
- un secondo modulo configurato come router anch’esso collegato con una seconda scheda Arduino nel medesimo modo.
Le due schede Arduino potranno essere collegate allo stesso PC (o a due PC differenti) via USB nella maniera consueta (se avete dubbi su installazione e collegamenti, il sito di Arduino è molto chiaro ed esauriente).
I moduli andranno prima di tutto configurati con gli indirizzi corretti, poi si potrà controllare che effettivamente comunichino utilizzando due emulatori di terminale collegati ciascuno ad una delle porte seriali a cui è collegato un Arduino: ciò che scriveremo in un emulatore apparirà sull’altro e viceversa. Una chat, insomma! Come visto, in questo caso Arduino avrà un ruolo assolutamente passivo. Nella prova successiva faremo invece parlare gli Arduino tra loro.
Come emulatore, nell’esempio seguente ho scelto CoolTerm, semplice e completo. Volendo si può usare lo stesso X-CTU, aprendo il tab ‘Terminal’.
Qualunque sia il programma scelto, dovrete impostare la connessione con questi parametri (solitamente il default):
- Porta: la seriale a cui è collegato l’Arduino con cui volete parlare;
- Baud: 9600
- Data bits: 8
- Parity: none
- Flow Control: none
Quella che segue è la finestra di dialogo dei parametri di CoolTerm utilizzata per connettermi all’Arduino collegato a COM3. Una nota: CoolTerm di default disabilita il ”local echo”, vale a dire che qualunque input da tastiera viene inviato alla seriale ma non è visualizato a video, per vedere ciò che scrivete dovete selezionare la casella ‘Local Echo’ nel tab Terminal della finestra di configurazione.
Una volta stabilita la connessione (in CoolTerm cliccare sul bottone ‘Connect’ presente nella barra in alto) provate a digitare:
+++
senza aggiungere nulla, nemmeno un ‘invio’: se è tutto a posto dopo un secondo (non è un modo dire, dovrete attendere veramente un sessantesimo di minuto) dovreste vedere comparire ‘OK’ seguito da un ritorno a capo:
+++OK
Cosa è successo? Qui ci vuole un altro piccolo approfondimento….
AT, ovvero come ti comando il modulo
Ogni modulo XBee può interpretare in due modi ciò che gli viene comunicato: come qualcosa da trasmettere (modalità ‘dati’) o come un comando diretto al modulo stesso (modalità ‘comandi’). All’accensione il modulo si attiva in modalità dati, il passaggio alla modalità comandi avviene quando viene trasmessa al modulo la stringa ‘+++’, preceduta e seguita da almeno un secondo di silenzio (sequenza di escape). Al riconoscimento di questo input, XBee cambierà modalità ed interpreterà tutto ciò che segue come un’istruzione da eseguire fino al ritorno alla modalità dati, cosa che avverrà in maniera automatica dopo 10 secondi di silenzio (o dopo che è stato dato il comando di abbandono modalità comandi). La modalità comandi permette la gestione di tutte le funzionalità del modulo, dalla configurazione degli indirizzi (che vedremo tra un momento) alla gestione dell’energia al campionamento degli input digitali o analogici dei sensori collegati. I comandi sono costituito da una stringa di testo avente sempre la stessa sintassi:
AT[due lettere][eventuale spazio][eventuale parametro in esadecimale] (invio).
Tutto ciò suona familiare? In effetti lo è: stiamo usando XBee come modem e i comandi di gestione si rifanno, in pratica, allo standard introdotto da Hayes all’inizio degli anni ’80 per i primi modem a larga diffusione.
Utilizzeremo alcuni comandi AT per configurare i moduli:
- ATID : senza parametro visualizza il PAN address impostato, altrimenti imposta il PAN address al valore passato. Il range di validità va da 0x0 a oxFFFF (il che, in termini decimali, significa da 0 a 65535).
- ATSH : visualizza i primi 4 bytes (Serial High) dell’indirizzo fisico del modulo stesso. Non accetta parametri, in quanto non è modificabile.
- ATSL : visualizza i secondi 4 bytes (Serial Low) dell’indirizzo fisico del modulo stesso. Non accetta parametri, in quanto non è modificabile.
- ATDH : senza parametro visualizza i primi 4 bytes (Destination High) dell’indirizzo fisico del modulo di destinazione attualmente impostato, altrimenti imposta i bytes con il valore ricevuto in input. Valori ammissibili: 0x0 – 0xFFFFFFFF.
- ATDL : senza parametro visualizza i secondi 4 bytes (Destination Low) dell’indirizzo fisico del modulo di destinazione attualmente impostato, altrimenti imposta i bytes con il valore ricevuto in input. Valori ammissibili: 0x0 – 0xFFFFFFFF.
- ATWR : scrive sul modulo la configurazione impostata, in modo che non venga eliminata una volta tolta l’alimentazione.
- ATMY : visualizza l’indirizzo di rete a 16 bit assegnato dal coordinatore. Non può essere modificato (almeno sulla serie 2).
- ATNI : senza parametri visualizza l’identificativo del nodo, altrimenti imposta l’identificativo con il valore ricevuto in input. E’ ammessa qualunque sequenza di max 20 caratteri ASCII.
- ATCN : abbandona la modalità comandi e torna in modalità dati.
Su ciascun modulo dovremo assegnare PAN ID, DH (Destination High, ovvero i primi 4 byte dell’indirizzo esteso del modulo di destinazione) e DL (Destination Low, ovvero i successivi 4 bytes dell’indirizzo esteso del modulo di destinazione) ma mentre PAN ID può essere scelto arbitrariamente gli altri indirizzi devono essere coerenti tra i due moduli: il primo passo consisterà quindi nel leggere qual’è l’indirizzo esteso di ciascun modulo, diviso anch’esso in due parti (Serial High e Serial Low).
E ora….chattiamo!
Iniziamo dal coordinatore: nella finestra di CoolTerm ad esso associato (sul mio PC è quello collegato a COM4) basterà digitare
+++
ed attendere l’OK per entrare in modalità comandi ;
ATSH
per leggere il Serial High e
ATSL
per leggere il Serial Low.
L’intera ‘conversazione’ avrà l’aspetto seguente (ovviamente gli indirizzi sono quelli dei miei moduli, per altri i valori saranno diversi):
+++OK atsh 13A200 atsl 408A8669
quindi in questo caso SH è uguale a 13A200 e SL a 408A8669. Ripetendo la stessa procedura sulla finestra di CoolTerm collegata al router (COM3 sul mio PC) leggo che, per il router, SH è 13A200 e SL è 408A87BD.
Ciascuna coppia di indirizzi di un modulo andrà impostata sull’altro come indirizzo di destinazione. Partiamo dal coordinatore: nella solita finestra di CoolTerm collegata a COM4 andrà scritto:
+++
per entrare in modalità comandi, dopo aver ricevuto l’OK
ATDH 13A200
per impostare il Destination High con il Serial High del router e
ATDL 408A87BD
per impostare il Destination Low con il Serial Low del router.
Anche in questo caso la conversazione completa sarà qualcosa come:
+++OK atdl 408A87BD OK atdh 13A200 OK
La stessa procedura va eseguita sul router per impostare gli indirizzi del coordinatore come indirizzi di destinazione.
Resta da assegnare il PAN ID: basta scegliere un id da scrivere su ciascun modulo con il comando ATID (in questo caso 1974):
+++OK atid 1974 OK
Se è tutto a posto, i due moduli dovranno avere la configurazione seguente:
Coordinatore | Router | |
PAN ID | 1974 | 1974 |
Serial High | 13A200 | 13A200 |
Serial Low | 408A8669 | 408A87BD |
Destination High | 13A200 | 13A200 |
Destination Low | 408A87BD | 408A8669 |
Come detto, i valori sono riferiti ai miei moduli ed in un caso diverso saranno sicuramente differenti. l’importante è che:
- PAN ID coordinatore = PAN ID router;
- DH coordinatore = SH router
- DL coordinatore = SL router;
- DH router= SH coordinatore
- DL router= SL coordinatore.
Ora non resta che provare! Basterà attendere 10 secondi per essere certi che entrambi i moduli siano tornati in modalità dati e poi scrivere qualcosa nella finestra di CoolTerm di uno dei due per vederlo comparire in quello dell’altro.
E se non funziona?
- controllate cavi e collegamenti
- assicuratevi che sugli Arduino siano stati caricati degli sketch vuoti;
- assicuratevi che tutti i parametri siano stati configurati correttamente
- ehm…..dormiteci sopra: a mente fresca sarete in grado di capire più facilmente dove sta il problema.
E per finire, come ogni buon serial, qualche anticipazione sulla prossima puntata: finalmente Arduino farà qualcosa, giocheremo con i LED e si faranno comizi!
(La prima puntata di questo sproloquio è disponibile qui).
Pingback: Arduino, ZigBee e le infinite possibilità (3) | The Monday Morning Tech Newsletter
Pingback: Arduino, ZigBee e le infinite possibilità (5) | The Monday Morning Tech Newsletter
Wow, 6 anni… però ci sono con una domanda.
Ultimamente con la domotica e i vari componenti lo zigbee sta tornando di moda (lo era già), ma mi sorge una domanda: mettiamo che ho un arduino con un xbee configurato come coordinatore e un componente zigbee a se stante, come faccio a metterli in comunicazione se non hanno lo stesso pan id?
Ciao Giancarlo, è passato un po’ di tempo, ti dico quel che mi ricordo…
Il PAN ID può essere configurato manualmente (come nel caso dei test che ho riportato nel mio articoletto) oppure essere lasciato a 0 (ID=0) sia sul coordinatore che su qualunque altro dispositivo. Questo genera (in sintesi) il comportamento seguente:
Il coordinatore: esegue una scansione per eventuali PAN ID già presenti e per creare la rete ne imposta uno che non sia in già utilizzato;
Il dispositivo: esegue una scansione (questo in ogni caso) e cerca di associarsi alla prima rete che individua. Non è detto che ciò sia possibile: il coordinatore potrà permettere o meno la join in base alla propria configurazione.
Occhio però che, stando alla documentazione (non ho eseguito test), il PAN ID è un dato che viene mantenuto anche in caso di power cycle, è necessario reimpostarlo in maniera esplicita: sulle mie schedine si può fare via comandi AT oppure via frame API, se stai lavorando in API mode, su altri tipi di dispositivo non saprei….
Qui trovi il manuale d’uso degli xbee, ovvero La Bibbia per questo tipo di esperimenti: https://www.digi.com/resources/documentation/digidocs/pdfs/90000976.pdf