Comunicazione seriale tra due microcontrollori ..

@GINGARDU
Ho iniziato il lavoro ...

il primo problema, il minore, l'ho risolto approssimativamente così:
.... per ricevere la stringa via seriale.... faccio così:

#define dimVettore 25                // lunghezza max del buffer di lettura (stringa seriale)
#define baudSeriale  4800            // velocità seriale
char stringaSERIALE[dimVettore+1]; // stringa buffer destinata a contenere la stringa ricevuta dalla seriale 
boolean stringaOK = false;

void setup() 
{
Serial.begin(baudSeriale);
}

void loop()
{
if (Serial.available()>0){leggiSeriale();}
}

void leggiSeriale()
 { 
   unsigned long count = millis();      //interrompe la lettura dalla seriale se passano più di countMax ms senza che arrivino caratteri
   unsigned long const countMax = 10;   // limite max millisecondi senza che arrivino caratteri .. oltre chiude il ciclo di lettura (non scendere sotto i 5 per 4800 bps e 10 1200bps) 
   boolean fineLettura;                 // controllo sul checksum della stringa Seriale ricevuta

   int index=1;
   // LEGGE i primi dimVettore caratteri ........
   do    
     { if(Serial.available()> 0) {stringaSERIALE[index]=Serial.read(); count = millis(); index++; } 
       fineLettura = ((index > dimVettore) || (millis() - count > countMax));}
   while (!fineLettura);   
   
   stringaSERIALE[0]= index-1; // in posizione 0 pone l'indice massimo ... servirà per il parser della stringa ...
   fineLettura = false;

    byte tempByte;
   // CANCELLA il buffer, se c'è ancora qualcosa nel buffer .....
   do
     { if(Serial.available()> 0) { tempByte = Serial.read(); count = millis();} 
       fineLettura = (millis() - count > countMax);}
   while (!fineLettura);

     int k=0;
     Serial.print("\n ......................................................................");
     Serial.print("\n\t k=0\t   "); Serial.print(stringaSERIALE[0], DEC); Serial.print(" dimensione Vett");
     while (k < stringaSERIALE[0])
     {  k++;
        Serial.print("\n\t k="); Serial.print(k); 
        Serial.print("\t   ")  ; Serial.print(stringaSERIALE[k], DEC);
        Serial.print("\t   ")  ; Serial.print(stringaSERIALE[k]); 
       }
      Serial.print("\n ...................................................................... \n\n\n");
}

... la stringa viene ricevuta e messa nel vettore stringaSeriale[] .. in posizione 0 viene messo il valore massimo raggiunto dal puntatore..... mi pare che funzioni sempre, con qualsiasi velocità di bps.....
per adesso, per il debug, uso la seriale standard, ma poi l'idea è di usare la libreria softSerial per usare qualsiasi PIN ed usare la seriale standard come eco dei comandi e dei messaggi ricevuti ...

Ho anche abozzato la mia idea della decodifica della stringa comando in questo modo:

#define dimVettore 25                // lunghezza max del buffer di lettura (stringa seriale)
#define baudSeriale  4800            // velocità seriale
char stringaSERIALE[dimVettore+1]; // stringa buffer destinata a contenere la stringa ricevuta dalla seriale 
boolean stringaOK = false;

void setup() 
{
Serial.begin(baudSeriale);
}

void loop()
{
if (Serial.available()>0){leggiSeriale();}
if (stringaOK) {analizzaStringa();}
}

void leggiSeriale()
 { 
   unsigned long count = millis();      //interrompe la lettura dalla seriale se passano più di countMax ms senza che arrivino caratteri
   unsigned long const countMax = 10;   // limite max millisecondi senza che arrivino caratteri .. oltre chiude il ciclo di lettura (non scendere sotto i 5 per 4800 bps e 10 1200bps) 
   boolean fineLettura;                 // controllo sul checksum della stringa Seriale ricevuta

   int index=1;
   // LEGGE i primi dimVettore caratteri ........
   do    
     { if(Serial.available()> 0) {stringaSERIALE[index]=Serial.read(); count = millis(); index++; } 
       fineLettura = ((index > dimVettore) || (millis() - count > countMax));}
   while (!fineLettura);   
   
   stringaSERIALE[0]= index-1; // in posizione 0 pone l'indice massimo ... servirà per il parser della stringa ...
   fineLettura = false;

    byte tempByte;
   // CANCELLA il buffer, se c'è ancora qualcosa nel buffer .....
   do
     { if(Serial.available()> 0) { tempByte = Serial.read(); count = millis();} 
       fineLettura = (millis() - count > countMax);}
   while (!fineLettura);

  stringaOK = true;
}


