0
\$\begingroup\$

I have a RaspberryPi acting as a master for an Atmel ATTiny861A slave over i2c, continuously sending a command plus 3 bytes of data to light an RGB LED. This works perfectly but ONLY if the AVR programmer is attached (it shares the same pins I'm using for i2c) OR if my Saleae Logic analyzer is connected to SDA and SCL. If neither is connected, the Python code running on the RaspberryPi reports an "Input/output error" about every 50 to 100 commands and eventually the line will lock up; the slave holds SDA low and won't let go.

My question is, what is special about the programmer or the probes that are allowing this to work? What do I need to change to allow normal operation when they are not connected?

I don't know what conditions lead to the Python code giving the error (its hard to catch on the analyzer with the constant stream of data), but I'm assuming the slave simply doesn't respond with an ACK when it should.

Additional details; I am running about 5ft of ribbon cable from the RaspberryPi to the slave (it cannot be closer). The RPi i2c operates at 3.3V so there is a level shifter/repeater (http://www.ti.com/lit/ds/symlink/tca9509.pdf) that I connect to. The output side Vcc is 5V. Additionally on the output of the TCA9509, I have 5k pullup resistors on the SDA and SCL lines. The distance between the TCA9509 and the ATTiny861 is about 2 inches.

If its useful, this is the code running on the ATTiny861A:

https://github.com/garthwebb/dance-floor

It uses Donald Blake's USI TWI Slave driver code, modified to remove defines related to non-ATTiny861 devices.

\$\endgroup\$

bumped to the homepage by Community 8 hours ago

This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.

  • 1
    \$\begingroup\$ Your pullup resistors are too large, but more importantly your cable is well beyond what this interface is designed for. Likely your test equipment is helping provide a little parasitc load and absorbing reflections just enough to make it work. You could try distributing your pullup resistance by having 5k resistors at both ends, and you could consider using more carefully selected cables - for example examine implementation details of the I2C-like interface used in monitor cables. Unless you need replies, consider an asynchronous interface with bipolar drive and termination. \$\endgroup\$ – Chris Stratton Feb 26 '17 at 20:37
  • \$\begingroup\$ It's the probe ground that makes it work better. \$\endgroup\$ – Sunnyskyguy EE75 Feb 26 '17 at 20:47
  • \$\begingroup\$ Thank you @ChrisStratton. The test equipment is on the output side of the repeater which has a 2" length, not the 5' side. I feel it would not have an effect through the repeater like this? Point taken however on the length. I do need replies, so maybe I'll post a second question for recommendations with my requirements and constraints. \$\endgroup\$ – Garth Winter Webb Feb 26 '17 at 22:12
  • \$\begingroup\$ FYI, while I plan to re-evaluate using i2c, switching out the 5k resistor with 10k resistors seems to have fixed the problem. \$\endgroup\$ – Garth Winter Webb Feb 27 '17 at 5:53
0
\$\begingroup\$

Consider the I2C bus needing pull up resisters as most I2C drivers need to be of the open collector type. For example, here 2 10K ohm resistors bring the I2C lines back high when not pulled low by an open collector output:

enter image description here

\$\endgroup\$
  • \$\begingroup\$ In my "additional details" I noted that the i2c bus after the repeater uses a 5k resistor for SDA and SCL. For the i2c bus between the master and the repeater, note that the doc I linked to mentions in the features section "Requires no external pull-up resistors on the lower-voltage port-A". \$\endgroup\$ – Garth Winter Webb Feb 26 '17 at 21:59
0
\$\begingroup\$

I'd suggest you could use a couple of changes to improve your I2C bus.

  1. Use lower value pull-up resistors. Your long cable is highly capacitive and will result in corruption of both signal and Gnd levels.
    Use this document from TI to establish the best pull-up value at 100 kHz (the default speed in the Raspberry Pi). (Personally, I always terminate on both ends of long cables using twice the calculated pull-up value) Your TCA9509 complicates the issue a little. It already has 1 mA pull-up current sources on your A side (the Rasberry Pi), so I would put 2.5 k-Ohm single value pull-ups only on the source end of the bus.

  2. Lower your I2c bus speed. You can do this a couple of ways.

If you are using earlier copies of Raspian, then you need to use modprobe. For example: Sudo modprobe i2c_bcm2708 baudrate=50000 ...this will set the bus speed to 50 kHz
If you are using the latest builds of Raspian, then it uses device tree and you have to add elements to configure the BCM2708 to the config.txt file.
For example add these lines to config.txt:
dtparam=i2c1=on (this should already be there since I2C is enabled) dtparam=i2c_arm_baudrate=50000
....this will drop the I2C to 50 kHz
Anything you need to know about configuration control via device tree is here.

The I2C will work down to 10 kHz without any problems, and can go up to 1 Mhz equally without problems....though you could not drive your long cable at these speeds.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.