Struct non riceve

Buongiorno,
ho la necessità di ricevere a comando , su un arduino mega, dei dati di alcuni sensori montati su un arduino mega.
creando una struct il loop nessun problema, il mittente invia e il destinatario riceve.

il problema sta quando implemento il codice di richiesta.
in questo caso l'ordine parte, viene ricevuto, i dati vengono ricavati dai sensori, vengono inviati ma il ricevitore non li visualizza. inserendo un return alla fine i dati vengono visualizzati ma il mittente continua a inviare i dati anche se sostituisco il comando di richiesta.

RICEVITORE

#include "AR_000_Master_DEF.h"

/*
    - - -UNION
*/

//UNION - DATA_001_ProxDis_PACK --> 000_Master
struct DATA_001_ProxDis  //Definiamo la struttura e il tipo
{
  long  distanzaUT_00S;
  long  distanzaUT_01S;
  long  distanzaUT_02S;
  long  distanzaUT_03S;
  long  distanzaUT_04S;

  long  distanzaUT_05S;
  long  distanzaUT_06S;
  long  distanzaUT_07S;
  long  distanzaUT_08S;
  long  distanzaUT_09S;

  long  distance00_ASS;
  long  distance01_PSS;
  long  distance00_ADS;
  long  distance01_PDS;

  long BSL_00_X;
  long BSL_00_Y;
  long BSL_00_Z;
  long BSL_00_AN;
};
DATA_001_ProxDis DATA_001_ProxDis_PACK; //Diamo un nome alla struttura
int i = 0;  // inizializiamo la variabile per memoprizzare i valori a 0
byte buff [5000]; // dichiariamo una grandezza in caratteri dello spazio per la ricezione

void setup() {
  Serial.begin(9600); // inizializiamo la seriale monitor
  Serial1.begin(115200); //inizializiamo la seriale per la comunicazione con AR_001_DCM
  Serial.println ("Serial 0-1 Started");

  Serial.println("AR_000_MASTER : STATUS OK");
}

void loop() {

  Serial1.write(0);
  delay(5);
  while (Serial1.available())   // finché dalla seriale di ricezione é disponibile
  {
    byte n = Serial1.read();    // leggi i caratteri ricevuti e mettili in n
    if ((char)n == '\n') // se il carattere n é uguale a '\n'
    {
      memcpy(&DATA_001_ProxDis_PACK, buff, i); //memorizza i caratteri ricevuti in sequenza fino al massimo dichiarato  in i

      Serial.print("U_ASS : ");  Serial.print(DATA_001_ProxDis_PACK.distanzaUT_00S); Serial.print("  ||  ");
      Serial.print("U_ASA : ");  Serial.print(DATA_001_ProxDis_PACK.distanzaUT_01S); Serial.print("  ||  ");
      Serial.print("U_ACT : ");  Serial.print(DATA_001_ProxDis_PACK.distanzaUT_02S); Serial.print("  ||  ");
      Serial.print("U_ADA : ");  Serial.print(DATA_001_ProxDis_PACK.distanzaUT_03S); Serial.print("  ||  ");
      Serial.print("U_ADD : ");  Serial.println(DATA_001_ProxDis_PACK.distanzaUT_04S);

      Serial.print("U_PSS : ");  Serial.print(DATA_001_ProxDis_PACK.distanzaUT_05S); Serial.print("  ||  ");
      Serial.print("U_PSP : ");  Serial.print(DATA_001_ProxDis_PACK.distanzaUT_06S); Serial.print("  ||  ");
      Serial.print("U_PCT : ");  Serial.print(DATA_001_ProxDis_PACK.distanzaUT_07S); Serial.print("  ||  ");
      Serial.print("U_PDD : ");  Serial.print(DATA_001_ProxDis_PACK.distanzaUT_08S); Serial.print("  ||  ");
      Serial.print("U_PDP : ");  Serial.println(DATA_001_ProxDis_PACK.distanzaUT_09S);

      Serial.print("H_AS : ");  Serial.print(DATA_001_ProxDis_PACK.distance00_ASS); Serial.print("  ||  ");
      Serial.print("H_PS : ");  Serial.println(DATA_001_ProxDis_PACK.distance01_PSS);

      Serial.print("H_AD : ");  Serial.print(DATA_001_ProxDis_PACK.distance00_ADS); Serial.print("  ||  ");
      Serial.print("H_PD : ");  Serial.println(DATA_001_ProxDis_PACK.distance01_PDS);

      Serial.print("BSL_000_X : ");  Serial.print(DATA_001_ProxDis_PACK.BSL_00_X); Serial.print("  ||  ");
      Serial.print("BSL_000_Y : ");  Serial.print(DATA_001_ProxDis_PACK.BSL_00_Y); Serial.print("  ||  ");
      Serial.print("BSL_000_Z : ");  Serial.print(DATA_001_ProxDis_PACK.BSL_00_Z); Serial.print("  ||  ");
      Serial.print("BSL_000_AN : ");  Serial.println(DATA_001_ProxDis_PACK.BSL_00_AN);

      Serial.print("ricevuti"); Serial.print(i);             // stampa la scritta ricevuti seguito dal valore di i
      Serial.print("bytes - END"); Serial.print("\n");       // stampa la scritta byte -end e vai a capo
      i = 0;        // riporta i a valore 0
                }
    else            // altrimenti
    {
      buff[i] = n;  // scrivi il valore n in i
      i++;         //sposta la posizione di scrittura in i di un carattere avanti
      
    }
  }
  return; 
}






