Open Source Hardware

The
Sensor Ring

6 pillars. 14 Arduinos. 20+ sensor modalities. Every schematic, wiring diagram, firmware spec, and channel map — fully open source under the MIT license.

6
Pillars
14
Arduinos
20+
Sensor Types
3 Uno + 1 Mega
Per Pillar A+B
MIT
License
System Architecture

How It All Fits Together

Six physical pillars are arranged around a central measurement zone. Each pillar carries two Arduino microcontrollers and a set of sensors. All modules communicate over USB serial at 115,200 baud (camera boards at 500 kbaud or 2 Mbaud) using a CRC8-validated binary packet protocol to a central C# / Godot 4 host application running on Windows.

HOST PC — Windows 11
┌─────────────────────────────────────────────────────────────────┐
│  Godot 4.x + C# (.NET 6)                                        │
│                                                                  │
│  ModuleManager ──► SignalAnalysisEngine ──► PhaseEngine          │
│       │               FFT @ 200 ms            4-ch PLL           │
│       │               8 invariants             Lock detect        │
│       ▼                                                          │
│  30+ UI Pages: Dashboard · Magnetic · Thermal · Gas · LiDAR     │
│                RF · Phase · Magnitude · Fusion · MetatronUnits   │
│                                                                  │
│  Logger ──► session.bin  │  ApiServer ──► REST :8080             │
│                          │  WebSocketServer ──► WS :8081         │
└─────────────────────────────────────────────────────────────────┘
       │  USB/Serial ×14 (COM ports)
       │
┌──────┴──────────────────────────────────────────────────────────┐
│  PHYSICAL SENSOR RING                                            │
│                                                                  │
│  PILLAR 1–3          │  PILLAR 4–6                               │
│  Nano (Hall+Ultra)   │  Uno (Thermal+Gas)                        │
│  Uno  (AV Camera)    │  Uno (LiDAR+Microwave)                    │
│  320×240 RGB565      │  Uno (Hi-Res Camera 640×480)              │
│                      │                                           │
│  VOLTAGE_01 (Uno)  VOLTAGE_02 (Nano)                             │
│  IMPEDANCE_01 (Uno) IMPEDANCE_02 (Nano)                          │
└─────────────────────────────────────────────────────────────────┘

Pillars 1, 2 & 3

2 boards each

Nano (Hall+Ultra) + Uno (AV Camera)

Pillars 4, 5 & 6

3 boards each

Uno (Thermal+Gas) + Uno (LiDAR+MW) + Uno (Hi-Res Camera)

Voltage Modules

2 boards total

VOLTAGE_01 (Uno) + VOLTAGE_02 (Nano)

Impedance Modules

2 boards total

IMPEDANCE_01 (Uno) + IMPEDANCE_02 (Nano)

Pillars 01–03

Pillars 1, 2 & 3

Hall Effect + Ultrasonic + Low-Res AV Camera

Board A — Hall + Ultrasonic

Arduino Nano (ATmega328P)

PILLAR_01 / 02 / 03115,200 baud

Sensors

4× KY-003 Hall EffectA0, A1, A2, A3

Analog magnetic field sensing. 4-bit pattern encodes which magnets are present. 10 ms debounce, auto-calibrated baseline at boot.

2× HC-SR04 UltrasonicTrig D6/D4, Echo D7/D5

40 kHz ToF ranging. Distance = pulse_µs × 0.0343 / 2. 3-sample circular buffer, outlier rejection >50 cm from median.

SSD1306 OLED 128×64I²C A4=SDA, A5=SCL (0x3C)

Live display of Hall pattern, active count, and distances. Refreshes every 250 ms.

Board B — AV Camera

Arduino Uno (ATmega328P)

PILLAR_01_AV / 02_AV / 03_AV500,000 baud

Sensors

OV7670 Camera (QVGA 320×240)SCCB I²C A4/A5, D2–D7+A0–A1 data bus, D11 XCLK, D12 VSYNC, D13 HREF

RGB565 pixel format. 320×240 = 153,600 bytes/frame. UART_MODE 5 at 500 kbaud. 8 MHz XCLK from Timer2. 3.3V only — use AMS1117-3.3 regulator.

LM393 MicrophoneD10 (INPUT_PULLUP)

Comparator-based sound sensor. Digital presence flag sent every frame cycle. Threshold set by onboard potentiometer.

⚠ OV7670 requires 3.3V — never connect to 5V. Use 4.7 kΩ pull-ups to 3.3V on SCCB lines.
Pillars 04–06

Pillars 4, 5 & 6

Thermal+Gas / LiDAR+Microwave + Hi-Res Camera (Dual Arduino, Back-to-Back)

