Trasmissione seriale

buon di a tutti,
sto cercando di fare comunicare 2 arduini con la serial software.
ho preso qualche pezzo qua e la e funziona, io vorrei modo di inviare
una struct da arduino A verso arduino B , quando arduino B ha ricevuto trasmette una seconda struct verso arduino A

non sono moltro bravo ma cerco di arrangiarmi con qualche copia incolla dalla rete e spesso non arrivo da solo
spero di non darvi troppo noia
grazie buona giornata

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SoftwareSerial.h>

#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
SoftwareSerial mySerial(10, 11); // RX, TX

unsigned long t1, dt;
int stato = 0;

struct mydata {
  char cmd;
  int count;
  float temp;
  char str[20];
int st_size ;
};

mydata dato = {'x', 0, 18.0f, "hello world!",0};

void setup() {
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  Serial.println("trasmettitore");
  Serial.begin(9600);
  mySerial.begin(9600);
  digitalWrite(13, LOW);
  sensors.begin();
}

void loop() {
 Serial.print("."); 
 sensors.requestTemperatures();
  dato.temp = sensors.getTempCByIndex(0);
  //Serial.println (sensors.getTempCByIndex(0));

  switch (stato) {
    case 0:
      tx();
      break;
    case 1:
      ack();
      break;
    case 2:
      timeout();
      break;
  }
}
void tx() {
dato.st_size = sizeof(struct mydata);
  Serial.print("millis "); Serial.println(millis()/100 );
  Serial.println("TX");
 
  mySerial.write((const uint8_t *)&dato, sizeof(struct mydata));
  mySerial.write((byte)'\n');
  dato.count++;
  digitalWrite(13, HIGH);
  stato = 1;
  t1 = millis();
}
bool FIRST = true;

void ack() {
  if (FIRST) {
    Serial.println("RX...");
    FIRST = false;
  }
  if (mySerial.available()) {
    byte c = mySerial.read();
    if (c == 'k') {
      Serial.println("ACK");
      mySerial.flush();
      digitalWrite(13, LOW);
      delay(500);
      stato = 0;
    }
  }
  dt = millis() - t1;
  if (dt > 5000) {
    //timeout!
    Serial.println("timeout");
    stato = 2;
  }
}
void timeout() {
  digitalWrite(13, LOW);
  digitalWrite(12, HIGH);
  stato = 0;
  delay(3000);
  digitalWrite(12, LOW);
}
//sensors.requestTemperatures();
//dato.temp = sensors.getTempCByIndex(0);
//Serial.println (sensors.getTempCByIndex(0));
//mySerial.write((const uint8_t *)&dato, sizeof(struct mydata));
//mySerial.write((byte)'\n');
//dato.count++;
//delay(1000);
//}

#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

SoftwareSerial mySerial(10, 11); // RX, TX
LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned long t1, dt;
int stato = 0;




struct mydata {
  char cmd;
  int count;
  float temp;
  char str[20];
  int st_size ;
};

mydata dato;

void setup() {
 
  pinMode(2, OUTPUT);
  lcd.init();
  lcd.backlight();
  mySerial.begin(9600);
  Serial.begin(9600);
  Serial.print(" - ");
  lcd.setCursor(0, 0);
  lcd.print("Hello, world!");
}

byte buff[30];
int i = 0;

void loop() {
   switch (stato) {
    case 0:
      recv();
      break;
    case 1:
      ack();
      break;
  }
}

void recv() {
 dt = millis() - t1;// messo per evitare che sia  
  if (dt > 300) {  //fermo in ascolto
    //timeout!
    Serial.println("timeout");
    stato = 1;
  }
  if (mySerial.available()) {
    byte n = mySerial.read();
    // if (n == 'a') {
    if ((char)n == '\n') {
      //mySerial.write((const uint8_t *)&dato, sizeof(struct mydata));
      Serial.println("rx");
      digitalWrite(2, HIGH);
      delay(500);
      digitalWrite(2, LOW);
      stato = 1;
      memcpy(&dato, buff, i);

      Serial.print(dato.cmd); Serial.print(" - ");
      Serial.print(dato.count); Serial.print(" - ");
      Serial.print(dato.temp); Serial.print("\n");
      Serial.print(dato.str); Serial.print("\n");
      Serial.print(dato.st_size); Serial.print("\n");
      Serial.print("ricevuti: ");
      Serial.print(i);
      Serial.println(" bytes - END");
      mySerial.flush();
      if (dato.st_size == i) {
        Serial.println("dati ok ");
        lcd.setCursor(1, 1);
        lcd.print(dato.temp);
        dato.st_size = 0;
      }
      else {
        Serial.println("ERRORE");
        digitalWrite(3, HIGH);
      delay(500);
      digitalWrite(3, LOW);
      lcd.setCursor(1, 1);
        lcd.print("ERRORE");
      }
      i = 0;
    }
    else {
      buff[i] = n;
      i++;
    }
  }
}
//}
void ack() {
  delay(300);
  mySerial.write('k');
  digitalWrite(2, LOW);
  Serial.println("ack");
  mySerial.flush();
  stato = 0;
  t1 = millis();
}


