From 39aeb47d0e0dde847a5184bd55c25f3a8a2ae490 Mon Sep 17 00:00:00 2001 From: "Joseph T. Foley" Date: Mon, 29 Jun 2026 00:35:34 +0000 Subject: [PATCH 01/14] disabling ethernet --- Scripts/gadget.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Scripts/gadget.sh b/Scripts/gadget.sh index 148f635..c1d054b 100755 --- a/Scripts/gadget.sh +++ b/Scripts/gadget.sh @@ -45,9 +45,11 @@ mkdir functions/acm.usb0 ln -s functions/acm.usb0 configs/c.1/ ## Ethernet (RNDIS and ECM) -mkdir functions/ecm.usb0 -ln -s functions/ecm.usb0 configs/c.1/ +## Of note, this may cause the IP to show up as 127.0.0.1 +## and wireless to suddenly fail to connect +#mkdir functions/ecm.usb0 +#ln -s functions/ecm.usb0 configs/c.1/ ## USB Device Controller update UDC=`ls /sys/class/udc` -echo $UDC > UDC \ No newline at end of file +echo $UDC > UDC From c6f164220966e75691210b347b5e9d18cd9ca3a7 Mon Sep 17 00:00:00 2001 From: Joseph Timothy Foley Date: Thu, 2 Jul 2026 09:33:44 +0000 Subject: [PATCH 02/14] Ignore generated html files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 25be4a4..3691aad 100644 --- a/.gitignore +++ b/.gitignore @@ -225,3 +225,4 @@ cython_debug/ # PyPI configuration file .pypirc +*.html From f8dac3c07f800b669db05eedcb938923d63d2796 Mon Sep 17 00:00:00 2001 From: Joseph Timothy Foley Date: Thu, 2 Jul 2026 09:33:56 +0000 Subject: [PATCH 03/14] Testing code formatting --- gadget.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/gadget.md b/gadget.md index 999c8dc..d9a893a 100644 --- a/gadget.md +++ b/gadget.md @@ -1,11 +1,16 @@ # Gadget Mode to setup a serial connection over USB Prepare Raspberry Pi OS connection over a microUSB serial cable -Important: You will want to disable the serial console on RX/TX if you are trying to use that serial port for communicating with other devices. - Based upon Adafruit guide: https://learn.adafruit.com/turning-your-raspberry-pi-zero-into-a-usb-gadget/serial-gadget: The author discovered the guide was out of date, consulted the [2025 Raspberry Pi whitepaper on OTG](https://pip-assets.raspberrypi.com/categories/685-app-notes-guides-whitepapers/documents/RP-009276-WP/Using-OTG-mode-on-Raspberry-Pi-SBCs), found additional errors, and was finally able to correct them thanks to this blog https://www.isticktoit.net/?p=1383 +## Important : +- **Using the Gadget Mode will make the usb port unable to connect to a mouse or keyboard!!!** You will need to disable it make them work again. +- You will want to disable the serial console on RX/TX in `raspi-config` if you are trying to use that serial port for communicating with other devices. + + +## Procedure + Make sure you have your USB cable plugged into the left port **USB** and not the right port marked **PWR**. 1. Open a connection to the device via ssh or Raspberry Pi Connect 1. Become root (the superuser) @@ -13,9 +18,9 @@ Make sure you have your USB cable plugged into the left port **USB** and not the sudo su ``` 1. Enable the DWC version 2 USB peripheral device tree overlay by appending it to the end after the `[all]` category (which is at the end) - ``` - echo "dtoverlay=dwc2" >> /boot/firmware/config.txt - ``` +``` +echo "dtoverlay=dwc2" >> /boot/firmware/config.txt +``` 1. We add the required module `dwc2` for loading at startup ``` echo "dwc2" >> /etc/modules From aebf3aaab8886af2e8978e05610b8085ade0857d Mon Sep 17 00:00:00 2001 From: Joseph Timothy Foley Date: Thu, 2 Jul 2026 09:37:25 +0000 Subject: [PATCH 04/14] Formatted code indentation to match sequence --- gadget.md | 52 +++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/gadget.md b/gadget.md index d9a893a..3c75f9d 100644 --- a/gadget.md +++ b/gadget.md @@ -14,41 +14,43 @@ The author discovered the guide was out of date, consulted the [2025 Raspberry P Make sure you have your USB cable plugged into the left port **USB** and not the right port marked **PWR**. 1. Open a connection to the device via ssh or Raspberry Pi Connect 1. Become root (the superuser) - ``` - sudo su - ``` +``` +sudo su +``` 1. Enable the DWC version 2 USB peripheral device tree overlay by appending it to the end after the `[all]` category (which is at the end) ``` echo "dtoverlay=dwc2" >> /boot/firmware/config.txt ``` 1. We add the required module `dwc2` for loading at startup - ``` - echo "dwc2" >> /etc/modules - ``` +``` +echo "dwc2" >> /etc/modules +``` 1. Check that we can load the libcomposite module - ``` - modprobe libcomposite - ``` +``` +modprobe libcomposite +``` 1. Put a copy of this repository in root's home directory using git - ``` - apt install -y git - git clone https://gitea.cs.ru.is/RU-V207/rover-pi.git - ``` +``` +apt install -y git +git clone https://gitea.cs.ru.is/RU-V207/rover-pi.git +``` 1. Go to Scripts and test if the `gadget.sh` runs without errors and hopefully a Serial port appers in Device Manager or equivalent - ``` - cd rover-pi/Scripts/ - ./gadget.sh - ``` -1. Install the systemd script - `cp serial-ether-gadget.service /lib/systemd/system/.` + ``` +cd rover-pi/Scripts/ +./gadget.sh +``` +1. Install the systemd +``` +cp serial-ether-gadget.service /lib/systemd/system/. +``` 1. Enable the service - ``` - systemctl enable serial-ether-gadget.service - ``` +``` +systemctl enable serial-ether-gadget.service +``` 1. Enable the getty (which connects a login terminal to the serial port) - ``` - systemctl enable serial-getty@ttyGS0.service - ``` +``` +systemctl enable serial-getty@ttyGS0.service +``` 1. Reboot and see if the serial port appears # Connecting to the serial terminal From ca46da2501e39a06b4986f148a84876c3a5fa446 Mon Sep 17 00:00:00 2001 From: Joseph Timothy Foley Date: Thu, 2 Jul 2026 09:45:23 +0000 Subject: [PATCH 05/14] imager --- imager.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imager.md b/imager.md index 7d02e84..939db9a 100644 --- a/imager.md +++ b/imager.md @@ -23,7 +23,7 @@ We don't have many monitors and keyboards in V207 for students to use, so we wil ![imager-ssh_nokey.png](Graphics/imager-ssh_nokey.png) 1. Once you have uploaded your `id_edcsa.pub` file it should look like this. ![imager-ssh_key.png](Graphics/imager-ssh_key.png) -1. Since we don't have enough monitors, we will need another way to setup the initial connection. The officially supported option is Raspberry Pi Connect. You will need to: +1. Since we don't have a monitor, keyboard, and mouse available, we will need another way to setup the initial connection. The officially supported option is Raspberry Pi Connect. You will need to enable it then: 1. Register for an account first at https://connect.raspberrypi.com 2. Confirm your account with email 2. Login with that account From 15222445611ad1d237b931a67a7332c6fc9b1cf8 Mon Sep 17 00:00:00 2001 From: Joseph Timothy Foley Date: Thu, 2 Jul 2026 09:47:30 +0000 Subject: [PATCH 06/14] Started file on making initial connection --- connect.md | 10 ++++++++++ imager.md | 9 +-------- 2 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 connect.md diff --git a/connect.md b/connect.md new file mode 100644 index 0000000..98a5e7c --- /dev/null +++ b/connect.md @@ -0,0 +1,10 @@ +# Initial connection to the Raspberry Pi +Now that you have an image with ssh and Raspberry Pi connect on your SD, you can connect to the pi + + +## Connecting using Raspberry Pi Connect +1. Login to https://connect.raspberrypi.com if you haven't already +1. Look at the list of devices, find the one you want, and click on "Connect" +![connect-devices.png](Graphics/connect-devices.png) +1. A remote shell window will pop up +![connect-shell.png](Graphics/connect-shell.png) diff --git a/imager.md b/imager.md index 939db9a..69377ef 100644 --- a/imager.md +++ b/imager.md @@ -42,12 +42,5 @@ We don't have many monitors and keyboards in V207 for students to use, so we wil 1. Now you get to watch the writing then verifying. ![imager-writeimage-progress.png](Graphics/imager-writeimage-progress.png) ![imager-writeimage-verifying.png](Graphics/imager-writeimage-verifying.png) -1. The process is complete! +1. The process is complete! Now you can [connect to your pi](connect.md) ![imager-complete.png](Graphics/imager-complete.png) - -## Connecting using Raspberry Pi Connect -1. Login to https://connect.raspberrypi.com if you haven't already -1. Look at the list of devices, find the one you want, and click on "Connect" -![connect-devices.png](Graphics/connect-devices.png) -1. A remote shell window will pop up -![connect-shell.png](Graphics/connect-shell.png) From b6679263156007838f4dbcfa99433d3395539632 Mon Sep 17 00:00:00 2001 From: Joseph Timothy Foley Date: Thu, 2 Jul 2026 09:49:02 +0000 Subject: [PATCH 07/14] API link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d01d895..42174c0 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Scripts and documentation for setting up a Raspberry Pi (Zero W 1 or 2) for use - [Turning your Raspberry Pi Zero into a USB Gadget](https://learn.adafruit.com/turning-your-raspberry-pi-zero-into-a-usb-gadget/serial-gadget) Official Adafruit guide to gadget mode to allow the USB port to be used as a serial console to connect to it. We had trouble getting it to work in 2026 due to some changes in Raspberry Pi OS. - [Python gpiozero library](https://gpiozero.readthedocs.io/en/stable/) a simple interface for working with GPIO devices - [CircuitPython Libraries on Linux and Raspberry Pi](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/installing-circuitpython-on-raspberry-pi) This is one option for GPIO, I2C, SPI, and PWM access in python. +- [Comparing Rasbperry Pi python interfaces](https://raspberry.tips/en/raspberrypi-tutorials/raspberry-pi-gpio-python) ## For the Future - [Setting up Zeroconf to use local names (.local) to access your Pi](https://learn.adafruit.com/bonjour-zeroconf-networking-for-windows-and-linux): this does not work on iot-research because multicast and MDNS are broken. From 29fb570ae5b08113ca51c4beb39f9241f0841c9c Mon Sep 17 00:00:00 2001 From: Joseph Timothy Foley Date: Thu, 2 Jul 2026 10:05:09 +0000 Subject: [PATCH 08/14] Adding module detect functionality --- Scripts/gadget.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Scripts/gadget.sh b/Scripts/gadget.sh index 148f635..0918cba 100755 --- a/Scripts/gadget.sh +++ b/Scripts/gadget.sh @@ -2,6 +2,17 @@ # Adapted from # "Using OTG mode on Raspberry Pi SBCs" # https://pip-assets.raspberrypi.com/categories/685-app-notes-guides-whitepapers/documents/RP-009276-WP/Using-OTG-mode-on-Raspberry-Pi-SBCs + +# Is the dwc2 overlay installed? Nothing will work if it isn't. +LOGGER="systemd-cat -t gadget.sh" +if lsmod | grep -q "dwc2"; then + $LOGGER -p info "DWC2 module loaded, setting up OTG gadget serial and ethernet" +else + $LOGGER -p warning "DWC2 module missing. Aborting OTG setup" + exit 1 +fi + + sudo modprobe libcomposite cd /sys/kernel/config/usb_gadget # Create our new gadget @@ -50,4 +61,4 @@ ln -s functions/ecm.usb0 configs/c.1/ ## USB Device Controller update UDC=`ls /sys/class/udc` -echo $UDC > UDC \ No newline at end of file +echo $UDC > UDC From 17c0ffab67258d13b73970609f907f14ed1d015b Mon Sep 17 00:00:00 2001 From: "Joseph T. Foley" Date: Thu, 2 Jul 2026 10:08:47 +0000 Subject: [PATCH 09/14] ECM was not breaking network --- Scripts/gadget.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/gadget.sh b/Scripts/gadget.sh index c1d054b..4cfe8f3 100755 --- a/Scripts/gadget.sh +++ b/Scripts/gadget.sh @@ -47,8 +47,8 @@ ln -s functions/acm.usb0 configs/c.1/ ## Ethernet (RNDIS and ECM) ## Of note, this may cause the IP to show up as 127.0.0.1 ## and wireless to suddenly fail to connect -#mkdir functions/ecm.usb0 -#ln -s functions/ecm.usb0 configs/c.1/ +mkdir functions/ecm.usb0 +ln -s functions/ecm.usb0 configs/c.1/ ## USB Device Controller update UDC=`ls /sys/class/udc` From 3ef2ca02a62ab715b6e262c4b29cb27f14d6ee66 Mon Sep 17 00:00:00 2001 From: "Joseph T. Foley" Date: Thu, 2 Jul 2026 10:29:54 +0000 Subject: [PATCH 10/14] test if MyGadget already exists --- Scripts/gadget.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Scripts/gadget.sh b/Scripts/gadget.sh index 52e1ca3..86514d4 100755 --- a/Scripts/gadget.sh +++ b/Scripts/gadget.sh @@ -4,17 +4,22 @@ # https://pip-assets.raspberrypi.com/categories/685-app-notes-guides-whitepapers/documents/RP-009276-WP/Using-OTG-mode-on-Raspberry-Pi-SBCs # Is the dwc2 overlay installed? Nothing will work if it isn't. -LOGGER="systemd-cat -t gadget.sh" if lsmod | grep -q "dwc2"; then - $LOGGER -p info "DWC2 module loaded, setting up OTG gadget serial and ethernet" + systemd-cat -t gadget.sh -p info echo "DWC2 module loaded, setting up OTG gadget serial and ethernet" else - $LOGGER -p warning "DWC2 module missing. Aborting OTG setup" + systemd-cat -t gadget.sh -p warning echo "DWC2 module missing. Aborting OTG setup." exit 1 fi sudo modprobe libcomposite cd /sys/kernel/config/usb_gadget +# Was the script already run? +if [ -d "MyGadget" ]; then + systemd-cat -t gadget.sh -p warning echo "MyGadget already exists. Aborting OTG setup." + exit 1 +fi + # Create our new gadget sudo mkdir MyGadget cd MyGadget From 01b3a189ed83facac3fac11be6dd87ffb5eaa6eb Mon Sep 17 00:00:00 2001 From: "Joseph T. Foley" Date: Thu, 2 Jul 2026 10:34:26 +0000 Subject: [PATCH 11/14] enable/disable gettys as needed --- Scripts/gadget.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Scripts/gadget.sh b/Scripts/gadget.sh index 86514d4..fde27f2 100755 --- a/Scripts/gadget.sh +++ b/Scripts/gadget.sh @@ -8,20 +8,19 @@ if lsmod | grep -q "dwc2"; then systemd-cat -t gadget.sh -p info echo "DWC2 module loaded, setting up OTG gadget serial and ethernet" else systemd-cat -t gadget.sh -p warning echo "DWC2 module missing. Aborting OTG setup." + systemctl disable serial-getty@ttyGS0.service exit 1 fi - sudo modprobe libcomposite cd /sys/kernel/config/usb_gadget -# Was the script already run? if [ -d "MyGadget" ]; then systemd-cat -t gadget.sh -p warning echo "MyGadget already exists. Aborting OTG setup." exit 1 fi # Create our new gadget -sudo mkdir MyGadget +mkdir MyGadget cd MyGadget # Add some boilerplate data that the gadget needs echo 0x1d6b > idVendor # Linux Foundation’s USB VID. Replace with your own VID if required @@ -46,6 +45,7 @@ echo "Config 1" > configs/c.1/strings/0x409/configuration ### Remember to create the storage block device first ## cd /root ### Example: Make a 256 MB file to act as "USB stick" +## Only create it once or it will delete the previous content ## sudo dd if=/dev/zero of=drive.bin bs=1M count=256 ### Create a VFAT file system on the backing store ## sudo mkfs.vfat drive.bin @@ -69,3 +69,6 @@ ln -s functions/ecm.usb0 configs/c.1/ ## USB Device Controller update UDC=`ls /sys/class/udc` echo $UDC > UDC + +# Enable the gettys +systemctl enable serial-getty@ttyGS0.service From 9f51718235c8507ae101b99fdaebd75439c1221f Mon Sep 17 00:00:00 2001 From: "Joseph T. Foley" Date: Thu, 2 Jul 2026 10:39:13 +0000 Subject: [PATCH 12/14] test if running as root --- Scripts/gadget.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Scripts/gadget.sh b/Scripts/gadget.sh index fde27f2..490c1ef 100755 --- a/Scripts/gadget.sh +++ b/Scripts/gadget.sh @@ -3,6 +3,13 @@ # "Using OTG mode on Raspberry Pi SBCs" # https://pip-assets.raspberrypi.com/categories/685-app-notes-guides-whitepapers/documents/RP-009276-WP/Using-OTG-mode-on-Raspberry-Pi-SBCs +# This script only works if you are running it as root +if [ $(id -u) -ne 0 ]; then + echo "Please run as root or use sudo" + exit 1 +fi + + # Is the dwc2 overlay installed? Nothing will work if it isn't. if lsmod | grep -q "dwc2"; then systemd-cat -t gadget.sh -p info echo "DWC2 module loaded, setting up OTG gadget serial and ethernet" From b43d1d67983705406f30be1706a5b476e6354bc2 Mon Sep 17 00:00:00 2001 From: Joseph Timothy Foley Date: Thu, 2 Jul 2026 16:13:20 +0000 Subject: [PATCH 13/14] added GPIO pinout document link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 42174c0..1d4160a 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Scripts and documentation for setting up a Raspberry Pi (Zero W 1 or 2) for use - [Starting on Raspberry Pi Zero](https://reykjavik.instructure.com/courses/6589/pages/starting-on-raspberry-pi-zero-w) ## References and Links +- [Sparkfun GPIO pinout](https://cdn.sparkfun.com/assets/learn_tutorials/6/7/6/PiZero_1.pdf) - [Guide to creating ssh keys](https://pimylifeup.com/raspberry-pi-ssh-keys/) Of note, this guide is a little dated as it suggests using RSA keys and many people are moving toward EDCSA keys. - [Raspberry Pi Connect](https://connect.raspberrypi.com) - [Setting up Raspberry Pi Connect](https://www.raspberrypi.com/documentation/services/connect.html) From aa83f5c957f3754b8bf9d8fad81edadcec628c3f Mon Sep 17 00:00:00 2001 From: "Joseph T. Foley" Date: Thu, 2 Jul 2026 16:56:44 +0000 Subject: [PATCH 14/14] got an LED to blink on GPIO18 --- lgpio/blink.py | 19 +++++++++++++++++++ lgpio/pwm-test.py | 25 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100755 lgpio/blink.py create mode 100755 lgpio/pwm-test.py diff --git a/lgpio/blink.py b/lgpio/blink.py new file mode 100755 index 0000000..7c6b782 --- /dev/null +++ b/lgpio/blink.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +# From https://raspberry.tips/en/raspberrypi-tutorials/raspberry-pi-gpio-python +import lgpio +import time + +# Open GPIO chip (0 = /dev/gpiochip0, on Pi 5 gpiochip4 also possible) +h = lgpio.gpiochip_open(0) + +try: + lgpio.gpio_claim_output(h, 18) # GPIO18 (pin 12) as output (MOTA1) + + for _ in range(5): + lgpio.gpio_write(h, 18, 1) # HIGH + time.sleep(0.5) + lgpio.gpio_write(h, 18, 0) # LOW + time.sleep(0.5) + +finally: + lgpio.gpiochip_close(h) # Always close! diff --git a/lgpio/pwm-test.py b/lgpio/pwm-test.py new file mode 100755 index 0000000..e44f005 --- /dev/null +++ b/lgpio/pwm-test.py @@ -0,0 +1,25 @@ +#!/usr/bin/python +# From https://raspberry.tips/en/raspberrypi-tutorials/raspberry-pi-gpio-python +import lgpio +import time + +# Open GPIO chip (0 = /dev/gpiochip0, on Pi 5 gpiochip4 also possible) +h = lgpio.gpiochip_open(0) + +try: + lgpio.gpio_claim_output(h, 16) # GPIO16 as output (MOTA2) + lgpio.gpio_write(h, 16, 0) # LOW + + # Hardware PWM on GPIO18 (pin 12) must be PWM-capable + # Frequency: 1000 Hz, duty cycle: 50% + lgpio.tx_pwm(h, 18, 1000, 50) + time.sleep(2) + + # Reduce duty cycle to 20% + lgpio.tx_pwm(h, 18, 1000, 20) + time.sleep(2) + + lgpio.tx_pwm(h, 18, 0, 0) # Stop PWM + +finally: + lgpio.gpiochip_close(h) # Always close!