Board A — Thermal + Gas

Arduino Uno (ATmega328P)

PILLAR_04 / 05 / 06115,200 baud

Sensors

MLX90614 IR ThermometerI²C A4=SDA, A5=SCL

Non-contact object + ambient temperature. Shared I²C bus with AMG8833.

AMG8833 8×8 Thermal ArrayI²C A4/A5 (0x69), INT D2

64-pixel thermal image at 10 fps, 0.25°C resolution, 60° FoV. Full 64-pixel frame sent in 4 chunks of 16 pixels every 40 ms.

MQ Gas SensorA0 (analog), D3 (digital alarm)

Rs = (Vcc−Vout)/Vout × RL. PPM = a×(Rs/R0)^b. Supports MQ-2 through MQ-138. 11 sensor variants, 4 gas curves each. 5-sample R0 calibration at boot.

DHT11 Temp + HumidityD6 (single-wire, 4.7 kΩ pull-up)

Bit-bang protocol. Pulses <40 µs = 0, ≥40 µs = 1. 5-byte frame with checksum.

KY-008 LaserD7 (HIGH = on)

Used with photodiodes for optical interruption detection.

2× PhotodiodesA1 (left), A2 (right)

Voltage divider: 10 kΩ to GND. Optical presence sensing.

2× IR Obstacle SensorsD4 (left), D5 (right)

Digital proximity detection.

Board B — LiDAR + Microwave

Arduino Uno (ATmega328P)

PILLAR_04_LM / 05_LM / 06_LM115,200 baud

Sensors

VL53L1X ToF LiDARTCA9548A CH7 (auto-detect), XSHUT D8

940 nm Class 1 VCSEL. 16×16 SPAD array. Long Distance mode, 33 ms timing budget. ±25 mm accuracy up to 4 m. d = (c × t) / 2. Servo sweeps 0–90° in 1° steps, 25 ms settle.

MPU6050 6-Axis IMUTCA9548A CH1 (0x68)

3-axis gyro + 3-axis accel. Accel: raw/4096 × 9.80665 m/s². Gyro: raw/65.5 × π/180 rad/s. Temp: raw/340 + 36.53°C. Read every 50 ms.

TCA9548A I²C MuxA4=SDA, A5=SCL (0x70)

8-channel I²C multiplexer. Firmware auto-scans all 8 channels at boot to locate LiDAR (0x29) and OLED (0x3C). Physical wiring order is flexible.

Microwave Doppler SensorD2 (serial/digital input)

Motion presence and intensity. Up to 128 bytes buffered per packet. Host interprets as motion detection.

Servo MotorD7 (PWM)

Pan/tilt for LiDAR scanning. 0–90° range, 1° step. Auto-sleep after 30 s of no host command. CMD_SET_SCAN wakes it.

SSD1306 OLED 128×64TCA9548A CH5 (auto-detect, 0x3C)

Live scan angle and distance display.

⚠ VL53L1X requires 3.3V. Servo needs separate 5V 2A supply to avoid Uno brownout.

Hi-Res Camera

Arduino Uno (ATmega328P)

Camera board (Pillars 4–6)2,000,000 baud

Sensors

OV7670 Camera (VGA 640×480)SCCB I²C A4/A5, D2–D7+A0–A1 data bus, D11 XCLK, D12 VSYNC, D13 HREF

RGB565 pixel format. 640×480 = 614,400 bytes/frame. UART_MODE 16 at 2 Mbaud. Same wiring as Pillars 1–3 low-res board — only baud rate and resolution config differ. 3.3V only.

⚠ 640×480 RGB565 = 614,400 bytes/frame. Host processes frames asynchronously. Budget ~900 mA per pillar (all 3 boards combined).
Utility Modules

Voltage + Impedance

Voltage Modules

VOLTAGE_01 (Uno) + VOLTAGE_02 (Nano)

ADS1115 16-bit ADC, 4-channel voltage monitoring
V_out = (ADC_raw / 1023.0) × 5.0 × 5.0 (divider scale) → 0–25V range
Voltage divider: R1 = 30 kΩ (top), R2 = 7.5 kΩ (bottom)
EEPROM-backed CalibrationTable — up to 5 calibration points, linear interpolation
OLED display: both channel voltages at 250 ms update rate
Quality byte: 100 for mid-range, lower near ADC rails
showMetatronCube() geometric pattern on OLED during idle

Impedance Modules

IMPEDANCE_01 (Uno) + IMPEDANCE_02 (Nano)

