Merge branch 'stepper_custom-driver' into dev
custom stepper driver successfully implemented, will be used and continued in the further development in dev branch
This commit is contained in:
commit
a22c60b817
File diff suppressed because one or more lines are too long
@ -8,6 +8,7 @@ idf_component_register(
|
|||||||
"display.cpp"
|
"display.cpp"
|
||||||
"cutter.cpp"
|
"cutter.cpp"
|
||||||
"switchesAnalog.cpp"
|
"switchesAnalog.cpp"
|
||||||
|
"stepper.cpp"
|
||||||
"guide-stepper.cpp"
|
"guide-stepper.cpp"
|
||||||
"encoder.cpp"
|
"encoder.cpp"
|
||||||
INCLUDE_DIRS
|
INCLUDE_DIRS
|
||||||
|
@ -85,7 +85,7 @@ extern "C" {
|
|||||||
//----- stepper config -----
|
//----- stepper config -----
|
||||||
//--------------------------
|
//--------------------------
|
||||||
//enable stepper test mode (dont start control and encoder task)
|
//enable stepper test mode (dont start control and encoder task)
|
||||||
//#define STEPPER_TEST
|
#define STEPPER_TEST
|
||||||
#define STEPPER_STEP_PIN GPIO_NUM_18 //mos1
|
#define STEPPER_STEP_PIN GPIO_NUM_18 //mos1
|
||||||
#define STEPPER_DIR_PIN GPIO_NUM_16 //ST3
|
#define STEPPER_DIR_PIN GPIO_NUM_16 //ST3
|
||||||
#define STEPPER_EN_PIN GPIO_NUM_0 //not connected (-> stepper always on)
|
#define STEPPER_EN_PIN GPIO_NUM_0 //not connected (-> stepper always on)
|
||||||
|
@ -7,7 +7,7 @@ extern "C"
|
|||||||
#include "driver/adc.h"
|
#include "driver/adc.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "DendoStepper.h"
|
#include "stepper.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "guide-stepper.hpp"
|
#include "guide-stepper.hpp"
|
||||||
#include "encoder.hpp"
|
#include "encoder.hpp"
|
||||||
@ -46,11 +46,9 @@ extern "C"
|
|||||||
//----------------------
|
//----------------------
|
||||||
//----- variables ------
|
//----- variables ------
|
||||||
//----------------------
|
//----------------------
|
||||||
static DendoStepper step;
|
|
||||||
static const char *TAG = "stepper"; //tag for logging
|
static const char *TAG = "stepper"; //tag for logging
|
||||||
|
|
||||||
static bool stepp_direction = true;
|
static bool stepp_direction = true;
|
||||||
static bool dir = true, dirPrev; //TODO local variables in travelSteps?
|
|
||||||
static uint32_t posNow = 0;
|
static uint32_t posNow = 0;
|
||||||
|
|
||||||
|
|
||||||
@ -58,114 +56,98 @@ static uint32_t posNow = 0;
|
|||||||
//----------------------
|
//----------------------
|
||||||
//----- functions ------
|
//----- functions ------
|
||||||
//----------------------
|
//----------------------
|
||||||
//move axis certain Steps (relative) between left and right or reverse when negative
|
////move axis certain Steps (relative) between left and right or reverse when negative
|
||||||
void travelSteps(int stepsTarget){
|
//void travelSteps(int stepsTarget){
|
||||||
//posNow = step.getPositionMm(); //not otherwise controlled, so no update necessary
|
// //posNow = step.getPositionMm(); //not otherwise controlled, so no update necessary
|
||||||
int stepsToGo, remaining;
|
// int stepsToGo, remaining;
|
||||||
|
//
|
||||||
stepsToGo = abs(stepsTarget);
|
// stepsToGo = abs(stepsTarget);
|
||||||
if(stepsTarget < 0) stepp_direction = !stepp_direction; //invert direction in reverse mode
|
// if(stepsTarget < 0) stepp_direction = !stepp_direction; //invert direction in reverse mode
|
||||||
|
//
|
||||||
|
// while (stepsToGo != 0){
|
||||||
while (stepsToGo != 0){
|
// //--- currently moving right ---
|
||||||
|
// if (stepp_direction == true){ //currently moving right
|
||||||
//--- wait if direction changed ---
|
// remaining = POS_MAX_STEPS - posNow; //calc remaining distance fom current position to limit
|
||||||
if (dirPrev != dir){
|
// if (stepsToGo > remaining){ //new distance will exceed limit
|
||||||
ESP_LOGI(TAG, " dir-change detected - waiting for move to finish \n ");
|
// //....step.runAbs (POS_MAX_STEPS); //move to limit
|
||||||
while(step.getState() != 1) vTaskDelay(1); //wait for move to finish
|
// //....while(step.getState() != 1) vTaskDelay(1); //wait for move to finish
|
||||||
}
|
// posNow = POS_MAX_STEPS;
|
||||||
|
// stepp_direction = false; //change current direction for next iteration
|
||||||
//--- currently moving right ---
|
// stepsToGo = stepsToGo - remaining; //decrease target length by already traveled distance
|
||||||
if (stepp_direction == true){ //currently moving right
|
// ESP_LOGI(TAG, " --- moved to max -> change direction (L) --- \n ");
|
||||||
remaining = POS_MAX_STEPS - posNow; //calc remaining distance fom current position to limit
|
// }
|
||||||
if (stepsToGo > remaining){ //new distance will exceed limit
|
// else { //target distance does not reach the limit
|
||||||
step.runAbs (POS_MAX_STEPS); //move to limit
|
// //....step.runAbs (posNow + stepsToGo); //move by (remaining) distance to reach target length
|
||||||
dirPrev = dir;
|
// //....while(step.getState() != 1) vTaskDelay(1); //wait for move to finish
|
||||||
dir = 1;
|
// ESP_LOGD(TAG, "moving to %d\n", posNow+stepsToGo);
|
||||||
//while(step.getState() != 1) vTaskDelay(1); //wait for move to finish
|
// posNow += stepsToGo;
|
||||||
posNow = POS_MAX_STEPS;
|
// stepsToGo = 0; //finished, reset target length (could as well exit loop/break)
|
||||||
stepp_direction = false; //change current direction for next iteration
|
// }
|
||||||
stepsToGo = stepsToGo - remaining; //decrease target length by already traveled distance
|
// }
|
||||||
ESP_LOGI(TAG, " --- moved to max -> change direction (L) --- \n ");
|
//
|
||||||
}
|
// //--- currently moving left ---
|
||||||
else { //target distance does not reach the limit
|
// else {
|
||||||
step.runAbs (posNow + stepsToGo); //move by (remaining) distance to reach target length
|
// remaining = posNow - POS_MIN_STEPS;
|
||||||
dirPrev = dir;
|
// if (stepsToGo > remaining){
|
||||||
dir = 1;
|
// //....step.runAbs (POS_MIN_STEPS);
|
||||||
//-- dont wait for move to finish since moves in same direction get merged --
|
// //....while(step.getState() != 1) vTaskDelay(2); //wait for move to finish
|
||||||
//while(step.getState() != 1) vTaskDelay(1); //wait for move to finish
|
// posNow = POS_MIN_STEPS;
|
||||||
ESP_LOGD(TAG, "moving to %d\n", posNow+stepsToGo);
|
// stepp_direction = true;
|
||||||
posNow += stepsToGo;
|
// stepsToGo = stepsToGo - remaining;
|
||||||
stepsToGo = 0; //finished, reset target length (could as well exit loop/break)
|
// ESP_LOGI(TAG, " --- moved to min -> change direction (R) --- \n ");
|
||||||
}
|
// }
|
||||||
}
|
// else {
|
||||||
|
// //....step.runAbs (posNow - stepsToGo); //when moving left the coordinate has to be decreased
|
||||||
//--- currently moving left ---
|
// while(step.getState() != 1) vTaskDelay(2); //wait for move to finish
|
||||||
else {
|
// ESP_LOGD(TAG, "moving to %d\n", posNow - stepsToGo);
|
||||||
remaining = posNow - POS_MIN_STEPS;
|
// posNow -= stepsToGo;
|
||||||
if (stepsToGo > remaining){
|
// stepsToGo = 0;
|
||||||
step.runAbs (POS_MIN_STEPS);
|
// }
|
||||||
dirPrev = dir;
|
// }
|
||||||
dir = 0;
|
// }
|
||||||
//while(step.getState() != 1) vTaskDelay(2); //wait for move to finish
|
// if(stepsTarget < 0) stepp_direction = !stepp_direction; //undo inversion of stepp_direction after reverse mode is finished
|
||||||
posNow = POS_MIN_STEPS;
|
// return;
|
||||||
stepp_direction = true;
|
//}
|
||||||
stepsToGo = stepsToGo - remaining;
|
//
|
||||||
ESP_LOGI(TAG, " --- moved to min -> change direction (R) --- \n ");
|
//
|
||||||
}
|
////move axis certain Mm (relative) between left and right or reverse when negative
|
||||||
else {
|
//void travelMm(int length){
|
||||||
step.runAbs (posNow - stepsToGo); //when moving left the coordinate has to be decreased
|
// travelSteps(length * STEPPER_STEPS_PER_MM);
|
||||||
dirPrev = dir;
|
//}
|
||||||
dir = 0;
|
//
|
||||||
//-- dont wait for move to finish since moves in same direction get merged --
|
//
|
||||||
//while(step.getState() != 1) vTaskDelay(2); //wait for move to finish
|
////define zero/start position
|
||||||
ESP_LOGD(TAG, "moving to %d\n", posNow - stepsToGo);
|
////currently crashes into hardware limitation for certain time
|
||||||
posNow -= stepsToGo;
|
////TODO: limit switch
|
||||||
stepsToGo = 0;
|
//void home() {
|
||||||
}
|
// ESP_LOGW(TAG, "auto-home...");
|
||||||
}
|
// //....step.setSpeedMm(100, 500, 10);
|
||||||
}
|
// //....step.runInf(1);
|
||||||
if(stepsTarget < 0) stepp_direction = !stepp_direction; //undo inversion of stepp_direction after reverse mode is finished
|
// vTaskDelay(1500 / portTICK_PERIOD_MS);
|
||||||
return;
|
// //....step.stop();
|
||||||
}
|
// //....step.resetAbsolute();
|
||||||
|
// ESP_LOGW(TAG, "auto-home finished");
|
||||||
|
//}
|
||||||
//move axis certain Mm (relative) between left and right or reverse when negative
|
|
||||||
void travelMm(int length){
|
|
||||||
travelSteps(length * STEPPER_STEPS_PER_MM);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//define zero/start position
|
|
||||||
//currently crashes into hardware limitation for certain time
|
|
||||||
//TODO: limit switch
|
|
||||||
void home() {
|
|
||||||
ESP_LOGW(TAG, "auto-home...");
|
|
||||||
step.setSpeedMm(100, 500, 10);
|
|
||||||
step.runInf(1);
|
|
||||||
vTaskDelay(1500 / portTICK_PERIOD_MS);
|
|
||||||
step.stop();
|
|
||||||
step.resetAbsolute();
|
|
||||||
ESP_LOGW(TAG, "auto-home finished");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//initialize/configure stepper instance
|
//initialize/configure stepper instance
|
||||||
void init_stepper() {
|
void init_stepper() {
|
||||||
ESP_LOGW(TAG, "initializing stepper...");
|
// ESP_LOGW(TAG, "initializing stepper...");
|
||||||
DendoStepper_config_t step_cfg = {
|
// DendoStepper_config_t step_cfg = {
|
||||||
.stepPin = STEPPER_STEP_PIN,
|
// .stepPin = STEPPER_STEP_PIN,
|
||||||
.dirPin = STEPPER_DIR_PIN,
|
// .dirPin = STEPPER_DIR_PIN,
|
||||||
.enPin = STEPPER_EN_PIN,
|
// .enPin = STEPPER_EN_PIN,
|
||||||
.timer_group = TIMER_GROUP_0,
|
// .timer_group = TIMER_GROUP_0,
|
||||||
.timer_idx = TIMER_0,
|
// .timer_idx = TIMER_0,
|
||||||
.miStep = MICROSTEP_32,
|
// .miStep = MICROSTEP_32,
|
||||||
.stepAngle = 1.8};
|
// .stepAngle = 1.8};
|
||||||
step.config(&step_cfg);
|
// //....step.config(&step_cfg);
|
||||||
step.init();
|
// //....step.init();
|
||||||
|
//
|
||||||
|
// //....step.setSpeed(1000, 1000, 1000); //random default speed
|
||||||
|
// //....step.setStepsPerMm(STEPPER_STEPS_PER_MM); //guide: 4mm/rot
|
||||||
|
|
||||||
step.setSpeed(1000, 1000, 1000); //random default speed
|
stepper_init();
|
||||||
step.setStepsPerMm(STEPPER_STEPS_PER_MM); //guide: 4mm/rot
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -174,7 +156,7 @@ void updateSpeedFromAdc() {
|
|||||||
int potiRead = gpio_readAdc(ADC_CHANNEL_POTI); //0-4095 GPIO34
|
int potiRead = gpio_readAdc(ADC_CHANNEL_POTI); //0-4095 GPIO34
|
||||||
double poti = potiRead/4095.0;
|
double poti = potiRead/4095.0;
|
||||||
int speed = poti*(SPEED_MAX-SPEED_MIN) + SPEED_MIN;
|
int speed = poti*(SPEED_MAX-SPEED_MIN) + SPEED_MIN;
|
||||||
step.setSpeedMm(speed, ACCEL_MS, DECEL_MS);
|
//....step.setSpeedMm(speed, ACCEL_MS, DECEL_MS);
|
||||||
ESP_LOGW(TAG, "poti: %d (%.2lf%%), set speed to: %d", potiRead, poti*100, speed);
|
ESP_LOGW(TAG, "poti: %d (%.2lf%%), set speed to: %d", potiRead, poti*100, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,80 +167,121 @@ void updateSpeedFromAdc() {
|
|||||||
//----------------------------
|
//----------------------------
|
||||||
void task_stepper_test(void *pvParameter)
|
void task_stepper_test(void *pvParameter)
|
||||||
{
|
{
|
||||||
init_stepper();
|
stepper_init();
|
||||||
home();
|
int state = 0;
|
||||||
|
while(1){
|
||||||
|
vTaskDelay(20 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
while (1) {
|
//------ handle switches ------
|
||||||
updateSpeedFromAdc();
|
//run handle functions for all switches
|
||||||
step.runPosMm(STEPPER_TEST_TRAVEL);
|
SW_START.handle();
|
||||||
while(step.getState() != 1) vTaskDelay(2);
|
SW_RESET.handle();
|
||||||
ESP_LOGI(TAG, "finished moving right => moving left");
|
SW_SET.handle();
|
||||||
|
SW_PRESET1.handle();
|
||||||
|
SW_PRESET2.handle();
|
||||||
|
SW_PRESET3.handle();
|
||||||
|
SW_CUT.handle();
|
||||||
|
SW_AUTO_CUT.handle();
|
||||||
|
|
||||||
updateSpeedFromAdc();
|
//cycle through test commands with one button
|
||||||
step.runPosMm(-STEPPER_TEST_TRAVEL);
|
if (SW_RESET.risingEdge) {
|
||||||
while(step.getState() != 1) vTaskDelay(2); //1=idle
|
switch (state){
|
||||||
ESP_LOGI(TAG, "finished moving left => moving right");
|
case 0:
|
||||||
}
|
stepper_setTargetPosMm(50);
|
||||||
|
//stepper_setTargetPosSteps(1000);
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
stepper_setTargetPosMm(80);
|
||||||
|
//stepper_setTargetPosSteps(100);
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
stepper_setTargetPosMm(20);
|
||||||
|
//stepper_setTargetPosSteps(100);
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
stepper_setTargetPosMm(60);
|
||||||
|
//stepper_setTargetPosSteps(2000);
|
||||||
|
state = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if (SW_PRESET1.risingEdge) {
|
||||||
|
// buzzer.beep(2, 300, 100);
|
||||||
|
// stepperSw_setTargetSteps(1000);
|
||||||
|
// }
|
||||||
|
// if (SW_PRESET2.risingEdge) {
|
||||||
|
// buzzer.beep(1, 500, 100);
|
||||||
|
// stepperSw_setTargetSteps(10000);
|
||||||
|
// }
|
||||||
|
// if (SW_PRESET3.risingEdge) {
|
||||||
|
// buzzer.beep(1, 100, 100);
|
||||||
|
// stepperSw_setTargetSteps(30000);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------
|
//----------------------------
|
||||||
//----- TASK stepper-ctl -----
|
//----- TASK stepper-ctl -----
|
||||||
//----------------------------
|
//----------------------------
|
||||||
void task_stepper_ctl(void *pvParameter)
|
void task_stepper_ctl(void *pvParameter)
|
||||||
{
|
{
|
||||||
//variables
|
// //variables
|
||||||
int encStepsNow = 0; //get curret steps of encoder
|
// int encStepsNow = 0; //get curret steps of encoder
|
||||||
int encStepsPrev = 0; //steps at last check
|
// int encStepsPrev = 0; //steps at last check
|
||||||
int encStepsDelta = 0; //steps changed since last iteration
|
// int encStepsDelta = 0; //steps changed since last iteration
|
||||||
|
//
|
||||||
double cableLen = 0;
|
// double cableLen = 0;
|
||||||
double travelStepsExact = 0; //steps axis has to travel
|
// double travelStepsExact = 0; //steps axis has to travel
|
||||||
double travelStepsPartial = 0;
|
// double travelStepsPartial = 0;
|
||||||
int travelStepsFull = 0;
|
// int travelStepsFull = 0;
|
||||||
double travelMm = 0;
|
// double travelMm = 0;
|
||||||
double turns = 0;
|
// double turns = 0;
|
||||||
|
//
|
||||||
float potiModifier;
|
// float potiModifier;
|
||||||
|
//
|
||||||
init_stepper();
|
// init_stepper();
|
||||||
home();
|
// home();
|
||||||
|
//
|
||||||
while(1){
|
// while(1){
|
||||||
//get current length
|
// //get current length
|
||||||
encStepsNow = encoder_getSteps();
|
// encStepsNow = encoder_getSteps();
|
||||||
|
//
|
||||||
//calculate change
|
// //calculate change
|
||||||
encStepsDelta = encStepsNow - encStepsPrev; //FIXME MAJOR BUG: when resetting encoder/length in control task, diff will be huge!
|
// encStepsDelta = encStepsNow - encStepsPrev; //FIXME MAJOR BUG: when resetting encoder/length in control task, diff will be huge!
|
||||||
|
//
|
||||||
//read potentiometer and normalize (0-1) to get a variable for testing
|
// //read potentiometer and normalize (0-1) to get a variable for testing
|
||||||
potiModifier = (float) gpio_readAdc(ADC_CHANNEL_POTI) / 4095; //0-4095 -> 0-1
|
// potiModifier = (float) gpio_readAdc(ADC_CHANNEL_POTI) / 4095; //0-4095 -> 0-1
|
||||||
//ESP_LOGI(TAG, "current poti-modifier = %f", potiModifier);
|
// //ESP_LOGI(TAG, "current poti-modifier = %f", potiModifier);
|
||||||
|
//
|
||||||
//calculate steps to move
|
// //calculate steps to move
|
||||||
cableLen = (double)encStepsDelta * 1000 / ENCODER_STEPS_PER_METER;
|
// cableLen = (double)encStepsDelta * 1000 / ENCODER_STEPS_PER_METER;
|
||||||
turns = cableLen / (PI * D_REEL);
|
// turns = cableLen / (PI * D_REEL);
|
||||||
travelMm = turns * D_CABLE;
|
// travelMm = turns * D_CABLE;
|
||||||
travelStepsExact = travelMm * STEPPER_STEPS_PER_MM + travelStepsPartial; //convert mm to steps and add not moved partial steps
|
// travelStepsExact = travelMm * STEPPER_STEPS_PER_MM + travelStepsPartial; //convert mm to steps and add not moved partial steps
|
||||||
travelStepsPartial = 0;
|
// travelStepsPartial = 0;
|
||||||
travelStepsFull = (int)travelStepsExact;
|
// travelStepsFull = (int)travelStepsExact;
|
||||||
|
//
|
||||||
//move axis when ready to move at least 1 step
|
// //move axis when ready to move at least 1 step
|
||||||
if (abs(travelStepsFull) > 1){
|
// if (abs(travelStepsFull) > 1){
|
||||||
travelStepsPartial = fmod(travelStepsExact, 1); //save remaining partial steps to be added in the next iteration
|
// travelStepsPartial = fmod(travelStepsExact, 1); //save remaining partial steps to be added in the next iteration
|
||||||
ESP_LOGD(TAG, "cablelen=%.2lf, turns=%.2lf, travelMm=%.3lf, travelStepsExact: %.3lf, travelStepsFull=%d, partialStep=%.3lf", cableLen, turns, travelMm, travelStepsExact, travelStepsFull, travelStepsPartial);
|
// ESP_LOGD(TAG, "cablelen=%.2lf, turns=%.2lf, travelMm=%.3lf, travelStepsExact: %.3lf, travelStepsFull=%d, partialStep=%.3lf", cableLen, turns, travelMm, travelStepsExact, travelStepsFull, travelStepsPartial);
|
||||||
ESP_LOGI(TAG, "MOVING %d steps", travelStepsFull);
|
// ESP_LOGI(TAG, "MOVING %d steps", travelStepsFull);
|
||||||
//TODO: calculate variable speed for smoother movement? for example intentionally lag behind and calculate speed according to buffered data
|
// //TODO: calculate variable speed for smoother movement? for example intentionally lag behind and calculate speed according to buffered data
|
||||||
step.setSpeedMm(35, 100, 50);
|
// //....step.setSpeedMm(35, 100, 50);
|
||||||
//testing: get speed from poti
|
// //testing: get speed from poti
|
||||||
//step.setSpeedMm(35, 1000*potiModifier+1, 1000*potiModifier+1);
|
// //step.setSpeedMm(35, 1000*potiModifier+1, 1000*potiModifier+1);
|
||||||
travelSteps(travelStepsExact);
|
// travelSteps(travelStepsExact);
|
||||||
encStepsPrev = encStepsNow; //update previous length
|
// encStepsPrev = encStepsNow; //update previous length
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
//TODO use encoder queue to only run this check at encoder event?
|
// //TODO use encoder queue to only run this check at encoder event?
|
||||||
vTaskDelay(2);
|
// vTaskDelay(2);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@ extern "C"
|
|||||||
#include "guide-stepper.hpp"
|
#include "guide-stepper.hpp"
|
||||||
#include "encoder.hpp"
|
#include "encoder.hpp"
|
||||||
|
|
||||||
|
#include "stepper.hpp"
|
||||||
|
|
||||||
|
|
||||||
//=================================
|
//=================================
|
||||||
//=========== functions ===========
|
//=========== functions ===========
|
||||||
@ -92,17 +94,18 @@ extern "C" void app_main()
|
|||||||
|
|
||||||
#ifdef STEPPER_TEST
|
#ifdef STEPPER_TEST
|
||||||
//create task for stepper testing
|
//create task for stepper testing
|
||||||
xTaskCreate(task_stepper_test, "task_stepper_test", configMINIMAL_STACK_SIZE * 3, NULL, 5, NULL);
|
xTaskCreate(task_stepper_test, "task_stepper_test", configMINIMAL_STACK_SIZE * 3, NULL, 2, NULL);
|
||||||
|
//xTaskCreate(task_stepper_debug, "task_stepper_test", configMINIMAL_STACK_SIZE * 3, NULL, 2, NULL);
|
||||||
#else
|
#else
|
||||||
//create task for controlling the machine
|
//create task for controlling the machine
|
||||||
xTaskCreate(task_control, "task_control", configMINIMAL_STACK_SIZE * 3, NULL, 5, NULL);
|
xTaskCreate(task_control, "task_control", configMINIMAL_STACK_SIZE * 3, NULL, 4, NULL);
|
||||||
|
|
||||||
//create task for controlling the machine
|
//create task for controlling the stepper
|
||||||
xTaskCreate(task_stepper_ctl, "task_stepper_ctl", configMINIMAL_STACK_SIZE * 3, NULL, 5, NULL);
|
xTaskCreate(task_stepper_ctl, "task_stepper_ctl", configMINIMAL_STACK_SIZE * 3, NULL, 2, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
//create task for handling the buzzer
|
//create task for handling the buzzer
|
||||||
xTaskCreate(&task_buzzer, "task_buzzer", 2048, NULL, 2, NULL);
|
xTaskCreate(&task_buzzer, "task_buzzer", 2048, NULL, 2, NULL);
|
||||||
#endif
|
|
||||||
|
|
||||||
//beep at startup
|
//beep at startup
|
||||||
buzzer.beep(3, 70, 50);
|
buzzer.beep(3, 70, 50);
|
||||||
|
249
main/stepper.cpp
Normal file
249
main/stepper.cpp
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
//custom driver for stepper motor
|
||||||
|
#include "config.hpp"
|
||||||
|
#include "hal/timer_types.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "driver/timer.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
//config from config.hpp
|
||||||
|
//#define STEPPER_STEP_PIN GPIO_NUM_18 //mos1
|
||||||
|
//#define STEPPER_DIR_PIN GPIO_NUM_16 //ST3
|
||||||
|
|
||||||
|
#define STEPPER_STEPS_PER_MM 200/2 //steps/mm
|
||||||
|
#define STEPPER_SPEED_DEFAULT 20 //mm/s
|
||||||
|
#define STEPPER_SPEED_MIN 4 //mm/s - speed at which stepper immediately starts/stops
|
||||||
|
#define STEPPER_ACCEL_INC 3 //steps/s per cycle
|
||||||
|
#define STEPPER_DECEL_INC 8 //steps/s per cycle
|
||||||
|
|
||||||
|
|
||||||
|
#define TIMER_F 1000000ULL
|
||||||
|
#define TICK_PER_S TIMER_S
|
||||||
|
#define NS_TO_T_TICKS(x) (x)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//========================
|
||||||
|
//=== global variables ===
|
||||||
|
//========================
|
||||||
|
static const char *TAG = "stepper-ctl"; //tag for logging
|
||||||
|
|
||||||
|
bool direction = 1;
|
||||||
|
bool directionTarget = 1;
|
||||||
|
bool timerIsRunning = false;
|
||||||
|
bool timer_isr(void *arg);
|
||||||
|
|
||||||
|
static timer_group_t timerGroup = TIMER_GROUP_0;
|
||||||
|
static timer_idx_t timerIdx = TIMER_0;
|
||||||
|
|
||||||
|
//TODO the below variables can be moved to isr function once debug output is no longer needed
|
||||||
|
static uint64_t posTarget = 0;
|
||||||
|
static uint64_t posNow = 0;
|
||||||
|
static uint64_t stepsToGo = 0;
|
||||||
|
static uint32_t speedMin = STEPPER_SPEED_MIN * STEPPER_STEPS_PER_MM;
|
||||||
|
static uint32_t speedNow = speedMin;
|
||||||
|
static int debug = 0;
|
||||||
|
static uint32_t speedTarget = STEPPER_SPEED_DEFAULT * STEPPER_STEPS_PER_MM;
|
||||||
|
//TODO/NOTE increment actually has to be re-calculated every run to have linear accel (because also gets called faster/slower)
|
||||||
|
static uint32_t decel_increment = STEPPER_DECEL_INC;
|
||||||
|
static uint32_t accel_increment = STEPPER_ACCEL_INC;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//======================
|
||||||
|
//===== DEBUG task =====
|
||||||
|
//======================
|
||||||
|
void task_stepper_debug(void *pvParameter){
|
||||||
|
while (1){
|
||||||
|
ESP_LOGI("stepper-DEBUG",
|
||||||
|
"timer=%d "
|
||||||
|
"dir=%d "
|
||||||
|
"dirTarget=%d "
|
||||||
|
"posTarget=%llu "
|
||||||
|
"posNow=%llu "
|
||||||
|
"stepsToGo=%llu "
|
||||||
|
"speedNow=%u "
|
||||||
|
"speedTarget=%u "
|
||||||
|
"debug=%d ",
|
||||||
|
|
||||||
|
timerIsRunning,
|
||||||
|
direction,
|
||||||
|
directionTarget,
|
||||||
|
posTarget,
|
||||||
|
posNow,
|
||||||
|
stepsToGo,
|
||||||
|
speedNow,
|
||||||
|
speedTarget,
|
||||||
|
debug
|
||||||
|
);
|
||||||
|
|
||||||
|
vTaskDelay(300 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=====================
|
||||||
|
//===== set speed =====
|
||||||
|
//=====================
|
||||||
|
void stepper_setSpeed(uint32_t speedMmPerS) {
|
||||||
|
ESP_LOGW(TAG, "set target speed from %u to %u mm/s (%u steps/s)",
|
||||||
|
speedTarget, speedMmPerS, speedMmPerS * STEPPER_STEPS_PER_MM);
|
||||||
|
speedTarget = speedMmPerS * STEPPER_STEPS_PER_MM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==========================
|
||||||
|
//== set target pos STEPS ==
|
||||||
|
//==========================
|
||||||
|
void stepper_setTargetPosSteps(uint64_t target_steps) {
|
||||||
|
ESP_LOGW(TAG, "update target position from %llu to %llu steps (stepsNow: %llu", posTarget, target_steps, posNow);
|
||||||
|
posTarget = target_steps;
|
||||||
|
|
||||||
|
// Check if the timer is currently paused
|
||||||
|
if (!timerIsRunning){
|
||||||
|
// If the timer is paused, start it again with the updated targetSteps
|
||||||
|
timerIsRunning = true;
|
||||||
|
ESP_LOGW(TAG, "starting timer because did not run before");
|
||||||
|
ESP_ERROR_CHECK(timer_set_alarm_value(timerGroup, timerIdx, 1000));
|
||||||
|
//timer_set_counter_value(timerGroup, timerIdx, 1000);
|
||||||
|
ESP_ERROR_CHECK(timer_start(timerGroup, timerIdx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=========================
|
||||||
|
//=== set target pos MM ===
|
||||||
|
//=========================
|
||||||
|
void stepper_setTargetPosMm(uint32_t posMm){
|
||||||
|
ESP_LOGW(TAG, "set target position to %u mm", posMm);
|
||||||
|
stepper_setTargetPosSteps(posMm * STEPPER_STEPS_PER_MM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//========================
|
||||||
|
//===== init stepper =====
|
||||||
|
//========================
|
||||||
|
void stepper_init(){
|
||||||
|
ESP_LOGW(TAG, "init - configure struct...");
|
||||||
|
|
||||||
|
// Configure pulse and direction pins as outputs
|
||||||
|
ESP_LOGW(TAG, "init - configure gpio pins...");
|
||||||
|
gpio_set_direction(STEPPER_DIR_PIN, GPIO_MODE_OUTPUT);
|
||||||
|
gpio_set_direction(STEPPER_STEP_PIN, 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(timerGroup, timerIdx, &timer_conf)); // init the timer
|
||||||
|
ESP_ERROR_CHECK(timer_set_counter_value(timerGroup, timerIdx, 0)); // set it to 0
|
||||||
|
ESP_ERROR_CHECK(timer_isr_callback_add(timerGroup, timerIdx, timer_isr, (void *)timerIdx, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================================
|
||||||
|
//=== timer interrupt function ===
|
||||||
|
//================================
|
||||||
|
bool timer_isr(void *arg) {
|
||||||
|
|
||||||
|
//-----------------
|
||||||
|
//--- variables ---
|
||||||
|
//-----------------
|
||||||
|
//TODO used (currently global) variables here
|
||||||
|
|
||||||
|
//-----------------------------------
|
||||||
|
//--- define direction, stepsToGo ---
|
||||||
|
//-----------------------------------
|
||||||
|
//Note: the idea is that the stepper has to decelerate to min speed first before changeing the direction
|
||||||
|
//define target direction depending on position difference
|
||||||
|
bool directionTarget = posTarget > posNow ? 1 : 0;
|
||||||
|
//DIRECTION DIFFERS (change)
|
||||||
|
if ( (direction != directionTarget) && (posTarget != posNow)) {
|
||||||
|
if (stepsToGo == 0){ //standstill
|
||||||
|
direction = directionTarget; //switch direction
|
||||||
|
gpio_set_level(STEPPER_DIR_PIN, direction);
|
||||||
|
stepsToGo = abs(int64_t(posTarget - posNow));
|
||||||
|
} else {
|
||||||
|
//set to minimun decel steps
|
||||||
|
stepsToGo = (speedNow - speedMin) / decel_increment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//NORMAL (any direction 0/1)
|
||||||
|
else {
|
||||||
|
stepsToGo = abs(int64_t(posTarget - posNow));
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------
|
||||||
|
//--- define speed ---
|
||||||
|
//--------------------
|
||||||
|
//FIXME noticed crash: division by 0 when min speed > target speed
|
||||||
|
uint64_t stepsDecelRemaining = (speedNow - speedMin) / decel_increment;
|
||||||
|
//DECELERATE
|
||||||
|
if (stepsToGo <= stepsDecelRemaining) {
|
||||||
|
//FIXME if stepsToGo gets updated (lowered) close to target while close to target, the stepper may stop too fast -> implement possibility to 'overshoot and reverse'?
|
||||||
|
if ((speedNow - speedMin) > decel_increment) {
|
||||||
|
speedNow -= decel_increment;
|
||||||
|
} else {
|
||||||
|
speedNow = speedMin; //PAUSE HERE??? / irrelevant?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//ACCELERATE
|
||||||
|
else if (speedNow < speedTarget) {
|
||||||
|
speedNow += accel_increment;
|
||||||
|
if (speedNow > speedTarget) speedNow = speedTarget;
|
||||||
|
}
|
||||||
|
//COASTING
|
||||||
|
else { //not relevant?
|
||||||
|
speedNow = speedTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------
|
||||||
|
//--- update timer, increment ---
|
||||||
|
//-------------------------------
|
||||||
|
//AT TARGET -> STOP
|
||||||
|
if (stepsToGo == 0) {
|
||||||
|
timer_pause(timerGroup, timerIdx);
|
||||||
|
timerIsRunning = false;
|
||||||
|
speedNow = speedMin;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//STEPS REMAINING -> NEXT STEP
|
||||||
|
//update timer with new speed
|
||||||
|
ESP_ERROR_CHECK(timer_set_alarm_value(timerGroup, timerIdx, TIMER_F / speedNow));
|
||||||
|
|
||||||
|
//generate pulse
|
||||||
|
GPIO.out_w1ts = (1ULL << STEPPER_STEP_PIN); //turn on (fast)
|
||||||
|
ets_delay_us(10);
|
||||||
|
GPIO.out_w1tc = (1ULL << STEPPER_STEP_PIN); //turn off (fast)
|
||||||
|
|
||||||
|
//increment pos
|
||||||
|
stepsToGo --;
|
||||||
|
if (direction == 1){
|
||||||
|
posNow ++;
|
||||||
|
} else {
|
||||||
|
//prevent underflow FIXME this case should not happen in the first place?
|
||||||
|
if (posNow != 0){
|
||||||
|
posNow --;
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG,"isr: posNow would be negative - ignoring decrement");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
13
main/stepper.hpp
Normal file
13
main/stepper.hpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
//init stepper pins and timer
|
||||||
|
void stepper_init();
|
||||||
|
//set absolute target position in steps
|
||||||
|
void stepper_setTargetPosSteps(uint64_t steps);
|
||||||
|
//set absolute target position in millimeters
|
||||||
|
void stepper_setTargetPosMm(uint32_t posMm);
|
||||||
|
//set target speed in millimeters per second
|
||||||
|
void stepper_setSpeed(uint32_t speedMmPerS);
|
||||||
|
|
||||||
|
//task that periodically logs variables for debugging stepper driver
|
||||||
|
void task_stepper_debug(void *pvParameter);
|
104
testing/cnc-guide/main.c
Normal file
104
testing/cnc-guide/main.c
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define MAX 100
|
||||||
|
#define MIN 10
|
||||||
|
#define TRAVEL MAX-MIN
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==== VARIABLES ====
|
||||||
|
bool direction = true;
|
||||||
|
uint16_t posNow = 10;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==== FUNCTIONS ====
|
||||||
|
|
||||||
|
//print position
|
||||||
|
//print line that illustrates the position pos between 0 and MAX
|
||||||
|
//e.g. "|----<=>--------|"
|
||||||
|
void printPos(int pos){
|
||||||
|
int width = 50;
|
||||||
|
printf("(%d)|", pos);
|
||||||
|
for (int i = 0; i<(pos) * width/MAX; i++) printf("-");
|
||||||
|
printf("<=>");
|
||||||
|
for (int i = 0; i<(MAX-pos) * width/MAX; i++) printf("-");
|
||||||
|
printf("|\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//move "virtual axis" to absolute coordinate in mm
|
||||||
|
void moveToAbs(int d){
|
||||||
|
int posOld = posNow;
|
||||||
|
printf ("moving from %d %s to %d (%s)\n", posNow, direction ? "=>" : "<=", d, direction ? "RIGHT" : "LEFT");
|
||||||
|
posNow = d;
|
||||||
|
//illustrate movement (print position for each coordinate change)
|
||||||
|
for (int i=posOld; i!=posNow; i+=posNow>posOld?1:-1) printPos(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//travel back and forth between MIN and MAX coordinate for a certain distance
|
||||||
|
//negative values are processed reversed
|
||||||
|
void travel(int length){
|
||||||
|
int d, remaining;
|
||||||
|
d = abs(length);
|
||||||
|
if(length < 0) direction = !direction; //invert direction in reverse mode
|
||||||
|
|
||||||
|
while (d != 0){
|
||||||
|
//--- currently moving right ---
|
||||||
|
if (direction == true){ //currently moving right
|
||||||
|
remaining = MAX - posNow; //calc remaining distance fom current position to limit
|
||||||
|
if (d > remaining){ //new distance will exceed limit
|
||||||
|
moveToAbs (MAX); //move to limit
|
||||||
|
direction = false; //change current direction for next iteration
|
||||||
|
d = d - remaining; //decrease target length by already traveled distance
|
||||||
|
printf(" --- changed direction (L) --- \n ");
|
||||||
|
}
|
||||||
|
else { //target distance does not reach the limit
|
||||||
|
moveToAbs (posNow + d); //move by (remaining) distance to reach target length
|
||||||
|
d = 0; //finished, reset target length (could as well exit loop/break)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--- currently moving left ---
|
||||||
|
else {
|
||||||
|
remaining = posNow - MIN;
|
||||||
|
if (d > remaining){
|
||||||
|
moveToAbs (MIN);
|
||||||
|
direction = true;
|
||||||
|
d = d - remaining;
|
||||||
|
printf(" --- changed direction (R) --- \n ");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
moveToAbs (posNow - d); //when moving left the coordinate has to be decreased
|
||||||
|
d = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(length < 0) direction = !direction; //undo inversion of direction after reverse mode is finished
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==== MAIN ====
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
int input;
|
||||||
|
printf("**cable-length-cutter testing cnc-guide**\n");
|
||||||
|
while(1){
|
||||||
|
printf("enter mm to travel:");
|
||||||
|
scanf("%d", &input);
|
||||||
|
travel(input);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
7
testing/cnc-guide/makefile
Normal file
7
testing/cnc-guide/makefile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
default: program
|
||||||
|
|
||||||
|
program:
|
||||||
|
gcc main.c -o a.out -lm
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-rm -f a.out
|
Loading…
x
Reference in New Issue
Block a user