I2C library not working properly

I have a Xavier with Jetpack 4.1.1, and I’m trying to use the Jetsonhacks driver for the Adafruit I2c servo interface:

I’ve installed the I2C tools with the command “sudo apt-get install libi2c-dev i2c-tools” as per their instructions, and the interface board is properly detected under i2cdetect. But when I attempt to compile their example code, I get the error:

g++ servoExample.cpp ../src/JHPWMPCA9685.cpp -I../src -o servoExample
../src/JHPWMPCA9685.cpp: In member function ‘int PCA9685::readByte(int)’:
../src/JHPWMPCA9685.cpp:86:20: error: ‘i2c_smbus_read_byte_data’ was not declared in this scope
     int toReturn = i2c_smbus_read_byte_data(kI2CFileDescriptor, readRegister);
                    ^~~~~~~~~~~~~~~~~~~~~~~~
../src/JHPWMPCA9685.cpp:86:20: note: suggested alternative: ‘i2c_smbus_ioctl_data’
     int toReturn = i2c_smbus_read_byte_data(kI2CFileDescriptor, readRegister);
                    ^~~~~~~~~~~~~~~~~~~~~~~~
                    i2c_smbus_ioctl_data
../src/JHPWMPCA9685.cpp: In member function ‘int PCA9685::writeByte(int, int)’:
../src/JHPWMPCA9685.cpp:101:20: error: ‘i2c_smbus_write_byte_data’ was not declared in this scope
     int toReturn = i2c_smbus_write_byte_data(kI2CFileDescriptor, writeRegister, writeValue);
                    ^~~~~~~~~~~~~~~~~~~~~~~~~
../src/JHPWMPCA9685.cpp:101:20: note: suggested alternative: ‘i2c_smbus_ioctl_data’
     int toReturn = i2c_smbus_write_byte_data(kI2CFileDescriptor, writeRegister, writeValue);
                    ^~~~~~~~~~~~~~~~~~~~~~~~~
                    i2c_smbus_ioctl_data
Makefile:4: recipe for target 'all' failed
make: *** [all] Error 1

Does anyone know what’s going on here? In my attempts at researching this error, I’ve found a number of suggestions to include i2c-dev.h from i2c-tools instead of the kernel (which was never a problem in the Jetsonhacks I2C tutorials). If that’s what I need to do, does anyone know how to actually do that?

Thank you.

t

Ubuntu 18.04 uses SMBus differently than earlier versions. You need to:

extern “C” {
#include <i2c/smbus.h>
}

in one of the header files. Note that the JHPWMDriver is for the Jetson TK1.

Thank you, but after making that change I just get a slightly different error:

g++ servoExample.cpp ../src/JHPWMPCA9685.cpp -I../src -o servoExample
/tmp/ccw9ykah.o: In function `PCA9685::readByte(int)':
JHPWMPCA9685.cpp:(.text+0x3fc): undefined reference to `i2c_smbus_read_byte_data'
/tmp/ccw9ykah.o: In function `PCA9685::writeByte(int, int)':
JHPWMPCA9685.cpp:(.text+0x474): undefined reference to `i2c_smbus_write_byte_data'
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 1

Does anyone know what I would need to do about that? Searching that error on Google produces posts claiming that it’s a linker issue, but I have effectively zero experience with setting up linkers.

For what it’s worth, there’s a Jetsonhacks tutorial for connecting the Adafruit 4 digit 7-segment display to a Xavier, and the library they use for that appears to use an SMBus function with only the same #include statements that they have in their servo driver library.

Did you include the i2c library in your link statement ?

-li2c

The version that works for the Xavier in the 7 Segment Display is on Github in the L4T31 branch. That particular make file is:

g++ displayExample.cpp ../src/JHLEDBackpack.cpp -I../src -li2c -o displayExample

Thank you, that did the trick. I had actually sent a message from the Jetsonhacks contact page asking them about the errors I was having - hopefully, they’ll post a Xavier-compatible branch (like the one for their JHLED library) for anyone else who might want to use an I2C PWM board with a Xavier.

extern “C” did it for me - thanks!