A dual-MCU precision power supply and programmable electronic load with 24-bit measurement resolution, multi-point calibration, and full IoT integration via Raspberry Pi and ThingsBoard. Monitor voltage, current, and temperature in real time from anywhere — and control the power supply remotely through a web dashboard.
- Voltage Range: 0–25 V with 16-bit DAC control (DAC7565)
- Current Range: ±5 A — functions as both power supply (source) and electronic load (sink)
- 24-Bit ADC: TI ADS1219 for high-resolution voltage and current measurement at 330 SPS
- Multi-Point Calibration: 10-point voltage and 20-point current calibration with linear interpolation, stored in EEPROM
- Over-Temperature Protection: Dual temperature sensors with automatic shutdown at 60°C
- PWM Fan Control: Temperature-proportional automatic cooling
- Capacity Measurement Mode: Amp-hour integration for battery testing
- TFT Display: 320×240 color display showing real-time voltage, current, power, and temperature
- 5×5 Matrix Keypad: Direct numeric entry for setpoints
- Rotary Encoder: Fine/coarse adjustment with selectable step sizes (1 mV to 10 V steps)
- ThingsBoard Dashboard: Real-time monitoring and control via web browser
- MQTT Telemetry: Voltage, current, and temperature streamed every second
- Remote Procedure Calls (RPC): Power on/off, voltage adjustment (+1 V, -1 V, +0.1 V, -0.1 V) from the dashboard
- Raspberry Pi 5 Gateway: Bridges serial data to the cloud via MQTT
The system is built around a three-tier architecture: two custom PCBs for analog control and user interface, connected to a Raspberry Pi 5 for cloud connectivity.
| Component | Processor | Clock | Memory |
|---|---|---|---|
| Raspberry Pi 5 | 64-bit BCM2712 | 2.4 GHz | 8 GB RAM |
| Teensy 4.1 (UI MCU) | 32-bit iMXRT1062 | 600 MHz | 8192 KB Flash, 1024 KB SRAM |
| ATtiny 3227 (×2) | 8-bit AVR | 20 MHz | 32 KB Flash, 3 KB SRAM, 256 B EEPROM |
Each PSLoad module handles real-time analog control. It houses an ATtiny 3227 MCU, a DAC7565 quad 16-bit DAC, an ADS1219 24-bit ADC, a MOSFET power stage, current sense circuitry, and two temperature sensors. Communication with the UI controller passes through a digital isolator for galvanic isolation. The system supports two independent PSLoad channels.
The UI controller is based on a Teensy 4.1 and provides the user interface as well as IoT connectivity. It drives the TFT display, scans the 5×5 keypad matrix, reads the rotary encoder, controls the fan via PWM, and manages two independent serial links to the PSLoad modules at 2 Mbps. A separate 1 Mbps serial connection to the Raspberry Pi enables IoT data exchange.
The IoT layer connects the power supply to the cloud, enabling remote monitoring and control from any web browser.
PSLoad Modules ──(2 Mbps UART)──▶ Teensy 4.1 ──(1 Mbps UART)──▶ Raspberry Pi 5 ──(MQTT)──▶ ThingsBoard Cloud
◀──(RPC)──
The system uses ThingsBoard Community Edition as its IoT platform. ThingsBoard provides:
- MQTT broker for real-time telemetry ingestion
- Dashboards with customizable widgets for data visualization
- RPC (Remote Procedure Calls) for sending commands back to the device
- Shared Attributes for device configuration
The free demo version at demo.thingsboard.io supports up to two devices and is sufficient for this project.
The Raspberry Pi reads measurement data from the Teensy via serial and publishes it to ThingsBoard every second as JSON:
{
"VOLT": 12.345,
"CURR": 1.234,
"TEMP": 35.0,
"VoltSet": 12.0
}The ThingsBoard dashboard provides interactive controls that send RPC commands back through the Raspberry Pi to the power supply:
| RPC Method | Action |
|---|---|
setState (true/false) |
Turn output on or off |
up1 |
Increase voltage by +1 V |
down1 |
Decrease voltage by -1 V |
up0.1 |
Increase voltage by +0.1 V |
down0.1 |
Decrease voltage by -0.1 V |
The ThingsBoard dashboard provides a complete overview of the power supply's state with real-time charts for voltage, current, and temperature, RPC buttons for voltage adjustment, and a power toggle switch.
The Raspberry Pi 5 acts as a bridge between the power supply hardware (serial) and the ThingsBoard cloud (MQTT). The Python script thingsboard_bridge.py handles:
- Serial communication with the Teensy 4.1 at 1 Mbps (
/dev/ttyACM0) - Telemetry upload — reads voltage, current, and temperature, formats as JSON, publishes via MQTT
- RPC handling — listens for dashboard commands (power toggle, voltage adjustment) and forwards them as serial commands
- Shared attributes — synchronizes device configuration with the server
# Install dependencies
pip install tb-gateway-mqtt pyserial
# Configure your ThingsBoard access token in the script
nano firmware/raspberry-pi/thingsboard_bridge.py
# Replace YOUR_ACCESS_TOKEN_HERE with your device token from ThingsBoard
# Run the gateway
python3 firmware/raspberry-pi/thingsboard_bridge.py| Package | Purpose |
|---|---|
tb-gateway-mqtt |
ThingsBoard MQTT client (TBDeviceMqttClient) |
pyserial |
Serial communication with the Teensy |
logging |
Debug output (stdlib) |
| Command | Format | Description |
|---|---|---|
v |
v<float>t |
Set output voltage (0–25 V) |
i |
i<float>t |
Set source current limit (0–5 A) |
s |
s<float>t |
Set sink current limit (0–5 A) |
o |
o |
Enable output |
f |
f |
Disable output |
h |
h |
Select internal voltage sense (2-wire) |
u |
u |
Select external voltage sense (4-wire) |
r |
r<uint16> |
Write raw DAC value |
X |
X |
Zero voltage calibration coefficients |
x |
x |
Zero current calibration coefficients |
L |
L<n> <float> |
Set voltage DAC calibration coefficient [n] |
K |
K<n> <float> |
Set voltage ADC calibration coefficient [n] |
I |
I<n> <float> |
Set current DAC+ calibration coefficient [n] |
O |
O<n> <float> |
Set current DAC- calibration coefficient [n] |
P |
P<n> <float> |
Set current ADC calibration coefficient [n] |
S |
S |
Store all calibration to EEPROM |
| Prefix | Data | Description |
|---|---|---|
V |
float | Measured voltage (V) |
A |
float | Measured current (A) |
n |
float | Temperature sensor 1 (°C) |
m |
float | Temperature sensor 2 (°C) |
l |
— | End-of-frame delimiter |
E |
uint8_t | Error flag (1 = over-temp set, 0 = reset) |
The UI controller sends measurement data to the Raspberry Pi every second:
Volt: <float> Amp: <float> Temp: <float>
The Raspberry Pi can send commands back:
V<float>— Set voltageO— Turn output onF— Turn output off
The system uses multi-point linear interpolation for high accuracy across the full range:
- Voltage: 10 calibration points from 0.03 V to 25.0 V, with separate DAC and ADC offset arrays
- Current (Source): 10 calibration points from 0 A to 5.0 A (DAC+ offsets)
- Current (Sink): 10 calibration points from 0 A to 5.0 A (DAC- offsets)
- Current (ADC): 20 calibration points from -5.0 A to +5.0 A for bidirectional measurement
All calibration coefficients are stored in EEPROM (addresses 0–199) and loaded at startup. The calibration procedure is accessible through a hardware mode switch and guides the user through each setpoint on the TFT display.
| Library | Purpose |
|---|---|
DAC7565 |
SPI control of the quad 16-bit DAC |
SparkFun_ADS1219 |
I2C driver for the 24-bit ADC |
ATtiny_TimerInterrupt |
Hardware timer ISR for 25 ms sampling interval |
EEPROM |
Calibration coefficient storage |
SPI |
DAC communication bus |
Wire |
ADC I2C communication (1 MHz fast mode) |
| Library | Purpose |
|---|---|
TFT_eSPI |
TFT display driver (320×240, 16-bit color) |
Keypad |
5×5 matrix keypad scanning |
Metro |
Non-blocking timing intervals |
movingAvgFloat |
Moving average filter (10-sample and 50-sample) |
TimerThree |
Hardware timer for buzzer duration control |
InternalTemperature |
Teensy internal temperature readout |
| Package | Purpose |
|---|---|
tb-gateway-mqtt |
ThingsBoard MQTT device client |
pyserial |
Serial communication with UI controller |
- Install Arduino IDE or PlatformIO
- Install the megaTinyCore board package
- Install the required libraries listed above
- Open
firmware/psload-module/src/main.cpp - Select ATtiny 3227 as the target board
- Upload via UPDI programmer
- Install Teensyduino or PlatformIO with Teensy platform
- Install the required libraries listed above
- Open
firmware/ui-controller/src/main.cpp(ensureinclude/PSLoad.his in the include path) - Select Teensy 4.1 as the target board
- Upload via USB
Note: When using the Arduino IDE, you may need to rename
main.cpptomain.inoand adjust the project structure accordingly.
- Connect the Raspberry Pi to the Teensy 4.1 via USB (serial shows up as
/dev/ttyACM0) - Install Python dependencies:
pip install tb-gateway-mqtt pyserial
- Create a device on ThingsBoard and copy the access token
- Edit
firmware/raspberry-pi/thingsboard_bridge.pyand replaceYOUR_ACCESS_TOKEN_HEREwith your token - Run the gateway:
python3 firmware/raspberry-pi/thingsboard_bridge.py
A demonstration video showing the power supply in operation is available.
iot-lab-power-unit/
├── firmware/
│ ├── psload-module/
│ │ └── src/
│ │ └── main.cpp # ATtiny 3227 analog control firmware
│ ├── ui-controller/
│ │ ├── src/
│ │ │ └── main.cpp # Teensy 4.1 UI firmware
│ │ └── include/
│ │ └── PSLoad.h # PSLoad channel class
│ └── raspberry-pi/
│ └── thingsboard_bridge.py # Raspberry Pi ↔ ThingsBoard gateway
├── hardware/
│ ├── psload-module/
│ │ ├── PrecisionPowerSupply.png # PCB layout
│ │ └── PrecisionPowerSupply.pdf # Schematic (vector)
│ └── ui-controller/
│ ├── PreciPSLoadFront.png # PCB layout
│ └── PreciPSLoadFront.pdf # Schematic (vector)
├── docs/
│ └── images/
│ ├── system_overview.png # System architecture diagram
│ └── thingsboard_dashboard.png # ThingsBoard dashboard screenshot
├── README.md
├── LICENSE
└── .gitignore



