Wiring and ear configuration¶
Wiring¶
Both the original Atom Matrix and v1.1 official pin maps assign:
| Signal | GPIO / Grove wire |
|---|---|
| Left ear DIN | GPIO26, yellow |
| Right ear DIN | GPIO32, white |
| Common ground | black |
| 5 V | red; distribute strip power directly from the external supply |
| Onboard 25-pixel matrix | GPIO27; explicitly cleared then held low |
| Front button | GPIO39, active low; board pull-up |
| MPU6886 I2C | SCL GPIO21, SDA GPIO25; address 0x68 |
| IR, reserved | GPIO12 |
GPIO26 and GPIO32 are independent outputs and don't overlap matrix/button/IMU resources on either documented Matrix revision. Confirm connector labels and actual cable pinout before soldering; documentation verification doesn't establish the physical wiring. Data goes to DIN, following the strip arrows. The two ears are not daisy-chained.
The AtomS3 Lite profile uses the same Grove cable positions: left ear on GPIO2 / yellow, right ear on GPIO1 / white, with red/black still 5 V/GND. Its external IMU uses rear-header GPIO5 SDA / GPIO6 SCL. Select the driver for the actual breakout in menuconfig. Existing generated S3 configurations retain the previous GPIO5/6 LED and GPIO2/1 IMU values until changed through menuconfig.
The AtomS3R uses the same Grove ear cable: left GPIO2/yellow, right GPIO1/white.
Its onboard BMI270 uses a separate internal bus, SDA45/SCL0, at address 0x68;
no external IMU wiring is required. Select atoms3r-normal, not the Lite preset.
See the S3R pin/resource map.
Use external regulated 5 V with a direct distribution path to the ears and controller, and common ground. Don't route the full strip load through the Atom PCB/Grove connector. The first prototype can try short 3.3 V data wires; if unreliable at 5 V strip power, add a 74AHCT/74HCT level shifter. GPIOs/animation code don't depend on its presence. Don't tie two independent 5 V sources together without planning their power path; choose the physical USB/programming/power arrangement before final assembly.
The onboard matrix shares its daughterboard with the MPU6886, so it remains powered.
board_matrix_off() transmits 25 black pixels before freeing its temporary RMT channel,
then drives GPIO27 low. It stays dark but still draws idle current.
Counts, direction, order, brightness¶
idf.py menuconfig
Open Espurr cat ears. Initial settings:
| Setting | Default |
|---|---|
| Left / right pixel count | 18 / 18, independent, range 0–64 |
| Left / right reverse | off / off for v1; fixed mapping for v2 |
| Left / right RGB wire order | off / off, meaning GRB |
| Brightness | 20% control = 20% PWM, range 0–100% |
| Estimated current budget, both ears | 250 mA, excludes controller/matrix |
| AP password | empty; set privately in local menuconfig |
Logical index 0 = short-edge baseline, then up the short edge, through the tip, and down to count−1 = long-edge baseline. The Long edge setting still counts the long edge: 12 for the 18-pixel assembly, leaving 6 short-edge pixels. Zero selects a straight strip. V1 defaults to both outputs unreversed; its optional reverse switch maps the rendered frame onto a long-edge-fed strip. V2 uses fixed component/chain mapping with no reverse switch. JSON settings schema 22 migrates explicit saved split-ear directions once; see the layout contract. Saved direction settings remain authoritative: check these and physical left/right identity after upgrading. Every palette runs once up the short edge and down the long edge, without mirroring at the tip. Liquid light still uses height for its fill; the comet travels along the outline. Physical reversal stays in the output layer.
Use the actual number of pixels, not LED density or strip length. A count of 0 disables that output. The current assembly has 18 pixels per ear: 6 up the short edge and 12 down the long edge. Runtime reconfiguration clears its old full configured length before shrinking/disabling/recreating the strip. If the physical strip is longer than the configured count, unaddressed tail pixels can retain older colours. Configure the full connected count, and power-cycle when disconnecting/disabling an output.
If labelled red appears green, change that ear's RGB-order option in the UI. Firmware supports RGB and GRB; if the physical strip needs another permutation, record the observed primary sequence before changing the driver configuration.
Save menuconfig, then idf.py build and flash. These values seed defaults; validated
NVS settings override them after first use. Pixel counts, long-edge counts, direction, wire order and
brightness can all change live through the UI without rebuilding. Put intentional assembly defaults in
sdkconfig.defaults after confirming them physically. Existing generated sdkconfig
values override defaults, so use menuconfig to change an already configured build.