I am using I2C to successfully request critical data from a Slave device (I have to use requestFrom() in the Master) but if, for some reason, the power disconnects from the Slave device then the Master freezes altogether. I didn't realise I2C was so problematic in this regard and I have been a number of weeks trying all types of alternative setups to try and avoid this situation. I can't seem to find a way for example, to simply check if a Wire() connection exists before requesting data and freezing everything. Both devices are Arduino Uno r3. Any ideas I may not have tried yet? Any way to send a single value to the Master and update it every 30 secs would do. Actually the data comes from a capacitive sensor, so would it be possible to just have both arduinos read from the same sensor?
In response to Nick Gammons suggestions (below): I have edited the examples you gave to try and fit in with what I am trying to achieve. I would like to do the following. Catch a situation where the Master (Arduino Yun Shield) cannot communicate with the Slave ( Arduino r3 - with sensor) due to its power supply and/or sensor reading failing. In other words, an Arduino monitoring another Arduino. Here is my edited versions, however I am still not able to catch the "else" condition of the Slave being unreachable:
SLAVE
#include <Wire.h>
const byte MY_ADDRESS = 42;
// various commands we might get
enum {
CMD_ID = 1,
CMD_READ_A0 = 2
};
char command;
void setup()
{
command = 0;
pinMode (A0, INPUT);
Wire.begin (MY_ADDRESS);
Wire.onReceive (receiveEvent); // interrupt handler for incoming messages
Wire.onRequest (requestEvent); // interrupt handler for when data is wanted
} // end of setup
void loop()
{
// all done by interrupts
} // end of loop
void receiveEvent (int howMany)
{
command = Wire.read (); // remember command for when we get request
} // end of receiveEvent
void sendSensor (const byte which)
{
//int val = analogRead (which);
int val = 125;//test only
byte buf [2];
buf [0] = val >> 8;
buf [1] = val & 0xFF;
Wire.write (buf, 2);
}
void requestEvent ()
{
switch (command)
{
case CMD_ID: Wire.write (0x55); break; // send our ID
case CMD_READ_A0: sendSensor (A0); break; // send A0 value
}
}
MASTER
#include <Process.h>
#include <I2C.h>
#include <Bridge.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int SLAVE_ADDRESS = 42;
// various commands we might send
enum {
CMD_ID = 1,
CMD_READ_A0 = 2,
};
void setup ()
{
Bridge.begin();
Console.begin();
//while (!Console);
I2c.begin ();
I2c.timeOut(100); // milliseconds
lcd.init();
lcd.backlight();
}
void loop()
{
int value = getA0();
Console.print("A0 value:");
Console.println(value);
lcd.setCursor(0, 0);
lcd.print("A0 value:");
lcd.print(value);//displays first '0' reading then freezes code
delay (5000);
}
int getA0() {
if (I2c.write (SLAVE_ADDRESS, CMD_READ_A0) == 0) {
byte buf [2];
int val;
if (I2c.read (SLAVE_ADDRESS, sizeof buf, buf) == 0)
{
val = buf [0] << 8 | buf [1];
return val;
}
else {
return 0;
}
}
else {
return 0;
}
delay(500);
}
low
after the slave power supply disconnect?I am still not able to catch the "else" condition of the Slave being unreachable
- try testing theI2c.write
function calls as well, to see if they return a zero (which they should).