Comunicazione seriale tra 2 arduino

Salve ragazzi ed ancora grazie per la vostra pazienza ed aiuto.

Attualmente ho un programma che gira con arduino UNO che utilizza l'RTC e che "viaggia" bene ed un altro programma che gira su MEGA con touch screen da 2.8" che da due settimane sembra sia a posto. Ora ho cominciato a far scambiare i dati tra le due schede usando solo la libreria "serial" e tre cavi RX TX e GND. Il il programma funziona i dati arrivano ma ci sono 2 problemini ( altrimenti non sarei qua :D) Problema 1: quando connetto il seriale ed avvio il programma di comunicazione verso la UNO il Touch non mi funziona piu anche se gli azionamenti continuano a funzionare (mi sparisce solo la schermata). Problema 2: I dati li vedo sul seriale del computer ma non so come utilizzarli per farmi le variabili che mi servono. Ad esempio nel seriale del computer connesso alla UNO leggo il dato inviato dalla MEGA "temperatura camera 22*C" ma il "22" che a me servirebbe come variabile "int" per lavorarla con l'altra scheda non riesco a convertirla.

Qualcuno ha un idea di come fare?

Grazie.

Non posso sapere con certezza perché il Toch non funziona più, non è che per caso impegni il micro a spedire dati in continuazione o a leggerli. Sicuramente nel momento in cui impegni il micro a fare altro il touch non funziona.

Per convertire rappresentazioni ascii in numero arduino mette a disposizione ParserInt o qualcosa di simile, non l'ho mai usato. In C/C++ si possono usare le funzioni della libreria standard atoi (ascii to intero con segno), dtostrf (double to string float) e altre, cerca in avr-libc reference http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html

Non cercare solo in stdlib, c'è ne sono altre ma non ricordo dove.

Ci sono anche quelle per trasformare un numero in ASCII.

Comunque se hai molti dati in sequenza da spedire/leggere ti consiglio di collezionare questi dati in una struct e poi ti dico come spedire questa byte per byte e come ricevere questa dall'altro lato per formare la stessa struttura dati.

Inoltre ti consiglio di spedire dati raw, cioè non codici ascii a meno che non si tratti si singoli caratteri di comando.

Se descrivi uno scenario base e ridotto all'essenziale di come devono comunicare, si può teorizzare cosa conviene e cosa no.

Ciao.

Fino ad ora non ho ancora provato a vedere le cause di questi due problemini, sono arrivato a farli "parlare" utilizzando una linea lunga 50 metri e senza un 422 è gia qualcosa. Probabilmente il problema del touch è dovuto all'impegno continuo della seriale quindi proverò a scandire le trasmissioni. In generale i dati in circolazione sono: L'RTC da UNO a MEGA che posso anche eliminare con un altro rtc (il casino sarebbe poi sincronizzarli) I dati di temperatura da MEGA ad UNO dei 5 sensori che devo campionare poi su exel (per diponibilita dei grafici) assieme agli altri dati e che nella MEGA sono variabili float. Da UNO verso MEGA ho un dato di temperatura in "int" e comandi che arrivano dal computer.

In generale la struttura è: arduino UNO (master) con ethernet shield collegata ad un case PC con schermo tattile e tastiera dove girerà un programma di interfaccia utente che tramite la UNO (che svolge anche degli azionamenti) manda ordini a 2 MEGA con touch che fanno gli azionamenti. I due touch sevono a variare alcuni parametri derettamente nella stanza senza andare nello schermo centrale

I dati di temperatura da MEGA ad UNO dei 5 sensori che devo campionare poi su exel (per diponibilita dei grafici) assieme agli altri dati e che nella MEGA sono variabili float.

Quindi per questi sensori invii dei dati al pc e ogni quanto tempo invii i dati e soprattutto è il PC che li richiede o i dati li spari ogni tot e il pc è sempre in ascolto?

Usa struct di questo tipo:

typedef struct 
{
     float temp0;
     float temp1;
     float temp2;
     float temp3;
     float temp4;
} SensorCollection;

SensorCollection mySensorCollection;

