Hi,
I have a commercial power supply device controlled by Arduino Mega I2C line.
I use the standard Wire library and my program performs additional tasks.
All works fine, except that when the power supply device is turned off, my program halts, (probably runs into a closed loop waiting for the device to respond)
I wish to be able to ignore (and display a message) when the device is off, but not to halt the program.
There are some options like Wire.available or Wire.read, but they hung if the device is inactive.
Is there a clean way to detect if the device is connected and responds?
Can you take a voltage from the power supply, voltage divide it if necessary, and feed it to an Arduino pin? Then check the state of that pin, and if the device is off, bypass the portion of your code that hangs up when the supply is off.
My I2C test code doesn't lock up when the slave is powered down. It displays "fail". Here is my master test code. If you have two Arduinos, I can post my slave code also. Pay attention to the error checking at the endTransmission and requestFrom calls
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin(); // join i2c bus (address optional for master)
}
byte x = 0;
int failCount = 0;
void loop() {
Wire.beginTransmission(13); // transmit to device #13
Wire.write(x); // sends one byte
if(Wire.endTransmission() != 0)
Serial.println("Write failed");
delayMicroseconds(10);
if(Wire.requestFrom(13, 2) == 2) { // request 2 bytes from slave device #13
while(Wire.available()) // slave may send less than requested
{
char c = Wire.read(); // receive a byte as character
Serial.print(c,DEC); // print the character
Serial.print(" ");
}
Serial.print(failCount);
Serial.println();
}
else {
Serial.println(F("Fail"));
failCount++;
}
x++;
if(x > 3) x = 0;
delay(500);
}
Thanks all for the kind support.
My program seem to be just fine, and, as I wrote, it has been running for long time and served me well.
After several tests, my conclusion is that the program will ignore physically disconnected device, and will continue, but when the device is connected but powered off, the program will halt at the endTransmission command.
I am not sure if this is a software (library) issue or hardware (device input or Arduino output circuitry).
Can anyone comment on this or suggest further tests or modification? (a diode on the data line?)
Thanks
samtal
It seems like the device is holding the SDA line low when it is off, possibly due to its internal protection diodes. The master tries to address the slave and waits for an acknowledgement. The low signal looks like there is a slave there but it is a bit slow. The master waits forever for the slave to release the line. This will also block any other I2C device from transmitting on the bus.
I see two possible solutions: digitalRead() the SDA first to see if it is held low, then don't attempt any I2C. Or use a bidirectional level converter to allow that part of the bus to go low while the rest still has active voltages.
jremington:"It is usually a bad idea to connect a powered device to an unpowered device."
Well, I agree, but this can happen, especially if the master and the slave are two different devices.
Deeper testing showed that the slave device holds the master (arduino) SDA at approx 2V when the slave is turned off, or, in other words, it draws too much current.
Looking into the devices SDA and SCL lines shows diode behavior (0.6V) on one polarity, and 1.9V (like a zenner) on the other direction.
It looks like poor design, but, as I wrote, it is a commercial device and I have no control over its design.
The solution would probably be an optically isolated bidirectional converter as suggested by morganS. This will also protect both master and slave from parasitic ground currents as suggested by jremington.
"It is usually a bad idea to connect a powered device to an unpowered device."
Well, I agree, but this can happen, especially if the master and the slave are two different devices.
Deeper testing showed that the slave device holds the master (arduino) SDA at approx 2V when the slave is turned off, or, in other words, it draws too much current (As tested, to keep SDA voltage > 4 volts, the current must not exceed 30 mA)
Looking into the devices SDA and SCL lines shows diode behavior (0.6V) on one polarity, and 1.9V (like a zenner) on the other direction.
It looks like poor design, but, as I wrote, it is a commercial device and I have no control over its design.
The solution would probably be an optically isolated bidirectional level converter as suggested by morganS. This will also protect both master and slave from parasitic ground currents.
I will update and credit as soon as done.