[PYTHON] Getting Started with Yocto Project with Raspberry Pi 4 and WSL2

Introduction

The other day, I touched the Raspberry Pi with Playing with Ubuntu Desktop on Raspberry Pi 4, but this time I tried to move this Raspberry Pi using the Yocto Project. I tried using Yocto for the first time, but I think it was a good introduction, so I will summarize the contents.

What is Ycto Project?

Mainly, there are mechanisms and tools for creating Linux distributions for embedded and IoT. You can flexibly customize and build embedded Linux images. It seems to be adopted by many embedded Linux providers. Yocto Project - Wikipedia

What I tried

I started the Raspberry Pi 4 that I had at hand with the image built with Yocto.

This development environment

Yocto was built on Ubuntu 20.04 LTS with WSL2. The target is Raspberry Pi 4 as mentioned above.

Preparation

First, install WSL2. The distribution is using Ubuntu 20.04 LTS this time. Please refer to here for the procedure, for example. https://docs.microsoft.com/ja-jp/windows/wsl/install-win10

When the environment starts up, update the package for the time being.

$ sudo apt update && sudo apt upgrade -y

Next, install the necessary packages by referring to Yocto Project Quick Start.

$ sudo apt install -y gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat cpio python python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping libsdl1.2-dev xterm

Build targeting Raspberry Pi 4

First, clone Poky (reference distribution) with Git. The version specifies the latest Gatesgarth (Yocto 3.2) at this point. Releases - Yocto Project

$ mkdir ~/yocto && cd ~/yocto
$ git clone git://git.yoctoproject.org/poky
$ cd poky
$ git checkout -b gatesgarth-24.0.1 refs/tags/gatesgarth-24.0.1

Next, add a BSP layer for Raspberry Pi. There is meta-raspberrypi in OpenEmbedded Layer Index, so clone it. The branch specifies gatesgarth according to Poky.

$ cd ~/yocto/poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi
$ cd meta-raspberrypi
$ git checkout -b gatesgarth origin/gatesgarth

Refer to the procedure described in the README of meta-raspberrypi.

Dependencies
This layer depends on:
* URI: git://git.yoctoproject.org/poky
 - branch: master
 - revision: HEAD
* URI: git://git.openembedded.org/meta-openembedded
 - layers: meta-oe, meta-multimedia, meta-networking, meta-python
 - branch: master
 - revision: HEAD

Quick Start
1. source poky/oe-init-build-env rpi-build
2. Add this layer to bblayers.conf and the dependencies above
3. Set MACHINE in local.conf to one of the supported boards
4. bitbake core-image-base
5. Use bmaptool to copy the generated .wic.bz2 file to the SD card
6. Boot your RPI

First, load oe-init-build-env and set up the environment. When executed, the rpi-build directory is created and moved. Build is done in this directory.

$ cd ~/yocto/poky
$ source oe-init-build-env rpi-build

Next, make additional settings for this layer. add-layer will add meta-raspberrypi to conf/bblayers.conf.

$ bitbake-layers add-layer ../meta-raspberrypi/
$ cat conf/bblayers.conf
:
BBLAYERS ?= " \
  /home/user/yocto/poky/meta \
  /home/user/yocto/poky/meta-poky \
  /home/user/yocto/poky/meta-yocto-bsp \
  /home/user/yocto/poky/meta-raspberrypi \
  "

Next, add the dependent layer described in the README in the same way. Again, specify gatesgarth for the branch. Also, an error will occur depending on the order in which add-layer is executed, so add in the following order.

