Electronic leadscrew firmware for a small lathe using an Arduino Nano/Uno-class ATmega328P board, spindle encoder, stepper driver, and 16x2 I2C LCD.
The firmware supports synchronized threading, spindle-synchronized feed, a simple cycle mode, backlash-aware return moves, calibration, EEPROM settings, and a one-knob/one-button user interface.
This is working firmware, but it controls real machine motion. Treat it as experimental until it has been tested on your exact lathe, encoder, stepper driver, motor, power supply, and wiring.
The current sketch compiles for arduino:avr:nano:
Sketch uses 29682 bytes (96%) of program storage space.
Global variables use 1078 bytes (52%) of dynamic memory.
- Threading mode with TPI or metric pitch input.
- Feed mode with signed feed direction.
- Cycle mode with synchronized forward feed, dwell, return, and creep-to-start.
- Spindle quadrature direction from encoder A/B.
- EEPROM-stored settings with startup sanitization.
- RPM limit trip.
- Calibration routine for steps/mm correction.
- 16x2 LCD diff rendering to reduce I2C traffic.
- One rotary encoder with short/long press controls.
- Optional serial bench UI for testing.
The code is intentionally ATmega328P-specific. Timer1 and direct port writes are used for deterministic step timing.
| Function | Arduino Pin | Notes |
|---|---|---|
| Spindle encoder A | D2 / INT0 |
Interrupt on rising edge |
| Spindle encoder B | D4 |
Sampled for direction |
| Stepper STEP | D9 |
Direct port output |
| Stepper DIR | D8 |
Direct port output |
| Stepper ENABLE | D10 |
Active low by default |
| UI encoder CLK | A0 |
Pullup input |
| UI encoder DT | A1 |
Pullup input |
| UI encoder switch | A2 |
Pullup input |
| LCD SDA/SCL | Arduino I2C | 16x2 I2C LCD at 0x27 |
Default assumptions:
- Board: Arduino Nano/Uno, ATmega328P, 16 MHz.
- LCD: 16x2 I2C backpack at address
0x27. - Stepper driver: STEP/DIR/ENABLE style driver.
- ENABLE polarity: active low.
This firmware can move a lathe carriage. A software bug, wiring fault, wrong setting, missed step, missed encoder pulse, or driver fault can crash the machine.
Before using it on the lathe:
- Test with the stepper driver disabled or mechanically disconnected.
- Test with the motor unloaded.
- Verify carriage direction in every mode.
- Verify spindle encoder direction.
- Verify encoder PPR, leadscrew pitch, microsteps, belt ratio, and calibration.
- Verify the RPM limit.
- Verify emergency stop behavior.
- Keep a physical emergency stop in the motor power path. Do not rely on the Arduino as the only stop.
See docs/SAFETY.md and docs/TESTING.md.
The UI uses one rotary encoder with a push button.
Core rules:
- Rotate: move left/right through choices or change the selected digit.
- Short press: select, start, confirm, or advance to the next digit.
- Long press: stop, cancel, back, or menu.
Standby:
- Rotate selects
THRD,FEED, orCYCL. - Short press enters the selected mode.
- Long press opens the menu.
Thread/feed/cycle screens:
- Short press on the action field starts/arms/resumes.
- Short press on a parameter edits it.
- Long press stops active motion.
- If motion is not active, long press returns to standby.
Menu and calibration screens:
- Short press enters/commits the selected item.
- Long press cancels or backs out.
Optional serial bench controls are available at 115200 baud when ELS_ENABLE_SERIAL_UI is set to 1 before compilation:
| Command | Action |
|---|---|
l |
Rotate left |
r |
Rotate right |
p |
Short press |
lp |
Long press |
Install the Arduino AVR core and the LiquidCrystal_I2C library, then compile for Arduino Nano/Uno:
arduino-cli compile --fqbn arduino:avr:nano .The sketch is close to the Nano flash limit, so the serial bench UI is disabled by default. To enable it, set:
#define ELS_ENABLE_SERIAL_UI 1before the default ELS_ENABLE_SERIAL_UI definition in the sketch.
arduino_ELS_V0_1.ino- main firmware sketch.docs/SAFETY.md- machine safety notes.docs/TESTING.md- pre-cut testing checklist.docs/UI.md- UI behavior summary.CHANGELOG.md- release notes.LICENSE- MIT license.
MIT. See LICENSE.