/*
* * * * QUI PARTE IL MITTENTE
/*




//SPEGNAMO TUTTI I SENSORI UR
  for (int i = 0 ; i < 9; i++)  
  {
    digitalWrite (UST_PIN[i], LOW);
    digitalWrite (USE_PIN[i], LOW);
  }
  // - - - - - - - - - - - - - - - - - - - - - - - -
  
  int r = 0;
  r = Serial1.read();

  if (r == 1)
  {
    /*
* TUTTE LE VARIE LETTURE DEI SENSORI FUNZIONANTI
    */


    Serial.print("U_ASS : ");  Serial.print(distanzaUT_00); Serial.print("  ||  ");
    Serial.print("U_ASA : ");  Serial.print(distanzaUT_01); Serial.print("  ||  ");
    Serial.print("U_ACT : ");  Serial.print(distanzaUT_02); Serial.print("  ||  ");
    Serial.print("U_ADA : ");  Serial.print(distanzaUT_03); Serial.print("  ||  ");
    Serial.print("U_ADD : ");  Serial.println(distanzaUT_04);


    Serial.print("U_PSS : ");  Serial.print(distanzaUT_05); Serial.print("  ||  ");
    Serial.print("U_PSP : ");  Serial.print(distanzaUT_06); Serial.print("  ||  ");
    Serial.print("U_PCT : ");  Serial.print(distanzaUT_07); Serial.print("  ||  ");
    Serial.print("U_PDD : ");  Serial.print(distanzaUT_08); Serial.print("  ||  ");
    Serial.print("U_PDP : ");  Serial.println(distanzaUT_09);

    Serial.print("H_AS : ");  Serial.print(distance00_AS); Serial.print("  ||  ");
    Serial.print("H_PS : ");  Serial.println(distance01_PS);

    Serial.print("H_AD : ");  Serial.print(distance00_AD); Serial.print("  ||  ");
    Serial.print("H_PD : ");  Serial.println(distance01_PD);

    Serial.print("BSL_000_X : ");  Serial.print(event.magnetic.x); Serial.print("  ||  ");
    Serial.print("BSL_000_Y : ");  Serial.print(event.magnetic.y); Serial.print("  ||  ");
    Serial.print("BSL_000_Z : ");  Serial.print(event.magnetic.z); Serial.print("  ||  ");
    Serial.print("BSL_000_AN : ");  Serial.println(headingDegrees);

    Serial.println("\n");
    Serial.println();
    Serial.println();
    Serial.println("-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -");
    Serial.println();
    Serial.println();

    DATA_001_ProxDis_PACK.distanzaUT_00S = distanzaUT_00;
    DATA_001_ProxDis_PACK.distanzaUT_01S = distanzaUT_01;
    DATA_001_ProxDis_PACK.distanzaUT_02S = distanzaUT_02;
    DATA_001_ProxDis_PACK.distanzaUT_03S = distanzaUT_03;
    DATA_001_ProxDis_PACK.distanzaUT_04S = distanzaUT_04;

    DATA_001_ProxDis_PACK.distanzaUT_05S = distanzaUT_05;
    DATA_001_ProxDis_PACK.distanzaUT_06S = distanzaUT_06;
    DATA_001_ProxDis_PACK.distanzaUT_07S = distanzaUT_07;
    DATA_001_ProxDis_PACK.distanzaUT_08S = distanzaUT_08;
    DATA_001_ProxDis_PACK.distanzaUT_09S = distanzaUT_09;

    DATA_001_ProxDis_PACK.distance00_ASS = distance00_AS;
    DATA_001_ProxDis_PACK.distance01_PSS = distance01_PS;
    DATA_001_ProxDis_PACK.distance00_ADS = distance00_AD;
    DATA_001_ProxDis_PACK.distance01_PDS = distance01_PD;

    DATA_001_ProxDis_PACK.BSL_00_X = event.magnetic.x;
    DATA_001_ProxDis_PACK.BSL_00_Y = event.magnetic.y;
    DATA_001_ProxDis_PACK.BSL_00_Z = event.magnetic.z;
    DATA_001_ProxDis_PACK.BSL_00_AN = headingDegrees;

    Serial1.write((const uint8_t*)&DATA_001_ProxDis_PACK, sizeof(struct DATA_001_ProxDis));
    Serial1.write((byte)'\n');
    
  }
    r = 0;
}```




in sintesi il primo codice invia 1 per inviare la richiesta e rimane in attesa

il secondo si imposta con r = 0 e appena delle 1  sostituisce il valore. se r = 1 allora procede a fare tutte le letture e inviarle, dopo di che si imposta nuovamente a 0.

se io nel primo codice (mentre la seconda è in esecuzione) sostituisco il valre con 0 e ricerico il codice, la seconda continua a fare le letture come se r =1 anche se viene sia forzata alla fine a 0 sia se il primo gli invia valore 0.

questo perchè poi dovrei ricevere altri dati da un altra arduino e vorrei i dati mi venissero mandati soltanto quando li richiedo per effettuare le successive operazioni/manovre

In conformità al REGOLAMENTO , punto 7, cortesemente edita il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone a forma di piccola matita :pencil2: che si trova in basso del tuo post), seleziona TUTTA la parte di codice e premi l'icona </> nella barra degli strumenti per contrassegnarla come codice.

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà sistemato il codice, nel rispetto del suddetto regolamento nessuno ti risponderà, quindi ti consiglio di fare il tutto al più presto. :wink:

Sicuro che nei byte binari trasmessi non compaia mai il valore dieci corrispondente al carattere di fine pacchetto '\n' ?

Ulteriore cosa, quei 5 millisecondi di attesa ricezione mi sembrano troppo pochi per 73 byte, anche se sono inviati senza ritardi a 115200 b/s.

se rimuovo tutta la parte di richiesta e lascio lavorare solo le struct invia e riceve senza problemi.
è solo implementando la richiesta che ho problemi

Boh, metti solo dei pezzi, dici che invia 1 ma c'e' nel codice

La parte di attesa è quel pezzo commentato ?!?
Sul secondo non vedo un controllo che ci sia qualcosa nella serial1 con available.
Un'altra cosa poi potrebbe aiutare una Serial1.flush() nel trasmittente.

Probabilmente con le operazioni aggiunte in più diventa evidente una carenza progettuale che nel caso più semplice passa inosservata.

Ribadisco che con il tuo algoritmo se nei dati compare casualmente un valore dieci prima del '\n' finale, la ricezione si interrompe con dati incompleti, e il resto rimane nel buffer di ricezione trasformandosi in dati errati per la prossima volta (problema di sincronizzazione di cui si parla qui: https://forum.arduino.cc/t/comunicazione-seriale-tra-arduino-uno-e-arduino-mega/866064/7).

Inoltre 5 ms di attesa del master sono insufficienti a far svolgere tutte le operazioni richieste allo slave, mentre ad aumentarlo troppo si rischia che lo slave trasmetta più byte di quelli che il buffer di ricezione del master può immagazzinare.

Inoltre il ciclo while che legge i pacchetti in arrivo può terminare prematuramente per condizione available falsa mentre i dati sono ancora in corso di trasmissione da parte dello slave.

Va riprogettato da zero il protocollo/processo di trasmissione/ricezione in modo che sia immune da tutte queste cose.

Il master deve inviare la richiesta e restare in attesa di una risposta completa entro diciamo 200ms, altrimenti considerare fallita la richiesta.

Lo slave deve attendere una richiesta, e poi trasmettere quello che deve con un formato in cui inizio e fine trasmissione siano univocamente determinabili (ad esempio con una strategia (tra le tante) tipo questa https://forum.arduino.cc/t/interpretare-un-codice-inviato-da-smartphone-via-bluetooth/670511/12#msg4711666 ).

Chi riceve deve naturalmente adottare la stessa strategia di chi trasmette, applicando sempre anche un timeout per la ricezione del prossimo byte (timeout che si ottengono misurando il tempo con la funzione millis).

Fatto ciò i problemi (di trasmissione) sono finiti :wink: