No signal on i2c bus

Hi,

Im trying to connect Arduino with pcf8574 thru i2c. After many hours of tinkering I discovered, that Arduino is probably not sending any signal to wires a4/a5. Unfortunately, I have no oscilloscope or so, but my voltmeter show exact +5V on a5 wire and 0V on a4. I know it cannot be exact, but from my understanding of i2c protocol I expected values something between 0 and 5V on my voltmeter.

There is my code, which should switch on and off LED on pcf8574's pin 0 (address wires on PCF are connected to zero, so address should be B0100000).

#include <Wire.h>

void setup()
{
  Wire.begin();
}

void loop()
{
  Wire.beginTransmission(B0100000);
  delay(70);
  Wire.send(1);
  delay(200);
  Wire.send(0);
  delay(200);
  Wire.endTransmission();
}

I will be very happy if somebody find something bad on my code, because I really tested everything and without any success.

Thanks a lot,
Marek

Have you connected the two pull-up resistors on the I2C pins?

Also, remember that the 'loop()' function is called repeatedly, so your code will actually make the LED flash on and off rapidly.

I don't think those delays are going to do anything. The command is sent when you do Wire.endTransmission(). The sends just queue it up.
(At least this is my understanding.)

If you're expecting the led to blink based on this delays - I don't think it works that way. You probebly need to send a command for on and another for off.

Yes, that does make sense. So, there should be a complete "on" command followed by a delay, then a complete "off" command, then another delay.

Sorry don`t know the pcf8574 , so working from what I did with the MCP23016 .

1/ First get rid of the delays.

2/ Does to have a I/O DIRECTION REGISTERS , which you most set to output first.

3/work in blocks eg

Wire.beginTransmission(B0100000);
Wire.send(1);
Wire.send(0);
Wire.endTransmission();
delay(??);
Wire.beginTransmission(B0100000);
Wire.send(1);
Wire.send(1);
Wire.endTransmission();

4/ you do know that is putting 1 in the 2 command reg eg 0 then 1

I expected values something between 0 and 5V on my voltmeter.

No it's a digital signal, most of the time it sits at one level and then there is a very short burst of activity, you will not see this on a voltmeter.

Make sure you have the PCF8574 and not the PCF8574A as the A version has a different address.

Does to have a I/O DIRECTION REGISTERS

No it doesn't.
Peter, that code you posted will keep bit 0 high for all but the merest blip, as he only has a voltmeter or LED he will not see any change.

Make sure you have wired the address pins 1, 2 & 3 to GND as these are the least significant bits of the address line.

I know this is an overly complex example but I use these parts here:-
http://www.thebox.myzen.co.uk/Hardware/Transistor_Tester.html
Sorry if you already know that.

Hi guys, thank you for your responses! I didnt expected too many reactions :-).

Have you connected the two pull-up resistors on the I2C pins?

Also, remember that the 'loop()' function is called repeatedly, so your code will actually make the LED flash on and off rapidly.

Anachrocomputer: I tried both (internal pullups and external 10k). Without success.

I know about loop(), but there are delays (and I tested large delays between cycles too, this is only simplified example), but without effect, too.

I don't think those delays are going to do anything.

If you're expecting the led to blink based on this delays - I don't think it works that way. You probebly need to send a command for on and another for off.

BroHogan: I think so, but as I read in other i2c specifications, there should be small delay between begin and sending command in some devices. These delays are also "just for sure" and I think it cannot break anything.

I also tested separate blocks of code for "on" and "off", but also without effect.

peter247: This device doesnt have registers. It is simple 8bit expander, so each sent byte contains binary states for all pins (as far as I know - my source is this datasheet http://www.ges.cz/sheets/p/pcf8574.pdf)

Make sure you have wired the address pins 1, 2 & 3 to GND as these are the least significant bits of the address line.

Grumpy_Mike: Of course, I have.

Make sure you have the PCF8574 and not the PCF8574A as the A version has a different address.

Well, Im not sure at this moment :-[ and Im not at home for few days. To be honest - it can be the reason :-/, because I bought chip in eshop, but they have no more PCF8574, only PCF8574A on web pages. It is funny, because I spent on i2c many hours before asking this forum :-). I will write, if it helps.

Thanks,
Marek

My money is on the chance that you have a PCF8574A variant. Your address is right for the non-A.

Your code looks right, but I'll say it anyway. The correct way to build the i2c address for the Wire library is to consider it a seven-bit number. Don't just supply the top seven bits of the "address + R/!W" byte. The library shifts your address left and adds the R/!W bit.

For the PCF8574/PCF8574A, I wrote this test program. It flashes the outputs of two different slaves on the bus, so you can see the addressing work. You might keep the remoteWrite() and remoteRead() functions for yourself.

#include <Wire.h>

void remoteWrite(byte device, byte data);
byte remoteRead(byte device);

void setup()
{
    Wire.begin();
}

void loop()
{
    // send 8 output bits to i2c address 0111 001
    // (pcf8574a pin 1=H,2=L,3=L)
    remoteWrite(B0111001, 0xFF);
    delay(150);

    // send 8 output bits to i2c address 0111 010
    // (pcf8574a pin 1=L,2=H,3=L)
    remoteWrite(B0111010, 0xFF);
    delay(150);

    // send 8 output bits to i2c address 0111 001
    // (pcf8574a pin 1=H,2=L,3=L)
    remoteWrite(B0111001, 0x00);
    delay(150);

    // send 8 output bits to i2c address 0111 010
    // (pcf8574a pin 1=L,2=H,3=L)
    remoteWrite(B0111010, 0x00);
    delay(150);
}

void remoteWrite(byte device, byte data)
{
    Wire.beginTransmission(device);
    Wire.send(data);
    Wire.endTransmission();
}

byte remoteRead(byte device)
{
    Wire.requestFrom(device, (byte)1);
    byte data = 0x00;
    if (Wire.available())
        data = Wire.receive();
    return data;
}

Im a dumbass. Of course, I have "A" version ;D, so device address is B0111000. Thank you for this!

But I still have a problem, because output from chip have low current. My voltmeter says 5V (that is correct), but around 10mA (instead of 20mA in chip spec), so LED is blinking, but it has very weak intensity. Chip supply has possibility around 200mA.

Any idea, what can be wrong? Thank you.

but around 10mA (instead of 20mA in chip spec)

No the chip spec says 0.3mA as a current source (High level output current). However, 10mA as a current sink (Low level output current).

Therefore, wire your LED up so you have the 470R resistor to +5v the other end to the LED and the cathode of the LED to the chip. In that way a logic zero will turn the LED on and you will be driving the LED in the current sink mode.

Grumpy: You are a genius! It is working well, thanks a lot :-).