QT5 tinkering with a Raspberry Pi HAT on the emSBC-Argon

The following article gives a short overview on how to use and customize the emSBC-Argon to add sensors and graphic user interface. The goal of this little project was to integrate sensors from a Raspberry Pi pHAT and display the results on a QT5 user-interface. In this article, we describe two sensors examples which are the BMP280 from Bosch for temperature/pressure and the LSM303D from STMicroelectronics accelerometer.

Equipment used:

  • emSBC-Argon: This micro-processor is running a STMicroelectronics STM32MP1 MPU with Dual-Cortex-A7 and Cortex-M4.
  • DSI Display with 480x800 resolution and Touchscreen.
  • Raspberry Pi Enviro pHAT from PIMONORI :
    • BMP280 temperature/pressure sensor (0x77 on the i2c bus)
    • TCS3472 light and RGB colour sensor (0x29 on the i2c bus)
      (with two GPIO controlled LEDs for illumination)
    • LSM303D accelerometer/magnetometer sensor (0x1d on the i2c bus)
    • ADS1015 4-channel 5v tolerant 12-bit ADC (0x49 on the i2c bus)
      (3.3v 12-bit ADC at address 0x48 in first production run of the board)

First of all, the drivers corresponding to those sensors must be configured in the Linux kernel of our emSBC-Argon.

 


Sensor integration:

You can build your own, customized image using the Manual provided on our Support Website [1] Drivers can be easily added with just a few minor modifications on kernel and device-tree files. Check the .../driver/iio directory in the kernel to see if your sensor driver is provided. If not you can always contact emtrion to enquire a driver, we are happy to help you. If it's already there look up your sensor in the documentation of the kernel for the required changes in the device-tree.
In our case, we are going to add the driver for the BMP280 sensor and use the IIO (Industrial Input/Output) framework and for the second one, the LSM303D, we are going to use the direct access to the I2C bus using the Python SMBUS library.

 We can add the sensor in the Kernel image using, the command:
# make Arch=arm menuconfig

And select the Driver:

Now we need to add the sensor in the device tree :

&i2c5 {
            pressure@77 {
                           compatible = "bosch,bmp280";
                           reg = <0x77>;
                           interrupt-parent = <&gpioa>;
             };
};


You can check this out with command dmesg | grep BMP

[ 1.911556] bmp280 1-0077: Linked as a consumer to regulator.0
[ 1.920724] bmp280 1-0077: Linked as a consumer to regulator.14


Sensor input read:

The input values of the BMP280 sensor can be accessed in the root file system within these paths:
/sys/bus/iio/devices/iio:device0/in_temp_input
/sys/bus/iio/devices/iio:device0/in_pressure_input

About the accelerometer LSM303D, we have decided to use a python driver script which is simply reading the sensor inputs at precise address in the memory. Then our python script writes this data in a txt file that we put at /accelScripts/accel_input.txt. This sensor gives us 3 values corresponding to the 3 dimensions axes.

 

QT5 UI:

Using QT Creator in a free version (C++ coding language), we are able to create quick application with designed user-interface. We made the choice to display our sensor results in dynamic graphs using qcustomplot library (see https://www.qcustomplot.com ). This QT library allows you to customize your plots and make it dynamic. Using timer ticks, we can so display the sensor result every 250 millis for example, which gives a great UI result.
So there is a QTimer used, its signal timeout() is connected to a slot that will get all current sensor data thanks to driver or python script and add the corresponding points to graphs. The vectors of data points are also dynamic so that they are filled only with the several points displayed on the screen. It allows to let it run a very long time without memory crash caused by infinite allocations.


Sensor results used by QT5:

This piece of QT code is used to read the BMP280 temperature value.
// Opening the file in C++
ifstream inFile;
inFile.open("/sys/bus/iio/devices/iio:device0/in_temp_input");
// then get the value in our variable
inFile >> temp;
// Finally plot it every tick of timer.

This exactly the same coding style with the other sensor inputs. As an example we will read our file accel_input.txt to get the accelerometer values.
When the values are stored in our code, we can display them in a graph or anything else.



Back