firmware/
├── controller/ # Main motion controller (Teensy 4.1)
├── joystick/ # Joystick/control panel (Teensy LC)
└── legacy/ # Archived firmware versions
PlatformIO is the recommended build system for firmware development. It provides consistent builds, dependency management, and command-line tooling.
# Using pip
pip install platformio
# Or using Homebrew (macOS)
brew install platformio# Build and upload controller firmware
cd firmware/controller
pio run -t upload
# Build and upload joystick firmware
cd firmware/joystick
pio run -t uploadImportant: Before uploading, verify only one Teensy is connected:
pio device listIf multiple devices appear, disconnect the extras before uploading. The upload tool may not warn you and could flash the wrong board.
| Command | Description |
|---|---|
pio run |
Compile firmware |
pio run -t upload |
Compile and upload to device |
pio run -t clean |
Clean build artifacts |
pio device monitor |
Open serial monitor |
pio run -t upload && pio device monitor |
Upload and monitor |
pio test -e native |
Run unit tests (no hardware required) |
Unit tests run on your host machine without needing hardware:
cd firmware/controller
pio test -e nativeExample output:
test_crc8: test_crc8_empty_data [PASSED]
test_crc8: test_crc8_single_byte_zero [PASSED]
test_protocol: test_command_ids_are_unique [PASSED]
...
================= 11 test cases: 11 succeeded =================
Tests are located in controller/test/ and use the Unity test framework.
After successful compilation, the firmware binary is located at:
.pio/build/teensy41/firmware.hex(controller).pio/build/teensyLC/firmware.hex(joystick)
Device not found during upload:
- Ensure Teensy is connected via USB
- Check that no other application is using the serial port
- If firmware is unresponsive, press the button on Teensy to enter bootloader mode
Permission denied (Linux):
sudo usermod -a -G dialout $USER
# Log out and back inFirst build is slow:
- PlatformIO downloads toolchains and libraries on first run
- Subsequent builds are much faster (incremental compilation)
If you prefer Arduino IDE:
- Install Teensyduino
- Open
controller/main_controller_teensy41.inoin Arduino IDE - Select Board: "Teensy 4.1"
- Click Upload
- Install Teensyduino
- Open
joystick/control_panel_teensyLC.inoin Arduino IDE - Select Board: "Teensy LC"
- Click Upload
The main motion controller firmware for Teensy 4.1. Handles:
- XYZ stage motion control (TMC4361A + TMC2660 drivers)
- Illumination control (lasers and LED matrix)
- Camera triggering
- Serial communication with host software
Hardware-specific settings are in src/def/def_v1.h. This includes:
- Motor parameters (steps per rev, microstepping, current)
- Stage limits and velocities
- Joystick sensitivity
- Limit switch polarity
Disable Laser Safety Interlock:
By default, the firmware includes laser safety interlock detection. To disable it:
PLATFORMIO_BUILD_FLAGS="-DDISABLE_LASER_INTERLOCK" pio run -e teensy41 -t uploadWARNING: Only use this flag for systems without lasers installed. Disabling the interlock removes laser safety protection.
controller/
├── main_controller_teensy41.ino # Entry point
├── platformio.ini # PlatformIO config
├── test/ # Unit tests (run with pio test -e native)
│ ├── test_crc8/ # CRC8 checksum tests
│ └── test_protocol/ # Protocol/command ID tests
└── src/
├── commands/ # Command handlers
│ ├── commands.cpp/h # General commands
│ ├── light_commands.cpp/h # Illumination control
│ └── stage_commands.cpp/h # Motion control
├── def/
│ └── def_v1.h # Hardware configuration
├── tmc/ # TMC stepper driver library
├── utils/
│ └── crc8.cpp/h # CRC calculation
├── init.cpp/h # Initialization routines
├── operations.cpp/h # Main loop operations
├── serial_communication.cpp/h # Serial protocol handling
├── functions.cpp/h # Utility functions
├── globals.cpp/h # Global state variables
└── constants.h # Constants and pin definitions
Control panel firmware for Teensy LC. Handles:
- Joystick X/Y axis input
- Rotary encoder for focus control
- Button states
- Serial communication with main controller
Archived firmware versions kept for reference. Not actively maintained.