$ cd ~/yocto/poky
$ git clone git://git.openembedded.org/meta-openembedded
$ cd meta-openembedded
$ git checkout -b gatesgarth origin/gatesgarth
$ cd ~/yocto/poky/rpi-build
$ bitbake-layers add-layer ../meta-openembedded/meta-oe/
$ bitbake-layers add-layer ../meta-openembedded/meta-python/
$ bitbake-layers add-layer ../meta-openembedded/meta-multimedia/
$ bitbake-layers add-layer ../meta-openembedded/meta-networking/
$ cat conf/bblayers.conf
:
BBLAYERS ?= " \
  /home/user/yocto/poky/meta \
  /home/user/yocto/poky/meta-poky \
  /home/user/yocto/poky/meta-yocto-bsp \
  /home/user/yocto/poky/meta-raspberrypi \
  /home/user/yocto/poky/meta-openembedded/meta-oe \
  /home/user/yocto/poky/meta-openembedded/meta-python \
  /home/user/yocto/poky/meta-openembedded/meta-multimedia \
  /home/user/yocto/poky/meta-openembedded/meta-networking \
  "

Next, set MACHINE in local.conf. For the machine name to be specified, refer to Machines in here. This time, the settings are as follows.

~/yocto/poky/rpi-build/conf/local.conf


MACHINE ?= "raspberrypi4-64"

When I used WSL2 at the end, the following error appeared at build time. (This error did not occur on Ubuntu 18.04 installed on VMware.) It was solved by the countermeasure in Stack Overflow.

ERROR: Task (/home/user/yocto/poky/meta/recipes-kernel/linux-libc-headers/linux-libc-headers_5.8.bb:do_install) failed with exit code '134'

~/yocto/poky/rpi-build/conf/local.conf


PSEUDO_IGNORE_PATHS_append = ",/run/"

The setting is completed up to this point. Execute the build with the bitbake command. It takes a lot of time to build, and the PC runs at full capacity. Let's wait patiently. For reference, it took about 3-4 hours on my notebook PC (CPU: Core i7-8550U, memory: 16.0 GB). Also, SSD uses about 50GB.

$ cd ~/yocto/poky/rpi-build
$ bitbake core-image-base

If you are using WSL2, the following warning will be displayed. Please refer to "6. Optimize your WSLv2 storage often" in here for the countermeasures.

WARNING: You are running bitbake under WSLv2, this works properly but you should optimize your VHDX file eventually to avoid running out of storage space

When the build is complete, the OS image will be created in rpi-build/tmp/deploy/images/raspberrypi4-64. Write core-image-base-raspberrypi4-64.wic.bz2 to the SD card using the bmaptool command. However, in the WSL2 environment I am using this time, I did not know how to specify the device name of the SD card.

$ cd ~/yocto/poky/rpi-build/tmp/deploy/images/raspberrypi4-64
$ sudo apt install -y bmap-tools
$ sudo bmaptool copy core-image-base-raspberrypi4-64.wic.bz2 /dev/sdX  #I don't know how to specify the device name of the SD card

So this time, after decompressing wic.bz2, I wrote it to the SD card using Raspberry Pi Imager on Windows.

$ cd ~/yocto/poky/rpi-build/tmp/deploy/images/raspberrypi4-64
$ cp core-image-base-raspberrypi4-64.wic.bz2 /tmp/.  #Since it is a symbolic link, copy it to a suitable place
$ bunzip2 /tmp/core-image-base-raspberrypi4-64.wic.bz2
$ mv /tmp/core-image-base-raspberrypi4-64.wic /mnt/c/Users/user/Downloads/.  #Move to a suitable directory on the Windows side

Select core-image-base-raspberrypi4-64.wic from Use custom in the Operating System and write to the SD card. I think that there is no problem even if you write with Etcher or DD for Windows. image.png Insert the created SD card into the Raspberry Pi and turn on the power to start the OS. When the output to the console stops and you press the Enter key, log in: is displayed, so log in as root. There is no password. If successful, the environment is minimal, but you can operate it firmly in the terminal.

raspberrypi4-64 log in: root
root@raspberrypi4-64:~# uname -mnr
raspberrypi4-64 5.4.72-v8 aarch64
root@raspberrypi4-64:~# cat /etc/issue
Poky (Yocto Project Reference Distro) 3.2.1 \n \l

Create a simple recipe and Hello world!

Next, I will write my own simple source code and summarize the procedure to install the compiled executable binary. The following will be helpful. Creating a General Layer Using the bitbake-layers Script

First, create a layer. Execute the following command to create the meta-hello directory and a template in it.

