Quando si fa un particolare lavoro delle volte può essere necessario essere rintracciabili,
ma quando, per motivi personali, non si vuole fornire il proprio
numero telefonico, che fare? Ci sono due possibilità; o il chiamante
alza la voce sperando che il chiamato sia nelle immediate vicinanze o utilizzare un ricetrasmettitore. Quest'ultimo
potrebbe essere costituito da una semplice coppia di portatili con i
quali si potrebbe instaurare un dialogo tra il chiamato ed il
chiamante, delle volte, però, tale possibilità non serve, nel mio
caso, ad esempio, per il lavoro che faccio (portiere
condominiale) non occorre comunicare vocalmente con chi mi chiama ma
serve recarmi sul posto per aprire semplicemente un cancello (ad
esempio al postino o al corriere) dopo avere visto di persona chi è
dall'altra parte. D'altronde non potrei usare i
portatili data la sconvenienza di lasciarli fuori del
condominio a vista di tutti...anche di male intenzionati che
potrebbero farci un pensierino. Quindi servirebbe qualcosa che non
dia all'occhio stimolando appetiti illegali. Questo qualcosa dovrebbe
essere dotato di un pulsante, di un led e di un buzzer, il tutto racchiuso in
una scatoletta non eccessivamente attraente (ho usato una canalina 40 X 25). Sarebbe anche il caso di
poter rendere questa scatoletta staccabile dal posto dove si trova per
portarla in guardiola una volta finito il lavoro per poi riattaccarla
la mattina successiva quando riinizia il lavoro (ad essa ho attaccato una calamita per tale scopo).
Il
sistema è composto da un RTX fisso (fuori dal cancello) e un RTX
mobile attaccato alla mia cintura. I due apparecchi funzionano
sia come TX che come RX cambiando il modo di funzionamento
automaticamente in fase di comunicazione, infatti quando si preme il
tasto sull'RTX fisso quest'ultimo va in trasmissione (TX)
inviando
una messaggio (più altri dati del tipo, indirizzo, bit di controllo,
etc, etc...) all'RTX mobile, subito dopo avere trasmesso questi dati commuta
automaticamente in RX e aspetta il segnale di riconoscimento
(ACK) dall'RTX mobile che a riposo è sempre in fase di
ascolto (RX), appena l'RTX mobile riceve il messaggio fa una serie di
controlli su di esso (sull'integrità dei dati, indirizzo, etc, etc...), se tutto
va bene commuta in TX e invia all'RTX fisso il suddetto segnale di
riconoscimento (ACK), subito dopo ritorna in RX.
Come
ho scritto prima questa
commutazione avviene in maniera automatica grazie ai protocolli interni
al nRF24L01, non occorre quindi che inseriamo nel programma
istruzioni per far commutare i due moduli una volta in RX e poi in TX
all'occorrenza, si potrebbe fare ma sarebbe un inutile spreco di tempo
(e di energia della batteria).
Cominciamo ora ad analizzare il software dell'RTX fisso.
PROGRAMMA RTX FISSO
#include<SPI.h>
#include<nRF24L01.h>
#include<RF24.h>
int msg[1] = {};
RF24 radio(9,10);
const uint64_t pipe[1] = {0xF0F0F0F0E1};
void setup()
{
pinMode(2, INPUT_PULLUP);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
radio.begin();
digitalWrite(3, HIGH);
delay(500);
digitalWrite(3, LOW);
radio.enableAckPayload();
radio.enableDynamicPayloads();
radio.openWritingPipe(pipe[0]);
radio.setDataRate(RF24_250KBPS);
radio.stopListening();
}
void loop()
{
if(digitalRead(2) == 0)
{
while(!radio.write(msg,sizeof(msg)));
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
delay(500);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
}
#include<SPI.h>#include<nRF24L01.h>#include<RF24.h>Le tre librerie che servono per il corretto funzionamento.
int msg[1] = {}; Questo
è un array di tipo int, viene usato dall'RTX fisso per
inviare un messaggio al mobile, attenzione, non occorre che
l'array contenga un valore, l'importante è che l'RTX fisso invii
qualcosa per far fare
qualche altra cosa all'RTX mobile, può essere, quindi, anche
vuoto (in questo programma ovviamente).
RF24 radio(9,10); Con
questa istruzione si crea l'oggetto "radio" e si assegnano i pin CE e
CSS del modulo nRF24L01 ai pin di arduino nano ( nel mio caso CE = pin 9, CSS
pin 10).
const uint64_t pipe[1] = {0xF0F0F0F0E1}; Questo
è l'indirizzo, esso deve essere lo stesso sia per RTX fisso che
per quello mobile, possono essere usati , valori interi,
esadecimali e caratteri, l'importante che non siano più di 5 byte. Attenzione
non usare valori che diano in binario serie di "uni" o di "zeri"
continui (11111111 o 00000000) perché il ricevitore potrebbe interpretarli come noise. Non
devono essere neanche del tipo "01010101"...perché il ricevitore
potrebbe interpretarli come un proseguimento del preambolo (una serie
di "serie" ed "uno" alternati che servono per sincronizzare i dati).
Per questo motivo sono stati usati gli esadecimali F0 (11110000).
pinMode(2, INPUT_PULLUP);pinMode(3, OUTPUT); pinMode(4, OUTPUT);Predispone il pin 2 come ingresso con PULLUP (tasto)
Predispone il pin 3 come uscita (LED)
Predispone il pin 4 come uscita (BUZZER)
radio.begin();Attivazione modulo nRF24L01
digitalWrite(3, HIGH);delay(500); digitalWrite(3, LOW); Queste tre istruzioni servono per far lampeggiare il LED per 500mS e per dare una pausa tra
radio.begin(); e le successive istruzioni
radio.enableAckPayload();Questa
istruzione abilita il riconoscimento automatico (ACK), ne ho scritto all'inizio.
radio.enableDynamicPayloads();Questa funzione trasmette solo i byte necessari
, se non fosse presente questa funzione il TX trasmetterebbe 32 byte
fissi indipendentemente da quelli presenti nell'array. Funzione utile
per abbreviare i tempi di trasmissione dati.
radio.openWritingPipe(pipe[0]);Usa l'indirizzo precedentemente scritto nell'array
pipe[] per la trasmissione.
radio.setDataRate(RF24_250KBPS);
Velocità
dei dati (baud rate), più è bassa e maggiore è la sensibilità del
ricevitore (e quindi maggiore è la distanza di collegamento
raggiungibile). l'ho impostata al minimo.
radio.stopListening();Predispone il modulo nRF24L01 per trasmettere
if(digitalRead(2) == 0)Se il tasto è premuto viene eseguito il corpo della "if".
while(!radio.write(msg,sizeof(msg))); L'istruzione
radio.write(msg,sizeof(msg)) invia il dato contenuto nell'array
msg[] all'RTX
mobile, l'RTX fisso si pone poi in RX e aspetta l'ACK, quando lo riceve
la funzione restituisce un TRUE e il programma esce da "while" e
salta all'istruzione successiva.
Se
l'RTX mobile è fuori campo l'RTX fisso seguita a inviare il dato
tramite la "while" in attesa del riconoscimento. In questo modo l'RTX
mobile non perderà mai una chiamata anche quando è fuori campo, semmai la
riceverà in ritardo (quando tornerà ad essere raggiungibile).
digitalWrite(3, HIGH); digitalWrite(4, HIGH); delay(500);
digitalWrite(3, LOW); digitalWrite(4, LOW); Illumina il LED e attiva il BUZZER per 500 mS per indicare al chiamante che la chiamata è stata ricevuta dall'RTX mobile.
PROGRAMMA RTX MOBILE
#include<SPI.h>
#include<nRF24L01.h>
#include<RF24.h>
const uint64_t pipe[1] = {0xF0F0F0F0E1};
RF24 radio(9,10); // radio(pin CE, pin CSN)
int rec[1] = {};
void setup()
{
pinMode(2, OUTPUT);
pinMode(4, OUTPUT);
pinMode(3, INPUT_PULLUP);
radio.begin();
digitalWrite(2, HIGH);
delay(500);
digitalWrite(2, LOW);
radio.enableAckPayload();
radio.enableDynamicPayloads();
radio.openReadingPipe(1,pipe[0]);
radio.setDataRate(RF24_250KBPS);
radio.startListening();
}
void loop()
{
if(radio.available())
{
radio.read(rec,sizeof(rec));
digitalWrite(2, HIGH);
digitalWrite(4, HIGH);
delay(1000);
digitalWrite(2, LOW);
digitalWrite(4, LOW);
}
}
Questa volta spiegherò solo le istruzioni che differiscono da quelle per il RTX fisso.
pinMode(2, OUTPUT); pinMode(4, OUTPUT); Predispone il pin 2 come uscita (LED)
Predispone il pin 4 come uscita (BUZZER)
radio.openReadingPipe(1,pipe[0]);Usa l'indirizzo precedentemente scritto nell'array
pipe[] per la ricezione.
radio.startListening(); Predispone il modulo nRF24L01 per ricevere.
if(radio.available())Se arriva una dato viene eseguito il corpo della "if".
radio.read(rec,sizeof(rec));Legge il dato e lo memorizza nell'array
rec[],
anche se in questo programma il dato non contiene nulla occorre sempre
chiamare questa funzione per svuotare il registro FIFO del nRF24L01, se
non la si chiamasse il programma eseguirebbe il corpo della "if"
indefinitamente.
digitalWrite(2, HIGH); digitalWrite(4, HIGH);delay(1000); digitalWrite(2, LOW);digitalWrite(4, LOW);Si illumina il led ed emette un suono per 1S, sufficiente per avvertire che qualcuno ha chiamato.
COLLEGAMENTI
NOTE CONCLUSIVE
Questo sistema di comunicazione è molto affidabile grazie al protocollo interno dell'nRF24L01
che gestisce l'intero processo di trasmissione, di ricezione del dato
e relativo riconoscimento. Questa gestione automatica elimina
tutti quei processi necessari per effettuare le stesse operazioni con
il programma, questo alleggerisce il lavoro del programmatore ma
soprattutto diminuisce la corrente media consumata dal sistema.
Per consumare ulteriormente di meno consiglio di togliere il LED "on" sito
sulla scheda arduino, esso, stando internamente al contenitore, non è
visibile e quindi non serve se non a consumare energia.
Sempre
in tema di energia consiglio di usare un accumulatore a 9V
ricaricabile tramite USB di capacità 1000 mAH, la carica dura
tantissimo. Fate un buco quadrato sul contenitore che userete per
accedere facilmente al connettore della batteria senza togliere
il coperchio. Stessa cosa vale per il connettore di Arduino per la
programmazione.
I
due condensatori da 10 uF debbono essere saldati il più vicino
possibile ai pad di ingresso della tensione VIN di Arduino e della
tensione a 3.3 V del modulo nRF24L01 (nel disegno sono posti distanti
dai suddetti pad solo per questioni di leggibilità dello schema).
Questi condensatori eliminano disturbi creati sull'alimentazioni dalle
emissioni elettromagnetiche, sono molto importanti, senza di essi
questi segnali immessi sull'alimentazione possono resettare arduino o
al limite abbassare la potenza di trasmissione. Tra le altre cose
andando avanti con l'utilizzo dei due RTX si è evidenziato un fenomeno
anomalo sulla durata degli accumulatori da 9V che ho pensato
fosse dovuto a un difetto della ricarica o a un malfunzionamento degli
accumulatori. A tempi più o meno regolari gli accumulatori o duravano
tre giorni o una sola mattinata alternandosi tra loro in questa strana
manifestazione. Poi ho messo il condensatore sui pad della VIN di
Arduino e il fenomeno è scomparso, in media ora durano tre giorni.
Ipotizzo che quei disturbi sulla alimentazione siano i responsabili di
tale comportamento strano.
La distanza
massima raggiungibile dipende fortemente dai vari ostacoli che si
interpongono tra i due RTX (in particolare se sono conduttivi;
tubi, cavi elettrici, cancelli di metallo), ho fatto delle prove sia in
ambiente chiuso che in campo libero. Per ambiente chiuso intendo una
casa, un garage, insomma un posto dove vi siano molti muri, cavi e
altri oggetti metallici. In particolare ho posto l'RTX fisso al 5^
piano del mio condominio e sono sceso con l'RTX mobile per vedere fin
dove riceveva il segnale. Il mobile è riuscito a ricevere fino al 2
piano, essendo ogni piano alto 3 metri circa, in totale la massima
distanza raggiunta è stata pari a 12 metri. Poi ho fatto delle prove in
garage, ho posto l'RTX fisso in cantina e sono uscito con il
mobile. Gli ostacoli tra i due RTX erano: un muro e una porta
metallica, in questa esperienza la massima distanza raggiunta è
stata di 20 metri.
Per le prove in campo aperto sono andato al parco
e ho scelto un posto dove non vi era nulla tra i due RTX (neppure
alberi), cioè, i due RTX erano a vista, la distanza massima
raggiungibile è stata di 700 metri (misurata con GPS).
Se volete
aumentare notevolmente queste distanze dovete usare una antenna esterna
per l'RTX fisso. Quella che ho usato io è bibanda (2.4 GHz, 5.8 GHz) a
base magnetica di quelle che si usano per la videosorveglianza. Dalla
foto si notano le due bobine facenti parte delle trappole per l'accordo
alle due frequenze.
L'antenna suddetta risuona a 1/2
onda, con questa antenna si possono usare piani di massa estesi e
la si può posizionare in punti alti (la vendono con tre metri di
filo) rendendo il collegamento più efficiente rispetto a quello che si
ottiene con lo stilo che forniscono con il modulo nRF24L01 (dove
l'altro braccio del dipolo è costituito dal solo piano di massa delle schede).
Usando questa antenna i risultati sono i seguenti.
Nel condominio l'RTX è arrivato a ricevere fino al piano -1 (18 metri).
In garage l'RTX è arrivato a ricevere fino a 45 metri.
Nel parco l'RTX è arrivato a ricevere fino a 1 km circa.
Per questo modulo è stata creata una libreria con molte funzioni,
qui troverete la spiegazione per ognuna di esse..
Qui i due programmi TX_RF_24_11 (RTX fisso), RX_RF_24_11 (RTX mobile).
Ciao
Fabio