====== 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 * Compile with: * g++ test_i2c.cpp -lwiringPi */ #include #include #include 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 [[https://packages.debian.org/buster/python3-smbus|Python3 smbus]] library using ''apt''. sudo apt-get install python3-smbus # 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)