$ cd ~/yocto/poky
$ bitbake-layers create-layer meta-hello
$ ls meta-hello/
COPYING.MIT  README  conf  recipes-example

Next, make additional settings for the created layer.

$ cd ~/yocto/poky/rpi-build
$ bitbake-layers add-layer ../meta-hello/
$ cat conf/bblayers.conf
:
BBLAYERS ?= " \
  /home/user/yocto/poky/meta \
  /home/user/yocto/poky/meta-poky \
  /home/user/yocto/poky/meta-yocto-bsp \
  /home/user/yocto/poky/meta-raspberrypi \
  /home/user/yocto/poky/meta-openembedded/meta-oe \
  /home/user/yocto/poky/meta-openembedded/meta-python \
  /home/user/yocto/poky/meta-openembedded/meta-multimedia \
  /home/user/yocto/poky/meta-openembedded/meta-networking \
  /home/user/yocto/poky/meta-hello \

Next, prepare the source code. Create a files directory and place the source code as shown below.

$ cd ~/yocto/poky/meta-hello
$ mkdir -p recipes-hello/hello && cd recipes-hello/hello
$ mkdir files && cd files
$ vim hello.c

I prepared Hello world in C language.

hello.c


#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("Hello, world!\n");
    return 0;
}

Next, create a recipe (metadata used to build the package).

$ cd ~/yocto/poky/meta-hello/recipes-hello/hello
$ vim hello_1.0.bb

Here is a reference for how to write a recipe file. Single .c File Package (Hello World!) However, if it is left as it is, the build will fail, so add TARGET_CC_ARCH + =" $ {LDFLAGS} ". Default Linker Hash Style Changed If you don't know md5 of LIC_FILES_CHKSUM, leave it blank and the correct value will be displayed as an error at build time.

text:hello_1.0.bb


SUMMARY = "Simple helloworld application"
SECTION = "hello"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

TARGET_CC_ARCH += "${LDFLAGS}"

SRC_URI = "file://hello.c"

S = "${WORKDIR}"

do_compile() {
    ${CC} hello.c -o hello
}

do_install() {
    install -d ${D}${bindir}
    install -m 0755 hello ${D}${bindir}
}

The final directory / file structure is as follows.

meta-hello/
├── COPYING.MIT
├── README
├── conf
│   └── layer.conf
├── recipes-example
│   └── example
│       └── example_0.1.bb
└── recipes-hello
    └── hello
        ├── files
        │   └── hello.c
        └── hello_1.0.bb

Finally, specify the addition of the image with IMAGE_INSTALL_append in local.conf.

~/yocto/poky/rpi-build/conf/local.conf


IMAGE_INSTALL_append = " hello"  #Note that a leading whitespace character is required

When you are ready so far, build it.

$ cd ~/yocto/poky/rpi-build/
$ bitbake core-image-base

Write the completed OS image to the SD card and start it with Raspberry Pi. Log in and check that you can execute the hello command. If all goes well, you will see Hello, world!.

raspberrypi4-64 log in: root
root@raspberrypi4-64:~# hello
Hello, world!

Set to enable SSH connection via Wi-Fi

Next, set up to enable SSH connection via Wi-Fi. In the environment so far, it seems that wlan0 is recognized when you check with the ip command.

root@raspberrypi4-64:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq qlen 1000
    link/ether dc:a6:32:b8:2b:4a brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP8000> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether dc:a6:32:b8:2b:4b brd ff:ff:ff:ff:ff:ff

It seems easy to use ConnMan to make a Wi-Fi connection. Make additional settings for the image in local.conf. Also, add OpenSSH to make an SSH connection. It seems good to specify it as IMAGE_FEATURES by referring to here.

~/yocto/poky/rpi-build/conf/local.conf


IMAGE_INSTALL_append = " connman connman-client"
IMAGE_FEATURES_append = " ssh-server-openssh"

Up to this point, build the OS image with bitbake core-image-base and start Raspberry Pi from the SD card. Use the connmanctl command to set up the Wi-Fi connection according to the following procedure.

