Arduino Forum

International => Italiano => Software => Topic started by: Marcobz on Dec 14, 2013, 04:27 pm

Title: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 14, 2013, 04:27 pm
Un saluto a tutti !
Come ho già scritto in presentazione riprendo in mano un pò di aggeggi elettronici dopo 15 anni di digiuno..  XD

Sto smanettando da settimane ormai con i miei arduini e un passo alla volta mi sto districando tra le varie funzioni.
Il mio progetto che ho in testa è di domotizzare casa mia in maniera modulare. Pensavo a mettere un'Arduino UNO con TFT in ogni camera per renderli indipendenti in caso di guasti e collegarli ad una MEGA 2560 da mettere all'ingresso. La MEGA grazie a una shield Annikken Andee (che già ho e trovo fantastica perchè non devo imparare da zero a programmare android) viene comandata da un tablet Android.
Il progetto è in comtinua evoluzione e implementazione man mano che le mie conoscenze crescono.

Ma veniamo al mio problema.

Ho già preparato uno sketch che funge da termostato che verrà caricato su ogni arduino UNO (manca la parte TFT ma ci arriverò..). In questo sketch in sostanza mi trovo con due variabili Timpostata e Tambiente. L'unica cosa che mi manca è trasmettere queste variabili alla MEGA per poterle visualizzare con l'Andee sul tablet.

Penso che la soluzione migliore sia la libreria SoftwareSerial e finora sono riuscito in qualche modo a trasmettere qualcosa ma un problema mi blocca e pur cercando come un matto non trovo niente che mi aiuti.
Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10,11);

float valore = 0.0 ;
void setup()
{
 Serial.begin(9600);
 pinMode(13 , OUTPUT);
 mySerial.begin(9600);
}

void loop(){
 if (mySerial.available())
 {
   valore = mySerial.read();  
   Serial.println(valore);
   digitalWrite(13, HIGH);  
 
 }
   
 
}


Questo è lo sketch sul ricevitore, la MEGA 2560. Ho impostato la variabile valore come float perche la temperatura è con 2 decimali.

Code: [Select]
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11);

float valore = 0.0 ;      

void setup()  
{

 Serial.begin(9600);
 mySerial.begin(9600);
}

void loop()
{
 valore = 3.5;            
   
 if (valore>0){
    mySerial.print(valore);
    Serial.println(valore);  

}
}


Questo è lo sketch sulla arduino UNO, il trasmettitore diciamo. Per ora come esperimento immetto a mano il valore della variabile.

Il problema è che sul monitor seriale della trasmittente mi scrive il valore corretto 3.50 mentre sul monitor seriale mi scrive valori sballati.
Tipo:
53
45
67
32
34
ecc ecc...

Oppure il meglio che sono riuscito a fare (e non ricordo come...) valori tipo 22.00 anche se il valore di partenza era 21.77.

Chi mi spiega un pochino come fare ?

Graaaazie....
Title: Re: 6 Arduini UNO che comunicano una temperatura a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 14, 2013, 05:28 pm
Il problema è ... che non leggete il reference e cosa fanno le funzioni (... uso il plurale perché ogni volta è esattamente la stessa cosa ... se fai un po' di ricerche sul forum ne trovi a decine ;) )

SoftwareSerial.read() (http://arduino.cc/en/Reference/SoftwareSerialRead) : "Return a character that was received on the RX pin ..."

La funzione " mySerial.read()" (come la Serial.read) restituisce UN char ovvero legge un singolo byte. Se da un lato si trasmette una serie di bytes, come può fare una Serial.print ... dall'altro lato occorre gestire un meccanismo per ricevere una serie di bytes e capire quando essi sono finiti.

Quindi ... dovrai implemnetare un ciclo in cui leggerai carattere a carattere quello che arriva sulla seriale, dovrai capire, ad esempio con un carattere terminatore (es. CR) quando il dato è terminato ed infine ... trasformare la stringa di char che avrai ricevuto nel tuo valore numerico ...

Ripeto, se ne è parlato infinite volte e, se fai delle ricerche, trovi anche degli esempi fatti ;)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano una temperatura a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 14, 2013, 05:56 pm

Il problema è ... che non leggete il reference e cosa fanno le funzioni (... uso il plurale perché ogni volta è esattamente la stessa cosa ... se fai un po' di ricerche sul forum ne trovi a decine ;) )



Ringrazio sinceramente per la risposta ma il problema è ... che all'epoca non ho avuto la fortuna di poter studiare l'inglese, che non ho avuto modo di studiare linguaggio C e che chi scrive le reference magari sono persone che non pensano che dovrebbero essere rivolte anche ai niubbi che vogliono imparare ma le scrivono per gli addetti ai lavori... tutto quello che so su questi argomenti è autodidattico.

Io cerco di leggere tutto il possibile, di cercare il più possibile nei forum e di chiedere il meno possibile... ma quando non capisco una cosa e nonostante giorni di tentativi e ricerche non riesco ad arrivarci da solo mi tocca disturbare... abbiate pazienza.
Il progetto è oltre la mia portata attuale ma il mio scopo non è finirlo e venderlo ma imparare. Tanto è vero che non ho chiesto uno sketch pronto, ma che qualcuno mi spiegasse.

Senza rancore, giusto per mettere in chiaro le cose.  ;)

Ora che so cosa cercare nel forum, vado a cercare.
Title: Re: 6 Arduini UNO che comunicano una temperatura a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 14, 2013, 06:31 pm

Ringrazio sinceramente per la risposta ma il problema è ... che all'epoca non ho avuto la fortuna di poter studiare l'inglese, che non ho avuto modo di studiare linguaggio C ....


Capisco, ma purtroppo questo è un ambiente di lavoro (Arduino) dove se non sai il C ... non vai da nessuna parte e, se non sai l'inglese ... vai da ben poche parti ... mi spiace ... :(

Magari, prima di buttarti su un progetto così articolato ... io dedicherei molto più tempo a studiare BENE il linguaggio e le sue regole. Esistono un'infinità di ottimi testi e tutorials anche in lingua Italiana ... ;)

Quando avrai padronanza dello strumento ... allora vedrai che molte cose saranno più semplici ... :)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano una temperatura a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 14, 2013, 07:05 pm
Senza volermi dilungare troppo su di me.. ho scritto che non ho avuto la fortuna di poter studiare inglese e C intendendo a scuola..(non erano previste come materie nonostante l'indirizzo di "Tecnico delle industrie elettriche ed elettroniche")... ma poi i miei manualetti per i fatti miei me li sono letti !  XD E per l'inglese pian pianino negli anni qualcosa mi è entrato !

Comunque forse inizio a capire come far leggere la serie di caratteri ... mi hai dato la chiave giusta.
Appena riesco a mettere insieme uno sketch se lo posto me lo potresti controllare e vedere se ho capito bene ?

Grazie !
p.s. naturalmente la richiesta è per tutti !
Title: Re: 6 Arduini UNO che comunicano una temperatura a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 14, 2013, 07:07 pm

...
Appena riesco a mettere insieme uno sketch se lo posto me lo potresti controllare e vedere se ho capito bene ?


... naturalmente ... SI   XD

Guglielmo
Title: Re: 6 Arduini UNO che comunicano una temperatura a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 14, 2013, 11:31 pm
Niente... mi sta fumando la testa e ho gli occhi così  :smiley-eek: a furia di cercare e capire ma non ci arrivo.. non posto neanche gli sketch che ho provato...

Qualcuno può darmi una manina a trasmettere sto float da un'arduino all'altro ? Ormai sono in confusione totale...  :~
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 09:10 am
Marco,
da un lato puoi continuare a trasmettere tranquillamente usando la Serial.print solo che, dopo il tuo numero, aggiungi una Serial.print() di UN carattere che, per te, identificherà il separatore, esempio il carattere CR (0x0D oppure '\r') ...

... dall'altro lato, basta un ciclo che legge carattere a carattere e memorizza in un array che costituirà la tua stringa ricevuta (... ricordandosi di mettere sempre come ultimo carattere lo 0x00 and indicare la fine della stringa).

Finita la ricezione, dovrai convertire la stringa (array di char) nel tuo numero.

L'ho già messo in altri post e lo rimetto anche qui ...
... ecco un esempio "generico" di come ricevere una serie di caratteri terminati da un carattere terminatore :

Code: [Select]

#define MAXCHAR  32
#define TERCHAR  0x0D

char inputString[MAXCHAR + 1];
char inChar;
byte strIndex;


void setup() {
 
 strIndex = 0;
 inputString[strIndex] = 0x00;
 
 Serial.begin(9600);
 
}

void loop() {
 
 if (Serial.available()) {
   inChar = Serial.read();
   // se si vogliono vedere in HEX i caratteri che si ricevono
   // togliere il commento alla riga seguente
   // Serial.println(inChar, HEX);
   if (inChar == (char) TERCHAR) {
     // è arrivato il carattere terminatore, si puo' elaborare la stringa
     // In questo esempio semplicemente la si stampa ...
     Serial.println(inputString);
     //
     // finito il suo uso la si ripulisce per un uso successivo
     strIndex = 0;
     inputString[strIndex] = 0x00;
   }
   // NON è arrivato il carattere terminatore, si memorizza il carattere ricevuto
   // e si sposta il fine stringa ...
   inputString[strIndex] = inChar;
   strIndex++;
   if (strIndex > MAXCHAR) {
     // ... NON c'è pi` spazio nella stringa ... bisogna elaborarla e svuotarla
     // In questo esempio semplicemente la si stampa ...
     Serial.println(inputString);
     //
     // e la si ripulisce per un uso successivo
     strIndex = 0;
     inputString[strIndex] = 0x00;
   }
 }
}


... ora a te lavorarci sopra per adattarlo alle tue esigenze ... ! ;)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: PaoloP on Dec 15, 2013, 09:25 am
Nelle ultime versioni dell'IDE è stato inserito Parsefloat --> http://arduino.cc/en/Serial/ParseFloat (http://arduino.cc/en/Serial/ParseFloat)
Una discussione in merito --> http://forum.arduino.cc/index.php?topic=108452.0 (http://forum.arduino.cc/index.php?topic=108452.0)
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 09:33 am
@Paolo : Paolo, leggi bene il thread, stiamo parlando della SoftwareSerial (deve gestire SEI seriali su una Mega) e ... non mi sembra che qualcuno si sia preso la briga di implementarla con TUTTE le funzioni della Serial   ]:D ]:D ]:D

