Dear all,
I am hoping to utilize the Portenta M4 core to send instructions to a slow stepper motor, and use the M7 core to run other faster tasks in parallel, taking advantage of the M7 higher clock speed.
The precise details are not important, however generally speaking, the stepper motor will control a linear ball screw with a stage attached. I want this stage to move until a certain requirement is met, e.g. until a magnet attached to the stage meets an active-low Hall probe, and then an interrupt is triggered on the falling edge as this Hall probe input goes low, which causes the stepper motor to stop.
#define Stage_MotorSTEP_CW 8 // Pin assigned to clockwise step pin on stepper motor driver
#define Stage_MotorSTEP_CCW 7 // Pin assigned to counterclockwise step pin on stepper motor driver
#define Stage_Motor_Disable 6 // Pin assigned to 'disable' pin on stepper motor driver
#define DigitalHallProbe1 9 // Pin assigned to Hall probe signal input
void setup() {
pinMode(Stage_MotorSTEP_CW, OUTPUT); // Output for sending pulses to tell stepper driver to move one step CW
pinMode(Stage_MotorSTEP_CCW, OUTPUT); // Output for sending pulses to tell stepper driver to move one step CCW
pinMode(Stage_Motor_Disable, OUTPUT); // Output sends pulse to driver to disable stepper motor
pinMode(DigitalHallProbe1, INPUT_PULLUP); // Digital Hall probe input (this model of Hall probe is active low)
/*Assign interrupt variable to interrupt routine. Interrupt routine disables stepper motor when magnet reaches Hall Probe face and DigitalHallProbe1 switches from 3.3 V to 0V. Triggered on falling edge. */
attachInterrupt(digitalPinToInterrupt(DigitalHallProbe1), Hall_Switch_End_Limit1, FALLING);
}
void Hall_Switch_End_Limit1() { digitalWrite(Stage_Motor_Disable, HIGH); }
/* Stepper motor takes one step every 400 microseconds in the clockwise direction unless interrupt condition met*/
void loop() {
digitalWrite(Stage_MotorSTEP_CW, HIGH);
delayMicroseconds(400);
digitalWrite(Stage_MotorSTEP_CW, LOW);
delayMicroseconds(400);
}
This loop and interrupt code works absolutely fine when run on the M7 core. If I then switch this code to run on the M4 and then use the M7 to do something different, like blink an LED as shown in the code below, the loop part of the code on both cores works fine but the interrupt on M4 does not.
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LEDG, OUTPUT);
bootM4();
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LEDB, LOW); // turn the LED on (LOW is the voltage level)
delay(400); // wait for a second
digitalWrite(LEDB, HIGH); // turn the LED off by making the voltage HIGH
delay(400); // wait for a second
}
Is it because the M7 is the 'master core' that M4 cannot handle interrupts?
If this simply won't ever work, is it a reasonable alternative to use interrupts in the code that runs on M7 which stops M4 code? (an 'anti-bootM4() function if you will)?
All the best,
Ryan