Tuesday, 18 November 2025

Connecting Raspberry Pi 4B using USB to a Windows laptop

This guide provides a comprehensive, step-by-step process for flashing your SD card, editing the necessary configuration files on your Windows 11 PC, configuring Internet Connection Sharing (ICS), and connecting to your Raspberry Pi 4B (RPi4B) using a USB-C to USB-C cable.

## 1\. 🖥️ Prepare the SD Card on Windows 11

### Step 1: Flash the SD Card with Raspberry Pi Imager

1.  Download and install the *Raspberry Pi Imager* tool on your Windows 11 PC.
2.  Insert your microSD card into your PC's card reader.
3.  Launch Raspberry Pi Imager.
4.  Click *"Choose OS"* and select the latest *Raspberry Pi OS (64-bit)* or the version you prefer.
5.  Click *"Choose Storage"* and select your microSD card.
6.  *Crucially:* Press *Ctrl+Shift+X* (or click the gear icon in newer versions) to open the *Advanced Options* menu.
7.  In the Advanced Options, configure your desired *Hostname* (e.g., myraspi), set a *Username and Password, and enable **SSH*. This ensures the Pi is ready for headless access.
8.  Click *"Write"* and wait for the process to complete.


## 2\. ⚙️ Edit Configuration Files for Gadget Mode

After flashing, the Imager will eject the SD card. You may need to remove it and re-insert it into your PC to make the boot partition accessible.

### Step 1: Locate the Boot Partition

On Windows 11, only the small, FAT-formatted *Boot partition* of the SD card will be visible. It will appear as a drive letter (e.g., E:\).

### Step 2: Modify config.txt

1.  Open the file config.txt located in the root of the Boot partition (e.g., E:\config.txt).

2.  Add the following line to the end of the file to enable the USB gadget driver:

    dtoverlay=dwc2

### Step 3: Modify cmdline.txt

1.  Open the file cmdline.txt located in the root of the Boot partition (e.g., E:\cmdline.txt).

2.  The file contains a single, long line of text. *Append* the following text to the *end of that single line*, ensuring there is a single space before it:

    modules-load=dwc2,g_ether

3.  *Save* both files and safely *eject* the SD card from your Windows PC.


## 3\. 🔌 Windows 11 & Pi Connection Setup

### Step 1: Boot the Raspberry Pi and Connect

1.  Insert the prepared SD card into your RPi4B.

2.  Connect the *USB-C to USB-C cable* between the *RPi4B's USB-C power/data port* (not the display ports) and your Windows 11 laptop's USB-C port.

3.  The RPi will boot up and be recognized by Windows as a new device.

### Step 2: Optional Driver Installation (If Needed) ⚠️

If the Raspberry Pi adapter appears in Device Manager with a *yellow exclamation mark* (often under "Other devices"), manually assign the *Remote NDIS Compatible Device* driver:

1.  Open *Device Manager* (search for it in the Start Menu).
2.  *Right-click* on the unknown device and select *Update driver*.
3.  Select *Browse my computer for drivers*.
4.  Select *Let me pick from a list of available drivers on my computer*.
5.  Select *Network adapters, click **Next*.
6.  Select *Microsoft* as the Manufacturer and *Remote NDIS Compatible Device* as the Model.
7.  Click *Next* to install the driver.

### Step 3: Enable Internet Connection Sharing (ICS)

ICS automatically enables a DHCP server and provides the RPi with an IP address (in the 192.168.137.x range).

1.  Press *Windows Key + R, type ncpa.cpl, and press **Enter* to open *Network Connections*.
2.  Identify your adapters:
      * *Internet Adapter:* Your *Wi-Fi* connection (the one with internet access).
      * *RPi Adapter:* The new adapter, usually the *Remote NDIS based Internet Sharing Device*.