/* ipotesi di mappatura della stringa di comando

byte 0 - lunghezza max del vettore-buffer, (n: numero di byte - caratteri di cui si compone la stringa dati) 
byte 1 - ID destinatario (0 - 128) (al momento inutilizzato)
byte 2 - ID mittente (0 - 128) (al momento inutilizzato)
byte 3 - PIN prima parte, per riconoscere il comando/interrogazione (al momento inutilizzato)
byte 4 - PIN seconda parte, per riconoscere il comando/interrogazione (al momento inutilizzato)
byte 5 - inutilizzato (al momento inutilizzato)
byte 6 - inutilizzato (al momento inutilizzato)
byte 7 - inutilizzato (al momento inutilizzato)
byte 8 - comando/dispositivo (A: interrogazione;     B: comando;     C: invio dati;     D: comunicazione ricevuto Ok;     E: comunicazione errore ricezione ... etc.)
byte 9 - inutilizzato (al momento)
byte 10 - inutilizzato (al momento)

byte 11 - inizio sequenza del comando\dispositivo, 1 byte
byte 12 - continuo sequenza del comando\dispositivo, 2 byte
byte 13 - continuo sequenza del comando\dispositivo, 3 byte
... ...
... ...
byte n-2 - penultimo byte della sequenza comando\dispositivo, n-2'esimo byte
byte n-1 - ultimo byte della sequenza comando\dispositivo, n-1'esimo byte
byte n   - checksum (al momento inutilizzato), n'esimo byte
*/

void analizzaStringa ()
{ stringaOK = false; 

 if (stringaSERIALE[0] >= 12) //  ci sono i caratteri minimi necessari
    {
        switch (stringaSERIALE[8]) // byte in posizione 8
        {
        case 'A': //interrogazione
        Serial.print("\n\t Scelta:A");
        
        break;

        case 'B': //comando
        Serial.print("\n\t Scelta:B");
        
        break;
        
        case 'C': //comunicazione: ricevuto ok
        Serial.print("\n\t Scelta:C");
        
        break;

        case 'D': //comunicazione: errore ricezione
        Serial.print("\n\t Scelta:D");
        
        break;
        } 

     // stampa i dati ricevuti .....
     int k=0;
     Serial.print("\n ......................................................................");
     Serial.print("\n\t k=0\t   "); Serial.print(stringaSERIALE[0], DEC); Serial.print(" dimensione Vett");
     while (k < stringaSERIALE[0])
     {  k++;
        Serial.print("\n\t k="); Serial.print(k); 
        Serial.print("\t   ")  ; Serial.print(stringaSERIALE[k], DEC);
        Serial.print("\t   ")  ; Serial.print(stringaSERIALE[k]); 
       }
      Serial.print("\n ...................................................................... \n\n\n");
    }
 else //  non ci sono i caratteri minimi necessari
    {
     Serial.print("\n\t Stringa comando non corretta. Ricevuti solo ");  Serial.print(stringaSERIALE[0], DEC);  Serial.print(" caratteri!!");
    }
}

ipotizzo che la stringa di comando abbia questa forma:

byte 0 - lunghezza max del vettore-buffer, (n: numero di byte - caratteri di cui si compone la stringa dati)
byte 1 - ID destinatario (0 - 128) (al momento inutilizzato)
byte 2 - ID mittente (0 - 128) (al momento inutilizzato)
byte 3 - PIN prima parte, per riconoscere il comando/interrogazione (al momento inutilizzato)
byte 4 - PIN seconda parte, per riconoscere il comando/interrogazione (al momento inutilizzato)
byte 5 - inutilizzato (al momento inutilizzato)
byte 6 - inutilizzato (al momento inutilizzato)
byte 7 - inutilizzato (al momento inutilizzato)
byte 8 - comando/dispositivo (A: interrogazione; B: comando; C: invio dati; D: comunicazione ricevuto Ok; E: comunicazione errore ricezione ... etc.)
byte 9 - inutilizzato (al momento)
byte 10 - inutilizzato (al momento)
byte 11 - inizio sequenza del comando\dispositivo, 1 byte
byte 12 - continuo sequenza del comando\dispositivo, 2 byte
byte 13 - continuo sequenza del comando\dispositivo, 3 byte
... ...
... ...
byte n-2 - penultimo byte della sequenza comando\dispositivo, n-2'esimo byte
byte n-1 - ultimo byte della sequenza comando\dispositivo, n-1'esimo byte
byte n - checksum (al momento inutilizzato), n'esimo byte

lo so, ci sono molti bit inutilizzati ed inutili per la comununicazione seriale ... ma io, poi, vorrei utilizzarlo anche per altre cose.... quindi vorrei fare una sorta di protocollo generale utilizzabile per molti casi....

una volta stabilita la lunghezza max del buffer contenente la stringa, nella variabile dimVettore, che nel mio caso ho messo a 25, perchè certamente bastano per gestire il mio progetto ..... la decodifica della stringa sarebbe da fare con opportuni switc case.

Adesso comincio a scrivere la parte di decodifica specifica per il mio progetto che sostanzialmente consiste in:

  • il primo micro interroga il secondo per estrarre il contenuto di 12 byte della eeprom, a partire da in una certa posizione , quindi invia i dati al 2 micro;
  • il primo micro invia i dati per modificare i 12 byte della eeprom ...

aspetto opinioni al riguardo ....
ciao