Inoltre, parlando in generale, anche sulla Serial ritengo che chi comincia debba imparare a fare le cose come si debbono fare e non ad usare la "pappetta" fatta che, come si allontana dall'IDE di Arduino .. non trova più e non sa cosa fare !  :smiley-roll:

Certe funzioni sono solo diseducative !!!  ]:D

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: astrobeed on Dec 15, 2013, 09:48 am

Inoltre, parlando in generale, anche sulla Serial ritengo che chi comincia debba imparare a fare le cose come si debbono fare e non ad usare la "pappetta" fatta che, come si allontana dall'IDE di Arduino .. non trova più e non sa cosa fare !  :smiley-roll:
Certe funzioni sono solo diseducative !!!  ]:D


Assolutamente d'accordo :)
Manca ancora la spiegazione di come fare per scomporre un float nei quattro byte che lo compongono e come riunirli per ottenere nuovamente il float, il tutto lo spiego qui (http://arduino.cc/forum/index.php/topic,62965.msg456869.html#msg456869), leggere anche i post seguenti.
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 09:58 am
@Astro : Stavo pensando di fagli trasmettere il float come semplice stringa (mySerial.print) e poi di riconvertire la stringa di caratteri ricevuta con una atof() (... che ho visto essere presente nella stdlib.h AVR) ... ma non ricordo se poi a livello di libreria nella Toolchain Arduino standard ... è implementata ;)

Guglielmo

Edit : Comunque la tua spiegazione che hai linkato è molto più educativa ... almeno imparano anche ad accedere ai bytes attraverso l'uso dei pointers ;)
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: astrobeed on Dec 15, 2013, 10:06 am

@Astro : Stavo pensando di fagli trasmettere il float come semplice stringa (mySerial.print) e poi di riconvertire la stringa di caratteri ricevuta con una atof() (... che ho visto essere presente nella stdlib.h AVR) ... ma non ricordo se poi a livello di libreria nella Toolchain Arduino standard ... è implementata ;)


Non mi ricordo se sono implementate ftoa() e atof() in Arduino e/o avrgcc, però se si impara ad usare le unioni è meglio, assieme alle strutture e i puntatori sono tra gli strumenti più potenti del C e consentono di risolvere molte problematiche.
Da non scordarsi che le funzioni di manipolazione stringhe e conversione delle stesse sono molto pesanti dal punto di vista del codice e cicli macchina, una unione viene tradotta come uso di puntatori, senza dovere "combattere" direttamente con gli stessi, richiede pochi byte di codice e pochi cicli macchina per la sua esecuzione.
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 10:23 am

... però se si impara ad usare le unioni è meglio, assieme alle strutture e i puntatori sono tra gli strumenti più potente del C e consentono di risolvere molte problematiche.


(http://www.nikonland.eu/forum/public/style_emoticons/default/ibf_thumbup.gif)  (http://www.nikonland.eu/forum/public/style_emoticons/default/ibf_thumbup.gif)  (http://www.nikonland.eu/forum/public/style_emoticons/default/ibf_thumbup.gif)
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: PaoloP on Dec 15, 2013, 11:47 am
@Guglielmo
ParseInt e Parsefloat sono, mi pare, nella classe stream, quindi richiamabili anche dalla softserial.
Comunque sarebbe da verificare.

Se ragionate così allora tutto il core di Arduino è "diseducativo" e si dovrebbero programmare i micro in puro ANSI C.  ]:D
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: danyevo on Dec 15, 2013, 12:01 pm
Ciao come fai a far capire al mega chi degli arduini a inviato la temperatura?
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 12:06 pm

@Guglielmo
ParseInt e Parsefloat sono, mi pare, nella classe stream, quindi richiamabili anche dalla softserial.
Comunque sarebbe da verificare.


Paolo ... prima di scrivere .. avevo già provato ... mi dice che in SoftwareSerial non esiste la funzione :( .


Se ragionate così allora tutto il core di Arduino è "diseducativo" e si dovrebbero programmare i micro in puro ANSI C.


Buona parte LO E'  ]:D
Tanto è vero che molti, appena decidono di avvicinarsi ad un altra MCU ... vanno "nel pallone" ...  XD

Guglielmo

Edit : Avevo scritto male ... effettivamente parseFloat funziona ;)
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 12:08 pm

Ciao come fai a far capire al mega chi degli arduini a inviato la temperatura?


Basta ch prima dei dati invii un identificativo della board ... in pratica costruisci una struttura in cui c'è "l'indirizzo" del mittente ed "il messaggio" e poi trasmetti il tutto ;)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: danyevo on Dec 15, 2013, 12:13 pm
Ma perche usa la libreria softwareserial?
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: danyevo on Dec 15, 2013, 12:17 pm
Per identificare l'arduino che invia la temperatura potrebbe fare così:
Code: [Select]

stringa0 += char('a');  (a) è l'indirizzo
stringa0 += int(t1);  (t1) e la variabile dove è scritta la temperatura
Serial.println(stringa0)  invia la stringa

Giusto..
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 12:36 pm

Ma perche usa la libreria softwareserial?


Perché ... ha SEI seriali da gestire e la Mega ne ha fisicamente solo tre ...  :smiley-mr-green:

Ovviamente, con un po' di esperienza, avrebbe potuto semplificare il progetto ...
...  ad esempio usando una sola linea RS485 (con gli appositi adattatori) collegata ad una sola delle seriali della MEGA e da software avrebbe potuto implementare un protocollo di "polling" ... ma magari ci arriverà in futuro ... ora mi sembra veramente agli inizi ... :)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: danyevo on Dec 15, 2013, 12:59 pm
non è possibile utilizzare una porta seriale  e collegare tutti gli arduini li?
tutti i tx degli arduini vanno nel rx del mega, tutti i rx degli arduini i vanno nel tx del mega
magari sincronizandoli che trasmettono prima uno poi l'altro e così via
magari il mega quando riceve i dati dal primo invia i dati per far partire il secondo poi il terzo ecc ecc
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 03:12 pm
NO, non è possibile mettere in parallelo così le porte seriali.

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: astrobeed on Dec 15, 2013, 03:33 pm

NO, non è possibile mettere in parallelo così le porte seriali.


Direttamente no, i TX  sono degli out e metterli brutalmente in parallelo vuol dire fare un corto, però un modo semplice per mettere in parallelo delle UART c'è.
Tenuto conto che lo stato di idle della seriale è 1 logico basta appendere il RX al +5V con una pullup da 10k , mettere in serie ai vari TX un diodo schottky, p.e. un BAT48, collegando il catodo sul TX e i loro anodi in parallello sul RX, in questo modo i vari pin TX sono tra loro isolati e quando uno va a zero logico di conseguenza traina anche l'RX a questo livello consentendo la comunicazione.
Ovviamente con una soluzione di questo tipo è necessario usare un protocollo di comunicazione basato su un address tenendo conto che solo un TX per volta può entrare in funzione, va da se che il TX della Mega deve essere collegato in parallelo su tutti gli RX delle varie UNO.
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Etemenanki on Dec 15, 2013, 04:12 pm

