Go Down

Topic: Sincronizzazione di più Arduino tramite moduli wirelless (Read 585 times) previous topic - next topic

BlackHole900

Ciao a tutti, sto utilizzando la libreria radiohead, in particolare i driver RH_RF24  con il seguente modulo wireless : HC-12 SI4463 Wireless.


Per la gestione dei pacchetti, sto utilizzando la libreria manager di radiohead: Rhdatagram.h.

I 3 Arduino di cui dispongo sono dotati del micro-controllore ATMega328p.

Il mio obbiettivo è quello di inviare dati dai sensori periferici, verso il nodo centrale. Ogni nodo però ha un tempo limitato a disposizione per l'invio dei dati e questo invio non deve sovrapporsi con l'invio dei dati di altri nodi periferici, appunto per evitare interferenze. Per ora non sto utilizzando gli ACK.
Nella prima fase del mio piccolo progetto, avevo intenzione di sincronizzare in questa maniera:

1) Fase di sincronizzazione iniziale.
2) Ogni 8 secondi, il nodo 1 ha altrettanti 8 secondi per il inviare i dati.
3) Finiti gli 8 secondi parte il nodo 2 per altri 8 secondi.
4) ecc ecc.

 Il Nodo centrale però deve sapere quale nodo sta trasmettendo e chi trasmetterà dopo, quindi deve tenere traccia del tempo che sta passando ed essendo collegato al pc non ha bisogno di risparmiare energia.

In un primo momento per risparmiare batteria stavo utilizzando il watchdog in modalità interrupt, quindi il nodo 1, una volta passati gli 8 secondi a sua disposizione(valutati tramite la funzione millis) andava in sleep per un tempo pari 8 secondi, ovvero fin tanto che il nodo 2 non ha smesso di trasmettere.
Ho notato che utilizzando questo metodo, si veniva a creare uno sfasamento tra i tempi del nodo centrale e i 2 nodi periferici, che a lungo andare diveniva non trascurabile. Ciò penso sia dovuto al fatto che il passaggio tra sleep e normal mode, impiegava troppo tempo.

Allora ora per semplicità sto utilizzando solo la funzione millis per tenere conto del tempo che passa, e sto spegnendo solo la radio. Ovviamente il timer interno  di arduino non è ottimo e quindi diciamo che anche in questo caso si viene a definire uno sfasamento.

Non voglio un aiuto dal punto di vista del codice, ma più che altro un metodo da cui prendere spunto per effettuare questo tipo di sincronizzazione, cercando di risparmiare più energia possibile.

Le mie domande sono le seguenti:

Secondo voi sarebbe più utile utilizzare un RTC esterno da sincronizzare con il nodo centrale? E magari utilizzare questo RTC per inviare degli interrupt per accendere il nodo al momento giusto, tenendo conto dei tempi di accensione?

Mi potreste indicare qualche metodo di sincronizzazione che magari avete utilizzato?

Mi sapreste anche indicare come effettuare un sense del canale con i moduli che ho a disposizione?

E' un po' difficile spiegarvi cosa ho in testa attraverso un forum, quindi scusatemi se non sono riuscito a rendere bene l'idea.

Ringrazio tutti in anticipo per l'aiuto.

Standardoil

beh, io forse sto facendo qualcosa di simile al tuo
con un mio collega stiamo realizzando una rete di termometri remoti, che leggono la temepratra delle stanze
e la trasmettono ad una macchina centrale
ma per scelta precisa abbiamo deciso di non usare librerie di comunicazione
per il momento teniemo i satelliti in sleep, ongi 8 secondi si svegliano, e tornano a dormire
solo ogni 8 cicli leggono la temperatura, e solo se questa è cambiata di piu' di un valore di soglia la trasmettono alla centrale, assieme al numero del satellite
la gestione dell'orario la fa la centrale, che quando registra la temperatura le aggiunge l'ora
alla ricezione la centrale fa un check su una cifra di controllo, controllo superato, temperatura registrata e ritrasmessa al satellite
se il satellite ottiene la risposta torna a dormire: risposta ricevuta -> lavoro fatto
se non la ottine aspetta un tempo che dipende dal suo indirizzo (un numero di decimi di secondo pari al suo indirizzo)
siccome se due macchine trasmettono assieme si disturbano, MA non ci sono due macchine con lo stesso indirizzo trasmissione disturbata -> ritardo differente -> prossima trasmissione non disturbata
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

BlackHole900

Si questa potrebbe essere una soluzione, ovvero tenere il tempo solo con il nodo centrale(nel vostro caso la centrale) e mandare direttamente in sleep gli altri. La comunicazione che posso effettuare è la seguente:

1) Il nodo si sveglia e rimane sveglio per un tempo pari ad esempio 8 secondi e lo comunica al nodo centrale, indicandogli il tempo trascorso dall'attivazione.

