Creating an IoT thermostat (part III)

Improving our Yocto based distribution

Intro

Previously we made ourselves a Linux distribution ourselves for our target embedded system. We included basic Qt5 support which allows us to create a fast and responsive C++ frontend. This time we will further develop our embedded system and prepare it for usage.

Adding QtQuick – QML support

In the previous article we succeeded in created a QtWidget based application. However, with QtQuick there is a new UI framework available which has its own set of benefits. You may already have noticed that QtCreator comes with lots of examples and you may have even tried some of them. However, if you (like me) created your Yocto based OS using the bitbake qt5-basic-image command you will find that some programs may not work when yo run them on your embedded device:

root@raspberryyocto:~# ./clocks
./clocks: error while loading shared libraries: libQt5Quick.so.5: cannot open shared object file: No such file or directory
root@raspberryyocto:~#

Basically we didn’t include support for QtQuick when we compiled our OS. So if you’re into using QtQuick go back through your Yocto working folder and bitbake the qt5-image:

geoffrey@geoffrey-Dell-XPS-L502X:/media/geoffrey/Data/yocto-pi/rpi/build$ bitbake qt5-image
Loading cache: 100% |############################################| Time: 0:00:00
Loaded 2660 entries from dependency cache.
Parsing recipes: 100% |##########################################| Time: 0:00:01
Parsing of 1972 .bb files complete (1964 cached, 8 parsed). 2668 targets, 353 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION = "1.32.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "universal"
TARGET_SYS = "arm-poky-linux-gnueabi"
MACHINE = "raspberrypi"
DISTRO = "poky"
DISTRO_VERSION = "2.2.1"
TUNE_FEATURES = "arm armv6 vfp arm1176jzfs callconvention-hard"
TARGET_FPU = "hard"
meta
meta-poky = "morty:a3fa5ce87619e81d7acfa43340dd18d8f2b2d7dc"
meta-oe
meta-multimedia
meta-networking
meta-python = "morty:1efa5d623bc64659b57389e50be2568b1355d5f7"
meta-qt5 = "morty:9aa870eecf6dc7a87678393bd55b97e21033ab48"
meta-raspberrypi = "master:e1f69daa805cb02ddd123ae2d4d48035cb5b41d0"
meta-rpi = "morty:03841471ccaed549a2a14a896c13f71af76cf482"

Initialising tasks: 100% |#######################################| Time: 0:00:08
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 3619 tasks of which 3538 didn't need to be rerun and all succeeded.
geoffrey@geoffrey-Dell-XPS-L502X:/media/geoffrey/Data/yocto-pi/rpi/build$

Notice how fast compiling the image goes this time compared to when we build the qt5-basic-image. The reason for this faster build time is because the qt5-image inherits the qt5-basic-image and Yocto just needed to recompile some of the components that were not yet compiled. Also note that you don’t need a new SDK and you shouldn’t need to re-configure QtCreator.

With your SD card already formatted you only need to copy the compiled files to your SD card:

geoffrey@geoffrey-Dell-XPS-L502X:/media/geoffrey/Data/yocto-pi/rpi/build$ cd ../meta-rpi/scripts/
geoffrey@geoffrey-Dell-XPS-L502X:/media/geoffrey/Data/yocto-pi/rpi/meta-rpi/scripts$ sudo umount /dev/mmcblk0p1
geoffrey@geoffrey-Dell-XPS-L502X:/media/geoffrey/Data/yocto-pi/rpi/meta-rpi/scripts$ sudo umount /dev/mmcblk0p2
geoffrey@geoffrey-Dell-XPS-L502X:/media/geoffrey/Data/yocto-pi/rpi/meta-rpi/scripts$ export MACHINE=raspberrypi
geoffrey@geoffrey-Dell-XPS-L502X:/media/geoffrey/Data/yocto-pi/rpi/meta-rpi/scripts$ export OETMP=/media/geoffrey/Data/yocto-pi/rpi/build/tmp
geoffrey@geoffrey-Dell-XPS-L502X:/media/geoffrey/Data/yocto-pi/rpi/meta-rpi/scripts$ ./copy_rootfs.sh mmcblk0 qt5 raspberryyocto

OETMP: /media/geoffrey/Data/yocto-pi/rpi/build/tmp
IMAGE: qt5
HOSTNAME: raspberryyocto

File found: /media/geoffrey/Data/yocto-pi/rpi/build/tmp/deploy/images/raspberrypi/qt5-image-raspberrypi.tar.xz

Block device not found: /dev/mmcblk02, trying p2

Formatting /dev/mmcblk0p2 as ext4
[sudo] wachtwoord voor geoffrey:
/dev/mmcblk0p2 bevat een ext4-bestandssysteem met label 'ROOT'
laatst aangekoppeld op / op Sun Feb 19 22:07:51 2017
Toch doorgaan? (j,n) j
Mounting /dev/mmcblk0p2
Extracting qt5-image-raspberrypi.tar.xz to /media/card
Writing raspberryyocto to /etc/hostname
Unmounting /dev/mmcblk0p2
Done
geoffrey@geoffrey-Dell-XPS-L502X:/media/geoffrey/Data/yocto-pi/rpi/meta-rpi/scripts$

