Stepper Motor speed increases on its own
Posted: Wed Aug 11, 2021 7:20 am
In order to run a stepper motor, I am using an Arduino library (AccelStepper) that's been ported to ESP-IDF
Normally, it pulses GPIO 13 at a rate of 500 pulses per second.
However, after a period of time (maybe 30-60 minutes), the ESP32 decides to change it on its own to 50,000 pulses per second! Again, completely on its own.
The strangest part of this is that I cannot figure out why this suddenly changes. But if I reset the device, it goes back to normal. Then 1 hour later, it automatically changes again to a similar number, around 40,000 per second.
I used an oscilloscope to verify that the ESP32 does in fact send all pulses, but just extremely fast.
My code is below, but I suspect the issue to be in the AccelStepper port I am using. https://github.com/sdobz/AccelStepper-e ... tepper.cpp
However, the port works great for an hour, so I cannot even figure out what to do. I'll looked all through it and it works great in Arduino
I have spent close to 40 hours trying to figure this out, and it is one of the strangest issues I've ever had. Where is this ghost that's changing things!
Can anyone point me in a direction, I am so desperate for an answer. Thank you
Normally, it pulses GPIO 13 at a rate of 500 pulses per second.
However, after a period of time (maybe 30-60 minutes), the ESP32 decides to change it on its own to 50,000 pulses per second! Again, completely on its own.
The strangest part of this is that I cannot figure out why this suddenly changes. But if I reset the device, it goes back to normal. Then 1 hour later, it automatically changes again to a similar number, around 40,000 per second.
I used an oscilloscope to verify that the ESP32 does in fact send all pulses, but just extremely fast.
My code is below, but I suspect the issue to be in the AccelStepper port I am using. https://github.com/sdobz/AccelStepper-e ... tepper.cpp
However, the port works great for an hour, so I cannot even figure out what to do. I'll looked all through it and it works great in Arduino
I have spent close to 40 hours trying to figure this out, and it is one of the strangest issues I've ever had. Where is this ghost that's changing things!
Can anyone point me in a direction, I am so desperate for an answer. Thank you
Code: Select all
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "AccelStepper.h"
#include "TMCStepper.h"
#include "soc/timer_group_struct.h"
#include "soc/timer_group_reg.h"
#define MOTOR_UART_NUM UART_NUM_2
#define RXD2_PIN GPIO_NUM_16
#define TXD2_PIN GPIO_NUM_17
#define BUF_SIZE 1024
#define STEP_PIN GPIO_NUM_13
#define DIR_PIN GPIO_NUM_14
#define ENABLE_PIN GPIO_NUM_27
#define STALLGUARD GPIO_NUM_2
#define BUTTON1 GPIO_NUM_23
#define BUTTON2 GPIO_NUM_34
#define SERIAL_PORT_2 Serial2 // TMC2208/TMC2224 HardwareSerial port
#define DRIVER_ADDRESS 0b00 // TMC2209 Driver address according to MS1 and MS2
#define R_SENSE 0.10f // R_SENSE for current calc.
volatile long move_to_position = 0;
volatile bool run_motor = false;
xQueueHandle gpio_evt_queue = NULL;
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
TMC2209Stepper driver(MOTOR_UART_NUM, R_SENSE, DRIVER_ADDRESS);
void MotorTask( void *pvParameters );
TaskHandle_t MotorTaskTask;
//Interrupts
void IRAM_ATTR button1start(void *arg)
{
move_to_position = 0;
run_motor = true;
}
void IRAM_ATTR button2start(void *arg)
{
move_to_position = 500;
run_motor = true;
}
void motor_uart_init(void)
{
printf("Loading UART\n");
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
};
uart_driver_install(MOTOR_UART_NUM, BUF_SIZE * 2, 0, 0, NULL, 0);
uart_param_config(MOTOR_UART_NUM, &uart_config);
uart_set_pin(MOTOR_UART_NUM, TXD2_PIN, RXD2_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}
void ISR_init(void)
{
gpio_pad_select_gpio(STALLGUARD);
gpio_set_direction(STALLGUARD, GPIO_MODE_INPUT);
gpio_pad_select_gpio(BUTTON1);
gpio_set_direction(BUTTON1, GPIO_MODE_INPUT);
gpio_pad_select_gpio(BUTTON2);
gpio_set_direction(BUTTON2, GPIO_MODE_INPUT);
gpio_pad_select_gpio(STEP_PIN);
gpio_set_direction(STEP_PIN, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(DIR_PIN);
gpio_set_direction(DIR_PIN, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(ENABLE_PIN);
gpio_set_direction(ENABLE_PIN, GPIO_MODE_OUTPUT);
gpio_set_intr_type(STALLGUARD, GPIO_INTR_POSEDGE);
gpio_set_intr_type(BUTTON1, GPIO_INTR_NEGEDGE);
gpio_set_intr_type(BUTTON2, GPIO_INTR_NEGEDGE);
//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//install gpio isr service
gpio_install_isr_service(0);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(BUTTON1, button1start, (void *)BUTTON1);
gpio_isr_handler_add(BUTTON2, button2start, (void *)BUTTON2);
}
void setup(void)
{
printf("Starting Setup\n");
driver.begin();
driver.pdn_disable(true);
driver.mstep_reg_select(true);
driver.toff(4);
driver.blank_time(24);
driver.I_scale_analog(false);
driver.internal_Rsense(false);
driver.rms_current(300);
driver.SGTHRS(30);
driver.microsteps(0);//
driver.TCOOLTHRS(300);
driver.TPWMTHRS(0);
driver.semin(0);
driver.shaft(true);
driver.en_spreadCycle(false);
stepper.setMinPulseWidth(3);
stepper.setEnablePin(ENABLE_PIN);
stepper.setPinsInverted(false, false, true);
stepper.disableOutputs();
xTaskCreatePinnedToCore(
MotorTask
, "MotorTask"
, 1024 * 4
, NULL
, 5
, &MotorTaskTask
, 1);
}
extern "C" void app_main(void)
{
printf("Loading\n");
motor_uart_init();
ISR_init();
setup();
printf("Load Complete\n");
}
void feedTheDog()
{
// feed dog 0
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
TIMERG0.wdt_feed=1; // feed dog
TIMERG0.wdt_wprotect=0; // write protect
// feed dog 1
TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
TIMERG1.wdt_feed=1; // feed dog
TIMERG1.wdt_wprotect=0; // write protect
}
void move_motor(void)
{
printf("Acceleration: %f\n", stepper.getAccel());
printf("Max Speed: %f\n", stepper.getMaxSpeed());
printf("CurrentPosition: %li\n", stepper.currentPosition());
stepper.setAcceleration(300);
stepper.setMaxSpeed(500);
stepper.moveTo(move_to_position);
printf("Current Position: %li\n", stepper.currentPosition());
printf("Target Position: %li\n", stepper.targetPosition());
stepper.enableOutputs();
while (stepper.currentPosition() != stepper.targetPosition())
{
stepper.run();
feedTheDog();
}
stepper.disableOutputs();
printf("Moved To New Position: %li\n", stepper.currentPosition());
}
void MotorTask(void *pvParameters) // Motor Task
{
(void)pvParameters;
printf("MotorTask\n");
for (;;)
{
if (run_motor == true)
{
printf("Begin MotorTask\n");
move_motor();
printf("End MotorTask\n");
run_motor = false;
}
else
{
vTaskDelay(10);
}
}
}