Electronic – What could be the reasons for a stepper motor stuttering with an A4988 driver

stepper motorstepper-driverstm32

I am using an A4988 Stepper Motor Driver, which is controlled with an STM32F767ZI on a Nucleo 144 board. The stepper motor takes 12 V with a maximum of 350 mA.

When powered, the motor simply flickers and stutters, but moves at a negligible speed.

Here is a circuit diagram of the setup, with voltage readings taking from a multimeter:

enter image description here

The potentiometer has been set correctly.

The same results occur even with two other A4988 drivers.

For reference, here is the code (though I don't believe this is a software issue):

main.c

#include "./headers/stm32f767xx.h"
#include <stdint.h>

int main(void)
{
    initMotor(0); // initialise the motor
    initLed(7); // initialise the led
    unsigned long a = 0;
    while (1)
    {
        if (a == 50000)
        {
            toggleLed(7); // this LED flashes a little quicker than twice per second 
            stepMotor(0); // output a pulse to the driver to step the motor, attached to PA2
            a = 0;
        }
        a++;
    }
}

./drivers/led.c

#include "../headers/stm32f767xx.h"

void initLed(int pin)
{
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // enable the GPIOB clock
    GPIOB->MODER |= (0x1 << (pin * 2)); // set to output
    GPIOB->OTYPER = 0x00; // push-pull mode
    GPIOB->ODR = 0x00; // set output register to 0 across all pins
}

void toggleLed(int pin)
{
    GPIOB->ODR ^= (0x1 << pin); // toggle the pin
}

./drivers/motor.c

#include "../headers/stm32f767xx.h"

void initMotor(int step_pin)
{
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // enable the GPIOA clock
    GPIOA->MODER |= (0x1 << (step_pin * 2)); // set to output
    GPIOA->OTYPER = 0x00; // push-pull mode
    GPIOA->PUPDR |= (0x2 << (step_pin * 2)); // pull down the pin specified
    GPIOA->ODR = 0x00; // set output register to 0 across all pins
}

void stepMotor(int step_pin)
{
    GPIOA->ODR |= (1 << step_pin); // output to the pin specified
    GPIOA->ODR &= ~(1 << step_pin); // reset the output back to 0
}

With this code, I was expecting the motor to take steady and even steps, rather than the backwards-and-forwards stuttering it does.

I would appreciate any suggestions for the direction I should take from here, or any suggestions as to what the issue could be.


After some discussion, I updated my code a little to slow it down, here it is:

(only included the updated files)

main.c

#include "./headers/stm32f767xx.h"
#include <stdint.h>

int main(void)
{
    initMotor(0);
    initLed(0);
    uint32_t a = 0;
    while (1)
    {
        if (a >= 150000)
        {
            toggleLed(0);
            stepMotor(0);
            a = 0;
        }
        a++; 
    }
}

./drivers/motor.c

#include "../headers/stm32f767xx.h"

void initMotor(int step_pin)
{
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOGEN;
    GPIOG->MODER &= ~(0b11 << (step_pin * 2));
    GPIOG->MODER |= (0b01 << (step_pin * 2));
    GPIOG->OTYPER &= ~(0b1 << step_pin);
    GPIOG->PUPDR |= (0b10 << (step_pin * 2));
    GPIOG->ODR &= ~(0b1 << step_pin);
}

void stepMotor(int step_pin)
{
    GPIOG->ODR ^= (0b1 << step_pin);
}

Best Answer

After many days, I have finally tracked down the causes of the issues.

  1. Software

I misunderstood the purpose of Pull Up/Pull Down resistors within the MCU. I thought floating pins (which the STEP pin on the A4988 driver is) had to be pulled up/down. However when changing the output of this pin, there is no need to use Pull Up/Pull Down resistors, simply setting the output is sufficient.

You can see the question and answer posted about my software here.

  1. Power source

Initially, I decided to use a 12V to 5V DC step down converter. This appeared to work at first (in the sense it was providing the correct voltage to the driver), but when I took readings of the voltage between the output pin on the Nucleo-144 and the GND pin on the driver, it gave fixed readings (there was no evidence of the output of the pin changing, despite the program running). Weirdly though, when taking a voltage reading between the GND pin on the Nucleo-144 board and the output pin instead, the voltage changed in the way it had been written to in the software. So, I connected up the 5V and GND pins on the Nucleo-144 to the driver power pins. When taking the reading between the GND pin on the driver and the output pin of the Nucleo-144, it was clear that this voltage issue had now been fixed.

  1. Setting the potentiometer

Having done a bit of searching around into motor stuttering, I came across this post on an arduino forum. In short, it mentions how the potentiometer being too high or too low can cause motor stuttering. I adjusted this, with the power running, until the motor was stepping nicely (without taking any backwards steps).