Skip to the content
2 layers98 × 68.4 mmReflow low v, the printed circuit board in 3D

A reflow oven controller: RP2040, PT100 RTD, touchscreen profile editor, feed-forward + PID with automatic oven calibration, and a sealed 3D-printed mains enclosure.

Size
98 × 68.4 mm
Copper layers
2
Thickness
1.6 mm
Parts
14
Nets
49
Pads
97
Tracks, vias
125, 112
Pours
1
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
2 Oct 2026
Updated
2 Oct 2026

Overview

Reflow low v is an open-source printed circuit board by Greentalinjo, from the Greentalinjo/GreenToaster repository on GitHub. It is a 2-layer board of 98 × 68.4 mm with 14 parts on 49 nets, routed with 125 tracks and 112 vias.

Its parts include 5 connectors, 5 switches, 2 ICs, 1 capacitor and 1 diode. It belongs with the RP2040 boards of this library.

README

README.md

GreenToaster - reflow oven controller

GreenToaster

A reflow oven controller that turns an ordinary toaster oven into a reflow oven for soldering surface-mount boards. An RP2040 reads a platinum RTD probe in the oven, follows a solder profile on a 3.5" touchscreen, and switches the oven's mains through a solid-state relay, all inside a sealed 3D-printed enclosure that sits between the wall socket and the oven.

Preface

Reflowing a board properly means following a temperature profile: preheat, soak, a short peak above the solder's melting point, then cooling. A toaster oven gets hot enough, but its thermostat can't follow a curve. GreenToaster replaces the thermostat. Plug the oven into GreenToaster, put the probe in the oven, pick a profile, and the controller drives the heater to track it.

[!WARNING] This project switches mains voltage (230 V AC). The power board, the SSR and the wiring in the tower carry lethal voltages. Only build it if you are competent with mains wiring, keep the tower closed when powered, and fit an independent thermal cutoff (a bimetal snap-disc or a thermal fuse) in series with the oven's heater. The firmware's safety layers can't help if the microcontroller itself fails. Never leave the oven unattended.

At a glance
ControllerWeAct RP2040-Pico (Raspberry Pi Pico-compatible)
Display3.5" 480 × 320 ILI9488 SPI touchscreen (LCDwiki MSP3520)
SensorPT100/PT1000 platinum RTD through a MAX31865 module
OutputSSR on the oven's mains, behind a five-switch hardware interlock
Controlfeed-forward + PID, tuned automatically by a calibration run on your oven
Power230 V AC in, 5 V from an on-board HLK-10M05 supply
Profiles2 built in (Sn63Pb37 leaded, SAC305 lead-free) + 12 of your own
FirmwareC++ on the Arduino-Pico core, built with PlatformIO

Contents

  1. How it fits together
  2. Stage by stage
  3. What you can configure
  4. Building one
  5. The case
  6. Repository layout

1. How it fits together

The design is split along the line every mains project should be: a mains side, sealed in the rear "tower" of the case, and a low-voltage side in the front "wedge", separated by a solid firewall with a single low-voltage pass-through.

mermaid
flowchart LR
    subgraph mains["Mains side: the tower"]
        IN["C14 inlet<br/>230 V AC"] --> PB["Power board<br/>fuse, MOV, X-cap, choke<br/>HLK-10M05"]
        IN --> SSR["SSR<br/>on heatsink"]
        SSR --> OUT["Outlet<br/>the oven plugs in here"]
        FAN["60 mm fan<br/>cools the SSR heatsink"]
    end
    subgraph lv["Low-voltage side: the wedge"]
        CB["Controller board<br/>RP2040"]
        LCD["3.5in touchscreen"]
        SW["SW1..SW5<br/>interlock chain"]
        RTD["MAX31865<br/>RTD amplifier"]
    end
    PB -- "5 V" --> CB
    CB -- "5 V" --> FAN
    CB <--> LCD
    PROBE["PT100 probe<br/>in the oven"] --> RTD --> CB
    CB -- "SSR drive" --> SW -- "only if all 5 closed" --> SSR

Every 250 ms during a run:

  1. The RP2040 reads the oven temperature from the RTD.
  2. It works out where the profile says the temperature should be.
  3. It sets the heater power.

