Difference between revisions of "How to integrate the IKS01A2 expansion board with STM32MP157C-DK2"

[quality revision] [checked revision]
m (Hardware / software interface)
(Example of screenshot for displaying information)

1 Article purpose[edit]

The purpose of this article is to explain how to integrate the IKS01A2 expansion board with STM32MP157C-DK2, managed by Linux on Cortex-A7.

The IKS01A2 board is an expansion board composed by that includes several motion MEMS like HTS221 and LSM6DSL.

This article explains provides step-by-step instructions to:

  • how to configure Linux software to support IKS01A2 expansion board,
  • how to activate/use several motion MEMS such as HTS221 and LSM6DSL.

2 Prerequisites[edit]

2.1 Hardware prerequisites[edit]

  • STM32MP157C-DK2
STM32MP157C-DK2

For more information about this the STM32 discovery board and how to start with it up, jump to this section Getting_started/STM32MP1_boards/STM32MP157C-DK2

  • IKS01A2 expansion board
IKS01A2
IKS01A2 expansion board

2.2 Software prerequisites[edit]

The STM32MP157C-DK2 board must be populated downloaded with appropriate software to be able to customize it to in order to support IKS01A2 expansion board. To know how to proceed please For proceeding, follow the step-by-step description starting with instructions provided at STM32MP157C-DK2 Let's start article.

3 Software customization to support IKS01A2 expansion board[edit]

The STM32MP157C-DK2 Linux software must be configured to activate the IKS01A2 board connected on top of the STM32MP157C-DK2 board.

Configuration is done by The configuration consists in modifying the STM32MP157C-DK2 Linux kernel and by managing some new device tree elements.

3.1 Kernel configuration[edit]

By default, the motion MEMS drivers , present on IKS01A2 expansion board , are enabled in STM32MP1 kernel configuration: hts221, pressure(lp22hb) and lsm6dsl. The device tree must be updated to declare and activate them.

To check whether associated drivers are enabled inside the kernel, follow type the commands given provided here below :

Board $>  cat /proc/config.gz | gunzip | grep HTS221
CONFIG_HTS221=y
CONFIG_HTS221_I2C=y
CONFIG_HTS221_SPI=y
Board $>  cat /proc/config.gz | gunzip | grep ST_PRESS
CONFIG_IIO_ST_PRESS=m
CONFIG_IIO_ST_PRESS_I2C=m
CONFIG_IIO_ST_PRESS_SPI=m
Board $>  cat /proc/config.gz | gunzip |  grep ST_LSM6DS
CONFIG_IIO_ST_LSM6DSX=m
CONFIG_IIO_ST_LSM6DSX_I2C=m
CONFIG_IIO_ST_LSM6DSX_SPI=m
Info.png If those the above configurations are not enabled on your kernel configuration, please follow the indications given in Modify, rebuild and reload the Linux® kernel

3.2 Kernel device tree configuration[edit]

3.2.1 Hardware / software interface[edit]

Motion MEMS The HTS221 and LSM6DSL , motion MEMS present on IKS01A2 expansion board are used involved in the following use case explained in this article.
According to IKS01A2 user manual[1], both motion MEMS are controlled by I2C ITemplate:SupC bus.

In the schematics of IKS01A2 [2] and STM32MP157C-DK2[3] , presented below, are identified the pins which that interconnected are connected togetherhighlighted.

  • IKS01A2 schematic (Arduino connector) [2]
    • Pins 10 and 9 of CN5 are used for I2C ITemplate:SupC Bus (SDA and SCL) (I2C1 and I2C2 bus instances are mixed via the jumper JP7 and JP8 jumpers)
    • Pins 6 and 5 of CN9 are used to manage interruptions on LSM6DSL motion MEMS (indicated for information: not used on kernel configuration).
Screenshot iks01a2
IKS01A2 schematics extract
  • STM32MP157C-DK2 schematic (Arduino connector) [3]
    • Pins 10 and 9 of CN5 are used for I2C ITemplate:SupC Bus (I2C5_SDA and I2C5_SCL)
    • Pins 6 and 5 of CN14 are used to manage interruptions on LSM6DSL motion MEMS (indicated for information: not used on kernel configuration)
Screenshot stm32mp157c-dk2
stm32mp157c-dk2 schematics extract


Warning.png I2C5 bus instance MUST be enabled on by software in order to access to the motion MEMS present on IKS01A2

3.2.2 Kernel device tree configuration[edit]

As seen indicated in previous chaptersection, the IKS01A2 expansion board is controlled via IC2 ITemplate:SupC bus. On STM32MP157C-DK2, the associated I2C ITemplate:SupC bus is I2C5.

The I2C5 bus must be activated into STM32MP157C-DK2 device tree and a node for each hardware to support must be added (see entry on device tree entries like hts221, below, on the following as shown in the device tree content example below).


For that, add following content into stm32mp157c-dk2.dts file:

 &i2c5 {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&i2c5_pins_a>;
	pinctrl-1 = <&i2c5_pins_sleep_a>;
	i2c-scl-rising-time-ns = <124>;
	i2c-scl-falling-time-ns = <3>;
	/delete-property/dmas;
	/delete-property/dma-names;

	status = "okay";

	hts221@5f {
		compatible = "st,hts221";
		reg = <0x5f>;
	};
	lsm6dsl@6b {
		compatible = "st,lsm6dsl";
		reg = <0x6b>;
	};
 };
Info.png To generate a new device tree, please follow the indications given in Modify, rebuild and reload the Linux® kernel

3.3 Activate the new configuration in the STM32MP157C-DK2 board[edit]

  • Add the two generated files on in the board file system of board, more accurately precisely in the bootfs partition (/boot directory)
Board $> ls -1 /boot/stm32*dk2*
                                                                                              
/boot/stm32mp157c-dk2-a7-examples.dtb
/boot/stm32mp157c-dk2-iks01a2.dtb
/boot/stm32mp157c-dk2-m4-examples.dtb
/boot/stm32mp157c-dk2.dtb
  • Add a new entry in extlinux.conf file , here located in /boot/mmc0_stm32mp157c-dk2_extlinux/. If no directory the mmc0_<something> directory is not available, add the new entry in /boot/extlinux/extlinux.conf.
 
 # Generic Distro Configuration file generated by OpenEmbedded
 menu title Select the boot mode
 MENU BACKGROUND ../splash.bmp
 TIMEOUT 20
 DEFAULT stm32mp157c-dk2-iks01a2
 LABEL stm32mp157c-dk2-sdcard
         KERNEL /uImage
         FDT /stm32mp157c-dk2.dtb
         APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
 LABEL stm32mp157c-dk2-a7-examples-sdcard
         KERNEL /uImage
         FDT /stm32mp157c-dk2-a7-examples.dtb
         APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
 LABEL stm32mp157c-dk2-m4-examples-sdcard
         KERNEL /uImage
         FDT /stm32mp157c-dk2-m4-examples.dtb
         APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
 LABEL stm32mp157c-dk2-iks01a2
        KERNEL /uImage
        FDT /stm32mp157c-dk2-iks01a2.dtb
        APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
Warning.png Do not forget to synchronize the file system before rebooting the board
Board $> sync


  • Reboot the board

3.4 Verify the new configuration on board[edit]

  • Verify if i2c5 is enabled:
Board $>  cat /proc/device-tree/soc/i2c\@40015000/status 
okay
  • Verify if the motion MEMS drivers are declared on in the device tree node:
Board $> ls -l /proc/device-tree/soc/i2c\@40015000/
total 0
-r--r--r-- 1 root root  4 Dec 19 11:01 #address-cells
-r--r--r-- 1 root root  4 Dec 19 11:01 #size-cells
-r--r--r-- 1 root root  8 Dec 19 11:01 clocks
-r--r--r-- 1 root root 15 Dec 19 11:01 compatible
-r--r--r-- 1 root root  6 Dec 19 11:01 dma-names
-r--r--r-- 1 root root 32 Dec 19 11:01 dmas
drwxr-xr-x 2 root root  0 Dec 19 10:54 hts221@5f
-r--r--r-- 1 root root  4 Dec 19 11:01 i2c-scl-falling-time-ns
-r--r--r-- 1 root root  4 Dec 19 11:01 i2c-scl-rising-time-ns
-r--r--r-- 1 root root 19 Dec 19 11:01 interrupt-names
-r--r--r-- 1 root root 44 Dec 19 11:01 interrupts-extended
drwxr-xr-x 2 root root  0 Dec 19 10:54 lsm6dsl@6b
-r--r--r-- 1 root root  4 Dec 19 11:01 name
-r--r--r-- 1 root root  4 Dec 19 11:01 pinctrl-0
-r--r--r-- 1 root root  4 Dec 19 11:01 pinctrl-1
-r--r--r-- 1 root root 14 Dec 19 11:01 pinctrl-names
-r--r--r-- 1 root root  4 Dec 19 11:01 power-domains
-r--r--r-- 1 root root  8 Dec 19 11:01 reg
-r--r--r-- 1 root root  8 Dec 19 11:01 resets
-r--r--r-- 1 root root 12 Dec 19 11:01 st,syscfg-fmp
-r--r--r-- 1 root root  5 Dec 19 11:01 status
  • Verify if the motion MEMS drivers are correctly probed and if the system provides access to the associated hardware:
Board $>  grep OF_NAME /sys/bus/iio/devices/iio\:device*/uevent
/sys/bus/iio/devices/iio:device0/uevent:OF_NAME=adc
/sys/bus/iio/devices/iio:device1/uevent:OF_NAME=adc
/sys/bus/iio/devices/iio:device2/uevent:OF_NAME=hts221
/sys/bus/iio/devices/iio:device3/uevent:OF_NAME=temp
/sys/bus/iio/devices/iio:device4/uevent:OF_NAME=lsm6dsl
/sys/bus/iio/devices/iio:device5/uevent:OF_NAME=lsm6dsl
Info.png If the results are different then , check that
  1. the expansion board is correctly connected
  2. all steps, described above, were correctly done.

4 Read motion MEMS via bash script[edit]

The goal of this section are is to read the informations provided by Linux kernel interface and to process it on with a bash script.


4.1 List of sensors entry[edit]

The IKS01A2 expansion board provides several MEMS like HTS221, LSM6DSL, LPS22HB.
Hardware The list of hardware MEMS , detected by Linux via the IIO framework, can be listed by verifying the entries on verified in the sysfs.

Board $>   grep OF_NAME /sys/bus/iio/devices/iio\:device*/uevent
/sys/bus/iio/devices/iio:device0/uevent:OF_NAME=adc
/sys/bus/iio/devices/iio:device1/uevent:OF_NAME=adc
/sys/bus/iio/devices/iio:device2/uevent:OF_NAME=hts221
/sys/bus/iio/devices/iio:device3/uevent:OF_NAME=temp
/sys/bus/iio/devices/iio:device4/uevent:OF_NAME=lsm6dsl
/sys/bus/iio/devices/iio:device5/uevent:OF_NAME=lsm6dsl

This list of entries permits to know which entries are associated to a MEMS driverprovides the association between entries and MEMS drivers. In the rest of the article, this list is kept used a as reference list of entries.

4.2 HTS221: Temperature/Humidity[edit]

The HTS221 is a capacitive digital sensor for relative humidity and temperature.

In this example, hts221 entries are entry is /sys/bus/iio/devices/iio:device2/, please adapt to your setup if it's not the case by changing the entry on the scripts described/explained in following chapters. In case the user as a different setup the entry should be adapted accordingly in the scripts provided here after.

4.2.1 Temperature[edit]

  • Read IIO entries associated to the temperature for HTS221 driver
Board $>  cat /sys/bus/iio/devices/iio\:device2/in_temp_raw
Board $>  cat /sys/bus/iio/devices/iio\:device2/in_temp_offset
Board $>  cat /sys/bus/iio/devices/iio\:device2/in_temp_scale
  • Calculate real temperature according following formula
Temperature = ( Raw value + Offset value) * Scale value)
  • Calculate temperature by shell script : static IIO entries

Content of hts221_read_temperature_on_device2.sh:

#!/bin/sh
raw=`cat /sys/bus/iio/devices/iio\:device2/in_temp_raw`
offset=`cat /sys/bus/iio/devices/iio\:device2/in_temp_offset`
scale=`cat /sys/bus/iio/devices/iio\:device2/in_temp_scale`
printf "Value read: raw         %0f\n" $raw
printf "Value read: offset      %0f\n" $offset
printf "Value read: scale       %0f\n" $scale

temperature=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

echo "Temperature $temperature"
printf "Temperature %.01f\n" $temperature


  • Calculate temperature by shell script: auto detection of IIO entries

Content of hts221_read_temperature_with_entry_detection.sh:

#!/bin/sh
DRIVER_NAME=hts221
for d in `ls -d1 /sys/bus/iio/devices/*device*`;
do
    if grep -q $DRIVER_NAME $d/name ;
    then
        raw=`cat $d/in_temp_raw`
        offset=`cat $d/in_temp_offset`
        scale=`cat $d/in_temp_scale`

        printf "Value read: raw         %0f\n" $raw
        printf "Value read: offset      %0f\n" $offset
        printf "Value read: scale       %0f\n" $scale

        temperature=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

        echo "Temperature $temperature"
        printf "Temperature %.01f\n" $temperature

        break;
    fi
done
  • Test on board
Board $>  ./hts221_read_temperature_on_device2.sh
Value read: raw         563.000000
Value read: offset      1036.674817
Value read: scale       0.019172
Temperature 30.668765624
Temperature 30.7

4.2.2 Humidity[edit]

  • Read IIO entries associated to humidity for HTS221 driver
Board $> cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_raw
Board $> cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_offset
Board $> cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_scale
  • Calculate real humidity according following formula
Humidity = ( Raw value + Offset value) * Scale value)
  • Calculate humidity by shell script: static IIO entries

Content of hts221_read_humidity_on_device2.sh:

#!/bin/sh
raw=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_raw`
offset=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_offset`
scale=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_scale`
printf "Value read: raw         %0f\n" $raw
printf "Value read: offset      %0f\n" $offset
printf "Value read: scale       %0f\n" $scale

humidity=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

echo "Humidity $humidity"
printf "Humidity %.01f\n" $humidity


  • Calculate humidity by shell script: auto detection of IIO entries

Content of hts221_read_humidity_with_entry_detection.sh:

#!/bin/sh
DRIVER_NAME=hts221
for d in `ls -d1 /sys/bus/iio/devices/*device*`;
do
    if grep -q $DRIVER_NAME $d/name ;
    then
        raw=`cat $d/in_humidityrelative_raw`
        offset=`cat $d/in_humidityrelative_offset`
        scale=`cat $d/in_humidityrelative_scale`

        printf "Value read: raw         %0f\n" $raw
        printf "Value read: offset      %0f\n" $offset
        printf "Value read: scale       %0f\n" $scale

        humidity=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

        echo "Humidity $humidity"
        printf "Humidity %.01f\n" $humidity

        break;
    fi
done
  • Test on board
Board $> ./hts221_read_humidity_on_device2.sh
Value read: raw         2669.000000
Value read: offset      -10661.500000
Value read: scale       -0.003000
Humidity 23.977500000
Humidity 24.0

4.3 LSM6DSL: accelerometer/gyroscope[edit]

The LSM6DSL is an inertial measurement unit (IMU) with ultra-low power and high accuracy, for smartphones and battery operating operated IoT, gaming, wearable and consumer electronics, ultra-low power and high accuracy.

In this example, lsm6dsl entries are /sys/bus/iio/devices/iio:device4/ and /sys/bus/iio/devices/iio:device4/.
Device4 The device4 entry is dedicated to accelerometer and the device5 one to gyroscope.

4.3.1 Accelerometer[edit]

  • Read IIO entries associated to accelerometer for LSM6DSL driver
Board $> cat /sys/bus/iio/devices/iio\:device4/in_accel_x_raw
Board $> cat /sys/bus/iio/devices/iio\:device4/in_accel_x_scale
Board $> cat /sys/bus/iio/devices/iio\:device4/in_accel_y_raw
Board $> cat /sys/bus/iio/devices/iio\:device4/in_accel_y_scale
Board $> cat /sys/bus/iio/devices/iio\:device4/in_accel_z_raw
Board $> cat /sys/bus/iio/devices/iio\:device4/in_accel_z_scale
  • Calculate accelerometer values according following formula
X = Raw value * scale value * (256.0 / 9.81)
Y = Raw value * scale value * (256.0 / 9.81)
Z = Raw value * scale value * (256.0 / 9.81)
  • Calculate accelerometer value by shell script: static IIO entries

Content of lsm6dsl_accel_read_on_device4.sh:

#!/bin/sh
xraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_x_raw`
xscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_x_scale`

yraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_y_raw`
yscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_y_scale`

zraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_z_raw`
zscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_z_scale`

printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

factor=`echo "scale=2;256.0 / 9.81" | bc`
xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

printf "Accelerometer value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
  • Calculate accelerometer value by shell script: auto detection of IIO entries

Content of lsm6dsl_accel_read_with_entry_detection.sh:

#!/bin/sh
DRIVER_NAME=lsm6dsl_accel       
for d in `ls -d1 /sys/bus/iio/devices/*device*`;
do
    if grep -q $DRIVER_NAME $d/name ;
    then
        xraw=`cat $d/in_accel_x_raw`
        xscale=`cat $d/in_accel_x_scale`

        yraw=`cat $d/in_accel_y_raw`
        yscale=`cat $d/in_accel_y_scale`

        zraw=`cat $d/in_accel_z_raw`
        zscale=`cat $d/in_accel_z_scale`

        printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
        printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
        printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

        factor=`echo "scale=2;256.0 / 9.81" | bc`
        xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
        yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
        zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

        printf "Accelerometer value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
 
        break;
    fi
done
  • Test on board
Board $> ./lsm6dsl_accel_read_on_device4.sh
Value read: X (raw/scale)  104 / 0.000598 
Value read: Y (raw/scale)  -16378 / 0.000598 
Value read: Z (raw/scale)  -1117 / 0.000598 
Accelerometer value: [ 1.62, -255.53, -17.43 ]

4.3.2 Gyroscope[edit]

  • Read IIO entries associated to gyroscope for LSM6DSL driver
Board $> cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_raw
Board $> cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_scale
Board $> cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_raw
Board $> cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_scale
Board $> cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_raw
Board $> cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_scale
  • Calculate gyroscope values according following formula
X = Raw value * scale value * (256.0 / 9.81)
Y = Raw value * scale value * (256.0 / 9.81)
Z = Raw value * scale value * (256.0 / 9.81)
  • Calculate gyroscope value by shell script: static IIO entries

Content of lsm6dsl_gyro_read_on_device5.sh:

#!/bin/sh
xraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_raw`
xscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_scale`

yraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_raw`
yscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_scale`

zraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_raw`
zscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_scale`

printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

factor=`echo "scale=2;256.0 / 9.81" | bc`
xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

printf "Gyroscope value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
  • Calculate gyroscope value by shell script: auto detection of IIO entries

Content of lsm6dsl_gyro_read_with_entry_detection.sh:

#!/bin/sh
DRIVER_NAME=lsm6dsl_gyro       
for d in `ls -d1 /sys/bus/iio/devices/*device*`;
do
    if grep -q $DRIVER_NAME $d/name ;
    then
        xraw=`cat $d/in_anglvel_x_raw`
        xscale=`cat $d/in_anglvel_x_scale`

        yraw=`cat $d/in_anglvel_y_raw`
        yscale=`cat $d/in_anglvel_y_scale`

        zraw=`cat $d/in_anglvel_z_raw`
        zscale=`cat $d/in_anglvel_z_scale`

        printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
        printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
        printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

        factor=`echo "scale=2;256.0 / 9.81" | bc`
        xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
        yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
        zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

        printf "Gyroscope value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval

        break;
    fi
done
  • Test on board
Board $> ./lsm6dsl_gyro_read_on_device5.sh
Value read: X (raw/scale)  -2293 / 0.000153 
Value read: Y (raw/scale)  150 / 0.000153 
Value read: Z (raw/scale)  -111 / 0.000153 
Gyroscope value: [ -9.15, 0.60, -0.44 ]

4.4 BASH: script with all the measurements[edit]

  • Content of iks01a2.sh
#!/bin/sh
echo "============================="
echo "===       HTS221          ==="
echo "===    (temperature)      ==="
echo "============================="
raw=`cat /sys/bus/iio/devices/iio\:device2/in_temp_raw`
offset=`cat /sys/bus/iio/devices/iio\:device2/in_temp_offset`
scale=`cat /sys/bus/iio/devices/iio\:device2/in_temp_scale`
printf "Value read: raw      %0f\n" $raw
printf "Value read: offset   %0f\n" $offset
printf "Value read: scale    %0f\n" $scale

temperature=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

echo "Temperature $temperature"
printf "Temperature %.02f\n" $temperature

echo "============================="
echo "===       HTS221          ==="
echo "===    (humidity)         ==="
echo "============================="
raw=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_raw`
offset=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_offset`
scale=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_scale`
printf "Value read: raw         %0f\n" $raw
printf "Value read: offset      %0f\n" $offset
printf "Value read: scale       %0f\n" $scale

humidity=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

echo "Humidity $humidity"
printf "Humidity %.02f\n" $humidity


echo "============================="
echo "===      LSM6DSL          ==="
echo "===    (accelerometer)    ==="
echo "============================="

xraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_x_raw`
xscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_x_scale`

yraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_y_raw`
yscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_y_scale`

zraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_z_raw`
zscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_z_scale`

printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

factor=`echo "scale=2;256.0 / 9.81" | bc`
xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

printf "Accelerometer value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval

echo "============================="
echo "===      LSM6DSL          ==="
echo "===    (gyroscope)        ==="
echo "============================="

xraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_raw`
xscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_scale`

yraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_raw`
yscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_scale`

zraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_raw`
zscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_scale`

printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

factor=`echo "scale=2;256.0 / 9.81" | bc`
xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

printf "Gyroscope value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
  • Content of iks01a2_with_auto_detection.sh
#!/bin/sh

for d in `ls -d1 /sys/bus/iio/devices/*device*`;
do
    # for hts221: Temperature + Humidity
    if grep -q hts221 $d/name ;
    then
        echo "============================="
        echo "===       HTS221          ==="
        echo "===    (temperature)      ==="
        echo "============================="
        raw=`cat $d/in_temp_raw`
        offset=`cat $d/in_temp_offset`
        scale=`cat $d/in_temp_scale`

        printf "Value read: raw         %0f\n" $raw
        printf "Value read: offset      %0f\n" $offset
        printf "Value read: scale       %0f\n" $scale

        temperature=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

        echo "Temperature $temperature"
        printf "Temperature %.02f\n" $temperature

        echo "============================="
        echo "===       HTS221          ==="
        echo "===    (humidity)         ==="
        echo "============================="
        raw=`cat $d/in_humidityrelative_raw`
        offset=`cat $d/in_humidityrelative_offset`
        scale=`cat $d/in_humidityrelative_scale`

        printf "Value read: raw         %0f\n" $raw
        printf "Value read: offset      %0f\n" $offset
        printf "Value read: scale       %0f\n" $scale

        humidity=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

        echo "Humidity $humidity"
        printf "Humidity %.02f\n" $humidity
    fi

    # for lsm6dsl: accelerometer
    if grep -q lsm6dsl_accel $d/name ;
    then
        echo "============================="
        echo "===      LSM6DSL          ==="
        echo "===    (accelerometer)    ==="
        echo "============================="
        xraw=`cat $d/in_accel_x_raw`
        xscale=`cat $d/in_accel_x_scale`

        yraw=`cat $d/in_accel_y_raw`
        yscale=`cat $d/in_accel_y_scale`

        zraw=`cat $d/in_accel_z_raw`
        zscale=`cat $d/in_accel_z_scale`

        printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
        printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
        printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

        factor=`echo "scale=2;256.0 / 9.81" | bc`
        xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
        yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
        zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

        printf "Accelerometer value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
    fi

    # for lsm6dsl: gyroscope
    if grep -q lsm6dsl_gyro $d/name ;
    then
        echo "============================="
        echo "===      LSM6DSL          ==="
        echo "===    (gyroscope)        ==="
        echo "============================="
        xraw=`cat $d/in_anglvel_x_raw`
        xscale=`cat $d/in_anglvel_x_scale`

        yraw=`cat $d/in_anglvel_y_raw`
        yscale=`cat $d/in_anglvel_y_scale`

        zraw=`cat $d/in_anglvel_z_raw`
        zscale=`cat $d/in_anglvel_z_scale`

        printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
        printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
        printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

        factor=`echo "scale=2;256.0 / 9.81" | bc`
        xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
        yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
        zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

        printf "Gyroscope value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
    fi
done

5 Read motion MEMS via Python script[edit]

The goal of this section isto is to read the informations provided by Linux kernel interface and process it on with a python script.
The python will display displays the calculated value calculated on a window UIthrough a graphic user interface.

5.1 Display a window with Python and weston/wayland[edit]

#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GObject
from gi.repository import Gdk
from gi.repository import GLib
from gi.repository import GdkPixbuf
import cairo

import random
import math
import os
from time import sleep, time

# -------------------------------------------------------------------
# -------------------------------------------------------------------
class MainUIWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Sensor usage")
        #self.set_decorated(False)
        self.maximize()
        self.screen_width = self.get_screen().get_width()
        self.screen_height = self.get_screen().get_height()

        self.set_default_size(self.screen_width, self.screen_height)
        print("[DEBUG] screen size: %dx%d" % (self.screen_width, self.screen_height))
        self.set_position(Gtk.WindowPosition.CENTER)
        self.connect('destroy', Gtk.main_quit)

    def destroy(self, widget, data=None):
        Gtk.main_quit()

# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Main
if __name__ == "__main__":
    # add signal to catch CRTL+C
    import signal
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    win = MainUIWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()

    Gtk.main()

5.2 Read temperature[edit]

Part of code for reading temperature with HTS221 driver:

def found_iio_device_with_name(data, name):
    prefix = "/sys/bus/iio/devices/"
    of_name = 'OF_NAME=' + name
    try:
        for filefolder in os.listdir(prefix):
            with open(prefix + '/' + filefolder + '/uevent') as f:
                for line in f:
                    if line.split('\n')[0] == of_name:
                        ''' return directory which contains "data" '''
                        if os.path.exists(prefix + '/' + filefolder + '/' + data):
                            return (prefix + '/' + filefolder + '/')
    except OSError:
        pass
    except Exception as exc:
        pass
    return None

prefix_path = found_iio_device_with_name("in_temp_raw", "hts221")
try:
    with open(prefix_path + "in_temp_" + 'raw', 'r') as f:
        raw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_temp_" + 'raw', exc)
    raw = 0.0

try:
    with open(prefix_path + "in_temp_" + 'scale', 'r') as f:
        scale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_temp_" + 'scale', exc)
    scale = 0.0

try:
    with open(prefix_path + "in_temp_" + 'offset', 'r') as f:
        offset = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_temp_" + 'offset', exc)
    offset = 0.0

temp = (offset + raw) * scale


5.3 Read humidity[edit]

Part of code for reading humidity with HTS221 driver:

def found_iio_device_with_name(data, name):
    prefix = "/sys/bus/iio/devices/"
    of_name = 'OF_NAME=' + name
    try:
        for filefolder in os.listdir(prefix):
            with open(prefix + '/' + filefolder + '/uevent') as f:
                for line in f:
                    if line.split('\n')[0] == of_name:
                        ''' return directory which contains "data" '''
                        if os.path.exists(prefix + '/' + filefolder + '/' + data):
                            return (prefix + '/' + filefolder + '/')
    except OSError:
        pass
    except Exception as exc:
        pass
    return None

prefix_path = found_iio_device_with_name("in_humidityrelative_raw", "hts221")
try:
    with open(prefix_path + "in_humidityrelative_" + 'raw', 'r') as f:
        raw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'raw', exc)
    raw = 0.0

try:
    with open(prefix_path + "in_humidityrelative_" + 'scale', 'r') as f:
        scale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'scale', exc)
    scale = 0.0

try:
    with open(prefix_path + "in_humidityrelative_" + 'offset', 'r') as f:
        offset = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'offset', exc)
    offset = 0.0

humidity = (offset + raw) * scale

5.4 Read accelerometer[edit]

Part of code for reading accelerometer with LSM6DSL driver:

def found_iio_device_with_name(data, name):
    prefix = "/sys/bus/iio/devices/"
    of_name = 'OF_NAME=' + name
    try:
        for filefolder in os.listdir(prefix):
            with open(prefix + '/' + filefolder + '/uevent') as f:
                for line in f:
                    if line.split('\n')[0] == of_name:
                        ''' return directory which contains "data" '''
                        if os.path.exists(prefix + '/' + filefolder + '/' + data):
                            return (prefix + '/' + filefolder + '/')
    except OSError:
        pass
    except Exception as exc:
        pass
    return None

prefix_path = found_iio_device_with_name("in_accel_x_raw", "lsm6dsl")
try:
    with open(prefix_path + "in_accel_" + 'x_raw', 'r') as f:
        xraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'x_raw', exc)
    xraw = 0.0

try:
    with open(prefix_path + "in_accel_" + 'x_scale', 'r') as f:
        xscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'x_scale', exc)
    xscale = 0.0
accel_x = int(xraw * xscale * 256.0 / 9.81)

try:
    with open(prefix_path + "in_accel_" + 'y_raw', 'r') as f:
        yraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'y_raw', exc)
    yraw = 0.0

try:
    with open(prefix_path + "in_accel_" + 'y_scale', 'r') as f:
        yscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'y_scale', exc)
    yscale = 0.0
accel_y = int(yraw * yscale * 256.0 / 9.81)

try:
    with open(prefix_path + "in_accel_" + 'z_raw', 'r') as f:
        zraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'z_raw', exc)
    zraw = 0.0

try:
    with open(prefix_path + "in_accel_" + 'z_scale', 'r') as f:
        zscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'z_scale', exc)
    zscale = 0.0
accel_z = int(zraw * zscale * 256.0 / 9.81)

5.5 Read gyroscope[edit]

Part of code for reading gyroscope with LSM6DSL driver:

def found_iio_device_with_name(data, name):
    prefix = "/sys/bus/iio/devices/"
    of_name = 'OF_NAME=' + name
    try:
        for filefolder in os.listdir(prefix):
            with open(prefix + '/' + filefolder + '/uevent') as f:
                for line in f:
                    if line.split('\n')[0] == of_name:
                        ''' return directory which contains "data" '''
                        if os.path.exists(prefix + '/' + filefolder + '/' + data):
                            return (prefix + '/' + filefolder + '/')
    except OSError:
        pass
    except Exception as exc:
        pass
    return None

prefix_path = found_iio_device_with_name("in_anglvel_x_raw", "lsm6dsl")
try:
    with open(prefix_path + "in_anglvel_" + 'x_raw', 'r') as f:
        xraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'x_raw', exc)
    xraw = 0.0

try:
    with open(prefix_path + "in_anglvel_" + 'x_scale', 'r') as f:
        xscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'x_scale', exc)
    xscale = 0.0
gyro_x = int(xraw * xscale * 256.0 / 9.81)

try:
    with open(prefix_path + "in_anglvel_" + 'y_raw', 'r') as f:
        yraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'y_raw', exc)
    yraw = 0.0

try:
    with open(prefix_path + "in_anglvel_" + 'y_scale', 'r') as f:
        yscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'y_scale', exc)
    yscale = 0.0
gyro_y = int(yraw * yscale * 256.0 / 9.81)

try:
    with open(prefix_path + "in_anglvel_" + 'z_raw', 'r') as f:
        zraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'z_raw', exc)
    zraw = 0.0

try:
    with open(prefix_path + "in_anglvel_" + 'z_scale', 'r') as f:
        zscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'z_scale', exc)
    zscale = 0.0
gyro_z = int(zraw * zscale * 256.0 / 9.81)

5.6 Full script with information displayed on in a windowsgraphic user interface[edit]

#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GObject
from gi.repository import Gdk
from gi.repository import GLib
from gi.repository import GdkPixbuf
import cairo

import random
import math
import os
from time import sleep, time

# time between each sensor mesearuement (1s)
TIME_UPATE = 2000


class Sensors():
    def __init__(self):
        ''' '''
        self.sensor_dictionnary = {}

    def found_iio_device_with_name(self, data, name):
        prefix = "/sys/bus/iio/devices/"
        of_name = 'OF_NAME=' + name
        try:
            for filefolder in os.listdir(prefix):
                with open(prefix + '/' + filefolder + '/uevent') as f:
                    for line in f:
                        if line.split('\n')[0] == of_name:
                            ''' return directory which contains "data" '''
                            if os.path.exists(prefix + '/' + filefolder + '/' + data):
                                return (prefix + '/' + filefolder + '/')
        except OSError:
            pass
        except Exception as exc:
            pass
        return None

    def found_all_sensor_path(self):
        self.sensor_dictionnary['temperature'] = self.found_iio_device_with_name("in_temp_raw", "hts221")
        self.sensor_dictionnary['humidity']    = self.found_iio_device_with_name("in_humidityrelative_raw", "hts221")
        self.sensor_dictionnary['accelerometer'] = self.found_iio_device_with_name("in_accel_x_raw", "lsm6dsl")
        self.sensor_dictionnary['gyroscope'] = self.found_iio_device_with_name("in_anglvel_x_raw", "lsm6dsl")

        print("[DEBUG] temperature   -> ", self.sensor_dictionnary['temperature'], "<")
        print("[DEBUG] humidity      -> ", self.sensor_dictionnary['humidity'], "<")
        print("[DEBUG] accelerometer -> ", self.sensor_dictionnary['accelerometer'], "<")
        print("[DEBUG] gyroscope     -> ", self.sensor_dictionnary['gyroscope'], "<")

    def temperature_read(self):
        prefix_path = self.sensor_dictionnary['temperature']
        try:
            with open(prefix_path + "in_temp_" + 'raw', 'r') as f:
                raw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_temp_" + 'raw', exc)
            raw = 0.0
        try:
            with open(prefix_path + "in_temp_" + 'scale', 'r') as f:
                scale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_temp_" + 'scale', exc)
            scale = 0.0
        try:
            with open(prefix_path + "in_temp_" + 'offset', 'r') as f:
                offset = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_temp_" + 'offset', exc)
            offset = 0.0
        return (offset + raw) * scale

    def humidity_read(self):
        prefix_path = self.sensor_dictionnary['humidity']
        try:
            with open(prefix_path + "in_humidityrelative_" + 'raw', 'r') as f:
                raw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'raw', exc)
            raw = 0.0
        try:
            with open(prefix_path + "in_humidityrelative_" + 'scale', 'r') as f:
                scale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'scale', exc)
            scale = 0.0
        try:
            with open(prefix_path + "in_humidityrelative_" + 'offset', 'r') as f:
                offset = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'offset', exc)
            offset = 0.0
        return (offset + raw) * scale

    def accelerometer_read(self):
        prefix_path = self.sensor_dictionnary['accelerometer']
        try:
            with open(prefix_path + "in_accel_" + 'x_raw', 'r') as f:
                xraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'x_raw', exc)
            xraw = 0.0
        try:
            with open(prefix_path + "in_accel_" + 'x_scale', 'r') as f:
                xscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'x_scale', exc)
            xscale = 0.0
        accel_x = int(xraw * xscale * 256.0 / 9.81)
        try:
            with open(prefix_path + "in_accel_" + 'y_raw', 'r') as f:
                yraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'y_raw', exc)
            yraw = 0.0
        try:
            with open(prefix_path + "in_accel_" + 'y_scale', 'r') as f:
                yscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'y_scale', exc)
            yscale = 0.0
        accel_y = int(yraw * yscale * 256.0 / 9.81)
        try:
            with open(prefix_path + "in_accel_" + 'z_raw', 'r') as f:
                zraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'z_raw', exc)
            zraw = 0.0
        try:
            with open(prefix_path + "in_accel_" + 'z_scale', 'r') as f:
                zscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'z_scale', exc)
            zscale = 0.0
        accel_z = int(zraw * zscale * 256.0 / 9.81)
        return [ accel_x, accel_y, accel_z]

    def gyroscope_read(self):
        prefix_path = self.sensor_dictionnary['gyroscope']
        try:
            with open(prefix_path + "in_anglvel_" + 'x_raw', 'r') as f:
                xraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'x_raw', exc)
            xraw = 0.0
        try:
            with open(prefix_path + "in_anglvel_" + 'x_scale', 'r') as f:
                xscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'x_scale', exc)
            xscale = 0.0
        gyro_x = int(xraw * xscale * 256.0 / 9.81)
        try:
            with open(prefix_path + "in_anglvel_" + 'y_raw', 'r') as f:
                yraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'y_raw', exc)
            yraw = 0.0
        try:
            with open(prefix_path + "in_anglvel_" + 'y_scale', 'r') as f:
                yscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'y_scale', exc)
            yscale = 0.0
        gyro_y = int(yraw * yscale * 256.0 / 9.81)
        try:
            with open(prefix_path + "in_anglvel_" + 'z_raw', 'r') as f:
                zraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'z_raw', exc)
            zraw = 0.0
        try:
            with open(prefix_path + "in_anglvel_" + 'z_scale', 'r') as f:
                zscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'z_scale', exc)
            zscale = 0.0
        gyro_z = int(zraw * zscale * 256.0 / 9.81)
        return [ gyro_x, gyro_y, gyro_z]

# -------------------------------------------------------------------
# -------------------------------------------------------------------
class MainUIWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Sensor usage")
        #self.set_decorated(False)
        self.maximize()
        self.screen_width = self.get_screen().get_width()
        self.screen_height = self.get_screen().get_height()

        self.set_default_size(self.screen_width, self.screen_height)
        print("[DEBUG] screen size: %dx%d" % (self.screen_width, self.screen_height))
        self.set_position(Gtk.WindowPosition.CENTER)
        self.connect('destroy', Gtk.main_quit)

        # search sensor interface
        self.sensors = Sensors()
        self.sensors.found_all_sensor_path()

        sensor_box = Gtk.VBox(spacing=0)

        # temperature
        temp_label = Gtk.Label()
        temp_label.set_markup("<span font_desc='LiberationSans 25'>Temperature</span>")
        self.temp_value_label = Gtk.Label()
        self.temp_value_label.set_markup("<span font_desc='LiberationSans 25'>--.-- °C</span>")
        temp_box = Gtk.HBox(False, 0)
        temp_box.add(temp_label)
        temp_box.add(self.temp_value_label)
        sensor_box.add(temp_box)

        # humidity
        humidity_label = Gtk.Label()
        humidity_label.set_markup("<span font_desc='LiberationSans 25'>Humidity</span>")
        self.humidity_value_label = Gtk.Label()
        self.humidity_value_label.set_markup("<span font_desc='LiberationSans 25'>--.-- %c</span>" % '%')
        humidity_box = Gtk.HBox(False, 0)
        humidity_box.add(humidity_label)
        humidity_box.add(self.humidity_value_label)
        sensor_box.add(humidity_box)

        # Accel
        accel_label = Gtk.Label()
        accel_label.set_markup("<span font_desc='LiberationSans 25'>Accelerometer</span>")
        self.accel_value_label = Gtk.Label()
        self.accel_value_label.set_markup("<span font_desc='LiberationSans 25'> [ --.--, --.--, --.--]</span>")
        accel_box = Gtk.HBox(False, 0)
        accel_box.add(accel_label)
        accel_box.add(self.accel_value_label)
        sensor_box.add(accel_box)

        # Gyroscope
        gyro_label = Gtk.Label()
        gyro_label.set_markup("<span font_desc='LiberationSans 25'>Gyroscope</span>")
        self.gyro_value_label = Gtk.Label()
        self.gyro_value_label.set_markup("<span font_desc='LiberationSans 25'> [ --.--, --.--, --.--]</span>")
        gyro_box = Gtk.HBox(False, 0)
        gyro_box.add(gyro_label)
        gyro_box.add(self.gyro_value_label)
        sensor_box.add(gyro_box)

        self.add(sensor_box)

        # Add a timer callback to update
        # this takes 2 args: (how often to update in millisec, the method to run)
        self.timer = GObject.timeout_add(TIME_UPATE, self.update_ui, None)
        self.timer_enable = True


    def destroy(self, widget, data=None):
        Gtk.main_quit()


    def update_ui(self, user_data):
        if False == self.timer_enable:
            return False;
        # temperature
        temp = self.sensors.temperature_read()
        self.temp_value_label.set_markup("<span font_desc='LiberationSans 25'>%.02f °C</span>" % temp)
        # humidity
        hum = self.sensors.humidity_read()
        self.humidity_value_label.set_markup("<span font_desc='LiberationSans 25'>%.02f %c</span>" % (hum, '%'))
        # accel
        accel = self.sensors.accelerometer_read()
        self.accel_value_label.set_markup("<span font_desc='LiberationSans 25'>[ %.02f, %.02f, %.02f]</span>" % (accel[0], accel[1], accel[2]))
        # gyro
        gyro = self.sensors.gyroscope_read()
        self.gyro_value_label.set_markup("<span font_desc='LiberationSans 25'>[ %.02f, %.02f, %.02f]</span>" % (gyro[0], gyro[1], gyro[2]))

        # As this is a timeout function, return True so that it
        # continues to get called
        return True


# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Main
if __name__ == "__main__":
    # add signal to catch CRTL+C
    import signal
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    win = MainUIWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()

    Gtk.main()
  • Screenshot showing the results in the graphic user interface
Result of Python script
Result of Python script

5.7 Example of screenshot for displaying information More screenshot examples with results displayed in a graphic user interface[edit]

Example of interpreted IMU data
Example of interpreted IMU data


Example of raw IMU data
Example of raw IMU data


Example of sensors data presentation
Example of sensors data presentation


6 References[edit]

  1. IKS01A2 User Manual [1]
  2. 2.02.1 IKS01A2 Schematics [2]
  3. 3.03.1 STM32MP157C-DK2 Schematics [3]


{{ReviewsComments|CPR :<br/> section 4.3 change the style of extlinux.conf content to highlight some part <br/> To be done when SyntaxHighlight extension will be fully functional}}
==Article purpose==
The purpose of this article is to explain how to integrate the IKS01A2 expansion board with STM32MP157C-DK2, managed by '''Linux on Cortex-A7'''.<br>

The IKS01A2 board is an expansion board composed bythat includes several motion MEMS like HTS221 and LSM6DSL.

This article explainsprovides step -by step:
* how to -step instructions to:
* configure Linux software to support IKS01A2 expansion board,
* how to activate/use several motion MEMS such as HTS221 and LSM6DSL.

==Prerequisites==

===Hardware prerequisites===
* STM32MP157C-DK2
 [[File: STM32MP157C-DK2_angle2.jpg|thumb|upright=2|center|link=|STM32MP157C-DK2]]

For more information about thisthe STM32 discovery board and how to start with itit up, jump to this section [[Getting_started/STM32MP1_boards/STM32MP157C-DK2]]

* IKS01A2 expansion board
[[File:en.x-nucleo-iks01a2_image.jpg|thumb|center|upright=2|alt=IKS01A2|IKS01A2 expansion board]]

===Software prerequisites===
The STM32MP157C-DK2 board must be populateddownloaded with appropriate software to be able to customize it to in order to support IKS01A2 expansion board. To know how to proceed please For proceeding, follow the step-by-step description starting withinstructions provided at [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Let%27s_start|STM32MP157C-DK2 Let's start]] article.

==Software customization to support  IKS01A2 expansion board ==The STM32MP157C-DK2 Linux software must be configured to activate the IKS01A2 board connected on top of the STM32MP157C-DK2 board.<br>

Configuration is done byThe configuration consists in modifying the STM32MP157C-DK2 Linux kernel and by managing some new device tree elements.

===Kernel configuration===
By default, the motion MEMS drivers, present on IKS01A2 expansion board, are enabled in STM32MP1 kernel configuration: hts221, pressure(lp22hb) and lsm6dsl.  The device tree must be updated to declare and activate them. 

To check whether associated drivers are enabled inside the kernel, follow type the commands given provided here below :

 {{Board$}}  cat /proc/config.gz | gunzip | grep HTS221
 CONFIG_HTS221=y
 CONFIG_HTS221_I2C=y
 CONFIG_HTS221_SPI=y

 {{Board$}}  cat /proc/config.gz | gunzip | grep ST_PRESS
 CONFIG_IIO_ST_PRESS=m
 CONFIG_IIO_ST_PRESS_I2C=m
 CONFIG_IIO_ST_PRESS_SPI=m

 {{Board$}}  cat /proc/config.gz | gunzip |  grep ST_LSM6DS
 CONFIG_IIO_ST_LSM6DSX=m
 CONFIG_IIO_ST_LSM6DSX_I2C=m
 CONFIG_IIO_ST_LSM6DSX_SPI=m

{{Info|If those the above configurations are not enabled on your kernel configuration, please , follow the indications given in [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Develop_on_Arm®_Cortex®-A7/Modify,_rebuild_and_reload_the_Linux®_kernel|Modify, rebuild and reload the Linux® kernel]] }}

===Kernel device tree configuration===

====Hardware / software interface====Motion MEMS The HTS221 and LSM6DSL,  motion MEMS present on IKS01A2 expansion board are usedinvolved in the following use case explained in this article.<br>

According to IKS01A2 user manual<ref  name="User Manual of IKS01A2"> IKS01A2 User Manual [https://www.st.com/resource/en/user_manual/dm00333132.pdf]</ref>, both motion MEMS are controlled by I2C bus.

In I{{sup|2}}C bus.

In the schematics of IKS01A2 <ref name="Schematics of IKS01A2"> IKS01A2 Schematics  [https://www.st.com/resource/en/schematic_pack/x-nucleo-iks01a2_schematic.pdf]</ref> and STM32MP157C-DK2<ref  name="Schematics of STM32MP157C-DK2">STM32MP157C-DK2 Schematics  [https://www.st.com/resource/en/schematic_pack/mb1272-dk2-c01_schematic.pdf]</ref> , presented below, are identified the pins which that interconnected are connected togetherhighlighted.

* IKS01A2 schematic (Arduino connector) <ref name="Schematics of IKS01A2"/>

** Pins 10 and 9 of CN5 are used for I2CI{{sup|2}}C Bus (SDA and SCL) (I2C1 and I2C2 bus instances are mixed via the jumper JP7 and JP8 jumpers)
** Pins 6 and 5 of CN9 are used to manage interruptions on LSM6DSL motion MEMS (indicated for information: not used on kernel configuration).

[[File:Arduino_IKS01A2_schematic.png|thumb|center|800px|alt=Screenshot iks01a2|IKS01A2 schematics extract]]

*STM32MP157C-DK2 schematic (Arduino connector) <ref  name="Schematics of STM32MP157C-DK2"/> 

** Pins 10 and 9 of CN5 are used for I2CI{{sup|2}}C Bus (I2C5_SDA and I2C5_SCL)
** Pins 6 and 5 of CN14 are used to manage interruptions on LSM6DSL motion MEMS (indicated for information: not used on kernel configuration)

[[File:Arduino_stm32mp157c-dk2_schematic.png|thumb|center|800px|alt=Screenshot stm32mp157c-dk2|stm32mp157c-dk2 schematics extract]]

{{Warning|I2C5''' bus instance MUST be enabled onby software in order to access tothe motion MEMS present on IKS01A2}}

====Kernel device tree configuration====
As seenindicated in previous chapter, section, the IKS01A2 expansion board is controlled via IC2I{{sup|2}}C bus. On STM32MP157C-DK2, the associated I2CI{{sup|2}}C bus is '''I2C5'''.
The I2C5 bus must be activated into STM32MP157C-DK2 device tree and a node for each hardware to support must be added  (see entry on device tree like '''hts221''', below, on the following device tree contententries like '''hts221''', as shown in the device tree content example below).

For that, add following content into '''stm32mp157c-dk2.dts''' file:<pre style="overflow-y: visible; max-height: none;">

 &i2c5 {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&i2c5_pins_a>;
	pinctrl-1 = <&i2c5_pins_sleep_a>;
	i2c-scl-rising-time-ns = <124>;
	i2c-scl-falling-time-ns = <3>;
	/delete-property/dmas;
	/delete-property/dma-names;

	status = "okay";

	hts221@5f {
		compatible = "st,hts221";
		reg = <0x5f>;
	};
	lsm6dsl@6b {
		compatible = "st,lsm6dsl";
		reg = <0x6b>;
	};
 };</pre>

{{Info|To generate a new device tree, please follow the indications given in [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Develop_on_Arm®_Cortex®-A7/Modify,_rebuild_and_reload_the_Linux®_kernel|Modify, rebuild and reload the Linux® kernel]] }}

===Activate the new configuration in the STM32MP157C-DK2 board===

* '''Prerequisites''': Device The device tree and the Linux kernel must have been regenerated. If not already done, please done yet, follow the indications given in [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Develop_on_Arm®_Cortex®-A7/Modify,_rebuild_and_reload_the_Linux®_kernel|Modify, rebuild and reload the Linux® kernel]] 

* Add the two generated files on file system of board, more accurately in in the board file system, precisely in the bootfs partition (/boot directory)
 {{Board$}} ls -1 /boot/stm32*dk2*

 /boot/stm32mp157c-dk2-a7-examples.dtb
 /boot/stm32mp157c-dk2-iks01a2.dtb
 /boot/stm32mp157c-dk2-m4-examples.dtb
 /boot/stm32mp157c-dk2.dtb

* Add a new entry in extlinux.conf file, here  located in '''/boot/mmc0_stm32mp157c-dk2_extlinux/'''. If no directory the mmc0_<something> directory is not available, add the new entry in '''/boot/extlinux/extlinux.conf'''.
<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true; highlight: [5,18,19,20,21];"> 

 # Generic Distro Configuration file generated by OpenEmbedded
 menu title Select the boot mode
 MENU BACKGROUND ../splash.bmp
 TIMEOUT 20
 DEFAULT stm32mp157c-dk2-iks01a2
 LABEL stm32mp157c-dk2-sdcard
         KERNEL /uImage
         FDT /stm32mp157c-dk2.dtb
         APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
 LABEL stm32mp157c-dk2-a7-examples-sdcard
         KERNEL /uImage
         FDT /stm32mp157c-dk2-a7-examples.dtb
         APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
 LABEL stm32mp157c-dk2-m4-examples-sdcard
         KERNEL /uImage
         FDT /stm32mp157c-dk2-m4-examples.dtb
         APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
 LABEL stm32mp157c-dk2-iks01a2
        KERNEL /uImage
        FDT /stm32mp157c-dk2-iks01a2.dtb
        APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200</pre>


{{Warning| Do not forget to synchronize the file system before rebooting the board <br/> {{Board$}} sync }}

* Reboot the board

===Verify the new configuration on board===
* Verify if '''i2c5''' is enabled:
 {{Board$}}  cat /proc/device-tree/soc/i2c\@40015000/status 
 okay
* Verify if the motion MEMS drivers are declared on in the device tree node:

 {{Board$}} ls -l /proc/device-tree/soc/i2c\@40015000/<pre style="overflow-y: visible; max-height: none;">total 0
-r--r--r-- 1 root root  4 Dec 19 11:01 #address-cells
-r--r--r-- 1 root root  4 Dec 19 11:01 #size-cells
-r--r--r-- 1 root root  8 Dec 19 11:01 clocks
-r--r--r-- 1 root root 15 Dec 19 11:01 compatible
-r--r--r-- 1 root root  6 Dec 19 11:01 dma-names
-r--r--r-- 1 root root 32 Dec 19 11:01 dmas
drwxr-xr-x 2 root root  0 Dec 19 10:54 hts221@5f
-r--r--r-- 1 root root  4 Dec 19 11:01 i2c-scl-falling-time-ns
-r--r--r-- 1 root root  4 Dec 19 11:01 i2c-scl-rising-time-ns
-r--r--r-- 1 root root 19 Dec 19 11:01 interrupt-names
-r--r--r-- 1 root root 44 Dec 19 11:01 interrupts-extended
drwxr-xr-x 2 root root  0 Dec 19 10:54 lsm6dsl@6b
-r--r--r-- 1 root root  4 Dec 19 11:01 name
-r--r--r-- 1 root root  4 Dec 19 11:01 pinctrl-0
-r--r--r-- 1 root root  4 Dec 19 11:01 pinctrl-1
-r--r--r-- 1 root root 14 Dec 19 11:01 pinctrl-names
-r--r--r-- 1 root root  4 Dec 19 11:01 power-domains
-r--r--r-- 1 root root  8 Dec 19 11:01 reg
-r--r--r-- 1 root root  8 Dec 19 11:01 resets
-r--r--r-- 1 root root 12 Dec 19 11:01 st,syscfg-fmp
-r--r--r-- 1 root root  5 Dec 19 11:01 status</pre>


* Verify if the motion MEMS drivers are correctly probed and if the system provides access to the associated hardware:

 {{Board$}}  grep OF_NAME /sys/bus/iio/devices/iio\:device*/uevent
 /sys/bus/iio/devices/iio:device0/uevent:OF_NAME=adc
 /sys/bus/iio/devices/iio:device1/uevent:OF_NAME=adc
 /sys/bus/iio/devices/iio:device2/uevent:OF_NAME=hts221
 /sys/bus/iio/devices/iio:device3/uevent:OF_NAME=temp
 /sys/bus/iio/devices/iio:device4/uevent:OF_NAME=lsm6dsl
 /sys/bus/iio/devices/iio:device5/uevent:OF_NAME=lsm6dsl

{{Info|If the results are different then , check that
# the expansion board is correctly connected 
# all steps, described above, were correctly done.}}

==Read motion MEMS via bash script==
The goal of this section areis to read the informations provided by Linux kernel interface and to process it onwith a bash script.

=== List of sensors entry ===The IKS01A2 expansion board provides several MEMS like HTS221, LSM6DSL, LPS22HB.<br>
Hardware MEMS,The list of hardware MEMS detected by Linux via the [[IIO overview|IIO framework]], can be listed by verifying the entries on verified in the sysfs.

 {{Board$}}   grep OF_NAME /sys/bus/iio/devices/iio\:device*/uevent
 /sys/bus/iio/devices/iio:device0/uevent:OF_NAME=adc
 /sys/bus/iio/devices/iio:device1/uevent:OF_NAME=adc
 /sys/bus/iio/devices/iio:device2/uevent:OF_NAME=hts221
 /sys/bus/iio/devices/iio:device3/uevent:OF_NAME=temp
 /sys/bus/iio/devices/iio:device4/uevent:OF_NAME=lsm6dsl
 /sys/bus/iio/devices/iio:device5/uevent:OF_NAME=lsm6dsl

This list of entries permits to know which entries are associated to a MEMS driverprovides the association between entries and MEMS drivers. In the rest of the article,  this list is kept used a as reference list of entries.

===HTS221: Temperature/Humidity===The HTS221 is a capacitive digital sensor for relative humidity and temperature. 

In this example, '''hts221''' entries areentry is '''/sys/bus/iio/devices/iio:device2/''', please adapt to your setup if it's not the case by changing the entry on the scripts described/explained in following chapters. In case the user as a different setup the entry should be adapted accordingly in the scripts provided here after.

====Temperature====
* Read IIO entries associated to the temperature for '''HTS221''' driver

 {{Board$}}  cat /sys/bus/iio/devices/iio\:device2/in_temp_raw
 {{Board$}}  cat /sys/bus/iio/devices/iio\:device2/in_temp_offset
 {{Board$}}  cat /sys/bus/iio/devices/iio\:device2/in_temp_scale

* Calculate real temperature according following formula 
 '''Temperature''' = ( '''Raw''' value + '''Offset''' value) * '''Scale''' value)

* Calculate temperature by shell script : '''static''' IIO entries
Content of '''hts221_read_temperature_on_device2.sh''':<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/bin/sh
raw=`cat /sys/bus/iio/devices/iio\:device2/in_temp_raw`
offset=`cat /sys/bus/iio/devices/iio\:device2/in_temp_offset`
scale=`cat /sys/bus/iio/devices/iio\:device2/in_temp_scale`
printf "Value read: raw         %0f\n" $raw
printf "Value read: offset      %0f\n" $offset
printf "Value read: scale       %0f\n" $scale

temperature=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

echo "Temperature $temperature"
printf "Temperature %.01f\n" $temperature</pre>
<br/>


* Calculate temperature by shell script: '''auto detection''' of IIO entries
Content of '''hts221_read_temperature_with_entry_detection.sh''':<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/bin/sh
DRIVER_NAME=hts221
for d in `ls -d1 /sys/bus/iio/devices/*device*`;
do
    if grep -q $DRIVER_NAME $d/name ;
    then
        raw=`cat $d/in_temp_raw`
        offset=`cat $d/in_temp_offset`
        scale=`cat $d/in_temp_scale`

        printf "Value read: raw         %0f\n" $raw
        printf "Value read: offset      %0f\n" $offset
        printf "Value read: scale       %0f\n" $scale

        temperature=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

        echo "Temperature $temperature"
        printf "Temperature %.01f\n" $temperature

        break;
    fi
done</pre>


* Test on board
 {{Board$}}  ./hts221_read_temperature_on_device2.sh
 Value read: raw         563.000000
 Value read: offset      1036.674817
 Value read: scale       0.019172
 Temperature 30.668765624
 Temperature 30.7

====Humidity====
* Read IIO entries associated to humidity for HTS221 driver
 {{Board$}} cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_raw
 {{Board$}} cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_offset
 {{Board$}} cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_scale

* Calculate real humidity according following formula 
 '''Humidity''' = ( '''Raw''' value + '''Offset''' value) * '''Scale''' value)

