element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Raspberry Pi
  • Products
  • More
Raspberry Pi
Blog Raspberry Pico stepper driver IC library, with example: Allegro A4988
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Raspberry Pi to participate - click to join for free!
Featured Articles
Announcing Pi
Technical Specifications
Raspberry Pi FAQs
Win a Pi
GPIO Pinout
Raspberry Pi Wishlist
Comparison Chart
Quiz
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 30 Apr 2025 2:28 PM Date Created
  • Views 723 views
  • Likes 7 likes
  • Comments 4 comments
Related
Recommended
  • raspberry
  • pico_pio_stepper_lib
  • pico
  • stepper-motor
  • c++

Raspberry Pico stepper driver IC library, with example: Allegro A4988

Jan Cumps
Jan Cumps
30 Apr 2025

Pico C++ library for Allegro A4988 stepper driver IC.

I created a generic stepper driver library, and made a first example:  Raspberry Pico stepper driver IC library, with example: Texas Instruments DRV8711. In this post, I create a plug-in replaceable driver for that Allegro IC.

The abstract base class that I created, supports 3 functions:

  • init()
  • microsteps()
  • enable()

Those will also be the functions that the new A4900 supports. While the TI IC in my first post used SPI for all configurations, this IC uses input pins:

image

image source: allegro a4988 datasheet

The pins that I want to control are the 3 microstep pins, and enable.I don't program sleep and reset. Both are pulled to VDD to disable them.

This is how the class will be used in the code:

import stepper_driver;    // wakeup class
import a4988_pico;        // driver classes and registers

// ...
const uint n_enable = 6U;
const uint ms1 = 7U;
const uint ms2 = 8U;
const uint ms3 = 9U;

// object to manage the a4988 IC used for motor1
using driver_t = a4988_pico::a4988_pico;
driver_t driver1(n_enable, ms1, ms2, ms3);

In the firmware, it will now work exactly the same as the TI DRV8711 of the previous post. No code changes needed.

Pico A4988 driver class

image

This is the class you'd instantiate, if you want to control a A4988 on a Pico:

class a4988_pico: public stepper_driver::stepper_driver {
public:
    a4988_pico( uint n_enable, uint ms1, uint ms2,  uint ms3) :
        n_enable_(n_enable), ms1_(ms1), ms2_(ms2), ms3_(ms3) {}

    virtual inline  bool init() override { 
        init_gpio();
        return true;
    }
    
    virtual bool microsteps(unsigned int microsteps) override { 
        unsigned int mode = true;
        switch (microsteps) {
        case 1:
            mode = 0x0000;
            break;
        case 2:
            mode = 0x0001;
            break;
        case 4:
            mode = 0x0002;
            break;
        case 8:
            mode = 0x0003;
            break;
        case 16:
            mode = 0x0004;
            break;
        default:
            assert(false); // develop check unsupported microstep
            mode = 0x0000;
        }
        gpio_put(ms1_, mode & 0b001);
        gpio_put(ms2_, mode & 0b010);
        gpio_put(ms1_, mode & 0b100);

        return true;
    }
    
    virtual void enable(bool enable) override {
        gpio_put(n_enable_, enable? 0 : 1);
    }
    
private:
    uint n_enable_;
    uint ms1_;
    uint ms2_;
    uint ms3_;

    virtual void init_gpio() {
        gpio_init(n_enable_);
        gpio_put(n_enable_, 1);
        gpio_set_dir(n_enable_, GPIO_OUT);

        gpio_init(ms1_);
        gpio_put(ms1_, 0);
        gpio_set_dir(ms1_, GPIO_OUT);

        gpio_init(ms2_);
        gpio_put(ms2_, 0);
        gpio_set_dir(ms2_, GPIO_OUT);

        gpio_init(ms3_);
        gpio_put(ms3_, 0);
        gpio_set_dir(ms3_, GPIO_OUT);
    }    
};

In action

Check the previous (DRV8711) post. This class makes the A4988 behave in exactly the same  way.
The protocol is different: GPIO instead of SPI, but the API is identical.

Here are the CMake sections:

include(FetchContent)

FetchContent_Declare(stepper
  GIT_REPOSITORY "https://github.com/jancumps/pio_stepper_lib.git"
  GIT_TAG "origin/main"
)
FetchContent_MakeAvailable(stepper)

# start DRIVER IC specific
FetchContent_Declare(stepper_driver
  GIT_REPOSITORY "https://github.com/jancumps/stepper_driver_lib.git"
  GIT_TAG "origin/main"
)
FetchContent_MakeAvailable(stepper_driver)

FetchContent_Declare(pico_a4988
  GIT_REPOSITORY "https://github.com/jancumps/pico_a4988_lib.git"
  GIT_TAG "origin/main"
  # prevent makefile execution (if any)
  SOURCE_SUBDIR =
)
FetchContent_MakeAvailable(pico_a4988)

add_library(driver)
target_sources(driver
        PUBLIC
        FILE_SET cxx_modules TYPE CXX_MODULES FILES
        ${stepper_driver_SOURCE_DIR}/source/stepper_driver.cpp
        ${pico_a4988_SOURCE_DIR}/source/a4988_pico.cpp
)
target_link_libraries(driver $<COMPILE_ONLY:hardware_gpio>)
# end DRIVER IC specific

# ...

target_link_libraries( your_firmware
        pico_stdlib
        hardware_gpio
# start DRIVER IC specific
        driver
# end DRIVER IC specific
        stepper
)

project: https://github.com/jancumps/pio_a4988_stepper

driver code (automatically fetched by the project): https://github.com/jancumps/pio_a4988_stepper

  • Sign in to reply
  • Jan Cumps
    Jan Cumps 3 months ago in reply to Robert Peter Oakes

    I have not, but I read up on their smart ones. The ones with configurable profiles.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Robert Peter Oakes
    Robert Peter Oakes 3 months ago

    nice post, very interesting it has been a long time since I was using those chips for stepper driving. Have you looked at driving trinamics stepper chips, there awesome and very quiet, the first choice for 3d printers and the like these days, all my 3d printers use them,. also for driving steppers, the libraries in Klipper are very good for real time (time synced etc) across many separate MCU's and abstracted through API's like your suggesting 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • DAB
    DAB 4 months ago

    Great update Jan.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz 4 months ago

    Good to see that example of how to create that derived class for your driver IC. I'm going to copy this for the Toshiba driver (once I've worked on the PCB a little bit.).

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube