SkillAgentSearch skills...

FastAccelStepper

A high speed stepper library for Atmega 168/328p (nano), Atmega32u4, Atmega 2560, ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C6, Atmel SAM Due, Raspberry pi pico and pico 2

Install / Use

/learn @gin66/FastAccelStepper

README

FastAccelStepper

GitHub tag PlatformIO Registry arduino-library-badge

Run tests Simvar tests

Matrix build for arduino using platformio (esp32, esp32c3, atmega328, pico2,...)

Build examples

Matrix build for espidf using platformio

Build espidf

Arduino and esp32

Arduino core v3.0.x are using esp-idf v5.0 up to v5.1 and FastAccelStepper will fail to compile.

Arduino core 3.1.0 will support ESP-IDF V5.3.0 (based on RC1)

Overview

This is a high speed alternative for the AccelStepper library. Supported are avr (ATmega 168/328/P, ATmega2560, ATmega32u4), atmelsam due, esp32, esp32s2, esp32s3, esp32c3, esp32c6, esp32p4, Raspberry pi pico and pico2.

For memory footprint information across supported architectures, see Memory Report.

The stepper motors should be connected via a driver IC (like A4988) with a 1, 2 or 3-wire connection:

  • Step Signal
    • avr atmega168/328/p: only Pin 9 and 10.
    • avr atmega32u4: only Pin 9, 10 and 11.
    • avr atmega2560: only Pin 6, 7 and 8. On platformio, this can be changed to other triples: 11/12/13 Timer 1, 5/2/3 Timer 3 or 46/45/44 Timer 5 with FAS_TIMER_MODULE setting.
    • esp32: This can be any output capable port pin, or use I2S for additional steppers:
      • I2S Mux mode: up to 32 additional steppers via external demultiplexer (IDF ≥5.3)
      • I2S Direct mode: 1-3 additional steppers using I2S controllers directly (IDF ≥5.3)
    • pico: Any GPIO up to 31
    • atmel sam due: This can be one of each group of pins: 34/67/74/35, 17/36/72/37/42, 40/64/69/41, 9, 8/44, 7/45, 6
    • Step should be done on transition Low to High. High time will be only a few us. On esp32 the high time is for slow speed fixed to ~2ms and high speed to 50% duty cycle. For pico direction delay is recommended
  • Direction Signal (optional)
    • This can be any output capable port pin.
    • esp32: Can also use I2S Mux slots for direction control (IDF ≥5.3)
    • pico: Any GPIO up to 31
    • Position counting up on direction pin high or low, as per optional parameter to setDirectionPin(). Default is high.
    • With external callback on esp32 derivates, even shift register outputs can be used
  • Enable Signal (optional)
    • This can be any output capable port pin.
    • esp32: Can also use I2S Mux slots for enable control (IDF ≥5.3)
    • Stepper will be enabled on pin high or low, as per optional parameter to setEnablePin(). Default is low.
    • With external callback, even shift register outputs can be used

FastAccelStepper offers the following features:

  • 1-pin operation for e.g. peristaltic pump => only positive move
  • 2-pin operation for e.g. axis control
  • 3-pin operation to reduce power dissipation of driver/stepper
  • Lower limit of 260s per step @ 16MHz aka one step every four minute (esp32/avr), 198s for sam due
  • fully interrupt/task driven - no periodic function to be called from application loop
  • supports acceleration and deceleration with per stepper max speed/acceleration
  • Allows the motor to continuously run in the current direction until stopMove() is called.
  • speed/acceleration can be varied while stepper is running (call to functions move or moveTo is needed in order to apply the new values)
  • Constant acceleration control: In this mode the motor can be controled by acceleration values and with acceleration=0 will keep current speed
  • Linear acceleration increase from/to standstill using cubic speed function - configurable by setLinearAcceleration()
  • Jump start from standstill - configurable by setJumpStart()
  • Auto enable mode: stepper motor is enabled before movement and disabled afterwards with configurable delays
  • Enable pins can be shared between motors
  • Direction pins can be shared between motors
  • Configurable delay between direction change and following step
  • External callback function can be used to drive the enable pins (e.g. connected to shift register) and, only esp32 derivates: the direction pins
  • No float calculation (log2 representation in range -64..64 with 16bit integer representation and 1/512th resolution)
  • Provide API to each steppers' command queue. Those commands are tied to timer ticks aka the CPU frequency!
  • Command queue can be filled with commands and then started. This allows near synchronous start of several steppers for multi axis applications.

Star History

Star History Chart

AI generated documentation

I have stumbled over an excellent AI-generated description of FastAccelStepper, which provides surprisingly deep and (mostly) correct implementation details. It would have costed me many days to write an equally good description with so many details and diagrams. This docu can be found here.

Source Code Structure

The src/ directory is organized into the following subdirectories:

| Directory | Purpose | |-----------|---------| | fas_arch/ | Platform abstraction: compiler/framework detection, interrupt macros, Arduino-like polyfills | | pd_avr/ | AVR pulse driver: timer-based stepper control for ATmega chips | | pd_esp32/ | ESP32 pulse driver: RMT, MCPWM/PCNT, and I2S-based stepper control | | pd_pico/ | RP2040/RP2350 pulse driver: PIO-based stepper control | | pd_sam/ | SAM Due pulse driver: timer-based stepper control | | pd_test/ | Test platform pulse driver: PC-based testing simulation | | fas_queue/ | Queue implementation: command queue management | | fas_ramp/ | Ramp calculation: acceleration/deceleration curves | | log2/ | Log2 representation: fixed-point arithmetic for speed calculations |

Platform-specific configuration constants (queue sizes, timing, feature flags) are defined in pd_*/pd_config.h files, which are included by fas_arch/common.h during the platform dispatch.

General behaviour of Moves

  • The desired end position to move to is set by calls to moveTo() and move()
  • The desired end position is in case of moveTo() given as absolute position
  • For move() the delta is added to the latest desired end position
  • The stepper tries to reach the given desired end position as fast as possible with adherence to acceleration/deceleration
  • If the stepper is e.g. running towards position 1000 and moveTo(0) is called at position 500, then the stepper will
    1. decelerate, which means it will overshoot position 500
    2. stop and accelerate towards 0
    3. eventually coast for a while and then decelerate
    4. stop
  • The stepper position is a 32bit integer variable, which wraps around for continuous movement. Example:
    • Assume counting up turns stepper clockwise, and counting down, anti-clockwise.
    • Current position is -2.000.000.000, move to 2.000.000.000.
    • Apparently the position has to count up, and count should run clockwise.
    • Implementation is done via difference of 32bit signed numbers, which can overflow (being legit).
    • The calculation is then: 2.000.000.000 - (-2.000.000.000) = 4.000.000.000
    • But 4.000.000.000 interpreted as signed 32bit is -294.967.296 => count down, turn anti-clockwise Means the position will count:
		-2.000.000.000
		-2.000.000.001
		-2.000.000.002
			:
		-2.147.483.647
		-2.147.483.648
		 2.147.483.647
		 2.147.483.646
		 2.147.483.645
			:
		 2.000.000.000

Comments to pin sharing:

  • Enable pin sharing: the common pin will be enabled for as long as one motor is running + delay off. Every motor will adhere to its auto enable delay, even if other motors already have enabled the pin.
  • Direction pin sharing: The direction pin will be exclusively driven by one motor. If one motor is operating, another motor will wait until the direction pin comes available

AVR ATMega 168/168P/328/328P

  • allows up to 50000 generated steps per second for single stepper operation, 37000 for dual stepper
  • supports up to two stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
  • Uses F_CPU Macro for the relation tick value to time, so it should now not be limited to 16 MHz CPU frequency (untested)
  • Steppers' command queue depth: 16

AVR ATMega 32u4

  • allows up to 50000 generated steps per second for single stepper operation, 37000 for dual stepper and 20000 for three steppers
  • supports up to three stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
  • Uses F_CPU Macro for the relation tick value to time, so it should now not be limited to 16 MHz CPU frequency (untested)
  • Steppers' command queue depth: 16

AVR ATMega 2560

  • allows up to 50000 generated steps per second for single stepper operation, 37000 for dual stepper and 20000 for three steppers
  • supports up to three stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
  • Uses F_CPU Macro for the relat
View on GitHub
GitHub Stars460
CategoryDevelopment
Updated1d ago
Forks95

Languages

C++

Security Score

100/100

Audited on Mar 20, 2026

No findings