* Calculate humidity  by shell script: '''static''' IIO entries
Content of '''hts221_read_humidity_on_device2.sh''':<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/bin/sh
raw=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_raw`
offset=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_offset`
scale=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_scale`
printf "Value read: raw         %0f\n" $raw
printf "Value read: offset      %0f\n" $offset
printf "Value read: scale       %0f\n" $scale

humidity=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

echo "Humidity $humidity"
printf "Humidity %.01f\n" $humidity</pre>



* Calculate humidity  by shell script: '''auto detection''' of IIO entries
Content of '''hts221_read_humidity_with_entry_detection.sh''':<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/bin/sh
DRIVER_NAME=hts221
for d in `ls -d1 /sys/bus/iio/devices/*device*`;
do
    if grep -q $DRIVER_NAME $d/name ;
    then
        raw=`cat $d/in_humidityrelative_raw`
        offset=`cat $d/in_humidityrelative_offset`
        scale=`cat $d/in_humidityrelative_scale`

        printf "Value read: raw         %0f\n" $raw
        printf "Value read: offset      %0f\n" $offset
        printf "Value read: scale       %0f\n" $scale

        humidity=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

        echo "Humidity $humidity"
        printf "Humidity %.01f\n" $humidity

        break;
    fi
done</pre>


* Test on board
 {{Board$}} ./hts221_read_humidity_on_device2.sh
 Value read: raw         2669.000000
 Value read: offset      -10661.500000
 Value read: scale       -0.003000
 Humidity 23.977500000
 Humidity 24.0

===LSM6DSL: accelerometer/gyroscope===The LSM6DSL is an inertial measurement unit (IMU) with ultra-low power and high accuracy, for smartphones and battery operatingoperated IoT, gaming, wearable and consumer electronics, ultra-low power and high accuracy.<br/>
<br/>

In this example, '''lsm6dsl''' entries are '''/sys/bus/iio/devices/iio:device4/''' and '''/sys/bus/iio/devices/iio:device4/'''.<br/>
Device4 The device4 entry is dedicated to accelerometer and the device5 one to gyroscope.

====Accelerometer====
* Read IIO entries associated to accelerometer for LSM6DSL driver
 {{Board$}} cat /sys/bus/iio/devices/iio\:device4/in_accel_x_raw
 {{Board$}} cat /sys/bus/iio/devices/iio\:device4/in_accel_x_scale
 {{Board$}} cat /sys/bus/iio/devices/iio\:device4/in_accel_y_raw
 {{Board$}} cat /sys/bus/iio/devices/iio\:device4/in_accel_y_scale
 {{Board$}} cat /sys/bus/iio/devices/iio\:device4/in_accel_z_raw
 {{Board$}} cat /sys/bus/iio/devices/iio\:device4/in_accel_z_scale

* Calculate accelerometer values according following formula 
 '''X''' = '''Raw''' value * '''scale''' value * (256.0 / 9.81)
 '''Y''' = '''Raw''' value * '''scale''' value * (256.0 / 9.81)
 '''Z''' = '''Raw''' value * '''scale''' value * (256.0 / 9.81)

* Calculate accelerometer value by shell script: '''static''' IIO entries
Content of '''lsm6dsl_accel_read_on_device4.sh''':<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/bin/sh
xraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_x_raw`
xscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_x_scale`

yraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_y_raw`
yscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_y_scale`

zraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_z_raw`
zscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_z_scale`

printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

factor=`echo "scale=2;256.0 / 9.81" | bc`
xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

printf "Accelerometer value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval</pre>


* Calculate accelerometer value by shell script: '''auto detection''' of IIO entries
Content of '''lsm6dsl_accel_read_with_entry_detection.sh''':<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/bin/sh
DRIVER_NAME=lsm6dsl_accel       
for d in `ls -d1 /sys/bus/iio/devices/*device*`;
do
    if grep -q $DRIVER_NAME $d/name ;
    then
        xraw=`cat $d/in_accel_x_raw`
        xscale=`cat $d/in_accel_x_scale`

        yraw=`cat $d/in_accel_y_raw`
        yscale=`cat $d/in_accel_y_scale`

        zraw=`cat $d/in_accel_z_raw`
        zscale=`cat $d/in_accel_z_scale`

        printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
        printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
        printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

        factor=`echo "scale=2;256.0 / 9.81" | bc`
        xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
        yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
        zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

        printf "Accelerometer value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval

        break;
    fi
done</pre>


* Test on board
 {{Board$}} ./lsm6dsl_accel_read_on_device4.sh
 Value read: X (raw/scale)  104 / 0.000598 
 Value read: Y (raw/scale)  -16378 / 0.000598 
 Value read: Z (raw/scale)  -1117 / 0.000598 
 Accelerometer value: [ 1.62, -255.53, -17.43 ]

====Gyroscope====
* Read IIO entries associated to gyroscope for LSM6DSL driver
 {{Board$}} cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_raw
 {{Board$}} cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_scale
 {{Board$}} cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_raw
 {{Board$}} cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_scale
 {{Board$}} cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_raw
 {{Board$}} cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_scale

* Calculate gyroscope values according following formula 
 '''X''' = '''Raw''' value * '''scale''' value * (256.0 / 9.81)
 '''Y''' = '''Raw''' value * '''scale''' value * (256.0 / 9.81)
 '''Z''' = '''Raw''' value * '''scale''' value * (256.0 / 9.81)

* Calculate gyroscope value by shell script: '''static''' IIO entries
Content of '''lsm6dsl_gyro_read_on_device5.sh''':<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/bin/sh
xraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_raw`
xscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_scale`

yraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_raw`
yscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_scale`

zraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_raw`
zscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_scale`

printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

factor=`echo "scale=2;256.0 / 9.81" | bc`
xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

printf "Gyroscope value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval</pre>

* Calculate gyroscope value by shell script: '''auto detection''' of IIO entries
Content of '''lsm6dsl_gyro_read_with_entry_detection.sh''':<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/bin/sh
DRIVER_NAME=lsm6dsl_gyro       
for d in `ls -d1 /sys/bus/iio/devices/*device*`;
do
    if grep -q $DRIVER_NAME $d/name ;
    then
        xraw=`cat $d/in_anglvel_x_raw`
        xscale=`cat $d/in_anglvel_x_scale`

        yraw=`cat $d/in_anglvel_y_raw`
        yscale=`cat $d/in_anglvel_y_scale`

        zraw=`cat $d/in_anglvel_z_raw`
        zscale=`cat $d/in_anglvel_z_scale`

        printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
        printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
        printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

        factor=`echo "scale=2;256.0 / 9.81" | bc`
        xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
        yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
        zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

        printf "Gyroscope value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval

        break;
    fi
done</pre>


* Test on board
 {{Board$}} ./lsm6dsl_gyro_read_on_device5.sh
 Value read: X (raw/scale)  -2293 / 0.000153 
 Value read: Y (raw/scale)  150 / 0.000153 
 Value read: Z (raw/scale)  -111 / 0.000153 
 Gyroscope value: [ -9.15, 0.60, -0.44 ]

===BASH: script with all the measurements===
* Content of '''iks01a2.sh'''<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/bin/sh
echo "============================="
echo "===       HTS221          ==="
echo "===    (temperature)      ==="
echo "============================="
raw=`cat /sys/bus/iio/devices/iio\:device2/in_temp_raw`
offset=`cat /sys/bus/iio/devices/iio\:device2/in_temp_offset`
scale=`cat /sys/bus/iio/devices/iio\:device2/in_temp_scale`
printf "Value read: raw      %0f\n" $raw
printf "Value read: offset   %0f\n" $offset
printf "Value read: scale    %0f\n" $scale

temperature=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

echo "Temperature $temperature"
printf "Temperature %.02f\n" $temperature

echo "============================="
echo "===       HTS221          ==="
echo "===    (humidity)         ==="
echo "============================="
raw=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_raw`
offset=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_offset`
scale=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_scale`
printf "Value read: raw         %0f\n" $raw
printf "Value read: offset      %0f\n" $offset
printf "Value read: scale       %0f\n" $scale

humidity=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

echo "Humidity $humidity"
printf "Humidity %.02f\n" $humidity

echo "============================="
echo "===      LSM6DSL          ==="
echo "===    (accelerometer)    ==="
echo "============================="

xraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_x_raw`
xscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_x_scale`

yraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_y_raw`
yscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_y_scale`

zraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_z_raw`
zscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_z_scale`

printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

factor=`echo "scale=2;256.0 / 9.81" | bc`
xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

printf "Accelerometer value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval

echo "============================="
echo "===      LSM6DSL          ==="
echo "===    (gyroscope)        ==="
echo "============================="

xraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_raw`
xscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_x_scale`

yraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_raw`
yscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_y_scale`

zraw=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_raw`
zscale=`cat /sys/bus/iio/devices/iio\:device5/in_anglvel_z_scale`

printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

factor=`echo "scale=2;256.0 / 9.81" | bc`
xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

printf "Gyroscope value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval</pre>


* Content of '''iks01a2_with_auto_detection.sh'''<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/bin/sh

for d in `ls -d1 /sys/bus/iio/devices/*device*`;
do
    # for hts221: Temperature + Humidity
    if grep -q hts221 $d/name ;
    then
        echo "============================="
        echo "===       HTS221          ==="
        echo "===    (temperature)      ==="
        echo "============================="
        raw=`cat $d/in_temp_raw`
        offset=`cat $d/in_temp_offset`
        scale=`cat $d/in_temp_scale`

        printf "Value read: raw         %0f\n" $raw
        printf "Value read: offset      %0f\n" $offset
        printf "Value read: scale       %0f\n" $scale

        temperature=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

        echo "Temperature $temperature"
        printf "Temperature %.02f\n" $temperature

        echo "============================="
        echo "===       HTS221          ==="
        echo "===    (humidity)         ==="
        echo "============================="
        raw=`cat $d/in_humidityrelative_raw`
        offset=`cat $d/in_humidityrelative_offset`
        scale=`cat $d/in_humidityrelative_scale`

        printf "Value read: raw         %0f\n" $raw
        printf "Value read: offset      %0f\n" $offset
        printf "Value read: scale       %0f\n" $scale

        humidity=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

        echo "Humidity $humidity"
        printf "Humidity %.02f\n" $humidity
    fi

    # for lsm6dsl: accelerometer
    if grep -q lsm6dsl_accel $d/name ;
    then
        echo "============================="
        echo "===      LSM6DSL          ==="
        echo "===    (accelerometer)    ==="
        echo "============================="
        xraw=`cat $d/in_accel_x_raw`
        xscale=`cat $d/in_accel_x_scale`

        yraw=`cat $d/in_accel_y_raw`
        yscale=`cat $d/in_accel_y_scale`

        zraw=`cat $d/in_accel_z_raw`
        zscale=`cat $d/in_accel_z_scale`

        printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
        printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
        printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

        factor=`echo "scale=2;256.0 / 9.81" | bc`
        xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
        yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
        zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

        printf "Accelerometer value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
    fi

    # for lsm6dsl: gyroscope
    if grep -q lsm6dsl_gyro $d/name ;
    then
        echo "============================="
        echo "===      LSM6DSL          ==="
        echo "===    (gyroscope)        ==="
        echo "============================="
        xraw=`cat $d/in_anglvel_x_raw`
        xscale=`cat $d/in_anglvel_x_scale`

        yraw=`cat $d/in_anglvel_y_raw`
        yscale=`cat $d/in_anglvel_y_scale`

        zraw=`cat $d/in_anglvel_z_raw`
        zscale=`cat $d/in_anglvel_z_scale`

        printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
        printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
        printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

        factor=`echo "scale=2;256.0 / 9.81" | bc`
        xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
        yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
        zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

        printf "Gyroscope value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
    fi
done</pre>


==Read motion MEMS via Python script==

The goal of this section isto is to read the informations provided by Linux kernel interface and process it onwith a python script.<br/>

The python will display displays the calculated value calculated on through a window UIgraphic user interface.

===Display a window with Python and weston/wayland===<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GObject
from gi.repository import Gdk
from gi.repository import GLib
from gi.repository import GdkPixbuf
import cairo

import random
import math
import os
from time import sleep, time

# -------------------------------------------------------------------
# -------------------------------------------------------------------
class MainUIWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Sensor usage")
        #self.set_decorated(False)
        self.maximize()
        self.screen_width = self.get_screen().get_width()
        self.screen_height = self.get_screen().get_height()

        self.set_default_size(self.screen_width, self.screen_height)
        print("[DEBUG] screen size: %dx%d" % (self.screen_width, self.screen_height))
        self.set_position(Gtk.WindowPosition.CENTER)
        self.connect('destroy', Gtk.main_quit)

    def destroy(self, widget, data=None):
        Gtk.main_quit()

# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Main
if __name__ == "__main__":
    # add signal to catch CRTL+C
    import signal
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    win = MainUIWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()

    Gtk.main()</pre>


===Read temperature===
Part of code for reading temperature with HTS221 driver:<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

def found_iio_device_with_name(data, name):
    prefix = "/sys/bus/iio/devices/"
    of_name = 'OF_NAME=' + name
    try:
        for filefolder in os.listdir(prefix):
            with open(prefix + '/' + filefolder + '/uevent') as f:
                for line in f:
                    if line.split('\n')[0] == of_name:
                        ''' return directory which contains "data" '''
                        if os.path.exists(prefix + '/' + filefolder + '/' + data):
                            return (prefix + '/' + filefolder + '/')
    except OSError:
        pass
    except Exception as exc:
        pass
    return None

prefix_path = found_iio_device_with_name("in_temp_raw", "hts221")
try:
    with open(prefix_path + "in_temp_" + 'raw', 'r') as f:
        raw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_temp_" + 'raw', exc)
    raw = 0.0

try:
    with open(prefix_path + "in_temp_" + 'scale', 'r') as f:
        scale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_temp_" + 'scale', exc)
    scale = 0.0

try:
    with open(prefix_path + "in_temp_" + 'offset', 'r') as f:
        offset = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_temp_" + 'offset', exc)
    offset = 0.0

temp = (offset + raw) * scale
</pre>


===Read humidity===
Part of code for reading humidity with HTS221 driver:<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

def found_iio_device_with_name(data, name):
    prefix = "/sys/bus/iio/devices/"
    of_name = 'OF_NAME=' + name
    try:
        for filefolder in os.listdir(prefix):
            with open(prefix + '/' + filefolder + '/uevent') as f:
                for line in f:
                    if line.split('\n')[0] == of_name:
                        ''' return directory which contains "data" '''
                        if os.path.exists(prefix + '/' + filefolder + '/' + data):
                            return (prefix + '/' + filefolder + '/')
    except OSError:
        pass
    except Exception as exc:
        pass
    return None

prefix_path = found_iio_device_with_name("in_humidityrelative_raw", "hts221")
try:
    with open(prefix_path + "in_humidityrelative_" + 'raw', 'r') as f:
        raw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'raw', exc)
    raw = 0.0

try:
    with open(prefix_path + "in_humidityrelative_" + 'scale', 'r') as f:
        scale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'scale', exc)
    scale = 0.0

try:
    with open(prefix_path + "in_humidityrelative_" + 'offset', 'r') as f:
        offset = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'offset', exc)
    offset = 0.0

humidity = (offset + raw) * scale
</pre>


===Read accelerometer===
Part of code for reading accelerometer with LSM6DSL driver:<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

def found_iio_device_with_name(data, name):
    prefix = "/sys/bus/iio/devices/"
    of_name = 'OF_NAME=' + name
    try:
        for filefolder in os.listdir(prefix):
            with open(prefix + '/' + filefolder + '/uevent') as f:
                for line in f:
                    if line.split('\n')[0] == of_name:
                        ''' return directory which contains "data" '''
                        if os.path.exists(prefix + '/' + filefolder + '/' + data):
                            return (prefix + '/' + filefolder + '/')
    except OSError:
        pass
    except Exception as exc:
        pass
    return None

prefix_path = found_iio_device_with_name("in_accel_x_raw", "lsm6dsl")
try:
    with open(prefix_path + "in_accel_" + 'x_raw', 'r') as f:
        xraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'x_raw', exc)
    xraw = 0.0

try:
    with open(prefix_path + "in_accel_" + 'x_scale', 'r') as f:
        xscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'x_scale', exc)
    xscale = 0.0
accel_x = int(xraw * xscale * 256.0 / 9.81)

try:
    with open(prefix_path + "in_accel_" + 'y_raw', 'r') as f:
        yraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'y_raw', exc)
    yraw = 0.0

try:
    with open(prefix_path + "in_accel_" + 'y_scale', 'r') as f:
        yscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'y_scale', exc)
    yscale = 0.0
accel_y = int(yraw * yscale * 256.0 / 9.81)

try:
    with open(prefix_path + "in_accel_" + 'z_raw', 'r') as f:
        zraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'z_raw', exc)
    zraw = 0.0

try:
    with open(prefix_path + "in_accel_" + 'z_scale', 'r') as f:
        zscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_accel_" + 'z_scale', exc)
    zscale = 0.0
accel_z = int(zraw * zscale * 256.0 / 9.81)</pre>


===Read gyroscope===
Part of code for reading gyroscope with LSM6DSL driver:<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

def found_iio_device_with_name(data, name):
    prefix = "/sys/bus/iio/devices/"
    of_name = 'OF_NAME=' + name
    try:
        for filefolder in os.listdir(prefix):
            with open(prefix + '/' + filefolder + '/uevent') as f:
                for line in f:
                    if line.split('\n')[0] == of_name:
                        ''' return directory which contains "data" '''
                        if os.path.exists(prefix + '/' + filefolder + '/' + data):
                            return (prefix + '/' + filefolder + '/')
    except OSError:
        pass
    except Exception as exc:
        pass
    return None

prefix_path = found_iio_device_with_name("in_anglvel_x_raw", "lsm6dsl")
try:
    with open(prefix_path + "in_anglvel_" + 'x_raw', 'r') as f:
        xraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'x_raw', exc)
    xraw = 0.0

try:
    with open(prefix_path + "in_anglvel_" + 'x_scale', 'r') as f:
        xscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'x_scale', exc)
    xscale = 0.0
gyro_x = int(xraw * xscale * 256.0 / 9.81)

try:
    with open(prefix_path + "in_anglvel_" + 'y_raw', 'r') as f:
        yraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'y_raw', exc)
    yraw = 0.0

try:
    with open(prefix_path + "in_anglvel_" + 'y_scale', 'r') as f:
        yscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'y_scale', exc)
    yscale = 0.0
gyro_y = int(yraw * yscale * 256.0 / 9.81)

try:
    with open(prefix_path + "in_anglvel_" + 'z_raw', 'r') as f:
        zraw = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'z_raw', exc)
    zraw = 0.0

try:
    with open(prefix_path + "in_anglvel_" + 'z_scale', 'r') as f:
        zscale = float(f.read())
except Exception as exc:
    print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'z_scale', exc)
    zscale = 0.0
gyro_z = int(zraw * zscale * 256.0 / 9.81)</pre>


===Full script with information displayed onin a windowsgraphic user interface===<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">

#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GObject
from gi.repository import Gdk
from gi.repository import GLib
from gi.repository import GdkPixbuf
import cairo

import random
import math
import os
from time import sleep, time

# time between each sensor mesearuement (1s)
TIME_UPATE = 2000

class Sensors():
    def __init__(self):
        ''' '''
        self.sensor_dictionnary = {}

    def found_iio_device_with_name(self, data, name):
        prefix = "/sys/bus/iio/devices/"
        of_name = 'OF_NAME=' + name
        try:
            for filefolder in os.listdir(prefix):
                with open(prefix + '/' + filefolder + '/uevent') as f:
                    for line in f:
                        if line.split('\n')[0] == of_name:
                            ''' return directory which contains "data" '''
                            if os.path.exists(prefix + '/' + filefolder + '/' + data):
                                return (prefix + '/' + filefolder + '/')
        except OSError:
            pass
        except Exception as exc:
            pass
        return None

    def found_all_sensor_path(self):
        self.sensor_dictionnary['temperature'] = self.found_iio_device_with_name("in_temp_raw", "hts221")
        self.sensor_dictionnary['humidity']    = self.found_iio_device_with_name("in_humidityrelative_raw", "hts221")
        self.sensor_dictionnary['accelerometer'] = self.found_iio_device_with_name("in_accel_x_raw", "lsm6dsl")
        self.sensor_dictionnary['gyroscope'] = self.found_iio_device_with_name("in_anglvel_x_raw", "lsm6dsl")

        print("[DEBUG] temperature   -> ", self.sensor_dictionnary['temperature'], "<")
        print("[DEBUG] humidity      -> ", self.sensor_dictionnary['humidity'], "<")
        print("[DEBUG] accelerometer -> ", self.sensor_dictionnary['accelerometer'], "<")
        print("[DEBUG] gyroscope     -> ", self.sensor_dictionnary['gyroscope'], "<")

    def temperature_read(self):
        prefix_path = self.sensor_dictionnary['temperature']
        try:
            with open(prefix_path + "in_temp_" + 'raw', 'r') as f:
                raw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_temp_" + 'raw', exc)
            raw = 0.0
        try:
            with open(prefix_path + "in_temp_" + 'scale', 'r') as f:
                scale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_temp_" + 'scale', exc)
            scale = 0.0
        try:
            with open(prefix_path + "in_temp_" + 'offset', 'r') as f:
                offset = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_temp_" + 'offset', exc)
            offset = 0.0
        return (offset + raw) * scale

    def humidity_read(self):
        prefix_path = self.sensor_dictionnary['humidity']
        try:
            with open(prefix_path + "in_humidityrelative_" + 'raw', 'r') as f:
                raw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'raw', exc)
            raw = 0.0
        try:
            with open(prefix_path + "in_humidityrelative_" + 'scale', 'r') as f:
                scale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'scale', exc)
            scale = 0.0
        try:
            with open(prefix_path + "in_humidityrelative_" + 'offset', 'r') as f:
                offset = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'offset', exc)
            offset = 0.0
        return (offset + raw) * scale

    def accelerometer_read(self):
        prefix_path = self.sensor_dictionnary['accelerometer']
        try:
            with open(prefix_path + "in_accel_" + 'x_raw', 'r') as f:
                xraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'x_raw', exc)
            xraw = 0.0
        try:
            with open(prefix_path + "in_accel_" + 'x_scale', 'r') as f:
                xscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'x_scale', exc)
            xscale = 0.0
        accel_x = int(xraw * xscale * 256.0 / 9.81)
        try:
            with open(prefix_path + "in_accel_" + 'y_raw', 'r') as f:
                yraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'y_raw', exc)
            yraw = 0.0
        try:
            with open(prefix_path + "in_accel_" + 'y_scale', 'r') as f:
                yscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'y_scale', exc)
            yscale = 0.0
        accel_y = int(yraw * yscale * 256.0 / 9.81)
        try:
            with open(prefix_path + "in_accel_" + 'z_raw', 'r') as f:
                zraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'z_raw', exc)
            zraw = 0.0
        try:
            with open(prefix_path + "in_accel_" + 'z_scale', 'r') as f:
                zscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_accel_" + 'z_scale', exc)
            zscale = 0.0
        accel_z = int(zraw * zscale * 256.0 / 9.81)
        return [ accel_x, accel_y, accel_z]

    def gyroscope_read(self):
        prefix_path = self.sensor_dictionnary['gyroscope']
        try:
            with open(prefix_path + "in_anglvel_" + 'x_raw', 'r') as f:
                xraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'x_raw', exc)
            xraw = 0.0
        try:
            with open(prefix_path + "in_anglvel_" + 'x_scale', 'r') as f:
                xscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'x_scale', exc)
            xscale = 0.0
        gyro_x = int(xraw * xscale * 256.0 / 9.81)
        try:
            with open(prefix_path + "in_anglvel_" + 'y_raw', 'r') as f:
                yraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'y_raw', exc)
            yraw = 0.0
        try:
            with open(prefix_path + "in_anglvel_" + 'y_scale', 'r') as f:
                yscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'y_scale', exc)
            yscale = 0.0
        gyro_y = int(yraw * yscale * 256.0 / 9.81)
        try:
            with open(prefix_path + "in_anglvel_" + 'z_raw', 'r') as f:
                zraw = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'z_raw', exc)
            zraw = 0.0
        try:
            with open(prefix_path + "in_anglvel_" + 'z_scale', 'r') as f:
                zscale = float(f.read())
        except Exception as exc:
            print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'z_scale', exc)
            zscale = 0.0
        gyro_z = int(zraw * zscale * 256.0 / 9.81)
        return [ gyro_x, gyro_y, gyro_z]

# -------------------------------------------------------------------
# -------------------------------------------------------------------
class MainUIWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Sensor usage")
        #self.set_decorated(False)
        self.maximize()
        self.screen_width = self.get_screen().get_width()
        self.screen_height = self.get_screen().get_height()

        self.set_default_size(self.screen_width, self.screen_height)
        print("[DEBUG] screen size: %dx%d" % (self.screen_width, self.screen_height))
        self.set_position(Gtk.WindowPosition.CENTER)
        self.connect('destroy', Gtk.main_quit)

        # search sensor interface
        self.sensors = Sensors()
        self.sensors.found_all_sensor_path()

        sensor_box = Gtk.VBox(spacing=0)

        # temperature
        temp_label = Gtk.Label()
        temp_label.set_markup("<span font_desc='LiberationSans 25'>Temperature</span>")
        self.temp_value_label = Gtk.Label()
        self.temp_value_label.set_markup("<span font_desc='LiberationSans 25'>--.-- °C</span>")
        temp_box = Gtk.HBox(False, 0)
        temp_box.add(temp_label)
        temp_box.add(self.temp_value_label)
        sensor_box.add(temp_box)

        # humidity
        humidity_label = Gtk.Label()
        humidity_label.set_markup("<span font_desc='LiberationSans 25'>Humidity</span>")
        self.humidity_value_label = Gtk.Label()
        self.humidity_value_label.set_markup("<span font_desc='LiberationSans 25'>--.-- %c</span>" % '%')
        humidity_box = Gtk.HBox(False, 0)
        humidity_box.add(humidity_label)
        humidity_box.add(self.humidity_value_label)
        sensor_box.add(humidity_box)

        # Accel
        accel_label = Gtk.Label()
        accel_label.set_markup("<span font_desc='LiberationSans 25'>Accelerometer</span>")
        self.accel_value_label = Gtk.Label()
        self.accel_value_label.set_markup("<span font_desc='LiberationSans 25'> [ --.--, --.--, --.--]</span>")
        accel_box = Gtk.HBox(False, 0)
        accel_box.add(accel_label)
        accel_box.add(self.accel_value_label)
        sensor_box.add(accel_box)

        # Gyroscope
        gyro_label = Gtk.Label()
        gyro_label.set_markup("<span font_desc='LiberationSans 25'>Gyroscope</span>")
        self.gyro_value_label = Gtk.Label()
        self.gyro_value_label.set_markup("<span font_desc='LiberationSans 25'> [ --.--, --.--, --.--]</span>")
        gyro_box = Gtk.HBox(False, 0)
        gyro_box.add(gyro_label)
        gyro_box.add(self.gyro_value_label)
        sensor_box.add(gyro_box)

        self.add(sensor_box)

        # Add a timer callback to update
        # this takes 2 args: (how often to update in millisec, the method to run)
        self.timer = GObject.timeout_add(TIME_UPATE, self.update_ui, None)
        self.timer_enable = True

    def destroy(self, widget, data=None):
        Gtk.main_quit()

    def update_ui(self, user_data):
        if False == self.timer_enable:
            return False;
        # temperature
        temp = self.sensors.temperature_read()
        self.temp_value_label.set_markup("<span font_desc='LiberationSans 25'>%.02f °C</span>" % temp)
        # humidity
        hum = self.sensors.humidity_read()
        self.humidity_value_label.set_markup("<span font_desc='LiberationSans 25'>%.02f %c</span>" % (hum, '%'))
        # accel
        accel = self.sensors.accelerometer_read()
        self.accel_value_label.set_markup("<span font_desc='LiberationSans 25'>[ %.02f, %.02f, %.02f]</span>" % (accel[0], accel[1], accel[2]))
        # gyro
        gyro = self.sensors.gyroscope_read()
        self.gyro_value_label.set_markup("<span font_desc='LiberationSans 25'>[ %.02f, %.02f, %.02f]</span>" % (gyro[0], gyro[1], gyro[2]))

        # As this is a timeout function, return True so that it
        # continues to get called
        return True

# -------------------------------------------------------------------
# -------------------------------------------------------------------
# Main
if __name__ == "__main__":
    # add signal to catch CRTL+C
    import signal
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    win = MainUIWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()

    Gtk.main()</pre>


* Screenshot showing the results in the graphic user interface[[File:iks01a2-stm32mp157c-dk2_sensor_python_basic.png|thumb|center|upright=4|alt=Result of Python script|Result of Python script]]

===Example of More screenshot for displaying informationexamples with results displayed in a graphic user interface===
[[File:iks01a2-stm32mp157c-dk2_sensor_python_expert_imu.png|thumb|center|upright=4|alt=Example of interpreted IMU data|Example of interpreted IMU data]]<br/>

[[File:iks01a2-stm32mp157c-dk2_sensor_python_expert_move.png|thumb|center|upright=4|alt=Example of raw IMU data|Example of raw IMU data]]<br/>

[[File:iks01a2-stm32mp157c-dk2_sensor_python_expert_sensor.png|thumb|center|upright=4|alt=Example of sensors data presentation|Example of sensors data presentation]]<br/>


== References==<references />

<noinclude>

[[Category:How to run applicative demonstrations]]
{{PublicationRequestId | 12269 | 07Jun'19}}</noinclude>
(17 intermediate revisions by 2 users not shown)
Line 4: Line 4:
 
<br>
 
<br>
   
IKS01A2 board is an expansion board composed by several motion MEMS like HTS221 and LSM6DSL.
+
The IKS01A2 board is an expansion board that includes several motion MEMS like HTS221 and LSM6DSL.
   
This article explains step by step:
+
This article provides step-by-step instructions to:
* how to configure Linux software to support IKS01A2 expansion board,
+
* configure Linux software to support IKS01A2 expansion board,
* how to activate/use several motion MEMS such as HTS221 and LSM6DSL.
+
* activate/use several motion MEMS such as HTS221 and LSM6DSL.
   
 
==Prerequisites==
 
==Prerequisites==
Line 16: Line 16:
 
  [[File: STM32MP157C-DK2_angle2.jpg|thumb|upright=2|center|link=|STM32MP157C-DK2]]
 
  [[File: STM32MP157C-DK2_angle2.jpg|thumb|upright=2|center|link=|STM32MP157C-DK2]]
   
For more information about this STM32 discovery board and how to start with it, jump to this section [[Getting_started/STM32MP1_boards/STM32MP157C-DK2]]
+
For more information about the STM32 discovery board and how to start it up, jump to this section [[Getting_started/STM32MP1_boards/STM32MP157C-DK2]]
   
 
* IKS01A2 expansion board
 
* IKS01A2 expansion board
Line 22: Line 22:
   
 
===Software prerequisites===
 
===Software prerequisites===
The STM32MP157C-DK2 board must be populated with software to be able to customize it to support IKS01A2 expansion board. To know how to proceed please follow the step-by-step description starting with [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Let%27s_start|STM32MP157C-DK2 Let's start]] article.
+
The STM32MP157C-DK2 board must be downloaded with appropriate software in order to support IKS01A2 expansion board. For proceeding, follow the step-by-step instructions provided at [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Let%27s_start|STM32MP157C-DK2 Let's start]].
   
 
==Software customization to support  IKS01A2 expansion board ==
 
==Software customization to support  IKS01A2 expansion board ==
STM32MP157C-DK2 Linux software must be configured to activate IKS01A2 board connected on top of STM32MP157C-DK2 board.<br>
+
The STM32MP157C-DK2 Linux software must be configured to activate the IKS01A2 board connected on top of the STM32MP157C-DK2 board.<br>
   
Configuration is done by modifying the STM32MP157C-DK2 Linux kernel and by managing some new device tree elements.
+
The configuration consists in modifying the STM32MP157C-DK2 Linux kernel and managing some new device tree elements.
   
 
===Kernel configuration===
 
===Kernel configuration===
By default the motion MEMS drivers, present on IKS01A2 expansion board, are enabled in STM32MP1 kernel configuration: hts221, pressure(lp22hb) and lsm6dsl.  The device tree must be updated to declare and activate them.  
+
By default, the motion MEMS drivers present on IKS01A2 expansion board are enabled in STM32MP1 kernel configuration: hts221, pressure(lp22hb) and lsm6dsl.  The device tree must be updated to declare and activate them.  
   
To check whether associated drivers are enabled inside the kernel, follow commands given below :
+
To check whether associated drivers are enabled inside the kernel, type the commands provided here below :
   
 
  {{Board$}}  cat /proc/config.gz | gunzip | grep HTS221
 
  {{Board$}}  cat /proc/config.gz | gunzip | grep HTS221
Line 49: Line 49:
 
  CONFIG_IIO_ST_LSM6DSX_SPI=m
 
  CONFIG_IIO_ST_LSM6DSX_SPI=m
   
{{Info|If those configurations are not enabled on your kernel configuration, please follow the indications given in [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Develop_on_Arm®_Cortex®-A7/Modify,_rebuild_and_reload_the_Linux®_kernel|Modify, rebuild and reload the Linux® kernel]] }}
+
{{Info|If the above configurations are not enabled, follow the indications given in [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Develop_on_Arm®_Cortex®-A7/Modify,_rebuild_and_reload_the_Linux®_kernel|Modify, rebuild and reload the Linux® kernel]] }}
 
 
   
 
===Kernel device tree configuration===
 
===Kernel device tree configuration===
Line 56: Line 55:
   
 
====Hardware / software interface====
 
====Hardware / software interface====
Motion MEMS HTS221 and LSM6DSL, present on IKS01A2 expansion board are used in the use case explained in this article.<br>
+
The HTS221 and LSM6DSL motion MEMS present on IKS01A2 expansion board are involved in the following use case.<br>
According to IKS01A2 user manual<ref  name="User Manual of IKS01A2"> IKS01A2 User Manual [https://www.st.com/resource/en/user_manual/dm00333132.pdf]</ref>, both motion MEMS are controlled by I2C bus.
+
According to IKS01A2 user manual<ref  name="User Manual of IKS01A2"> IKS01A2 User Manual [https://www.st.com/resource/en/user_manual/dm00333132.pdf]</ref>, both motion MEMS are controlled by I{{sup|2}}C bus.
   
In schematics of IKS01A2 <ref name="Schematics of IKS01A2"> IKS01A2 Schematics  [https://www.st.com/resource/en/schematic_pack/x-nucleo-iks01a2_schematic.pdf]</ref> and STM32MP157C-DK2<ref  name="Schematics of STM32MP157C-DK2">STM32MP157C-DK2 Schematics  [https://www.st.com/resource/en/schematic_pack/mb1272-dk2-c01_schematic.pdf]</ref> , presented below, are identified the pins which are connected together.
+
In the schematics of IKS01A2 <ref name="Schematics of IKS01A2"> IKS01A2 Schematics  [https://www.st.com/resource/en/schematic_pack/x-nucleo-iks01a2_schematic.pdf]</ref> and STM32MP157C-DK2<ref  name="Schematics of STM32MP157C-DK2">STM32MP157C-DK2 Schematics  [https://www.st.com/resource/en/schematic_pack/mb1272-dk2-c01_schematic.pdf]</ref> presented below, the pins that interconnected are highlighted.
   
 
* IKS01A2 schematic (Arduino connector) <ref name="Schematics of IKS01A2"/>
 
* IKS01A2 schematic (Arduino connector) <ref name="Schematics of IKS01A2"/>
** Pins 10 and 9 of CN5 are used for I2C Bus (SDA and SCL) (I2C1 and I2C2 bus instances are mixed via the jumper JP7 and JP8)
+
** Pins 10 and 9 of CN5 are used for I{{sup|2}}C Bus (SDA and SCL) (I2C1 and I2C2 bus instances are mixed via JP7 and JP8 jumpers)
 
** Pins 6 and 5 of CN9 are used to manage interruptions on LSM6DSL motion MEMS (indicated for information: not used on kernel configuration).
 
** Pins 6 and 5 of CN9 are used to manage interruptions on LSM6DSL motion MEMS (indicated for information: not used on kernel configuration).
   
Line 68: Line 67:
   
 
*STM32MP157C-DK2 schematic (Arduino connector) <ref  name="Schematics of STM32MP157C-DK2"/>  
 
*STM32MP157C-DK2 schematic (Arduino connector) <ref  name="Schematics of STM32MP157C-DK2"/>  
** Pins 10 and 9 of CN5 are used for I2C Bus (I2C5_SDA and I2C5_SCL)
+
** Pins 10 and 9 of CN5 are used for I{{sup|2}}C Bus (I2C5_SDA and I2C5_SCL)
 
** Pins 6 and 5 of CN14 are used to manage interruptions on LSM6DSL motion MEMS (indicated for information: not used on kernel configuration)
 
** Pins 6 and 5 of CN14 are used to manage interruptions on LSM6DSL motion MEMS (indicated for information: not used on kernel configuration)
   
Line 74: Line 73:
   
   
{{Warning|I2C5''' bus instance MUST be enabled on software to access to motion MEMS present on IKS01A2}}
+
{{Warning|I2C5''' bus instance MUST be enabled by software in order to access the motion MEMS present on IKS01A2}}
   
 
====Kernel device tree configuration====
 
====Kernel device tree configuration====
As seen in previous chapter, IKS01A2 expansion board is controlled via IC2 bus. On STM32MP157C-DK2, the associated I2C bus is '''I2C5'''.
+
As indicated in previous section, the IKS01A2 expansion board is controlled via I{{sup|2}}C bus. On STM32MP157C-DK2, the associated I{{sup|2}}C bus is '''I2C5'''.
   
I2C5 bus must be activated into STM32MP157C-DK2 device tree and a node for each hardware to support must be added  (see entry on device tree like '''hts221''', below, on the following device tree content).
+
The I2C5 bus must be activated into STM32MP157C-DK2 device tree and a node for each hardware to support must be added  (see entries like '''hts221''', as shown in the device tree content example below).
   
   
Line 106: Line 105:
 
</pre>
 
</pre>
 
{{Info|To generate a new device tree, please follow the indications given in [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Develop_on_Arm®_Cortex®-A7/Modify,_rebuild_and_reload_the_Linux®_kernel|Modify, rebuild and reload the Linux® kernel]] }}
 
{{Info|To generate a new device tree, please follow the indications given in [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Develop_on_Arm®_Cortex®-A7/Modify,_rebuild_and_reload_the_Linux®_kernel|Modify, rebuild and reload the Linux® kernel]] }}
 
   
 
===Activate the new configuration in the STM32MP157C-DK2 board===
 
===Activate the new configuration in the STM32MP157C-DK2 board===
   
* '''Prerequisites''': Device tree and Linux kernel must have been regenerated. If not already done, please follow the indications given in [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Develop_on_Arm®_Cortex®-A7/Modify,_rebuild_and_reload_the_Linux®_kernel|Modify, rebuild and reload the Linux® kernel]]  
+
* '''Prerequisites''': The device tree and the Linux kernel must have been regenerated. If not done yet, follow the indications given in [[Getting_started/STM32MP1_boards/STM32MP157C-DK2/Develop_on_Arm®_Cortex®-A7/Modify,_rebuild_and_reload_the_Linux®_kernel|Modify, rebuild and reload the Linux® kernel]]  
 
   
 
   
* Add the two generated files on file system of board, more accurately in bootfs partition (/boot directory)
+
* Add the two generated files in the board file system, precisely in the bootfs partition (/boot directory)
 
  {{Board$}} ls -1 /boot/stm32*dk2*
 
  {{Board$}} ls -1 /boot/stm32*dk2*
 
                                                                                                
 
                                                                                                
Line 120: Line 118:
 
  /boot/stm32mp157c-dk2.dtb
 
  /boot/stm32mp157c-dk2.dtb
   
* Add a new entry in extlinux.conf file, here located in '''/boot/mmc0_stm32mp157c-dk2_extlinux/'''. If no directory mmc0_<something> is available, add the new entry in '''/boot/extlinux/extlinux.conf'''.
+
* Add a new entry in extlinux.conf file located in '''/boot/mmc0_stm32mp157c-dk2_extlinux/'''. If the mmc0_<something> directory is not available, add the new entry in '''/boot/extlinux/extlinux.conf'''.
   
 
<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true; highlight: [5,18,19,20,21];">  
 
<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true; highlight: [5,18,19,20,21];">  
Line 155: Line 153:
 
  {{Board$}}  cat /proc/device-tree/soc/i2c\@40015000/status  
 
  {{Board$}}  cat /proc/device-tree/soc/i2c\@40015000/status  
 
  okay
 
  okay
* Verify if motion MEMS drivers are declared on device tree node:
+
* Verify if the motion MEMS drivers are declared in the device tree node:
   
 
  {{Board$}} ls -l /proc/device-tree/soc/i2c\@40015000/
 
  {{Board$}} ls -l /proc/device-tree/soc/i2c\@40015000/
Line 182: Line 180:
 
</pre>
 
</pre>
   
* Verify if motion MEMS drivers are correctly probed and if the system provides access to the associated hardware:
+
* Verify if the motion MEMS drivers are correctly probed and if the system provides access to the associated hardware:
   
 
  {{Board$}}  grep OF_NAME /sys/bus/iio/devices/iio\:device*/uevent
 
  {{Board$}}  grep OF_NAME /sys/bus/iio/devices/iio\:device*/uevent
