(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?
1 Answer 1
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.
Explore related questions
See similar questions with these tags.
loop()
function