Project Started


Revised the design around a TCA8418 keypad scanner: all 20 diodes were removed, the 5×4 matrix now connects only to the scanner, and I²C, INT, RESET, decoupling, and required pull-ups were added. The potentiometer and latching-switch sections remain intact; ERC and legibility checks are clean.

Generated image

The project specification, firmware guide, and bring-up plan were also updated for the TCA8418 architecture. The next priority is reviewing the schematic before starting PCB placement.
I’ll inspect the board state first, determine whether placement, routing, or both are incomplete, then run the required auto-layout steps and validate the applied result.
Placement was required—the prior components were mostly off-board—and is now applied as a 5×4 key grid with grouped scanner, controls, and MCU. The board passed routing preflight, so full trace routing is now running.
Both placement and routing were needed.
  • Re-placed all 44 components inside the 160 × 100 mm, 4-layer board.
  • Arranged the 20 keys into a 5×4 grid and grouped the TCA8418, ESP32-S3, analog controls, latching switches, and support passives.
  • Cleared placement overlaps and out-of-bounds errors in the placement validation.
  • Generated 23 fine-pitch neckdowns for the TCA8418.
  • Routing preflight passed with only an informational via-at-SMD adjustment for the TCA8418 exposed pad.
  • Started auto-routing; the partially applied result currently has approximately 126 airwires remaining.
Routing is not complete. The existing auto-route job is paused and can be resumed without discarding its progress. Execution stopped because your ACUs ran out.

U1
S5
S6
S17
S15
S13
S8
S9
S1
S16
S7
S19
S4
S18
S11
S10
S20
S12
S2
S3
S14
R5
Resistance
10kΩ
R10
Resistance
10kΩ
R4
Resistance
10kΩ
C3
Capacitance
100nF
R8
Resistance
10kΩ
R14
Resistance
10kΩ
R12
Resistance
10kΩ
R3
Resistance
10kΩ
RV1
Resistance
10kΩ
R6
Resistance
10kΩ
U2
R15
Resistance
10kΩ
R7
Resistance
10kΩ
RV2
Resistance
10kΩ
C1
Capacitance
100nF
R13
Resistance
10kΩ
R1
Resistance
4.7kΩ
R2
Resistance
4.7kΩ
R11
Resistance
10kΩ
R9
Resistance
10kΩ
C2
Capacitance
100nF
SW22
SW21
Firmware Getting Started
Toolchain
Arduino-ESP32 or ESP-IDF targeting ESP32-S3-DevKitC-1.
Pin Mapping

Table


NetGPIOUse
ADC_POT11ADC input
ADC_POT22ADC input
I2C_SDA8TCA8418 SDA
I2C_SCL9TCA8418 SCL
KEYPAD_INT10active-low interrupt input
KEYPAD_RST11active-low reset output
LATCH113active-low input, external 10 kΩ pull-up
LATCH214active-low input, external 10 kΩ pull-up
Startup Sequence
  1. Hold KEYPAD_RST low for at least 120 us, release it high, and wait at least 120 us.
  2. Initialize I2C on I2C_SDA/I2C_SCL.
  3. Verify the TCA8418 responds, then configure ROW0–ROW4 and COL0–COL3 for keypad scanning.
  4. Configure the keypad debounce and event/interrupt registers.
  5. Configure GPIO10 for falling-edge or low-level interrupt handling.
  6. Initialize ADC_POT1/ADC_POT2 and LATCH1/LATCH2.
Keypad Behavior
  • U2 performs matrix scanning and debounce; ESP32 firmware must not directly scan ROW1..ROW5 or COL1..COL4.
  • KEYPAD_INT is active-low open-drain.
  • On interrupt, read the keypad event count/FIFO, process all queued press/release events, clear the interrupt condition according to the TCA8418 register procedure, and repeat if more events remain.
  • Maintain a 5×4 logical key map from TCA8418 row/column event codes to Stream Deck actions.
Arduino-Style Skeleton

Cpp


#include <Wire.h>

constexpr int PIN_SDA = 8;
constexpr int PIN_SCL = 9;
constexpr int PIN_INT = 10;
constexpr int PIN_RST = 11;
constexpr int PIN_POT1 = 1;
constexpr int PIN_POT2 = 2;
constexpr int PIN_LATCH1 = 13;
constexpr int PIN_LATCH2 = 14;

volatile bool keypadPending = false;
void IRAM_ATTR keypadISR() { keypadPending = true; }

void setup() {
  pinMode(PIN_RST, OUTPUT);
  digitalWrite(PIN_RST, LOW);
  delayMicroseconds(120);
  digitalWrite(PIN_RST, HIGH);
  delayMicroseconds(120);

  Wire.begin(PIN_SDA, PIN_SCL);
  pinMode(PIN_INT, INPUT);       // external pull-up fitted
  pinMode(PIN_LATCH1, INPUT);    // external pull-up fitted
  pinMode(PIN_LATCH2, INPUT);    // external pull-up fitted
  attachInterrupt(PIN_INT, keypadISR, FALLING);
  analogReadResolution(12);

  // Configure TCA8418 keypad rows/columns, debounce, FIFO and interrupt registers here.
}

void loop() {
  if (keypadPending) {
    keypadPending = false;
    // Drain TCA8418 key-event FIFO and clear its interrupt status.
  }
  int pot1 = analogRead(PIN_POT1);
  int pot2 = analogRead(PIN_POT2);
  bool latch1Closed = digitalRead(PIN_LATCH1) == LOW;
  bool latch2Closed = digitalRead(PIN_LATCH2) == LOW;
}
Use the selected TCA8418 driver library's named register constants rather than copying unverified numeric addresses into application code.
  • Toolchain

  • Pin Mapping

  • Startup Sequence

  • Keypad Behavior

  • Arduino-Style Skeleton