Is I2C working correctly on 1.5.5??

Hi,

I can't seem to figure out what the problem is.
I can't seem to get correct results using the Wire library in 1.5.5
I've read something about being a problem back in 1.5.1.
Is it still broken?
I seem to always get true when I can Wire.available() and I seem to get always something other than zero on Wire.endTransmission() even though the device is in the bus.
Any help would be appreciated.

Thank you,
RI

Does anyone have any comments?
All posts I read date back to 1 year ago and I couldn't get Wire library work correctly yet.
Is there any alternative for I2C on Due board?

It works fine so far as I know. I'm involved with a fairly large project that uses the Arduino core with a custom Due-like board (GEVCU - an ECU for electric cars). This project includes I2C connected EEPROM and it works fine. I'm using a custom wire library but the only difference is that I enlarged the buffer to something like 270 bytes so that I could send 256 byte EEPROM pages along with a header all in one shot. So, I'd say that the wire library for Due works fine.

Here is a simple code to test:

#include <Wire.h>


int a;

void setup() {
  // put your setup code here, to run once:
  Wire.begin();
  Serial.begin(57600);
}

void loop() {
  // put your main code here, to run repeatedly:
  Wire.beginTransmission(0X4d);
  Serial.println(Wire.endTransmission());
  delay(100);
}

You can change the I2C address to whatever chip you have available.
This example always returns 1 whether the chip is found or not....
1 means data too long to fit in transmit buffer
It should be 0 for found and 2 for not found.
Attached are some screenshots to confirm the chip is responding correctly for both not found and found.

found.png

not-found.png

I'll chime in.... The last time I checked Wire.endTransmission() is still broken, and as a result, utilities like I2CScanner won't work, as well as repeated starts.

You can code around these issues. Search this forum for solutions.

I have not looked at the latest builds, so I can't say for sure if the issues are still present there. I suppose you should scan the release notes.

-Chris

Well, the endTransmission is the least of my problems... It's just something I found along the way of trying to find out why my code wasn't working...
So, here is the biggest issue I have:

#include <Wire.h>


int a;

void setup() {
  // put your setup code here, to run once:
  Wire.begin();
  Serial.begin(57600);
}

void loop() {
  // put your main code here, to run repeatedly:
  Wire.requestFrom(0X4d,2);
  if (Wire.available())
    Serial.println((Wire.read()<<8)+Wire.read());
  delay(100);
}

In this code, I get serial print all the time no matter if the chip is found or not.
It gets worse, if the chip is found, it correctly displays the results by reading the 2 incoming bytes, but if the chip is disconnected, it starts returning garbage. For example, it returns always 65321. If I connect and disconnect again, it returns a different number.
I scanned the bus and I can see the 2 bytes coming in when the device is plugged. See attachment.
But when the device is disconnected, I do see the correct response of the bus, which is exactly like the not found picture on the previous post.
So, the hardware is indeed responding correctly with a NACK, but the library is returning me garbage that I don't know where it came from. I think the problems really lies on the Wire.available() that is always returning true.

incoming-data.png

Yes.
No NACK detection...

Examples/solutions in the forum.
Like:
http://forum.arduino.cc/index.php?topic=182727.0
From August, and links to posts from February of 2013.

-Chris

Cool. Thanks.
I guess it is still broken even after 1 year :frowning:
Did you ever send a patch or merge request to the arduino team with your changes?
It would help a ton of people if the library was fixed once and for all.
I'll try to change my libs too if I can wrap my head around the low level code.

newhobby:
In this code, I get serial print all the time no matter if the chip is found or not.
It gets worse, if the chip is found, it correctly displays the results by reading the 2 incoming bytes, but if the chip is disconnected, it starts returning garbage. For example, it returns always 65321. If I connect and disconnect again, it returns a different number.
I scanned the bus and I can see the 2 bytes coming in when the device is plugged. See attachment.
But when the device is disconnected, I do see the correct response of the bus, which is exactly like the not found picture on the previous post.
So, the hardware is indeed responding correctly with a NACK, but the library is returning me garbage that I don't know where it came from. I think the problems really lies on the Wire.available() that is always returning true.

Oh, yes, I do think that my project exhibits this sort of behavior. If the EEPROM is on the board and responding properly then the program can get and set data. But, if the chip isn't there it still "works" in the sense that it returns data. However, as you found, it returns garbage that seems to be either random or some artifact of the hardware or software state.

I just pretend to be a programmer (I'm actually a EE, the most dangerous type of coder).

It is my sincere belief that the skills of the Arduino team far surpass my own.

In addition, this DUE project of mine is on indefinite-hold. Testing any code at this moment is not possible.

-Chris

Ok, I went ahead and took a jab at fixing this. I kind of needed it to work or my project would just end up down the toilet and I don't want this to happen after all the time, money and effort spent in developing prototypes and everything.
I only needed to modify the Wire.cpp file.
If anyone would kindly test it out to make sure it works, it would be great.
I was able to get Wire.available and Wire.endTransmission to behave as it was on the avr platform.
There may be other functions that can be improved too, but since I don't need them, they were not touched.
So, if you run the I2CScanner, it should work. Let me know if it doesn't.
Attached are the Wire.cpp and I2CScannerDue.ino that I used to test it.

I2CScannerDue.ino (982 Bytes)

Wire.cpp (10.5 KB)

NewHobby

I've been going crazy trying to get the Due to communicate with the UDA1380 audio board. My Pro Mini could find it, but, the Due couldn't Not with the existing SAM Wire.cpp library. I don't have a scope, yet, so i had to wire up an Arduino Scope, at least i could see there was activity on the SDA and SCL, but, couldn't tell if the data was correct.

Finally, after weeks - about to give up and go a different route, finally your wire.cpp at least the scanner program finds it - finally, now on to seeing what changes you made and see if i can read and write to the registers in the UDA 1380.
Once i get the i2c interface working, then i've got to deal with the i2s interface.... receiving digitized audio into the Due from the UDA1380, processing it, and sending it back out to the UDA1380 - this project is going to take me forever, but, you libraries finally allowing me to complete step 1... After weeks and weeks of bald headed hair pulling. Thank You

The Due has been around for some time, why has this issue not been resolved. I found one thread where someone said that the Wire library was one of the first to be ported to the Due, it works for simple devices - maybe, but totally failed on others. Now I'm wondering how many other libraries are totally off when it come to other processors, like the Due.

Awesome!!!
Glad it worked out for you :slight_smile:

I tried Newhobby's code. It blows up for me in endTransmission(). It sets off an infinite sketch reset that keeps cycling through setup(). It appears to blow in the following:

uint8_t TwoWire::endTransmission(uint8_t sendStop) {
	uint8_t code=0;
	// transmit buffer (blocking)

 //////////////////// BLOWS IN THIS CALL //////////////////
	TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]);

 	if (TWI_WaitByteSent(twi, XMIT_TIMEOUT)==0) code=2;  
	int sent = 1;
  	while (sent < txBufferLength) {
		TWI_WriteByte(twi, txBuffer[sent++]);
		if (TWI_WaitByteSent(twi, XMIT_TIMEOUT)==0) code=3;
	}
 	TWI_Stop( twi);
	if (TWI_WaitTransferComplete(twi, XMIT_TIMEOUT)==0) code=4;
   
	// empty buffer
	txBufferLength = 0;

	status = MASTER_IDLE;
	return code;
}

There are dozens of posts about Due's I2C problems. Some assert the Wire library is broke. Some assert it works. Most agree that endTransmission() gives unexpected results. I have spent hours following the threads, but have yet to find a way to get the Due I2C to work, on either channel. What would be most helpful would be a repeatable solution that would allow a scan of I2c addresses on the bus.

Any help appreciated.

Are you sure your bus is free?

i am testing my i2c chips on a breadboArd using SDA1/SCL1 and 4k6 pullups. I can see the SDA1 line bounce in my DVM when I scan the addresses 1-127. Wire1.endTransmission() returns that it sent out each address. But I can't seem to get any response.

The same setup on an Uno at 5v finds the devices. I don't have a scope to see the waveform.

I have tried 2.2k pullups. And the default I2C pins w/o pullups.

I have a couple of mux's ( PCF8574, MCP30137) and a DS1307 RTC to play with. Would love to have a recipe to get one of these to communicate with the DUE.

I thought I was making a little progress. I found a 24LC256 I2C EEPROM in my kit and hooked it all up again with Newhobby's code. The Due scanner appeared to recognize an I2C device! However, the address did not change when i selected different address pins. The number of false positives increase as I increase the pullups from 1k to 5k. and I get a false positive or an error code 4 for each address.

	while (sent < txBufferLength) {
		TWI_WriteByte(twi, txBuffer[sent++]);
		if (TWI_WaitByteSent(twi, XMIT_TIMEOUT)==0) code=3;
	}
	TWI_Stop( twi);
	if (TWI_WaitTransferComplete(twi, XMIT_TIMEOUT)==0) code=4;  //////  here ///////////////////

I am usind SDA1/SCL1. I'll try some other devices and report back.

I have not tried with sda1/scl1.
I only tried with sda/scl.

I'm not getting anywhere. With no I2C pins connected, I get a hit on about 1/3 of the addresses. If I hook up SDA1/SCL1 to 1K pullups, I get an apparent hit on the same 2 addresses, 0x04 and 0x08. But that is with or without the EEPROM! Hooking up to SDA/SCL just gets me about half random hits. I need to get a scope on this.