root@raspberrypi4-64:~# connmanctl
connmanctl> enable wifi
connmanctl> scan wifi
connmanctl> services
    Buffalo-A-0F20       wifi_dca632b82b4b_42756666616c6f2d412d30463230_managed_psk
    Buffalo-G-0F20       wifi_dca632b82b4b_42756666616c6f2d472d30463230_managed_psk
    WARPSTAR-D56FD6      wifi_dca632b82b4b_57415250535441522d443536464436_managed_psk
connmanctl> agent on
connmanctl> connect wifi_dca632b82b4b_42756666616c6f2d412d30463230_managed_psk
Passphrase?
connmanctl> exit

When you have finished entering the passphrase, exit connmanctl and check again with the ip command. The IP address is assigned to wlan0. If you try an SSH connection to this IP address, you should be able to log in as root.

$ ssh [email protected]  #IP address assigned to wlan0 of Raspberry Pi
Last login: Sun Jan 10 02:06:14 2021 from 192.168.1.7
root@raspberrypi4-64:~#

It is not directly related to SSH connection, but I added it because it was convenient to use SFTP in my development environment. In addition, set the root password and create a new pi user. Also add the sudo command. Also, when I was investigating with the addition of OpenSSH, I often saw a setting to enable systemd, so I will include this as well.

~/yocto/poky/rpi-build/conf/local.conf


IMAGE_INSTALL_append = " openssh-sftp-server sudo"
IMAGE_FEATURES_append = " ssh-server-openssh"

# user settings
INHERIT_append = " extrausers"
EXTRA_USERS_PARAMS = "useradd -P raspberry pi;usermod -P raspberry root;"

# systemd settings
DISTRO_FEATURES_append = " systemd"
VIRTUAL-RUNTIME_init_manager = "systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME_initscripts = ""
IMX_DEFAULT_DISTRO_FEATURES_append = " systemd"

Build up to this point, start with Raspberry Pi and check the SSH connection. (This build will take some time again.) In addition to root, pi users can also log in with SSH. Use the newly set password. (In this example, raspberry)

To enable sudo as a pi user, set it from root with the visudo command.

/etc/sudoers


root ALL=(ALL) ALL
pi   ALL=(ALL) ALL  #Add here

Build a development environment by adding Python

Add Python as a development environment. Since I am using Raspberry Pi, I will add rpi-gpio to easily control GPIO. Also, since I didn't have an LED at hand, I used a command called raspi-gpio to control GPIO to check it.

~/yocto/poky/rpi-build/conf/local.conf


IMAGE_INSTALL_append = " python3 python3-pip rpi-gpio raspi-gpio"

Build the OS image and start it with Raspberry Pi. I am checking with the root user. Let's check if Python and pip can be used. You can also see that the output is as shown below and that rpi-gpio is added.

# python3 --version
Python 3.8.5
# python3 -m pip list
Package    Version
---------- -------
pip        20.0.2
RPi.GPIO   0.7.0
setuptools 49.6.0

Also make sure that you can use the raspi-gpio command. You can check how to use it easily with help. GPIO pin 1 seems to be pulled up by input by default.

# raspi-gpio help
# raspi-gpio get 1
GPIO 1: level=1 fsel=0 func=INPUT pull=UP

Write a simple sample code to control GPIO in Python. Set GPIO pin 1 as the output setting and switch ON/OFF every second.

gpio.py


import time
import RPi.GPIO as GPIO

def main():
    pin_num = 1
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(pin_num, GPIO.OUT)
    for i in range(10):
        GPIO.output(pin_num, i % 2)
        print(f'GPIO {"ON" if i % 2 else "OFF"}')
        time.sleep(1)
    GPIO.cleanup(pin_num)

if __name__ == '__main__':
    main()

If you repeatedly execute raspi-gpio while executing the above Python code and check the GPIO pin 1, you can see that func is switched to output and level is switched to 0/1.

