When the I2C bus sin't doing anything, should SDA and SCL be high or low?

I've got a custom board with a 1284p using the avr-developer's pinout and I can't for the life of me get I2C communication to work. I have checked and rechecked my schematic, I've looked at other people's code to see how they communicated with the same AS1115 chip I'm using, and I've looked at the pins_arduino.h for this variant (using Arduino 1.0.1 because that's what I first began this project on) and the I2C pin constants seem to be set correctly.

So now I'm trying to figure out what's gone wrong electrically but I don't have a logic analyzer, so I'm just probing it and I have a simple example program which should just write to the display once and stop, which should leave the I2C bus in the default state, but that default state seems to be high for both data pins, while the diagrams I've been looking at are utterly confusing and seem to either end with both lines high, or both low, or SDA high and SCL low. It doesn't make sense, and furthermore I can't tell if the pins are high because they're set high (which they shouldn't be) or because they're being pulled up by the 4.7K pull up resistors.

Here's my code:

#include <Wire.h>


// the setup routine runs once when you press reset:
void setup() {                
    
 initBargraph();
 
}

// the loop routine runs over and over again forever:
void loop() {

}

void initBargraph() {
  
  Wire.begin();
  
  Wire.beginTransmission(0x00);
  
    // AS1115 is in shutdown on power-up.  Wake up & reset feature register:
    Wire.write(0x0C); // Register
    Wire.write(0x01); // Data
  
  Wire.endTransmission();
  
  Wire.beginTransmission(0x00);
  
    // Default global intensity is minimal. Set to 100%: (The intensity of individual digits can also be set.)
    Wire.write(0x0A);
    Wire.write(0xFF);
  
  Wire.endTransmission();
  
  Wire.beginTransmission(0x00);
  
    // Set scan limit to display all digits:
    Wire.write(0x0B);
    Wire.write(0x07);
  
  Wire.endTransmission();
  
  Wire.beginTransmission(0x00);
  
    // Set all digits to "no decode":
    Wire.write(0x09);
    Wire.write(0x00);

  Wire.endTransmission();

  // Write to display:

  for(byte digit=0; digit<=7; digit++) {
    Wire.beginTransmission(0x00);
    Wire.write(digit+1);
    Wire.write(0xFF);   // turn all segments ON
    Wire.endTransmission(); 
  }
  
  // Optical test
  Wire.beginTransmission(0x00);
  Wire.write(0x0F);
  Wire.write(0x01);
  Wire.endTransmission(); 
  
}

The I2C address should be correct, the chip defaults to 0x00 unless you tell it to select a new address based on which pins you've pulled high. And I've done the same setup procedure as someone else who successfully used this chip.

That optical test bit at the end is just something I tried out of desperation. I thought maybe if I were setting the display incorrectly somehow that would show something but I get nothing.

I have also checked that my multiplexed display is wired up properly, and have tried connecting a single LED in both orientations just in case. Still nothing.

The pins are floating (high impedance) when the sketch starts. External pullup resistors might make them high.
After Wire.begin() the I2C pins are also pulled high with the internal pullup resistors (50k or 70k).
When the I2C bus is idle, the SCL and SDA should be 5V.

Address 0x00 is the broadcast address. No I2C device should use it :confused:

Run the i2c_scanner to check the bus and find the address : Arduino Playground - I2cScanner

When in doubt about the total pullup value, you can do a test. Make an empty sketch and just call Wire.begin() in the setup() function.
Measure the shortcut current from SDA to GND and the same from SCL to GND. It should be somewhere near 0.2mA to 2mA.

I ran the scanner. It said no devices found, but I noticed it does not scan for devices at 0x00 so I changed it to search for those as well, but still nothing.

These are the relevant portions of my schematic:

I've checked the chip is soldered on the bargraph module in the correct orientation. I also had two assembled and I have tried both with my own code and the test program, so it is unlikely to be any issues with the soldering. I've also double checked the layout and I have no crossed or airwires.

At this point I think it's got to be some issue with the Wire library but as far as I can tell it only ever references SDA and SCL and those should be correct. I guess I will modify that demo to print those values so I can see if they are.

Well, serial monitor says SDA = 17 and SCL = 16, just as they should be.

The datasheet of the AS1115 does indeed say that the factory default address is 0 :confused:

You could make a test sketch without using Wire functions. Just toggle SDA between INPUT_PULLUP and OUTPUT LOW. See if you can follow that signal to the AS1115 chip. Do the same for SCL.

I figured it out.

My SDA and SCL lines were getting swapped.

I've got the bargraph connected to the main board via a FFC. The connectors have identical pinouts, and the FFC has the pins on the same at both ends.

End result: If I place the two boards side by side with the connectors oriented the same way, I cannot plug the FFC into both and have the pins make contact. I have to either flip one board over, or around, or twist the cable. As the connector is mounted on the bottom of my bargraph board, this problem was difficult to detect.

Solution: Temporarily flip the connector around so the contacts are on the other side, changing the pin mapping.

Changing the pin mapping on one end isn't an ideal solution though, as I want to be cable to chain modules without having "input" and "output" ports to confuse people about what goes where. So I'll have to have flat flex cables with the connectors on opposite sides made.

Thanks for the help!

Flat ribbon cable is the worst cable for I2C.
At least don't put SCL and SDA next to each other.

Why is it the worst cable? Seems to me it should be no different than running the tracks on a PCB. I mean, aside from there being no ground plane beneath.

But I followed the I2C specs for how I arranged the pinout. SCL and SDA are separated by two ground lines, and two 5V lines run along the outside edges of the cable.

I've also got a CAT5E cable for longer runs. The FFC will be used for around 1.5' runs, while the CAT5E will run longer distances. With the CAT5E each data line is twisted with a ground line, again, according to spec. I've also got a pair of 5V lines twisted with a couple spare IO lines so I can get interrupts or read a rotary encoder.

Anyway, a 1' cable seems to work. That's the longest I can test thus far.

"My SDA and SCL lines were getting swapped."

I am not really sure what that means.
Do you mean you had a SDA from one unit, connected to the SCL of another unit? That would be in error.

All of your devices (if you have only 2, or 20), all the SDA lines should be connected common, and all your SCL lines should be connected common.

There should be one master, and the rest slaves.

There should be one pullup resistor on each of the two lines. Two resistors total.

The I2C bus wat not developed with a cable in mind. It is best used on the pcb board itself.
Up to 50 cm distance is no problem, and with seperate wires for SDA and SCL then up to 2 meters is possible (seperate wires in the air with nothing nearby).

The SDA and SCL may have 400pF to GND due to cable capacitance. A bigger problem is often cross-talk. When the SDA has a peak in the SCL (or vica versa) the I2C bus is no longer working.
Therefor the worst cable is a flat ribbon cable with SDA and SCL next to each other. You have GND wires between them, that eliminates the cross-talk, but increases the capacitance. If you can split the seperate wires, please do.
The next badest thing is SDA and SCL on a twisted pair. The signal are not ment for twisted pair at all.

Do you mean you had a SDA from one unit, connected to the SCL of another unit?

Yes. My wires were just crossed.

The next badest thing is SDA and SCL on a twisted pair. The signal are not ment for twisted pair at all.

The Cat5E cable will only run a couple meters at most. If it turns out to be a problem, there are bus transceivers I can use to convert the signals to differential at each end:

http://www.nxp.com/documents/data_sheet/PCA9615.pdf

Only a couple of meters is a lot (too much ?) for I2C.
You should check the return value of every Wire.endTransmission() and every Wire.requestFrom() to detect a problem.

You could try "Wire.setClock(50000) ;" after "Wire.begin() ;" to reduce the I2C clock speed to 50k instead of the default of 100k.
Lowering the value of the pullup resistor lowers the impedance of the I2C bus, which is better with long wires. But you have to be careful that total pullup value (of all the pullup resistors on every ATmega and every module) is not too low. The maximum current to pull SDA or SCL low is 3mA.

The PCA9615 makes some kind of differential bus (like the RS-485) and that is ment to be used for twisted pair wires (like in a Cat5e cable).

Well according to the I2C specs, I should be okay. I went back and double checked everything.

Here are the specs:
http://www.nxp.com/documents/user_manual/UM10204.pdf

And here is the capacitance for CAT5 cable with each data line twisted with a ground return:
7’ = 2.13M, 93.72pF
10’ = 3.05m, 134.2pF

Minimum pullup resistor value is calculated as follows:
(5V - 0.4V) / 0.003A = 1534 ohms

But that's only true of fast mode (<=400KHz)devices which can only sink 3mA. Fast Mode Plus devices (1MHz) can sink 20mA. I'd like to work with both though, so I'll stick with 3mA max.

Now we need to calculate the maximum pullup resistor value. That's determined by our bus capacitance and the rise time we need for our signal.

Max rise time is 120ns for fast mode plus. (1MHz)
Max rise time is 300ns for fast mode. (400Khz)

120ns max rise time / (.8473 * 135pF bus capacitance for 10ft cable) = 1K max pullup
300ns / (.8473 / 135pF) = 2.62K max pullup

For 7ft cable:
120ns / (.8473 * 94pF) = 1.5K max pullup
300ns / (.8473 * 94pF) = 3.77K max pullup

So for my needs... an I2C bus speed of 400KHz or less, over a 7-10ft twisted pair cable, 2K pullup resistors should do.

Okay, if you have the ground in the return wire, there is little crosstalk between SDA and SCL. You only have to calculate the capacitance.

The ATmega chips can pull a digital pin down with 20mA (40mA max).
When they are set into I2C mode, I think that the pin is set according to the I2C specifications to 3mA maximum.
According to the datasheet: VOL Output Low-voltage, Condition 3mA sink current is 0 to 0.4 V
Page 328

7ft = 2.13 meters
10ft = 3.05 meters

Lower the I2C clock speed, and 2 meters should work.

What if you set SDA to both wires of a pair ? (and SCL to an other pair on the other side of the cable).
What if you ground the return wire on one end with a resistor and leave it open at the other end ? or also a resistor at the other end ?
The SDA and SCL are weak slew-rate limited signals, therefor the ground does not have to be very solid. It will increase the cross-talk, but lower the capacitance.

The wire library is blocking.
The Arduino Wire library is blocking. Sometimes it waits for a signal to go high. When you are at the limits of I2C, that might have influence. Check the return values are I wrote in Reply #11 and perhaps use a custom Wire library with timeouts.