With that done we need to have a QtQuick test application. If you haven’t yet tried on of the QtCreator’s QtQuick examples do so now. Get back to your embedded device, insert the SD card and boot. Once booted, retrieve the device’s IP address and copy over any QtQuick test application. I’ve used the clocks application. Once you have the application compiled and copied over to the raspberry pi, ssh into your pi and start the application (or launch it from within QtCreator if you’ve had it still openened). You should see more or less something like this:

qtquick-demo-clocks-small

If you happen to run into “out of memory” errors:

root@raspberryyocto:~# ./clocks
QML debugging is enabled. Only use this in a safe environment.
Unable to query physical screen size, defaulting to 100 dpi.
To override, set QT_QPA_EGLFS_PHYSICAL_WIDTH and QT_QPA_EGLFS_PHYSICAL_HEIGHT (in millimeters).
JIT is disabled for QML. Property bindings and animations will be very slow. Visit https://wiki.qt.io/V4 to learn about possible solutions for your platform.
glGetError 0x505
QSGTextureAtlas: texture atlas allocation failed, out of memory

… then you should tweak the CPU/GPU memory allocation settings. This settings is loaded at boot and it is also saved in a config file on your boot partition. To adjust the config file we first need to mount the boot partition, and next we can edit the file using the vi editor:

root@raspberryyocto:~# mkdir /mnt/fat
root@raspberryyocto:~# mount /dev/mmcblk0p1 /mnt/fat
root@raspberryyocto:~# vi /mnt/fat/config.txt

Add gpu_mem=256 to this file and reboot your pi. Try again running the clocks application, things should go now as intended:

root@raspberryyocto:~# ./clocks
QML debugging is enabled. Only use this in a safe environment.
Unable to query physical screen size, defaulting to 100 dpi.
To override, set QT_QPA_EGLFS_PHYSICAL_WIDTH and QT_QPA_EGLFS_PHYSICAL_HEIGHT (in millimeters).
JIT is disabled for QML. Property bindings and animations will be very slow. Visit https://wiki.qt.io/V4 to learn about possible solutions for your platform.

Setting the timezone

To show the current time we will rely on NTP. RaspberryPi does not come with a RTC see I don’t see any other option. NTP is already added via Yocto, we only have to set the correct timezone:

root@yoctopi:~# ls -l /etc/localtime
lrwxrwxrwx 1 root root 27 Apr 10 18:36 /etc/localtime -> /usr/share/zoneinfo/EST5EDT
root@yoctopi:~# rm /etc/localtime
root@yoctopi:~# ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime
root@yoctopi:~# date
Sun Apr 16 12:30:40 CEST 2017

Adding a touch screen

The RaspberryPi community has a very decent 7″ touch screen. There is not much to say about, I got one, followed the instructions to hook it op and basically started testing some my applications straight away!

2033-01

Side note: I used the same housing as show above. This one has the display upside down, the rotate the display through software we must again edit the config file on the boot partition:

root@raspberryyocto:~# mkdir /mnt/fat
root@raspberryyocto:~# mount /dev/mmcblk0p1 /mnt/fat
root@raspberryyocto:~# vi /mnt/fat/config.txt

and add:

display_rotate=2

Restart to apply your changes.

Adding a HTU21D I²C temperature sensor

The HTU21D is a decent temperature and humidity sensor which perfectly suits our needs. To hook it up to our Raspberry Pi 2:

htu21d-block-s

Before we can use the I2C bus we must again edit the Pi’s config file:

root@raspberryyocto:~# mkdir /mnt/fat
root@raspberryyocto:~# mount /dev/mmcblk0p1 /mnt/fat
root@raspberryyocto:~# vi /mnt/fat/config.txt

and add:

dtparam=i2c_arm=on

Restart to apply your changes.
After the system has booted into Linux again we will first check if the i2c_bcm2708 module has been loaded:

root@yoctopi:~# lsmod
Module                  Size  Used by
ipv6                  350447  28
i2c_dev                 6115  2
evdev                  11396  1
joydev                  8960  0
bcm2835_gpiomem         3036  0
i2c_bcm2708             4834  0
bcm2835_wdt             3225  0
rpi_ft5406              4612  0
uio_pdrv_genirq         3164  0
rpi_backlight           2064  0
uio                     8128  1 uio_pdrv_genirq

Now we must add the i2c device by doing:

root@yoctopi:~# touch /etc/modules
root@yoctopi:~# echo 'i2c-dev' >> /etc/modules

Reboot again. When all went good we can now use the ic2detect tool to see if the Pi is able to communicate with our temperature sensor:

root@yoctopi:~# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

With everything setup and good to go I can now start developing my application. Stay tuned for more!

Advertisements

2 thoughts on “Creating an IoT thermostat (part III)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s