1

(Arduino) Hello I don't know where I am going wrong here, please advise.

In the end I want to step a bipolar motor, HIGH/LOW, using Timer0 with OCR0A and OCR0B interrupts to adjust the motors step interval and duty cycle. Eventually I would like to do the same thing with a second motor and Timer2.

The idea is that the interrupt at OCR0A triggers step LOW and the interrupt at OCR0B triggers step HIGH. This breaks down into the TCNT count from 0 to OCR0B is the LOW phase and TCNT count from OCR0B to OCR0A is the HIGH phase. Both phases together make up the motor step interval which would be between TCNT0=0 and OCR0A ISR Clear. The duty cycle is determined by value between OCR0B and OCR0A, the duration of the HIGH phase.

My first test was to use Serial.println() to return "LOW" or "HIGH" from the corresponding ISRs to the computer to see if the step sequence is in the correct AB-AB pattern. It is not. The step sequence starts out correctly but after 7(seven) OCR0B ISR interrupts in sequence the OCR0B ISR ceases to repeat while the ISR for OCR0A prints repeatedly. The following is the code:

 ISR(TIMER0_COMPA_vect) { Serial.println("HIGH");} //end ISR COMPA//
 ISR(TIMER0_COMPB_vect) { Serial.println("LOW"); } //end ISR COMPB//
 
 int long SPEED_A = 200; // OCR0B->OCR0A is HIGH PHASE // trigger LOW // clear to 0 //
 int long SPEED_B = 150; // 0->OCR0B is LOW PHASE // trigger HIGH
 
 void setup()
 { 
 noInterrupts(); // disable interrupts
 
 OCR0A = SPEED_A; // interrupt A compare to TCNT0 value each tick // 0-255
 OCR0B = SPEED_B; // interrupt B compare to TCNT0 value each tick // 0-255
 TCCR0A |= ( 1 << COM0A1); // clear counter on match // OCR0A
 TIMSK0 |= ( 1 << OCIE0A); // enable timer compare interrupt A
 TIMSK0 |= ( 1 << OCIE0B); // enable timer compare interrupt B
 interrupts(); // enable interrupts
 Serial.begin(9600); // serial
 } //END setup///
 void loop() { } //END loop//

The Serial return is as follows:

LOW HIGH LOW HIGH LOW HIGH LOW HIGH LOW HIGH LOW HIGH LOW HIGH HIGH HIGH HIGH ...

Why does the ISR for OCR0B stop executing?

asked Feb 11, 2022 at 0:47
2
  • 1
    flash an LED instead of printing ... if you still want to print, do not do any printing inside an ISR function ... set a flag inside one ISR ... clear the flag inside the other ISR ... print the state of the flag inside the loop() function Commented Feb 11, 2022 at 2:33
  • Thank you for the comment, I noticed I was misunderstanding the math of what 1 period equated to microsecond wise and the LED 100% helped me see the issue. I need to include global variable to count the ticks or 'OCR0A revolutions' to time the intervals correctly. Commented Feb 11, 2022 at 8:02

1 Answer 1

5

Don't do serial prints inside an ISR. Ever. They require interrupts to work, and inside the ISR interrupts are off. For a while the attempts to print will fill up a buffer which is emptied by another ISR, however when that buffer fills the Serial.print will block. And if it blocks inside an ISR waiting for an interrupt it will block forever. Thus it stops printing.

As Jstola suggested in a comment under the question, turn an LED on and off, or something like that.

I can't explain your 7 prints perfectly, but printing HIGH and LOW repeatedly, with their corresponding carriage-return/linefeeds, would, after 7 turns (7 x 11 = 77), pretty-much fill up the serial buffer which is 64 bytes.

So, you are sending around 77 bytes, some would have "escaped" before the buffer filled up, and when you filled it with 64 bytes, it stops.

Your results would change slightly if you made the baud rate higher, say 115200 baud, which I always use, but still, you should not print inside an ISR.

answered Feb 11, 2022 at 6:43

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.