Hi @monkeyfist!
Update:
(When this happens the controller loses actual positions i think, because the start and end point of the steppers that set up at the start changes. For example the tilt motor starts centered, moves back and forth max 200 steps, from center. But if this uncontrolled movements occur the center point is moving away from the starting center point. Updated the code!
You already solved one of my problems here with the uart communication, now there is another error of a different nature.
I have a strange situation and after a day of debugging doesn't find the cause of it.
I',m using three TMC2209 with fastaccelstepper library on ESP32. Now everything works, except i have a strange uncontrolled movement on the axes. I control the steppers with an RC controller, and if i have stop moving the input joysticks the steppers stopping and after a while the motors make movements (few random steps) back and forth. So not stopping the last position.
My uart is working because if i set the current or microsteps i see the result, but this error ruins everything for me.
I commented out the wifi and most of the code, but doesnt find the root of this.
Can you please help me with this situation?
Any help would be great.
Thank you very very much if you have some time to help me.
#include "SumdRx.h"
#include "FastAccelStepper.h"
#include <TMCStepper.h>
#include <HardwareSerial.h>
#include <WiFi.h>
#include <WebServer.h>
#include <WebSocketsServer.h>
#include <ArduinoSort.h>
#define SLIDE_MOTOR_STEP_PIN 26
#define SLIDE_MOTOR_DIRECTION_PIN 27
#define PAN_MOTOR_STEP_PIN 22
#define PAN_MOTOR_DIRECTION_PIN 23
#define TILT_MOTOR_STEP_PIN 19
#define TILT_MOTOR_DIRECTION_PIN 21
#define SLIDE_MAX_SPEED 700
#define SLIDE_MAX_ACCELERATION 8000
#define PAN_MAX_SPEED 500
#define PAN_MAX_ACCELERATION 8000
#define TILT_MAX_SPEED 250
#define TILT_MAX_ACCELERATION 8000
#define RXD2 16
#define TXD2 17
#define SERIAL_PORT_2 Serial2 // TMC2208/TMC2224 HardwareSerial port - pins 16 & 17
#define DRIVER_S_ADDRESS 0b00 // TMC2209 Driver address according to MS1 and MS2
#define DRIVER_P_ADDRESS 0b01 // TMC2209 Driver address according to MS1 and MS2
#define DRIVER_T_ADDRESS 0b10 // TMC2209 Driver address according to MS1 and MS2
#define R_SENSE 0.11f // E_SENSE for current calc, SilentStepStick series use 0.11
FastAccelStepperEngine engine = FastAccelStepperEngine();
FastAccelStepper *slide_stepper = NULL;
FastAccelStepper *pan_stepper = NULL;
FastAccelStepper *tilt_stepper = NULL;
TMC2209Stepper driver_s(&SERIAL_PORT_2, R_SENSE, DRIVER_S_ADDRESS); // Create TMC driver
TMC2209Stepper driver_p(&SERIAL_PORT_2, R_SENSE, DRIVER_P_ADDRESS); // Create TMC driver
TMC2209Stepper driver_t(&SERIAL_PORT_2, R_SENSE, DRIVER_T_ADDRESS); // Create TMC driver
// //*Web things***********************************//
//-----------------------------------------------
const char *ssid = "ESP32Slider"; // Your WiFi AP SSID
const char *password = "testpassword"; // Your WiFi Password
//-----------------------------------------------
WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);
String JSONtxt;
//-----------------------------------------------
#include "webpage.h"
#include "functions.h"
// //**********************************************//
const int ReedSensor = 35; //REED switch port
int ReedState; // 0 close - 1 open switch
// RC Channel order and functions //
// CH1 Stepper 1 Axle S Slide (Only negative positions enabled, the ZERO is the limitswitch)
// CH2 Stepper 2 Axle P Pan
// CH3 Stepper 3 Axle T Tilt
// CH4 Speed Control for AutoMOve
// CH5 Set IN/OUT position if CH8 ENABLED, the In/Out block is selected in CH7 (1,2,3)
// CH6 Start / Stop / ReSet AUTO MOve according to CH7 setting (1,2,3), 3 sec long push resets all axles to ZERO
// CH7 Set IN/OUT SET (1,2,3)
// CH8 UP In/Out setting ENABLED, center nothing, LOW Move to In or OUT, selected by CH5 - CH8
// CH9 Reset board
//TMC2209 variables
int current = 1000;
int stall = 255;
int motor_microsteps = 4;
int motor_steps_per_rev = 200;
int msread;
int mpread;
int mtread;
//Position variables
int ActualInOut = 1;
int InandOut = 0; //IN-OUT points active or not
boolean SetInOut = false;
long SInPoint[4]; //Slide IN
long PInPoint[4]; //Pan IN
long TInPoint[4]; //Tilt IN
long SOutPoint[4]; //Slide OUT
long POutPoint[4]; //Pan OUT
long TOutPoint[4]; //Tilt OUT
boolean InSet[4]; //IN point is stored
boolean OutSet[4]; //OUT point is stored
boolean automove = false; //automove is ACTIVE or not
long gotoposition[3]; // An array to store the In or Out position for each stepper motor
int SMS; //Slide Stepper speed from pwm[0]
int PMS; //Pan Stepper speed from pwm[1]
int TMS; //Tilt Stepper speed from pwm[2]
//*** Speed calculation variables ***
long pan_steps_to_move = 0;
long tilt_steps_to_move = 0;
long slide_steps_to_move = 0;
long steps_to_move[3] = { 0, 0, 0 };
double pan_time_motion_complete = 0;
double tilt_time_motion_complete = 0;
double slide_time_motion_complete = 0;
int pan_speed_motion_complete = 0;
int tilt_speed_motion_complete = 0;
int slide_speed_motion_complete = 0;
//*** Speed calculation end
//Variables for Homing
long initial_homing = 1; // Used to Home Stepper at startup
//Speed variables
int inOutSpeed = 0;
//PWM values array
int pwm[9];
//RC read timing variables
unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 1000; //the value is a number of milliseconds
//HardwareSerial SerialPort(1); // use UART1
//remote control status
bool failSafe = true;
SumdRx *sumdDecoder;
void setup() {
pinMode(SLIDE_MOTOR_DIRECTION_PIN, OUTPUT);
pinMode(SLIDE_MOTOR_STEP_PIN, OUTPUT);
pinMode(PAN_MOTOR_DIRECTION_PIN, OUTPUT);
pinMode(PAN_MOTOR_STEP_PIN, OUTPUT);
pinMode(TILT_MOTOR_DIRECTION_PIN, OUTPUT);
pinMode(TILT_MOTOR_STEP_PIN, OUTPUT);
// INTITIALIZE SERIAL0 ITERFACE
Serial.begin(115200);
delay(500);
Serial.println(F("---------------------------------------------------"));
Serial.println(F("UART0 serial output interface intitialized @ 115200"));
//*********************************************************************//
//Server is accessible at 192.168.4.1/webserial URL.
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
server.on("/", handleRoot);
server.begin();
webSocket.begin();
webSocket.onEvent(webSocketEvent);
//*********************************************************************//
Serial1.begin(115200, SERIAL_8N1, 33, -1);
// INITIALIZE SERIAL2 UART FOR TMC2209
SERIAL_PORT_2.begin(115200); // INITIALIZE UART TMC2209, SERIAL_8N1, 16, 17
Serial.println(F("UART2 interface for TMC2209 intitialized @ 115200"));
Serial.println(F("---------------------------------------------------"));
//Attach SUMD decoder to the serial port
sumdDecoder = new SumdRx();
delay(1000);
//************************************************************************************************************************//
//TMCSTEPPER SETTINGS
driver_s.begin();
driver_s.pdn_disable(true); // Use PDN/UART pin for communication
driver_s.toff(3); // [1..15] enable driver_s in software
driver_s.blank_time(24); // [16, 24, 36, 54]
driver_s.I_scale_analog(false); // Use internal voltage reference
driver_s.rms_current(current); // motor RMS current (mA) "rms_current will by default set ihold to 50% of irun but you can set your own ratio with additional second argument; rms_current(1000, 0.3)."
driver_s.mstep_reg_select(true);
driver_s.microsteps(motor_microsteps); //note that MicroPlyer will interpolate to 256
driver_s.seimin(1); // minimum current for smart current control 0: 1/2 of IRUN 1: 1/4 of IRUN
driver_s.semin(15); // [0... 15] If the StallGuard4 result falls below SEMIN*32, the motor current becomes increased to reduce motor load angle.
driver_s.semax(15); // [0... 15] If the StallGuard4 result is equal to or above (SEMIN+SEMAX+1)*32, the motor current becomes decreased to save energy.
driver_s.iholddelay(3); // 0 - 15 smooth current drop
driver_s.intpol(true); // interpolate to 256 microsteps
driver_s.SGTHRS(stall);
driver_s.pwm_autoscale(true); // Needed for stealthChop
driver_s.en_spreadCycle(false); // false = StealthChop / true = SpreadCycle, Spreadcycle can have higher RPM but is louder
driver_s.internal_Rsense(false);
driver_s.TCOOLTHRS(0);
driver_s.TPWMTHRS(0);
//************************************************************************************************************************//
//************************************************************************************************************************//
//TMCSTEPPER SETTINGS
driver_p.begin();
driver_p.pdn_disable(true); // Use PDN/UART pin for communication
driver_p.toff(3); // [1..15] enable driver_p in software
driver_p.blank_time(24); // [16, 24, 36, 54]
driver_p.I_scale_analog(false); // Use internal voltage reference
driver_p.rms_current(current); // motor RMS current (mA) "rms_current will by default set ihold to 50% of irun but you can set your own ratio with additional second argument; rms_current(1000, 0.3)."
driver_p.mstep_reg_select(true);
driver_p.microsteps(motor_microsteps); //note that MicroPlyer will interpolate to 256
driver_p.seimin(1); // minimum current for smart current control 0: 1/2 of IRUN 1: 1/4 of IRUN
driver_p.semin(15); // [0... 15] If the StallGuard4 result falls below SEMIN*32, the motor current becomes increased to reduce motor load angle.
driver_p.semax(15); // [0... 15] If the StallGuard4 result is equal to or above (SEMIN+SEMAX+1)*32, the motor current becomes decreased to save energy.
driver_p.iholddelay(3); // 0 - 15 smooth current drop
driver_p.intpol(true); // interpolate to 256 microsteps
driver_p.SGTHRS(stall);
driver_p.pwm_autoscale(true); // Needed for stealthChop
driver_p.en_spreadCycle(false); // false = StealthChop / true = SpreadCycle, Spreadcycle can have higher RPM but is louder
driver_p.internal_Rsense(false);
driver_p.TCOOLTHRS(0);
driver_p.TPWMTHRS(0);
//************************************************************************************************************************//
//************************************************************************************************************************//
//TMCSTEPPER SETTINGS
driver_t.begin();
driver_t.pdn_disable(true); // Use PDN/UART pin for communication
driver_t.toff(3); // [1..15] enable driver_t in software
driver_t.blank_time(24); // [16, 24, 36, 54]
driver_t.I_scale_analog(false); // Use internal voltage reference
driver_t.rms_current(current); // motor RMS current (mA) "rms_current will by default set ihold to 50% of irun but you can set your own ratio with additional second argument; rms_current(1000, 0.3)."
driver_t.mstep_reg_select(true);
driver_t.microsteps(motor_microsteps); //note that MicroPlyer will interpolate to 256
driver_t.seimin(1); // minimum current for smart current control 0: 1/2 of IRUN 1: 1/4 of IRUN
driver_t.semin(15); // [0... 15] If the StallGuard4 result falls below SEMIN*32, the motor current becomes increased to reduce motor load angle.
driver_t.semax(15); // [0... 15] If the StallGuard4 result is equal to or above (SEMIN+SEMAX+1)*32, the motor current becomes decreased to save energy.
driver_t.iholddelay(3); // 0 - 15 smooth current drop
driver_t.intpol(true); // interpolate to 256 microsteps
driver_t.SGTHRS(stall);
driver_t.pwm_autoscale(true); // Needed for stealthChop
driver_t.en_spreadCycle(false); // false = StealthChop / true = SpreadCycle, Spreadcycle can have higher RPM but is louder
driver_t.internal_Rsense(false);
driver_t.TCOOLTHRS(0);
driver_t.TPWMTHRS(0);
//************************************************************************************************************************//
engine.init();
pan_stepper = engine.stepperConnectToPin(PAN_MOTOR_STEP_PIN);
tilt_stepper = engine.stepperConnectToPin(TILT_MOTOR_STEP_PIN);
slide_stepper = engine.stepperConnectToPin(SLIDE_MOTOR_STEP_PIN);
if (pan_stepper) {
pan_stepper->setDirectionPin(PAN_MOTOR_DIRECTION_PIN);
pan_stepper->setAutoEnable(true);
pan_stepper->setSpeedInHz(0); // steps/s
pan_stepper->setAcceleration(PAN_MAX_ACCELERATION); // steps/s²
}
if (tilt_stepper) {
tilt_stepper->setDirectionPin(TILT_MOTOR_DIRECTION_PIN);
tilt_stepper->setAutoEnable(true);
tilt_stepper->setSpeedInHz(0); // steps/s
tilt_stepper->setAcceleration(TILT_MAX_ACCELERATION); // steps/s²
}
if (slide_stepper) {
slide_stepper->setDirectionPin(SLIDE_MOTOR_DIRECTION_PIN);
slide_stepper->setAutoEnable(true);
slide_stepper->setSpeedInHz(0); // steps/s
slide_stepper->setAcceleration(SLIDE_MAX_ACCELERATION); // steps/s²
}
for (int i = 0; i < 5; i++) { //SET all IN and OUT points to zero
InSet[i] = false;
OutSet[i] = false;
}
//pinMode(ReedSensor, INPUT_PULLUP);
/*
// Move the slider to the initial position - homing
// Start Homing procedure of Stepper Motor at startup
println("Stepper is Homing . . .");
ReedState = digitalRead(ReedSensor);
print("LiMiT SW: ");
println(ReedState);
delay(5000);
while (digitalRead(ReedSensor)) { // Make the Stepper move CCW until the switch is activated
stepper1.moveTo(initial_homing); // Set the position to move to
initial_homing++; // Decrease by 1 for next move if needed
stepper1.run(); // Start moving the stepper
delay(5);
}
stepper1.setCurrentPosition(0); // Set the current position as zero for now
stepper1.setMaxSpeed(100.0); // Set Max Speed of Stepper (Slower to get better accuracy)
initial_homing = -1;
ReedState = digitalRead(ReedSensor);
print("LiMiT SW: ");
println(ReedState);
while (!digitalRead(ReedSensor)) { // Make the Stepper move CW until the switch is deactivated
stepper1.moveTo(-2000);
stepper1.run();
initial_homing--;
delay(5);
}
stepper1.setCurrentPosition(0);
println("Homing Completed");
println("");
stepper1.setMaxSpeed(max_speed); // Set Max Speed of Stepper (Slower to get better accuracy)*/
startMillis = millis(); //initial start time
pan_stepper->setCurrentPosition(0);
tilt_stepper->setCurrentPosition(0);
slide_stepper->setCurrentPosition(0);
}
//***********************************************************************
void read_ms() {
msread = driver_s.microsteps();
mpread = driver_p.microsteps();
mtread = driver_t.microsteps();
}
//***********************************************************************
void loop() {
webSocket.loop();
server.handleClient();
//-----------------------------------------------
static unsigned long l = 0;
unsigned long t = millis();
if ((t - l) > 1000) {
//-----------------------------------------------
String pwm0valString = String(pwm[0]);
String pwm1valString = String(pwm[1]);
String pwm2valString = String(pwm[2]);
String pwm3valString = String(pwm[3]);
String pwm4valString = String(pwm[4]);
String pwm5valString = String(pwm[5]);
String pwm6valString = String(pwm[6]);
String pwm7valString = String(pwm[7]);
String pwm8valString = String(pwm[8]);
String slidespdvalString = String(SMS);
String panspdvalString = String(PMS);
String tiltspdvalString = String(TMS);
//-----------------------------------------------
JSONtxt = "{\"pwm0\":\"" + pwm0valString + "\",";
JSONtxt += "\"pwm1\":\"" + pwm1valString + "\",";
JSONtxt += "\"pwm2\":\"" + pwm2valString + "\",";
JSONtxt += "\"pwm3\":\"" + pwm3valString + "\",";
JSONtxt += "\"pwm4\":\"" + pwm4valString + "\",";
JSONtxt += "\"pwm5\":\"" + pwm5valString + "\",";
JSONtxt += "\"pwm6\":\"" + pwm6valString + "\",";
JSONtxt += "\"pwm7\":\"" + pwm7valString + "\",";
JSONtxt += "\"pwm8\":\"" + pwm8valString + "\",";
JSONtxt += "\"slidespd\":\"" + slidespdvalString + "\",";
JSONtxt += "\"panspd\":\"" + panspdvalString + "\",";
JSONtxt += "\"tiltspd\":\"" + tiltspdvalString + "\"}";
webSocket.broadcastTXT(JSONtxt);
}
GetData(); //read SUMD from Serial RX
CheckCH1();
CheckCH2();
CheckCH3();
pwm[3] = sumdDecoder->channel[3];
pwm[4] = sumdDecoder->channel[4];
pwm[5] = sumdDecoder->channel[5];
pwm[6] = sumdDecoder->channel[6];
pwm[7] = sumdDecoder->channel[7];
pwm[8] = sumdDecoder->channel[8];
/*CheckCH4();
if (pwm[4] > 1550 || pwm[4] < 1450) {
CheckCH5();
} else if (pwm[5] > 1550 || pwm[5] < 1450) {
CheckCH6();
}
CheckCH7();
CheckCH8();
CheckCH9();*/
// currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started)
// if (currentMillis - startMillis >= period) //test whether the period has elapsed
// {
// startMillis = currentMillis; //IMPORTANT to save the start time
// }
}
void CheckCH1() {
pwm[0] = sumdDecoder->channel[0]; // Get pwm[0]
SMS = abs(map(pwm[0], 1000, 2000, -SLIDE_MAX_SPEED, SLIDE_MAX_SPEED)); // MAP speed from PWM
slide_stepper->setSpeedInHz(SMS);
if (pwm[0] > 1510) {
if (slide_stepper->getCurrentPosition() >= -200) {
slide_stepper->setSpeedInHz(0);
slide_stepper->stopMove();
} else {
slide_stepper->moveTo(-200);
}
} else if (pwm[0] < 1490) {
if (slide_stepper->getCurrentPosition() <= -5000) {
slide_stepper->setSpeedInHz(0);
slide_stepper->stopMove();
} else {
slide_stepper->moveTo(-5000);
}
} else {
slide_stepper->setSpeedInHz(0);
slide_stepper->stopMove();
}
}
void CheckCH2() {
pwm[1] = sumdDecoder->channel[1];
PMS = abs(map(pwm[1], 1000, 2000, -PAN_MAX_SPEED, PAN_MAX_SPEED)); // Increase speed as moving
pan_stepper->setSpeedInHz(PMS);
if (pwm[1] > 1520) {
if (pan_stepper->getCurrentPosition() >= 200) {
pan_stepper->setSpeedInHz(0);
pan_stepper->stopMove();
} else {
pan_stepper->moveTo(200);
}
} else if (pwm[1] < 1480) {
if (pan_stepper->getCurrentPosition() <= -200) {
pan_stepper->setSpeedInHz(0);
pan_stepper->stopMove();
} else {
pan_stepper->moveTo(-200);
}
} else {
pan_stepper->setSpeedInHz(0);
pan_stepper->stopMove();
}
}
void CheckCH3() {
pwm[2] = sumdDecoder->channel[2];
TMS = abs(map(pwm[2], 1000, 2000, -TILT_MAX_SPEED, TILT_MAX_SPEED)); // Increase speed as moving
tilt_stepper->setSpeedInHz(TMS);
if (pwm[2] > 1520) {
if (tilt_stepper->getCurrentPosition() >= 200) {
tilt_stepper->setSpeedInHz(0);
tilt_stepper->stopMove();
} else {
tilt_stepper->moveTo(200);
}
} else if (pwm[2] < 1480) {
if (tilt_stepper->getCurrentPosition() <= -200) {
tilt_stepper->setSpeedInHz(0);
tilt_stepper->stopMove();
} else {
tilt_stepper->moveTo(-200);
}
} else {
tilt_stepper->setSpeedInHz(0);
tilt_stepper->stopMove();
}
}
void CheckCH4() {
inOutSpeed = pwm[3];
inOutSpeed = map(inOutSpeed, 1000, 2000, 0, SLIDE_MAX_SPEED); // Increase speed as moving
}
void CheckCH5() {
if (pwm[4] < 1490 && SetInOut == true) { // Set IN position
SInPoint[ActualInOut] = slide_stepper->getCurrentPosition(); // Set the IN position for steppers
PInPoint[ActualInOut] = pan_stepper->getCurrentPosition();
TInPoint[ActualInOut] = tilt_stepper->getCurrentPosition();
InSet[ActualInOut] = true;
} else if (pwm[4] > 1510 && SetInOut == true) { // Set OUT position
SOutPoint[ActualInOut] = slide_stepper->getCurrentPosition(); // Set the OUT Points for steppers
POutPoint[ActualInOut] = pan_stepper->getCurrentPosition();
TOutPoint[ActualInOut] = tilt_stepper->getCurrentPosition();
OutSet[ActualInOut] = true;
InandOut = 0;
}
}
void CheckCH6() {
if (pwm[5] > 1510 && OutSet[ActualInOut] == true) {
automove = true;
switch (InandOut) {
case 0: // Move to IN position / go to case 1
// Place the IN position into the Array
gotoposition[0] = SInPoint[ActualInOut];
gotoposition[1] = PInPoint[ActualInOut];
gotoposition[2] = TInPoint[ActualInOut];
CalcMoves();
if (slide_stepper->getCurrentPosition() != gotoposition[0]) {
slide_stepper->moveTo(gotoposition[0]);
}
if (pan_stepper->getCurrentPosition() != gotoposition[1]) {
pan_stepper->moveTo(gotoposition[1]);
}
if (tilt_stepper->getCurrentPosition() != gotoposition[2]) {
tilt_stepper->moveTo(gotoposition[2]);
}
if (!(pan_stepper->isRunning()) && !(tilt_stepper->isRunning()) && !(slide_stepper->isRunning())) {
delay(500);
InandOut = 1;
}
break;
case 1: // Move to OUT position / go back to case 0
// Place the OUT position into the Array
gotoposition[0] = SOutPoint[ActualInOut];
gotoposition[1] = POutPoint[ActualInOut];
gotoposition[2] = TOutPoint[ActualInOut];
CalcMoves();
if (slide_stepper->getCurrentPosition() != gotoposition[0]) {
slide_stepper->moveTo(gotoposition[0]);
}
if (pan_stepper->getCurrentPosition() != gotoposition[1]) {
pan_stepper->moveTo(gotoposition[1]);
}
if (tilt_stepper->getCurrentPosition() != gotoposition[2]) {
tilt_stepper->moveTo(gotoposition[2]);
}
if (!(pan_stepper->isRunning()) && !(tilt_stepper->isRunning()) && !(slide_stepper->isRunning())) {
InandOut = 0;
delay(500);
}
break;
}
} else if (pwm[5] < 1490 && pwm[7] > 1510) { // If we hold RC 6 longer then half second, reset the in and out positions
delay(500);
if (pwm[5] < 1490) { //Exit from autoMOve / reset In-Out positions
SInPoint[ActualInOut] = 0; //Slide
PInPoint[ActualInOut] = 0; //Pan
TInPoint[ActualInOut] = 0; //Tilt
SOutPoint[ActualInOut] = 0; //Slide
POutPoint[ActualInOut] = 0; //Pan
TOutPoint[ActualInOut] = 0; //Tilt
InSet[ActualInOut] = false;
OutSet[ActualInOut] = false;
automove = false;
//SetSpeed();
}
}
if (pwm[5] < 1490 && pwm[7] < 1510) { // If we hold RC 6 longer then three second, reset to ZERO point
delay(3000);
if (pwm[5] < 1490) { //Reset to ZERO all axles
gotoposition[0] = 0;
gotoposition[1] = 0;
gotoposition[2] = 0;
slide_stepper->setSpeedInHz(inOutSpeed);
pan_stepper->setSpeedInHz(inOutSpeed);
tilt_stepper->setSpeedInHz(inOutSpeed);
automove = false;
delay(200);
//SetSpeed();
}
}
}
//***************************************************************************************
void set_Speed(char _pts) {
switch (_pts) {
case 'p':
{
pan_time_motion_complete = double(steps_to_move[2]) / double(PAN_MAX_SPEED);
pan_speed_motion_complete = PAN_MAX_SPEED;
tilt_speed_motion_complete = abs(tilt_steps_to_move) / pan_time_motion_complete;
slide_speed_motion_complete = abs(slide_steps_to_move) / pan_time_motion_complete;
break;
}
case 't':
{
tilt_time_motion_complete = double(steps_to_move[2]) / double(TILT_MAX_SPEED);
tilt_speed_motion_complete = TILT_MAX_SPEED;
pan_speed_motion_complete = abs(pan_steps_to_move) / tilt_time_motion_complete;
slide_speed_motion_complete = abs(slide_steps_to_move) / tilt_time_motion_complete;
break;
}
case 's':
{
slide_time_motion_complete = double(steps_to_move[2]) / double(SLIDE_MAX_SPEED);
slide_speed_motion_complete = SLIDE_MAX_SPEED;
pan_speed_motion_complete = abs(pan_steps_to_move) / slide_time_motion_complete;
tilt_speed_motion_complete = abs(tilt_steps_to_move) / slide_time_motion_complete;
break;
}
}
}
void CalcMoves() {
pan_steps_to_move = PInPoint[ActualInOut] - POutPoint[ActualInOut];
tilt_steps_to_move = TInPoint[ActualInOut] - TOutPoint[ActualInOut];
slide_steps_to_move = SInPoint[ActualInOut] - SOutPoint[ActualInOut];
steps_to_move[0] = abs(pan_steps_to_move);
steps_to_move[1] = abs(tilt_steps_to_move);
steps_to_move[2] = abs(slide_steps_to_move);
sortArray(steps_to_move, 3);
if (steps_to_move[2] == abs(pan_steps_to_move)) {
//Serial.println("most steps 2 move on pan axis");
set_Speed('p');
}
if (steps_to_move[2] == abs(tilt_steps_to_move)) {
//Serial.println("most steps 2 move on tilt axis");
set_Speed('t');
}
if (steps_to_move[2] == abs(slide_steps_to_move)) {
//Serial.println("most steps 2 move on slide axis");
set_Speed('s');
}
pan_stepper->setSpeedInHz(pan_speed_motion_complete);
tilt_stepper->setSpeedInHz(tilt_speed_motion_complete);
slide_stepper->setSpeedInHz(slide_speed_motion_complete);
}
//***************************************************************************************
void CheckCH7() {
if (pwm[6] > 1510) { // Set 1st InOut position
ActualInOut = 1;
} else if (pwm[6] > 1490 && pwm[6] < 1510) { // Set 2rd InOut position
ActualInOut = 2;
} else if (pwm[6] < 1490) { // Set 3nd InOut position
ActualInOut = 3;
}
}
void CheckCH8() {
if (pwm[7] < 1490) { // Activate the MoveToIn or MoveToOut sequence
switch (ActualInOut) {
case 1:
if (pwm[4] < 1490) {
inOutSpeed = pwm[3]; // Auto speed potentiometer
// Place the 1st IN position into the Array
gotoposition[0] = SInPoint[ActualInOut];
gotoposition[1] = PInPoint[ActualInOut];
gotoposition[2] = TInPoint[ActualInOut];
slide_stepper->setSpeedInHz(inOutSpeed);
pan_stepper->setSpeedInHz(inOutSpeed);
tilt_stepper->setSpeedInHz(inOutSpeed);
delay(200);
} else if (pwm[4] > 1490) {
inOutSpeed = pwm[3];
// Place the 1st OUT position into the Array
gotoposition[0] = SOutPoint[ActualInOut];
gotoposition[1] = POutPoint[ActualInOut];
gotoposition[2] = TOutPoint[ActualInOut];
slide_stepper->setSpeedInHz(inOutSpeed);
pan_stepper->setSpeedInHz(inOutSpeed);
tilt_stepper->setSpeedInHz(inOutSpeed);
delay(200);
}
break;
case 2:
if (pwm[4] < 1490) {
inOutSpeed = pwm[3]; // Auto speed potentiometer
// Place the 2nd IN position into the Array
gotoposition[0] = SInPoint[ActualInOut];
gotoposition[1] = PInPoint[ActualInOut];
gotoposition[2] = TInPoint[ActualInOut];
slide_stepper->setSpeedInHz(inOutSpeed);
pan_stepper->setSpeedInHz(inOutSpeed);
tilt_stepper->setSpeedInHz(inOutSpeed);
delay(200);
} else if (pwm[4] > 1490) {
inOutSpeed = pwm[3];
// Place the 2nd OUT position into the Array
gotoposition[0] = SOutPoint[ActualInOut];
gotoposition[1] = POutPoint[ActualInOut];
gotoposition[2] = TOutPoint[ActualInOut];
slide_stepper->setSpeedInHz(inOutSpeed);
pan_stepper->setSpeedInHz(inOutSpeed);
tilt_stepper->setSpeedInHz(inOutSpeed);
delay(200);
}
break;
case 3:
if (pwm[4] < 1490) {
inOutSpeed = pwm[3]; // Auto speed potentiometer
// Place the 3rd IN position into the Array
gotoposition[0] = SInPoint[ActualInOut];
gotoposition[1] = PInPoint[ActualInOut];
gotoposition[2] = TInPoint[ActualInOut];
slide_stepper->setSpeedInHz(inOutSpeed);
pan_stepper->setSpeedInHz(inOutSpeed);
tilt_stepper->setSpeedInHz(inOutSpeed);
delay(200);
} else if (pwm[4] > 1490) {
inOutSpeed = pwm[3];
// Place the 3rd OUT position into the Array
gotoposition[0] = SOutPoint[ActualInOut];
gotoposition[1] = POutPoint[ActualInOut];
gotoposition[2] = TOutPoint[ActualInOut];
slide_stepper->setSpeedInHz(inOutSpeed);
pan_stepper->setSpeedInHz(inOutSpeed);
tilt_stepper->setSpeedInHz(inOutSpeed);
delay(200);
}
break;
}
} else if (pwm[7] > 1510) {
SetInOut = true;
} else if (pwm[7] > 1490 && pwm[7] < 1510) {
SetInOut = false;
}
}
void CheckCH9() {
if (pwm[8] > 1900) {
pan_stepper->setCurrentPosition(0);
tilt_stepper->setCurrentPosition(0);
slide_stepper->setCurrentPosition(0);
}
}
/*void SetSpeed() {
// Set speed values for the steppers
slide_stepper->setSpeedInHz(max_speed); //SPEED = Steps / second
pan_stepper->setSpeedInHz(max_speed); //SPEED = Steps / second
tilt_stepper->setSpeedInHz(max_speed); //SPEED = Steps / second
}*/
void GetData() {
uint8_t index;
//process sumd input, due to lead time from previous decoding, buffer may overflow and being corrupted -> reset
sumdDecoder->reset();
while (Serial1.available() > 0) sumdDecoder->add(Serial1.read());
//display failsafe status on console
if (failSafe && !sumdDecoder->failSafe()) {
failSafe = false;
//println("Reception OK");
} else if (!failSafe && sumdDecoder->failSafe()) {
failSafe = true;
//println("Reception Lost");
}
// if (!sumdDecoder->failSafe()) {
// for (index = 0; index < sumdDecoder->channelRx; index++) { //display channel status
// print(sumdDecoder->channel[index]);
// print(" ");
// }
// println();
// }
delay(25);
}