Line 192: Line 190:
 
  /sys/bus/iio/devices/iio:device5/uevent:OF_NAME=lsm6dsl
 
  /sys/bus/iio/devices/iio:device5/uevent:OF_NAME=lsm6dsl
   
{{Info|If the results are different then check that
+
{{Info|If the results are different, check that
 
# the expansion board is correctly connected  
 
# the expansion board is correctly connected  
 
# all steps, described above, were correctly done.}}
 
# all steps, described above, were correctly done.}}
   
 
==Read motion MEMS via bash script==
 
==Read motion MEMS via bash script==
The goal of this section are to read the informations provided by Linux kernel interface and process it on a bash script.
+
The goal of this section is to read the informations provided by Linux kernel interface and to process it with a bash script.
 
   
 
   
  +
 
=== List of sensors entry ===
 
=== List of sensors entry ===
IKS01A2 expansion board provides several MEMS like HTS221, LSM6DSL, LPS22HB.<br>
+
The IKS01A2 expansion board provides several MEMS like HTS221, LSM6DSL, LPS22HB.<br>
Hardware MEMS, detected by Linux via the [[IIO overview|IIO framework]], can be listed by verifying the entries on sysfs.
+
The list of hardware MEMS detected by Linux via the [[IIO overview|IIO framework]] can be verified in the sysfs.
   
 
  {{Board$}}  grep OF_NAME /sys/bus/iio/devices/iio\:device*/uevent
 
  {{Board$}}  grep OF_NAME /sys/bus/iio/devices/iio\:device*/uevent
Line 211: Line 210:
 
  /sys/bus/iio/devices/iio:device5/uevent:OF_NAME=lsm6dsl
 
  /sys/bus/iio/devices/iio:device5/uevent:OF_NAME=lsm6dsl
 
   
 
   
This list of entries permits to know which entries are associated to a MEMS driver. In the rest of the article, this list is kept as reference list of entries.
+
This list provides the association between entries and MEMS drivers. In the rest of the article, this list is used a as reference.
   
 
===HTS221: Temperature/Humidity===
 
===HTS221: Temperature/Humidity===
HTS221 is a capacitive digital sensor for relative humidity and temperature.  
+
The HTS221 is a capacitive digital sensor for relative humidity and temperature.  
   
In this example, '''hts221''' entries are '''/sys/bus/iio/devices/iio:device2/''', please adapt to your setup if it's not the case by changing the entry on the scripts described/explained in following chapters.
+
In this example, '''hts221''' entry is '''/sys/bus/iio/devices/iio:device2/'''. In case the user as a different setup the entry should be adapted accordingly in the scripts provided here after.
   
 
====Temperature====
 
====Temperature====
* Read IIO entries associated to temperature for '''HTS221''' driver
+
* Read IIO entries associated to the temperature for '''HTS221''' driver
   
 
  {{Board$}}  cat /sys/bus/iio/devices/iio\:device2/in_temp_raw
 
  {{Board$}}  cat /sys/bus/iio/devices/iio\:device2/in_temp_raw
Line 345: Line 344:
   
 
===LSM6DSL: accelerometer/gyroscope===
 
===LSM6DSL: accelerometer/gyroscope===
LSM6DSL is an inertial measurement unit (IMU), for smartphones and battery operating IoT, gaming, wearable and consumer electronics, ultra-low power and high accuracy.<br/>
+
The LSM6DSL is an inertial measurement unit (IMU) with ultra-low power and high accuracy, for smartphones and battery operated IoT, gaming, wearable and consumer electronics.<br/>
 
<br/>
 
<br/>
 
In this example, '''lsm6dsl''' entries are '''/sys/bus/iio/devices/iio:device4/''' and '''/sys/bus/iio/devices/iio:device4/'''.<br/>
 
In this example, '''lsm6dsl''' entries are '''/sys/bus/iio/devices/iio:device4/''' and '''/sys/bus/iio/devices/iio:device4/'''.<br/>
Device4 entry is dedicated to accelerometer and device5 one to gyroscope.
+
The device4 entry is dedicated to accelerometer and the device5 one to gyroscope.
   
 
====Accelerometer====
 
====Accelerometer====
Line 701: Line 700:
 
==Read motion MEMS via Python script==
 
==Read motion MEMS via Python script==
   
The goal of this section isto read the informations provided by Linux kernel interface and process it on a python script.<br/>
+
The goal of this section is to read the informations provided by Linux kernel interface and process it with a python script.<br/>
The python will display the value calculated on a window UI.
+
The python displays the calculated value through a graphic user interface.
   
 
===Display a window with Python and weston/wayland===
 
===Display a window with Python and weston/wayland===
Line 980: Line 979:
 
</pre>
 
</pre>
   
===Full script with information displayed on a windows===
+
===Full script with information displayed in a graphic user interface===
 
<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">
 
<pre style="overflow-y: visible; max-height: none;" class="brush:c; gutter:true;">
 
#!/usr/bin/python3
 
#!/usr/bin/python3
Line 1,272: Line 1,271:
 
</pre>
 
</pre>
   
* Screenshot
+
* Screenshot showing the results in the graphic user interface
 
[[File:iks01a2-stm32mp157c-dk2_sensor_python_basic.png|thumb|center|upright=4|alt=Result of Python script|Result of Python script]]
 
[[File:iks01a2-stm32mp157c-dk2_sensor_python_basic.png|thumb|center|upright=4|alt=Result of Python script|Result of Python script]]
   
===Example of screenshot for displaying information===
+
===More screenshot examples with results displayed in a graphic user interface===
 
[[File:iks01a2-stm32mp157c-dk2_sensor_python_expert_imu.png|thumb|center|upright=4|alt=Example of interpreted IMU data|Example of interpreted IMU data]]
 
[[File:iks01a2-stm32mp157c-dk2_sensor_python_expert_imu.png|thumb|center|upright=4|alt=Example of interpreted IMU data|Example of interpreted IMU data]]
 
<br/>
 
<br/>

Attachments

Discussions