That power becomes on/off time within a two-second window on the SSR, which switches the oven's mains. The SSR drive passes through five physical switches on the front panel. If any one is open, the oven cannot heat, whatever the firmware is doing.


2. Stage by stage

Stage 1 — The power board (hardware/power-board)

A small single-purpose mains board, 116 × 55 mm, that turns the wall supply into the controller's 5 V. In signal order:

PartJob
F1, 1 A fuse (5 × 20 mm)in the line conductor, first thing after the input terminal
RV2, 10D561K varistorclamps mains surges, behind the fuse so a failing MOV blows it
C1, 100 nF / 275 V X-capacitorsuppresses differential-mode noise
FL1, 10 mH common-mode chokekeeps the converter's switching noise off the mains
U1, HLK-10M05isolated AC/DC module, 5 V at up to 2 A (10 W)
C2, 220 µFbulk capacitance on the 5 V output

Mains comes in on J1 (pin 1 neutral, pin 2 line) and 5 V leaves on J2. Both are large 7.62 mm screw terminals. The board carries no logic at all: the SSR and the oven outlet are wired directly in the tower.

Power board

Stage 2 — The controller board (hardware/controller-board)

A 98 × 68.5 mm carrier with ground poured on both sides. It holds the microcontroller and connects it to everything else:

RefWhatConnects to
U2WeAct RP2040-Picothe brain
U3MAX31865 RTD modulethe oven probe, on its own SPI bus (SPI0)
J314-pin headerthe touchscreen and its XPT2046 touch controller, sharing SPI1
SW1–SW5panel-mount SPDT togglesthe interlock chain (stage 4)
J5screw terminalthe SSR's control input
J6screw terminal5 V in, from the power board
J22-pin headerthe heatsink fan, on the 5 V rail
D1, C31N5817, 100 µFreverse-polarity clamp and bulk capacitance on the 5 V input
J44-pin headernot connected electrically

5 V from J6 feeds the Pico's VSYS. The WeAct module's own USB connector also feeds VSYS through its on-board diode, so USB alone powers the board for flashing. The display is write-only: its data-out pin isn't connected, so only the touch controller talks back on SPI1. The full pin map is in firmware/include/board_pins.h.

Controller board, switch side Controller board, Pico side

Stage 3 — Reading the temperature (firmware/src/sensor.cpp)

The probe is a platinum RTD read by a MAX31865 in continuous conversion mode. The chip converts on its own, and the firmware just collects a sample every 250 ms, so reading the oven never stalls the touchscreen. Resistance becomes temperature through the Callendar–Van Dusen equation for IEC 60751 platinum sensors.

Faults are decoded rather than hidden. NO SENSOR, RTD OPEN, RTD SHORT, RTD OV/UV or RTD RANGE replaces the reading on screen. Each detected fault is cleared and fault detection re-armed, so a passing glitch can't latch.

Stage 4 — The interlock chain (firmware/src/interlock.cpp)

The SSR is driven from GPIO 16 through all five panel switches in series:

text
GP16 → SW1 → SW2 → SW3 → SW4 → SW5 → J5 (SSR+)
          ↓      ↓      ↓      ↓      ↓
        GP28   GP27   GP26   GP22   GP21     (taps, read by the firmware)

Opening any switch physically cuts the SSR drive. The taps between the switches, held low by the RP2040's internal pull-downs, let the firmware see how far the chain is closed. It counts closed switches from SW1 onwards, so a floating input can never report more than are really closed.

Reading the taps needs GP16 high, and GP16 high with all five closed is the heater on. So while arming, the firmware senses with 50 µs pulses, at most 50 per second, which is far too little to heat anything. During a run it reads the taps for free during the SSR's on-time.

Stage 5 — The control loop (firmware/src/control.cpp)

The controller is feed-forward plus PID:

text
duty = feed_forward(setpoint) + PID(setpoint − measured)
  • Feed-forward comes from a first-order model of your oven, measured by the dry run (stage 6). From the oven's gain (°C per % of power), time constant and ambient temperature, it works out the power the profile needs, so the oven tracks a ramp rather than lagging behind it. It's evaluated one oven dead-time ahead, so the power arrives when it's needed.
  • PID only corrects what the model gets wrong. It uses derivative-on-measurement, so there's no kick when the profile changes slope. It uses conditional integration, so it doesn't wind up while the heater is saturated.
  • Peak coast: on the final climb, the heater is cut 3 °C short of the peak and the elements' stored heat carries the rest. This is decided before the PID runs, so the integrator can't wind up during the coast.
  • The run starts from the measured temperature, not an assumed ambient, so starting in a still-warm oven doesn't overshoot the first section.

