Table of Contents

Raspberry Pi

Flash an SD card

To install the RaspiOS you will need to flash the operating system image to an SD card.

With dd:

Good in Linux and Mac shell. More info at https://www.devdungeon.com/content/how-format-sd-card-or-usb-flash-drive

```bash sudo dd if=/path/to/iso of=/path/to/device bs=1m ```

With Balena Etcher:

GUI that is easy to use on Windows, Mac, and Linux:

https://www.balena.io/etcher/

Force HDMI

To disable HDMI detection and force HDMI (fixes black screen after reboot)

In `/boot/config.txt` add:

``` hdmi_force_hotplug=1 # and config_hdmi_boost=4 ```

Default username and password

```text pi/raspberry ```

Change password

```bash # Change your own password passwd # Change specific user's password sudo -u pi passwd ```

Update and upgrade

```bash sudo apt update sudo apt full-upgarde sudo apt dist-upgrade # Upgrade Raspbian distro sudo rpi-update # Update Pi firmawre ```

Configure everything

E.g. network, display, login, modules, hostname, timezone

sudo raspi-config

Check Pi revision version

cat /sys/firmware/devicetree/base/model

Get Raspbian distro version

cat /etc/os-release

Check pin layout

pinout

Networking

Configure static IP address for eth0

It should use DHCP by default, but if you want to specify an IP Address you can. Edit /etc/dhcpcd.conf and uncomment the lines with the example static IP address. Be sure to change the IP address, net mask, and gateway as necessary. Then reboot with sudo reboot.

# Look for eth0 static IP example in comments
sudo vim /etc/dhcpcd.conf # Update config
sudo reboot

Manually configure wpa_supplicant for WiFi

sudo ifconfig
sudo iwconfig
sudo ip addr
sudo iwlist wlan0 scan
wpa_supplicant
wpa_passphrase my-wifi-essid secret pasword >etc/wpa_supplicant/
sudo service networking restart

In the file /etc/wpa_supplicant/wpa_supplicant.conf, you should see something like this:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=US
network={
    ssid="my-wifi-essid"
    psk="password-as-is"
}

Expose local port via remote server

You can take a service running locally, and use a remote VPS to be a proxy and allow connectivity from the internet.

https://www.devdungeon.com/content/expose-local-port-over-remote-vps-ssh-remote-port-forwarding

E.g. curl http://my-remote-host.com:9999 returns response from locahost:8000

# This will SSH to `my-remote-host.com` and while
# the session is open, the remote server will
# start listening on on port 9999 and any
# connection it recieves will get forward
# straight back to port 8000 on your local computer
ssh -R 9999:localhost:8000 my-remote-host.com

Create a system service user account

# To create a use that can't login. Good for running low privilege services
sudo useradd --system --no-create-home --shell=/sbin/nologin some_user
# https://www.devdungeon.com/content/how-create-secure-linux-system-user

Create a systemd service

https://www.devdungeon.com/content/creating-systemd-service-files

# /etc/systemd/system/my_service.service
[Unit]
Description=My Custom Service
After=network.target

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi
ExecStart=/home/pi/my_app --option=123
Restart=always

[Install]
WantedBy=multi-user.target

Setup cron

https://www.devdungeon.com/content/cron-job-examples-and-tip

# To edit `pi` user's cron jobs
crontab -e
# For root
sudo crontab -e
# For some other user
sudo -u some_user crontab -e

Take pictures and video

Pi Camera

Make sure Camera is enabled with `sudo raspi-config`.

To take picture:

raspistill

To take video: https://www.raspberrypi.org/documentation/usage/camera/raspicam/raspivid.md

raspivid
raspivid -t 30000 -w 640 -h 480 -fps 25 -b 1200000 -p 0,0,640,480 -o pivideo.h264

See below for how to convert `.h264` to `.mp4`.

Webcam

List webcam devices:

lsusb
ls /dev/video*

For pictures:

sudo apt install fswebcam
# sudo gpasswd -a pi video # Not needed for pics?
fswebcam --help | less
fswebcam image.jpg
fswebcam -r 1920x1080 ~/fswebcamtest.jpg

For video recording:

sudo apt install libav-tools
avconv -f video4linux2 -r 25 -s 1920x1080 -i /dev/video0 output.avi

Make timelapse video from images

sudo apt install mencoder
ls *.jpg > image_list.txt
mencoder -nosound -ovc lavc -lavcopts vcodec=mpeg4:aspect=16/9:vbitrate=8000000 -vf scale=1280:960 -o timelapse.avi -mf type=jpeg:fps=30 mf://@image_list.txt

Convert h264 video files to mp4

`raspivid` saves `.h264` videos by default. You can convert to mp4 with

sudo apt install -y gpac
# Convert .h264 to .mp4
MP4Box -add video.h264 video.mp4

## Example app: Pi-Cam-Server (Flask)

https://github.com/NanoDano/Pi-Cam-Server

## Example app: Pi-Timelaper (Django)

https://github.com/NanoDano/Pi-Timelapser

Remote desktop with VNC

Official docs at https://www.raspberrypi.org/documentation/remote-access/vnc/

Turn on VNC service first through `raspi-config`. It uses RealVNC. Go to the Interfacing Options and enable VNC.

# Go to 5) Interfacing Options and enable VNC
sudo raspi-config

If you want to connect to view, you'll need to use the RealVNC client which supports username and password auth.

To use a generic client like TigerVNC https://tigervnc.org instead of RealVNC, you'll need to change the authentication mechanism and essentially make it less secure. To do that, update the config file, update the VNC settings, and then restart the service.

sudo vim /root/.vnc/config.d/vncserver-x11
# Set `Authentication=VncAuth`
# Change VNC server to use one password instead of user auth
sudo vncpasswd -service
# Enter the password when it asks
systemctl restart vncserver-x11-serviced

Then connect as normal using a client like TigerVNC using the Pi's IP address or hostname and the password you set for the service.

FIX: When you connect and authenticate with VNC but then see `Cannot currently show the desktop`, it is because there is no graphical desktop running. You have

Option 1) set the Pi to boot into graphical mode. Use `raspi-config` and go to the Boot options and set it to boot to graphical desktop. You can also do it at the CLI with:

# Set default boot to graphical mode (`graphical`) and not CLI only (`multi-user`)
sudo systemctl set-default graphical
sudo reboot

Option 2) SSH into the Pi and run `vncserver` from the command line. This will create a virtual desktop that you can use. The virtual desktop numbers look like ports and start with the number 1. For example: `192.168.1.10:1`.

# Repeat this command to create multiple desktops
vncserver
# To kill a display, pass it the desktop numbers
vncserver -kill :1

TIP: You can change the desktop resolution and it will change the HDMI port an VNC at the same time.

Fix "failed to open vchiq instance" with raspi-still

This means your user can't open the video device and needs to be in group `video`.

I2C stuff

Turn on i2c using raspi-config under Interface options. Reboot after enabling. This will create a device like /dev/i2c-1.

Install i2c-utils to get tools like /usr/sbin/i2cdetect.

sudo apt install i2c-tools
dpkg -L i2c-tools
sudo i2cdetect 1  # they're in sbin, so need sudo
sudo i2cdump --help

I2C C library

test_i2c.cpp
/* test_i2c.cpp
 * Compile with:
 *   g++ test_i2c.cpp -lwiringPi
 */
#include <iostream>
#include <errno.h>
#include <wiringPiI2C.h>
 
int main() {
 
   /* Provide the i2c address from `sudo i2cdetect` */
   int file_handle = wiringPiI2CSetup(0x60);
 
   int result = wiringPiI2CWrite(file_handle, 0x40, 0xDEAD );
   if (result == -1) {
      std::cout << "Error #" << errno << std::endl;
   } else {
       std::cout << "Result: " << result << std::endl;
   }
 
   return 0;
}

I2C Python Library

Install the Python3 smbus library using apt.

sudo apt-get install python3-smbus
test_i2c.py
# Reference adapted from: https://pypi.org/project/smbus2/
from smbus import SMBus
 
DEVICE_ADDRESS = 80
 
bus1 = SMBus(1)
data = bus1.read_byte_data(DEVICE_ADDRESS, 0) # From offset 0
print(data)
bus1.close()
 
with SMBus(1) as bus1:
    # Write a byte to device address, offset 0
    data = 45
    bus1.write_byte_data(DEVICE_ADDRESS, 0, data)