Wire blocks when device is not powered

Situation:

Arduino, A4 and A5 connected to SCL and SDA of device, GND connected top GND of device, pin 10 connected to Vcc of device to power it up.

Sketch:

#include <Wire.h>

void setup() {
  Serial.begin(9600);
  //  make sure the device is not powered up
  digitalWrite(10, LOW);
  pinMode(10, OUTPUT);
}

void loop() {
  for(uint8_t i = 1; i < 120; ++i) {
    Serial.print(i);
    Serial.print(':');
    Wire.beginTransmission(i);
    Serial.println(Wire.endTransmission() == 0 ? 1 : 0);
  }
}

Output:

1:

Question:

Why doesn't this code work? Wire.endTransmission() never returns.
When I power up the device (using digitalWrite(10, HIGH)) it works as expected.

Why doesn't this code work? Wire.endTransmission() never returns.

endTransmission() is waiting for the device to acknowledge receipt of the data. A powered off device is never going to reply.

I understand that, maybe I should have made my question clearer.

If I disconnect the device, it works: that is how an i2c sniffer works: run over all the addresses and see where you get an 'acknowledge'.

The specific device I'm using has address 0x27 (not that that matters), so why doesn't Wire even get past address 0x01?

Maybe it's in the implementation of the device itself? Or maybe I need to add some other components to make this work?

You have pullups installed? Writing a 1 to an INPUT pin enables the built in pullup.

Adding pullups (or not adding them) doesn't change the behaviour.

If I disconnect the device, it works:

Then an unpowered device is different to a non-existant device.

I think we need more information on said device. Got a data sheet?


Rob

See: Arduino Playground - HomePage

Are you using the circuit in Fig 4 of the HIH6130 datasheet?

If so are you also removing power from the pullup resistors and the LED?

Also when you say "remove power" are you driving pin 10 LOW or making it an input?


Rob

Are you using the circuit in Fig 4 of the HIH6130 datasheet?

Yes, I'm using figure 4 (left side) in the datasheet.

If so are you also removing power from the pullup resistors and the LED?

  1. If I use any pullups, it doesn't really matter, for testing I usually skip them (so I don't need t use a breadboard), for production they are there. In this case the result is the same.
  2. There is no LED. In the datasheet the LED or whatever is there is to show the use of the alarm triggers. I'm currently not using them (that is pins 5 an 6 on the HIH).
  3. I don't remove power from the pullups, the are wired directly to 3.3V on the arduino.

Also when you say "remove power" are you driving pin 10 LOW or making it an input?

I'm using: digitalWrite(X, LOW);

I'm using: digitalWrite(X, LOW);

Off hand I can't see why this would matter but we don't know what's inside the sensor. It could be that driving VDD to 0v allows some sort of low-impedance path through to the SCL and SDA pins, If so that would kill the bus.

It's easy to test, either just remove the wire to VDD or change your code to set the power pin to an input.

EDIT: Yes I can see why it would matter, if there are ESD diodes inside the sensor you will have a short through them to 0v, that will clamp the signals to about .6v.


Rob

  • set pin to input and digitalWrite(pin, LOW): doesn't work
  • set pin to input and digitalWrite(pin, HIGH): doesn't work
  • set pin to output and digitalWrite(pin, LOW): doesn't work
  • remove connection to VDD: doesn't work
  • remove connection to GND: this is the only thing that works

I guess I'll have to rethink my whole setup now :frowning:

Well I'm fresh out of ideas then, I was sure it would be the ESD diodes.

All I can suggest is that you isolated the I2C signals with an analog switch.


Rob