---
title: MechBase PLC
tags: [mechbase, project, plc, ladder-logic, esp32, income]
created: 2026-06-21
---

# MechBase PLC

**PLC-style logic editor** for industrial automation and Lego Technic projects. Web-based interface with Studio 5000 fidelity, targeting ESP32 firmware.

## Overview

| Field | Value |
|---|---|
| **Path** | `/home/vincent/projects/mechbase-plc/` |
| **Port** | 5003 |
| **Stack** | Flask, TailwindCSS, React, C++ |
| **Target** | ESP32 firmware |
| **Business** | Build fee + monthly retainer for local shops |
| **Status** | Active β€” Reactive subscriptions + structuredClone |

## Architecture

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ESP32 Firmware (C++)                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Ladder Interpreter                               β”‚  β”‚
β”‚  β”‚                                                    β”‚  β”‚
β”‚  β”‚  For each scan:                                    β”‚  β”‚
β”‚  β”‚    1. Read digital inputs (GPIO)                   β”‚  β”‚
β”‚  β”‚    2. Evaluate networks rung-by-rung               β”‚  β”‚
β”‚  β”‚       a. Input branches (OR)                       β”‚  β”‚
β”‚  β”‚       b. Output branches (OTE/OTL/OTU/Timers)     β”‚  β”‚
β”‚  β”‚    3. Update timers (TON/TOF/TP)                   β”‚  β”‚
β”‚  β”‚    4. Write physical outputs (GPIO)                β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Web UI (served from ESP32)                       β”‚  β”‚
β”‚  β”‚  β€” Visual ladder editor                           β”‚  β”‚
β”‚  β”‚  β€” I/O monitoring                                 β”‚  β”‚
β”‚  β”‚  β€” Program download                               β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

## Ladder Logic Instructions

### Contacts (Input Logic)

| Symbol | Name | Description |
|--------|------|-------------|
| `--\| \|---` | **NO** | Normally Open β€” passes when TRUE |
| `--\|/\|---` | **NC** | Normally Closed β€” passes when FALSE |
| `--\|P\|---` | Rising Edge | Single-scan TRUE→FALSE transition |
| `--\|N\|---` | Falling Edge | Single-scan FALSE→TRUE transition |
| `T0.DN` | Timer Done | Timer has reached preset |
| `T0.TT` | Timer Timing | Timer is currently running |
| `T0.EN` | Timer Enable | Timer rung has power flow |

### Outputs

| Symbol | Name | Description |
|--------|------|-------------|
| `--( )--` | **OTE** | Output Energize β€” follows input power |
| `--(L)--` | **OTL** | Output Latch β€” SET, stays ON once set |
| `--(U)--` | **OTU** | Output Unlatch β€” RESET, clears latched output |
| `--(TON)--` | TON | Timer On-Delay |
| `--(TOF)--` | TOF | Timer Off-Delay |
| `--(TP)--` | TP | Timer Pulse |

### Timer Status Bits

| Bit | Meaning |
|-----|---------|
| **EN** | Enable β€” controlling rung has power flow |
| **TT** | Timing β€” timer is currently counting |
| **DN** | Done β€” timer has reached preset |

## GPIO Map (ESP32)

| Pin | Function |
|-----|----------|
| GPIO 27 | Digital Input 0 |
| GPIO 26 | Digital Input 1 |
| GPIO 33 | Digital Input 2 |
| GPIO 35 | Digital Input 3 |
| GPIO 34 | Digital Input 4 |
| GPIO 25 | Digital Output 0 |
| GPIO 32 | Digital Output 1 |
| GPIO 4  | Digital Output 2 |
| GPIO 15 | Digital Output 3 |

## Key Files

| Path | Purpose |
|------|---------|
| `src/ladder_interpreter.h` | C++ header β€” all types, enums, structs |
| `src/ladder_interpreter.cpp` | C++ implementation β€” evaluation, I/O, timers |
| `tests/ladder_test.py` | Python test harness (runs on Pi for testing) |
| `templates/motor_control.json` | Motor interlock template |

## Testing

```bash
cd ~/projects/mechbase-plc
python3 tests/ladder_test.py
```

**10 tests covering:** NO/NC, OTE, OTL/OTU, parallel branching, series contacts, TON/TOF/TP with all status bits, start/stop latching, motor interlock.

## Related

- [[Lego Ladder]] β€” Ladder logic for Lego Technic hubs (TypeScript/Vite, IndexedDB)
- [[Projects]]
- [[Second-Brain-Vault]]