- optimize some variable and macro names - change/add function that travels guide certain steps - stepper task: - calculate steps depending on encoder steps - move steps if at least 1 step possible - prepare poti modifier -> untested
232 lines
7.6 KiB
C++
232 lines
7.6 KiB
C++
extern "C"
|
|
{
|
|
#include <stdio.h>
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "esp_log.h"
|
|
#include "driver/adc.h"
|
|
}
|
|
|
|
#include "DendoStepper.h"
|
|
#include "config.hpp"
|
|
#include "guide-stepper.hpp"
|
|
#include "encoder.hpp"
|
|
|
|
|
|
|
|
//---------------------
|
|
//--- configuration ---
|
|
//---------------------
|
|
//also see config.hpp
|
|
//for pin definition
|
|
|
|
#define STEPPER_TEST_TRAVEL 65 //mm
|
|
//
|
|
#define MIN_MM 0
|
|
#define MAX_MM 60
|
|
#define POS_MAX_STEPS MAX_MM * STEPPER_STEPS_PER_MM
|
|
#define POS_MIN_STEPS MIN_MM * STEPPER_STEPS_PER_MM
|
|
|
|
|
|
#define SPEED_MIN 2.0 //mm/s
|
|
#define SPEED_MAX 60.0 //mm/s
|
|
|
|
#define ACCEL_MS 100.0 //ms from 0 to max
|
|
#define DECEL_MS 90.0 //ms from max to 0
|
|
|
|
#define STEPPER_STEPS_PER_ROT 1600
|
|
#define STEPPER_STEPS_PER_MM STEPPER_STEPS_PER_ROT/4
|
|
|
|
#define D_CABLE 6
|
|
#define D_REEL 155 //actual 170
|
|
#define PI 3.14159
|
|
|
|
|
|
|
|
//----------------------
|
|
//----- variables ------
|
|
//----------------------
|
|
static DendoStepper step;
|
|
static const char *TAG = "stepper"; //tag for logging
|
|
|
|
static bool stepp_direction = true;
|
|
static uint32_t posNow = 0;
|
|
|
|
|
|
|
|
//----------------------
|
|
//----- functions ------
|
|
//----------------------
|
|
//move axis certain Steps (relative) between left and right or reverse when negative
|
|
void travelSteps(int stepsTarget){
|
|
//posNow = step.getPositionMm(); //not otherwise controlled, so no update necessary
|
|
int stepsToGo, remaining;
|
|
|
|
stepsToGo = abs(stepsTarget);
|
|
if(stepsTarget < 0) stepp_direction = !stepp_direction; //invert direction in reverse mode
|
|
|
|
while (stepsToGo != 0){
|
|
//--- currently moving right ---
|
|
if (stepp_direction == true){ //currently moving right
|
|
remaining = POS_MAX_STEPS - posNow; //calc remaining distance fom current position to limit
|
|
if (stepsToGo > remaining){ //new distance will exceed limit
|
|
step.runAbs (POS_MAX_STEPS); //move to limit
|
|
while(step.getState() != 1) vTaskDelay(2); //wait for move to finish
|
|
posNow = POS_MAX_STEPS;
|
|
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 ");
|
|
}
|
|
else { //target distance does not reach the limit
|
|
step.runAbs (posNow + stepsToGo); //move by (remaining) distance to reach target length
|
|
while(step.getState() != 1) vTaskDelay(2); //wait for move to finish
|
|
ESP_LOGD(TAG, "moving to %d\n", posNow+stepsToGo);
|
|
posNow += stepsToGo;
|
|
stepsToGo = 0; //finished, reset target length (could as well exit loop/break)
|
|
}
|
|
}
|
|
|
|
//--- currently moving left ---
|
|
else {
|
|
remaining = posNow - POS_MIN_STEPS;
|
|
if (stepsToGo > remaining){
|
|
step.runAbs (POS_MIN_STEPS);
|
|
while(step.getState() != 1) vTaskDelay(2); //wait for move to finish
|
|
posNow = POS_MIN_STEPS;
|
|
stepp_direction = true;
|
|
stepsToGo = stepsToGo - remaining;
|
|
ESP_LOGI(TAG, " --- moved to min -> change direction (R) --- \n ");
|
|
}
|
|
else {
|
|
step.runAbs (posNow - stepsToGo); //when moving left the coordinate has to be decreased
|
|
while(step.getState() != 1) vTaskDelay(2); //wait for move to finish
|
|
ESP_LOGD(TAG, "moving to %d\n", posNow - stepsToGo);
|
|
posNow -= stepsToGo;
|
|
stepsToGo = 0;
|
|
}
|
|
}
|
|
}
|
|
if(stepsTarget < 0) stepp_direction = !stepp_direction; //undo inversion of stepp_direction after reverse mode is finished
|
|
return;
|
|
}
|
|
|
|
|
|
//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(120, 120, 100);
|
|
step.runInf(0);
|
|
vTaskDelay(1500 / portTICK_PERIOD_MS);
|
|
step.stop();
|
|
step.resetAbsolute();
|
|
ESP_LOGW(TAG, "auto-home finished");
|
|
}
|
|
|
|
|
|
//initialize/configure stepper instance
|
|
void init_stepper() {
|
|
ESP_LOGW(TAG, "initializing stepper...");
|
|
DendoStepper_config_t step_cfg = {
|
|
.stepPin = STEPPER_STEP_PIN,
|
|
.dirPin = STEPPER_DIR_PIN,
|
|
.enPin = STEPPER_EN_PIN,
|
|
.timer_group = TIMER_GROUP_0,
|
|
.timer_idx = TIMER_0,
|
|
.miStep = MICROSTEP_32,
|
|
.stepAngle = 1.8};
|
|
step.config(&step_cfg);
|
|
step.init();
|
|
|
|
step.setSpeed(1000, 1000, 1000); //random default speed
|
|
step.setStepsPerMm(STEPPER_STEPS_PER_MM); //guide: 4mm/rot
|
|
}
|
|
|
|
|
|
//function that updates speed value using ADC input and configured MIN/MAX
|
|
void updateSpeedFromAdc() {
|
|
int potiRead = gpio_readAdc(ADC_CHANNEL_POTI); //0-4095 GPIO34
|
|
double poti = potiRead/4095.0;
|
|
int speed = poti*(SPEED_MAX-SPEED_MIN) + SPEED_MIN;
|
|
step.setSpeedMm(speed, ACCEL_MS, DECEL_MS);
|
|
ESP_LOGW(TAG, "poti: %d (%.2lf%%), set speed to: %d", potiRead, poti*100, speed);
|
|
}
|
|
|
|
|
|
|
|
//----------------------------
|
|
//---- TASK stepper-test -----
|
|
//----------------------------
|
|
void task_stepper_test(void *pvParameter)
|
|
{
|
|
init_stepper();
|
|
home();
|
|
|
|
while (1) {
|
|
updateSpeedFromAdc();
|
|
step.runPosMm(-STEPPER_TEST_TRAVEL);
|
|
while(step.getState() != 1) vTaskDelay(2);
|
|
ESP_LOGI(TAG, "finished moving right => moving left");
|
|
|
|
updateSpeedFromAdc();
|
|
step.runPosMm(STEPPER_TEST_TRAVEL);
|
|
while(step.getState() != 1) vTaskDelay(2); //1=idle
|
|
ESP_LOGI(TAG, "finished moving left => moving right");
|
|
}
|
|
}
|
|
|
|
|
|
//----------------------------
|
|
//----- TASK stepper-ctl -----
|
|
//----------------------------
|
|
void task_stepper_ctl(void *pvParameter)
|
|
{
|
|
//variables
|
|
int encStepsNow = 0; //get curret steps of encoder
|
|
int encStepsPrev = 0; //steps at last check
|
|
int encStepsDelta = 0; //steps changed since last iteration
|
|
|
|
double stepsTravel = 0; //steps axis hast to travel
|
|
|
|
init_stepper();
|
|
home();
|
|
|
|
while(1){
|
|
//get current length
|
|
encStepsNow = encoder_getSteps();
|
|
|
|
//calculate change
|
|
encStepsDelta = encStepsNow - encStepsPrev; //FIXME MAJOR BUG: when resetting encoder/length in control task, diff will be huge!
|
|
//TODO add modifier e.g. poti value
|
|
|
|
//read potentiometer for calibration
|
|
float potiModifier = (float) 4095 / gpio_readAdc(ADC_CHANNEL_POTI); //0-4095 -> 0-1
|
|
ESP_LOGI(TAG, "current poti-modifier = %f", potiModifier);
|
|
|
|
//calculate steps moved
|
|
//steps-axis = (length moved in mm) * (travel distance per length) * (stepper steps per mm)
|
|
stepsTravel = (float) (encStepsDelta * 1000 / ENCODER_STEPS_PER_METER) * (D_CABLE/(PI*D_REEL)) * (STEPPER_STEPS_PER_MM);
|
|
//FIXME: rounding issue? e.g. 1.4 steps gets lost
|
|
ESP_LOGD(TAG, "stepsDelta: %d stepsTravel: %lf",encStepsDelta, stepsTravel);
|
|
|
|
//move axis when ready to move at least 1 step
|
|
if (abs((int)stepsTravel) > 1){
|
|
ESP_LOGI(TAG, "MOVING %d steps",(int)stepsTravel);
|
|
travelSteps((int)stepsTravel);
|
|
while(step.getState() != 1) vTaskDelay(2); //wait for move to finish
|
|
encStepsPrev = encStepsNow; //update length
|
|
}
|
|
else {
|
|
//TODO use encoder queue to only run this check at encoder event?
|
|
vTaskDelay(5);
|
|
}
|
|
}
|
|
}
|