Dilemma su I2C e il comando Wire.beginTransmission

Salve a tutti,
Sta per arrivare Natale e per il mio presepe voglio realizzare una centralina guidata da arduino.
In rete ho trovato skech di alba-tramonto ma io vorrei aggiungere altri effetti(fuoco, cielo stellato, movimenti personaggi) ma purtroppo non funziona.
Quindi ho optato per usare più arduino per far funzionare la mia idea.
Guardando il tutorial su youtube, dove spiegava I2C, e al comando Wire.beginTransmission, li indicava indirizzo dello SLAVE. Ma cosi facendo, il MASTER invia a uno solo SLAVE per volta. Cosa che non mi serve.
Leggendo sul sito di arduino va per forza indicato un indirizzo specifico.
C'è possibilità di inviare contemporaneamente a tutti i SLAVE il comando senza chiamarli uno ad uno?
grazie per il vostro aiuto e tempo.

Si, è possibile ed il grande Nick Gammon ne parla e da anche un esempio ...
... studiati tutto QUESTO suo capitolo sul I2C; oltre ad ampliare le tue conoscenze sull'argomento, troverai una sezione specifica sul Broadcasting I2C (indirizzo riservato 0x00) :wink:

Guglielmo

Grazie per il tuo consiglio, è stato utilissimo.
Ho realizzato il progetto, un master (uno) e un slave (Mega), ed funziona benissimo.
Ma collegando un secondo slave (uno), non vuole proprio ascoltare il master.
Master

#include <Wire.h>

void setup()
{
  Serial.begin(9600);
  Wire.begin();
}

void loop ()
{
  
  Wire.requestFrom(8, 10);
  while (Wire.available())
  {
    char c = Wire.read();
    Serial.print(c);
  }
  Serial.println();

  Wire.beginTransmission(8);
  Wire.write("down");
  Wire.endTransmission("si");
  delay(4194);

  Wire.beginTransmission(8);
  Wire.write("sun");
  Wire.endTransmission();
  delay(22958);
  
    Wire.beginTransmission(8);
  Wire.write("sunset");
  Wire.endTransmission();
  delay(4195);
  
    Wire.beginTransmission(8);
  Wire.write("moon");
  Wire.endTransmission();
  delay(28651);
}

Slave

#include <Wire.h>
#define pin_down   13
#define pin_sun    12
#define pin_sunset 11
#define pin_moon   10
#define pin_starsA 9
#define pin_starsB 8

byte fade[]  = {255, 250, 245, 240, 235, 230, 225, 220, 215, 210, 205, 200, 195, 190, 185, 180, 175, 170, 165, 160, 155, 150, 145, 140, 135, 130, 125, 120, 115, 110, 105, 100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5, 0}; // 52 step


void setup() {
  Wire.begin(8);
  Wire.onRequest(rispondi);
  Wire.onReceive(ricevi);
  pinMode( pin_down  , OUTPUT );
  pinMode( pin_sun   , OUTPUT );
  pinMode( pin_sunset, OUTPUT );
  pinMode( pin_moon  , OUTPUT );
  pinMode( pin_starsA, OUTPUT );
  pinMode( pin_starsB, OUTPUT );

  analogWrite( pin_down  , LOW );
  analogWrite( pin_sun   , LOW );
  analogWrite( pin_sunset, LOW );
  analogWrite( pin_moon  , LOW );
  analogWrite( pin_starsA, LOW );
  analogWrite( pin_starsB, LOW );
}

void loop (){
}
void down() {
  for ( int i = 0; i < 52; i++) {
    analogWrite(pin_down,   fade[(51 - i)]);
    analogWrite(pin_sun,    0 );
    analogWrite(pin_sunset, 0 );
    analogWrite(pin_moon,   fade[i] );
    analogWrite(pin_starsA, fade[i] );
    analogWrite(pin_starsB, fade[i] );
    delay(5000);
  }
}
void sun() {
  for ( int i = 0; i < 52; i++) {
    analogWrite(pin_down, fade[i]);
    if ( fade[i] < 125)
    analogWrite(pin_sun, fade[(51 - i)] * 2 );
    analogWrite(pin_sunset, 0 );
    analogWrite(pin_moon,   0 );
    analogWrite(pin_starsA, 0 );
    analogWrite(pin_starsB, 0 );
    delay(5000);
  }
}
void sunset() {
  for ( int i = 0; i < 52; i++) {
    analogWrite(pin_down, 0);
    analogWrite(pin_sun, fade[i] );
    analogWrite(pin_sunset, fade[(51 - i)] );
    analogWrite(pin_moon, 0);
    analogWrite(pin_starsA, 0);
    analogWrite(pin_starsB, 0);
    delay(5000);
  }
}
void moon() {
  for ( int i = 0; i < 52; i++) {
    analogWrite(pin_down,0);
    analogWrite(pin_sun,0);
    analogWrite(pin_sunset,fade[i]);
    if ( fade[i] < 125) analogWrite(pin_moon,   fade[(51 - i)] * 2 );
    if ( fade[i] < 125) analogWrite(pin_starsA, fade[(51 - i)] * 2 );
    if ( fade[i] < 125) analogWrite(pin_starsB, fade[(51 - i)] * 2 );
    delay(5000);
  }
}
void rispondi() {
  if (down == down) {
    Wire.write("11");
  } else {
    Wire.write("aa");
  }
}

