Comunicazione nRF24l01 in movimento

Buongiorno,

Inizio descrivendo il problema:
Per un evento dobbiamo realizzare un sistema di cronometraggio su una pista di kart (8 kart gareggeranno contemporaneamente), sulla pista sono presenti delle bande magnetiche ed ogni volta che il kart passa su una di queste un contatto reed a bordo si chiude, conclude la misura dell'intertempo precedente e inizia la misura del successivo.
A bordo è presente un Arduino che esegue il cronometraggio e stampa su un display i vari tempi, inoltre ogni kart deve avere una ricetrasmittente RF che al passaggio sulla finish line trasmetta i tempi ad un altro arduino a terra che poi si occuperà di elaborare i dati e creare una classifica.
La comunicazione deve essere veloce in quanto i dispositivi rimangono in contatto radio per tempi di qualche secondo e per tale motivo abbiamo escluso comunicazioni di tipo Wi-Fi e Bluetooth.
Le due alternative che ci sembrano plausibili sono:
-moduli RF24l01, due riceventi collegate all'arduino sulla finish line in modo da poter gestire tutte e otto le trasmittenti.
-moduli GMS/GPRS montati su ogni kart e trasmissione via rete cellulare (SMS o internet).

Riguardo ai moduli nRF24l01 i dubbi erano due:
-la loro affidabilità e versatilità in condizioni di kart in movimento e limitato tempo per effettuare la comunicazione;
-la possibilità collegare due riceventi allo stesso arduino in modo da avere la possibilità di ricevere tutte le otto trasmittenti (infatti questi moduli hanno max 6 indirizzi).

Grazie a tutti!

Bravo per aver descritto bene la scena.
Bravo anche per la chiarezza
Ho una sola domanda
La parte reed la hai provata?
Perché non so se hanno un campo di lettura abbastanza ampio

Il contatto magnetico è già stato collaudato in eventi precedenti e funziona correttamente.
L'unica aggiunta è la trasmissione del tempo alla finish line ad un arduino esterno, che eventualmente potrebbe essere collegato (o rimpiazzato) da un raspberry pi connesso a internet che aggiorna in tempo reale la classifica visualizzata su dispositivi mobile (su quest'ultima parte abbiamo già chiaro come procedere).

Forse la cosa più semplice sono 2 Arduino per 2 ricevitori. Poi o un Arduino fa anche da collettore dei dati generali o lo fa un terzo Arduino oppure un RaspberryPi.

Però non so se gli nRF24l01 si connettono in così poco tempo.

Progetto interessante.

Nel caso della trasmissione radio a me la cosa che preoccupa di più è la contemporaneità delle trasmissioni verso lo stesso ricevitore: se due auto (o più) passano contemporaneamente sul traguardo temo che possano disturbarsi a vicenda.

Per le soluzioni alternative all'uso della radio, non ho capito bene perché la trasmissione GSM/GPRS (che richiede la presenza di sufficiente campo cellulare) sarebbe preferibile, scartando quella WiFi (per la quale basta un access point nelle vicinanze del tracciato, supporterebbe bene trasmissioni contemporanee) che ti permetterebbe di avere come "server" un normale PC, ben più capace di renderizzare e magari pure stampare tempi e risultati, o un RaspBerry se si volesse risparmiare sull'hardware (al costo però di una maggiore complicazione implementativa).

Se la trasmissione non è contemporanea puoi usare anche più di 6 nRF24l01
Questo dice di connetterne fino a 255
https://www.insidegadgets.com/2013/06/09/nrf24-multi-network-allowing-for-255-addresses/
Praticamente incapsula un altro protocollo con indirizzo ad 1 byte. Funziona proprio perché le trasmissioni non sono contemporanee.
A quanto ho capito l'nRF24l01 dovrebbe essere in grado di gestire fino a 6 connessioni contemporanee, usa pacchetti piccini.

Il WiFi va bene se sei sempre collegato, se ti scolleghi a collegarti ci metti un po' specialmente se ti stai avvicinando. Coprire un circuito intero di kart potrebbe essere un problema ma non è detto.

Però i miei ESP8266 sembra si connettano in meno di un secondo, ma sono fermi.

docdoc:
..., o un RaspBerry se si volesse risparmiare sull'hardware (al costo però di una maggiore complicazione implementativa).

io sarò anche inesperto, ma non vedo perché dovrei avere maggiori difficoltà con Raspbian su raspberry piuttosto che con ubuntu su pc

Che comunque io vedo semplice un gruppo di HC12 sui veicoli e uno centrale, un protocollo che gestisce ack, ritrasmissione, e collisione

Ti consiglio questi...

zoomx:
A quanto ho capito l'nRF24l01 dovrebbe essere in grado di gestire fino a 6 connessioni contemporanee, usa pacchetti piccini.

Hm, si, ovviamente con pacchetti molto brevi la probabilità di collisione si abbassa, ma se capita ti perdi i tempi di un kart e credo che voglia evitarlo. Per cui non so bene, ma sai per caso se si possono trovare trasmettitori (e ricevitori) a frequenze sufficientemente diverse da non "pestarsi" toppo i piedi?