The SSR is time-proportional over a 2 s window, which is 100 mains half-cycles at 50 Hz, so the duty resolution is 1 %.

Stage 6 — Calibrating to your oven: the dry run

Instead of hand-tuning, the controller measures your oven in an automatic dry run, with the oven empty and cold (it refuses to start above 50 °C):

PhaseHeaterRuns untilMeasures
1 baselineoff15 sambient temperature
2 step response100 %200 °Cdead time and peak heating rate
3 relay autotune70 % / off around 180 °C4 clean oscillationsultimate gain Ku, period Pu, and the power needed to hold 180 °C
4 coolingoffdown to 150 °Cpassive cooling rate

Phase 3 is the Åström–Hägglund relay method, which characterises the oven at reflow temperature. The PID gains use the no-overshoot rule (Kp = 0.2·Ku, Ti = 0.5·Pu, Td = 0.33·Pu), because overshoot on a reflow profile is what damages boards. Each phase has a timeout, so a fault can't leave it running.

At the end, the screen shows an Oven characterised card: the oven's gain, heating and cooling rates, Ku/Pu, and the resulting PID gains. The model is saved to flash (/oven.bin) and survives reflashing. Start Reflow is refused until a dry run has succeeded.

Stage 7 — The touchscreen UI (firmware/src/screens_*.cpp)

text
Home ──┬── Profiles ─── Profile view ──── Arming ──── Run (live graph)
       │                 (graph, Start Reflow / Dry Run)
       └── New Profile ─── Section editor
  • Home: the live temperature, plus Profiles and New Profile.
  • Profiles: the built-ins and your saved profiles, five per page. Saved ones have a delete button; the built-ins can't be deleted.
  • Profile view: the profile as a temperature-against-time graph, with Start Reflow and Dry Run.
  • Arming: five bars that fill in as you close SW1 to SW5. The run starts the moment the fifth one closes.
  • Run: the target curve in orange and the measured temperature in cyan on one graph, with target, elapsed time, the heater duty and STOP. When the profile's temperature starts falling, it tells you to open the oven door, since cooling is done by the door.
  • New Profile / Section editor: build a profile from sections, each a target temperature and the time to reach it. New profiles are named Profile 1, Profile 2, and so on.

A four-button rail down the right edge (UP, DOWN, SAVE, BACK) keeps the same meaning on every screen. Held buttons auto-repeat after 450 ms, so stepping a temperature up doesn't take dozens of taps. The case's bezel covers the panel's left edge, so every screen is laid out clear of it.

Safety layers

  1. The hardware interlock: the SSR cannot be driven unless all five switches are closed.

  2. The independent thermal cutoff you fit in series with the heater (see the warning above).

  3. Software aborts:

    • temperature above 280 °C;
    • the sensor unreadable for 3 s;
    • the interlock opening while the heater is on;
    • over 95 % power for 3 minutes with less than a 3 °C rise. This catches a dead element, a dead SSR, or a probe that isn't in the oven.

    A run also won't start if the sensor is faulty, the oven is already over 280 °C, or another run is in progress.

  4. A hardware watchdog (8 s), armed as soon as any run is armed and kept until the next reboot. If the firmware hangs, the reset drops every pin to high impedance, which the SSR reads as off.


3. What you can configure

The RTD module — firmware/platformio.ini

Build flagDefaultSet it to
MAX_RREF_OHMS430.0fthe module's reference resistor: 4300 marking = 430 Ω (PT100), 4301 = 4.3 kΩ (PT1000)
MAX_RNOMINAL_OHMS100.0fthe probe's resistance at 0 °C: 100 for PT100, 1000 for PT1000
MAX_WIRES32, 3 or 4, matching the solder jumpers on the module
MAX_FILTER_50HZ11 for 50 Hz mains, 0 for 60 Hz

Profiles

Built in, and can't be deleted:

