Assembly Manual

Oh My Ondas Hardware Prototype — March 2026 — Barcelona

Teensy 4.1 complete pin assignment

TEENSY 4.1 — COMPLETE PIN ASSIGNMENT — Pins 7, 8, 20, 21, 23 RESERVED by Audio Shield I2S

Before You Start

Confirm these counts. If anything is short, note it before beginning.

  • Slide pots 45mm (P4272): ordered 5 — confirm you have 5
  • Wire Kit 22AWG (P3174): check Adafruit box
  • Helping Third Hand (P291): check Adafruit box

Key Decisions

  1. Use Teensy built-in SD (SanDisk Ultra 32GB). Audio Shield SD slot unused.
  2. LCD is 2.8″ ILI9341 (P1770) — DMA-optimized ILI9341_t3 library.
  3. Dual I2C: Wire (18/19) audio-path, Wire1 (16/17) UI-polling.
  4. 4 main buttons direct to Teensy pins for latency + interrupts.
  5. ESP32-S2 powered from 5V, not Teensy 3.3V.

Tools

Soldering station 48W, solder 1mm, flux, 2× breadboard, jumper wires, helping hand, micro-USB cable, 3.5mm headphones.

1

Core Audio

GOAL: Hear a WAV file through headphones

Teensy 4.1Audio Shield Rev D2SD Card (32GB)Headphones
1.1 — Solder Audio Shield Headers

The Audio Shield Rev D2 stacks directly on top of the Teensy 4.1 via two rows of female headers. You need 2 × 14-pin female headers (cut from a 40-pin strip).

  1. Cut headers: Count 14 pins on the strip and cut with flush cutters. You need two 14-pin pieces. Cut on the 15th socket to avoid cracking pin 14.
  2. Insert headers into Teensy: Push the two 14-pin female headers onto the Teensy's outer male pin rows (the two long rows of pins along each edge). The headers sit on top of the Teensy, sockets facing up.
  3. Stack the Audio Shield on top: Place the Audio Shield board onto the headers so the shield's through-holes line up with all 28 header pins. The Audio Shield's 3.5mm jack should face the same end as the Teensy's USB port. The Teensy is your alignment jig — stacking before soldering guarantees all pins are straight and spaced correctly.
  4. Solder from the TOP of the Audio Shield: Flip the stack so the Audio Shield PCB is on the bottom. The header pins now poke through the Audio Shield's top surface. Solder each pin where it comes through the Audio Shield PCB. Do NOT solder anything to the Teensy itself.
  5. Technique: Heat the pad and pin together for 2 seconds, feed solder until it flows around the pin and wets the pad. Move to the next pin. Do corners first to lock alignment, then fill in the rest.
  6. Separate: After all 28 joints cool, gently pull the Audio Shield off the Teensy. Inspect every joint — look for bridges between adjacent pins and cold joints (dull/blobby). Reflow any bad joints.
The Audio Shield connects to the Teensy through these pins: I2S audio (7, 20, 21, 23), I2C control (18, 19 — SGTL5000 codec at 0x0A), and power (3.3V, GND, VIN). All of these are on the outer pin rows you just soldered. No extra wiring needed — the header connection carries everything.
If you've never soldered headers before: practice on a spare piece of perfboard first. The key mistakes are (1) not heating long enough so solder blobs instead of flowing, and (2) moving the board while the joint cools, creating a cold joint. PJRC has photos of the correct stack at pjrc.com/store/teensy3_audio.html.
1.2 — Prepare SD Card
  1. Format as FAT32 (not exFAT).
  2. Copy PJRC test WAV files to root.
  3. Insert into Teensy built-in slot (not Audio Shield slot).
1.3 — Stack and Connect
  1. Teensy into breadboard (spans center gap).
  2. Audio Shield on top via headers.
  3. Headphones into Audio Shield 3.5mm jack.
  4. USB to computer.
1.4 — Flash and Test
#define SDCARD_CS_PIN    BUILTIN_SDCARD
// DO NOT use pins 10/7/14 for SD
// Those are Audio Shield SD (unused)

Open WavFilePlayer example. Set CS pin as above. Upload. Serial Monitor 9600 baud.

If no sound: check Serial Monitor for “Unable to access SD card”. Verify FAT32 format, correct slot, headphone jack fully inserted.
✓ VALIDATION: Hear WAV audio through headphones
2

Touch Sensing

GOAL: Touch copper pads to trigger audio samples

CAP1188 BreakoutCopper Tape 5mm10KΩ Resistors ×2Jumper Wires
2.1 — Wire CAP1188 to I2C1
CAP1188 PinTeensy PinNotes
SDA17 (SDA1)Wire1 bus
SCL16 (SCL1)Wire1 bus
VIN3.3V
GNDGND
Wire1 has NO built-in pull-ups. Add 10KΩ from pin 17 to 3.3V and from pin 16 to 3.3V. (2.2K better — next Diotronic visit.)
2.2 — Make Touch Pads

Cut 8 pieces of copper tape (~20×20mm). Stick on cardboard in 2×4 grid, 5mm spacing. Solder wire to each. Connect to C1–C8.

2.3 — Test
Wire1.begin();
Adafruit_CAP1188 cap = Adafruit_CAP1188();
cap.begin(0x29, &Wire1);  // I2C1 at 0x29

Serial Monitor: touch each pad → see event. Then integrate: pad N triggers sample N via AudioPlaySdWav.

✓ VALIDATION: Touch each pad → hear different sample
3

Displays + LEDs

GOAL: OLED shows status, LCD shows UI, NeoPixels animate — audio still clean

SSD1306 OLED 0.96″ILI9341 2.8″ TFTWS2812B NeoPixel ×8470Ω Resistor
3.1 — Wire OLED
OLED PinTeensy PinBus
SDA18 (SDA0)Wire — shared with Audio Shield
SCL19 (SCL0)Wire
VCC3.3V
GNDGND

I2C scan on Wire should show: 0x0A (SGTL5000) + 0x3C (SSD1306).

3.2 — Wire ILI9341 LCD
LCD PinTeensy PinNotes
CLK13 (SCK)SPI clock
MOSI11SPI data out
MISO12SPI data in
CS10Chip select
DC9Data/Command
RST15Reset (NOT pin 8!)
LITE3.3VBacklight always on
3.3 — Wire NeoPixels

Data → pin 6 via 470Ω series resistor. VCC → 5V. GND → GND.

If audio glitches when NeoPixels update: switch to WS2812Serial library with a Serial TX pin.
✓ VALIDATION: OLED text + LCD graphics + NeoPixels animate — audio still clean
4

Analog Inputs

GOAL: Slide pots control parameters, smooth 0–26000 readings

ADS1115 16-bit ADCSlide Pots ×5100nF Caps ×5
4.1 — Wire ADS1115
ADS1115 PinTeensy PinNotes
SDA18 (SDA0)Shared I2C0 bus
SCL19 (SCL0)
VDD3.3V
GNDGND
ADDRGNDSets address to 0x48
4.2 — Wire Slide Pots

Each pot: Left → GND, Right → 3.3V, Wiper → ADS1115 A0–A3. Pot 5 wiper → Teensy pin 14 (A0).

Pots to 3.3V only! The ADS1115 and Teensy ADC are 3.3V max. 5V will damage them.

Add 100nF ceramic cap from each wiper to GND, close to the ADC input.

4.3 — Test
Adafruit_ADS1115 ads;
ads.begin(0x48, &Wire);
// ads.readADC_SingleEnded(0) ... sweep 0 to ~26000

If jumpy: check 100nF caps, keep wiper wires away from SPI lines.

✓ VALIDATION: All 5 faders sweep smoothly — no jitter
5

I/O Expansion

GOAL: Encoders rotate, buttons click, nav switch responds in all 5 directions

MCP23017 ×2DIP Sockets ×2EC11 Encoders ×7 Buttons ×45-Way Nav Switch100nF Caps ×2
5.1 — Wire 4 Direct Buttons
ButtonTeensy PinWiring
MODE2Button between pin and GND, INPUT_PULLUP
SHIFT3Same
REC4Same
PLAY5Same — Pressed=LOW, Released=HIGH
5.2 — Install MCP23017s into DIP Sockets