# python3 gpio.py  #Check the following in another session during execution
# raspi-gpio get 1
GPIO 1: level=0 fsel=1 func=OUTPUT pull=NONE
# raspi-gpio get 1
GPIO 1: level=1 fsel=1 func=OUTPUT pull=NONE
# raspi-gpio get 1
GPIO 1: level=0 fsel=1 func=OUTPUT pull=NONE
# raspi-gpio get 1
GPIO 1: level=1 fsel=1 func=OUTPUT pull=NONE

How to control GPIO from device file

I will also briefly summarize how to control GPIO from a device file without using raspi-gpio. If you check by the following procedure, you can see that GPIO pin 1 is the input by default. With this method as well, you can see how the Python sample code is executed and switched to output to turn it on and off.

# cd /sys/class/gpio
# ls
export       gpiochip0    gpiochip504  unexport
# echo 1 > export
# ls
export       gpio1        gpiochip0    gpiochip504  unexport
# cd gpio1
# ls
active_low  device      direction   edge        power       subsystem   uevent      value
# cat active_low direction value
0
in
1

Create a toolchain and build a cross-compilation environment

Finally, build the toolchain and build a cross-compilation environment on your local PC. This time I built and ran the C ++ code, but when I ran it I got an error saying that libstdc ++. So.6 could not be found. It seems that the C ++ standard library is not included by default, so make additional settings.

~/yocto/poky/rpi-build/conf/local.conf


IMAGE_INSTALL_append = " libstdc++"
TOOLCHAIN_TARGET_TASK_append = " libstdc++-staticdev"

Summarizing the contents so far, the final contents of local.conf are as follows.

~/yocto/poky/rpi-build/conf/local.conf


MACHINE ?= "raspberrypi4-64"

# for WSL2
PSEUDO_IGNORE_PATHS_append = ",/run/"

# image
IMAGE_INSTALL_append = " hello connman connman-client openssh-sftp-server sudo python3 python3-pip rpi-gpio raspi-gpio libstdc++"
IMAGE_FEATURES_append = " ssh-server-openssh"

# user settings
INHERIT_append = " extrausers"
EXTRA_USERS_PARAMS = "useradd -P raspberry pi;usermod -P raspberry root;"

# systemd settings
DISTRO_FEATURES_append = " systemd"
VIRTUAL-RUNTIME_init_manager = "systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME_initscripts = ""
IMX_DEFAULT_DISTRO_FEATURES_append = " systemd"

# for c++
TOOLCHAIN_TARGET_TASK_append = " libstdc++-staticdev"

After writing local.conf, build the OS image and toolchain. It will take some time to build the toolchain, so please wait slowly. Also, please note that SSD will use about 80GB in the previous procedure.

$ cd ~/yocto/poky/rpi-build
$ bitbake core-image-base
$ bitbake core-image-base -c populate_sdk  #Toolchain build

When the build is complete, you will have a toolchain in rpi-build/tmp/deploy/sdk. You can install it by executing the .sh file in it. The installation destination is / opt/poky/3.2.1 by default. You can use the cross-compilation environment by loading environment-setup-cortexa72-poky-linux.

$ cd ~/yocto/poky/rpi-build/tmp/deploy/sdk
$ sudo ./poky-glibc-x86_64-core-image-base-cortexa72-raspberrypi4-64-toolchain-3.2.1.sh
$ source /opt/poky/3.2.1/environment-setup-cortexa72-poky-linux

This time, C ++ Hello world! Build with CMake and run it with Raspberry Pi.

$ mkdir ~/hello && cd ~/hello
$ vim hello.cpp
$ vim CMakeLists.txt
$ mkdir build && cd build
$ cmake ..
$ make

The hello.cpp and CMakeLists.txt used this time have the following contents.

hello.cpp


#include <iostream>

int main(int argc, char const *argv[])
{
    std::cout << "Hello, world!" << std::endl;
    return 0;
}

CMakeLists.txt


cmake_minimum_required(VERSION 3.0.0)
project(hello VERSION 0.1.0)

set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "limited configs" FORCE)

add_executable(hello
    hello.cpp
)

target_compile_features(hello
    PRIVATE cxx_std_17
)

