Showing posts with label raspberrypi. Show all posts
Showing posts with label raspberrypi. Show all posts

Wednesday, February 05, 2025

PiZero OTG: Host or Peripheral

Background

An OTG (On-The-Go) device is a device that can act as both a host and a peripheral on a USB network. The PiZero is an OTG device. This guide pertains specifically to the PiZero and PiZero 2, but similar concepts also apply to other Raspberry Pi products (more information here).
Host mode
  • Used for connecting the PiZero to a USB peripheral, eg. USB keyboard, mouse, etc
  • PiZero is the OTG A device (supplying power to USB)
  • USB keyboard, mouse is the OTG B device
Peripheral mode
(a.k.a. device mode, gadget mode)
  • Used for connecting the PiZero to a host computer, eg. PC, phone
  • The host computer is the OTG A device (supplying power to USB)
  • PiZero is the OTG B device

Micro USB ports on the PiZero

There are two micro USB ports on the PiZero. There is only one micro USB data port (labeled USB), and it is capable of supporting OTG. The second micro USB port is used for power delivery and does not support OTG.

Controlling OTG mode

There are two methods to control whether the data port operates in host or peripheral mode.
  1. Cable method
  2. Software method

Cable method

The USB cable consists of one end being a USB Micro-B male and the other being a USB-A female.

Whether the data port operates as host or peripheral can be controlled with the type of USB cable used. A USB cable may or may not support OTG.
  • If the ID pin on the USB Micro-B is shorted to ground, PiZero operates in host mode (cable usually known as an OTG cable)
  • If the ID pin on the USB Micro-B is not shorted to ground (left floating), PiZero operates in peripheral mode

Software method

Specify the following setting in config.txt.
  • peripheral mode: dtoverly=dwc2,dr_mode=peripheral
  • host mode: dtoverly=dwc2,dr_mode=host
  • otg mode: dtoverly=dwc2,dr_mode=otg (default: forces the PiZero to follow the ID pin functions)

What if the cable method conflicts with the software method

TBD @thagrol suggested the following.
My experience is that when you force the mode to either host or peripheral the ID pin in the microUSB socket is ignored. It is only when you set dr_mode=otg or don't include dr_mode at all (because the default is otg) that the ID pin functions.

Checking the mode

Sunday, December 31, 2023

Pi Zero 2 W micro USB Journey

I've been using a RPi4 for running Pi-hole. The RPi4 is way overpowered for Pi-hole so I decided to switch to using the Pi Zero 2 W. The Pi Zero 2 supports WiFi but does not come with an ethernet port. WiFi works perfectly well for Pi-hole, but for personal reasons, I wanted to use ethernet instead. I've read many posts that setting up an ethernet USB dongle is as easy as plugging it in. I decided to purchase the TP-Link UE300, because a poster had given the thumbs up that the UE300 works on the Pi Zero 2 W. The UE300 has an USB A plug.

Through many attempts, I was more and more convincing myself that the USB (data) micro port on the Pi Zero 2 W was faulty. Some folks have floated this idea in the Raspberry Pi Forums. I eventually did find a solution, and I'm detailing my experience below.

Before I start, I am running thte lastest Raspberry Pi OS (64-bit) Lite for the Pi Zero 2 W installed using the Raspberry Pi Imager. I also want to mention that there are two USB micro ports on the Pi Zero 2 W. One is dedicated to providing only power while the second provides both power and data. Please ensure you are using the right port. 

I didn't have a USB A to micro USB adapter but had the parts on hand so I decided put together a DIY adapter. The wiring is pretty simple because the sequence of signals on the pins of the USB A aligned with the sequence of signals on the pins of the micro USB. The USB A has 4 pins while the micro USB has 5 pins. The extra pin on the micro USB is the ID pin which I first ignored (left floating) but will touch on later.

Attempt 1:

My first attempt invovled not using the ID pin. I wired up only the V, D-, D+, and G pins between the USB A and micro USB plugs. When I plugged in the UE300 adapter, I did not see the ethernet interface. I should mention that I also tried plugging in an USB keyboard and mouse but none showed any signs of functionality. I decided to dig into this issue and found a number of posts saying that I should use an OTG cable. OTG stands for "On the Go", and it's a special adapter that treats the Pi Zero as a host to the USB device that it is connected to (I do not know the full specifications of when an OTG cable is is needed).

Attempt 2:

My second attempt involved making an OTG cable. This is easily accomplished by shorting the ID pin and the G pin on the micro USB. Again, when I plugged in the UE300 adapter, I did not see the ethernet interface. It was now that I was starting to think whether the USB micro port was faulty given what I read from the Raspberry Pi Forums.

Validation:

I tried the UE300 adapter on a Windows machine and the machine recognized the adapter. I thought that perhaps the Raspberry Pi OS didn't support this adapter so I tried it on a RPi4 and it also recognized the adapter. At this point, I concluded that the UE300 was not misbehaving.

