comunicazione tra 2 arduini via seriale

salve

dovrei inviare da un arduino ad un altro via seriale un gruppo di variabili intere senza usare le stringhe
pensavo di usare un array di interi ma non so come inviare il pacchetto via seriale in una trasmissione unica

sarebbe possibile?

grazie

Crei un array di interi e poi usi write

nid69ita:
Crei un array di interi e poi usi write

cosi?

int dati[3] = {3, 3, 3};

void setup() {
Serial.begin(9600);

}

void loop() {
  
for (int i = 0; i < 3; i++) 
         {
          Serial.write(dati[i]);
         }
 delay (2000);
}

e poi come faccio a riceverlo nel secondo arduino per reinserire i dati ancora in un array

ma li rileggete i post che fate ? ... devo sempre correggerli perché fate un disastro nell'editare i QUOTE, inserire le risposte e quant'altro ... ::slight_smile:

Cortesemte, dopo aver postato, RILEGGETE e, se occorre, corregete !!! Grazie.

Guglielmo

La funzione 'write' di Arduino scrive un byte alla volta, vedi qui, così come la funzione 'read' legge un byte alla volta. Di questo bisogna tener conto nella predisposizione degli array di output e di input.

Se si devono trasmettere interi o float o long conviene scomporli in byte in trasmissione e ricomporli in ricezione con semplici sequenze logiche.

Ciao,
P.

birrohgt:
cosi?

No, cosi:
Serial.write( (byte*)dati,sizeof(dati));

Io ti sconsiglio l'uso di write, fai una spedizione di dati "binario", meglio inviare i dati con print ovvero con una spedizione di dati testuali. Avrai il problema di convertire in lato ricezione da stringa/testo a numero ma meglio che "smontare" un int in 2 byte e poi "rimontarli" in ricezione.
In una trasmissione seriale poi è sempre bene crearsi un protocollo, esempio invia per prima cosa un carattere inizio trasmissione (esempio @) e poi a fine trasmissione #. In mezzo mandi i dati testuali.
Con la trasmissione binaria non è semplice inventarsi un valore inizio trasmissione non usato (spediamo dei byte, valori da 0 a 255 quali non usa un int ?? )

nid69ita:
No, cosi:
Serial.write( (byte*)dati,sizeof(dati));

grazie
e in ricezione come ricompongo ancora array?

In ricezione NON c'è nessuna certezza che ti arrivano i byte nella giusta sequenza o che possano esserci "perdite".

Comunque, in ricezione ricevi un byte alla volta, dovrai aspettare di ricevere 2 byte per "rimontare" l'intero.
Non ricordo se prima viene spedita parte alta o la bassa del valore int
Quando hai i due byte li metti insieme con una moltiplicazione.

byte c1,c2; // i due byte ricevuti
...
c1=Serial.read();
...
c2=Serial.read();
...
valint=c1*256+c2;

es. 4660 = 0x1234 in esadecimale, quindi verrà spedito 0x12 e poi 0x34 (o viceversa non ricordo)
ricevi c1=0x12 (ovvero 18) e c2=0x34 (ovvero 52)
18*256+52=4660

Dovresti anche controllare che c1 e/o c2 non siano -1 (ovvero errore in lettura read)

nid69ita:
Quando hai i due byte li metti insieme con una moltiplicazione.

Credo che sia un modo poco efficiente per ricostruire un intero a partire da due byte.
Usando l’operatore shift e un po’ di matematica booleana si ottiene un codice molto più “snello” rispetto all’eseguire calcoli che coinvolgono dei float.

// Lato TX
unsigned int num1 = 1500; // == 0x05DC == 0b0000 0101 1101 1100
unsigned char lsb, msb;   // byte == unsigned char

lsb = num1 & 0xFF;           // otteniamo il byte più significativo (quello di sinistra) 0x05 == 0b0000 0101
msb = ( num1 >> 8 ) & 0xFF;  // otteniamo il byte meno significativo (quello di destra) 0xDC == 0b1101 1100

// Lato RX
unsigned int num2 = 0;
num2 = (msb<<8) | lsb;  // byte msb spostato a sinistra di 8 posizioni in OR con il byte lsb.

cotestatnt:
all'eseguire calcoli che coinvolgono dei float.

?? 256 è un int
int = int * int non coinvolge float, avrei dovuto scrivere 256.0 per coinvolgerli.

allora vi ringrazio tutti per i consigli e gli aiuti ma ho un po di confusione in testa

io dovrei inviare delle variabili int multiple da e riceverle in un altro arduino

questo è il codice in tx

int dati[3] = {25, 325, 1025};

void setup() {
Serial.begin(9600);

}

void loop() {
 
Serial.write( (byte*)dati,sizeof(dati));

 delay (2000);
}