Il WiFi va bene se sei sempre collegato, se ti scolleghi a collegarti ci metti un po' specialmente se ti stai avvicinando. Coprire un circuito intero di kart potrebbe essere un problema ma non è detto.

Oooops, ho riletto meglio, scusate, cazzata mia! Quando parlavano di kart immaginavo una pista con dei MODELLINI, non kart veri... :frowning: Quindi in una seppur larga pista di modellini un WiFi andava benissimo.
Scusatemi.

Comunque sia, si, con i WeMos D1 (parlo di questi perché ne ho usato svariati) se ha campo ci mette meno di 1 secondo a connettersi, ma anche se credo che in campo aperto un access point potrebbe ricevere le connessioni in tempo per la trasmissione effettuata sul traguardo, forse è comunque rischioso.

Standardoil:
io sarò anche inesperto, ma non vedo perché dovrei avere maggiori difficoltà con Raspbian su raspberry piuttosto che con ubuntu su pc

Tu non apprezzi molto Windows, immagino, ma in generale lo è per due ragioni:

  1. perché su PC puoi programmare con Visual Studio in C# dove tutto è molto più semplice di tutte quelle piattaforme che hai elencato
  2. per chiedere un aiuto trovi più gente che possa aver lavorato in .NET che non su Ubuntu
  3. in fondo deve solo ricevere dei dati, salvarli, e presentarli in modo tabellare, quindi Raspberry non serve in questo contesto (WiFi), e Ubuntu è una inutile complicazione (per chi non è pratico di Linux).

Standardoil:
Che comunque io vedo semplice un gruppo di HC12 sui veicoli e uno centrale, un protocollo che gestisce ack, ritrasmissione, e collisione

Si, certo, chiaramente, anche se lui ha detto che non sa quanto tempo potrebbe mantenere la connessione, per cui più è rapida e "sicura" meglio è.

Per questo forse la soluzione migliore è nell'unione di tutte queste cose, ossia trovare almeno un paio di frequenze da utilizzare (l'ideale sarebbero 8 ma diciamo un paio) o magari usare i LoRa che ha consigliato elsabz, e ridurre le possibili collisioni facendo pacchetti molto piccoli ed un minimo di protocollo ACK/NAK (con una ritrasmissione del pacchetto "mancato", ossia che non ha ricevuto ACK, e se perde la connessione ci riprova al giro successivo).

HC12 hanno 100 canali, con un margine di sicurezza di 20 tra di loro (valore consigliato, vado a memoria) ci stiamo: 6 mobili su 6 fissi
Richiede naturalmente tanti rx (fissi) quanti sono i canali impiegati

E aggiungo, portano bene varie decine di metri, se i fissi sono ben piazzati c'è tutto il tempo che serve
Naturalmente serve un arduino per ogni fisso: è inutile evitare collisioni in radio e poi avere una sola softserial in ascolto

Gli nRF24l01 gestiscono la collisione, c'è un pacchetto di ritorno, se non ricordo male, alcuni lo usano per trasportare ulteriori comunicazioni, se non ricordo male!
Inoltre la portata aumenta scendendo di velocità di trasmissione. Ci sono anche i moduli con antenna esterna.

Io personalmente non saprei cosa consigliare, ogni soluzione ha i suoi pro e i suoi contro, non mi pare ce ne sia una ottimale. Ci sarebbe da sperimentare.

Standardoil:
HC12 hanno 100 canali, con un margine di sicurezza di 20 tra di loro

Ottimo, non lo sapevo grazie!

Naturalmente serve un arduino per ogni fisso: è inutile evitare collisioni in radio e poi avere una sola softserial in ascolto

Ma forse usando un Mega che ha 4 UART se ne possono gestire fino a 4 (3 UART ed una software) + 1 (USB) verso il PC, quindi con due Mega ce la si farebbe.
Questi a loro volta possono inviare i dati al PC che fa da "server" e che mostra i dati e permette di stampare le schede.

potrebbe andare

