I can't point to a link but, it's been mentioned many times that you shouldn't print inside an ISR because the print function depends itself on interrupts - which are disabled in an ISR.
The screenshot is using baud 115200
Apparently printing inside an ISR is possible. I am surprised, but it doesn’t brick the processor. I’d need to dive deep into the behaviour of Serial to find out why it doesn’t.
In my experience, it prints a lot. Problem is I do not comprehend why/how...
I suggested to go back to the sketch from post #1 with higher speed to confirm that that was the real fault in that sketch.
But not all you meant/wanted to print.
True
There was some accommodation made, I think, at some point to allow it.
But it remains a Bad Idea in my opinion.
I wonder if the 600 was at one time 9600, still quite low for this purpose.
a7
For learning and amusement, take a look at this one.
/* To read signals from RC receiver with Arduino UNO R3
with 1 microsecond accuracy
knowing all pulses go high at the same time
not using ISR
CH1 is connected to Arduino pin 8 (PB0)
CH2 is connected to Arduino pin 9 (PB1)
CH3 is connected to Arduino pin 10 (PB2)
CH4 is connected to Arduino pin 11 (PB3)
*/
void setup() {
Serial.begin(115200);
TCCR1A = 0; // TIMER1 in normal mode, no more PWM available at pins 9 and 10
TCCR1B = 1; // prescaler 1, running at 16MHz, max = 4 ms
}
void loop() {
static unsigned long startInterval;
unsigned int allStart;
unsigned int ch1end;
unsigned int ch2end;
unsigned int ch3end;
unsigned int ch4end;
if ((millis() - startInterval) > 250) { // perform one measuring cycle each 250 milliseconds
startInterval += 250; // for next interval
while (PINB & 0x0F) {} // wait if there are ongoing pulses present
while (!(PINB & 0x0F)) {} // wait until the pulses start
allStart = TCNT1; // read TIMER1 for start time
while (PINB & 0x0F) { // do wile there are still pulses present
unsigned int presentTime = TCNT1; // read TIMER1 again
if (bitRead(PINB, 0)) ch1end = presentTime; // update end time for this channel
if (bitRead(PINB, 1)) ch2end = presentTime; // updating will go on as long as the pulse is up
if (bitRead(PINB, 2)) ch3end = presentTime; // but will take less time than a bunch of ifs
if (bitRead(PINB, 3)) ch4end = presentTime; // this updating cycle may take about 1 microsecond, which limits the accuracy
}
unsigned int ch1duration = (ch1end - allStart) / 16; // calculate duration in microseconds
unsigned int ch2duration = (ch2end - allStart) / 16;
unsigned int ch3duration = (ch3end - allStart) / 16;
unsigned int ch4duration = (ch4end - allStart) / 16;
// This measuring cycle may take as long as the repeat time of the pulses plus the longest pulse
// or as short as the longest pulse
showFlyskyPwmLength(ch1duration, ch2duration, ch3duration, ch4duration);
}
}
void showFlyskyPwmLength(unsigned int t1, unsigned int t2, unsigned int t3, unsigned int t4) {
Serial.print("Roll PWM Length: ");
Serial.print(t1);
Serial.print("\u00B5s"); // Unicode code point \u00B5 for micro plus letter "s"
Serial.print(" -> Pitch PWM Length: ");
Serial.print(t2);
Serial.print("\u00B5s"); // Unicode code point \u00B5 for micro plus letter "s"
Serial.print(" -> Gas PWM Length: ");
Serial.print(t3);
Serial.print("\u00B5s"); // Unicode code point \u00B5 for micro plus letter "s"
Serial.print(" -> Yaw PWM Length: ");
Serial.print(t4);
Serial.print("\u00B5s"); // Unicode code point \u00B5 for micro plus letter "s"
Serial.println("");
}
EDIT: added static to a variable
When you tested using buttons, did you use hardware interrupts or pin change interrupts??
Interrupt Service Routine (ISR) calls are used in embedded systems to handle hardware interrupts. When an interrupt occurs, the ISR is called to temporarily halt the main program and address the event, ensuring quick and efficient response to critical tasks like input from peripherals or time-sensitive operations.
The testing I referred to was using interrupts.
Post #96 is to show that there are more ways that lead to Rome.
My specific question was due to the fact that hardware interrupts are more versatile (FALLING, RISING, CHANGE, LOW) than pin change interrupts (PCIs) that are only CHANGE. So, on a button using PCIs there are 2 interrupts being triggered: one when the button is pressed and one when it's released. Hence, my last question.
The ISRs in post #18 (yours) and post #38 (mine) both test the states of each channel every time they are called.
Indeed, INT0 and INT1 are more versatile, but you need 4 inputs.
PinChange is perfectly fine to do the job.
I'm just wondering if hardware interrupts like INT0/INT1 are not only more versatile but also a more efficient/faster option. I know you need 4 inputs, but I believe some boards do have more than 4 hardware interrupts.
The reaction time, from occurrence of trigger condition to executing first operation of the ISR, is independent of the triggering method.
Another board I'm familiar with, Nano Every, can have each input set to trigger an interrupt under the same conditions as INT0 and INT1 of the UNO R3, but these are gathered per port just like the PinChanges in the UNO R3.
In your case it is likely that there are multiple inputs that change at the same time, thus processing them within the same interrupt call is advantageous. If they were to be processed in different interrupt calls, the processing of a subsequent interrupt would be delayed by the previous.
Thanks!, great remark
Could you elaborate on your suggestion please??
Looks like borjanboonoo1 has removed the post. Probably it was post #106.
You are right, it's gone. Too bad, I managed to read it and it seemed like a reasonable suggestion.