Problema timing I2C tra due Arduino [RISOLTO]

Salve a tutti, ho un problema a capire il timing della comunicazione I2c e ci sto uscendo di testa da un pezzo :frowning:
Ho due arduino, master e slave, il master invia una domanda "A" allo slave che la elabora interrogando dei sensori via radio e poi genera una risposta. Il tempo per generare la risposta è variabile di molto e il master non puo sapere quando lo slave sia pronto a rispondere. Qui è il mio blocco: anche se nel master metto un delay prima di richiedere dati sul bus, questo delay a volte potrebbe non essere sufficiente e richiederà dei dati ancor prima che lo slave sia pronto.
Puo darsi che sia una stupidaggine ma non ci sto capendo piu niente :o qualcuno è in grado di aiutarmi? grazie mille….

Questo è il codice semplificato del master

#include <Wire.h>

char domanda = "A";
char risposta = "X";//risposta non conosciuta

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop() {
 
Wire.beginTransmission(8); // transmit to device #8
Wire.write(domanda);        // sends
Wire.endTransmission();    // stop transmitting
Serial.print("Domanda inviata: ");Serial.println(domanda);

risposta = "X";//resetto la risposta

//attendo la risposta, ma lo slave potrebbe metterci piu di 1 secondo
//per generarne una
delay(1000);

//richiedo una risposta allo slave
Wire.requestFrom(8, sizeof(risposta));    // request 1 byte from slave device #8

byte i = 0;
while (Wire.available()) { // slave may send less than requested
  char c = Wire.read(); // receive a byte as character
  risposta = c;
  i++;
}

Serial.print("Risposta ricevuta: ");Serial.println(risposta);
Serial.println("------------");
Serial.println("----FINE-----");
Serial.println();
Serial.println();
}

e questo delllo slave

#include <Wire.h>

char domanda = "X";//domanda non conosciuta
char risposta = "B";


void setup() {
  Serial.begin(9600);
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Wire.onRequest(requestEvent); // register event
}

void loop() {

 delay(200); 
}



// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
 while (Wire.available()) { // loop through all
    char c = Wire.read(); // receive byte as a character
    //Serial.print(c);         // print the character
    domanda= c;
  }
  Serial.print("Domanda ricevuta: "); Serial.println(domanda);
  
if (domanda !="X"){
  //se ho ricevuto una domanda valida faccio qualcosa che puo durare un tempo variabile
  //ma il master potrebbe interrompermi prima con la richiesta dati sul bus!!
            for (int i=0; i<10; i++){
              Serial.print("Conto fino a...");Serial.println(i);
              delay(250);
            }
            risposta = "B";
}


domanda = "X";//resetto di nuovo la domanda
}



// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  Wire.write(risposta); // respond 
  // as expected by master
  Serial.print("Risposta inviata al master: ");
  Serial.println(risposta);
  Serial.println("------------");
  Serial.println("----FINE-----");
  Serial.println();
  Serial.println(); 
}

Si chiama "polling" ...
... il master interroga in continuazione lo/gli slave, quest'ultimo/i se ha/hanno qualche cosa da dare indietro la da/danno, altrimenti risponde/rispondono con un messaggio di "nessun dato disponibile".

Guglielmo

oppure collega i 2 Arduino con un pin dove il slave comunica al master che ha dei dati da richiedere.
Ciao Uwe

Grazie a tutti per le risposte! Così ho capito meglio come funziona il polling.
Il problema era che il master (che in realtà è un webserver) fa una domanda allo slave, attende la risposta e poi continua facendo altro, a volte lo slave puo impiegare piu tempo a rispondere e volevo rendere questo tempo di attesa "dinamico" in modo da ottimizzare i tempi, potevo fare un while nel master chiedendo di continuo la risposta ma in un qualche modo mi creava problemi sullo slave. La soluzione di Uwe fa proprio al caso mio (grazie!), posso usare un pin "ready_to_reply" e alzarlo lato slave solo quando la risposta è pronta e bloccare il master in un loop finche non vede questo pin alto.
Grazie a tutti!