how to install qwiic drivers correctly for jetbot?

Hello,

I have manually setup a clean version of Jetpack 4.5 and performed the docker install of the JetBot code. I then performed pip3 install sparkfun-qwiic, prior to realizing I should have just run the jetbot/setup.py (which I performed immediately after).

Now, I am unable to initialize an instance of the Robot() class and I think I have narrowed it down to the i2c communication. When I attempt to scan for the OLED and motor driver, I getting the following:

import qwiic

The qwiic drivers are not installed - please check your installation

import qwiic_i2c

import qwiic

qwiic.scan()

qwiic.list_devices()

but when I do a pip3 list I DO see the correct packages installed… any ideas of what I would need to do to resolve this?

sparkfun-pi-servo-hat (0.9.0)
sparkfun-qwiic (1.1.7)
sparkfun-qwiic-adxl313 (0.0.7)
sparkfun-qwiic-alphanumeric (0.0.1)
sparkfun-qwiic-as6212 (0.0.2)
sparkfun-qwiic-bme280 (0.9.0)
sparkfun-qwiic-button (2.0.1)
sparkfun-qwiic-ccs811 (0.9.4)
sparkfun-qwiic-dual-encoder-reader (0.0.2)
sparkfun-qwiic-eeprom (0.0.1)
sparkfun-qwiic-gpio (0.0.2)
sparkfun-qwiic-i2c (1.0.0)
sparkfun-qwiic-icm20948 (0.0.1)
sparkfun-qwiic-joystick (0.9.0)
sparkfun-qwiic-keypad (0.9.0)
sparkfun-qwiic-kx13x (1.0.0)
sparkfun-qwiic-large-oled (0.0.1)
sparkfun-qwiic-led-stick (0.0.1)
sparkfun-qwiic-max3010x (0.0.2)
sparkfun-qwiic-micro-oled (0.10.0)
sparkfun-qwiic-oled-base (0.0.2)
sparkfun-qwiic-oled-display (0.0.2)
sparkfun-qwiic-pca9685 (0.9.1)
sparkfun-qwiic-pir (0.0.4)
sparkfun-qwiic-proximity (0.9.0)
sparkfun-qwiic-relay (0.0.2)
sparkfun-qwiic-rfid (2.0.0)
sparkfun-qwiic-scmd (0.9.1)
sparkfun-qwiic-serlcd (0.0.1)
sparkfun-qwiic-sgp40 (0.0.4)
sparkfun-qwiic-soil-moisture-sensor (0.0.2)
sparkfun-qwiic-tca9548a (0.9.0)
sparkfun-qwiic-titan-gps (0.1.1)
sparkfun-qwiic-twist (0.9.0)
sparkfun-qwiic-vl53l1x (1.0.1)
sparkfun-top-phat-button (0.0.2)
sparkfun-ublox-gps (1.1.5)

Note that the jetson DOES see the i2c devices, per command line output:

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

Also for reference, here is the error output when I try to initialize the Robot() class instance:

Note that I have the SparkFun hardware installed, but because it is not recognizing any i2c devices, I think it’s trying to setup an adafruit motor driver.

robot = Robot()

OSErrorTraceback (most recent call last)
<ipython-input-5-b418ad9f6ab3> in <module>
----> 1 robot = Robot()

/usr/local/lib/python3.6/dist-packages/jetbot-0.4.3-py3.6.egg/jetbot/robot.py in __init__(self, *args, **kwargs)
     20     def __init__(self, *args, **kwargs):
     21         super(Robot, self).__init__(*args, **kwargs)
---> 22         self.motor_driver = Adafruit_MotorHAT(i2c_bus=self.i2c_bus)
     23         self.left_motor = Motor(self.motor_driver, channel=self.left_motor_channel, alpha=self.left_motor_alpha)
     24         self.right_motor = Motor(self.motor_driver, channel=self.right_motor_channel, alpha=self.right_motor_alpha)

/usr/local/lib/python3.6/dist-packages/Adafruit_MotorHAT-1.4.0-py3.6.egg/Adafruit_MotorHAT/Adafruit_MotorHAT_Motors.py in __init__(self, addr, freq, i2c, i2c_bus)
    229         self.motors = [ Adafruit_DCMotor(self, m) for m in range(4) ]
    230         self.steppers = [ Adafruit_StepperMotor(self, 1), Adafruit_StepperMotor(self, 2) ]
