I2C and C++
-
@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) $(TARGET1): @echo "Compiling C program" $(CC) $(CFLAGS) $(TARGET1).cpp -o $(TARGET1) $(LDFLAGS) $(LIB) clean: @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 thelibonion2c.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 yourOnionBME280.cpp
and link against thelibonioni2c.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.
-
@larry-biscuits exactly how did you get it working? I have the exact same problem and have tried all suggestions in this post and nothing has worked.
-
@Brian-Franklin What exact code are you running and what exact problem do you have?
-
// This is my main.cpp
#include <iostream>
#include <onion-i2c.h>// confirmed /usr/include/onion-i2c.h exists
// confirmed /usr/lib/liboniondebug.so exists
// confirmed /usr/lib/libonioni2c.so existsint main(int argc, char* argv[])
{std::cout << "\nTest I2C Start\n" ; int status, val; status = i2c_readByte(0, 38, 0, &val); std::cout << val; std::cout << "\nTest I2C End\n\n" ; return 0;
}
during the linking
g++ main.o -o minitesti2c -loniondebug -lonioni2c
main.o: In function 'main':
/sources/minitesti2c/main.cpp: undefined reference to 'i2c_readByte'
/sources/minitesti2c/main.cpp: undefined reference to 'i2c_readByte'
collect2: error: ld returned 1 exit statusFrom the above suggestions I changed the test function to i2c_write
i2c_write(0, 56, 0, 112);
and the errors that come back are
/sources/minitesti2c/main.cpp: undefined reference to 'i2c_write'
/sources/minitesti2c/main.cpp: undefined reference to 'i2c_write'so then I copied the files /usr/lib/liboniondebug.so and /usr/lib/libonioni2c.so to the local directory and changed the link to
g++ -L/sources/minitesti2c/ main.o -o minitesti2c -loniondebug -lonioni2c
same error(s)
so then I copied the libraries reference above from
https://github.com/gamer-cndg/omega2-libs
put them in the /sources/minitest2c/ directory
same errors(s)
I can confirm that my i2c chip is wired correctly
i2cdetect -y 0 shows device at 0x38
i2cset -y 0 0x38 0x70 works!
i2cget -y 0 0x38 works. return 0x70!
I don't know what to try next.
-
This post is deleted!
-
@Brian-Franklin said in I2C and C++:
so then I copied the libraries reference above from
https://github.com/gamer-cndg/omega2-libs
put them in the /sources/minitest2c/ directory
same errors(s)You should temporarily rename the
.so
libraries// confirmed /usr/lib/liboniondebug.so exists
// confirmed /usr/lib/libonioni2c.so existsto something else so that the linker doesn't attempt to link against these. Then add
-L .
to the compiler options to add the current directory (.
) to the linker search path.
-
@Maximilian-Gerhardt Thank You.
I have been fighting against an error where it looked like the linker was not finding my the shared libonioni2c.so. Your suggestion about first renaming the current files /usr/lib/libonioni2c.so to /usr/lib/libonioni2c.so.XX and /usr/lib/liboniondebug.so to /usr/lib/liboniondebug.so.XX was a good suggestion.
My error changed to libonioni2c.so not found. So it shows me the linker was finding the correct shared object but there was something wrong with that libonioni2c.so share object. then I copied the shared objecs from github https://github.com/gamer-cndg/omega2-libs and put them in /usr/lib and everything worked!!!
2 weeks I have wasted.
Now I don't know what is in those shared objects or what is different but at least I can continue building my project.
From my 2 weeks of trying everything I have concluded that the shared object libraries provided in the standard distribution for the 2+ libonioni2c.so and/or liboniondebug.so are defective.