I2C ATTiny85 Communication

I’m unable to get the JetsonNano to detect an ATTiny85 (16MHz internal clock) in slave mode on the I2C bus. I can detect it just fine with a RaspberryPi Zero.

I’ve stripped down the code (Arduino) running on the ATTiny85:

// ATTiny85
// Joins I2C bus as slave

#include <TinyWire.h>

#define ADDRESS 0x40

void setup() {
  TinyWire.begin( ADDRESS );
}

void loop() {
}

Wiring on the Jetson to ATTiny85:

Nano J41 Pin     ATTiny85 Pin
------------     ------------
GND    (25)      GND    (4)
3.3V   (1)       VCC    (8)
SDA    (27)      SDA    (5)
SCL    (28)      SCL    (7)

I’ve confirmed that SDA and SCL levels on the bus are high when not receiving or transmitting data. I’ve checked that signals are arriving at the SDA and SCL pins as expected using a scope. Running i2cdetect -y -r 0 returns -- for every available address.

Just to make sure I wasn’t loosing my mind, I hooked it up to a RaspberryPi Zero and could see the ATTiny85 at the specified address:

$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

I’m at a loss for what the issue might be, if I’m overlooking something. Where can I find more information about the JetsonNano I2C implementation, configuration, specs that might point me toward some fixes. I haven’t been able to find any documentation detailing how to set the I2C clock frequency for the JetsonNano. Any help is greatly appreciated!

Update and Observations:

The following commands on the Jetson Nano:

$ python3
Python 3.6.9 (default, Apr 18 2020, 01:56:04) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from smbus import SMBus
>>> bus = SMBus(0)
>>> bus.write_byte_data(0x40,0,0b1010101)

Yield the following scope output:

The following commands on the Raspberry Pi Zero:

sudo python3
Python 3.7.3 (default, Dec 20 2019, 18:57:59) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from smbus import SMBus
>>> bus = SMBus(1)
>>> bus.write_byte_data( 0x40, 0, 0b10101010)

Yield the following scope output:

Observations:

  • The clock speed of the Jetson Nano was measured at ~80KHz
  • There seems to be a period where the ground floats just prior to the clock pulses from the Jetson Nano.
  • The Raspberry Pi Zero clock pulses were measured at ~40KHz
  • The clock transitions of the Jetson Nano are not nearly as clean as those of the Raspberry Pi Zero

Questions:

  • Is there a way to adjust the I2C clock frequency of the Jetson Nano, if so, how? Is there documentation on this?
  • Would pull-up resistors improve the waveform? The rising edges seem to recover very slowly.

Any other suggestions are greatly appreciated.

The difference in scope images seems consistent with the ATTiny not seeing the clock/data from the Jetson, and not responding.

The scope from the Jetson has SIGNIFICANTLY weaker pull-ups. You will need to make those pull-ups much stronger; I’d recommend at least 4x more than what you have now. If you’re using the built-in pull-ups on the GPIO ports, then add additional external 4.7 kOhm or less pull-ups to 3.3V for both clock and data. Also try running at a slower clock frequency if 100 (80) kHz doesn’t work.

Also, I assume that you’re running the ATTiny85 at 3.3V? Which is outside spec IIRC – the ATTiny will run at 8 MHz at 3.3V and 20 MHZ at 5.0V, but the Jetson is not 5V tolerant, and a 5V Tiny may not see 3.3V as “high.” (In practice, those chips are super robust and can often be over-clocked and under-volted, but data sheets are there for a reason …)

Communication Issue is Solved but not perfect…

The solution was to use I2C Bus 1 on the Jetson Nano, corresponsing to pins 3 and 5 on the J41 GPIO header. I can send data down the I2C bus using the smbus
python library and receive it at the ATTiny85. SUCCESS!

The problem remains that I am unable to scan for the ATTiny85s using i2cdetect because doing so causes the SDA pins on the ATTiny85 to drive low and never return high. This may be an issue with the TinyWire library I’m using or with my use of it. I’ll update when I get to the bottom, but for the time being, for those who go down a similar rabbit hole, try manually bringing up the SDA and SCL when your onReceive callback function exits AND make sure that it does in fact exit.