--> 231         self._pwm = PWM(addr, debug=False, i2c=i2c, i2c_bus=i2c_bus)
    232         self._pwm.setPWMFreq(self._frequency)
    233 

/usr/local/lib/python3.6/dist-packages/Adafruit_MotorHAT-1.4.0-py3.6.egg/Adafruit_MotorHAT/Adafruit_PWM_Servo_Driver.py in __init__(self, address, debug, i2c, i2c_bus)
     57         self.i2c = get_i2c_device(address, i2c, i2c_bus)
     58         logger.debug("Reseting PCA9685 MODE1 (without SLEEP) and MODE2")
---> 59         self.setAllPWM(0, 0)
     60         self.i2c.write8(self.__MODE2, self.__OUTDRV)
     61         self.i2c.write8(self.__MODE1, self.__ALLCALL)

/usr/local/lib/python3.6/dist-packages/Adafruit_MotorHAT-1.4.0-py3.6.egg/Adafruit_MotorHAT/Adafruit_PWM_Servo_Driver.py in setAllPWM(self, on, off)
     93     def setAllPWM(self, on, off):
     94         "Sets a all PWM channels"
---> 95         self.i2c.write8(self.__ALL_LED_ON_L, on & 0xFF)
     96         self.i2c.write8(self.__ALL_LED_ON_H, on >> 8)
     97         self.i2c.write8(self.__ALL_LED_OFF_L, off & 0xFF)

/usr/local/lib/python3.6/dist-packages/Adafruit_GPIO-1.0.4-py3.6.egg/Adafruit_GPIO/I2C.py in write8(self, register, value)
    114         """Write an 8-bit value to the specified register."""
    115         value = value & 0xFF
--> 116         self._bus.write_byte_data(self._address, register, value)
    117         self._logger.debug("Wrote 0x%02X to register 0x%02X",
    118                      value, register)

/usr/local/lib/python3.6/dist-packages/Adafruit_PureIO-1.1.8-py3.6.egg/Adafruit_PureIO/smbus.py in write_byte_data(self, addr, cmd, val)
    320         # Send the data to the device.
    321         self._select_device(addr)
--> 322         self._device.write(data)
    323 
    324     def write_word_data(self, addr, cmd, val):

OSError: [Errno 121] Remote I/O error

cross-posted with https://forum.sparkfun.com/viewtopic.ph … 29#p248639[\url]

Which guide are you following?

The easiest fix is probably to just re-install/re-attempt without the mistaken step (‘I then performed pip3 install sparkfun-qwiic, prior to realizing I should have just run the jetbot/setup.py (which I performed immediately after’)…Also ensure there wasn’t a typo in the apt command (qwiic may not be supported by apt)…it looks like an issue with python and/or linux pkgs

Solution found:

qwiic has been updated since the release of the Sparkfun Jetson Nano and is now broken on the latest release. After installing sparkfun-qwiic==1.1.6 it’s working out.

The updated jetbot installation instructions are also lacking - the jetbot release 0.4.3 from pypi does not include the Sparkfun updates in it, so when I did the Docker installation, I had to uninstall jetbot package and build/install the local package, which included the Sparkfun updates.

Some of the [methods of the qwiic object are inherently broken

  • - list_devices()
  • - get_available_devices()
  • - etc.
  • When we initially started working on the Qwiic Python package, we hadn’t considered the Qwiic ecosystem would blow up so quickly or account for the multitude of I2C addresses. The beta implementation of some of the methods have, since been broken by the addition of several of our Python packages for new Qwiic devices. Unfortunately, at this time, we don’t have the resources to fix this issue. However, if you or someone you know is interested… [we are hiring!

    Please refer to:

    https://github.com/sparkfun/Qwiic_Py/is … -569757920

    I also just updated the hookup guide… for users to follow the instructions on jetbot.org (for the docker container implementation); instead of the GitHub Wiki.](Embedded Software Engineer - SparkFun Electronics)](Qwiic_Py/qwiic/__init__.py at main · sparkfun/Qwiic_Py · GitHub)