Go Down

Topic: Comunicazione seriale tra due microcontrollori .. (Read 1 time) previous topic - next topic

leo72


ci "andrebbe" che qualche guru  facesse una FAQ seria  seguita da dimostrazioni su questo argomento,  perché  è  la cosa più richiesta

La questione non è fare la guida. La questione è che la gente la cerchi, quella guida.
La comunicazione fra 2 MCU è stata trattata un sacco di volte, basterebbe fare una ricerca per vedere che si tratta di una semplice comunicazione seriale. E' che nessuno cerca.

gingardu


ciao gingardu....
ho appena cominciato a lavorarci... conto di riprendere appena dopo questi giorni di festa. appena ho qualcosa di funzionamente posto qui.. così facciamo qualcosa di standard e utilizzabile per molti usi.... .. a presto ciao...




sarebbe un ottima cosa,  (SANTO SUBITO)
l'unica cosa che mi sento di "consigliare"  è   quella  di tenere sempre in mente   il possibile scopo finale dell'utilizzare  la trasmissione   seriale tra 2 micro 
detto in altre parole   gia se si riuscirebbe   a inviare un numero  e ricevere il numero inviato
hai fatto gia molto  e per numero si intende un int  o float 
che il ricevente lo vede come un int o float 
Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

gingardu



ci "andrebbe" che qualche guru  facesse una FAQ seria  seguita da dimostrazioni su questo argomento,  perché  è  la cosa più richiesta

La questione non è fare la guida. La questione è che la gente la cerchi, quella guida.
La comunicazione fra 2 MCU è stata trattata un sacco di volte, basterebbe fare una ricerca per vedere che si tratta di una semplice comunicazione seriale. E' che nessuno cerca.



certo La comunicazione fra 2 MCU è stata trattata un "sacco di volte",   

ma quando si cerca di adattare al proprio progetto e mettere in pratica quasi niente funziona

anche perche le "cose"  non sono cosi semplici  da mettere in pratica in un progetto vero e proprio
se conosci  dei  post   gia fatti (e validi )  si potrebbero mettere i link nella  FAQ

che è utile anche per evitare richieste   ripetitive
Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Paolo S

#8
Jan 11, 2013, 08:08 pm Last Edit: Jan 11, 2013, 09:20 pm by Paolo S Reason: 1
@GINGARDU
Ho iniziato il lavoro ...

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

#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:
Code: [Select]

#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

pablos

#9
Jan 11, 2013, 08:19 pm Last Edit: Jan 11, 2013, 08:28 pm by pablos Reason: 1
Quote
certo La comunicazione fra 2 MCU è stata trattata un "sacco di volte",  
ma quando si cerca di adattare al proprio progetto e mettere in pratica quasi niente funziona


weeee gingardu sei sempre incazzato??
ci sei mancato .... ma dove eri finito??!! XD XD XD XD
no comment

Go Up