ProfileSections (target °C / seconds to reach it)
Sn63Pb37 leaded150 / 90 → 180 / 60 → 235 / 45 → 235 / 20 → 50 / 100
SAC305 lead-free150 / 90 → 200 / 90 → 249 / 45 → 249 / 20 → 50 / 110

Your own: up to 12 profiles of up to 16 sections, built on the touchscreen. A section is a ramp: a target temperature (up to 300 °C, in 5 °C steps) and the time to reach it from the previous section (up to 900 s, in 5 s steps). A hold is a section that repeats the previous temperature. Profiles are stored in flash, written through a temporary file so a power cut can't corrupt them.

The serial console (115200 baud)

KeyDoes
traw RTD dump: ADC code, resistance and temperature. A PT100 at 25 °C reads about 109.7 Ω
mprints the calibrated oven model and PID gains
ishows how many interlock switches are closed
TSSR self test: 25 % duty (0.5 s on, 1.5 s off) once the interlock closes, for up to 60 s. It stops early if the oven warms by 25 °C or reaches 80 °C
xaborts a run
ctouch calibration (see below)

While the oven is being driven, the board also prints one CSV telemetry line per second (R,t_s,mode,phase,temp_c,set_c,duty_pct,armed), which firmware/scripts/log_run.py captures to a log file.

Other settings

WhereWhat
src/main.cpp, gTouchCalibrationtouch calibration. Send c, take the display out of the case first so you can reach the corner targets, then paste the printed values here
platformio.ini, SPI_FREQUENCYthe display's SPI clock (27 MHz). Lower it if the image corrupts
platformio.ini, board_build.filesystem_sizethe 4 MB flash partition for profiles and the oven model. Changing it orphans what's already stored
src/control.cppthe safety limits, the SSR window and the dry-run phases. Change them only if you understand them

4. Building one

The boards

Both are 2-layer boards made with KiCad 10. Open the .kicad_pro in each folder under hardware/ and plot gerbers and drill files. Each project carries copies of every symbol and footprint it uses, so the boards open and plot without any extra libraries. Schematic PDFs are in docs/.

Power boardController board
U1HLK-10M05U2WeAct RP2040-Pico
F11 A fuse, 5 × 20 mm, with holderU3MAX31865 RTD module (8-pin)
RV210D561K varistorJ31 × 14 header, to the MSP3520 display
C1100 nF 275 V X2, 10 mm pitchSW1–SW5SMTS-102 SPDT toggle switches
FL110 mH common-mode choke, UU9.8J5, J67.62 mm 2-way screw terminals
C2220 µF, 6.3 mm radialJ2, J41 × 2 and 1 × 4 headers
J1, J27.62 mm 2-way screw terminalsD1, C31N5817, 100 µF

Also needed: an SSR with a heatsink, a 60 mm 5 V fan, a C14 inlet, an outlet for the oven, a PT100 probe (3-wire to match the default build), mains-rated wire, and the thermal cutoff.

The firmware

sh
cd firmware
pio run                 # build
pio run -t upload       # flash
pio device monitor      # serial console, 115200 baud

Uploading needs no driver. scripts/upload_uf2.py resets the board into its bootloader and copies the firmware onto the RPI-RP2 drive, so you don't need picotool, Zadig or the BOOT button.

First use

  1. Power up and check the banner on the serial console. It reports the storage, the RTD settings and whether the oven is calibrated.
  2. Check the probe with t at room temperature. If it's off, fix the RTD build flags.
  3. Check the interlock with i, closing the switches one at a time.
  4. Optionally test the SSR with T.
  5. Run a Dry Run once from a cold, empty oven: open any profile and tap Dry Run.
  6. Reflow: pick a profile, tap Start Reflow, close the five switches, and open the door when the screen says so.

5. The case

Five printable parts, in case/:

FilePart
reflow_tower.stlthe sealed mains tower: the power board, the SSR on its heatsink, the fan, the C14 inlet and the oven outlet, with the firewall at its front
reflow_lid.stlthe tower's vented lid
reflow_wedge.stlthe slanted front wedge: the low-voltage side, holding the controller board behind the panel
reflow_panel.stlthe faceplate, with the display window and the five switch holes. The display screws to it
reflow_fanbar.stlthe fan bar that mounts the cooling fan

Tower   Wedge

