Jetbot - I2C I/O error 121

Hi,

I started working on a jetbot project last week, implementing the Jetbot_ros solution ( GitHub - dusty-nv/jetbot_ros: ROS nodes and Gazebo model for NVIDIA JetBot with Jetson Nano) last week. All instructions followed on GitHub - dusty-nv/jetbot_ros: ROS nodes and Gazebo model for NVIDIA JetBot with Jetson Nano with no errors.

I’m receiving an i2c I/O Error 121. when running the ros node: rosrun jetbot_ros jetbot_motors.py. I tried many things to resolve this but have not been able worked. The sudo i2cdetect -y -r 1 command showed the OLED display at 0X30 but nothing for the the Adafruit driver board.

I tried just connecting the board to the nano pins directly, without the OLED, no luck.

I changed the Adafruit_MotorHAT/Adafruit_MotorHAT_Motors.py line 227 change:
def init (self, addr = 0x60, freq = 1600, i2c=None, i2c_bus=None):
to:
def init (self, addr = 0x60, freq = 1600, i2c=None, i2c_bus = 1): no luck.

I check the wiring based on , no luck…

Checked all solder points.

The power light is on on the Adafruit Board

JetPack 4.5.1
Ubuntu 18.04 LTS
ROS Melodic

Using GPIO Nano Pins 1,3,5,6

ros@jetson:~/workspace/catkin_ws/src/jetbot_ros/scripts$ sudo i2cdetect -y -r 1
[sudo] password for ros: shows the OLED but not the DC Motor Driver
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – – – – – – – – – – – – –
10: – – – – – – – – – – – – – – – –
20: – – – – – – – – – – – – – – – –
30: – – – – – – – – – – – – 3c – – –
40: – – – – – – – – – – – – – – – –
50: – – – – – – – – – – – – – – – –
60: – – – – – – – – – – – – – – – –
70: – – – – – – – –

RUN node:
rosrun jetbot_ros jetbot_motors.py

CODE for jetbot_motors.py:

#!/usr/bin/env python
import rospy
import time

from Adafruit_MotorHAT import Adafruit_MotorHAT
from std_msgs.msg import String

sets motor speed between [-1.0, 1.0]

def set_speed(motor_ID, value):
max_pwm = 115.0
speed = int(min(max(abs(value * max_pwm), 0), max_pwm))

if motor_ID == 1:
motor = motor_left
elif motor_ID == 2:
motor = motor_right
else:
rospy.logerror(‘set_speed(%d, %f) → invalid motor_ID=%d’, motor_ID, value, motor_ID)
return

motor.setSpeed(speed)

if value > 0:
motor.run(Adafruit_MotorHAT.FORWARD)
else:
motor.run(Adafruit_MotorHAT.BACKWARD)

stops all motors

def all_stop():
motor_left.setSpeed(0)
motor_right.setSpeed(0)

motor_left.run(Adafruit_MotorHAT.RELEASE)
motor_right.run(Adafruit_MotorHAT.RELEASE)

directional commands (degree, speed)

def on_cmd_dir(msg):
rospy.loginfo(rospy.get_caller_id() + ’ cmd_dir=%s’, msg.data)

raw L/R motor commands (speed, speed)

def on_cmd_raw(msg):
rospy.loginfo(rospy.get_caller_id() + ’ cmd_raw=%s’, msg.data)

simple string commands (left/right/forward/backward/stop)

def on_cmd_str(msg):
rospy.loginfo(rospy.get_caller_id() + ’ cmd_str=%s’, msg.data)

if msg.data.lower() == “left”:
set_speed(motor_left_ID, -1.0)
set_speed(motor_right_ID, 1.0)
elif msg.data.lower() == “right”:
set_speed(motor_left_ID, 1.0)
set_speed(motor_right_ID, -1.0)
elif msg.data.lower() == “forward”:
set_speed(motor_left_ID, 1.0)
set_speed(motor_right_ID, 1.0)
elif msg.data.lower() == “backward”:
set_speed(motor_left_ID, -1.0)
set_speed(motor_right_ID, -1.0)
elif msg.data.lower() == “stop”:
all_stop()
else:
rospy.logerror(rospy.get_caller_id() + ’ invalid cmd_str=%s’, msg.data)