... si dovrebbero programmare i micro in puro ANSI C.  ]:D


Perche' vuoi complicarti la vita ? ... vai di binario ... :P XD  ]:D
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 04:34 pm

Perche' vuoi complicarti la vita ? ... vai di binario ... :P XD  ]:D


Già fatto fanciullo, già fatto ...  ]:D
... e anche per molto tempo, quando all'inizio non potevo permettermi di acquistare neanche un assemblatore (... con quello che negli anni '70 costavano)  XD

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: astrobeed on Dec 15, 2013, 04:35 pm

Già fatto fanciullo, già fatto ...  ]:D


Idem, gli Z80 li programmavo scrivendo direttamente i codici macchina in ram  :smiley-mr-green:
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 04:37 pm

Direttamente no, i TX  sono degli out e metterli brutalmente in parallelo vuol dire fare un corto, però un modo semplice per mettere in parallelo delle UART c'è ....


:smiley-mr-green:  Direi che, poveraccio, gli stiamo mettendo una bella confusione in testa ... dato che aveva esordito con :


Come ho già scritto in presentazione riprendo in mano un pò di aggeggi elettronici dopo 15 anni di digiuno ...


Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 15, 2013, 08:20 pm


Direttamente no, i TX  sono degli out e metterli brutalmente in parallelo vuol dire fare un corto, però un modo semplice per mettere in parallelo delle UART c'è ....


:smiley-mr-green:  Direi che, poveraccio, gli stiamo mettendo una bella confusione in testa ... dato che aveva esordito con :


Come ho già scritto in presentazione riprendo in mano un pò di aggeggi elettronici dopo 15 anni di digiuno ...

Credimi.. quello che ha scritto astrobeed è l'unica cosa che capisco veramente... avrei fatto pure io così ma non so esattamente l'hardware come potrebbe reagire...

Comunque.. oggi a un certo punto mi è sceso sangue dal naso a forza di ragionare. Ho iniziato mettendo sulla UNO um mySerial.println così automaticamente mi accoda al valore il carriage. Giusto ?
Code: [Select]
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11);

float valore = 0.0 ;       

void setup() 
{

  Serial.begin(9600);
  mySerial.begin(4800);
}

void loop()
{
  valore = 29.57;           
   
  if (valore>0){
     mySerial.println(valore);
     Serial.println(valore);
     delay(1000);

}
}

Sulla MEGA ho adattato lo sketch di Guglielmo per la Serialprint e lanciando il tutto sul serial monitor il valore arrivava ma su stringhe lunghissime e incasinate.
Ho abbassato i baud a 4800 .... ho messo su tutti i valori possibili la MAXCHAR che da come ho capito io indica dopo quanti char ricevuti stampa il dato sul monitor. Dopo MILIONI di tentativi sono arrivato a questo
Code: [Select]
#include <SoftwareSerial.h>                    //includo libreria
SoftwareSerial mySerial(10,11);                //assegno pin tx e rx

#define MAXCHAR  1
#define TERCHAR 0x00

char inputString[MAXCHAR + 1];
char inChar;
byte strIndex;


void setup() {
 
  strIndex = 0;
  inputString[strIndex] = 0x00;
 
  Serial.begin(9600);
  mySerial.begin(4800);
}

