Creare buffer di trasmissione per udp

Ho messo a punto la comunicazione udp tra Master e slave
Ora ho un problema e un dubbio
Adesso chiamo uno Slave e mi risponde con una stringa fissa.
Ed é tutto ok
Come faccio a impacchettare più informazioni (byte)nella stessa trasmissione ?
Poi trasmettendo la temperatura ad esempio , ho sia il segno che i decimali ,float temp =-12.5
Quando invio la variabile, mi trasmette la variabile float o mi tronca il segno e i decimali?
Poi se faccio udp.write(var1,var 2…) funziona ?
Se li faccio singoli udp.write il buffer di arrivo é completo o contiene solo l ultimo valore ?
Troppe domande ?

A qualche domanda mi sono risposto da solo provando , se faccio più udp.write le trasmissioni finiscono sempre nello stesso buffer e quindi posso elaborare la stringa di arrivo. Non si concatenano , udp.write(var1,var2..). Adesso devo capire come trasmettere un valore con segno e decimali .

non puoi "impacchettare" i vari dati dentro una stringa (magari con un separatore, tipo "12.4|33.65|27") e mandare quella, per poi nel ricevente splittare i valori e riconvertirli con toFloat()?

Il problema da quello che ho capito è che la trasmissione converte in un byte io dovrei prendere la temperatura e dividerla in più byte e poi ricomporla Byte segno , byte gradi , byte decimali Ps sto aspettando "Il libro dei Creatori" così se ci riesco provo a spezzettare un numero

Converte in un byte? Dove lo hai letto? No, no, è che la Udp.write() ha overload in base al tipo di dato che mandi, per cui se mandi stringa è stringa, se mandi un valore numerico allora lo interpreta come byte! Vedi il reference del metodo: https://www.arduino.cc/en/Reference/EthernetUDPWrite Occhio, non puoi usare oggetti String ma solo char! Quindi ad esempio NON va fatto:

   Udp.beginPacket(RemoteIP, RemotePort);
   Udp.write("x=");
   Udp.write(mioValore);
   Udp.endPacket();

ma:

   Udp.beginPacket(RemoteIP, RemotePort);
   char msg[20];
   sprintf(msg, "x=%d", mioValore);
   Udp.write(msg);
   Udp.endPacket();

Ovviamente poi alla ricezione devi riconvertire da stringa a float. Fammi sapere se questo ti può aiutare.

Ancora non sono riuscito a fare una prova seria, se domani pomeriggio non succede niente al lavoro faccio qualche esperimento serio. Una prova al volo non ha funzionato , ma chissà se ho fatto giusto Comunque grazie

io penso di essere cretino :frowning:
non riesco

allora uso questo per inviare i dati via udp

Udp.write(WiFi.localIP()[3]);
Udp.write(", ");
Udp.write(itoa (statoD0,a,10));
Udp.write(", ");
Udp.write(itoa (statoD1,b,10));
Udp.write(", ");
Udp.write(itoa (statoD2,c,10));
Udp.write(", ");
Udp.write(itoa (statoD3,d,10));
Udp.write(", ");
Udp.write(dtostrf(val, 4, 4, T));

arriva tutto al master
poi li decodifico cosi

else if (packetBuffer[0] == 104) {
          Serial.print(" -------------------");
          Serial.print(packetBuffer[0], DEC);
          Serial.print(" ------------------");
          len4 = packetSize;
          for (int index = 0;  index < packetSize; index++) {
            m4_sta[index] = packetBuffer[index];
          }
          Serial.println("");
        }

e li butto dentro la pagina web
con questo

for (int index = 0;  index < len4; index++) {
        webPageHome += m4_sta[index] ;

e fino qui tutto ok
ma perche di tutti i numeri che trasmetto solo WiFi.localIP()[3] il terzo byte mi vieni scritto H nella pagina web ?

ho provato in tutti i modi,
anche cosi

/*  char stringaTs[30] ; 
    //strcat(stringaTs, "%d"); 
    strcat(stringaTs, String(WiFi.localIP()[3]));  
    //strcat(stringaTs, "; ");
    strcat(stringaTs,itoa (statoD0,a,10) ); 
    //strcat(stringaTs, "; ");
    strcat(stringaTs,itoa (statoD1,b,10) ); 
   // strcat(stringaTs, "; "); 
    strcat(stringaTs,itoa (statoD2,c,10) );
    //strcat(stringaTs, "; ");
    strcat(stringaTs,itoa (statoD3,c,10) );
    //strcat(stringaTs, "; ");
    strcat(stringaTs,dtostrf(val, 4, 4, T) );
    Udp.write(stringaTs);
    Serial.println(stringaTs);

ma mi aggiunge 56,147,254,63,allynizio
questi maledetti byte che non so da dove vengono e mi smonta tutti i numeri(poco male ) 56,147,254,63,10,49,48…gli untimi tre sono 104 …perfetto ma i primi cosa sono, li mette sempre
cosa mi sto perdendo ?

dimenticavo che se faccio cosi
webPageHome += String(WiFi.localIP()[3]);nella pagina leggo 104

alla fine fo risolto cosi

char sendtxt[100];
sprintf(sendtxt,"%sout1%dout2%din1%din2%dTemp",WiFi.localIP().toString().c_str(),statoD0,statoD1,statoD2,statoD3);
strcat(sendtxt,dtostrf(val, 4, 4, T) );
Serial.println(sendtxt); 
Udp.write(sendtxt);

accodo alla fine val adesso devo inserire il crc

Per questo genere di cose io consiglio sempre la libreria PString, semplice, comoda ed efficiente.

Se proprio vuoi usare sprintf(), strcat() & co, almeno usa le versioni "sicure" snprintf(), strncat(), ecc.

Il CRC lascialo perdere, UDP ha già un suo checksum che garantisce l'integrità dei dati (se arrivano).

Per ora i dati arrivano sempre , e comunico con 5 slave Volevo ritrasmettere se arrivavano corrotti e se non avevo risposta quind aggiungendo un crc se non ricevevo un ok dallo slave ritrasmettevo. Cosa intendi per versioni sicure ?

Ripeto che UDP ha un suo meccanismo di checksum interno, per cui i dati o arrivano o non arrivano, non è possibile che arrivino corrotti (in realtà sì, ma non vengono passati all'applicazione, per cui dal suo punto di vista non arrivano e basta).

Mandare una risposta e reinviare i dati in mancanza di questa vuol dire che sostanzialmente stai implementando una sorta di "TCP dei poveri" su UDP. Ma a questo punto non puoi usare direttamente TCP?

Le versioni sicure sono quelle con una n nel nome, che prendono un parametro extra per la dimensione del buffer. Fai una ricerca su Google.

Io stavo implementando un mini protocollo tipo modbus , in modo di avere nella stringa anche i comandi , della sicurezza mi interessa poco non ci devo far camminare i treni .
i comandi li faccio locali sui moduli slave e concentro tutto su un master
Cosi gli slave sono sempre raggiungibili. In caso di guasto master
Ognuno vive di vita propria , ha tutte le funzioni e si autoconfigura per la rete , e può funzionare da solo , poi concentro i dati su un master che serve solo per agevolare il collegamento alllo slave.
Avere una stringa udp di comando sarebbe una cosa in piu per comandi generali
Immagina una rete di plc modbus dove anche senza master funziona tutto , e tutto èraggiungibile

In bocca al lupo.

Vi terrò aggiornati , sono già a un buon punto, adesso già è tutto funzionante , devo aggiungere finezze e alleggerire il programma . Comunque tanti spunti e aiuti li ho soprattutto trovati qui dentro .