Problema software invio pacchetti di dati usando protocollo i2c

Ciao a tutti e un grazie in anticipo a chi mi aiuterà, è da un po’ che non ci sentiamo.

Devo creare un meccanismo che mi permetta dal Master, tramite i2c, di inviare blocchi di dati numerici o matrici di caratteri (più di quelli mostrati nel codice allegato) a più Slave.

Nell’esempio io ne ho considerato solo uno, per ora, visto che non sono riuscito a ottenere quello che desidero.

In pratica mi serve di INVIARE una serie di dati A COMANDO, secondo alcune mie esigenze (può essere una matrice di caratteri o solo una variabile).

Il Master

  • prima invia una serie di caratteri o numeri allo slave.

Lo Slave

  • ricevere la serie di dati inviati dal master e sino a qui ci siamo.

Infatti se lascio dal codice allegato solo il primo invio di dati (con alcune modifiche) tutto è ok e funziona.

Però a me occorre esattamente quanto segue:

  • Il Master ha all’interno una serie di funzioni (da me omesse per semplicità) che devo inviare in blocco allo (o agli) Slave.

  • Lo Slave deve ASSICURARSI di RICEVERE dal Master correttamente il primo blocco in toto.

  • Lo Slave a questo punto deve dire al MASTER di non considerare più la prima serie inviata e di occuparsi della successiva.

In pratica il Master dice allo Slave svegliati che ti invio questa serie di dati, poi te ne invio altri quando ho bisogno.

Questo è il problema che non riesco a risolvere e credo che possa servire a molti, pensavo che il codice allegato lo potesse fare, ma non è così.

Grazie ancora per l’attenzione.

PS: Uso Arduino Mega

Codice Master

#include <Wire.h>
#include <LiquidCrystal_I2C.h>                        // Library for LCD
                                                      // Mi serve per avere un monitor consultabile non attraverso il computer

char Name_A_Intro       [5]     {65, 66, 67, 68, 69};      // A,B,C,D,E
char Name_B_Intro       [5]     {70, 71, 72, 73, 74};      // F,G,H,I,J

byte slave_1 = 11;                      // indirizzo dello slave 1 per ora invia solo su questo
byte slave_2 = 12;                      // indirizzo dello slave 2
byte slave_3 = 13;                      // indirizzo dello slave 3
byte slave_4 = 14;                      // indirizzo dello slave 4

char _char_ = 0;                        // carattere da inviare
byte i = 0;                             //
byte invio = 1;                         //

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


void setup() {
  Wire.begin();                                 // attiva il bus I2C; il dispositivo è master
  Serial.begin(9600);

  Serial.println(F("Master"));

  lcd.backlight();  //                          // Backlight ON
  lcd.begin(20, 4); //                          // Inizializzazione Display LCD 20x4
  lcd.clear();      //                          // Cancella caratteri LCD

  lcd.setCursor(0, 0);
  lcd.print(F("Master"));

}



void loop() {

  delay(1000);
  //                                        // Esegue il primo invio
  if (invio == 1)
  {
    invio_Name_A_step_1();
    //delay(2000);
    //lcd.clear();
    invio++;
    Serial.println(F(""));

  }

  //                                        // Esegue il secondo invio
  if (invio == 2)
  {
    invio_Name_B_step_1();    
    //delay(2000);
    lcd.clear();
    invio++;
    Serial.println(F(""));

  }

  //                                        // Esegue il terzo invio
  if (invio == 3)
  {
    lcd.clear();
    Serial.print(F("Invii completati "));
    lcd.setCursor(0, 1);
    lcd.print(F("Invii completati "));
    Serial.println(F(""));
  }


  // a questo punto dato che la variabile -invio- = 4 non viene inviato più nulla
  // questo è quello che mi interessa, cioè poter inviare una serie di dati
  // agli SLAVE come e quando ho bisogno (voglio).

}

void invio_Name_A_step_1()
{
  i = 0;
  _char_ = 0;
  Serial.print(F("Name A - "));
  lcd.setCursor(0, 1);
  lcd.print(F("Name A "));

  for (int k = 0; k < 5; k++)
  {
    invio_Name_A_step_2();
    i++;
  }
}