void loop() {
 
  if (mySerial.available()) {
    inChar = mySerial.read();
    // se si vogliono vedere in HEX i caratteri che si ricevono
    // togliere il commento alla riga seguente
    // Serial.println(inChar, HEX);
    if (inChar == (char) TERCHAR) {
      // è arrivato il carattere terminatore, si puo' elaborare la stringa
      // In questo esempio semplicemente la si stampa ...
      Serial.println(inputString);
      //
      // finito il suo uso la si ripulisce per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
    // NON è arrivato il carattere terminatore, si memorizza il carattere ricevuto
    // e si sposta il fine stringa ...
    inputString[strIndex] = inChar;
    strIndex++;
    if (strIndex > MAXCHAR) {
      // ... NON c'è pi` spazio nella stringa ... bisogna elaborarla e svuotarla
      // In questo esempio semplicemente la si stampa ...
      Serial.println(inputString);
      //
      // e la si ripulisce per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
  }
}


Purtroppo però il risultato è questo

Code: [Select]
29.57
29.57
29.57
29.57
29.57
299
299 ..57
29.57
9.57
29.57
29.57
29.57
29.57
29.57
29.57
299

.55 ..57
29.57
2957
29.57
29.57
29.57
29.57
29.57
29.57
299
7

 ..57
29.57
29.5
29.57
29.57
29.57
29.57
29.57
29.57
299

22 ..57


Non capisco....

P.S. : il discorso di astro sulle unioni e puntatori mi ha stuzzicato parecchio però meglio che faccio una cosa alla volta !
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 08:42 pm

...
Comunque.. oggi a un certo punto mi è sceso sangue dal naso a forza di ragionare. Ho iniziato mettendo sulla UNO um mySerial.println così automaticamente mi accoda al valore il carriage. Giusto ?


"Errare humanum est, perseverare autem diabolicum" ...  ]:D
... devi leggere il REFERENCE (http://arduino.cc/en/Reference/SoftwareSerialPrintln) ... non puoi inventare ciò che fanno le istruzioni :

Quote
Prints data to the transmit pin of the software serial port, followed by a carriage return and line feed.


... quindi NO, non va bene, perché accoda DUE caratteri ... non per nulla ti avevo scritto di inviare con una print() il carattere 0x0D !

Code: [Select]
if (valore > 0) {
     mySerial.print(valore);
     mySerial.print(0x0D);
     Serial.println(valore);
     delay(1000);
}


Per il resto ...
... la SoftwareSerial la puoi usare tranquillamente a 9600 e ben oltre, non ti serve farla lavorare a 4800, rallenti solo l'invio.

Poi ... per adattare un codice, prima ti devi mettere li e studiarlo con attenzione !

Non ha senso aver messo MAXCHAR a 1 ... MAXCHAR indica quanti caratteri, al massimo, è lunga la tua string, per poter correttamente dimensionare un array di char per riceverla senza sprecare spazio (altrimenti avrei messo nel codice char inputString[255] e non c'erano problemi). Quindi ...
... valuta la lunghezza massima in caratteri del numero che spedirai ed aggiusta MAXCHAR.

Ti chiedo poi, giusto per essere sicuro ... ti sei ricordato vero di mettere tutte le masse in comune ... quella della MEGA e quelle degli Arduino collegati ?

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 15, 2013, 08:58 pm
Ok... hai ragione... mi sfuggono sempre i dettagli...

Le masse e i collegamenti sono ok ovviamente.
Ho letto e letto attentamente lo sketch che hai postato e credo di aver capito abbastanza come lavora ma ovviamente non tanto da poterlo insegnare !  XD
Solo una domanda: il punto vale come carattere ?
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 15, 2013, 09:32 pm
Niente... ma porca zozza ! Ma possibile che sia così complicato trasmettere un caccoloso numero con la virgola ??? E che cos'è ? Il terzo segreto di fatima ??? Possibile che non esiste nessuno che mi sa spiegare come fare senza indovinelli, misteri e soprattutto senza scervellarmi per 5 giorni ??
Mi manca solo questo per andare avanti.....................

Scusate lo sfogo ma è frustrante.

Possibile che non esiste una guida "Inviare e ricevere float for Dummies " ??

=( =( =(
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 09:47 pm
Tutto vale come carattere ... anche il punto ;)

Guarda che non serve una guida per trasmettere i float ... perché allora servirebbe per trasmettere qualsiasi cosa ... si trasmette TUTTO allo stesso modo ... carattere a carattere e, carattere a carattere si riceve ...

Ora, con calma, ricopia e incolla qui sia il programma che trasmette, che il programma che riceve ... nella loro nuova veste, e vediamo cosa c'è che non va ...

Ah ... la fretta di voler vedere funzionare qualche cosa ... è una pessima consigliera ... ;)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 15, 2013, 10:02 pm
Trasmettitore
Code: [Select]
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11);

float valore = 0.0 ;       

void setup() 
{

  Serial.begin(9600);
  mySerial.begin(9600);
}

void loop()
{
  valore = 29.57;           
   
  if (valore > 0) {
     mySerial.print(valore);
     mySerial.print(0x0D);
     Serial.println(valore);
     
}

}


ricevitore
Code: [Select]
#include <SoftwareSerial.h>                    //includo libreria
SoftwareSerial mySerial(10,11);                //assegno pin tx e rx

#define MAXCHAR  5
#define TERCHAR 0x0D

char inputString[MAXCHAR + 1];
char inChar;
byte strIndex;


void setup() {
 
  strIndex = 0;
  inputString[strIndex] = 0x00;
 
  Serial.begin(9600);
  mySerial.begin(9600);
}

void loop() {
 
  if (mySerial.available()) {
    inChar = mySerial.read();
    // se si vogliono vedere in HEX i caratteri che si ricevono
    // togliere il commento alla riga seguente
     //Serial.println(inChar, HEX);
    if (inChar == (char) TERCHAR) {
      // è arrivato il carattere terminatore, si puo' elaborare la stringa
      // In questo esempio semplicemente la si stampa ...
      Serial.println(inputString);
      // finito il suo uso la si ripulisce per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
    // NON è arrivato il carattere terminatore, si memorizza il carattere ricevuto
    // e si sposta il fine stringa ...
    inputString[strIndex] = inChar;
    strIndex++;
    if (strIndex > MAXCHAR) {
      // ... NON c'è pi` spazio nella stringa ... bisogna elaborarla e svuotarla
      // In questo esempio semplicemente la si stampa ...
      Serial.println(inputString);
      //
      // e la si ripulisce per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
  }
}


E questo è il risultato
Code: [Select]
329.577 29.571329.57
1329.55 29.571329.571329.5
71329.. 29.571329.571329.571329.
5713299 29.571329.571329.571329.571329.571329.571329.
.571322 9.571329.571329.571329.571329.5713229.571329.571329.571329.57132#$
9.57133 9.571329.571329.571329.571329.5713229.571329.571329.571329.57132)*
29.5711 9.571329.571329.571329.571329.5713229.57171329.1329.571329.57132/0
329.577 9.571329.571329.571329.571329.5713229.57171329.9.571371329.5713256
1329.55 9.571329.571329.571329.571329.5713229.57171329.9.5713329.5757132;<
71329.. ..571329.571329.571329.571329.5713229.57171329.9.5713329.5771329
5713299 .9.57139.571329.571329.571329.5713229.57171329.9.5713329.5771329
.571322 .9.5713329.5729.571329.571329.5713229.57171329.9.5713329.5771329

9.57133 .9.5713329.57571329329.571329.5713229.57171329.9.5713329.5771329
29.5711 .9.5713329.5757132929.5711329.5713229.57171329.9.5713329.5771329
329.577 .9.5713329.5757132929.5711329.5713229.57171329.9.5713329.5771329
13229.. .9.5713329.5757132929.5711329.5571329.57171329.9.5713329.5771329%&
5717133 .9.5713329.5757132929.5711329.557132929.571329.9.5713329.5771329+,
29.9.55 .9.5713329.5757132929.5711329.557132929.5711329.55713329.577132912
7133299 .9.5713329.5757132929.5711329.557132929.5711329.5.571329.577132978
.577133 .9.5713329.5757132929.5711329.557132929.5711329.5.5713229.571329=>
29.9.55 29.5713329.5757132929.5711329.557132929.5711329.5.5713229.571713
7133299 29..571329.5757132929.5711329.557132929.5711329.5.5713229.571713

.575711 29..5713229.571132929.5711329.557132929.5711329.5.5713229.571713
32929.. 29..5713229.57171329..5711329.557132929.5711329.5.5713229.571713
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 10:25 pm
Mmm ... sembra che il buffer sia troppo piccolo e ci siano delle sovrascritture, o che non riconosca il terminatore. Fai una cosa, modifica così il programma di ricezione che vediamo di capire cosa veramente arriva (ti stamperà in HEX ogni singolo carattere ricevuto e poi la stringa completa) ...

Code: [Select]

#include <SoftwareSerial.h>                    //includo libreria
SoftwareSerial mySerial(10,11);                //assegno pin tx e rx

#define MAXCHAR  6
#define TERCHAR 0x0D

char inputString[MAXCHAR + 1];
char inChar;
byte strIndex;


void setup() {
 
  strIndex = 0;
  inputString[strIndex] = 0x00;
 
  Serial.begin(9600);
  mySerial.begin(9600);
}

void loop() {
 
  if (mySerial.available()) {
    inChar = mySerial.read();
    // se si vogliono vedere in HEX i caratteri che si ricevono
    // togliere il commento alla riga seguente
    Serial.print("Char ricevuto : ");
    Serial.println(inChar, HEX);
    if (inChar == (char) TERCHAR) {
      // è arrivato il carattere terminatore, si puo' elaborare la stringa
      // In questo esempio semplicemente la si stampa ...
      Serial.print("Stringa ricevuta : ");
      Serial.println(inputString);
      // finito il suo uso la si ripulisce per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
    // NON è arrivato il carattere terminatore, si memorizza il carattere ricevuto
    // e si sposta il fine stringa ...
    inputString[strIndex] = inChar;
    strIndex++;
    if (strIndex > MAXCHAR) {
      // ... NON c'è pi` spazio nella stringa ... bisogna elaborarla e svuotarla
      // In questo esempio semplicemente la si stampa ...
      Serial.print("Overflow : ");
      Serial.println(inputString);
      //
      // e la si ripulisce per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
  }
}


.... copialo ed incollalo così come è, compreso il MAXCHAR più grande ... e dimmi cosa ti stampa ... ;)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 15, 2013, 10:30 pm
Code: [Select]
Char ricevuto : FFFFFFFE
Char ricevuto : 32
Char ricevuto : 39
Char ricevuto : 2E
Char ricevuto : 35
Char ricevuto : 37
Overflow : ?þ29.577R329.5771329.571329.571329.571329.571329.571329.571329.571329.571
Char ricevuto : 31
Char ricevuto : 33
Char ricevuto : 32
Char ricevuto : 39
Char ricevuto : 2E
Char ricevuto : 35
Char ricevuto : 37
Overflow : 1329.577R329.57252535371329.571329.571329.571329.571329.571329.571329.571

Char ricevuto : 31
Char ricevuto : 33
Char ricevuto : 32
Char ricevuto : 39
Char ricevuto : 2E
Char ricevuto : 35
Char ricevuto : 37
Overflow : 1329.577R329.5725253535253.3.71329.571329.571329.571329.571329.571329.571
Char ricevuto : 31
Char ricevuto : 33
Char ricevuto : 32
Char ricevuto : 39
Char ricevuto : 2E
Char ricevuto : 35
Char ricevuto : 37
Overflow : 1329.577R329.5725253535253.3.353.3.171329.571329.571329.571329.571329.571
Char ricevuto : 31
Char ricevuto : 33
Char ricevuto : 32
Char ricevuto : 39
Char ricevuto : 2E
Char ricevuto : 35
Char ricevuto : 37
Overflow : 1329.577R329.5725253535253.3.353.3.1.3.1.1971329.571329.571329.571329.571"#
Char ricevuto : 31
Char ricevuto : 33
Char ricevuto : 32
Char ricevuto : 39
Char ricevuto : 2E
Char ricevuto : 35
Char ricevuto : 37
Overflow : 1329.577R329.5725253535253.3.353.3.1.3.1.193.1919171329.571329.571329.571)*
Char ricevuto : 31
Char ricevuto : 33
Char ricevuto : 32
Char ricevuto : 39
Char ricevuto : 2E
Char ricevuto : 35
Char ricevuto : 37

ecco....
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 10:56 pm
Ahahahahah ... non ci sono dubbi che qualche cosa NON quadra ...  :smiley-mr-green: :smiley-mr-green:

... è chiaramente visibile che la parte ricevente stà ricevendo REGOLARMENTE (scartando il primo valore, poiché probabilmente non era ancora in ricezione quando tu hai cominciato a trasmettere e ha letto porcheria) : 0x31 che è '1', 0x33 che è '3', 0x32 che è '2', 0x39 che è '9', 0x2E che è il punto, 0x35 che è '5' e 0x37 che è '7'.

Quindi ... la stringa che riceve in continuazione è : 1329.57 e non 29.57 ... e sai perché ?

Perché (... mea culpa che non c'ho pensato) per inviare il CR (0x0D = 13 in decimale) NON puoi usare la print() che lo trasforma nei suoi due caratteri ASCII che lo compongono (1 e 3), ma la write() !!!

Code: [Select]
mySerial.print(valore);
mySerial.write(0x0D);


Modifica e prova ... ;)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 15, 2013, 11:04 pm
Code: [Select]
Stringa ricevuta :
29.57
Char ricevuto : 32
Char ricevuto : 39
Char ricevuto : 2E
Char ricevuto : 35
Char ricevuto : 37
Char ricevuto : D
Stringa ricevuta :
29.57
Char ricevuto : 32
Char ricevuto : 39
Char ricevuto : 2E
Char ricevuto : D
Stringa ricevuta :
29.57
Char ricevuto : 37
Char ricevuto : 35
Char ricevuto : 35
Char ricevuto : 2E
Char ricevuto : 39
Char ricevuto : 37
Overflow :
755.977R25.9275.922755.9255.92
5.92
7.92
7792
7752
775.
775.9
75.9275.92
Char ricevuto : 35
Char ricevuto : 35
Char ricevuto : 2E
Char ricevuto : 39
Char ricevuto : 32
Char ricevuto : 35
Char ricevuto : 35
Overflow : 55.92555R25.9275.92275.922
5.92
5.92
7.92
7792
7752
775.
775.9
75.9275.92
Char ricevuto : 2E
Char ricevuto : 39
Char ricevuto : 32
Char ricevuto : D
Stringa ricevuta : .929255
R25.9275.92275.922
5.92
5.92
7.92
7792
7752
775.
775.9
75.9275.92
Char ricevuto : 35
Char ricevuto : 2E
Char ricevuto : 39
Char ricevuto : 32
Char ricevuto : D
Stringa ricevuta :
5.9255
R25.9275.92275.922
5.92
75.9
7.92
7792
7752
775.
775.9
75.9275.92
Char ricevuto : 37
Char ricevuto : 2E
Char ricevuto : 39
Char ricevuto : 32
Char ricevuto : D
Stringa ricevuta :
7.9255
R25.9275.92275.922
5.92
75.92
75.
7792
7752
775.
775.9
75.9275.92 !
Char ricevuto : 37
Char ricevuto : 37
Char ricevuto : 39
Char ricevuto : 32
Char ricevuto : D
Stringa ricevuta :
779255
R25.9275.92275.922
5.92
75.92
75.22
75
7752
775.
775.9
75.9275.92%&
Char ricevuto : 37
Char ricevuto : 37
Char ricevuto : 35
Char ricevuto : 32
Char ricevuto : D
Stringa ricevuta :
775255
R25.9275.92275.922
5.92
75.92
75.2


ci siamo quasi !
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: dr4gone on Dec 15, 2013, 11:10 pm

Ahahahahah ... non ci sono dubbi che qualche cosa NON quadra ...  :smiley-mr-green: :smiley-mr-green:

... è chiaramente visibile che la parte ricevente stà ricevendo REGOLARMENTE (scartando il primo valore, poiché probabilmente non era ancora in ricezione quando tu hai cominciato a trasmettere e ha letto porcheria) : 0x31 che è '1', 0x33 che è '3', 0x32 che è '2', 0x39 che è '9', 0x2E che è il punto, 0x35 che è '5' e 0x37 che è '7'.

Quindi ... la stringa che riceve in continuazione è : 1329.57 e non 29.57 ... e sai perché ?

Perché (... mea culpa che non c'ho pensato) per inviare il CR (0x0D = 13 in decimale) NON puoi usare la print() che lo trasforma nei suoi due caratteri ASCII che lo compongono (1 e 3), ma la write() !!!

Code: [Select]
mySerial.print(valore);
mySerial.write(0x0D);


Modifica e prova ... ;)

Guglielmo


OT

Giù il cappello.
Sto seguendo questa discussione da oggi... e da un paio di giorni i tuoi suggerimenti agli utenti del forum,.
Non c'è niente da dire. ne sai una più del diavolo! :)
Di solito non mi esprimo in questi termini.. ma in questo caso....
Si vede che di esperienza ne hai da vendere. :D
Complimenti! ;)

P.s. scusate l' OT  :smiley-mr-green:
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 15, 2013, 11:14 pm
In pratica le prime 35 volte ha lavorato a dovere... poi inizia a mettere quelle "stringhe" lunghissime... ho provato a mettere un delay sulla trasmittente ma non cambia nulla..

ps: concordo con dr4gone nonostante la mia frustrazione..
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 11:23 pm

...
Si vede che di esperienza ne hai da vendere. :D
Complimenti! ;)


Ma no, dai ...  :smiley-red: :smiley-red: :smiley-red:
... e che sono ... appena 30 anni che faccio questo lavoro e quindi ... ne ho viste ...  :smiley-mr-green: :smiley-mr-green: :smiley-mr-green:

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 11:26 pm

In pratica le prime 35 volte ha lavorato a dovere... poi inizia a mettere quelle "stringhe" lunghissime... ho provato a mettere un delay sulla trasmittente ma non cambia nulla..


Ecco, questo invece è un bel problema ...
... perché ora il codice si comporta correttamente, ma ... ogni tanto, senza un'apparente ragione, sembra che vada in "overflow" NON controllato e sovrascriva la memoria ... e questo ... non dovrebbe comunque accadere, visto che c'è un apposito controllo sull'overflow ...  :smiley-roll:

Ci devo ragionare ...

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 15, 2013, 11:28 pm
Ahpperò... mica poco...

Potrebbe essere che MAXCHAR dopo un tot non viene preso in considerazione ? Che senso ha che per un pò va e poi sbrocca ?
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 11:35 pm
NO, quello non è possibile, invece mi sono accorto che nel codice che ti ho copiato all'inizio ... manca una riga ...  :smiley-roll:

Code: [Select]

#include <SoftwareSerial.h>                    //includo libreria
SoftwareSerial mySerial(10,11);                //assegno pin tx e rx

#define MAXCHAR  6
#define TERCHAR 0x0D

char inputString[MAXCHAR + 1];
char inChar;
byte strIndex;


void setup() {
 
  strIndex = 0;
  inputString[strIndex] = 0x00;
 
  Serial.begin(9600);
  mySerial.begin(9600);
}

void loop() {
 
  if (mySerial.available()) {
    inChar = mySerial.read();
    // se si vogliono vedere in HEX i caratteri che si ricevono
    // togliere il commento alla riga seguente
    Serial.print("Char ricevuto : ");
    Serial.println(inChar, HEX);
    if (inChar == (char) TERCHAR) {
      // è arrivato il carattere terminatore, si puo' elaborare la stringa
      // In questo esempio semplicemente la si stampa ...
      Serial.print("Stringa ricevuta : ");
      Serial.println(inputString);
      // finito il suo uso la si ripulisce per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
    // NON è arrivato il carattere terminatore, si memorizza il carattere ricevuto
    // e si sposta il fine stringa ...
    inputString[strIndex] = inChar;
    strIndex++;
    inputString[strIndex] = 0x00;   // <<<<<<<<<<<<<<<<<<<<<<<< MANCAVA QUESTO
    if (strIndex > MAXCHAR) {
      // ... NON c'è pi` spazio nella stringa ... bisogna elaborarla e svuotarla
      // In questo esempio semplicemente la si stampa ...
      Serial.print("Overflow : ");
      Serial.println(inputString);
      //
      // e la si ripulisce per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
  }
}


... e senza quella riga, manca il terminatore di stringa (0x00) e quindi ... quando va in stampa, succede di tutto e di più :)

Guglielmo

P.S. : Questo dovrebbe risolvere le stringhe lunghissime, ma non capisco perché, ogni tanto, riceva porcheria ... comunque aggiungi quella riga e dimmi come va ;)
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 15, 2013, 11:43 pm
... credo ci sia un'altra piccola correzione ...

Code: [Select]
if (strIndex > MAXCHAR) {

deve diventare :

Code: [Select]
if (strIndex >= MAXCHAR) {

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 15, 2013, 11:56 pm
Guglieeeeeeeelmooooo !!!

Sto per piangere !!!!
Nell'attesa che mi rispondessi proseguivo imperterrito nelle mie ricerche e prove e ho messo insieme questo
Code: [Select]
#include <SoftwareSerial.h>                    //includo libreria
SoftwareSerial mySerial(10,11);                //assegno pin tx e rx

float valore;                                  //valore finale float

void setup() {
  Serial.begin(9600);                          //inizializzo la seriale
 
  mySerial.begin(9600);                        // inizializzo la seriale software
}

void loop() {
  while (mySerial.available() > 0) {           //finchè la mySerial è in trasmissione

  valore =  mySerial.parseFloat();
    Serial.println(valore);
    }
  }



E funzionaaaaaaaa !!!!!!! Sarà una scorciatoia diseducativa  XD ma funzionaaaaa !
Ciò non toglie che il tuo sistema serve comunque in tutti gli altri casi...
Infatti adesso vado ad apportare le correzioni che hai riportato.
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 16, 2013, 12:03 am
Ho apportato le modifiche al tuo sketch ma non cambia niente... anzi si accorcia la stringa overflow.
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 16, 2013, 12:13 am
... mi dai due notizie interessanti :

1. che la parseFloat() funziona ... cosa che a me in precedenza non aveva funzionato, quindi dovevo avere qualche problema io nel mio sorgente.  :smiley-roll:

2. che comunque invece le modifiche sul codice non ti hanno risolto il problema ... e questo è veramente incomprensibile ...  :smiley-eek:

Domani faccio delle prove pratiche e ti saprò dire ... ;)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 16, 2013, 12:15 am

... anzi si accorcia la stringa overflow.


Si, quello è quello che mi aspettavo ... ora dovrebbero essere corrette e non dovrebbe più sparare delle raffiche di caratteri leggendoli dalla memoria. Il problema è ... perché perde il sincronismo e perché va in overflow ???  :smiley-eek: :smiley-eek: :smiley-eek:

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 16, 2013, 12:21 am
A sto punto sono curioso anche io perchè in realtà il parseFloat non mi risolve al 100%. Infatti lo step successivo sarebbe ricevere 2 valori float da ogni arduino UNO, uno relativo alla temperatura rilevata e uno relativo alla temperatura impostata..
Siccome il parseFloat si ferma al primo numero con virgola che trova come faccio a mandarne due ? Ho letto 30 volte le reference ma non mi pare di aver capito che si possa fare...
Quote
list : the stream to check for floats (char)

Cosa viene inteso qui ?
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 16, 2013, 12:29 am
Non capisco .. la sto provando da me e ... non sbaglia un colpo ...

C'è effettivamente un problema con l'overflow ...
... quando va in overflow, bisogna infatti aggiungere un piccolo loop che pulisce il buffer in ingresso, altrimenti, quando ricomincia a leggere, legge i vecchi caratteri che erano rimasti nel buffer ! ;)

Se hai pazienza, domani mattina sistemo il codice, faccio un altro piccolo test e te lo metto qui.

Per l'altra tua domanda relativa all'uso del parseFloat...
... suppongo tu debba fare delle println() separate, una per ogni float e delle parseFloat separate una per ogni float che devi ricevere ... ma non ne sono certo, non l'ho mai usata  :D :D :D

Continuo a dire che è meglio avere sotto il proprio controllo la situazione e saper gestire ogni possibile caso (... capendo come fare) che affidarsi a dei blocchetti già fatti che oggi qui trovi, domani, in un altro ambiente, non trovi più ;)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 16, 2013, 12:36 am
Concordo !
Buonanotte e grazie intanto !
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 16, 2013, 12:50 am
Difficile andare a letto con il tarlo nella mente ...  :smiley-mr-green: :smiley-mr-green: :smiley-mr-green:

Versione aggiornata e collaudata del mio codice :

Code: [Select]

#define MAXCHAR  10
#define TERCHAR  0x0D

char inputString[MAXCHAR + 2];
char inChar;
byte strIndex;


void setup() {
 
 strIndex = 0;
 inputString[strIndex] = 0x00;
 
 Serial.begin(9600);
 
}

void loop() {
 
 if (Serial.available()) {
   inChar = Serial.read();
   // se si vogliono vedere in HEX i caratteri che si ricevono
   // togliere il commento alla riga seguente
   // Serial.println(inChar, HEX);
   if (inChar == (char) TERCHAR) {
     // è arrivato il carattere terminatore, si puo' elaborare la stringa
     // In questo esempio semplicemente la si stampa ...
     Serial.print(F("Input string : "));
     Serial.println(inputString);
     //
     // finito il suo uso la si ripulisce per un uso successivo
     strIndex = 0;
     inputString[strIndex] = 0x00;
   }
   // NON è arrivato il carattere terminatore, si memorizza il carattere ricevuto
   // e si sposta il fine stringa ...
   inputString[strIndex] = inChar;
   strIndex++;
   inputString[strIndex] = 0x00;
   if (strIndex > MAXCHAR + 1) {
     // ... NON c'è pi` spazio nella stringa ... bisogna elaborarla e svuotarla
     // In questo esempio semplicemente la si stampa ...
     Serial.print(F("Overflow string : "));
     Serial.println(inputString);
     delay(5);
     Serial.print(F("More chars : "));
     Serial.println(Serial.available());
     // Butta via i caratteri che erano rimasti nel buffer della seriale ...
     while (Serial.available()) {
         delay(5);
         Serial.read();
     }
     //
     // e ripulisce la stringa per un uso successivo
     strIndex = 0;
     inputString[strIndex] = 0x00;
   }
 }
}


... ho ampliato di un carattere il buffer e inserito, in caso di overflow, un ciclo di svuotamento del buffer. Come vedi ci sono dei piccolissimi ritardi (dei delay(5)) che servono a dare il tempo ai vari caratteri di arrivare anche a basse velocità ;)

