Section 10: Understanding Positioning
The advanced features such as StallGuard can be purchased in our PDF guide here. |
When we tell the motor to move to position 5000 or 50000, what does that mean? How does that translate to a value we can understand? In the image below we have a blue object on a track. The left side is position 0 and the right side is position 5000. Whenever we tell a position, imagine your motor moving an object like this.
The value 5000 is based on step count. Remember the section about microsteps where we discussed how many steps are in one revolution.
When we tell the motor to move 5000 steps we are telling the motor how many microsteps to move. If we have 256 microsteps set it will require many more steps to move 1 meter than if we have 64 microsteps.
But using steps to move is very difficult to understand as a distance, so we need something we can understand like inches or centimeters. In this case I will work with inches which you can convert to different units.
Question: If we attach a rope or belt to the motor and want to move it just 1 inch, how many steps will we need to move?
First, that depends on your microstep setting! Second, it depends on the diameter of your pulley.
Assuming a 64 microstep setting and a 1-inch diameter pulley on the motor, to move 1 linear inch we need to move 4074.37 steps.
Since there are 200 steps per revolution and 64 microsteps per steps, that means each full revolution of the motor is 12,800 steps.
One full revolution of a 1 inch diameter pulley will move the pulley a total or 3.14159 linear inches. This can be figured out by converting radius to circumference.
2pi x 0.5 inches = 3.14159 inches
Now we divide the steps per revolution by 3.14159
12,800 / 3.14159 = 4,074 steps. This is the number of steps we need to command to move our belt one inch.
Starting a Movement
Let’s look at our motor loop function.
When you see "stepper->" this means we are accessing the FastAccelStepper object and passing values to it. It will then control the stepper motor.
We begin by setting the current position of the motor. This happens right before the while(true) because we only want to set it one time. This can be done in the setup() loop as well
stepper->setCurrentPosition(0); |
Next, we tell the motor to move TO a certain position. Remember, this library supports multiple types of movement commands:
- move()
- moveTo()
- runForward()
- runBackward()
- applySpeedAcceleration()
- moveByAcceleration()
I think that positioning moveTo() is the most important to understand, which is why this tutorial will use it. Here we tell it to move to the move_to_step position, which was set earlier to 3200 (3200 is an example, set it to whatever you want)
The ESP32 will now send 3200 HIGH pulses to the TMC2209 to get it to move 3200 steps.
stepper->moveTo(move_to_step); |
While the motor starts moving to our new position, we need to wait. The while loop will now continually check if the motor is still moving. If it’s moving, it will run the loop. Once the motor stops moving, the while loop will exit.
This loop does two things. First, it has a delay. The delay is there to just kill time while we wait for the motor to stop.
The second thing is we check if stallGuard has triggered a stall. The stall gets triggered in a separate interrupt that we created during setup using this code:
attachInterrupt(digitalPinToInterrupt(STALLGUARD_PIN), stalled_position, RISING); |
The TMC2209 will set the STALLGUARD_PIN to high when it detects a stall. By attaching an interrupt to this pin and monitoring for a rising edge, we can immediately detect a stall and react to it right away. The interrupt function sets a Boolean flag to true.
void IRAM_ATTR stalled_position() { stalled_motor = true; } |
In the if loop, we check if the variable stalled_motor == true. If it is, then we will react to it and stop the motor immediately. The forceStop() function will not decelerate, instead it will stop right away. After we stop the motor, we’ll clear the stalled_motor flag.
After the stop, we wait two seconds (for fun) and then break from the loop and wait 3 more seconds (for more fun).
while (stepper->isRunning() == true) { if (stalled_motor == true) { stepper->forceStop(); Serial.println("Stalled"); stalled_motor = false; delay(2000); break; } delay(1); } delay(3000); |
Finally, we move back to the home position 0 and repeat the entire process.
stepper->moveTo(0);
NEXT SECTION: 11
Course Sections:
- Section 0: Background
- Section 1: Hardware Setup
- Section 2: Stepper Motor Basics
- Section 3: Power Requirements
- Section 4: Arduino Setup
- Section 5: Understanding Trinamic Drivers
- Section 6: TMCStepper Library
- Section 7: FastAccelStepper Library
- Section 8: ESP32 Dual Core Setup
- Section 9: Motor Setup
- Section 10: Understanding Positioning
Advanced Sections: