A crosspoint relay matrix controller based on the STM32F401 microcontroller. This project implements SCPI-like commands to control a 4x4 relay matrix using TPL9201 drivers. It is designed for anisotropy measurement and equipment testing applications and was developed for the course "Elettronica dei Sistemi Programmabili".
- Crosspoint Matrix: True 4x4 crosspoint switching - connect any input (A-D) to any output (1-4)
- TPL9201 Drivers: SPI-controlled MOSFET arrays for relay driving
- Dual Relay Types: Interchangeable footprints for HFD2/012-S-L2 (EMR) and OMRON G3MB-202P (SSR)
- ATX PSU Integration: Uses ATX power supply for 12V relay power and PS_ON control
- Power Management: Basic PSU control with power monitoring
- Status Monitoring: Simple relay status reporting
- Command Queuing: Basic queuing system for command execution
- USB Serial Interface: PC connectivity for control
- STM32F401XE - ARM Cortex-M4 with FPU
- 84 MHz maximum operating frequency
- 512KB Flash / 96KB RAM
- 4x4 Crosspoint Matrix: Connect any input (A-D) to any output (1-4)
- TPL9201 SPI Drivers: MOSFET arrays controlled via SPI interface
- Relay Options: HFD2/012-S-L2 (EMR) or OMRON G3MB-202P (SSR)
- Interchangeable Footprints: Choose relay type during PCB assembly
Power Control:
- PS_ON → PC9 (ATX Power Supply Enable)
- PWR_OK → PB5 (ATX Power Supply Status)
TPL9201 SPI Control:
Group A: NCS→PA12, NRST→PB12
Group B: NCS→PA9, NRST→PB9
Group C: NCS→PB6, NRST→PB14
Group D: NCS→PC5, NRST→PC6
SWITCH:COMMUTE <relay> # Activate specific relay
SWITCH:COMMUTE:EXCLUSIVE <relay> # Activate relay, deactivate others in group
SWITCH:COMMUTE:RESET <relay> # Deactivate specific relay
SWITCH:COMMUTE:RESET:ALL # Deactivate all relays
SWITCH:COMMUTE:STATUS? # Get power status of all groups
SWITCH:COMMUTE:BYTE:STATUS? # Get detailed binary status
*IDN? # Device identification
*OPC? # Operation complete
SYS:LOG? # System log messages
SYS:GETSTATE? # Current system state
SYS:HALT # Stop system - power down
Relays are addressed using the format: <input><output>
- Inputs: a, b, c, d (case insensitive)
- Outputs: 1, 2, 3, 4
Examples:
a1
- Connect input A to output 1b3
- Connect input B to output 3d4
- Connect input D to output 4
Crosspoint Behavior:
a1 a2
- Connects A to both 1 and 2 (thus 1↔2)a3 b2 c1 d3
- Multiple connections: A↔3, B↔2, C↔1, D↔3 (so A↔D via 3)
Multiple relays can be controlled in a single command for complex routing:
SWITCH:COMMUTE a1 b2 c3 d4 # Connect A→1, B→2, C→3, D→4
SWITCH:COMMUTE:RESET a1 a2 # Disconnect A from 1 and 2
- STM32CubeIDE or compatible ARM toolchain
- STM32CubeProgrammer for flashing
- ST-Link debugger/programmer (included in STM32F401RE Nucleo)
- VS Code with STM32 extension (recommended for this workspace)
# Build the project
Ctrl+Shift+P → "Tasks: Run Task" → "Build STM"
# Clean build
Ctrl+Shift+P → "Tasks: Run Task" → "Build Clean STM"
# Flash to device
Ctrl+Shift+P → "Tasks: Run Task" → "Flash STM"
- Insert STM32F401RE Nucleo board into the custom PCB sockets (2x 20-pin headers, 2.54mm pitch)
- Connect ATX power supply: PS_ON control line and 12V for relay power
- Connect USB to Nucleo for serial communication
- Choose and mount either HFD2/012-S-L2 (EMR) or OMRON G3MB-202P (SSR) relays during PCB assembly
Assembly Notes:
- The only valued components are the capacitors and resistors around the TPL9201 driver
- Make sure to solder the TPL9201 with the first pin aligned to the silkscreen mark
- See images section below for TPL9201 component values and PCB layout
- Baud Rate: 115200
- Data Bits: 8
- Stop Bits: 1
- Parity: None
- Flow Control: None
- Terminator:
\n
(configurable)
import serial
ser = serial.Serial('COM3', 115200, timeout=1)
# Activate relay A1
ser.write(b'SWITCH:COMMUTE a1\n')
response = ser.readline()
# Get status
ser.write(b'SWITCH:COMMUTE:STATUS?\n')
status = ser.readline().decode().strip()
# Emergency stop
ser.write(b'SYS:HALT\n')
See Powershell/comms.ps1
for communication examples.
Edit Core/Src/components/config/config.h
:
#define SWITCH_COMMUTE_MODE SWITCH_EMR // for HFD2/012-S-L2
// or
#define SWITCH_COMMUTE_MODE SWITCH_SSR // for OMRON G3MB-202P
#define HANDSHAKE_SCPI 1 // Enable SCPI handshaking
#define TERM_CHAR "\n" // Command terminator
#define MAX_COMMAND_LENGTH 256 // Maximum command length
#define MAX_COMMAND_QUEUE_SIZE 16 // Command buffer size
#define ACTION_QUEUE_SIZE 16 // Action buffer size
- Parser: SCPI-like command parsing and validation
- Interpreter: Command execution and relay matrix control
- FSM: System state management (PASSIVE/ACTIVE/ERROR)
- Queues: Command and message management
- Actions: TPL9201 SPI control and relay matrix logic
- Callbacks: UART interrupt handlers for serial communication
- PASSIVE: Low power, PSU off
- ACTIVE: Normal operation, PSU on
- ERROR: Fault condition handling
UART RX → Parser → Command Queue → Interpreter → TPL9201 SPI → Relay Matrix
↓
Response Queue ← Status Monitor ← Matrix State ←——————————————————
- No Response: Check serial connection and baud rate
- Command Error: Verify command syntax and relay addressing
- Power Issues: Check ATX PSU connections and PWR_OK signal
- Relay Not Switching: Verify TPL9201 SPI connections and 12V supply
- System log accessible via
SYS:LOG?
- Status monitoring with
SYS:GETSTATE?
- Basic self-test capabilities
Component values for the relay driving module around the TPL9201 driver:

Complete PCB layout showing the 4x4 relay matrix design:

3D visualization of the assembled PCB:

This project is licensed under the terms specified in the LICENSE file.
darderik - DIIEM, Università Roma Tre
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request