Teensy LC and I2C not working with another LC (works with Arduino UNO)

Status
Not open for further replies.

sebrk

Member
I've been experimenting with I2C and have been running into some issues. I have wired everything up on a breadboard and using external pullup resistors (around 4.3K). The thing is I cannot get it to communicate with another Teensy LC. After banging my head I tried communicating with an Arduino UNO instead and that worked fine (same exact wiring). The one Teensy is meant to power the other btw (as it did with the UNO). I tried both Wire and i2c_t3 libraries to no avail. i2c_t3 throws an error 4 back at me which unfortunately doesn't tell me much. Any help appreciated.
 
Which code did you run on Teensy LC? And on Arduino Uno? I'm guessing you didn't run i2c_t3 on Uno.

Maybe trying running the Wire library examples? (use the more complicated i2c_t3 library only after Wire is working)

If you show photos of how you connected everything and show the exact code you ran, maybe we'll be able to notice what's wrong? Or if everything looks ok, I could try testing it here? But please, be very specific about the exact code and wiring. I have tested this stuff before and it does work, so if there is a bug in the code, I need to know the exact why you're doing things so I can recreate the problem here.
 
Which code did you run on Teensy LC? And on Arduino Uno? I'm guessing you didn't run i2c_t3 on Uno.

Maybe trying running the Wire library examples? (use the more complicated i2c_t3 library only after Wire is working)

If you show photos of how you connected everything and show the exact code you ran, maybe we'll be able to notice what's wrong? Or if everything looks ok, I could try testing it here? But please, be very specific about the exact code and wiring. I have tested this stuff before and it does work, so if there is a bug in the code, I need to know the exact why you're doing things so I can recreate the problem here.

You are right, the Arduino UNO and the one Teensy LC used Wire-library and I tested with the bundled basic master_writer and slave_receiver examples.

I have attached a photo of the setup. When testing with the UNO all I did was change the wires from the left Teensy to the UNO, including power. Let me know if you need something. I hope the photo suffices. I can assure you that the cables are correct. The resistance on each line is about 4.3K.
 

Attachments

  • IMG_1470.jpg
    IMG_1470.jpg
    150.3 KB · Views: 108
First, remove the red wire.
Then, it seems to me you inserted the resistors into the data-lines - is that correct?

That's wrong. The resistors should be connected to 3.3 volt.
 
Definitely not connected correctly.

You need to connect SDA directly to SDA, and then connect the resistor between SDA and 3.3V.

Likewise for SCL, connect SCL on one Teensy LC directly to the SCL on the other Teensy LC. Then connect a resistor from SCL to 3.3V.
 
looking at your pic i can also see you don't have the correct I2C pins wired. Since when is pins 17 and 18 for I2C? Should be 18 and 19..

Honestly I think you took out the 2nd LC and put it back at an offset of 1 pin since all wires are offset. Hopefully you didn't damage anything, especially since your running VCC from one to GND of other....
 
looking at your pic i can also see you don't have the correct I2C pins wired. Since when is pins 17 and 18 for I2C? Should be 18 and 19..

Honestly I think you took out the 2nd LC and put it back at an offset of 1 pin since all wires are offset. Hopefully you didn't damage anything, especially since your running VCC from one to GND of other....

No damage. Pins are at 18, 19. Photo is a bit angled, might be hard to see.
 
Last edited:
If only 1 is plugged into power, then yes, you would need the red wire.

You're close to getting this working. Just get those 2 signals directly connected with 1 pullup resistor per signal. I'm pretty sure you'll find it "just works" with those Wire lib examples, once we get the wires right.
 
If only 1 is plugged into power, then yes, you would need the red wire.

You're close to getting this working. Just get those 2 signals directly connected with 1 pullup resistor per signal. I'm pretty sure you'll find it "just works" with those Wire lib examples, once we get the wires right.

First off thank you all for your help. I'm new to the electrical part of making and obviously I have some way to go until I figure this out. I guess I was somewhat fooled by the internal pullup resistors of the Arduinio. Regardless this community seems solid and I'm very grateful for your time and effort in helping a noob as myself.