void invio_Name_A_step_2()
{
  _char_ = Name_A_Intro [i];

  Wire.beginTransmission(slave_1);  // indirizzo slave 1
  Wire.write(_char_);
  Wire.endTransmission();

  Serial.print(Name_A_Intro [i]);
  lcd.setCursor(i + 5, 2);
  lcd.print(_char_);

  lcd.setCursor(0, 3);
  lcd.print(F("Name A inviato"));
}

void invio_Name_B_step_1()
{
  i = 0;
  _char_ = 0;
  Serial.print(F("Name B - "));
  lcd.setCursor(0, 1);
  lcd.print(F("Name B "));

  for (int k = 0; k < 5; k++)
  {
    invio_Name_B_step_2();
    i++;
  }
}



void invio_Name_B_step_2()
{
  _char_ = Name_B_Intro [i];

  Wire.beginTransmission(slave_1);  // indirizzo slave 1
  Wire.write(_char_);
  Wire.endTransmission();

  Serial.print(Name_B_Intro [i]);
  lcd.setCursor(i + 15, 2);
  lcd.print(_char_);

  lcd.setCursor(0, 3);
  lcd.print(F("Name B inviato"));
}

Codice Slave

#include <Wire.h>
char Name_A_Intro       [5]     {0, 0, 0, 0, 0};
char Name_B_Intro       [5]     {0, 0, 0, 0, 0};
int k = 0;
char _char_ = 0;

byte ricevo = 1;
byte slave_1 = 11;                      // indirizzo dello slave per ora invia solo su questo

void setup() {

  Serial.begin(9600);

}

void loop() {


  if (ricevo == 1)
  {
    Serial.println(F("Name_A_Intro inizio ricezione"));
    for (int k = 0; k < 5; k++)
    {
      Wire.begin(slave_1);
      Wire.onReceive(ricevo_Name_A);
    }

    Serial.print(F(" Name_A_Intro ricevuto"));
    Serial.println(F(" "));
    ricevo++;
  }
  if (ricevo == 2)
  {
    Serial.println(F("Name_B_Intro inizio ricezione"));

    for (int k = 0; k < 5; k++)
    {
      Wire.begin(slave_1);
      Wire.onReceive(ricevo_Name_B);
    }
    Serial.print(F(" Name_B_Intro ricevuto"));
    Serial.println(F(" "));
    ricevo++;
  }

  if (ricevo == 3)
  {
    Serial.println(F("Ricezione completa"));
    Serial.print(F("Name_A_Intro - "));

    for (int k = 0; k < 5; k++)
    {
      Serial.print(Name_A_Intro [k]);
    }
    Serial.println(F(" "));
        Serial.print(F("Name_B_Intro - "));

    for (int k = 0; k < 5; k++)
    {
      Serial.print(Name_B_Intro [k]);
    }
    Serial.println(F(" "));
    //ricevo++;
  }

  // a questo punto dato che la variabile -ricevo- = 4 non viene ricevuto più nulla
  // questo è quello che mi interessa, cioè poter ricevere una serie di dati
  // dal MASTER come e quando ho bisogno (voglio).
}


void ricevo_Name_A()
{

  _char_ = Wire.read();
  Name_A_Intro [k] = _char_;
  k++;
  if (k == 5)
  {
    k = 0;
  }
}

void ricevo_Name_B()
{
  _char_ = Wire.read();
  Name_B_Intro [k] = _char_;
  k++;
  if (k == 5)
  {
    k = 0;
  }
}

Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe magari venir direttamente eliminato ::slight_smile:

Guglielmo

Scusa carissimo Guglielmo, ero convinto di aver postato nella sezione italiana.

patdepri:
Scusa carissimo Guglielmo, ero convinto di aver postato nella sezione italiana.

.... capita se si usa la "traduzione automatica" delle pagine con Google ... meglio disablitarla :wink:

Guglielmo

Manda insieme ai dati un byte di controllo. Il slave ricalcola il byte di controllo e su richiesta del master risponde ok o ko.
Il byte di controllo puó essere un a semplice somma di controllo fino a un codice ECC

Ciao Uwe