Ringrazio tutti per le risposte, non mi aspettavo tutta questa partecipazione quindi grazie a tutti di cuore.
Procedo elencandovi le novità:

  • la parte di raccolta dati su PC e visualizzazione è praticamente completa, un programma java legge i dati da porta COM che riceve da Arduino e li manda ad un server con database SQL che aggiorna una pagina WEB (per i curiosi la pagina è questa http://kartfabi.altervista.org/) raggiungibile sia da dispositivi mobili sugli spalti sia da un eventuale monitor nei box. Il programma è stato testato sia su Windows che su Raspberry Pi 2.
    -Il programma Arduino invece è ancora in fase “molto” beta (anche perchè non sono un gran SWista) e per ora è limitato alla raccolta di dati da un singolo nRF.
    Come suggerito da qualcuno (non mi ricordo chi ma non fatemi andare a vedere :slight_smile: ) ho abbracciato la filosofia di fregarmene dei sei indirizzi “HW” forniti dal sistema di comunicazione Enhanched ShockBurst e di inviare io come prima informazione un identificativo del kart che sta trasmettendo.
    Riassumendo in breve la dinamica del programma a bordo:
    1-chiede all’utente che è fermo (attraverso display) appena prima della linea di partenza alcune info (canale su cui si vuole trasmettere e numero di bande magnetiche sulla pista, ossia quanti intertempi è possibile misurare);
    2-rimane in una fase di IDLE fin quando non si taglia la prima banda magnetica, a quel punto parte il cronometro, se le bande impostate sono n dopo aver contato n tempi lui saprà di aver tagliato l’arrivo (è tornato alla banda da cui era partito) a questo punto la piccola radio incomincia a trasmettere i dati e continua a provarci fin quando non arriva alla banda successiva.
    Per sicurezza ogni volta vengono trasmessi sia i tempi del giro appena concluso sia i tempi di quello precedente (ma nulla vieta, se non la capacità della RAM dell’arduino, di inviare ogni volta anche 20 giri precedenti).

Il programma a funzionato fino a venerdì scorso da ieri questi maledetti nRF24l01 non vogliono andare (penso sia un problema di contatti).

Sempre qualcuno di voi (grazie ma non mi ricordo il nome) ha parlato della funzione di ACK, non ho ben capito ma credo che questa sia utilizzata in maniera automatica dalla funzione radiox.write(var, sizeof(var)) in quanto essa restituisce un valore booleano in caso di trasmissione andata a buon fine e si “accorge” se ad esempio la ricevente è scollegata e quindi sta scrivendo “a vuoto”.

Quello che mi sembrava molto utile ma purtroppo non riesco ad usare è l’AckPayload, la mia idea (se riuscivo a far funzionare questi moduli con questa funzione) era quelli di avere la ricevente di terra che continua a inviare dei pacchetti di richiesta in maniera completamente casuale (uno pacchetto ogni tot ms) e se per caso una trasmittente (montata su un kart) arriva nel raggio di ricezione riceve il pacchetto di richiesta e con la funzione AckPayload invia automaticamente come risposta di Ack con i valori dei tempi.

Vantaggi di questa soluzione:

  • se il kart non rileva una banda è un casino, perchè non incomincia a trasmettere dallo linea di start ma tutto si shifta di una banda, con questo metodo invece anche se perde una banda lui trasmette sempre quando “a tiro” della ricevente.

Svantaggi:
-Per avere il vantaggio sopra bisognerebbe che una volta ricevuta la richiesta il modulo attivi l’interrupt sul pin IRQ, e la ISR si dovrebbe occupare di trasmettere i tempi, il problema sta nel fatto il µcontrollore può gestire un solo interrupt e questo significherebbe fare a meno del conteggio con la funzione millis() che anch’essa utilizza l’interrupt del TMR.

Ora sono un po’ in panico con questi maledetti moduli che non vogliono andare e spero di sistemare al più presto, allego i due programmi uno un po’ commentato l’altro non ho fatto in tempo, invio il file perchè un po’ lunghi, purtroppo sono scritti in più giorni e quindi non sono molto lineari, ve li allego nel caso foste curiosi.

Allego anche un file PDF con un piccolo schema della ricevente, è presente anche un secondo arduino che dovrà occuparsi di raccogliere dati di telemetria ma non centra molto.

Grazie a tutti per il supporto!

P.S. ho premuto un tasto random sulla tastiera per sbaglio e mi ha inviato solo la prima frase del messaggio scusate.

Receiver.ino (2.56 KB)

Transmitter.ino (9.54 KB)

Non ho capito bene la storia degli interrupt. Arduino è in grado di gestire l'interrupt del millis contemporaneamente all'interrupt su piedino.
Esiste una gerarchia fra gli interrupt, alcuni vengono gestiti prima di altri ma gli altri non vanno persi, vengono messi in una sorta di coda.

zoomx:
Non ho capito bene la storia degli interrupt. Arduino è in grado di gestire l'interrupt del millis contemporaneamente all'interrupt su piedino ....

No, il problema che descrive è che, mentre sei in usa ISR, gli interrupts sono disabilitati e quindi millis() NON avanza.

La cosa però si dovrebbe risolvere scrivendo le ISR le più veloci possibili (alzare una flag per indicare l'avvenuto interrupt e uscire subito) e gestire poi la cosa (la flag attiva) a livello di loop() (... gestione tipo "deferred interrupt") con, di nuovo, tutti gli interrupt attivi.

Guglielmo

Nella gerarchia l'interrupt del millis viene dopo quello dei pin?

Forse ci vorrebbe anche una guida agli interrupt che spesso viene compresa come una gestione di eventi stive Visual Studio cosa che non è.

zoomx:
Nella gerarchia l'interrupt del millis viene dopo quello dei pin?

NON esiste una gerarchia, NON sei, ad esempio, su PIC32 dove ci sono le priorità degli interrupt ... su AVR hanno tutti la stessa priorità.

Guglielmo