Watch the notch — pin 1 at the notch end. Both on I2C1 (16/17). #1 at 0x20 (A0/A1/A2 = GND). #2 at 0x21 (A0 = 3.3V). RESET pins → 3.3V. 100nF cap on each VDD–VSS.

5.3 — Wire Encoders

Each EC11: C (common) → GND, A + B → MCP GPIO, SW → MCP GPIO. Enable MCP internal pull-ups in firmware. 5 encoders on MCP#1, 2 on MCP#2.

5.4 — Wire 5-Way Nav

Common → GND. Up/Down/Left/Right/Select → MCP#2 GPIOs. Internal pull-ups.

✓ VALIDATION: 7 encoders rotate + click, 4 buttons respond, nav switch 5 directions
6

GPS

GOAL: Barcelona coordinates on the OLED

PA1010D GPS (STEMMA QT)
6.1 — Wire GPS
PA1010D PinTeensy PinNotes
SDA18 (SDA0)Shared I2C0
SCL19 (SCL0)
VIN3.3V
GNDGND
6.2 — Test GPS
Adafruit_GPS GPS(&Wire);
GPS.begin(0x10);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
Test outdoors or near a window. PA1010D built-in antenna needs sky view.
✓ VALIDATION: OLED shows Barcelona lat/lon and satellite count
7

WiFi Link

GOAL: ESP32 and Teensy communicate over UART

SparkFun ESP32-S2 Thing Plus
7.1 — Program ESP32 Separately First

Flash WiFi test via its own USB port before wiring to Teensy. Verify it connects to your network.

7.2 — Wire ESP32 to Teensy
ESP32 PinTeensy PinNotes
TX0 (RX1)ESP32 sends → Teensy receives
RX1 (TX1)Teensy sends → ESP32 receives
5V / VBUSVINShared 5V from USB
GNDGND
Do NOT connect ESP32 3.3V to Teensy 3.3V. Each board uses its own regulator.
7.3 — Test UART
// Teensy:
Serial1.begin(115200);
if (Serial1.available()) {
  String msg = Serial1.readStringUntil('\n');
  Serial.print("From ESP32: ");
  Serial.println(msg);
}
✓ VALIDATION: Teensy receives ESP32 messages — audio still clean
8

Full Integration

GOAL: Everything runs simultaneously — CPU <70%, no I2C errors, audio clean

Everything
Run health monitor in loop() — print CPU% and memory every 5 seconds. If CPU exceeds 70%, check which audio objects are running.
✓ VALIDATION: All 12 checks pass — prototype complete
I2C Bus Architecture

I2C BUS ARCHITECTURE — Wire (audio-path) and Wire1 (UI-polling, external pull-ups required)

Power Distribution

POWER DISTRIBUTION — USB 5V → Teensy LDO 3.3V (~60mA external) + ESP32-S2 (own regulator)

Bus Map — Final State

Wire — I2C0

Pins 18 (SDA), 19 (SCL)
SGTL5000 Audio Codec0x0A
PA1010D GPS0x10
SSD1306 OLED0x3C
ADS1115 ADC0x48

Wire1 — I2C1

Pins 16 (SCL1), 17 (SDA1) — 10K pull-ups required
MCP23017 #10x20
MCP23017 #20x21
CAP1188 Touch0x29

SPI

Pins 10 (CS), 11 (MOSI), 12 (MISO), 13 (SCK)
ILI9341 2.8″ LCDDC=9, RST=15

Audio Shield SD NOT used — Teensy SDIO instead

UART — Serial1

Pins 0 (RX1), 1 (TX1)
ESP32-S2 Thing Plus115200 baud

Next Diotronic Visit

  • 2.2KΩ resistors ×4 — replace 10K I2C1 pull-ups with proper values
  • 1KΩ resistors ×5 — RC filter series resistors for slide pots
  • 470Ω resistor ×1 — NeoPixel data line (check your assortment first)
  • EC11 rotary encoders ×6 — complete the 13-encoder interface

Parts Set Aside

  • KB2040 (P5302) — RP2040 keyboard MCU
  • RFM95W LoRa (P3072) — 900MHz radio, future device-to-device
  • USB-C Plug + Vertical Port (P5978, P5993) — enclosure phase
  • Backup Teensy 4.1 + Audio Shield — in the drawer