hello,
i recently got some steppers working with accel stepper and interupts,
i have got the interupt running every 1ms with the help of online forums and it works fine on arduino boards,but i made a pcb shield for the teensy and some steppers not realising that interupts dont work the same and that teensystep doesnt work on teensy 4.0.
so with the code below my question is how can i convert this to teensy,how would i go about changing the interupts to work on teensy 4?
i just need a function to be called every 1ms,
if someone could point me in the right direction that would be cool.
thanks
i recently got some steppers working with accel stepper and interupts,
i have got the interupt running every 1ms with the help of online forums and it works fine on arduino boards,but i made a pcb shield for the teensy and some steppers not realising that interupts dont work the same and that teensystep doesnt work on teensy 4.0.
so with the code below my question is how can i convert this to teensy,how would i go about changing the interupts to work on teensy 4?
i just need a function to be called every 1ms,
if someone could point me in the right direction that would be cool.
thanks
Code:
#include <Arduino.h>
#include <AccelStepper.h>
#define stepM1 9// m1
#define dirM1 8
#define dirM2 7 // m2
#define stepM2 6
#define stepM3 4 // m3
#define dirM3 5
#define stepM4 2 // m4
#define dirM4 3
#define stepM5 15 // m5
#define dirM5 16
#define stepM6 13 // m6
#define dirM6 14
#define global_enable 10
AccelStepper stepper1(AccelStepper::FULL2WIRE, stepM1, dirM1);
AccelStepper stepper2(AccelStepper::FULL2WIRE, stepM2, dirM2);
AccelStepper stepper3(AccelStepper::FULL2WIRE, stepM3, dirM3);
AccelStepper stepper4(AccelStepper::FULL2WIRE, stepM4, dirM4);
AccelStepper stepper5(AccelStepper::FULL2WIRE, stepM5, dirM5);
AccelStepper stepper6(AccelStepper::FULL2WIRE, stepM6, dirM6);
constexpr uint32_t steps_per_mm = 21; //
long stepstotake = 200 * 4;
uint8_t stepper_choice = 0;
long previousMillis = 0;
const int interval = 1300;
const uint8_t Amount_of_steppers = 6;
AccelStepper* stepperArray[Amount_of_steppers] = {
&stepper1,
&stepper2,
&stepper3,
&stepper4,
&stepper5,
&stepper6,
};
void setup()
{
pinMode(global_enable, OUTPUT);
digitalWrite(global_enable, LOW);
for (int x = 0; x < Amount_of_steppers; x++) {
stepperArray[x]->setMaxSpeed(50 * steps_per_mm); //
stepperArray[x]->setAcceleration(1000 * steps_per_mm); //
}
if (!SetUpInterrupts(100)) {
while (1) {
}
}
}
void loop()
{
all_up_down(1);
wave(1);
while (1);
}
int AmountofpassesWave = 0;
void wave(uint8_t times ) {
times = times * 2;
while (AmountofpassesWave < 2) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
stepperArray[stepper_choice]->moveTo(stepstotake);
stepper_choice++;
}
if (stepper_choice == Amount_of_steppers) {
stepper_choice = 0;
stepstotake -= stepstotake;
AmountofpassesWave++;
}
}
AmountofpassesWave=0;
}
void all_up_down(uint8_t times ) {
times = times * 2;
while (int Amountofpasses = 0 < 2) {
for (int x = 0; x < Amount_of_steppers; x++) {
stepperArray[x]->moveTo(stepstotake/2);
}
if (stepper1.distanceToGo() == 0) {
stepstotake -= stepstotake;
Amountofpasses++;
}
}
AmountofpassesWave=0;
}
ISR(TIMER1_COMPA_vect)
{
for (int x = 0; x < Amount_of_steppers; x++) {
stepperArray[x]->run();
}
}
/*****************************************************************************
The standard Arduino has 3 timers,
timer0 is 8 bit and used for the millis() and micros() functions.
Timer1 is 16 bit and not used by default,
timer2 is another 8 bit timer like timer0 but not used by default.
** SetUpInterrupts
** ===============
Set up interrupt routine to service stepper motor run() function.
*/
// TIMER1_COMPA_vect TIMSK1,OCIE1A TIFR1,OCF1A Timer 1 Compare A Match
bool SetUpInterrupts(const int usecs) // usec = µs
{
// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// set compare match register to desired timer count (1ms):
// ATmega328 with a 16MHz clock, clk/8
// (# timer counts + 1) = (target time) / (timer resolution)
// = .0001s / 6.25e-8 s * 8
// = 200
const float targetSecs = ((float) usecs) / 1e6;
const float timerSteps = 6.25e-8; // 1/16MHz
int count = 0;
int prescale = 1; // valid values: 1, 8, 64, 256, 1024
do {
count = targetSecs / (timerSteps * prescale);
if (count < 65535) // Timer 1 is 16-bits wide
break;
prescale *= 8;
} while (prescale <= 1024);
if (prescale > 1024) // time too long
return false;
if (prescale == 1 && count < 100) // time too short
return false;
OCR1A = count; // Eg, 200 = 0.1ms - I found 1ms gives rough acceleration
// turn on CTC mode (Clear Timer on Compare Match):
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
// CS12 CS11 CS10
// 0 0 0 no clock source, Timer/counter stopped
// 0 0 1 clk/1 no prescaling
// 0 1 0 clk/8
// 0 1 1 clk/64
// 1 0 0 clk/256
// 1 0 1 clk/1024
// 1 1 0 external clock on T1 pin, falling edge
// 1 1 1 external clock on T1 pin, rising edge
switch (prescale) {
case 1:
TCCR1B |= (1 << CS10); // 0 0 1
break;
case 8:
TCCR1B |= (1 << CS11); // 0 1 0
break;
case 64:
TCCR1B |= (1 << CS11) & (1 << CS10); // 0 1 1
break;
case 256:
TCCR1B |= (1 << CS12); // 1 0 0
break;
case 1024:
TCCR1B |= (1 << CS12) & (1 << CS10); // 1 0 1
break;
}
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
// enable global interrupts:
sei();
return true;
}