Devi riadattarlo alla tua SoftwareSerial ... visto che io le prove le sto facendo sulla Serial connessa alla USB ;)

Buona notte  XD

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Maurotec on Dec 16, 2013, 01:56 am
Quote


Posts: 17
View Profile
   
   
Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
« Reply #49 on: Today at 06:21:00 pm »
   Bigger Bigger Smaller Smaller Reset Reset
A sto punto sono curioso anche io perchè in realtà il parseFloat non mi risolve al 100%. Infatti lo step successivo sarebbe ricevere 2 valori float da ogni arduino UNO, uno relativo alla temperatura rilevata e uno relativo alla temperatura impostata..
Siccome il parseFloat si ferma al primo numero con virgola che trova come faccio a mandarne due ? Ho letto 30 volte le reference ma non mi pare di aver capito che si possa fare...


@Marcobz
Ho letto tutti i post, mi sembra evidente che l'approccio è sbagliato, e questo ti porta in confusione, perché in effetti se fosse così complicato spedire e ricevere dati in pochi saprebbero farlo.

Studiare il reference non è risolutivo, ciò non vuol dire che non va studiato, per cui devi integrare altre conoscenze.
Studia come è composto un float. Un float in Arduino è un tipo che occupa in memoria 4 byte.
I byte sono spediti nudi e crudi e ricevuti alla stessa maniera.

