Raspberry Pi



Introduction

The Raspberry Pi is a ARM-based, single-board, bare-bones computer system sold in the form of a palm-sized (or even smaller) circuit board that fits all the necessary components plus connectivity options. You can install operating systems like Raspbian or Windows 10 on it. I use the Raspberry Pi as the task controller of my robots.

Processors

  • Raspberry Pi 2 has the ARM Cortex-A7 based Broadcom BCM2836 processor with 32-bit ARMv7-A programming model.
  • Raspberry Pi 3 has the ARM Cortex-A53 based Broadcom BCM2837 processor with 32/64-bit ARMv8-A programming model.


Alternative Platforms


GPIO

Raspberry Pi 2 & 3 come with 40 General Purpose Input Output pins (layout) that can be used to interface with the other electronic components in your project.


Installing Raspbian on Micro SD Card

First, you need to decide which flavor of Raspbian you want to download. I use the Lite version because it is better suited for embedded applications. The fewer software modules are running, the lower the power consumption, and the lower the chance that user-space processes will be interrupted.

Preparing the SD Card on Linux

First we need to find out which device to copy the install image to. Type

df -h

or

sudo fdisk --list

in the command terminal to look up the mount point for the SD card. Let us assume the card was mounted as /dev/sdb2. The card needs to be unmounted before we can copy the downloaded Raspbian install image:

umount /dev/sdb2


Copy the image to the card with the dd command:

sudo dd bs=4M if=raspbian.img of=/dev/sdb

where we use the path to the device file /dev/sdb instead of the partition /dev/sdb2, which was unmounted. The option bs is used for adjusting the buffer size for the writing operation.

Preparing the SD Card on Apple macOS

Insert the SD card in your Mac and determine the assigned disk number disk# (e.g., disk2) under which the card has been mounted to the filesystem by using the 'diskutil' tool in Terminal.

diskutil list


Now unmount the disk

diskutil unmountDisk disk2

and copy the data with the dd tool

sudo dd bs=1m if=~/Downloads/raspbian.img of=/dev/rdisk2

where I assumed that the Raspbian image file is located at ~/Downloads/raspbian.img and the card was mounted as disk2.

Upgrading a Raspbian Installation

You don't want to erase your existing Raspbian environment and set up all the software from start each time a new version of Raspbian is released. Fortunately, Raspbian can upgrade itself to the latest release with the following commands.

sudo apt-get update
sudo apt-get dist-upgrade



Assigning a Static Ethernet IP Address

Edit the file /etc/network/interfaces and make sure that the entries for the interface eth0 are as follows:

auto eth0
iface eth0 inet static
	address 192.168.0.20
	netmask 255.255.255.0
	broadcast 192.168.0.255

where the IP address 192.168.0.20 is just an example.

Make sure you don't break the WiFi connectivity because of editing /etc/network/interfaces. If there is no empty describing wlan0 we will need to create one. For dynamically assigned IPs via DHCP you will need these lines:

auto wlan0
iface wlan0 inet dhcp
	wpa-ssid <your WiFi router name (SSID)>
	wpa-psk <your WiFi password>


The new network setting becomes effective on the next system boot or when you type

sudo ifdown eth0
sudo ifup eth0



Setting Up SSH

  • As a security measure, SSH is not enabled by default on headless (= Raspbian Lite, without GUI) installations. Place a file named "ssh" into the root folder of the boot partition (= /boot) to enable SSH.
  • In the web browser go to the configuration page of your home Internet router (e.g., http://192.168.1.1).
  • Open the page that lists all currently connected LAN devices.
  • Connect the Raspberry Pi via Ethernet cable to the LAN router.
  • Look for a new entry in the list of LAN devices. That should be your Raspberry Pi. Note the IP address. Let's assume it is 192.168.1.10.
  • Optional: You should be able to read the MAC address of the Raspberry Pi from the table. For future reference, write down the MAC address somewhere.
  • Open Terminal and type ssh pi@192.168.1.10 to log in via SSH. On a fresh Raspbian installation the username is pi and the password is raspberry.
  • After logging in type sudo raspi-config to start the Raspbian configuration tool, where you can change the password or expand the filesystem to take up the whole SD card, among other things.



Setting Up WiFi

Raspberry Pi 2

The Raspberry Pi 2 does not have built-in WiFi. I assume that you are using a USB WiFi adapter. Before connecting the adapter you need to edit the network interfaces on the Raspberry Pi. Log in to the Raspberry Pi over SSH and edit /etc/network/interfaces as follows:

auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
auto wlan0

iface wlan0 inet dhcp
	wpa-ssid "ssid"
	wpa-psk “password"


where ssid is the SSID (a.k.a. name) of your WLAN router, and password is supplied in encoded form. Do not type the quotation marks. The password is encoded by running

wpa_passphrase <ssid> <password>


If your WLAN router uses a hidden SSID use this configuration:

auto lo

iface lo inet loopback
iface eth0 inet dhcp

auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
	wpa-scan-ssid 1
	wpa-ap-scan 1
	wpa-key-mgmt WPA-PSK
	wpa-proto RSN WPA
	wpa-pairwise CCMP TKIP
	wpa-group CCMP TKIP
	wpa-ssid "My Secret SSID"
	wpa-psk "My SSID PSK”

iface default inet dhcp


Instead of putting the WPA configuration directly into interfaces you can put it into the file /etc/wpa_supplicant/wpa_supplicant.conf

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
   ssid="<your ssid>"
   psk=<your encoded password given by running wpa_passphrase>
   scan_ssid=1
   proto=WPA RSN
   key_mgmt=WPA-PSK
   pairwise=CCMP TKIP
}


and refer to it from interfaces like so

auto lo
iface lo inet loopback

iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf

iface default inet dhcp



Raspberry Pi 3 or newer

The Raspberry Pi 3 has a WLAN transmitter built in and it is turned on by default. You should see the device wlan0 along with eth0 and lo when typing

ifconfig -a


Make sure the Raspberry Pi can log in to your WLAN router. If a MAC filter is active, add the Raspberry Pi WiFi MAC address to the list of allowed devices. The MAC address of the Pi is displayed in the output of ifconfig -a as HWaddr. Open a text editor to add the network configuration details, such as your login credentials, to the file /etc/wpa_supplicant/wpa_supplicant.conf.

network={
  ssid="MySSID"
  psk=MyCodedPassword
  scan_ssid=1
  proto=WPA RSN
  key_mgmt=WPA-PSK
  pairwise=CCMP TKIP
}


where MySSID is the SSID (a.k.a. name) of the router, and MyCodedPassword is the encoded password obtained via

wpa_passphrase MySSID MyPassword

and where MyPassword is the actual password.

Power Saving

If the WiFi connection is unstable you can turn off the WiFi power management feature, which may cause connection dropouts, by issuing the command

sudo iw dev wlan0 set power_save off

or by manually editing /etc/network/interfaces, where you add the line

wireless-power off

right after the line

wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

within the wlan0 block. You can check whether power management is currently turned on or off, among other parameters, with the command

iwconfig



For Raspberry Pi 2 and WiFi dongles with 8192CU or 8188CUS chip (for example, Edimax EW-7811un dongles)you can prevent connections from being dropped by creating the file /etc/modprobe.d/8192cu.conf

sudo nano /etc/modprobe.d/8192cu.conf

and adding the line

options 8192cu rtw_power_mgnt=0 rtw_enusbss=0


Camera

There is a camera module for Raspberry Pi, which I use in my robots. In fact, the camera module is part of the Core Module.

Refer to the official camera setup instructions. Be careful with the camera module, handle the camera board and the connector strip delicately.

To be able to access the camera through the Python programming environment you need to install the python-picamera package

The Raspberry Pi project does not provide a C/C++ library for accessing the camera. Instead it provides utility applications raspistill and raspivid which record still images and videos, respectively. A number of third-party C++ libraries have been created based on the open source code of these utility applications. The RaspiCam C++ library developed at the University of Cordoba is one such library (source code available from SourceForge).

Video Streaming

To stream video from the Raspberry Pi camera to the network, open a terminal on the RPi and type

raspivid -t 0 -w 1280 -h 720 -hf -ih -fps 30 -o - | nc -k -l 8100


To view the stream on a client computer with Mplayer installed, open a terminal there and type

mplayer -fps 300 -demuxer h264es ffmpeg://tcp://192.168.0.20:8100



Alternatively, you can use GStreamer to transport the video frames. Make sure that the command line interface to GStreamer, gst-launch-1.0, is installed.