I needed a way to check if the micro USB data port was faulty. I learned that it was possible to connect the Pi Zero 2 W to a Windows machine by treating the Pi Zero W 2 as a OTG device. Don't confuse this concept with the OTG adapter mentioned above. The OTG concept here means that we can turn the Pi Zero 2 W into a OTG device which allows a connection to the Pi Zero 2 W using ethernet over USB. Anyway, I followed the instructions on the page below. Because the Pi Zero 2 W showed up as only a COM device on my Windows system, and I needed to install the RNDIS driver.

https://www.factoryforward.com/pi-zero-w-headless-setup-windows10-rndis-driver-issue-resolved/

After installing the driver, I was able to see the ethernet device and putty into the Pi Zero 2 W. This validated that the micro USB data port was functional.

Attempt 3:

Having validated the functionality of the UE300 and the Pi Zero 2 W's USB micro data port, I decided to look at the dmesg output on the Pi Zero 2 W when I plugged in the UE300.

[ 204.742680] Indeed it is in host mode hprt0 = 00021501
[ 204.952584] usb 1-1: new high-speed USB device number 2 using dwc_otg
[ 204.952825] Indeed it is in host mode hprt0 = 00001101
[ 205.162556] usb 1-1: device descriptor read/64, error -71
[ 205.282811] Indeed it is in host mode hprt0 = 00001101
[ 205.492506] usb 1-1: device descriptor read/64, error -71
[ 205.612548] Indeed it is in host mode hprt0 = 00001101
[ 205.822445] usb 1-1: new high-speed USB device number 3 using dwc_otg
[ 205.822743] Indeed it is in host mode hprt0 = 00001101
[ 206.032416] usb 1-1: device descriptor read/64, error -71
[ 206.152692] Indeed it is in host mode hprt0 = 00001101
[ 206.362359] usb 1-1: device descriptor read/64, error -71
[ 206.482400] usb usb1-port1: attempt power cycle

At least I was getting an indication when I plugged in the adapter. However, the highlighted text caught my attention. I googled this and came across several posts that offered different solutions. I tried them one by one. I'm not lisitng all of them but instead mentioning the one setting that worked for me. I'm convinced what setting you need is dependent on the USB peripheral that you are using.

For me, the solution was to add
"dwc_otg.speed=1" to /boot/cmdline.txt

There are more options described on this page.
https://raspberrypi.stackexchange.com/questions/1886/what-kernel-parameters-are-available-for-fixing-usb-problems

Upon booting, I now see this in dmesg.

[ 850.956370] Indeed it is in host mode hprt0 = 00021501
[ 851.166317] usb 1-1: new full-speed USB device number 3 using dwc_otg
[ 851.166517] Indeed it is in host mode hprt0 = 00021501
[ 851.406722] usb 1-1: not running at top speed; connect to a high speed hub
[ 851.407623] usb 1-1: New USB device found, idVendor=2357, idProduct=0601, bcdDevice=30.00
[ 851.407636] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=6
[ 851.407645] usb 1-1: Product: USB 10/100/1000 LAN
[ 851.407652] usb 1-1: Manufacturer: TP-Link
[ 851.407659] usb 1-1: SerialNumber: 000001
[ 851.413636] Indeed it is in host mode hprt0 = 00021501
[ 851.616299] usb 1-1: reset full-speed USB device number 3 using dwc_otg
[ 851.616444] Indeed it is in host mode hprt0 = 00021501

I should mention that I tried using the OTG micro USB adapter and non-OTG micro USB adapter, and both work flawlessly for the UE300. In my case, I did not need an OTG micro USB adapter for the UE300.

Summary:

I'm using a non-OTG micro USB adapter to connect the UE300 to the Pi Zero 2 W. I'm running the latest Raspberry Pi OS. I had to add "dwc_otg.speed=1" to /boot/cmdline.txt to get the OS to recognize the UE300. I am convinced that the OS for the Pi Zero 2 W requires tweaking for your peripherals to work. Don't assume your micro USB port is faulty.

Good luck.

Thursday, September 23, 2021

Power Raspberry Pi 4 over HDMI

I was setting up a new system. When I disconnected the USB-C power connector, the RPi4 retained its power from the HDMI cable.



Wednesday, October 21, 2020

Kiosk Setup on Raspbian

The following instructions document how to enable a kiosk setup on Raspbian with the following requirements.

  • utilize the lightweight Matchbox window manager
  • utilize the Chromium browser to render a webpage in fullscreen mode
  • remove the X cursor
  • turn off the display after 10 minutes of inactivity

Install the latest Raspbian Lite image. Note, this is the barebone image for server setup.

Install packages

apt install matchbox-window-manager xinit

Use raspi-config to enable auto login into the console with user pi

raspi-config

Add the following to the bottom of /home/pi/.bashrc.

if [ -z "${SSH_TTY}" ]; then
  exec startx /home/pi/startup.sh -- -nocursor
fi

Install a browser that can run fullscreen.

apt install chromium-browser -y

Create the file /home/pi/startup.sh.

#!/bin/sh

# Tweak the energy settings to your liking
xset dpms 0 0 600
xset s off

# Start the Matchbox window manager
matchbox-window-manager -use_cursor no -use_titlebar no &

