Questions on Jetson Nano - Arduino i2c communication

Hi there. Any information on how I could go on about establishing i2c communication between Nvidia Jetson Nano and Arduino… using Python?

I’ve looked up a lot of posts on Google but the replies are very unclear and usually just link to Raspberry Pi tutorials (I’m not sure if the Raspberry Pi tutorials are even 100% applicable to working with the Jetson Nano though… too much confusion!)

I also saw the tutorial on how to work with a PCA9685 PWM driver.

…But what I’m trying to do is simply establish a simple i2c bridge so I can send (Wire.write()) commands like 1, 2, 3, 4, etc. and have the Arduino receive this data using Wire.read()

This is for a humanoid robot project - where the Jetson Nano takes care of the ‘Brains’ (computer vision, reinforcement learning, etc)… and where invidiual Arduino Mini’s take care of each and every joint throughout the rest of the body, all of which are connected to stepper motors.

You can just try the linux tools i2cget to confirm the HW connection without problem first. Then try the python script.

Solved. I wired pins GND, 27 (SDA), 28 (SDL) to Arduino Nano GND, A4 (SDA), A5 (SCL) …

…and ran i2cdetect -y -r 0:

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: -- -- -- -- -- -- -- --

Here’s my Python code (must first install smbus module with Python Pip):

import smbus
import time
# Nvidia Jetson Nano i2c Bus 0
bus = smbus.SMBus(0)

# This is the address we setup in the Arduino Program
address = 0x40

def writeNumber(value):
    bus.write_byte(address, value)
    # bus.write_byte_data(address, 0, value)
    return -1

def readNumber():
    number = bus.read_byte(address)
    # number = bus.read_byte_data(address, 1)
    return number

while True:
    var = input("")
    if not var:
        continue

    writeNumber(var)
    number = readNumber()

And the Arduino code, which simply instructs a Servo on Pin 3 to move 90 degrees clockwise or counterclockwise:

#include <Wire.h>
#include <Servo.h>

int i2cAddress = 0x40;

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

//int pos = 0;    // variable to store the servo position

void setup()
{
  Wire.begin(i2cAddress);                // join i2c bus with address #0x40
  Wire.onReceive(receiveEvent); // register event
  Wire.onRequest(sendData);
  
  //Serial.begin(9600);           // start serial for output
  myservo.attach(3);  // attaches the servo on pin 3 to the servo object
  myservo.write(90);
}

int servoState = 0;

void receiveEvent(int bytes) {
  servoState = Wire.read();    // read one character from the I2C
}

void loop()
{
  if(servoState > 0) {  
    if(servoState == 2){
        myservo.write(90);
        servoState = 0;
    }
    else if(servoState == 3){    
        myservo.write(180);
        servoState = 0;                    
    }
  }
}

void sendData(){
    Wire.write(servoState);
}
1 Like