AD5933 network analyzer, 1 kHz–100 kHz sweep
|Z| = (Vref − Vmeasured) / Vmeasured × 400 Ω (default scale)
Phase derived from phase-shifted secondary ADC channel
Signal source → R_ref (10 kΩ) → unknown Z_x → GND
EEPROM CalibrationTable corrects bridge non-linearity
OLED updates at 300 ms interval
Both magnitude and phase reported per channel
Firmware

Common Binary Protocol

All 14 Arduino boards use the same CRC8-validated binary packet format. The host's ModuleManager scans all COM ports, parses IDENT packets, and routes DATA packets to subscribers.

Byte:  [0]      [1]    [2]     [3 … N+2]   [N+3]   [N+4]
       START    LEN    TYPE    PAYLOAD      CRC8    END
       0xAA     N+1    0x01–0A  N bytes     poly07  0x55

START  = 0xAA  — fixed frame marker
LEN    = payload length + 1 (includes TYPE byte)
TYPE   = message type (see table)
CRC8   = polynomial 0x07 over bytes [1 … N+2]
END    = 0x55  — fixed frame terminator
TypeCodeDirectionDescription
IDENT0x01Module→HostJSON identification: id, type, fw, channels, health
DATA0x02Module→HostSensor data. Payload: 4B timestamp, 1B channel, 1B module type, 2B data length, then data
STATUS0x03Module→HostHealth report: temp, voltage, uptime, error count, SNR, status byte
CALIBRATE0x04Host→ModuleTrigger calibration sequence
CONFIG0x05Host→ModuleUpdate configuration parameters
ERROR0x06Module→HostError report with error code and message string
HEARTBEAT0x07Module→Host5-byte keep-alive: 4B uptime (big-endian) + 1B health status
ACK0x08Module→Host2-byte acknowledgment: command byte + result byte (0=OK)
COMMAND0x09Host→ModuleCommand packet. First payload byte = command ID
REQUEST_IDENT0x0AHost→ModuleRequest module to re-send IDENT
Signal Science

Key Sensor Mathematics

MQ Gas Sensor — Rs from ADC

Rs = (Vcc − Vout) / Vout × RL

Vout = ADC_raw / 1023 × 5.0 V

RL = 10,000 Ω (load resistor)

PPM = a × (Rs/R0)^b (non-linear)

PPM = 10^(a × log₁₀(Rs/R0) + b) (log-linear)

VL53L1X LiDAR — Time of Flight

d = (c × t) / 2

c = 3×10⁸ m/s (speed of light)

t = round-trip photon time

Resolution: 1 mm

Accuracy: ±25 mm up to 4 m (Long Distance mode)

MPU6050 IMU — Unit Conversion

a_xyz [m/s²] = raw / 4096.0 × 9.80665 (±8G range)

ω_xyz [rad/s] = raw / 65.5 × (π / 180) (±500°/s)

T [°C] = raw / 340.0 + 36.53

All 14 registers (0x3B–0x48) read every 50 ms

HC-SR04 Ultrasonic — Distance

Trigger: HIGH pulse for 10 µs

Distance [cm] = pulse_µs × 0.0343 / 2

Speed of sound = 0.0343 cm/µs

Valid range: 2–400 cm

Quality = 100 − 5×σ (3-sample circular buffer)

Voltage Module — Divider

V_out = (ADC_raw / 1023.0) × 5.0 × 5.0

Divider: R1 = 30 kΩ (top), R2 = 7.5 kΩ (bottom)

Effective range: 0–25 V

EEPROM CalibrationTable: up to 5 points, linear interp

Impedance Module — |Z| from ADC

|Z| = (Vref − Vmeasured) / Vmeasured × 400 Ω

Default scale: 400 Ω (reference load)

Phase [°] from phase-shifted secondary ADC channel

Signal source → R_ref (10 kΩ) → Z_x → GND

Gas Sensor Reference

Supported MQ Sensor Variants

SensorGas AGas BGas CGas D
MQ-2 (default)LPGCOH₂Alcohol
MQ-3AlcoholBenzeneCOLPG
MQ-4CH₄LPGCOAlcohol
MQ-5LPGCH₄COH₂
MQ-7COH₂LPGCH₄
MQ-135NH₃COAlcoholBenzene

11 MQ sensor variants supported total (MQ-2 through MQ-138). Each with a lookup table of 4 gas curves. Dominant gas = highest PPM above 10 ppm threshold.

Metatron Harmonic logo

An open-source multi-sensor acquisition, analysis, and visualization platform built on Godot 4 + C#. Phase is not a property of signals. Phase is the substrate of reality.

MIT License · Open Source

Metatron Research Project · Thousand Oaks, California

© 2026 Metatron Research Project · R. Careaga · Thousand Oaks, California

MIT License · MetatronHarmonic.info