2) il nodo centrale richiede il dato e una volta ricevuto manda un ack al nodo periferico, che una volta terminato il range di 8 secondi, va in modalità sleep.

3)Dal momento in cui l'altro nodo finisce  di comunicare dovrebbe partire l'altro nodo periferico, e così via.

In questo caso però interviene una comunicazione in più con il nodo centrale,dato che comunque devo avvisare il nodo centrale dell'attivazione di quel nodo. Purtroppo credo che senza l'utilizzo di RTC esterni, mi toccherà per forza utilizzare un metodo di questo genere. Andare a correggere gli errori di drift e offset non è una buona idea, anche perchè i timer di arduino, non sono tanto affidabili.

Se qualcuno ha in mente un altro metodo, è ben accetto.

Standardoil

In questo caso però interviene una comunicazione in più con il nodo centrale,dato che comunque devo avvisare il nodo centrale dell'attivazione di quel nodo.

Se qualcuno ha in mente un altro metodo, è ben accetto.

perché?
 Da me il satellite si sveglia e se il caso trasmette senza essere interrogato, trasmetto direttamente numero (indirizzo) del satellite e temperatura, senza attendere richiesta
Stiamo pensando di aggiungere una fase di ore-sincronismo. Col satellite che prima di trasmettere vede se il canale è libero, ma sto valutando se ne vale la pena
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

BlackHole900

#4
Apr 30, 2018, 03:28 pm Last Edit: Apr 30, 2018, 03:30 pm by BlackHole900
Devo avvisare il nodo centrale, perchè vorrei implementare dei comandi  da inviare al nodo periferico, ad esempio per modificare alcuni parametri. Io ho necessità che i pacchetti vadano a destinazione senza interferenze, quindi volevo trovare un modo per fare il channel sense con i moduli che ho a disposizione, ma per fare ciò dovrei andare a modificare la libreria rh_rf24, e sinceramente è un passo troppo lungo in questo momento.  Ora proverò a sfruttare quello che hai detto tu, per effettuare quel tipo di connessione.

Claudio_FF

Idea senza RTC:

Il nodo centrale continua a chiamare a rotazione i periferici (ciascuno col suo nome).

Quando un periferico si sveglia aspetta di essere chiamato, e a quel punto trasmette sicuramente su canale pulito perché gli altri parleranno solo quando chiamati (visto che si parla di slot di 10..20 secondi immagino che i tempi non siano stringenti).

Poi a seconda dell'affidabilità richiesta si può implementare un ACK da centrale a periferico o una richiesta di ritrasmissione.

In ogni caso i pacchetti dati *devono* avere un controllo errori robusto, minimo un CRC16 (non basta uno XOR o un checksum).
* * * *    if non è un ciclo   * * * *
* * * Una domanda ben posta è già mezza risposta. * * *

BlackHole900

Si questa è una buona idea, per ora lascio perdere gli RTC dato che ancora devo comprarli. Grazie, lascio il topic aperto, casomai a qualcuno vengono altre idee in mente.

BlackHole900

Ciao, vi riscrivo su questa discussione perchè vorrei sapere quanto impiega il microcontrollore per passare dallo stato PWR_DOWN allo stato attivo. Non riesco a trovare questo dato nel datasheet.

gpb01

... se ben ricordo, riavviato l'oscillatore, pochi cicli di clock ... nel datasheet c'è sicuramnete, magari non come valore in una tabella, ma in qualche grafico temporale, prova a cercarlo ... ::)

Guglielmo
Search is Your friend ... or I am Your enemy !

BlackHole900


BlackHole900

Ragazzi torno a scrivervi. La rete funziona utilizzando gli RTC ds3231, il problema è che si generano offsett tra i vari Arduino che devo corregere ogni volta. Vi è un modo per modificare la frequenza di clock degli RTC, al fine di eliminare questo offset? Sapete indicarmi qualche guida?

Standardoil

L'uomo con un orologio conosce l'ora
L'uomo con due orologi conosce il dubbio
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

BlackHole900

Mi stanno facendo impazzire , comunque la rete funziona, ogni nodo si sveglia al momento giusto, ma questi offset mi fanno impazzire. Devo correggerli spesso, via software.

fabpolli

Puoi risolvere decidendo dal nodo centrale una volta al giorno (ad esempio ma potresti farlo anche più spesso se necessario) di inviare l'ora da settare ai nodi periferici, lo potresti fare quando il nodo periferico contatta il master, come risposta invii l'ora da settare

Standardoil

Come sei messo ?
Io dopo che mi sono arrivati gli attiny85 ho quasi finito.
Mi manca solo la fase di ack dopo trasmissione.
Se mi va bene oggi pubblico il definitivo
Però io tengo l'ora centralizzata, presa da server ntp, i miei satelliti non sanno l'ora
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

Go Up