vois setup { 
    mySensorCollection.temp0 = getTemp(sensor0);
    mySensorCollection.temp1 = getTemp(sensor1);
   //Oppure ancora meglio la funzione getTemp() salva il valore direttamente in mySensorCollection.temp0
   // mySensorCollection.temp1 ecc.
}

La variabile mySensorCollection può essere scomposta in byte e spedita fino a sizeof(SensorCollection) Dal PC sempre se hai la possibilità di creare tipi struct con 5 campi float grandi 4byte (con il C/C++, sei apposto) puoi scrivere byte per byte i dati ricevuto nella variabile PCMySensorCollection e li leggerai nel modo consueto, tramite l'uso dell'operatore " . "

Facendo il conto per i 5 sensori (senza tenere conto di codice di start e end) hai una collezione di dati che pesa 4 byte per ogni float moltiplicato 5 sensori totale 4 x 5 = 20 byte.

Ciao.

OK ora i dati almeno li posso lavorare adesso sto cercando di far andare il touch. Come faccio a richiamare un dato dall'altra scheda senza impegnare continuamente il seriale?

Senza impegnare continuamente il seriale (cioè la seriale) In che senso?

Aspetta, mi mancano dei pezzi, hai usato mySensorColletion e vuoi sapere altro oppure la domanda è slegata dal modo di spedire i dati.

Lavoro di fantasia. mySensorCollection può essere acceduta come un array di float e quindi è possibile accedervi tramite indice.

float *sensorCollections;
sensorCollections = (float*)&mySensorCollection;
// Si accede a mySensorCollection attraverso un array, non c'è overhead, il cast è statico e quindi risolto a 
//  tempo di compilazione
sensorCollections[0] = 100.2;
sensorCollections[1] = 1000.25;
// mySensorCollection.temp0 vale 100.2 e temp1 vale 1000.25, c'è pure il vantaggio che 
//  sensorCollections[2] e gli altri indici non inizializzati sono pre-inizializzati dal compilatore 
// che pone a zero i campi di struct 
// ovviamente è possibile scrivere o leggere in entrami i modi alla stessa porzione di memoria.

Quindi se volessi richiedere da PC solo temp0 e non tutte gli altri campi dovresti inviare solo sensorCollection[0].

C'è anche un altra possibilità, ma è rognosa e perché.... hee...

Gli indirizzi di una variabile globale sono conosciuti a tempo di compilazione, per cui da arduino io potrei mandare gli indirizzi di temp0, temp1 e il pc se li conserva, poi quando il pc vuole accedere al valore di temperatura di un sensore, ciò che deve fare è semplicemente spedire ad arduino l'indirizzo di memoria, una volta ricevuto, una istruzione di questo tipo legge il valore (float)(address_recv) e lo spedisce al pc. Però è rognoso, perché gli indirizzi cambiano man mano che lo sketch di evolve.

Ciao.

Il problema e che seriale ausiliaria(mySerial per capirci) non va d'accordo con il touch. Ho provato a cambiare i pin perche il52 ed il53 sono usati anche dall'SPI del touch e quindi ho optato per il50 ed il51. Usando questi pin il touch va ma nei pin della seriale leggo numeri senza senso, se invece tolgo dallo sketch tutta la parte che compila lo schermo del touch allora nei pin della seriale leggo valori corretti. Un bel problema. L'idea che mi e venuta e': eseguire lo sketch con il touch, poi ogni tot tempo eseguo in "if" che esclude il touch apre la seriale richiama i dati chiude la seriale. Il loop sucessivo prende i dati del loop precedente ed aggiorna le variabili dello schermo. Sinceramente la vedo complicata ma accetto consigli

Non conosco il software che gestisce il touch e non so dire che pin usa e in che modalità. Se usasse l'hardware ISP, questa potrebbe impegnare 50 51 52 e addirittura anche il 53 (SS).

Per mySerial tu intendi la seriale software, giusto? Penso proprio di si, perché dici di aver scelto dei pin di uso generico, quindi tu stai impegnando tutte e 4 le seriali hardware e te ne serve una quinta.

I pin analogici possono anche essere usati in modo digitale, io intanto sposterei la seriale software su dei pin analogici visto che ne hai 16 (A0 a A15) a disposizione.

Ciao.