nella ricezione come dovrei fare

int dati[3];

void setup() {
Serial.begin(9600);
}
void loop() {

if (Serial. available())
{
 non capisco come devo leggere la seriale
}

grazie

nid69ita:
avrei dovuto scrivere 256.0 per coinvolgerli.

Hai ragione, ho scritto una stupidaggine. :o
Tra l'altro se il compilatore fa bene il suo lavoro il codice assembly alla fine se non è lo stesso, poco ci manca.
@birrohgt l'istruzione per leggere dalla seriale è quella che ti ha già scritto nid69ita, Serial.read(), ma prima di tutto deve essere chiaro come vengono memorizzati i diversi tipi di dati in Arduino e come un "numero" viene rappresentato in un calcolatore.
Una variabile int occupa 2 byte quindi ad esempio il numero decimale 1500, "rappresentato" in esadecimale è 0x05 DC

Ricapitolando, il tuo array di 3 elementi avrà una dimensione totale di 6 byte, che devi leggere uno per uno e "re-infiocchettare" come detto nei post precedenti.
Comunque una qualsivoglia trasmissione fatta alla cieca in questo modo non è mai una buona idea.
Prevedi un minimo di protocollo... almeno un byte di START ed uno di STOP cosi sai con certezza quando ricevi questi famosi 6 byte e puoi fare le operazioni necessarie correttamente.

si grazie per il consiglio infatti volevo fare anche un protocollo per riconoscere il dato che sta arrivando ma su questo sono un po indietro e on so come fare mi daresti qualche dritta?
grazie gentilissimo

>birrohgt: Quando si quota un post, NON è necessario riportarlo (inutilmente) tutto; bastano poche righe per far capire di cosa si parla ed a cosa ci si riferisce, inoltre, se si risponde al post immediatamente precedente, normalmente NON è necessario alcun "quote" dato che è sottinteso. :slight_smile:

Gli utenti da device "mobile" (piccoli schermi) ringrazieranno per la cortesia :wink:

Guglielmo

P.S.: Ho eliminato io il "quote" dal tuo post qui sopra :wink:

ok grazie scusa :slight_smile:

Talvolta un nostro problema è già stato affrontato da qualcun altro. Per un protocollo di comunicazione prova a dare un'occhiata qui

Ciao,
P.

nid69ita:
No, cosi:
Serial.write( (byte*)dati,sizeof(dati));

Io ti sconsiglio l'uso di write, fai una spedizione di dati "binario", meglio inviare i dati con print ovvero con una spedizione di dati testuali. Avrai il problema di convertire in lato ricezione da stringa/testo a numero ma meglio che "smontare" un int in 2 byte e poi "rimontarli" in ricezione.
In una trasmissione seriale poi è sempre bene crearsi un protocollo, esempio invia per prima cosa un carattere inizio trasmissione (esempio @) e poi a fine trasmissione #. In mezzo mandi i dati testuali.
Con la trasmissione binaria non è semplice inventarsi un valore inizio trasmissione non usato (spediamo dei byte, valori da 0 a 255 quali non usa un int ?? )

se seguo il tuo consiglio come dovrei fare per inviare delle variali int tipo misurazioni di temperature senza usare le stringhe?

partendo sempre dalla array di int?

grazie

Le variabili che sono più grandi di UN byte, vanno sempre suddivise nei bytes che le compongono, trasmessi i singoli byte e ricostrute le variabili a destinazione oppure, creando una struttura (struct) e vedendo questa come una serie continua di bytes che trasmetto, dall'altra parte ricevo, rimetto in una identica struttura e mi ritrovo, senza sforzo, tutto ciò che la compone. Il tutto con un decente protocollo che mi dica se ho ricevuto tutto e se l'ho ricevuto esente da errori ... ::slight_smile:

Guglielmo

ti ringrazio ma non so bene come fare :confused: :confused: :confused:
mi potresti aiutare
grazie

In merito a cosa ? ... perché come suddividere un 'int' in due 'byte' e poi ricomporlo (che è la cosa più semplice) te lo ha ben scritto cotestatnt al post #8 e ti a messo anche il codice :slight_smile:

Scrivere un protocollo di trasmissione "sicuro" è invece cosa ben più complessa e ... pgiagno, al post #15, ti ha indicato una libreria che, oltre al link da lui riportato, è anche qui in megatopic, la libreria PJON. Sul sito indicato da pgiagno è anche possibile scaricare l'ultima versione e trovare tutta la documentazione.

Poi, naturamente, puoi anche, a tuo rischio e pericolo di perdere dati per strada, non usare un protocollo e trasmettere e ricevere in modo "brutale", ma ...
... se qualche cosa si perde per strada ... sai solo tu che succede ... ::slight_smile:

Guglielmo