I did rewire according to your suggestions and the Wire examples now work. I have not tried with i2c_t3 yet but there is no reason it should not work. And using only one resistor did suffice. I still have to say that I'm not entierly clear on how the flow works though. Should think of it as the I2C signals "riding" on the 3.3V flow? But what exactly is the function of the resistor? In my simple mind it feels wrong to have have the resistors wired "behind" the I2C connection. And why resistors in the first place? What do they achieve? The word resistor seems to me to indicate that it hinders or flattens singnals?

I hope someone can shed a light on this for me. I have attached a new photo of the working setup as reference.
 

Attachments

  • IMG_1471.jpg
    IMG_1471.jpg
    146.1 KB · Views: 104
Here is one explanation of why you need pull-up resistors:

You don't need them on AVR systems, because internally the pull-up resistor that is available in the chip is strong enough. However, on ARM based systems like the Teensy, the chip's internal pull-up resistors are not strong enough, and you need to add external resistors. Note, you only need one set of resistors per i2c bus (i.e. if you have 4 devices connected, you only need a pair of resistors, and not 4 pair). I've read that in some complex i2c environments, people would have to desolder the pull-up resistors on other devices.

It would be nice if there was two simple solder jumpers on each board that could be closed to add the resistors. I bought an Adafruit Feather M4 express, and discovered that I had to put in external resistors on that system as well. And then I looked at the various other M0 and M4 offerings, and there too, you had to add the resistors.
 
Thanks. I have read multiple explanations but not all questions that arise in my head are ever answered. Can I effectively place the resistors anywhere on the line?
 
as close to the master as possible is recommended, however some people place them at the slave device. results vary but its recommended only one set near the master, and to make sure no other slaves have pullups as well.
 
Again I would really appreciate "the why" too :)

Another one that's a short & easy read.

https://www.i2c-bus.org/i2c-primer/how-i2c-hardware-works/

Key part:

allows for features like the concurrent operation of more than one I2C master (if they are multi-master capable) or stretching (slaves can slow down communication by holding down SCL).

Just to expand on this explanation a bit, the clock "stretching" is where the I2C slave device needs more time to respond. With traditional serial, this is done using an extra wire called RTS. When the slave isn't ready, it drives RTS low. When it is able to receive, it drives RTS high. The master is supposed to look at the voltage it's getting (on its CTS pin) and holds off transmitting more data when the slave isn't ready.

I2C accomplishes this without using an extra wire! This trick relies on the fact that 2 devices can both safely pull the line to logic low. When the master drives the clock low, if the slave isn't ready to reply it also drives the clock low. While the clock is low, the master can't tell anything is out of the ordinary. But when the master attempts to allow the clock to be high (by virtue of the pullup resistor - it never actively drives the line high), it then looks at the clock line to check if it actually went to logic high. If the clock remains low, the master knows this means the slave isn't ready. It waits until the slave device releases the SCL signal, and then the resistor brings it high. So I2C can accomplish flow control - waiting for a slave device that requires extra time, without using any additional wire to communicate the ready vs not-ready status.

A similar trick is done with the SDA line, to allow multiple masters to share access to the same bus. How that works is more complicated and harder to understand, so I'm going to cut this message short. Buy the underlying principle is the same - 2 or more devices can safely drive the SDA line low and the same time, and then all devices can learn info about the others by looking to see whether the SDA pin returns high when they are not actively driving it low.

Hopefully this lets you see how I2C makes use of the open collector protocol, where the devices only drive the line low and the resistor is responsible for logic high.
 
Thank you all for the information. Highly appreciated!

I have since wired everything up and it does indeed work. Fast forward and I've made a PCB design that I would like to share with you. First let me tell you that this is a hobby project for my own learning and amusement. Even though I've tried to follow best practices it is probably far from perfect. For one I know that I could do this with less hardware but I like the experiment and I had a few Teensys at home so I utilize them first. Secondly the bottom half of the PCB is not made by me but by @jerware of Tested.com and unfortunately I could not get ahold of the schematics so this is all done in layout mode (Eagle). My goal was simply to extend it with another Teensy to handle some LED-stuff and extras. This all works on my breadboard. Now I wonder if I've gotten this right. The idea is to send a I2C signal to the upper Teensy when a certain button is pressed (callback in software) and then let that unit do some stuff with LEDs. Do I have the Pull-Ups correctly wired? Would this design actually work as I intend? (again the upper half is of most interest in this case). Attached image shows the PCB. Thank you all for any valuable input.

file.jpg
 
Status
Not open for further replies.
Back
Top