Skip to content

ScionResearch/machine-controller-v1

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Kiln Door Controller

Pneumatic kiln door control system built on the BSI Machine Controller M4 (ATSAMD51J20A, 120 MHz Cortex-M4F).

Controller panel and kiln door

Hardware

Component Interface Notes
ILI9341 320x240 TFT SPI (SERCOM 5 ALT) Landscape rotation 3
FT6206 capacitive touch I2C (SERCOM 3) Shared reset with TFT
6x WS2812B NeoPixel LEDs GPIO (PIN_LED_DATA) Status + per-function indicators
14x digital inputs MOSFET-isolated, 5 V pull-up Buttons active HIGH, E-Stop NC (active LOW)
8x digital outputs MOSFET-driven 24 VDC HIGH = ON at terminal
6x analog inputs Opamp-buffered /5, 0-10.24 V range ADC ref: 2.048 V VREFA
2x analog outputs (DAC) Opamp-buffered x5 Provisioned, not used
RS485 (SERCOM 2) Half-duplex Provisioned, not used

Wiring

Defined in src/hardware/wiring_def.h:

Buttons (momentary, active HIGH):

  • DI1: Open, DI2: Close, DI3: Lock, DI4: Release, DI5: E-Stop Panel (NC, active LOW), DI12: E-Stop Door (NC, active LOW)

Sensors (active HIGH):

  • DI6: Door Open, DI7: Door Closed, DI8: Locked, DI9: Lock Lowered, DI10: Lock Raised, DI11: Human Detected

Actuators (active HIGH = 24 VDC):

  • DO1: Open (raise door) — dual solenoid, momentary
  • DO2: Close (vent raise side) — dual solenoid, momentary
  • DO3: Lock Top — single solenoid, spring-return; OFF = retracted/locked, ON = extended (wiring inverted)
  • DO4: Lock Bottom — single solenoid, spring-return; ON = engaged
  • DO5: Lock Raise — single solenoid, spring-return; ON = raised

Solenoid hold rule: The Open/Close ram uses two separate valves (energise to move, OFF when stationary). The lock-bottom and lock-raise solenoids each use a single spring-return valve and must remain energised to hold position. Lock Top has inverted wiring: spring-return goes to the retracted (locked) position, so it is safe on power loss — it only needs power to extend. In IDLE, FAULT, and PAUSED states the controller maintains the last commanded output state — sensors confirm operations but do not drive outputs.

Analog:

  • AI1: Air pressure (FESTO SPTE-P10R-Q4-V-2.5K, 0-10 V = 0-10 bar)

Wiring Diagrams

Controller connections:

Controller wiring

Valve box — solenoid valves and pressure sensor:

Valve wiring

Position sensors:

Sensor wiring

Software Architecture

src/
  main.cpp                    Main loop: inputs -> FSM -> LEDs -> LVGL -> UI
  config.h                    Compile-time constants (timeouts, gains, debounce)
  hardware/
    pin_def.h               Arduino pin numbers (matches variant.cpp)
    wiring_def.h            Application signal aliases + operation description
    led_def.h               LED addresses and colour definitions
  drivers/
    display.h/.cpp          LVGL 9 display driver (ILI9341 via SPI)
    touch.h/.cpp            LVGL 9 touch driver (FT6206 via I2C)
    led_manager.h/.cpp      NeoPixel manager with solid/pulse/breathe effects
  control/
    input_reader.h/.cpp     Debounced digital inputs + analog readings
    output_controller.h/.cpp Safe outputs with OPEN/CLOSE interlock
    door_fsm.h/.cpp         Goal-oriented door state machine
  ui/
    ui_common.h             Shared colour palette
    ui_manager.h/.cpp       Screen navigation (fade transitions)
    ui_home.h/.cpp          Home screen: door state, sensors, analog
    ui_io.h/.cpp            I/O diagnostic page: all inputs/outputs/analog
    ui_outputs.h/.cpp       Manual output control page (compile-time optional)

Door Operation

Open Sequence

Step Outputs Hold outputs Wait for
1. Unlock lock_top ON (extend), lock_bottom OFF lock_raise holds current position locked sensor LOW
2. Raise locks lock_raise ON, lock_top ON (extended) lock_raised sensor HIGH
3. Retract top locks lock_top OFF (retract), lock_raise ON 2 s timeout (no sensor)
4. Open door open ON, lock_top OFF (retracted), lock_raise ON door_open sensor HIGH
IDLE (open) open OFF, close OFF lock_top OFF (retracted), lock_raise ON

Close Sequence

Step Outputs Hold outputs Wait for
1. Close door close ON, lock_top OFF (retracted), lock_raise ON (hold) door_closed sensor HIGH
2. Extend top locks lock_top ON (extend), lock_raise ON 2 s timeout (no sensor)
3. Lower locks lock_raise OFF (spring return) lock_top ON (extended) lock_lowered sensor HIGH
4. Lock lock_top OFF (retract), lock_bottom ON lock_raise OFF locked sensor HIGH
IDLE (locked) open OFF, close OFF lock_top OFF (retracted), lock_bottom ON, lock_raise OFF

Manual Lock/Release

Only available when the door is fully closed. Lock and Release buttons trigger just the locking/unlocking portion of the sequence. The Lock sequence includes the extend → lower → engage steps if locks are not already lowered.

Power-Loss Recovery

After a power loss, all outputs default to OFF (spring-return). Lock Top has inverted wiring so it springs to the retracted (safe) position automatically. However, the lock-raise solenoid also springs OFF (lowered), so the lock carriage drops. If a Close or Open goal is started while the locks are not in the expected position, the FSM detects this and runs the necessary preparatory steps (raise, retract) before any ram movement.

Interrupting Operations

If a different button is pressed mid-sequence, the FSM stops the current operation and starts the new one from the current physical state (determined by sensors). Steps already satisfied are skipped automatically.

Safety

  • OPEN/CLOSE interlock: Outputs are mutually exclusive. Setting one forces the other off first.
  • E-Stop: Two E-Stop inputs (Panel DI5, Door DI12) — either triggers the same response. Ram movement stopped immediately; solenoid hold outputs maintained. If door is NOT closed+locked, the open sequence runs automatically to reach a safe state (with appropriate holds). If closed+locked, locks remain engaged. No other buttons accepted while active. UI shows which E-Stop is active (Panel, Door, or Both).
  • Human detection: Pauses the current operation — ram movement stopped, solenoid positions held via sensor feedback. Resumes automatically when sensor clears. No effect when disconnected (sensor reads LOW).
  • Hold-to-operate (compile-time, disabled by default): When HOLD_TO_OPERATE is set to 1 in config.h, the operator must hold the Open or Close button during door ram movement. Releasing the button pauses the ram and suspends the step timeout; pressing and holding again resumes. Lock manipulation steps run automatically and are not affected.
  • Step timeouts: Each FSM step has a configurable timeout (in config.h). If exceeded, the system enters FAULT state — ram movement stopped, solenoid positions held. Operator must press RESET on the touch screen.
  • Startup: All outputs OFF. A 500 ms grace period (STARTUP_GRACE_MS) lets inputs stabilise, then a startup-idle lock prevents the FSM from driving any outputs until the operator presses a physical button (Open, Close, Lock, or Release). This ensures transient E-Stop or sensor readings at power-on cannot unexpectedly activate solenoids. Entering the Manual Outputs page also clears the startup lock.
  • FAULT / PAUSED hold: Single-solenoid valves (locks, lock-raise) are maintained in their current position based on sensor state, preventing uncontrolled spring-return movement.

FSM States

State Description
IDLE No operation, position determined by sensors
UNLOCKING Disengaging locks
RAISING_LOCKS Raising upper locks to clear door path
RETRACTING_LOCKS Retracting top locks while raised (timed, no sensor)
OPENING Door opening
REOPENING Auto re-raising door after droop detection (3 s timeout)
CLOSING Door closing
EXTENDING_LOCKS Extending top locks before lowering (timed, no sensor)
LOWERING_LOCKS Lowering upper locks into position
LOCKING Engaging locks
ESTOP E-Stop active
FAULT Timeout or error, requires manual reset
PAUSED Human detected, auto-resumes when clear

LED Indicators

LED Address Function
Status 0 Green breathe = normal, Amber breathe = operating, Red pulse = fault/E-Stop
E-Stop 1 Green solid = normal, Red pulse = panel E-Stop active (door E-Stop uses status LED only)
Open 2 Blue breathe = opening/re-raising, Green solid = open
Close 3 Amber breathe = closing, Green solid = closed
Lock 4 Magenta breathe = locking/lowering/extending, Green solid = locked
Release 5 Yellow breathe = unlocking/raising/retracting, Green solid = released

IDLE Sensor-Mismatch Warnings

When idle, the expected physical state is determined from commanded outputs. If any sensor contradicts the expected state, the relevant LED flashes red pulse to alert the operator. The Status LED switches to amber pulse when any warning is active.

Expected State Commanded Outputs Open LED red if Close LED red if Lock LED red if
Open & Retracted raise ON, lock_top OFF, lock_bot OFF door not open door closed locked, not raised, or lowered
Closed & Locked raise OFF, lock_top OFF, lock_bot ON door open door not closed not locked, raised, or not lowered
Closed & Unlocked raise OFF, lock_top ON, lock_bot OFF door open door not closed locked, raised, or not lowered