initialization

if name == ’ main ':

setup motor controller

motor_driver = Adafruit_MotorHAT(i2c_bus=1)

motor_left_ID = 1
motor_right_ID = 2

motor_left = motor_driver.getMotor(motor_left_ID)
motor_right = motor_driver.getMotor(motor_right_ID)

stop the motors as precaution

all_stop()

setup ros node

rospy.init_node(‘jetbot_motors’)

rospy.Subscriber(‘~cmd_dir’, String, on_cmd_dir)
rospy.Subscriber(‘~cmd_raw’, String, on_cmd_raw)
rospy.Subscriber(‘~cmd_str’, String, on_cmd_str)

start running

rospy.spin()

stop motors before exiting

all_stop()

ros@jetson:~/workspace/catkin_ws/src/jetbot_ros/scripts$ rosrun jetbot_ros jetbot_motors.py
Traceback (most recent call last):
File “/home/ros/workspace/catkin_ws/src/jetbot_ros/scripts/jetbot_motors.py”, line 75, in
motor_driver = Adafruit_MotorHAT(i2c_bus=1)
File “/home/ros/.local/lib/python2.7/site-packages/Adafruit_MotorHAT/Adafruit_MotorHAT_Motors.py”, line 231, in init
self._pwm = PWM(addr, debug=False, i2c=i2c, i2c_bus=i2c_bus)
File “/home/ros/.local/lib/python2.7/site-packages/Adafruit_MotorHAT/Adafruit_PWM_Servo_Driver.py”, line 59, in init
self.setAllPWM(0, 0)
File “/home/ros/.local/lib/python2.7/site-packages/Adafruit_MotorHAT/Adafruit_PWM_Servo_Driver.py”, line 95, in setAllPWM
self.i2c.write8(self.__ALL_LED_ON_L, on & 0xFF)
File “/home/ros/.local/lib/python2.7/site-packages/Adafruit_GPIO/I2C.py”, line 114, in write8
self._bus.write_byte_data(self._address, register, value)
File “/home/ros/.local/lib/python2.7/site-packages/Adafruit_PureIO/smbus.py”, line 268, in write_byte_data
self._device.write(data)
IOError: [Errno 121] Remote I/O error

Any thoughts?

I have had a similar issue come up running jetbot tutorials. I think that there is some flakeyness that occurs between the OLED, 40 pin header and the adafruit driver board. I believe the actuall electrical connections are a little loose using jumper wires and that is what causes it to fail.

I soldered all my connections today and reset everything and that seemed to help.

If this is what is occurring it is a difficult fault to track down because it works when you connect a voltmeter up to it, but it seems that all it takes is one little momentary disconnection and everything fails, and fails hard.

Hi Michael,
Thanks for letting me know. I agree with your analysis. There is something flaky between the OLED and adafruit driver board. Just wasn’t sure where the issue was.

I will go back and re-solder my connections and try again.

Your help is really appreciated. Thanks again!

Unfortunately, after resoldering and checking everything again, the motor board is still not recognizing the adafruit driver board, it only recognizes the OLED. I triple-checked everything. Resoldered with no luck. Multimeter continuity checks on all connections checked out.

The adafruit motor driver board is not found on i2c. Is there other software that is needed to make this connection?
shows the OLED but not the DC Motor Driver
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – – – – – – – – – – – – –
10: – – – – – – – – – – – – – – – –
20: – – – – – – – – – – – – – – – –
30: – – – – – – – – – – – – 3c – – –
40: – – – – – – – – – – – – – – – –
50: – – – – – – – – – – – – – – – –
60: – – – – – – – – – – – – – – – –
70: – – – – – – – –

Help!

It turned out that the motor board was BAD! I sent this thread info to Adafruit. They thought that the motor board was probably bad since no devices were showing up when running the sudo i2cdetect -y -r 1 command. They replaced the motor board free of charge. Thanks Adafruit for your quick response and resolution! I just tried the new board and it works great!