Hi,
This is my first post on the forum, but I've found it very useful in the past reading through other peoples problems and projects - thank you everyone!
So the project: I'm trying to design a slave I2C device that will respond with various ADC values and measured data values, dependent on what command the master I2C device sends to it. All seems to be working OK but the system only works if the slave devices code starts running before the masters code starts running? If the master code is running when the slave starts up, the master has to be reset before the I2C starts to work.
Here is the code, I've trimmed it right back to bare bones to try and help troubleshoot the problem:
Master:
#include <Wire.h>
byte z = (0x22);
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}
void loop() {
Wire.beginTransmission(8);
Wire.write(z);
Wire.write(0x23);
Wire.endTransmission();
delay(10);
Wire.requestFrom(8, 2);
while(Wire.available() == 0); //wait for reply from slave
byte c = Wire.read();
byte d = Wire.read();
Serial.println(c);
Serial.println(d);
//Combinte byte c & d to form to display current measurement
int reportedCurrent = (int)d << 8;
reportedCurrent = reportedCurrent + c;
Serial.println(reportedCurrent);
z=z+1; // Increment x each loop to check value reported is 'live'
delay(500);
}
Slave:
#include <Wire.h>
volatile byte x = 0; //Volatile so variable can be changed in interupt
volatile byte y = 0; //Volatile so variable can be changed in interupt
void setup() {
Wire.begin(8); // join i2c bus with address #8
Wire.onRequest(requestEvent); // register event
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}
void loop() {
delay(100);
//Serial prints to check x & y can be read outside I2C interupt:
Serial.print("X is now:");
Serial.println(x);
Serial.print("Y is now:");
Serial.println(y);
}
// 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()) {
x = Wire.read();
y = Wire.read();
}
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
Wire.write(x+1);
Wire.write(y+1);
}
So in essence the master is sending a couple of bytes of data, the slave receives this data, it would then do something with this data (in this example it's just adding 1 but it would probably look up an ADC value) and then sends some data back to the master.
If I run the master code first, this is what I see on the slave serial monitor once the slave starts up:
X is now:0
Y is now:0
X is now:0
Y is now:0
X is now:0
Y is now:0
...
It will continue doing this forever.
If I now reset the master, this is what the slave prints out:
X is now:34
Y is now:35
and X will gradually increment up which is what should be happening! You can also now see the values being correctly reported back to the Master.
Can anyone see what is going wrong?
To be clear both boards are fully powered up all the time, it's just the order that the boards are reset in - this could cause issues in the use of the slave gadget in future.