Hi all !
I'm building a fast controller to control 3 stepper motors using 3 high resolution step / dir drivers DRV8434 and a teensy 4.0.
Code platform is Arduino IDE.
I will not upload the entire code, just explain that it uses a main "xyz.ino" file to handle mostly the communication with the PC via a serial communication, and a class library I wrote to handle all the motor's functionalities.
class header file. step and dir pins are pointers to a const uint8_t:
other function calls to move the motor's steps according to a step counter (not showed here), it calls the "move_step()" function at the correct timing.
there are no delays and no interrupts in the entire code.
I need to reach a very high speeds so I'm using the internal cycle counter (ARM_DWT_CYCCNT) as a timing reference to call this function at the correct "timing" from a "parent" function, so according the DRV8434 datasheet HIGH must remain at least 700ns and low at least 300ns for the driver to work properly. but to activate 3 motors "in parallel" I need every MCU cycle to be used efficiently as possible, so meanwhile I'm "waiting" those 700ns the MCU needs to process the other motors commands to make the movement smooth as possible.
It is highly important at very high speeds (where the gap between steps can be short as ~2us) to be consistent with the speed and acceleration or else the stepper will loose steps.
So I know the digitalWriteFast() function must receive a constant pin number to work fast, otherwise it will be same as digitalWrite() slow. at those high speeds I can't notice any different when using the Fast write and regular write, so I think the use of pointers did not work as a solution for the constant value needed for the fast function.
Do you have any advice on how to use a class which will controls 3 motors and gets the pin number at the beginning but let the Fast digital write work ?
Thanks
I'm building a fast controller to control 3 stepper motors using 3 high resolution step / dir drivers DRV8434 and a teensy 4.0.
Code platform is Arduino IDE.
I will not upload the entire code, just explain that it uses a main "xyz.ino" file to handle mostly the communication with the PC via a serial communication, and a class library I wrote to handle all the motor's functionalities.
// ### "xyz.ino" ###
#include "classes.h"
// all pins are const uint8_t
Motor m[3] = {
Motor("X" , &X_STEP_PIN , &X_DIR_PIN , X_SW_PIN , X_RES_0_PIN , X_RES_1_PIN ),
Motor("Y" , &Y_STEP_PIN , &Y_DIR_PIN , Y_SW_PIN , Y_RES_0_PIN , Y_RES_1_PIN ),
Motor("Z" , &Z_STEP_PIN , &Z_DIR_PIN , Z_SW_PIN , Z_RES_0_PIN , Z_RES_1_PIN )
// (Name, Step Pin , Dir Pin , Sw Pin , Resolution0 Pin , Resolution1 Pin )
};
void setup{
//...
}
// --------------------------- LOOP -------------------------
void loop(){
do_computer_command();
m[0].move_motor();
m[1].move_motor();
m[2].move_motor();
}
class header file. step and dir pins are pointers to a const uint8_t:
// ### "classes.h" ###
#include <Arduino.h>
class Motor{
private:
String name; // the name of the motor for example "X axis" / "Y"
const uint8_t *StepPin; // the pulse sending pin of the MCU to control "step" pin in driver
const uint8_t *DirPin; // the direction pin of the MCU to control "dir" pin on driver
//...
public:
//...
};
other function calls to move the motor's steps according to a step counter (not showed here), it calls the "move_step()" function at the correct timing.
// ### "classes.cpp" ###
#include "classes.h"
Motor::Motor(String n, const byte *s, const byte *d, byte sw, byte m0){ // constructor
name = n;
StepPin = s;
DirPin = d;
LimitSwPin = sw;
pinMode(*StepPin, OUTPUT);
pinMode(*DirPin, OUTPUT);
pinMode(LimitSwPin, INPUT_PULLUP);
sw_state = digitalRead(LimitSwPin);
m0Pin = m0;
}
/*
-- other functions --
*/
void Motor::move_step(){
if(do_step){
if (do_high){
digitalWriteFast(*StepPin, HIGH);
step_cyc = ARM_DWT_CYCCNT;
do_high = false;
}
else if (ARM_DWT_CYCCNT - step_cyc > 420){
digitalWriteFast(*StepPin, LOW);
do_step = false;
current_location = current_location + ((moving_dir)?1:-1);
steps_done++;
}
}
}
there are no delays and no interrupts in the entire code.
I need to reach a very high speeds so I'm using the internal cycle counter (ARM_DWT_CYCCNT) as a timing reference to call this function at the correct "timing" from a "parent" function, so according the DRV8434 datasheet HIGH must remain at least 700ns and low at least 300ns for the driver to work properly. but to activate 3 motors "in parallel" I need every MCU cycle to be used efficiently as possible, so meanwhile I'm "waiting" those 700ns the MCU needs to process the other motors commands to make the movement smooth as possible.
It is highly important at very high speeds (where the gap between steps can be short as ~2us) to be consistent with the speed and acceleration or else the stepper will loose steps.
So I know the digitalWriteFast() function must receive a constant pin number to work fast, otherwise it will be same as digitalWrite() slow. at those high speeds I can't notice any different when using the Fast write and regular write, so I think the use of pointers did not work as a solution for the constant value needed for the fast function.
Do you have any advice on how to use a class which will controls 3 motors and gets the pin number at the beginning but let the Fast digital write work ?
Thanks