This covers failed operations, unexpected states at power-on, and uncommanded position changes (e.g. air leaks causing ram droop).

Configuration

All tuning parameters are in src/config.h (compile-time only, not runtime configurable):

  • Debounce: 30 ms buttons, 20 ms sensors
  • Timeouts: 5-16 s per step (approx 1.5x expected mechanical duration)
  • Analog scaling: ADC ref 2.048 V, input gain x5, PSU divider 14.333:1
  • Pressure sensor: 0-10 V = 0-10 bar, displayed with 1 decimal place
  • LED brightness: 0-255 (compile-time)
  • Safety thresholds: PSU 20-26 V, air pressure 5-7 bar (operations refused if out of range)
  • Manual output page: MANUAL_OUTPUT_PAGE_ENABLED (1 = enabled, 0 = hidden)

UI Screens

Screens are navigated by swiping left/right (no on-screen buttons). Screen order: Home → I/O → Manual Outputs (if enabled).

Home Screen

Primary operator view:

  • Door state (large, colour-coded: green=idle, amber=operating, red=fault/E-Stop)
  • Current goal and step elapsed timer (seconds, only during active operations)
  • All sensor flags (open, closed, locked, locks raised/lowered)
  • PSU voltage and air pressure (fixed-position labels)
  • E-Stop and human detection status
  • FAULT reset button (visible only in fault state)

I/O Diagnostics

Commissioning and troubleshooting view:

  • All 12 digital input states with colour indicators
  • All 5 output states with colour indicators
  • All 6 analog input voltages, PSU voltage, and air pressure in engineering units

Manual Outputs (guarded by MANUAL_OUTPUT_PAGE_ENABLED)

Direct output control and safety check bypass for commissioning:

  • Switch per output (amber track = ON, dark = OFF)
  • Safety check bypass switches: Pressure, PSU Voltage, and Human Detection (green = check enabled, red = bypassed)
  • Warning popup on entry: "Safety features will not work!" with Confirm / Go Back
  • On Confirm: all outputs set OFF, FSM bypassed, all switches enabled
  • On Go Back: outputs unchanged, returns to Home
  • Swiping away returns output control to the FSM; outputs held until the next user-initiated operation (button press)
  • Safety check bypass states persist across page navigations

Pre-Operation Safety Checks

Before accepting a new goal from physical buttons, the FSM checks:

  • Air pressure: must be 5-7 bar (if pressure check enabled)
  • PSU voltage: must be 20-26 V (if voltage check enabled)

If a reading is out of range and its check is enabled, the button press is ignored and a message is logged to serial. E-Stop emergency open always works regardless of these checks. All checks default to enabled on boot and can be bypassed from the Manual Outputs page.

Door Droop Recovery

If the door slowly drops under its own weight while in the open position (e.g. due to a pneumatic leak), the FSM detects the open sensor going inactive and automatically re-raises the door:

  1. Conditions: IDLE, no active goal, lock_top and lock_raise outputs ON (open position), open sensor inactive, not in manual mode.
  2. The open ram is activated for up to 3 s (TIMEOUT_RERAISE_MS).
  3. If the open sensor re-activates within the timeout, the FSM returns to IDLE.
  4. If the timeout expires without the sensor re-activating, the FSM enters FAULT.

This replaces the previous behaviour where a sensor mismatch warning was the only indication of droop.

Lock Sensor Filtering

The lock sensor is only considered active when the door closed sensor AND locks lowered sensor are also active. This prevents false lock readings caused by the door swinging into the lock sensor when in the open/raised position, which would otherwise cause the FSM to spuriously cycle lock outputs (particularly during E-Stop recovery).

Build

# Build
pio run -e bsi_machine_ctrl_m4

# Upload via Atmel-ICE
pio run -e bsi_machine_ctrl_m4 --target upload

Dependencies (managed by PlatformIO)

  • lvgl/lvgl ^9.1.0
  • adafruit/Adafruit NeoPixel ^1.15.4
  • adafruit/Adafruit ILI9341 ^1.6.1
  • adafruit/Adafruit FT6206 Library ^1.1.0
  • adafruit/Adafruit GFX Library ^1.11.11

Build Notes

  • scripts/lvgl_build.py excludes ARM Helium/NEON assembly files from LVGL (not supported on Cortex-M4)
  • include/lv_conf.h configures LVGL: 16-bit colour, 48 KB memory pool, Montserrat 14/16/20/24 fonts
  • Custom board variant in hardware/board-def/ with DAC workaround for Adafruit core bug
  • Pin mapping: DI 0-13, Analog 14-23 (A0=14), DO 24-31, peripherals 32+

About

Small machine controller with 14 digital inputs, 6 analog inputs, 8 digital outputs, 2 analog outputs, 1 RS485 port and 2.8" TFT interface with CTP

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors