nox771 / i2c_t3

Enhanced I2C library for Teensy 3.x devices
156 stars 44 forks source link

Multiple Bus Conflict #7

Closed capricorn-one closed 7 years ago

capricorn-one commented 7 years ago

Hello, hope I'm posting this in the right place. I'm fairly certain the issue I'm having is a result of the library and not my hardware/software configuration, but I don't know enough about the library to be sure.

My hardware is a Teensy 3.2, and I'm trying to talk to multiple LED drivers (TLC59116) using both of the i2c busses. I have 4 drivers connected to the Wire bus, and 2 drivers connected to the Wire1 bus.

I have made a very basic sketch to demonstrate the problem I am having. Essentially, when I talk to the drivers over one bus, I can loop through setting and clearing the LEDs indefinitely. However, when I try and talk to both sets of busses, even though it's being done sequentially, I start to have issues. It will either run for a few seconds and crash, or other weird things will happen, and then it will crash.

I don't think it's a hardware issue, as when only when bus is running, it behaves correctly. Can anyone confirm success using more than one Wire interface at a time that there is no conflict?

here's my simple sketch: (in order to test one bus at a time, I comment out the Wire1 or Wire sections. `#include

define ALLCALL_ADDRESS 0x68

define SOFTWARE_RESET_ADDR 0x6B

define AUTO_INCREMENT_ALL_REGISTERS 0x80

define TLC_PWM0_REG 0x02

void setup() {

Wire1.begin(); Wire1.resetBus();

Wire1.beginTransmission(SOFTWARE_RESET_ADDR); Wire1.write(0xA5); Wire1.write(0x5A); Wire1.endTransmission(I2C_STOP); delay(50);

Wire1.beginTransmission(0x68); Wire1.write(byte(AUTO_INCREMENT_ALL_REGISTERS)); Wire1.write(byte(0x01)); Wire1.write(byte(0x88)); for (int i=0; i< 16; i++) Wire1.write(byte(0xFF)); Wire1.write(byte(0xFF)); Wire1.write(byte(0)); for (int i=0; i< 4; i++) Wire1.write(byte(0xFF)); Wire1.endTransmission();

// Wire.begin(); // Wire.resetBus(); // // Wire.beginTransmission(SOFTWARE_RESET_ADDR); // Wire.write(0xA5); // Wire.write(0x5A); // Wire.endTransmission(I2C_STOP); // delay(50); // // Wire.beginTransmission(0x68); // Wire.write(byte(AUTO_INCREMENT_ALL_REGISTERS)); // Wire.write(byte(0x01)); // Wire.write(byte(0x88)); // for (int i=0; i< 16; i++) // Wire.write(byte(0xFF)); // Wire.write(byte(0xFF)); // Wire.write(byte(0)); // for (int i=0; i< 4; i++) // Wire.write(byte(0xFF)); // Wire.endTransmission();

}

void loop() {

// //Set leds on Wire // for(uint8_t j=0; j<4; j++) { // for(uint8_t i=0; i<16; i++) { // setLED(0x60+j, i, 100); // delay(10); // } // }

//Set leds on Wire1 for(uint8_t j=0; j<2; j++) { for(uint8_t i=0; i<16; i++) { setLED1(0x60+j, i, 100); delay(10); } }

// //Clear all leds // for(uint8_t j=0; j<4; j++) { // for(uint8_t i=0; i<16; i++) // setLED(0x60+j, i, 0); // } for(uint8_t j=0; j<2; j++) { for(uint8_t i=0; i<16; i++) setLED1(0x60+j, i, 0); }

} // //void setLED(uint8_t address, uint8_t led, uint8_t val) { // Wire.beginTransmission(address); // Wire.write(TLC_PWM0_REG + led); // Wire.write(val); // Wire.endTransmission(); //}

void setLED1(uint8_t address, uint8_t led, uint8_t val) { Wire1.beginTransmission(address); Wire1.write(TLC_PWM0_REG + led); Wire1.write(val); Wire1.endTransmission(); }

`

nox771 commented 7 years ago

Just FYI - Regarding where to ask - for general questions you'll get more responses by asking on the Teensy forums here: https://forum.pjrc.com/forums/1-Main-Category and for I2C specifically the thread would be here: https://forum.pjrc.com/threads/21680-New-I2C-library-for-Teensy3 Posting on GH the only person who might respond would be me, as no one else will be monitoring it.

Regarding whether anyone has used multi-bus communication - yes many people have used this library in that configuration for years.

If you have the LED code working when talking to Wire or Wire1 individually, but it crashes when talking to both, my initial thought would be that you have a supply problem (or grounding problem). This could be many things - lack of bypass caps, excessive resistance in the supply line, daisy-chaining supply instead of star-wiring, and on and on. Especially with programmable LEDs as you have a large variable current load.

You could try some simple stuff:

Also checking I2C:

If the code stops executing at some point you'll need to identify where that point is. For I2C, if the bus exhibits communication errors and they go unchecked, and there is no timeout setting being used, then the bus can hang (it hangs waiting for the bus busy flag to clear). This situation can be identified via error codes, and can be circumvented by using timeouts. A simple thing is to set a default timeout and see if the hang disappears. Timeouts circumvent problems, but they don't fix them. The real fix is to identify what causes the communication to fail. That could be many things, but statistically it is usually something to do with pullups or wiring.

capricorn-one commented 7 years ago

THANK. YOU.

Sometimes I just need confirmation that I'm looking at the problem from the wrong angle. I didn't really believe there was a problem with your library, it just wasn't making any other sense the way I was thinking about it. Everyone once in a while I need a kick in the pants in the right direction. Took about 5 minutes after reading your response to figure out the problem, there was a pretty large inductor in the supply line that was probably going haywire when all the PWM leds would come on.

Seriously thank you for your fast and thorough response, saved me many hours of banging my head against the wall. And thank you for such a well written library, been using it for many years without any issues, very happy to be wrong about the issue in this case as well.

nox771 commented 7 years ago

Ok, glad it's working for you.