Electronics & Microcontrollers
Full electronics documentation for the 737 MAX build — ESP32 wiring, encoder debouncing, LED backlighting, and simulator integration.
Architecture Overview
Every input in this cockpit connects through a chain of ESP32 hardware, MobiFlight firmware, and SimConnect events:
Physical Input
→ ESP32
→ USB HID / Serial
→ MobiFlight Connector (PC)
→ SimConnect API
→ MSFS 2024
Outputs (LED states, display values) flow in reverse — the simulator writes variables, MobiFlight reads them, and Arduinos drive the LEDs or displays accordingly.
Arduino Selection
Arduino Mega 2560 is the workhorse of this build. Each MCP, overhead panel zone, and pedestal section gets its own Mega.
Why Mega over Uno or Nano:
| Feature | Arduino Uno | Arduino Mega |
|---|---|---|
| Digital I/O pins | 14 | 54 |
| Analog inputs | 6 | 16 |
| Hardware serial ports | 1 | 4 |
| Flash memory | 32 KB | 256 KB |
| Cost (AliExpress) | ~€3 | ~€7 |
With 54 digital I/O pins, a single Mega can handle an entire panel zone without the complexity of I²C multiplexers (though those are used for the overhead panel — see below).
MCP Wiring
Switch Matrix
Toggle switches and momentary buttons are wired in a matrix to save pins. A 6×8 matrix handles 48 switches using only 14 pins.
C0 C1 C2 C3 C4 C5 C6 C7
R0 [SW1] [SW2] [SW3] [SW4] [SW5] [SW6] [SW7] [SW8]
R1 [SW9] ...
R2 ...
R3 ...
R4 ...
R5 ...
MobiFlight handles matrix scanning natively — configure it in the firmware editor, no custom code needed.
Rotary Encoders
Encoders (Bourns PEC11R) use 2 digital pins each plus a common ground. For the MCP, 6 encoders are wired to pins 22–33 on the Mega:
// MobiFlight encoder pin assignment (MCP)
// Defined in MobiFlight firmware config, not in sketch directly
// HDG encoder → pins 22, 23
// SPD encoder → pins 24, 25
// ALT encoder → pins 26, 27
// VS encoder → pins 28, 29
// CRS1 encoder → pins 30, 31
// CRS2 encoder → pins 32, 33
Debouncing: MobiFlight handles software debouncing. For electrically noisy environments, add a 100nF capacitor between each encoder pin and GND.
7-Segment Displays
The MCP altitude, speed, heading, and VS readouts use TM1637 4-digit displays:
// TM1637 display wiring (MCP altitude display)
// CLK → Pin 40
// DIO → Pin 41
// VCC → 5V
// GND → GND
MobiFlight supports TM1637 natively — add it as an output device and bind it to AUTOPILOT_ALTITUDE_LOCK_VAR.
Backlighting System
LED Architecture
The backlight system uses two types of LEDs:
- WS2812B addressable LEDs — for panel flood lighting and RGB annunciators
- Individual 3mm warm-white LEDs — for through-legend backlighting on the acrylic overlay
WS2812B strips are driven by a single data pin using the FastLED library. All strips are on a shared 5V / 3A supply, separate from the Arduino's USB power.
// FastLED setup (panel backlight)
#include <FastLED.h>
#define LED_PIN 6
#define NUM_LEDS 48
#define BRIGHTNESS 80 // 0–255, tune for panel brightness
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
void setup() {
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
// Warm white for instrument panel feel
fill_solid(leds, NUM_LEDS, CRGB(255, 200, 120));
FastLED.show();
}
Tip: Real 737 MAX panel lighting is a warm amber-white at around 2700K.
CRGB(255, 200, 120)is a close approximation with WS2812B LEDs.
Annunciator LEDs
Warning and status annunciators use individual 3mm LEDs wired through 330Ω current-limiting resistors:
Arduino Pin → 330Ω Resistor → LED Anode → LED Cathode → GND
MobiFlight reads AUTOPILOT_MASTER and similar variables and writes HIGH/LOW to the corresponding LED pin.
Overhead Panel — I²C Multiplexing
The overhead panel has over 200 switches — far too many for a single Mega. The solution is PCF8574 I²C GPIO expanders, each adding 8 inputs on a shared 2-wire bus.
Arduino Mega SDA (pin 20) ─────┬──────────────────────
Arduino Mega SCL (pin 21) ─────┼─┬────────────────────
│ │
PCF8574 #1 (addr 0x20) → 8 switches
PCF8574 #2 (addr 0x21) → 8 switches
PCF8574 #3 (addr 0x22) → 8 switches
... up to 8 expanders per bus
Each expander has 3 address pins (A0, A1, A2), giving 8 unique addresses (0x20–0x27) per I²C bus. The Mega has 4 hardware serial ports and supports a second I²C bus via the Wire1 library for additional expanders.
#include <Wire.h>
#include <PCF8574.h>
PCF8574 expander1(0x20);
PCF8574 expander2(0x21);
void setup() {
Wire.begin();
expander1.begin();
expander2.begin();
}
void loop() {
// Read all 8 pins of expander 1
uint8_t state = expander1.read8();
// Check individual pin
bool sw1 = expander1.read(0); // pin P0
bool sw2 = expander1.read(1); // pin P1
// ...
}
Power Supply
| Rail | Voltage | Current | Powers |
|---|---|---|---|
| PSU 5V | 5V DC | 5A | Arduinos, WS2812B strips, logic |
| PSU 12V | 12V DC | 2A | Future: stepper motors (trim wheel) |
All Arduinos share a common 5V / GND bus from a single ATX power supply (silent fan, repurposed from a PC). USB connections to the PC are data-only — the Arduinos are powered by the ATX supply, not USB.
Critical: Always connect all GNDs together — Arduino GND, LED strip GND, and PSU GND must share a common reference or the WS2812B LEDs will flicker or behave erratically.
Full Wiring Diagram
Troubleshooting
Encoder skips steps or double-triggers → Add 100nF caps between encoder pins and GND. Check MobiFlight debounce setting (increase to 5–10ms).
WS2812B LEDs flash white on startup → Add a 300–500Ω resistor on the data line and a 1000µF cap across VCC/GND near the strip.
MobiFlight doesn't detect Arduino → Check COM port in Device Manager. Ensure CH340 driver is installed (common on AliExpress Mega clones). Try a different USB cable (data-capable, not charge-only).
SimConnect events not firing → Confirm MSFS is running before starting MobiFlight Connector. Check that the aircraft supports the event (some third-party aircraft use custom events).