# Start the web browser full screen
/usr/bin/chromium-browser --app=http://your-site \
  --kiosk \
  --noerrdialogs \
  --disable-session-crashed-bubble \
  --disable-infobars \
  --check-for-update-interval=604800 \
  --disable-pinch

Identifying IP of New Raspbian Host

Here's a handy command if you have an available linux system.

arp -a

Look for the hostname raspberrypi.

Wednesday, September 16, 2020

Raspberry Pi Audio Streaming Server

There are many prepackaged audio streaming servers available for the Raspberry Pi. Between Moode, Volumio, and piCorePlayer, piCorePlayer is very rich in its capabilities. It can access local media as well as a huge list of free online streaming content including TuneIn. piCorePlayer has also been the most stable where stable is defined to the quality of having a longer uptime. Although piCorePlayer is the most stable, I have occasionally encountered a loss of connectivity to the pi system (through the web interface and SSH). piCorePlayer also touts having a fast boot due to the use of Tiny Core Linux, but I experienced boot delays of greater than 30 seconds.

Granted that I could have spent time debugging why I lost connectivity and why boots took longer than 30 seconds, I decided to take another approach. Rather than using the prepackaged piCorePlayer which is convenient with its one-button push approach, I manually installed Logitech Media Server and Squeezelite player on Raspbian.

Here are some of the differences I see versus piCorePlayer.

  • I can access the LMS web interface using the hostname rather than the IP. ie. I don't need to assign a static IP to the server. See Resolve Linux Hostnames in Windows.
  • Booting the system takes less than <10 seconds.
  • The server has been rock solid.

Here are the steps for the setup.

Install Base Raspbian

Install the base Raspbian distribution. There are many instructions on the web on how to do this. If you want to be able to access LMS web interface using the host name, make sure you assign a host name to the system during setup.

Install Squeezelite

Install the Squeezelite package.

sudo apt-get install squeezelite

Identify the desired audio output device for Squeezelite.

squeezelite -l

Create a squeezelite service file.

sudo vi /etc/systemd/system/squeezelite.service

Paste the following contents into the file.

[Unit]
Description=Squeezelite

After=network.target

[Service]
ExecStart=/usr/bin/squeezelite -o hw:CARD=T1E,DEV=0 -n living_room -s 127.0.0.1

[Install]
WantedBy=multi-user.target

Here hw:CARD=T1E,DEV=0 is the name of the ALSA output device, living_room is the name assigned to the Squeezelite player, and 127.0.0.1 is the IP of the LMS server. Since Squeezelite and LMS will run on the same system, I'm using the loopback address.

Start the new service on boot.
sudo systemctl enable squeezelite.service

Install LMS

sudo apt-get install libio-socket-ssl-perl libnet-libidn-perl libnet-ssleay-perl perl-openssl-defaults
cd
mkdir lms
cd lms
wget http://downloads.slimdevices.com/nightly/8.0/lms/5949ad56255da8462b0e9f9fd6153acba5a7a7b3/logitechmediaserver_8.0.0~1600144351_all.deb
sudo dpkg -i 8.0.0~1600144351_all.deb

I'm running LMS 8.0 as of this writing.

Final Setup

Reboot your system.

sudo reboot

Point your web browser to the following URL.

http://<hostname or IP>:9000

Upgrading LMS

sudo dpkg -r logitechmediaserver
sudo dpkg -i logitechmediaserver_<xxx>_all.deb

References

Installation Instructions from John's Tech Blog
Installation Instructions from Winko Erades' Blog
Latest Squeezelite Builds

Friday, July 10, 2020

Raspberry Pi 4 4GB and USB Audio

There have been a number of reports of issues with USB on the Raspberry Pi 4. I am however encountering an USB audio-related issue that has not been described. I'm running Raspberry Pi OS (32-bit) Lite Version:May 2020. I've connected a USB speaker to the Pi. Sometimes when I play an audio file, aplay complains that it cannot open the audio device. In the terminal output below, you can see that the first two commands were successful but fails on the third. The state of audio system remains in this state indefinitely.

I have attempted the same exercise on the Raspberry Pi 3, and aplay never fails. If anyone has a solution, please let me know.

root@jazz:~# aplay piano2.wav
Playing WAVE 'piano2.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
root@jazz:~# alsamixer
root@jazz:~# aplay piano2.wav
Playing WAVE 'piano2.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
root@jazz:~# aplay piano2.wav
ALSA lib pcm_direct.c:1271:(snd1_pcm_direct_initialize_slave) unable to install hw params
ALSA lib pcm_dmix.c:1120:(snd_pcm_dmix_open) unable to initialize slave
aplay: main:828: audio open error: Broken pipe
root@jazz:~# aplay piano2.wav
ALSA lib pcm_direct.c:1271:(snd1_pcm_direct_initialize_slave) unable to install hw params
ALSA lib pcm_dmix.c:1120:(snd_pcm_dmix_open) unable to initialize slave
aplay: main:828: audio open error: Broken pipe

I have attempted using the Ubuntu Raspberry Pi OS as well as limiting the memory of the 4GB Pi to 3GB. None of these attempts were successful.