Use the readelf command to check the executed binary that has been built. You can see that the Machine is AArch64 and cross-compilation is possible. (The PC that was built this time is x86_64)

$ readelf -h hello
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           AArch64
  Version:                           0x1
  :
$ uname -m
x86_64

If you copy the execution binary to Raspberry Pi with the scp command and move it,Hello, world!Is displayed.

Local PC


$ scp ./hello [email protected]:/home/root/.

RaspberryPi


# ~/hello
Hello, world!

in conclusion

This time, I targeted Raspberry Pi 4 and built Linux using Yocto Project and actually ran it. I think I was able to confirm the basic procedure to some extent. Yocto doesn't have much information in Japanese, and it takes a long time to build, so I felt that it was difficult for beginners to get along with. I think this article is a good tutorial for those who are new to Yocto. I would be grateful if you could use it as a reference for people who are new to Yocto.

Referenced books

This is the last introduction of the books I referred to. For the beginning, I referred to Introduction to Yocto Project. It was very helpful because I touched Yocto for the first time. The contents summarized this time, especially in the first half, were moved according to my development environment by referring to the contents of this book, and I summarized it while checking it additionally.

Recommended Posts

Getting Started with Yocto Project with Raspberry Pi 4 and WSL2
Getting Started with Heroku-Viewing Hello World in Python Django with Raspberry PI 3
Pet monitoring with Rekognition and Raspberry pi
MQTT RC car with Arduino and Raspberry Pi
Get temperature and humidity with DHT11 and Raspberry Pi
Getting started with Android!
GPGPU with Raspberry Pi
Getting Started with Golang 2
Getting started with apache2
Getting Started with Golang 1
Getting Started with Python
Getting Started with Django 1
Getting Started with Optimization
Getting Started with Golang 3
Getting Started with Numpy
Getting started with Spark
DigitalSignage with Raspberry Pi
Getting Started with Python
Getting Started with Pydantic
Getting Started with Golang 4
Getting Started with Jython
Getting Started with Django 2
Record temperature and humidity with systemd on Raspberry Pi
Getting Started with python3 # 2 Learn about types and variables
Machine learning with Raspberry Pi 4 and Coral USB Accelerator
Easy IoT to start with Raspberry Pi and MESH
Detect mask wearing status with OpenCV and Raspberry Pi
Measure temperature and humidity with Raspberry Pi3 and visualize with Ambient
Getting Started with Tensorflow-About Linear Regression Hypothesis and Cost
Ubuntu 20.04 on raspberry pi 4 with OpenCV and use with python
Troubleshoot with installing OpenCV on Raspberry Pi and capturing
Getting Started with Python Functions
Getting Started with Tkinter 2: Buttons
Getting Started with Go Assembly
Getting Started with PKI with Golang ―― 4
Django Getting Started: 2_ Project Creation
Getting Started with Python Django (1)
Getting Started with Python Django (4)
Getting Started with Python Django (6)
Getting Started with Django with PyCharm
Python3 | Getting Started with numpy
Getting Started with Python Django (5)
Easy introduction to home hack with Raspberry Pi and discord.py
Create a web surveillance camera with Raspberry Pi and OpenCV
Python beginner opens and closes interlocking camera with Raspberry Pi
I tried connecting Raspberry Pi and conect + with Web API
Production of temperature control system with Raspberry Pi and ESP32 (1)
Measure and compare temperature with Raspberry Pi and automatically generate graph
Getting Started with Poetry From installation to execution and version control
[Raspberry Pi] Stepping motor control with Raspberry Pi
Getting Started with Python responder v2
Use vl53l0x with Raspberry Pi (python)
Servo motor control with Raspberry Pi
Getting Started with Git (1) History Storage
Getting started with Sphinx. Generate docstring with Sphinx
Getting Started with Python Web Applications
Serial communication with Raspberry Pi + PySerial
Getting Started with Python for PHPer-Classes
Getting Started with Sparse Matrix with scipy.sparse
Getting Started with Julia for Pythonista
Christmas classic (?) Lighting a Christmas tree with Raspberry Pi and Philips Hue