A slight refactoring of the slave, with interrupt handling via a volatile mutexe. Also changed x1/x2 to cmd/data.
#include<Wire.h>
struct Transmission {
byte cmd;
byte data;
};
volatile boolean tx_available = false;
volatile Transmission tx_incoming;
void setup()
{
Wire.begin(0x21); //UNO-2's slave address
Serial.begin(9600);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Wire.onReceive(receiveEvent); //MCU enters into this SUR once a data byte arrives in TWI Logic
}
void loop()
{
Transmission tx;
tx.cmd = 0;
// start of mutex block
noInterrupts();
if (tx_available) {
memcpy((void*)&tx, (void*)&tx_incoming, sizeof(Transmission));
tx_available = false;
}
interrupts();
// start of working block
if (tx.cmd == 0x02) {
do
{
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
tx.data--;
}
while (tx.data != 0);
}
}
void receiveEvent(int howmany)
{
/* we could test tx_available here, but I will just
unconditionally overwrite the previous unconsumed transmission, if any */
tx_incoming.cmd = Wire.read();
tx_incoming.data = Wire.read();
tx_available = true;
}
The Transmission struct would normally be in a shared .h file, and it would be read and written to the wire as a single block.