Knowledge Base
Software
QT
Getting Qt to work on Raspberry Pi
Installing from repositories
Building from source
This tutorial was inspired by the tutorial here. We will be using Qt 5.15 and skipping useless modules. Also gamepad and multimedia with GStreamer should be working out of the box.
Install preprequisities by running
sudo apt-get update
sudo apt-get install git gdb cmake gcc build-essential libfontconfig1-dev libdbus-1-dev libfreetype6-dev libicu-dev libinput-dev libxkbcommon-dev libsqlite3-dev libssl-dev libpng-dev libjpeg-dev libglib2.0-dev libraspberrypi-dev
sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-plugins-bad libgstreamer-plugins-bad1.0-dev gstreamer1.0-pulseaudio gstreamer1.0-tools gstreamer1.0-alsa libasound2-dev pulseaudio libpulse-dev libsdl2-dev libgles2-mesa-dev libgbm-dev libgl1-mesa-dev libglu1-mesa-dev mesa-common-dev libx11-dev
Download the sources from here in our case we'll be using wget
and downloading the 5.15.1 version
wget http://download.qt.io/official_releases/qt/5.15/5.15.1/single/qt-everywhere-src-5.15.1.tar.xz
Decompress the archive by running
tar xf qt-everywhere-src-5.15.1.tar.xz
Setup build configurations for the Raspberry Pi
git clone https://github.com/oniongarlic/qt-raspberrypi-configuration.git
cd qt-raspberrypi-configuration && make install DESTDIR=../qt-everywhere-src-5.15.1
cd ..
Prepare the build environment
mkdir -p build
cd build
PKG_CONFIG_LIBDIR=/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig ../qt-everywhere-src-5.15.1/configure -platform linux-rpi4-v3d-g++ -v -opengl es2 -eglfs -no-gtk -no-xcb -opensource -confirm-license -release -reduce-exports -force-pkg-config -nomake examples -no-compile-examples -skip qtwayland -skip qtwebengine -skip qt3d -skip qtlocation -skip qtscript -skip qtsensors -skip qtserialport -skip qtspeech -skip qtcharts -skip qtvirtualkeyboard -skip qtquick3d -qt-pcre -no-pch -ssl -evdev -system-freetype -fontconfig -glib -prefix /opt/Qt5.15 -qpa eglfs
And build it!
make -j4
sudo make install
Notes
It is recommended to use swap - at least 1 GB.
It is also recommended to use tmux
for running the build for cases of SSH disconnections.
You should also cool the Raspberry Pi properly, a small fan is enough to lower the CPU temperature by 20 C!.
Raspberry Pi
CAN Bus
Setting up the CAN bus is based on this tutorial.
Kernel-wise the following needs to be added to the /boot/config.txt
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
dtoverlay=spi0-hw-cs
This should work most of the time, however in recent Raspberry Pi firmware builds there happened to be a problem with this approach. A solution to the problem was described here.
The solution utilizes the pinout
program which can be installed using sudo apt-get install python3-gpiozero
. Using this program the BCM number is read and then used in the /boot/config.txt
as follows.
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
dtoverlay=spi-bcm{BCM_NUMBER}
For example:
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
dtoverlay=spi-bcm2837
Reboot is required after for the /boot/config.txt
to take place.
To debug problems with the SPI or the MCP2515 use dmesg | grep spi
.
Hardware
This chapter contains information about making devices work and general tips for working with them.
Arduino
This section contains bits of information about the Arduino boards itself, its main purpose however is providing information about using 3rd party modules with Arduino boards - mainly describing used libraries, but also electrical connections.
Arduino Leonardo
SPI problems
Arduino Leonardo doesn't have SPI connected to the female headers on its sides, SPI is only connected to the ICSP 6-pin header on the back of the board. The pinout can be seen in the following image.
Note that there are multiple pinout images around the internet that show the SPI pins connected to the side female headers.
Maxim 7219 single color matrix displays
[1]
There are several modules with this chip and the matrix itself for example the FC-16, which either comes with a single 8x8 matrix or 4 of these combined together forming a 64x8 matrix display.
A library that can be used to jumpstart the development is the MD_MAX72XX library and for animations and scrolling the MD_Parola library can be easily used.
[1] https://github.com/ridercz/Altairis-ESP8266-FC16
Hardware interfacing
This section describes hardware commonly used to interface other hardware - such as CAN dongles and modules, USB dongles, etc.
CH341A universal interface dongle
[1]
The CH341A provides USB accessible UART, I2C and SPI peripherals and some GPIO. The UART could theoretically be hooked to an RS232 transciever with hardware flow control etc. The problem is that the software support for this chip isn't that good even in Linux kernel. USB -> UART works out of the box, but I2C and SPI need their respective non upstream kernel modules loaded by the user.
From the design of these kernel modules it might not be possible to use both SPI and I2C simultaneously. This hasn't been confirmed as there was not enough experience in Linux kernel module development.
Working modules for the board are for example these:
These modules however need some small changes in the Makefile
(at least for building on Arch/Manjaro changing line 7 to KERNEL_DIR = /usr/lib/modules/$(KVERSION)/build
was required, DKMS failed on this operating system meaning that the modules need to be rebuilt when kernel updates).
It might be an interesting task to at first combine the module for I2C and SPI into one and also to write the kernel module in Rust for better maintainibility.
[1] https://zoobab.wdfiles.com/local--files/ch341-usb-spi-i2c-uart-isp-dongle/ch341a-devboard2.jpg
TGZ48
Calculating position from revolutions and angle
auto map = packet.asMap();
const uint32_t drive1Angle = static_cast<int32_t>(map[TGZRegisters::Monitor1_aAngle]);
const int32_t drive1Revs = static_cast<int32_t>(map[TGZRegisters::Monitor1_aRevol]);
const float revolutions = drive1Angle / static_cast<float>(static_cast<uint32_t>(0xffffffff)) + static_cast<float>(drive1Revs);
The key here is to correctly use signed and unsigned integers, mainly for storing the drive1Angle
and when casting the maximum value to float.
Uncategorized hardware
This section contains descriptions of hardware that may not be directly connected to robotics. I makes sense, however, to make some notes about making it work.
IKEA Tradfri
IKEA Tradfri + Phillips Hue + HomeKit
Both the Tradfri and Hue use ZigBee protocol to operate and also implement some standardized data interface. That means that a Hue bridge can be used to control Tradfri lightbulbs and read data from other sensors.
To connect a lightbulb to the bridge, first in the app it is required to start search for lights. Then the lightbulb needs to be turned off and on 6 times leaving it in connection mode (the bulb changes its brightness in three steps).
The bridge should then identify the bulb and pair with it.
When the connection mode is activated a new search for lightbulbs in the app can be performed.
After the pairing finishes, the lightbulb can be easily used with the Hue app, unfortunately the app won't publish the 3rd party accessories to HomeKit.
There are two solutions to this problem - either buy the IKEA Tradfri bridge and use it to publish the accessories to the HomeKit, or use a home server running Homebridge with appropriate plugins.
The Homebridge server can be installed using the tutorial here and can then be used to control devices from many more manufacturers that do not implement HomeKit on their own.
To make the devices connected to the Hue bridge work, a plugin homebridge-hue needs to be installed and configured with the following configuration, that ensures that the plugin won't advertise native Hue devices, but only the third party one.
...
"platforms": [
...
{
"name": "Hue-tradfri",
"anyOn": true,
"lights": true,
"nativeHomeKitLights": true,
"nativeHomeKitSensors": true,
"nupnp": true,
"resource": true,
"users": {
"USER_ID": "TOKEN"
},
"platform": "Hue"
}
...
]
...
Bear in mind, that after installing the plugin and making it connect to the bridge it is required to save the
USER_ID
andTOKEN
to the configuration file.
Using MSP430 with PlatformIO
There are some hurdles when configuring PlatformIO for development with MSP430 as there are no real examples and incomplete docs concerning uploading the code. The following config seemed to work.
[env:lpmsp430g2553]
platform = timsp430
board = lpmsp430g2553
framework = arduino
debug_tool = mspdebug
upload_protocol = rf2500
The important parts are debug_tool
and upload_protocol
.