sudo apt install gstreamer1.0-tools


For streaming from the RPi you can type

raspivid -t 0 -h 720 -w 1080 -fps 25 -hf -b 2000000 -o - | gst-launch-1.0 -v fdsrc ! h264parse !  rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=0.0.0.0 port=8100


For viewing on the client, you can type

gst-launch-1.0 -v tcpclientsrc host=192.168.0.20 port=8100 ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false

where 192.168.0.20 is assumed to be the IP address of the server (Raspberry Pi).

GPIO Programming in C

You can use WiringPi library to comfortably access the GPIO pins from a C/C++ program. WiringPi is installed from source like this

sudo apt-get install git-core
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build

Read the INSTALL file for what to do with the created shared library. Basically you need to copy wiringPi/libwiringPi.so.x.xx to /usr/local/lib and add the line

include /usr/local/lib

to the file /etc/ld.so.conf so that the library loader also looks in /usr/local/lib for dynamically loadable libraries. It is also possible to create a static library.

After installation, create a test program called blink.cpp

#include <stdio.h>
#include <iostream>
#include <wiringPi.h>

static int LED_PORT = 7; // The physical pin number. Corresponds to BCM GPIO pin 4.

void blink()
{
  digitalWrite(4, HIGH);
  delay(1000);
  digitalWrite(4, LOW);
  delay(1000);
};

int main(int numargs, char** args)
{
  wiringPiSetup();
  pinMode(LED_PORT, OUTPUT);
  for (int n = 0; n < 10; n++)
  {
    blink();
  }
  std::cout << "finished blinking" << std::endl;
  return 0;
}

and build like this

g++ blink.cpp -o blink -lstdc++ -lwiringPi -IwiringPi

where I assumed that the wiringPi root folder is located in the same folder as the blink.cpp source file.

Which pins can be used for what purpose is explained on the wiringPi pins page.

PWM

There are some Python libraries that communicate with the GPIO daemon to provide hardware PWM on selected pins. GPIO Zero (tutorial) is one such library and is included in Raspbian. With GPIO Zero you can implement dimming LEDs or control a brushed DC motor behind an H-Bridge circuit.


Running A Program On Startup

We want the Raspberry Pi to start the robot control program as soon as it's done with booting. In order to make sure that the system has completely initialized itself we will not use /etc/rc.local for starting our program. Instead, we will create a cron task with the crontab command

sudo crontab -e

which opens the editor of choice (most likely nano) where you can enter the program launch command. In our case this will be

@reboot python /home/pi/Core.py

where the leading @reboot indicates to cron that this command shall be executed only once, right after the booting process has completed. Notice that it is not necessary to start the command with sudo, which is necessary when running program from the command line.


Communicating With Other Devices

There are three popular communication protocols that the Raspberry Pi supports and that are often used in embedded systems: I2C, SPI, and UART.

I2C

Set the I2C clock speed by editing /boot/config.txt

dtparam=i2c1=on
dtparam=i2c_arm_baudrate=xxx

where xxx is the desired frequency. Keep in mind that ATmega microcontrollers used on Arduino boards support only up to 400 kHz while Raspberry Pi can support higher speeds.

Wiring To I2C Devices With 5 V Logic Level

Normally you can not connect a GPIO pin to a device with 5 V logic (most of the Arduino models, for example). The GPIO data pins of the Raspberry Pi use 3.3 V as the HIGH voltage level and can be damaged when 5 V is applied. However, because I2C pins have open-collector outputs they can be wired directly to I2C pins of devices with incompatible voltage levels. As long as the pull-up line voltage, which corresponds to the lowest of the device HIGH voltage levels, exceeds the minimum voltage for which HIGH is defined on each device, the devices will be able to sense the correct data bit.

Links:


SPI

First of all, you need to use the raspi-config command-line configuration utility to enable the SPI pins.

sudo raspi-config


You can use WiringPi SPI to add SPI capability to your C/C++ program.

UART

Here is a tutorial that shows how to communicate with an Arduino using the UART interface.

CAN

There are various CAN adapter boards available for Raspberry Pi. For example PiCAN2.

Development Tools

Raspbian Buster from 2019 comes with GCC version 8.3.0, which fully implements the C++14 standard.
If you are connected to the Raspberry Pi via a terminal session you can use VIM for editing code files.