Comunicazione seriale tra due arduini non funziona

Suddividerò il post in varie sezioni così potrete saltare i pezzi che non vi interessano!

PRESENTAZIONE:

Salve a tutti, sono un ragazzo di 16 anni. Sperimento con arduino da circa 2 anni, nello specifico sono partito con un bel progetto sin da subito e man mano che passa il tempo, faccio degli esperimenti che mi fanno capire bene come procedere con il progetto principale. Frequento un liceo Scientifico e pertanto non ho mai avuto delle basi scolastiche di elettronica o informatica, ma ritengo che ora ho delle buone basi, grazie al mio studio personale. Sono un autodidatta, le mie conoscenze e competenze derivano da molti corsi online, sia gratis sia a pagamento, ho un libro (Arduino trucchi e segreti - Paolo Aliverti)e ovviamente non mancano tutti i video tutorial su Youtube (Ringrazio in particolare Paolo Aliverti).

IL PROGETTO:

Sto sperimentando la comunicazione Seriale tra un Arduino Mega (Master) e un Arduino Uno (Slave).
Il progetto consiste che sull'Arduino Mega che d'ora in poi definirò come primo Arduino, ci sono 3 potenziometri, mentre sull'Arduino Uno, che sarà il secondo Arduino, c'è un led rgb e un display oled.
Il primo Arduino deve inviare i valori dei potenziometri al secondo Arduino, che riconoscerà e stamperà sull'oled i valori separandoli per i tre colori:rosso, verde, blu. Il progetto è dunque molto semplice.

IL PROBLEMA:

Se collego il secondo Arduino direttamente al computer e quindi uso il monitor seriale per comandare il led rgb, tutto funziona alla perfezione, mentre se collego i due arduini insieme, il secondo riceve ogni tanto i valori del led Rosso e quindi non funzionano gli altri led. Da questo è facile giungere alla conclusione che il problema si trova nel codice del primo Arduino, nella parte in cui invia i dati.

LA LOGICA DEL CODICE:

La logica è spiegata passo-passo con i commenti del codice. Spero di aver fatto un buon lavoro.

  • Lo schema elettrico e il codice sono in allegato.

P.s. Ho seguito la procedura corretta sull'Arduino Uno: Ho scollegato TX e RX, ho caricato il codice, ho collegato i cavi e infine ho resettato la scheda.

P.s. Gli altri componenti che vedrete nello schema sono irrilevanti, nel codice sono solo impostati i loro pin, ancora non hanno una funzione.

GRAZIE A TUTTI IN ANTICIPO!

Sketch_x_Master.ino (6.71 KB)

Sketch_x_Slave.ino (6.83 KB)

Domanda: ma tu quando fai questa prova tieni per caso collegata la UNO alla USB? Perché dato che usi i pin 0 ed 1 che sono dedicati alla comunicazione seriale tramite USB, tutto questo rischia sicuramente conflitti e quindi problemi di comunicazione. Inoltre la seriale USB è utile per fare un buon debug e tranne casi particolari (non ci sono altri pin liberi, o la velocità di comunicazione deve essere alta) meglio non collegare nulla ai pin 0 ed 1.

Prova ad usare la SoftwareSerial sulla UNO ed impostare la comunicazione tra i due Arduino su dei pin liberi (es. 7 ed 8 ), ma a 9600 o 19200 bps tanto per la tua comunicazione non necessiti di velocità elevata (la SoftwareSerial funziona al massimo a 38400, meglio stare al di sotto).

docdoc:
... la SoftwareSerial funziona al massimo a 38400, meglio stare al di sotto.

... ci sono anche alcuni thread di Sukkopera che fece ampie prove ... a 38400 ci sono frequenti errori ... la cosa migliore, in realtà, con la SoftwareSerial, è NON superare i 9600 :wink:

Molto meglio usare la altSoftSerial ... più veloce ed affidabile. :slight_smile:

Guglielmo

docdoc:
Domanda: ma tu quando fai questa prova tieni per caso collegata la UNO alla USB?

Ciao e grazie mille per la tua risposta.

