Voron filament dryer
Arduino Nano firmware for a chamber dryer with four SHT31 humidity/temperature sensors, PID heater control, and PWM fan mixing.
Pinout (Arduino Nano)
All settings below are defined in include/config.h.
| Signal | Nano pin | Notes |
|---|---|---|
| I2C SDA | A4 | Shared bus (Wire) |
| I2C SCL | A5 | Shared bus (Wire) |
| TCA9548A mux | I2C 0x70 |
8-channel I2C multiplexer |
| SHT31 sensors | Mux channels 2, 3, 4, 5 | One sensor per channel |
| SHT31 address | 0x44 |
ADDR pin low; use 0x45 if ADDR is high |
| Fan | D5 | 24 V fan via N-channel MOSFET (hardware PWM) |
| Heater | A2 | Solid-state relay (burst control) |
USB serial: 115200 baud.
Dev setup
PlatformIO
This repo uses the PlatformIO CLI (see .vscode/tasks.json). If PlatformIO is already installed under ~/.platformio/penv/, use that directly — you do not need to run the web installer again.
~/.platformio/penv/bin/pio --version
~/.platformio/penv/bin/pio run # build
~/.platformio/penv/bin/pio run -t upload # flash
~/.platformio/penv/bin/pio device monitor # serial monitor
On Arch Linux / CachyOS, install via the package manager if you prefer:
sudo pacman -S platformio
If upload cannot find the port, add to platformio.ini:
upload_port = /dev/ttyUSB0 ; or /dev/ttyACM0, or a /dev/serial/by-id/... path
monitor_port = /dev/ttyUSB0
List available ports:
ls -la /dev/serial/by-id/
Serial port permissions (Linux)
Recommended — udev rules (one-time, works in Cursor without re-login):
sudo ./scripts/install-udev-rules.sh
# unplug and replug the Arduino
This installs PlatformIO’s 99-platformio-udev.rules (covers CH340 clone Nanos and other common adapters).
Alternative — group membership:
# Arch / CachyOS
sudo usermod -aG uucp $USER
You must fully log out of the desktop (not just reboot or open a new terminal) so id shows the new group. Cursor’s terminal often keeps the old group list until you restart Cursor after logging out.
Immediate workaround (no sudo, current terminal only):
sg uucp -c "$HOME/.platformio/penv/bin/pio run -t upload"
Verify access: test -w /dev/ttyUSB0 && echo ok
First run
-
Flash firmware and open the serial monitor at 115200 baud.
-
Confirm
TCA9548A detectedand four valid sensor channels (ch2–ch5). -
Find stir fan speed (optional — default is PWM 178, ~70%):
target 0 fancharsSweeps 30%, 100%, 60%, 80% fan — heats to max 60°C corner at 100% heater. Cools to 40°C avg between runs. Skips a fan speed if 60°C isn't reached in time. Optional midpoint refine if best isn't at 30% or 100%. Or:
python3 scripts/fan_characterize.py. When done,fanchars savewrites the winner to EEPROM (or skip and keep the 178 default). -
Tune heat PI (stored in EEPROM on autotune complete):
target 0 pid default autotune 50Emergency cutoff is fixed at 70°C — you can autotune at 50–55°C with ABS in the chamber while hot corners stay below that.
-
Dry at your target — fan runs at stir PWM (default 178) whenever target > 0, including heat-up. Override with
fan <pwm>;fan autoreturns to default. Fan auto-off below 40°C applies only in idle (target 0).
Send help over serial for all commands (target, fanchars, fan, log on/off, status, pid, etc.).
Raspberry Pi control
On the Pi, use the curses TUI to set targets and monitor the chamber (SSH with a TTY: ssh -t):
python3 scripts/capture_csv.py tui
Keys: 0 idle · t target · p material presets · f/F fan · l CSV log · a autotune · : command · q quit
Headless CSV-only logging (e.g. systemd) is documented in pi-instructions.md.
Filament drying table
| Filament | Dryer temperature | Drying time (hours) |
|---|---|---|
| PLA | 50–55 °C (122–131 °F) | > 6 |
| ABS | 60–65 °C (140–149 °F) | > 6 |
| PETG | 60–65 °C (140–149 °F) | > 6 |
| Nylon | 70–75 °C (158–167 °F) | > 24 |
| Desiccants | 60–65 °C (149 °F) | > 12 |
| PVA | 40–45 °C (104–113 °F) | > 24 |
| TPU/TPE | 50–55 °C (122–131 °F) | > 8 |
| ASA | 60–65 °C (140–149 °F) | > 8 |
| PP | 50–55 °C (122–131 °F) | > 6 |
| HIPS | 60–65 °C (140–149 °F) | > 8 |
| PC | 70–75 °C (158–167 °F) | > 12 |
| PEEK | 120–125 °C (248–257 °F) | > 24 |