Share this

How to use pulse plus direction method to freely control the position of a stepper motor

2026-04-06 03:34:18 · · #1

General Introduction

Stepper motors are typically controlled using PWM (Pulse Width Modulation), which changes the frequency to control speed. The current position of the motor is determined by counting the number of pulses, making acceleration and deceleration planning easy. Alternatively, acceleration and deceleration smoothness can be disregarded, allowing the motor to start at a speed lower than the maximum starting speed and then stop the timer after a given number of pulses. However, none of these control methods achieve free control of the stepper motor's position, allowing it to follow any arbitrary position curve. This project aims to achieve free control of the stepper motor for accurate positioning. An encoder or potentiometer can be used as a controller. By manually turning the encoder, the stepper motor can either follow the encoder's movement or move according to a function curve.

Stepper motor drive

There are many types of stepper motor drivers, such as A4988 and TMC2208. The common driving method is pulse plus direction control, while some higher-end models use CAN or serial ports for control. This article introduces how to use the pulse plus direction method to freely control the position of a stepper motor!

Control Principles

Using a communication protocol to control a stepper motor allows for periodic synchronization of position to the driver, enabling free position control. The pulse plus direction method can also be abstracted as using a communication protocol to communicate with the driver, but in an incremental manner, accumulating pulses to obtain the target position.

The program uses two timers. One timer has an interrupt frequency of 1kHz to periodically sample the target position and calculate the current speed. The current speed value is used to modify the interrupt frequency of the other timer. Therefore, the second timer determines the deviation between the target position and the current position, then toggles the level to send a pulse, and simultaneously determines the direction to control the IO level accordingly.

In other functions, any form of position change can be given. According to the sampling theorem, any position change frequency not exceeding 500Hz should be normally sampled by a 1kHz timer interrupt. Since the pulse transmission needs to be at a certain frequency, the frequency of the second timer changes according to the target position change rate, which allows for smooth speed control and reduces CPU bandwidth usage. This method enables free control of the stepper motor, allowing for arbitrary control of the motor using encoders or functions!

Code Analysis

This program can control multiple stepper motors. The following are the stepper motor categories.

/*Stepper motor control class*/

typedef struct

{

volaTIle unsigned long *gpio_dir; // GPIO for motor direction control

volaTIle unsigned long *gpio_pluse; // Motor pulse GPIO

int pluse_count;

int goal_posit;

int last_position;

int cur_position;

int pos_bias;

int speed;

uint8_t status;

}stepMotor;

The core function for stepper motor control consists of a simple state machine. This function is executed in the second interrupt function mentioned above. It first obtains the current deviation, performs a state transition, and then sends a pulse.

void StepMotorCtrl(stepMotor *motor)

{

switch(motor->status)

{

case 0:

if (motor->goal_position != motor->cur_position) // Scan

{

motor->pos_bias = motor->goal_position - motor->cur_position; // Get the bias

motor->status = 1;

}

break

case 1:

if (motor->pos_bias > 0)

{

motor->pluse_count++;

*(motor->gpio_dir) = 1; // Positive direction

*(motor->gpio_pluse) = !*(motor->gpio_pluse);

if(motor->pluse_count == (motor->pos_bias * 2))

{

motor->cur_position += motor->pos_bias;

motor->pluse_count = 0;

motor->status = 0;

}

}

else

{

motor->pluse_count++;

*(motor->gpio_dir) = 0; // Negative direction

*(motor->gpio_pluse) = !*(motor->gpio_pluse);

if(motor->pluse_count == ((-motor->pos_bias) * 2))

{

motor->cur_position += motor->pos_bias;

motor->pluse_count = 0;

motor->status = 0;

}

}

break

default:

break

}

}


Read next

CATDOLL 108CM Dodo (TPE Body with Hard Silicone Head)

Height: 108cm Weight: 14.5kg Shoulder Width: 26cm Bust/Waist/Hip: 51/47/59cm Oral Depth: 3-5cm Vaginal Depth: 3-13cm An...

Articles 2026-02-22