//while (mySerial.available()) {
// byte n = mySerial.read();
//if ((char)n == '\n') {
//  lcd.setCursor(1, 1);
//lcd.print(dato.temp);
//mySerial.write((const uint8_t *)&dato, sizeof(struct mydata));

//memcpy(&dato, buff, i);

// Serial.print(dato.cmd); Serial.print(" - ");
// Serial.print(dato.count); Serial.print(" - ");
//Serial.print(dato.temp); Serial.print("\n");
//Serial.print(dato.str); Serial.print("\n");

//Serial.print("ricevuti: ");
// Serial.print(i);
//Serial.println(" bytes - END");
//i = 0;
//} else {
//buff[i] = n;
//i++;
//}
//}
//mySerial.write((const uint8_t *)&dato, sizeof(struct mydata));
//}

Ciao!

Per poter inviare un ulteriore valore al mittente, dovresti aggiornare la struttura mydata con un altro campo per il valore aggiuntivo che vuoi inviare. Ad esempio, se vuoi inviare un intero, potresti aggiungere un campo intero alla struttura come questo:

struct mydata {
  char cmd;
  int count;
  float temp;
  char str[20];
  int st_size;
  int valueToAdd;
};

Poi, nel loop, dopo aver richiesto le temperature e aver aggiornato i dati nella struttura mydata, puoi impostare il valore aggiuntivo che vuoi inviare:

dato.valueToAdd = 123; //a seconda di quale valore vuoi inviare

Infine, nel codice tx(), devi anche includere la nuova variabile nella trasmissione:

mySerial.write((const uint8_t *)&dato, sizeof(struct mydata));
mySerial.write((byte)'\n');

E poi nel codice ack(), devi aggiornare il ricevitore per leggere il nuovo valore:

//aggiungi questa linea subito dopo il memcpy nella funzione recv():
dato.valueToAdd = *((int *)(buff + i));

In questo modo, puoi leggere il valore aggiuntivo ricevuto dal mittente e utilizzarlo come desideri.

Spero che questo ti sia utile. Fammi sapere se hai altre domande!

ciao , grazie della tua risposta , che la volevo fare dopo, ma ancora meglio !!
io volevo fare il modo che A invia la struct mydata, B la riceve e B manda ack ed una ulteriore struct , che devo ancora mettere , e da qui non so andare avanti,
si devo mandare in loop le 2 struct a vicenda senza essere bloccante, ho cercato in rete ma non trovo nulla

Buonasera @RagnarokPJ e benvenuto nella sezione Italiana del forum,

cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie,

Guglielmo

ciao, ma il post resta sempre attivo?
scusate la mia ignoranza in materia..

In che senso?

La discussione o viene chiusa da un moderatore perché ha qualche problema o si chiude da sola dopo sei mesi che nessuno partecipa più ... in entrambi i casi appere un messaggio che informa della cosa e ... qui non se ne sono visti. :wink:

Guglielmo

Magari, se spieghi BENE cosa devi fare e cosa vuoi ottenere (e non cosa stai facendo tu ora) ... qualcuno può indicarti qualche altra possibile strada.

Guglielmo

ciao a tutti , allora mi sono messo a cercare di copiare quancosa in rete e sono arrivato a questo.
il primo arduino trasmette al secondo , verifica con crc e manda una risposta.
il tutto ogni secondo
non sono in grado di fare da solo , ho preso pezzi qui i la, cosa vi sembra?

#include <SoftwareSerial.h>
#include <FastCRC.h>

SoftwareSerial mySerial(10, 11);  // RX, TX

