jonny_l480 1d53d3467c Stepper driver from scratch, test with buttons - WIP
- Add stepper driver code from scratch
- Remove / comment out code that used DendoStepper library
- Test custom driver with buttons (guide-stepper.cpp)

untested limited features
2023-04-10 22:28:18 +02:00

164 lines
4.8 KiB
C++

//custom driver for stepper motor
#include "config.hpp"
//config from config.hpp
//#define STEPPER_STEP_PIN GPIO_NUM_18 //mos1
//#define STEPPER_DIR_PIN GPIO_NUM_16 //ST3
//
extern "C" {
#include "driver/timer.h"
#include "driver/gpio.h"
}
#define TIMER_F 1000000ULL
#define TICK_PER_S TIMER_S
#define NS_TO_T_TICKS(x) (x)
static const char *TAG = "stepper-ctl"; //tag for logging
bool direction = 0;
bool timer_isr(void *arg);
typedef struct {
int targetSteps; // Target step count
int currentSteps; // Current step count
int acceleration; // Acceleration (in steps per second^2)
int deceleration; // Deceleration (in steps per second^2)
gpio_num_t pulsePin; // Pin for pulse signal
gpio_num_t directionPin; // Pin for direction signal
timer_group_t timerGroup; // Timer group
timer_idx_t timerIdx; // Timer index
bool isAccelerating; // Flag to indicate if accelerating
bool isDecelerating; // Flag to indicate if decelerating
int initialSpeed; // Initial speed (in steps per second)
int targetSpeed; // Target speed (in steps per second)
int currentSpeed; // Current speed (in steps per second)
} StepperControl;
StepperControl ctrl; // Create an instance of StepperControl struct
void stepper_setTargetSteps(int steps){
ESP_LOGW(TAG, "set target steps to %d", steps);
//TODO switch dir pin in isr? not in sync with count
if(steps < 0){
gpio_set_level(ctrl.directionPin, 1);
} else {
gpio_set_level(ctrl.directionPin, 0);
}
ctrl.targetSteps = abs(steps);
}
void stepper_toggleDirection(){
direction = !direction;
gpio_set_level(ctrl.directionPin, 1);
ESP_LOGW(TAG, "toggle direction -> %d", direction);
}
void stepper_init(){
ESP_LOGW(TAG, "init - configure struct...");
// Set values in StepperControl struct
ctrl.targetSteps = 0;
ctrl.currentSteps = 0;
ctrl.acceleration = 50;
ctrl.deceleration = 50;
ctrl.pulsePin = STEPPER_STEP_PIN;
ctrl.directionPin = STEPPER_DIR_PIN;
ctrl.timerGroup = TIMER_GROUP_0;
ctrl.timerIdx = TIMER_0;
ctrl.isAccelerating = true;
ctrl.isDecelerating = false;
ctrl.initialSpeed = 0; // Set initial speed as needed
ctrl.targetSpeed = 500; // Set target speed as needed
ctrl.currentSpeed = ctrl.initialSpeed;
// Configure pulse and direction pins as outputs
ESP_LOGW(TAG, "init - configure gpio pins...");
gpio_set_direction(ctrl.pulsePin, GPIO_MODE_OUTPUT);
gpio_set_direction(ctrl.directionPin, GPIO_MODE_OUTPUT);
ESP_LOGW(TAG, "init - initialize/configure timer...");
timer_config_t timer_conf = {
.alarm_en = TIMER_ALARM_EN, // we need alarm
.counter_en = TIMER_PAUSE, // dont start now lol
.intr_type = TIMER_INTR_LEVEL, // interrupt
.counter_dir = TIMER_COUNT_UP, // count up duh
.auto_reload = TIMER_AUTORELOAD_EN, // reload pls
.divider = 80000000ULL / TIMER_F, // ns resolution
};
ESP_ERROR_CHECK(timer_init(ctrl.timerGroup, ctrl.timerIdx, &timer_conf)); // init the timer
ESP_ERROR_CHECK(timer_set_counter_value(ctrl.timerGroup, ctrl.timerIdx, 0)); // set it to 0
//ESP_ERROR_CHECK(timer_isr_callback_add(ctrl.timerGroup, ctrl.timerIdx, timer_isr, )); // add callback fn to run when alarm is triggrd
ESP_ERROR_CHECK(timer_isr_callback_add(ctrl.timerGroup, ctrl.timerIdx, timer_isr, (void *)ctrl.timerIdx, 0));
}
bool timer_isr(void *arg) {
// Cast arg to an integer type that has the same size as timer_idx_t
uintptr_t arg_val = (uintptr_t)arg;
// Cast arg_val to timer_idx_t
timer_idx_t timer_idx = (timer_idx_t)arg_val;
int32_t step_diff = ctrl.targetSteps - ctrl.currentSteps;
if (timer_idx == ctrl.timerIdx) {
if (ctrl.currentSteps < ctrl.targetSteps) {
// Check if accelerating
if (ctrl.isAccelerating) {
if (ctrl.currentSpeed < ctrl.targetSpeed) {
// Increase speed if not yet at target speed
ctrl.currentSpeed += ctrl.acceleration;
} else {
// Reached target speed, clear accelerating flag
ctrl.isAccelerating = false;
}
}
// Check if decelerating
if (ctrl.isDecelerating) {
if (ctrl.currentSpeed > ctrl.targetSpeed) {
// Decrease speed if not yet at target speed
ctrl.currentSpeed -= ctrl.deceleration;
} else {
// Reached target speed, clear decelerating flag
ctrl.isDecelerating = false;
}
}
// Generate pulse for stepper motor
gpio_set_level(ctrl.pulsePin, 1);
ets_delay_us(500); // Adjust delay as needed
gpio_set_level(ctrl.pulsePin, 0);
// Update current step count
ctrl.currentSteps++;
// Update timer period based on current speed
timer_set_alarm_value(ctrl.timerGroup, ctrl.timerIdx, TIMER_BASE_CLK / ctrl.currentSpeed);
} else {
// Reached target step count, stop timer
timer_pause(ctrl.timerGroup, ctrl.timerIdx);
ESP_LOGW(TAG,"finished, pausing timer");
}
}
return 1;
}