Files
linux-voice-assistant/examples/ReSpeaker 4mic HAT/DOCS.md
T
Omar Amin adcef575b7 Peripheral volume display (#411)
Adds the volume display effect to these boards that have LED Ring, when controlling the volume for LVA:

- Satellite 1 HAT Board

- ReSpeaker 4-Mic Array HAT

- ReSpeaker USB Mic Array v2.0

This animation appears on the LED ring temporarily to display an arc that sweeps clockwise when the volume increases and anti-clockwise when the volume decreases. Triggers by the volume_changed event.
2026-08-23 01:31:37 +03:00

9.8 KiB
Raw Blame History

ReSpeaker 4-Mic Array HAT

Peripheral controller for the ReSpeaker 4-Mic Array by Seeed Studio, running alongside the Linux Voice Assistant (LVA) container.

The controller runs as a separate Docker container on the same Raspberry Pi. It connects to LVA's peripheral WebSocket API and drives the 12-LED APA102 ring with animations that mirror the Home Assistant Voice PE LED behaviour.


Hardware

Component Details
Microphone array 4 × MEMS mics at board corners (AC108 codec, I2S)
LED ring 12 × APA102 RGB LEDs
Interface Raspberry Pi 40-pin HAT connector

Compatible hardware

Board Notes
Raspberry Pi Zero 2 W Recommended for compact builds
Raspberry Pi 3 B / B+ Fully supported
Raspberry Pi 4 B Fully supported
Raspberry Pi 5 Requires seeed-voicecard driver compatible with kernel 6.6+ — see Step 1

GPIO pin mapping

LED ring (APA102)

Signal GPIO (BCM) Notes
MOSI (data) GPIO 10 SPI0 MOSI
SCLK (clock) GPIO 11 SPI0 SCLK
CE (bus select) GPIO 7 (CE1) /dev/spidev0.1

LED ring animations

All animations mirror the Home Assistant Voice PE ESPHome firmware exactly.

LVA state Animation Description
No HA connection / not ready Red twinkle Random red sparkle across all LEDs
Idle Off All LEDs off
Wake word detected Slow clockwise spin Two trailing arcs at opposing positions
Listening Fast clockwise spin Same dual-arc pattern at 50 ms interval
Thinking Pulsing pair Two opposing LEDs fade in and out
TTS speaking Anticlockwise spin Dual-arc spin in reverse direction
Muted Solid ring + red indicators Full ring on; red at LEDs 1, 4, 7, 10 (mic corners)
Error Red pulse All LEDs red, pulsing
Timer ticking Countdown arc Arc proportional to seconds_left / total_seconds
Timer ringing Pulse + optional red Full ring pulsing; red at corners if muted
Volume changed Volume Display arc Temporary arc (2.5s) showing the current volume level, starting from LED 0 and sweeping clockwise
Volume muted Solid ring + red indicator Red at the bottom-mid LED

"User color" comes from the Home Assistant Light entity described below (default: HAVPE-style blue). HA brightness scales every animation in this table. Semantic colors (Waiting/Listening cyan spin, Thinking pulse, Replying anticlockwise, Muted solid + red, Timer pulse/arc, Error red pulse) are hardcoded so they remain recognisable across user customisation.

Mic indicator positions

The four mics sit at the corners of the square board. On the 12-LED ring (30° per step), the corners land at 45°, 135°, 225°, 315° → LEDs 1, 4, 7, 10.


Home Assistant Light entity

On connect the controller registers a Light entity with LVA, which appears in Home Assistant as light.leds. It defaults off, matching the Voice PE LED Ring; turn it on for a solid idle glow and set its RGB color and brightness from the device page.

Effects

Effect Behaviour
Voice Assistant (default) Run the pipeline animations from the table above. Waiting/Listening animations are tinted with the HA color; brightness scales every animation.

Like the Home Assistant Voice PE, this example exposes a single Voice Assistant effect: the pipeline animations always run and can't be switched off from HA. The peripheral protocol itself accepts any number of effects, so your own integration is free to declare more (a color loop, a static accent, and so on) — see the peripheral API docs.

Brightness, on/off, and color

Matching the HA Voice PE LED Ring, the Light defaults off, so the LEDs stay dark while idle until you turn it on; once on, idle shows the solid color, and turning it off again just removes that idle glow. The voice animations always run either way (on/off only gates the idle glow, it does not disable them), so the effect can't be switched off completely. Brightness scales linearly across every animation, and RGB color is the solid idle color and tints the Waiting/Listening animations.


Installation

Step 1 — Install the seeed-voicecard audio driver

This must be done on the host Raspberry Pi, not inside Docker.

git clone https://github.com/respeaker/seeed-voicecard
cd seeed-voicecard
sudo ./install.sh
sudo reboot

After rebooting, verify the microphone appears:

arecord -l
# Expected: card X: seeed4micvoicec [seeed-4mic-voicecard]

Note: The seeed-voicecard installer modifies /boot/firmware/config.txt automatically. Check the file after running install.sh — SPI may already be enabled.

Pi 5 note: The standard seeed-voicecard repository may not support the Pi 5 kernel (6.6+). Check the seeed-voicecard GitHub issues for a compatible branch or fork before proceeding.

Step 2 — Enable SPI in config.txt

If the seeed-voicecard installer did not already enable SPI, add to /boot/firmware/config.txt:

dtparam=spi=on

Reboot and verify:

ls /dev/spidev*
# Should show: /dev/spidev0.0  /dev/spidev0.1

Step 3 — Add user to GPIO and SPI groups

sudo usermod -aG gpio,spi $USER

Log out and back in. Check your UID:

id -u $USER

If it is not 1000, update the user: field in compose.yml to match.

Pi 5 note: On Pi 5, GPIO is exposed as /dev/gpiochip4 not /dev/gpiochip0. Update the devices mapping in compose.yml:

devices:
  - /dev/spidev0.1:/dev/spidev0.1
  - /dev/gpiochip4:/dev/gpiochip4

Step 4 — File structure

ReSpeaker 4mic HAT/
├── Dockerfile
├── compose.yml
├── requirements.txt
└── respeaker_4mic_hat.py

Step 5 — Build and start

docker compose up -d

Check logs:

docker compose logs -f

Option B — Run directly with Python

pip install -r requirements.txt
python respeaker_4mic_hat.py --host localhost --port 6055

Configuration

All configuration is at the top of respeaker_4mic_hat.py:

# LVA connection
DEFAULT_LVA_HOST = "localhost"
DEFAULT_LVA_PORT = 6055

# APA102 LED ring
LED_COUNT      = 12
SPI_BUS        = 0
SPI_DEVICE     = 1      # 1 = CE1 (/dev/spidev0.1), 0 = CE0 (/dev/spidev0.0)
LED_BRIGHTNESS = 10     # 0–31 (APA102 global brightness register)

# Default ring colour (R, G, B) — matches HA Voice PE default
DEFAULT_R, DEFAULT_G, DEFAULT_B = 24, 187, 242

Command-line arguments

Argument Default Description
--host localhost LVA container hostname or IP
--port 6055 LVA peripheral API port
--debug off Enable verbose debug logging

Drivers summary

Component Driver needed Where to install How
Microphone array (AC108) seeed-voicecard Host Pi git clone + sudo ./install.sh, then reboot
LED ring (APA102) SPI overlay Host Pi dtparam=spi=on in config.txt, then reboot

Troubleshooting

Microphone not detected by LVA

  1. Confirm arecord -l shows seeed-4mic-voicecard on the host.
  2. If not, re-run sudo ./install.sh from the seeed-voicecard repository and reboot.
  3. On Raspberry Pi 5 with kernel 6.6+, check the seeed-voicecard GitHub issues for a compatible branch.

LEDs do not light up

  1. Confirm dtparam=spi=on is in /boot/firmware/config.txt and the Pi has been rebooted.
  2. Check /dev/spidev0.1 exists: ls /dev/spidev*. If only spidev0.0 exists, change SPI_DEVICE = 0 in the script and update the device mapping in compose.yml to /dev/spidev0.0.
  3. Confirm the container user is in the spi group: groups $USER.
  4. Run with --debug and look for APA102 LED ring initialised in the logs.

SPI and seeed-voicecard conflict

The seeed-voicecard driver uses I2S — it does not use SPI — so there is no conflict with the APA102 LED ring. Both can run simultaneously without any special configuration.

LVA not reachable

  1. Confirm LVA is running and port 6055 is open: nc -zv localhost 6055.
  2. With network_mode: host, localhost resolves to the Pi itself.
  3. If LVA runs in a separate Docker network, use its container IP or service name as --host.