Più dati spediti in sequenza devono essere ricevuti nella stessa sequenza. Il protocollo software serve proprio a spedire e ricevere dati in modo che il ricevente sappia che i 4 byte spediti per primo sono la temperatura ambiente
gli altri 4 byte ricevuti per secondi sono la temperatura richiesta o viceversa.

C'è un modo semplice per spedire dati in modo ordinato e riceverli nello stesso ordine ed è quello di creare un pacchetto dati. Il pacchetto nel tuo caso è formato da 8 byte che se spediti 2 volte rappresentano per il ricevente due pacchetti. Stivare i dati in una struttura (keyword struct) semplifica il lavoro, la stessa struct l'avrai nel trasmittente e nel ricevente. Un struct composta da due dati di tipo float puo essere scandita byte per byte e inviata via seriale. Il ricevente riceve byte per byte e allora basta scrivere nella variabile di tipo struct 8 byte per il primo pacchetto. Questo dovrebbe farti capire anche che devi trovare il modo di capire quando inizia il pacchetto e quando finisce. La struct da inviare allora protrebbe essere composta da un byte, due float, e un byte, totale 10 byte.


Quando ricevi da seriale testi se il primo byte vale es 10 (decimale) se lo è i byte seguenti li scrivi byte per byte fino a che non ricevi un byte che es vale 20.

Es:
spedisci:
Startpack (10), 8 byte (i due float) e per ultimo il byte di EndPack(20)

Ho dei nomi al valore 10 e 20, cioè StartPack e EndPack, solo per intenderci, ma non è escluso si possano usare nel codice.
struct data {
    float tAmb;
    float tSet;
}

struct data dataSending;  // crea una variabile di tipo struct
dataSending.tAmb = 22.5;
dataSending.tSet   = 25.0;
for (byte i=0; i<sizeof(data); i++) { // clicla n volte in base a quanto è grande la struct data
    // qui spedisci i dati byte per byte
    // come scomporre la variabile dataSending in byte ora non mi viene (è tardi e sono cotto)
}

Vedi se riesci a capirci qualcosa, perché di tempo per scrivere tutto funzionante non nè ho.
In alternativa puoi usare il metodo parse... aggiungendo la gestione dei pacchetti, con start pack e end pack. Capisci? quando trasmetti chi riceve non è a conoscenza di quando hai iniziato a trasmettere.

PS: l'organizzazione dei dati in struct o contenitori come le classi o array ecc è solo una rappresentazione C/C++,
rappresentazioni create per aiutare il programmatore ad organizzare i dati e nel caso della classi unisce dati e metodi legati ai dati all'interno appunto di classi, ma tutto alla fine è fatto di byte o bit.

Ciao.
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 16, 2013, 06:34 am

@Marcobz
Ho letto tutti i post, mi sembra evidente che l'approccio è sbagliato, e questo ti porta in confusione, perché in effetti se fosse così complicato spedire e ricevere dati in pochi saprebbero farlo.