Panel Lid Fan bar

The mains side and the low-voltage side never share an open space. The only link between them is a single low-voltage pass-through in the firewall.


6. Repository layout

text
hardware/
  power-board/          KiCad project: the 230 V AC to 5 V board
  controller-board/     KiCad project: the RP2040 controller board
firmware/               PlatformIO project
  platformio.ini          build settings, display and RTD configuration
  include/, src/          the firmware (pin map in include/board_pins.h)
  scripts/                UF2 uploader, run logger, interlock watcher, layout check
case/                   STL files for the five printed parts
docs/
  power-board-schematic.pdf
  controller-board-schematic.pdf
  images/               renders used in this README

Parts

14
QtyValueFootprintReferences
5SW_SPDTsmts-102:SW_Toggle_SPDT_SMTS-102SW1, SW2, SW3, SW4, SW5
1100uFCapacitor_THT:CP_Radial_D5.0mm_P2.00mmC3
11N5817Diode_THT:D_DO-41_SOD81_P10.16mm_HorizontalD1
1Conn_01x04Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_VerticalJ4
1Conn_01x14Connector_PinHeader_2.54mm:PinHeader_1x14_P2.54mm_VerticalJ3
1Fan ConnectorConnector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_VerticalJ2
1MAX31865_RTD_Module31865:MAX31865_RTD_Module_2U3
1Power Connectorbig_terminal:TerminalBlock_E-Simpo_128_1x02_P7.62mmJ6
1SSR Connectorbig_terminal:TerminalBlock_E-Simpo_128_1x02_P7.62mmJ5
1WeAct-RP2040-PicoWeAct-RP2040-Pico:WeAct-RP2040-PicoU2

More from Greentalinjo/GreenToaster

1
  • 2 layers116 × 55 mmReflow, the printed circuit board in 3D

    Reflow

    Greentalinjo/GreenToaster

    A reflow oven controller: RP2040, PT100 RTD, touchscreen profile editor, feed-forward + PID with automatic oven calibration, and a sealed 3D-printed mains enclosure.

    8 parts

Similar boards

  • 2 layers116.8 × 30 mmType d, the printed circuit board in 3D

    Type d

    google/mozc-devices

    Circuit diagrams and firmware source code for Gboard DIY keyboards

    14 parts3kApache-2.0
  • 2 layers32 × 22 mmDiff driver, the printed circuit board in 3D

    Diff driver

    rene-dev/stmbl

    AC Servo Driver for STM32F4

    14 parts990GPL-3.0
  • 2 layers34 × 45 mm2032Charger, the printed circuit board in 3D

    2032Charger

    hackclub/OnBoard

    💡 Join 1,000 teenagers and make your first PCB with a $100 grant!

    14 parts915
  • 2 layers34 × 109.9 mmTdisplay s3, the printed circuit board in 3D

    Tdisplay s3

    landonr/homeThing

    Wifi Smart Home Remotes that run on ESPHome

    14 parts551GPL-3.0
  • 2 layers45.3 × 42.7 mmMainPcb, the printed circuit board in 3D

    MainPcb

    adamb314/ServoProject

    Getting the most out of your hobby servo

    14 parts545
  • 2 layers42.5 × 28.8 mmC5VRX JACK DIY, the printed circuit board in 3D

    C5VRX JACK DIY

    Twotoz/C5VRX

    Ultra-minimal, zero-CPU 5.8 GHz analog FPV video receiver using ESP32-C5 Wi-Fi 6 PHY MODEM_DIAG, BitScrambler WBFM demodulation & resistor DAC CVBS

    14 parts515GPL-3.0
  • 2 layers62 × 24 mmMai button, the printed circuit board in 3D

    Mai button

    whowechina/mai_pico

    Pico controller for Maimai

    14 parts475

Questions

How big is the Reflow low v PCB?

It measures 98 × 68.4 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Reflow low v use?

14 parts. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Reflow low v KiCad files?

From the Greentalinjo/GreenToaster repository on GitHub, at the commit this page was made from: the board is hardware/controller-board/reflow_low_v.kicad_pcb and its schematic hardware/controller-board/reflow_low_v.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Reflow low v design in my own project?

Its repository states no licence, so its author keeps all rights: ask Greentalinjo before reusing the design.