3.  *Right-click* on your *Internet Adapter* (Wi-Fi) and select *Properties*.
4.  Go to the *Sharing* tab.
5.  Check the box: *"Allow other network users to connect through this computer's Internet connection."*
6.  In the dropdown, select the *RPi Adapter*.
7.  Click *OK. Windows sets the RPi Adapter's IP to **192.168.137.1*.


## 4\. 🔑 SSH Connection

The Pi will automatically receive an IP address from Windows ICS.

Use ssh to access Raspberry Pi 4B:

1.  Open *Command Prompt* or *PowerShell* on Windows 11.
2.  Run the command:

ssh <username>@<hostname>.local

If this fails to determine the dynamic IP address alternatively  you can use this method:

### Step 1: Determine the Pi's Dynamic IP

1.  Open *Command Prompt* or *PowerShell* on Windows 11.
2.  Run the command:
    arp -a
3.  Look for the interface with the IP address *192.168.137.1* (your laptop's side).
4.  Scan the entries under that interface for another IP address in the *192.168.137.x* range (e.g., 192.168.137.100) that has a *Dynamic* type. This is the *Raspberry Pi's IP*.

### Step 2: Connect via SSH

Use the IP address you found in Step 1, along with the username you set in the Imager:

ssh <username>@<dynamic_ip_address>
(e.g., ssh pi@192.168.137.100)

You are now connected to your Raspberry Pi 4B and have internet access through your laptop.

Compiling and inserting wifi driver

Download and burn on a Raspberry Pi 3/4

https://downloads.raspberrypi.org/raspios_armhf/images/raspios_armhf-2021-05-28/2021-05-

07-raspios-buster-armhf.zip

Update, upgrade, reboot Raspberry Pi 3/4 using wired Ethernet (kernel version is 5.10.103-v7l+)

Blacklist onboard wifi driver

sudo nano /etc/modprobe.d/blacklist-wifi.conf
blacklist brcmfmac
blacklist brcmutil
sudo update-initramfs -u
sudo reboot

Download driver source code into home on Raspberry Pi

rtl8852BU_rtl8832BU_WiFi_linux_v1.19.21-68-gd16563cf8.20250603.tar.gz

Install kernel headers, extract source code and compile driver

sudo apt install raspberrypi-kernel-headers
tar -zxvf rtl8852BU_rtl8832BU_WiFi_linux_v1.19.21-68-gd16563cf8.20250603.tar.gz
cd rtl8852BU_rtl8832BU_WiFi_linux_v1.19.21-68-gd16563cf8.20250603
sudo make KSRC=/lib/modules/$(uname -r)/build ARCH=arm

Observe kernel object 8852bu.ko created.

To automatically load driver with default configuration

sudo mkdir -p /lib/modules/$(uname -r)/kernel/drivers/net/wireless/realtek/rtl8852bu
sudo cp 8852bu.ko /lib/modules/$(uname -r)/kernel/drivers/net/wireless/realtek/rtl8852bu/
sudo depmod -a
sudo reboot

Now insert USB wifi dongle and observe wlan0.

Configure wpa_supplicant to connect to the network.

To stream from command line you can use:

streamlink http://live.onetv-preprod.one.hu/123456789/vxfmt=dp/manifest.mpd?
device_profile=DASH_STB_CLR_LIVE_HD best &

Saturday, 1 March 2025

Raspberry Pi Imager on Chrome OS

Unfortunately the AppImages from the original github repository of Raspberry Pi Imager does not work for me on the Linux subsystem Crostini of my ARM64 Chrome OS laptop.

Fortunately precompiled arm64 deb packages of Raspberry Pi Imager that works under Linux subsystem Crostini in Chrome OS can be found in this archive:

https://archive.raspberrypi.org/debian/pool/main/r/rpi-imager/

USB drive in Chrome OS can be switched to Linux subsystem Crostini in Settings/About Chrome OS/Linux development environment/Manage USB devices

UPDATE: amd64 deb package can be found here:

https://github.com/raspberrypi/rpi-imager/releases

Saturday, 27 July 2024

USB HID gadget with Raspberry Pi OS

For some reason the wifi on my PiKVM installation on my Raspberry Pi Zero 2 W described in my previous post has become unstable. Also keeping underlying Arch Linux updated with my ansible update script is a challenge due to PiKVM keeps file system read-only by default. To solve both issues I moved USB HID gadget functionality to Raspberry Pi OS. Started with flashing latest Bookworm 64 bit Lite version to my Raspberry Pi Zero 2 W. I broadly used the configuration in this post.

jordana@pi02w2:~ $ sudo nano /boot/firmware/config.txt
dtoverlay=dwc2,dr_mode=peripheral
jordana@pi02w:~ $ sudo nano /boot/firmware/cmdline.txt
modules-load=dwc2,g_hid rootwait
jordana@pi02w2:~ $ sudo nano /etc/modules
dwc2
libcomposite
jordana@pi02w2:~ $ sudo nano /usr/bin/hid_keyboard_setup.sh
#!/bin/bash
cd /sys/kernel/config/usb_gadget/
mkdir -p g1
cd g1
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice
echo 0x0200 > bcdUSB
mkdir -p strings/0x409
echo "0123456789" > strings/0x409/serialnumber
echo "Raspberry Pi" > strings/0x409/manufacturer
echo "Pi Zero Keyboard" > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
echo "Config 1: HID Keyboard" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower
mkdir -p functions/hid.usb0
echo 1 > functions/hid.usb0/protocol
echo 1 > functions/hid.usb0/subclass
echo 8 > functions/hid.usb0/report_length
echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.usb0/report_desc
ln -s functions/hid.usb0 configs/c.1/
ls /sys/class/udc > UDC
jordana@pi02w2:~ $ sudo chmod +x /usr/bin/hid_keyboard_setup.sh
jordana@pi02w2:~ $ sudo nano /etc/rc.local
/usr/bin/hid_keyboard_setup.sh

I added the script with support for 0-9 numeric keys, arrow keys and mapped Enter and Esc for remotely driving UI on a STB that support USB HID keyboard to my git repository here.

UPDATE

Configuration above have been updated that supports Raspberry Pi 4 also with its OTG capability on its USB-C port. In order to connect Raspberry Pi 4 to a low power USB 2.0 keyboard port I had to provide power via GPIO. Pimoroni has a nice solution for this here

Monday, 22 July 2024

Low latency WebRTC streaming from HDMI source via zerotier

In order to achieve low latency WebRTC streaming over the Internet I found MediaMTX.

I installed it on my Raspberry Pi 4 on latest 64 bit Bookworm image as follows.

jordana@pi4g:~ $ mkdir mediamtx && cd mediamtx
jordana@pi4g:~/mediamtx $ wget https://github.com/bluenviron/mediamtx/releases/download/v1.8.4/mediamtx_v1.8.4_linux_arm64v8.tar.gz
jordana@pi4g:~/mediamtx $ tar -xvzf mediamtx_v1.8.4_linux_arm64v8.tar.gz 
jordana@pi4g:~/mediamtx $ nano mediamtx.yml
webrtcIPsFromInterfaces: no
webrtcAdditionalHosts: [zerotier_IP_of_Raspberry]
paths:
  cam:
    runOnInit: ffmpeg -f v4l2 -pix_fmt yuv420p -s:v 1280x720 -i /dev/video0 -f alsa -i hw:3,0 -filter:v fps=50 -c:v libx264 -c:a libopus -async 50 -preset ultrafast -tune zerolatency -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH
    runOnInitRestart: yes
jordana@pi4g:~/mediamtx $ ./mediamtx 

In order to find out the audio configuration hw:[card],[device] of the USB capture device I used arecord tool.

jordana@pi4g:~ $ arecord -l
**** List of CAPTURE Hardware Devices ****
card 3: MS2109 [MS2109], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

To stream WebRTC from the other side of a zerotier connection I simply had to use a browser to load this URL.

http://zerotier_IP_of_Raspberry:8889/cam/

I had to use Chromium from Crostini to have a stream within a minute but once it is up&running the latency and quality is fantastic!

UPDATE

After a few days of working stable the need arose to make a service out of it as described in the MediaMTX GitHub.

jordana@pi4g:~/mediamtx $ sudo mv mediamtx /usr/local/bin/
jordana@pi4g:~/mediamtx $ sudo mv mediamtx.yml /usr/local/etc/
jordana@pi4g:~ $ sudo tee /etc/systemd/system/mediamtx.service >/dev/null << EOF
[Unit]
Wants=network.target
[Service]
ExecStart=/usr/local/bin/mediamtx /usr/local/etc/mediamtx.yml
[Install]
WantedBy=multi-user.target
EOF
jordana@pi4g:~ $ sudo systemctl daemon-reload
jordana@pi4g:~ $ sudo systemctl enable mediamtx
jordana@pi4g:~ $ sudo systemctl start mediamtx

Sunday, 14 July 2024

Finally playing with OBS an Pi KVM

I have heard about OBS several times before and I always wanted to try it. Recently I got asked by a developer to use OBS to provide remote access to an HDMI signal. I am a happy user of a cheap HDMI to USB capture card for a long time but so far I have only used it with Camera application running directly on Android or ChromeOS host where it was connected to. Fortunately OBS is supported by Raspberry Pi OS:

jordana@pi4g:~ $ apt search obs-studio
Sorting... Done
Full Text Search... Done
obs-studio/stable,now 29.0.2+dfsg-1+b1 arm64
  recorder and streamer for live video content

Here came the first issue by launching OBS I bumped into this error message:

It did not take too long to find that we need an environmental variable to set on Raspberry Pi 4 and Raspberry Pi 5 so from command line it looks like this:

jordana@pi4g:~ $ LIBGL_ALWAYS_SOFTWARE=1 obs
jordana@pi5g:~ $ MESA_GL_VERSION_OVERRIDE=3.3 obs

I have bought a new HDMI capture card for this excersize from Amazon. To make it work, I only had to add it as a v4l2 video capture device as source and restart OBS. As during first time install OBS asked for a stream key I created an account on Twitch to get a stream key. Streaming via Twitch was also working more or less - althought I had to reduce framerate and resolution and it remained barely watchable. I guess the Raspberry Pi 4 with software only encoding is struggling with Motion JPEG source from the HDMI capture card. The delay was also excessive for the use case I had hence ultimately I will not use OBS let alone streaming but it was definitely a nice encounter with OBS.

Another ask from the developer was how to extend IR remote control over the network. While I am still playing with the idea there was a nice workaround possible to extend USB keyboard over the network. After some research, it turned out that OTG functionality in Linux have a usb gadget mode that does exactly what I need here. After a couple of unsuccessful tries I found this DIY PiKVM v2 in this github repository. As I have a couple of spare pi02w that supports OTG functionality and I only needed keyboard functionality I flashed the corresponding image on an SD card and added wifi password to pikvm.txt in PIBOOT partition. Please note that I did not have to escape \ in my Wifi password as in the guide for whatever the reason is. The nice feature of a pi02w is that its power consumption during light use largely remains below 5V/500mA standard USB 2 specification hence it can be a direct substitution of a USB keyboard where pi02w is only powered via the USB port itself. I have also added remote Tailscale access for this Pi KVM project that is beautifully integrated on my Chromebook with an Android app as such can nicely co-exist with Zerotier installation in the Linux subsystem Crostini.

UPDATE

After a while I started to have instable wifi connection to my Pi Zero 2 W. I added the following one line pikvm.txt to PIBOOT:

ENABLE_OTG_SERIAL=1

This way I could connect from a Pi 4 as follows:

jordana@pi4g:~ $ minicom --device /dev/ttyACM0 --baudrate 115200

Adding one line to this config file resolved my connection issue:

[root@pikvm ~]# vi /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
network={
    ssid="broadcom"
    psk=*************
    key_mgmt=WPA-PSK-SHA256
}








Monday, 25 December 2023

Raspberry Pi OS moves to Network Manager

There has been a major change on network configuration coming on Raspberry Pi OS for quite some time now. Along with the introduction of Debian Bookworm, the old dhcpcd has been replaced with Network Manager. This changes the way how I connect back to my parents that requires new configuration. Some of the configuration is similar to that of Inovato's Quadra that I used during the Raspberry Pi shortage.

To demonstrate the configuration here I used my 4GB Raspberry Pi 4 for which Imager 1.8.3 recommends Raspberry Pi OS 64-bit based on Debian Bookworm now. While this image includes desktop, I still prefer to use text based user interface to configure Network Manager. Please note the elegant way 5GHz is used hence higher speed and less interference.

jordana@pi4g:~ $ sudo nmtui
Edit a connection
<Add>
Device wlan0
SSID broadcom
Mode <Access Point>
Channel <A (5 GHz)>
Security 
<WPA & WPA2 Personal>
Password ********************
IPv4 CONFIGURATION <Shared>
<Show>
Addresses 192.168.3.1/24
<OK>
<Back>
Quit

This configuration automatically sets up DHCP on the access point with dnsmasq built into Network Manager hence separate dnsmasq should not be installed from apt package repository. However we will need to use Google DNS server as DHCP option hence we need to add a configuration file for that.

jordana@pi4g:~ $ sudo nano /etc/NetworkManager/dnsmasq-shared.d/server.conf
dhcp-option=6,8.8.8.8

Text based user interface does not allow setting the necessary IPv4 routing rules so for that I need to use command line interface of Network Manager. First we need to check UUID for the connection created above on wlan0 device.

jordana@pi4g:~ $ nmcli connection
NAME                UUID           TYPE      DEVICE     
Wi-Fi connection 1  6a55d164-xxxx  wifi      wlan0      
jordana@pi4g:~ $ sudo nmcli connection modify 6a55d164-xxxx ipv4.routing-rules "priority 1 from 192.168.3.0/24 table 1"

Next we need to install zerotier and set up its IP address and authorization on Zerotier Central web console to get the interface and IP address we want.

jordana@pi4g:~ $ ip a
4: zt5u4vfg76: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 2800 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    inet 192.168.193.3/24 brd 192.168.193.255 scope global zt5u4vfg76

Finally, after setting up Managed Routes 192.168.3.0/24 via 192.168.193.3 on Zerotier Central web console we need to dispatch default route towards my parents Raspberry Pi.

jordana@pi4g:~ $ sudo nano /etc/NetworkManager/dispatcher.d/10-zt5u4vfg76-up
#!/bin/bash
if [ "$1" = "zt5u4vfg76" ] && [ "$2" = "up" ]; then
  sudo /sbin/ip route add default via 192.168.193.4 table 1
fi
jordana@pi4g:~ $ sudo chmod +x /etc/NetworkManager/dispatcher.d/10-zt5u4vfg76-up

My friend struggled with the automatic choice of TKIP by Network Manager and needed the following configuration to make it work with iPad:

sudo nmcli con modify "Wi-Fi Hot" 802-11-wireless-security.proto rsn
sudo nmcli con modify "Wi-Fi Hot" 802-11-wireless-security.pairwise ccmp

UPDATE

Even though Network Manager takes care about MASQUERADE I realised that I still need this iptables rule to ensure zerotier-cli can access zerotier service locally.

quadra@inovato:~$ sudo iptables -t nat -I POSTROUTING -o lo -j ACCEPT
quadra@inovato:~$ sudo iptables-save -f /etc/iptables.rules
quadra@inovato:~$ sudo nano /etc/rc.local
iptables-restore /etc/iptables.rules