Ciao Mauro,
non è così complicato, ma non è nemmeno così semplice e ...
... il problema al momento NON è come trasferire uno o più float, cosa che affronterà in seguito, il problema (... se così si può chiamare ;) ) è mettere su una comunicazione seriale che preveda la gestione dell'overflow, la futura gestione del timeout, ecc. senza ricorre a ... scorciatioie dell'IDE (parseXXXX).

Una volta che ha messo a punto un bel sistema per trasmettere/ricevere, in modo controllato, una qualsiasi sequenza di byte ... usarlo per spedire ciò che si vuole non è un problema. :)

E, come vedi dai vari post, l'intento di questo thread è proprio questo ...

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 16, 2013, 07:31 am

E funzionaaaaaaaa !!!!!!! Sarà una scorciatoia diseducativa  XD ma funzionaaaaa !


Sembra, ma ... ecco un'altro esempio in cui un blocchetto chiuso ... ti nasconde quello che realmente accade ...

Leggendo carattere a carattere, stiamo evidenziando che, comunque, un qualche cosa di sporco sulla seriale c'è ... altrimenti non andrebbe mai in overflow e ti darebbe sempre la stinga pulita, mente, tutto il lavoro che stiamo facendo è per "intercettare" condizioni particolari e per gestirle (caratteri di troppo, mancanza del CR, ...)

Sai perché non vedi nulla di tutto questo con la parseXXXX ? ... E' scritto nel reference (http://arduino.cc/en/Serial/ParseFloat) :

Quote
Serial.parseFloat() returns the first valid floating point number from the Serial buffer. Characters that are not digits (or the minus sign) are skipped. parseFloat() is terminated by the first character that is not a floating point number.


Quindi ... qualsiasi porcheria accada sulla linea, tu non la vedrai MAI ... e se dei dati arrivano corrotti, semplicemente li perderai senza nessun avvertimento.

Come vedi c'è una bella differenza, nella realtà pratica, tra usare quella e ... controllarsi da soli quello che succede ;)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: PaoloP on Dec 16, 2013, 09:50 am
La cosa più semplice per capire come funziona è guardare il listato.
Le funzioni sono in Stream.cpp
Code: (Stream.cpp) [Select]
// returns the first valid (long) integer value from the current position.
// initial characters that are not digits (or the minus sign) are skipped
// function is terminated by the first character that is not a digit.
long Stream::parseInt()
{
 return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
}

// as above but a given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
long Stream::parseInt(char skipChar)
{
 boolean isNegative = false;
 long value = 0;
 int c;

 c = peekNextDigit();
 // ignore non numeric leading characters
 if(c < 0)
   return 0; // zero returned if timeout

 do{
   if(c == skipChar)
     ; // ignore this charactor
   else if(c == '-')
     isNegative = true;
   else if(c >= '0' && c <= '9')        // is c a digit?
     value = value * 10 + c - '0';
   read();  // consume the character we got with peek
   c = timedPeek();
 }
 while( (c >= '0' && c <= '9') || c == skipChar );

 if(isNegative)
   value = -value;
 return value;
}


// as parseInt but returns a floating point value
float Stream::parseFloat()
{
 return parseFloat(NO_SKIP_CHAR);
}

// as above but the given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
float Stream::parseFloat(char skipChar){
 boolean isNegative = false;
 boolean isFraction = false;
 long value = 0;
 char c;
 float fraction = 1.0;

 c = peekNextDigit();
   // ignore non numeric leading characters
 if(c < 0)
   return 0; // zero returned if timeout

 do{
   if(c == skipChar)
     ; // ignore
   else if(c == '-')
     isNegative = true;
   else if (c == '.')
     isFraction = true;
   else if(c >= '0' && c <= '9')  {      // is c a digit?
     value = value * 10 + c - '0';
     if(isFraction)
        fraction *= 0.1;
   }
   read();  // consume the character we got with peek
   c = timedPeek();
 }
 while( (c >= '0' && c <= '9')  || c == '.' || c == skipChar );

 if(isNegative)
   value = -value;
 if(isFraction)
   return value * fraction;
 else
   return value;
}


Le funzioni usano due metodi privati della classe per leggere il carattere successivo.
Code: [Select]
// private method to peek stream with timeout
int Stream::timedPeek()
{
 int c;
 _startMillis = millis();
 do {
   c = peek();
   if (c >= 0) return c;
 } while(millis() - _startMillis < _timeout);
 return -1;     // -1 indicates timeout
}

// returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters
int Stream::peekNextDigit()
{
 int c;
 while (1) {
   c = timedPeek();
   if (c < 0) return c;  // timeout
   if (c == '-') return c;
   if (c >= '0' && c <= '9') return c;
   read();  // discard non-numeric
 }
}


Read, Peek e Flush sono dichiarate virtuali e si riferiscono alla classe chiamante la classe Stream, ad esempio Serial.
Code: [Select]
virtual int read() = 0;
virtual int peek() = 0;
virtual void flush() = 0;

Quindi il read() può essere interpretato come Serial.read(), cioè legge un carattere dalla Seriale.
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Etemenanki on Dec 16, 2013, 10:01 am
Scusa, forse sto dicendo una ca**ata, ma non potrebbe essere la Mega ad interrogare a turno i vari slave, invece di passare tutto il tempo ad aspettare la loro trasmissione ? ... tipo:

(master>slave1) "inizia trasmissione" (e poi si mette in ricezione, se entro, esempio, 5 secondi, non riceve nulla, riprova, dopo 3 tentativi senza ricevere nulla segnala allarme mancanza comunicazione con slave 1, cosi c'e' pure una segnalazione di possibile malfunzionamento)