Il secondo Arduino, ovvero l'Arduino Uno non è collegato alla porta USB, quando ho fatto la prova, inviando i dati dal computer ho scollegato i cavi di TX e RX e ho collegato la USB. Quando invece provo a far funzionare il circuito, alimento solo l'Arduino mega, che a sua volta alimenta l'Uno con il VIN (come mostrato nello schema)

docdoc:
Prova ad usare la SoftwareSerial sulla UNO ed impostare la comunicazione tra i due Arduino su dei pin liberi (es. 7 ed 8 ), ma a 9600 o 19200 bps tanto per la tua comunicazione non necessiti di velocità elevata (la SoftwareSerial funziona al massimo a 38400, meglio stare al di sotto).

Proverò sicuramente il metodo che mi hai consigliato e ti farò sapere. Inoltre non so se questo vi può essere utile, ma alcune persone mi hanno consigliato di usare il metodo Serial1.write(), io credo che però non influisca, dato che io filtro gia tutti i \n che mi servono a riconoscere la stringa inviata alla seriale.

P.s. Mi sono dimenticato di dire che alcune volte, quando testo il circuito, mi da errore, ovvero il secondo Arduino legge dei valori non previsti. Sono abbastanza convinto che sbaglio qualcosa nella struttura che legge i dati della seriale. Forse ci può anche essere un problema nell'inviare i dati (forse i valori devono avere qualcosa che li separi)

Peppe_27:
Il secondo Arduino, ovvero l'Arduino Uno non è collegato alla porta USB, quando ho fatto la prova, inviando i dati dal computer ho scollegato i cavi di TX e RX e ho collegato la USB.

Ok, corretto.

Proverò sicuramente il metodo che mi hai consigliato e ti farò sapere. Inoltre non so se questo vi può essere utile, ma alcune persone mi hanno consigliato di usare il metodo Serial1.write(), io credo che però non influisca, dato che io filtro gia tutti i \n che mi servono a riconoscere la stringa inviata alla seriale.

Non cambia nulla, infatti. Lascia com'è almeno per ora. Se devi mandare dei valori interi potresti mandare 3 byte e non una stringa che li rappresenta, ma direi di fare una cosa per volta, iniziamo dall'hardware.

Intanto la prima cosa che ti consiglio è verificare i cavi che usi per la comunicazione: andando a 115200 se sono più di una decina di centimetri e/o non sono "buoni" cavetti e magari schermati, la comunicazione è molto a rischio. Quindi ti direi comunque di abbassare la velocità per evitare problemi, tanto trasferisci pochi byte alla volta.

Secondo, evita gli oggetti "String" (con la "S" maiuscola) perché su piccole MCU come Arduino non vengono gestite come su sistemi operativi più evoluti dove c'è un "garbage collector". Il motivo è legato al modo con cui si gestisce la memoria per questi oggetti ed è simboleggiato da questa immagine:

Per ulteriori informazioni vedi QUESTO topic dedicato a questo problema e come eventualmente risolverlo usando le "SafeString".
Ma se usi sempre le stringe "C" (vedi ad esempio QUI un articolo del solito ottimo Maffucci) è meglio.

Terzo, implementa la SoftwareSerial (o la altSoftSerial che ha consigliato Guglielmo, anche se a me è sempre bastata quella normale) spostando i pin per la comunicazione, così liberi la seriale della UNO che userai per tenere aperto il Monitor Seriale e poter quindi "vedere" cosa arriva allo slave (ossia usa Serial per scrivere al monitor seriale, quantomeno scrivendo tutto quello che ricevi dalla SoftwareSerial ed altre stringhe che possono esserti utili per visualizzare come ha "interpretato" i dati ricevuti) e fare quindi debug per capire se è un problema di protocollo, di comunicazione, o cosa.

Fatte queste cose, verifica il nuovo funzionamento e facci sapere (eventualmente posta sia i "nuovi" sketch sia i relativi risultati ottenuti, e cosa ottieni).

Dallo schema colleghi i 5V del MEGA a Vin di UNO, così facendo UNO non funziona bene