void ricevi() {
  String comando = "";
  while (Wire.available()) {
    comando += char(Wire.read());
  }
  if (comando == "down" ) {
    down();
  } else if (comando == "sun") {
    sun();
  }else if (comando == "sunset") {
    sunset();
  }else if (comando == "moon") {
    moon();
  }
}

Slave_2

#include <Wire.h>
int Tempo = 140;
int TmpRandom = 150;
int Giallo_1 = 11;
int Rosso = 10;
int Giallo_2 = 9;

void setup() {
  Serial.begin(9600);
  Wire.begin(8);
  Wire.onRequest(rispondi);
  Wire.onReceive(ricevi);
  pinMode(Giallo_1, OUTPUT); //Led giallo1 come uscita
  pinMode(Rosso, OUTPUT);    //Led rosso come uscita
  pinMode(Giallo_2, OUTPUT); //Led giallo2 come uscita
  pinMode(Giallo_1, HIGH); //Led giallo1 come uscita
  pinMode(Rosso, HIGH);    //Led rosso come uscita
  pinMode(Giallo_2, HIGH); //Led giallo2 come uscita
}

void loop () {
  /*if
    (ricevi == sun)
    {
    digitalWrite(Giallo_1, LOW);
    digitalWrite(Rosso, LOW);
    digitalWrite(Giallo_2, LOW);
    delay (500);
    }
    else
    {
    analogWrite(Giallo_1, random(TmpRandom) + Tempo);
    analogWrite(Rosso, random(TmpRandom) + Tempo);
    analogWrite(Giallo_2, random(TmpRandom) + Tempo);
    delay(random(100));
    }*/
}
void down() {
  analogWrite(Giallo_1, random(TmpRandom) + Tempo);
  analogWrite(Rosso, random(TmpRandom) + Tempo);
  analogWrite(Giallo_2, random(TmpRandom) + Tempo);
  delay(random(100));
}
void sun() {
  digitalWrite(Giallo_1, LOW);
  digitalWrite(Rosso, LOW);
  digitalWrite(Giallo_2, LOW);
  delay (500);
}
void sunset() {
  analogWrite(Giallo_1, random(TmpRandom) + Tempo);
  analogWrite(Rosso, random(TmpRandom) + Tempo);
  analogWrite(Giallo_2, random(TmpRandom) + Tempo);
  delay(random(100));
}
void moon() {
  analogWrite(Giallo_1, random(TmpRandom) + Tempo);
  analogWrite(Rosso, random(TmpRandom) + Tempo);
  analogWrite(Giallo_2, random(TmpRandom) + Tempo);
  delay(random(100));
}
void rispondi(void) {
  if (down == down) {
    Wire.write("2");
  } else {
    Wire.write("b");
  }
}
void ricevi() {
  String comando = "";
  while (Wire.available()) {
    comando += char(Wire.read());
  }
  if (comando == "down" ) {
    int down;
  } else if (comando == "sun") {
    int sun;
  } else if (comando == "sunset") {
    int sunset;
  } else if (comando == "moon") {
    int moon;
  }
}

Come scritto in codice, ho provato vari modi ma nulla. Sapreste consigliarmi qualche idea.

leggendo Nick Gammon...

Address 0 is reserved as a "broadcast" address, addresses 1 to 7 are reser...

e poi più in basso l'esempio:

// Written by Nick Gammon
// February 2011

#include <Wire.h>

const byte MY_ADDRESS = 25;      // me
const byte SLAVE_ADDRESS = 42;   // slave #42

void setup () 
  {
  Wire.begin (MY_ADDRESS);  // initialize hardware registers etc.
  }  // end of setup

void loop() 
  {
  unsigned int value = 1234;  // ie. 0x04 0xD2
  
  Wire.beginTransmission (0);  // broadcast to all
  Wire.write (highByte (value));   
  Wire.write (lowByte (value)); 
  byte err = Wire.endTransmission  ();  // non-zero means error
      
  delay (100);  // wait 0.1 seconds
  }   // end of loop

hai provato ad utilizzarlo per vedere se funziona?
una volta testato implementi il tuo codice :wink:

grazie per il suggerimento, avevo letto il manuale.
Credo al 99% che codice compilato da me funzioni, credo che il problema sia nel codice Slave_2, non sia compilato bene.
Ora non so se posso continuare qui la discussione perchè andrei fuori tema con il titolo del post.
Chiedo conferma del ADMIN, altrimenti apriro un nuovo post.