(slave1) (dopo un secondo di pausa, per consentire al master di passare in ricezione senza problemi) trasmette una stringa composita con tutti i valori in sequenza, ad esempio, carattere inizio stringa (puo essere *), primo valore, separatore (puo essere |), secondo valore, fine stringa (puo essere #), per due volte di seguito (come controllo) ... se la stringa fosse di lunghezza fissa, sarebbe meglio (ad esempio, spedendo sempre i valori della temperatura come quantita' fisse di bytes, potrebbero bastare 5 caratteri per dato, positivo/negativo, prima cifra, seconda cifra, punto decimale, cifra decimale ... in questo modo una stringa completa sarebbe sempre di 13 bytes, e una trasmissione sempre di 26), perche' cosi il master non dovrebbe controllarle in tempo reale, basterebbe che le infilasse in ordine in un buffer da 26 caratteri (o in due da 13, per semplificare il controllo comparandoli), e che le controllasse dopo averle ricevute tutte ...

(master) mentre riceve piazza tutto in un buffer, al termine della ricezione controlla che le due meta' della stringa siano uguali, se no, la trasmissione e' errata e ripete il tutto (max 3 volte, poi segnala errore), se si, trasforma le parti "numeriche" della stringa in valori numerici, li elabora, ci fa quello che vuoi, poi svuota il buffer e passa a "slave 2" ... e cosi via ...

In questo modo saprebbe sempre quale slave sta rispondendo, e cosa gli sta mandando, controllerebbe per errori di comunicazione, e non dovrebbe tenere sempre una linea aperta in ricezione mentre fa il resto (l'interrogazione degli slave potrebbe farla anche ogni 5 secondi, tanto la temperatura ambiente non cambia piu di tanto velocemente) ... inoltre in questo modo gli slave potrebbero trasmettere "codici di errore" se necessario quando interrogati, al posto del valore di temperatura, ed il master potrebbe discriminarli (magari perche' cominciano con un carattere diverso) ed eseguire le opportune azioni  ... o sbaglio e l'idea e' stupida ?
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 16, 2013, 10:14 am

Scusa, forse sto dicendo una ca**ata, ma non potrebbe essere la Mega ad interrogare a turno i vari slave, invece di passare tutto il tempo ad aspettare la loro trasmissione ? ...


Ahahahah ... SI, ma è ovvio che poi farà così, anzi ...
... la lettura dalla seriale dovrà diventare proprio una funzione che o gli ritorna l'array di char (se ha ricevuto qualche cosa di valido) o gli ritorna NULL in caso di errore (overflow, timeout, ...) e lui la chiamerà quando gli servirà di leggere una data porta ;)


Ragazzi, sappiamo che siete tutti bravissimi i materia e che problemini del genere sono banalità (tu, Paolo, ecc.) ... ma, scusate ... vi manca la parte "didattica" ...

... ce li volete far arrivare per gradi e da soli o gli dovete sempre dire tutto e fare voi il lavoro ???  XD XD XD

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: PaoloP on Dec 16, 2013, 10:25 am
:smiley-sweat: =(
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Etemenanki on Dec 16, 2013, 10:43 am

... sappiamo che siete tutti bravissimi ...


Gli altri di sicuro, ma io proprio no :P XD ... ricordati che sono un'hardwarista, non un softwarista ;)
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 16, 2013, 10:57 am

Gli altri di sicuro, ma io proprio no :P XD ... ricordati che sono un'hardwarista, non un softwarista ;)


XD Dai, dai, non fare il modesto ... che hai la tua gran bella esperienza ;)

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 16, 2013, 06:16 pm
Aggiornamento:

tra le mie mille ricerche mi è capitata in mano una libreria chiamata EasyTransfer. Me la sono studiata un pò e ho provato a mettere giù uno sketch  per le mie esigenze.
Ecco il risultato:

PARTE TRASMITTENTE

Code: [Select]
#include <SoftEasyTransfer.h>  //includo la libreria ET
#include <SoftwareSerial.h>    //includo la libreria SS
SoftwareSerial mySerial(10, 11); //definisco le porte della SS
SoftEasyTransfer ET;              //creo l'oggetto ET

struct SEND_DATA_STRUCTURE{        //creo la struttura della serie di dati
  float valore1;                   //definisco quali variabili devono far parte della struttura
  float valore2;
};
SEND_DATA_STRUCTURE mydata;        //do un nome al gruppo di variabili

float valore1=20.97;               //dichiaro le variabili
float valore2=19.88;

void setup(){
  mySerial.begin(9600);            //faccio partire la SS
  ET.begin(details(mydata), &mySerial);  //faccio partire la ET
  Serial.begin(9600);                    //faccio partire la seriale 
}
void loop(){
  mydata.valore1 = valore1;        //do un valore alle variabili con la struttura [nome del gruppo].[nome della variabile]
  mydata.valore2 = valore2;        //do un valore alle variabili con la struttura [nome del gruppo].[nome della variabile]
  Serial.println(valore1);
  Serial.println(valore2);
  ET.sendData();//invio i dati
  delay(1000);
}

Ho provato a commentare le righe per far capire come funziona.

PARTE RICEVENTE

Code: [Select]
#include <SoftEasyTransfer.h>  //includo la libreria ET
#include <SoftwareSerial.h>    //includo la libreria SS
SoftwareSerial mySerial(10, 11); //definisco le porte della SS
SoftEasyTransfer ET;              //creo l'oggetto ET

struct RECEIVE_DATA_STRUCTURE{    //creo la struttura
  float valore1;                  //stesse variabili del TX
  float valore2;
};
float valore1;                    //le dichiaro
float valore2;                    //le dichiaro
RECEIVE_DATA_STRUCTURE mydata;     //do lo stesso nome del TX alla struttura

void setup(){
  mySerial.begin(9600);            //faccio partire la SS
  ET.begin(details(mydata), &mySerial);  //faccio partire la ET
  Serial.begin(9600);                    //faccio partire la seriale 
}

void loop(){
  if(ET.receiveData()){        //controllo se è arrivato un pacchetto di dati
  valore1 = mydata.valore1;    //assegno i valori ricevuti alle variabili
  valore2 = mydata.valore2;
  Serial.println(valore1);     //le stampo
  Serial.println(valore2);
    }
  delay(250); //fortemente consigliato per non perdere pezzi del messaggio ricevuto
}


So che Guglielmo storcerà il naso.. Però FUNZIONA !!!
Tral l'altro da quello che ho capito ci sono diverse versioni della libreria. Questa SoftEasyTransfer nello specifico credo sia dedicata alle comunicazioni su seriale software (che poi è quello che mi serve).
Dal puro lato didattico non è il massimo.. lo so.. però per quanto mi riguarda non è che adesso smetto di cercare di imparare quello di cui si stava qui discutendo !

;)
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 16, 2013, 06:26 pm
Bene, contento tu ...   ]:D

... così non impari nulla e la prima volta che quella lib non ti funzionerà o, un giorno magari non sarà più supportata ... sarai da capo a dodici.

Ma ripeto ... contento tu ... contenti tutti !!!  :smiley-mr-green: :smiley-mr-green: :smiley-mr-green:

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 16, 2013, 06:40 pm
No non mi fraintendere !
Ho anche detto che il discorso affrontato fino a qui lo vorrei continuare ! Ovviamente se le parti sono interessate.... io lo sono !
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 16, 2013, 07:03 pm

Ho anche detto che il discorso affrontato fino a qui lo vorrei continuare ! Ovviamente se le parti sono interessate.... io lo sono !


Ok, allora metti l'ultima versione a cui sei arrivato e dimmi che problemi ti da ... che riprendiamo da li ...

Guglielmo
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Maurotec on Dec 16, 2013, 07:55 pm
Io non conosco nel dettaglio la SoftEasyTransfer, però da quello che vedo nel codice che hai postato mi sembra una libreria ben fatta. Più o meno è quello che dicevo nel mio post precedente riguardo alle struct usate come payload.

Preferisco questo del payload per vari motivi:
1) La classe o funzione che spedisce i dati è generica e non legata ad un tipo utente, ma richiede semplicemente un puntatore a byte e la lunghezza del payload in byte.
2) I dati da spedire sono messi in ordine e ricevuti nello stesso ordine in modo automatico grazie alla condivisione della struct.
3) La classe può essere personalizzata aggiungendo dei metodi setStartCode(int code) e setEndCode(int code)
questo permette al ricevente di scegliere il tipo di collezione di dati.
Un tipo di collezione di dati potrebbe essere:
- Dati di configurazione (code = 1)
- Dati di aggiornamento (code = 2)
- Dati di instradamento (code = 3)
- Dati di configurazione remota (code = 4)

In ricezione basta uno switch case startCode per ricevere dati e usarli in modo specifico, modo stabilito dal trasmittente.

@gpb01
Di soluzioni a problemi conosciuti (design pattern) ce n'è più di una, basta conoscerle tutte e scegliere quella che
preferiamo, questa del payload è una, le altre suggerite con tutte le varianti e quelle a venire sono tutte da scoprire.

Ciao.
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: Marcobz on Dec 17, 2013, 09:34 pm
Eccomi qua !

Scusa l'assenza Guglielmo ma è un periodo "pregno"  :smiley-mr-green:

Ho adattato lo sketch al mio caso
Code: [Select]
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11);


#define MAXCHAR  10
#define TERCHAR  0x0D

char inputString[MAXCHAR + 2];
char inChar;
byte strIndex;


void setup() {
 
  strIndex = 0;
  inputString[strIndex] = 0x00;
  mySerial.begin(9600);
  Serial.begin(9600);
 
}

void loop() {
 
  if (mySerial.available()) {
    inChar = mySerial.read();
    // se si vogliono vedere in HEX i caratteri che si ricevono
    // togliere il commento alla riga seguente
    // Serial.println(inChar, HEX);
    if (inChar == (char) TERCHAR) {
      // è arrivato il carattere terminatore, si puo' elaborare la stringa
      // In questo esempio semplicemente la si stampa ...
      Serial.print(F("Input string : "));
      Serial.println(inputString);
      //
      // finito il suo uso la si ripulisce per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
    // NON è arrivato il carattere terminatore, si memorizza il carattere ricevuto
    // e si sposta il fine stringa ...
    inputString[strIndex] = inChar;
    strIndex++;
    inputString[strIndex] = 0x00;
    if (strIndex > MAXCHAR + 1) {
      // ... NON c'è pi` spazio nella stringa ... bisogna elaborarla e svuotarla
      // In questo esempio semplicemente la si stampa ...
      Serial.print(F("Overflow string : "));
      Serial.println(inputString);
      delay(5);
      Serial.print(F("More chars : "));
      Serial.println(Serial.available());
      // Butta via i caratteri che erano rimasti nel buffer della seriale ...
      while (mySerial.available()) {
          delay(5);
          mySerial.read();
      }
      //
      // e ripulisce la stringa per un uso successivo
      strIndex = 0;
      inputString[strIndex] = 0x00;
    }
  }
}


e questo è il risultato
Code: [Select]
Overflow string : þ29.571329.5
More chars : 0

Che ne dici se commentiamo ogni riga a scopo esplicativo per chi vuole capire ? Tipo io ?  XD
Title: Re: 6 Arduini UNO che comunicano un float a un MEGA 2560 con SoftwareSerial
Post by: gpb01 on Dec 17, 2013, 09:59 pm
Allora,
primo ... occhio che non hai sostituito una Serial :

Code: [Select]
Serial.print(F("More chars : "));
Serial.println(Serial.available());


deve diventare :

Code: [Select]
Serial.print(F("More chars : "));
Serial.println(mySerial.available());


perché stiamo vedendo quanti caratteri ci sono ancora nel buffer della SoftwareSerial.

Poi ...
... ma ti da solo quello ???  Ovvero se lasci girare il tutto per 30 secondi ... cosa succede ... hai tutte le ricezioni errate ???

O capita ogni tanto ...

Guglielmo