I2C and C++

  • Hey all,

    I have been toying with the I2C driver in C++, however I am running into a problem. I got the header files and .so files on the Omega2+ (some were already loaded) and finally got the make to run correctly. However, the debugger is throwing an error with a method such as i2c_readByte. I will post the actuall error message tomorrow morning (not by the Omega at the moment). It almost seems like there needs to be an I2C object declared similar to the python version. However, I can't find the constructor in any of the source files. Is there one? How would I call a method without having on object defined?

    I haven't slept well in the past few days, so I might be completely overlooking something.



    Edit: The error messages

    OnionBME280.cpp:(.text+0x3c): undefined reference to `i2c_readByte'

    Edit: The very simple test code

    #include <stdio.h>
    #include <stdlib.h>
    #include <onion-i2c.h>
    int main()
    	int status, rdByte;
    	status = i2c_readByte(0, 0x76, 0x88, &rdByte);
    	// Print Results
    	printf("The result is: %i", status);
    	return 0;

  • Are you compiling on the Omega2 or cross compiling? Have you used the -lonioni2c flag?
    Agains what binary file are you linking? I've found that when I try to link against the libonioni2c.so that is provided in the package, linking fails. That's why I recompiled the libraries and then linking works.

    See e.g. https://github.com/gamer-cndg/omega2-wii-classic-controller and https://github.com/gamer-cndg/omega2-libs.

    I2C definetly works with C++, because I've written https://github.com/maxgerhardt/omega2-lmic-lorawan (see SC18IS602B.cpp) and that worked.

  • @Maximilian-Gerhardt I am compiling on the Omega2. I do have the flag in the make file. I am using the binary from that was pre-compiled; though I am not sure if I installed it from the GitHub Repo or it it already existing on the Omega2 out of the box.

    My make file:

    # main compiler
    CC = g++
    TARGET1 := OnionBME280
    LIBS := "-loniondebug -lonioni2c"
    all: $(TARGET1)
    	@echo "Compiling C program"
    	$(CC) $(CFLAGS) $(TARGET1).cpp -o $(TARGET1) $(LDFLAGS) $(LIB)
    	@rm -rf $(TARGET1) $(TARGET2)

    I will take a stab at recompiling the dynamic library, though I am not a g++ guru (which may be very obvious from my makefile) and I may have issue compiling it.

    Thank you for the example, I will definitely take a look. I learn in odd manners and an effective way to use an existing example and toy around with it.

    I see Kit Bishop posts here and has a library on GitHub. Any benefit to using that over Onion's?

    Thank you for your input!

  • @larry-biscuits I'm only ever cross-compiling my programs for the Omega2. Your issue may well be that you either can't link against the I2C library or GCC can't find it.

    For the latter, make sure you opkg update && opkg install libonioni2c. You can give GCC a path to the folder where the libonion2c.so is using the -L flag. The path should be /usr/lib/.. or something.

    When you want to try cross-compiling, you should use a Xubuntu 17 virtual machine (Ubuntu 18 needs a small patch to work) and compile LEDE and the toolchain as instructed in https://github.com/OnionIoT/source. Takes several hours. Or use their docker container.

    After you have a working mipsel-openwrt-linux-g++ you can cross-compile https://github.com/OnionIoT/i2c-exp-driver or just use the one from my omega2-libs folder above. With that, you can cross-compile your OnionBME280.cpp and link against the libonioni2c.so.

    Or, even easier, you can try downloading the libonioni2c.so from my repo above and try to compile and link it on the Omega2. Just make sure you use -L . to reference the current directory as a library path so that it wil maybe try to use the local .so file instead of the system's installed one..

  • Definitely got it up and running, though I got some really weird data out of a BME280 Temp, Press, Humidity sensor. It appeared one of the registers was not being read correctly. I am thinking there might be an issue with the I2C library? I compiled the same code on a Pi and it worked without problem. On the Omega, the data seemed fine until the temperature rose above a certain value (a few degrees C above room temp, heat from my finger). Once it got above this value, it seemed the read on one of the registers turns negative which doesn't seem correct.

    I recorded the register data from the Python version of the BME280 code run on the Omega and compared against the C++ code on the Omega. I couldn't find anything in the code; I even stepped through all of the raw data. It appeared that the difference/error between the Python and the C++ code was in the raw data from the I2C read function.

    I am cranking on something else at the moment and I will have to find time to crack this nut. If anyone is interested, I can post the code to see if there may be something wrong with the I2C C++ library. I have not been able to find a whole of example code, etc. for the Omega's using C++. The overwhelming majority of code out there is in Python. I am chasing down the C++ path since I am trying to build a fairly complicated program for performing analysis and need the interop so I can have the ability to blast code to an ARM, or other processor architecture.

    Again, total disclosure, I could be the one messing something up. I do a lot of dumb things.

    @Maximilian-Gerhardt thanks again for your guidance. I do believe the hiccup I initially hit was due to the .so library file. Once recompiled, it seemed fine.

  • @larry-biscuits I'd be happy to look over the code. The major difference between C++ and Python is arbitrary integer length. Your suddenly negative number could arrise from you having an integer overflow, e.g. when storing something an in int8_t.

    Do you have an example of a register value which yields two different values when decoded with the C++ and the Python problem? That way the problem can be found very quickly.

Log in to reply

Looks like your connection to Community was lost, please wait while we try to reconnect.