struct Ricezione {
  float value;
  uint32_t crc;
};

struct Scrittura {
  int value;
  uint32_t crc;
};

Ricezione ricezione;
Scrittura scrittura;

unsigned long lastCommunicationTime;

FastCRC32 crc32;

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

  lastCommunicationTime = millis();
}

void loop() {
  if (mySerial.available() >= sizeof(scrittura)) {
    mySerial.readBytes((byte*)&scrittura, sizeof(scrittura));

    uint32_t calculatedCRC = crc32.crc32((byte*)&scrittura.value, sizeof(scrittura.value));
    if (calculatedCRC == scrittura.crc) {
      Serial.print("Value received from Arduino B: ");
      Serial.println(scrittura.value);

      lastCommunicationTime = millis();
    }
    else {
      Serial.println("CRC error in received data from Arduino B");
    }

    ricezione.value = 3.14;
    ricezione.crc = crc32.crc32((byte*)&ricezione.value, sizeof(ricezione.value));

    mySerial.write((byte*)&ricezione, sizeof(ricezione));

    lastCommunicationTime = millis();
  }
}

qui il secondo


`#include <SoftwareSerial.h>
#include <FastCRC.h>

SoftwareSerial mySerial(3, 4);  // RX, TX

struct Ricezione {
  float value;
  uint32_t crc;
};

struct Scrittura {
  int value;
  uint32_t crc;
};

Ricezione ricezione;
Scrittura scrittura;

unsigned long lastCommunicationTime;

FastCRC32 crc32;

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

  lastCommunicationTime = millis();
}

void loop() {
  if (millis() - lastCommunicationTime >= 1000) {
    scrittura.value = 42;
    scrittura.crc = crc32.crc32((byte*)&scrittura.value, sizeof(scrittura.value));

    mySerial.write((byte*)&scrittura, sizeof(scrittura));

    lastCommunicationTime = millis();
  }

  if (mySerial.available() >= sizeof(ricezione)) {
    mySerial.readBytes((byte*)&ricezione, sizeof(ricezione));

    uint32_t calculatedCRC = crc32.crc32((byte*)&ricezione.value, sizeof(ricezione.value));

    if (calculatedCRC == ricezione.crc) {
      Serial.print("Value received from Arduino A: ");
      Serial.println(ricezione.value);

      lastCommunicationTime = millis();
    }
    else {
      Serial.println("CRC error in received data from Arduino A");
    }
  }
}

Carini, ma ci sono dei problemi.
I più grandi sono che il tipo dati di ricezione.value e di scrittura.value sono diversi,entre dovrebbero essere uguali (anzi, a rigore dovrebbe essere una ripetizione della stessa informazione, a quanto ho capito). Inoltre assegni, lato ricevitore, un valore fisso al valore da scrivere, il quale porterà a un CRC fisso, probabilmente diverso da quello di trasmissione.
Valuterei l'opportunità di fare si che il ricevitore risponda con il solo CRC letto, per ridurre il numero di dati che passano.

ciao , grazie della risposta, le informazioni sono diverse nelle 2 strutture.
ed molte possono cambiare.
oggi mi ci metto e vedo cosa sono in grado do fare sia per il nome delle strutture che per il crc.
per il momento grazie

Quei programmi sono inadeguati e vanno riscritti

Il più grave problema é che mancano di uno start e di uno stop di trasmissione; senza di questi trasmettitore e ricevitore saranno sincroni (ovvero la trasmissione parte proprio quando il ricevitore crede stia partendo) solo per miracolo (1)

Al secondo posto tu al ricevitore lasci che il buffer di ricezione si riempia prima di svuotarlo
Con strutture grandi rischi di sbordare (2)

Al terzo posto non hai ancora ben definito chi trasmette cosa, i programmi si scrivono "dopo" aver saputo cosa devono fare, non prima

Note
1 i miracoli purtroppo avvengono, purtroppo spesso avvengono all'inizio, lasciandoti credere che vada tutto bene

2 anche i rischi purtroppo si materializzano; questi invece alla fine, quando oramai sei "sicuro" che vada tutto bene
Come vedi in tutti e dei i casi si segue la famigerata legge di Murphy

... non per nulla, avevo chiesto, al mio post #7 ... :roll_eyes:

Guglielmo

ho cercato di capire qualcosa, ho messo il carattere di inizio trasmissione , con relativo controllo del carattere , ho modificato il nome delle variabili, ora
non so' per svuotare la seriale
Arduino A

#include <SoftwareSerial.h>
#include <FastCRC.h>

SoftwareSerial mySerial(3, 4);  // RX, TX
const int blueLedPin = 9; // Pin del LED blu

struct Ricezione {
  float value_A;
  float value_B;
  int value_C;
  int value_D;
  int value_E;
  int value_F;
  bool value_G;
  bool value_H;
  bool value_I;
  uint32_t crc;
};

struct Scrittura {
  char startChar;
  //int value;
  int valore_C;
  int valore_D;
  int valore_E;
  int valore_F;
  bool valore_G;
  bool valore_H;
  bool valore_I;
  char checksum;
  char endChar;
};

Ricezione ricezione;
Scrittura scrittura;

unsigned long lastCommunicationTime;
const unsigned long ledDuration = 200;  // Durata in millisecondi per cui i LED rimangono accesi

FastCRC32 crc32;

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

  pinMode(blueLedPin, OUTPUT); // Imposta il pin del LED blu come OUTPUT

  lastCommunicationTime = millis();
}

void loop() {
  if (millis() - lastCommunicationTime >= 1000) {
    scrittura.startChar = 0x02; // Carattere di inizio trasmissione (STX)
    //scrittura.value = 42;
    scrittura.valore_C = 100;
    scrittura.valore_D = 200;
    scrittura.valore_E = 300;
    scrittura.valore_F = 400;
    scrittura.valore_G = true;
    scrittura.valore_H = false;
    scrittura.valore_I = true;
    scrittura.checksum = calculateChecksum(&scrittura, sizeof(scrittura) - 2); // Calcola il checksum escludendo startChar e endChar
    scrittura.endChar = 0x03; // Carattere di fine trasmissione (ETX)

    mySerial.write((byte*)&scrittura, sizeof(scrittura));

    lastCommunicationTime = millis();

    while (millis() - lastCommunicationTime < ledDuration) {
      // Attendi senza bloccare il loop
      digitalWrite(blueLedPin, HIGH); // Accendi il LED blu
    }

    digitalWrite(blueLedPin, LOW); // Spegni il LED blu

    lastCommunicationTime = millis();
  }

  if (mySerial.available() >= sizeof(ricezione)) {
    mySerial.readBytes((byte*)&ricezione, sizeof(ricezione));

    uint32_t calculatedCRC = crc32.crc32((byte*)&ricezione, sizeof(ricezione) - sizeof(ricezione.crc));

    if (calculatedCRC == ricezione.crc) {
      Serial.print("Values received from Arduino B:\n");
      Serial.print("Value A: ");
      Serial.println(ricezione.value_A);
      Serial.print("Value B: ");
      Serial.println(ricezione.value_B);
      Serial.print("Value C: ");
      Serial.println(ricezione.value_C);
      Serial.print("Value D: ");
      Serial.println(ricezione.value_D);
      Serial.print("Value E: ");
      Serial.println(ricezione.value_E);
      Serial.print("Value F: ");
      Serial.println(ricezione.value_F);
      Serial.print("Value G: ");
      Serial.println(ricezione.value_G);
      Serial.print("Value H: ");
      Serial.println(ricezione.value_H);
      Serial.print("Value I: ");
      Serial.println(ricezione.value_I);

      lastCommunicationTime = millis();

      while (millis() - lastCommunicationTime < ledDuration) {
        // Attendi senza bloccare il loop
        digitalWrite(blueLedPin, HIGH); // Accendi il LED blu
      }

      digitalWrite(blueLedPin, LOW); // Spegni il LED blu
    }
    else {
      Serial.println("CRC error in received data from Arduino B");
    }
  }
}

char calculateChecksum(void* data, size_t size) {
  char checksum = 0;
  char* bytes = (char*)data;

  for (size_t i = 0; i < size; i++) {
    checksum ^= bytes[i];
  }

  return checksum;
}

Arduino B


#include <SoftwareSerial.h>
#include <FastCRC.h>

SoftwareSerial mySerial(10, 11);  // RX, TX
const int blueLedPin = 3; // Pin del LED blu

struct Ricezione {
  float value_A;
  float value_B;
  int value_C;
  int value_D;
  int value_E;
  int value_F;
  bool value_G;
  bool value_H;
  bool value_I;
  uint32_t crc;
};

struct Scrittura {
  char startChar;
  //int value;
  int valore_C;
  int valore_D;
  int valore_E;
  int valore_F;
  bool valore_G;
  bool valore_H;
  bool valore_I;
  char checksum;
  char endChar;
};

Ricezione ricezione;
Scrittura scrittura;

unsigned long lastCommunicationTime;
const unsigned long ledDuration = 200;  // Durata in millisecondi per cui i LED rimangono accesi

FastCRC32 crc32;

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

  pinMode(blueLedPin, OUTPUT); // Imposta il pin del LED blu come OUTPUT

  lastCommunicationTime = millis();
}

void loop() {
  if (mySerial.available() >= sizeof(scrittura)) {
    mySerial.readBytes((byte*)&scrittura, sizeof(scrittura));

    if (scrittura.startChar == 0x02 && scrittura.endChar == 0x03) { // Verifica che i caratteri di inizio e fine trasmissione siano corretti
      char calculatedChecksum = calculateChecksum(&scrittura, sizeof(scrittura) - 2); // Calcola il checksum escludendo startChar e endChar

      if (calculatedChecksum == scrittura.checksum) {
        Serial.print("Value received from Arduino A:\n");
        //Serial.print("Value: ");
       // Serial.println(scrittura.value);
        Serial.print("Value C: ");
        Serial.println(scrittura.valore_C);
        Serial.print("Value D: ");
        Serial.println(scrittura.valore_D);
        Serial.print("Value E: ");
        Serial.println(scrittura.valore_E);
        Serial.print("Value F: ");
        Serial.println(scrittura.valore_F);
        Serial.print("Value G: ");
        Serial.println(scrittura.valore_G);
        Serial.print("Value H: ");
        Serial.println(scrittura.valore_H);
        Serial.print("Value I: ");
        Serial.println(scrittura.valore_I);

        ricezione.value_A = 1.23;
        ricezione.value_B = 4.56;
        ricezione.value_C = 789;
        ricezione.value_D = 987;
        ricezione.value_E = 654;
        ricezione.value_F = 321;
        ricezione.value_G = true;
        ricezione.value_H = false;
        ricezione.value_I = true;
        ricezione.crc = crc32.crc32((byte*)&ricezione, sizeof(ricezione) - sizeof(ricezione.crc));

        mySerial.write((byte*)&ricezione, sizeof(ricezione));

        lastCommunicationTime = millis();

        while (millis() - lastCommunicationTime < ledDuration) {
          // Attendi senza bloccare il loop
          digitalWrite(blueLedPin, HIGH); // Accendi il LED blu
        }

        digitalWrite(blueLedPin, LOW); // Spegni il LED blu
      }
      else {
        Serial.println("Checksum error in received data from Arduino A");
      }
    }
  }
}

char calculateChecksum(void* data, size_t size) {
  char checksum = 0;
  char* bytes = (char*)data;

  for (size_t i = 0; i < size; i++) {
    checksum ^= bytes[i];
  }

  return checksum;
}

mi spiace, ma le tue conoscenze ed il tuo livello di attenzione non sono bastevoli per ottenere il risultato

ti facciamo tanti auguri, ma non possiamo accompagnarti ulteriormente in questo viaggio

Fabio e Massimo

non capisco il motivo ,mi e stato chiesto cosa contiene la struttura e ho messo quelle definitive.
lo start e stop l ho messo
la parte delle variabili da dove arrivano , non fa parte di questo post.
poi ho visto ora la risposta del post 7 di gpb01 perche
avendo letto la risposta dal cellulare ho notato che perde delle risposte a caso su tutti i post(ho visto ora , che spariscono se aggiorno manualmente le pagine)
in casa sono senza linea ecco perche uso il cellulare.
in poche parole arduino 1 trasmette ogno cecondo una struct a arduino 2 arduino 2 legge e tramette una seconda struct a arduino 1
chiedo scusa per questa causa tecnica
,

Il motivo che non capisci riguarda il fatto che le tue conoscenze e il tuo livello di attenzione sono inadeguati?

se è così è presto spiegato

però siccome sappiamo che dire le cose come stanno spesso "dispiace" agli interessati, ti preghiamo di fare eventualmente domanda esplicita

nel caso ti dimostro (senza alcuna offesa, ma solo con dati di fatto) la questione

complimenti , della risposta , poi da uno colto...

Grazie

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.