m (Sets size of screenshot image.)
Line 95: Line 95:
<br />
<br />
You can now use Raspberry Pi Imager or any flashing utility to flash a system image on the compute module eMMC.
You can now use Raspberry Pi Imager or any flashing utility to flash a system image on the compute module eMMC.
<br />
<br />
<br />



Revision as of 2022-11-05T11:50:25



Introduction

The Raspberry Pi Ltd. is a company producing small and affordable single-board, bare-bones computer systems, microcontrollers and accessories, marketed under the Raspberry Pi brand. All Raspberry Pi computing products use Arm-based processors. I use Raspberry Pi computers as task controller, and the microcontrollers as state agent in my robots.

Processors and Architectures

  • Arm Cortex-A7 with 32-bit Armv7 programming model
    • Raspberry Pi 2 B (Broadcom BCM2836 processor @ 900 MHz)


  • Arm Cortex-A53 with 64-bit Armv8-A programming model.
    • Raspberry Pi 2 B rev 1.2 (Broadcom BCM2837 processor @ 900 MHz)
    • Raspberry Pi 3 B (Broadcom BCM2837 processor @ 1.2 GHz)
    • Raspberry Pi 3 B+ (Broadcom BCM2837B0 processor @ 1.4 GHz)
    • Raspberry Pi Zero 2 W (@ 1 GHz)


  • Arm Cortex-A72 with 64-bit Armv8-A programming model
    • Raspberry Pi 4 (Broadcom BCM2711 processor @ 1.5 GHz)
    • Compute Module 4 (Broadcom BCM2711 @ 1.5 GHz)


  • Arm Cortex-M0+ with Armv6-M programming model
    • Raspberry Pi Pico (up to 133 MHz)


Installing a System Image

Raspberry Pi OS is the offical operating system of a Raspberry Pi. The Lite version, without a graphical desktop, is recommended for embedded applications unless you decide to create a custom system image. The fewer software modules are running, the lower the power consumption, and the lower the chance that user-space processes will be interrupted.

Installing the System Image on SD Card

This is the most popular method of installing a system image on a single-board computers. SD cards are cheap and reusable, almost all Raspberry Pi models come with an SD card reader. However, SD card memory is not designed to support frequent rewrite operations and may not be as durable as other storage solutions.

The preferred way of putting a system image on an SD card is to use the Raspberry Pi Imager tool that can fetch a Raspberry Pi OS image over the Internet or use a local image file, create a derived image with preconfigured user credentials, WLAN access and more, before writing it to the SD card.

Using built-in tools on Linux

The SD card can also be prepared by using standard Linux tools instead of Raspberry Pi Imager. 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 Raspberry Pi OS install image:

umount /dev/sdb2


Copy the image to the card with the dd command:

sudo dd bs=4M if=2021-01-11-raspios-buster-armhf-lite.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.

Using built-in tools on macOS

On Apple macOS, you can use the built-in 'diskutil' tool as an alternative to the Raspberry Pi Imager. First, attach the SD card to your Mac and determine the assigned disk number disk# (e.g., disk2) under which the card has been mounted to the filesystem by opening Terminal and typing

diskutil list

then unmount the disk

diskutil unmountDisk disk2

and copy the data with the dd tool

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

where I assume that the downloaded and unzipped Raspberry Pi OS image file is located at ~/Downloads/raspios.img and the SD card was mounted as disk2.

Booting from eMMC

Some Raspberry Pi models, like the Compute Module 4, come with an embedded MultiMediaCard (eMMC) storage component. A switch or jumper on the carrier board serves to make the Raspberry Pi bootloader boot the compute module into USB mass storage mode. In this mode you can attach the compute module to an external computer via USB. On Ubuntu you can use the

lsusb

command to list all connected USB devices. The Compute Module 4, for example, should show up as Broadcom Corp. BCM2711 Boot.
To make the operating system recognize the USB device as a mass storage device, we need to build and run Raspberry Pi's rpiboot tool.

sudo apt install libusb-1.0-0-dev
git clone --depth=1 https://github.com/raspberrypi/usbboot
cd usbboot
make
sudo ./rpiboot

On Ubuntu, lsusb will now list the Compute Module 4 as "Broadcom Corp. Compute Module". The compute module will also show up in the Disks app as RPi-MSD-0001.

You can now use Raspberry Pi Imager or any flashing utility to flash a system image on the compute module eMMC.

Upgrading a Raspberry Pi OS Installation

You don't want to erase your existing Raspberry Pi OS environment and set up all the software from start each time a new version of Raspberry Pi OS is released. Fortunately, Raspberry Pi OS 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 -w 640 -h 480 -fps 30 -hf -b 2000000 -o - | gst-launch-1.0 -q 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 ! videoflip method=vertical-flip ! autovideosink sync=false

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

  • On the Raspberry Pi side you can elevate the priority of the process by beginning the command with "nice -20".
  • For verbose output from gst-launch-1.0, use the option -v instead of -q.
  • Note that we used the videoflip filter to correct the rotation of the decoded image.


Disabling the LED

To disable the red indicator light of the camera, add the following line to /boot/config.txt and reboot:

disable_camera_led=1


pinout

A cool command-line tool provided by Raspberry Pi, and also available when running Ubuntu instead of Raspberry Pi OS, is pinout. It displays a layout of the Raspberry Pi board using ASCII art, a list of significant hardware features of the board, and the GPIO pin layout in tabular form.

sudo apt install python3-gpiozero
pinout



GPIO Programming in C

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

Using libgpiod

The standard C++ programming interface for GPIO on Linux is libgpiod, as described on the Jetson page.

Using WiringPi

Using the WiringPi library is a more popular method for programming the GPIO pins on a Raspberry Pi with C/C++. 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.


Debug data: