i seem to be facing a weird issue here. First time working with AVR timers. Basically what I am trying to achieve is to set timer2 (with prescaler val @ 1024) and use CTC mode (with val 78) to get 5ms timer ticks.
Every 5ms i just display the current framebuffer on a row of LEDs and every 1sec (using a counter to keep track of 200 timer ticks) update the frame buffer.
my code is
void setup()
{
pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(latchPin, OUTPUT);
pinMode(row1, OUTPUT); pinMode(row2, OUTPUT); pinMode(row3, OUTPUT); pinMode(row4, OUTPUT); pinMode(row5, OUTPUT);
digitalWrite(row1,LOW); digitalWrite(row2,LOW); digitalWrite(row3,LOW); digitalWrite(row4,LOW); digitalWrite(row5,LOW);
digitalWrite(latchPin,HIGH);
digitalWrite(clockPin,LOW);
Serial.begin(9600);
Serial.println("Program initialized ...");
//create string map + display the initial frame buffer
//create_string_map("hello!");
//generate the first frame_buffer
Serial.println("1");
//create_frame_buffer(0);
Serial.println("2");
//update_frame_buffer();
Serial.println("3");
//disable global interrupts
cli();
//init timer2
TCCR2A = 0;
TCCR2B = 0;
//set ctc mode
TCCR2B |= (1 << WGM12);
//set CTC value
OCR2A = 78;
//set prescaler @ 1024
TCCR2B |= (1<<CS10);
TCCR2B |= (1<<CS12);
//enable timer
TIMSK2 |= (1<<TOIE2);
sei();
}
//install the ISR
ISR(TIMER2_OVF_vect)
{
timer_counter++;
//disable timer
TIMSK2 |= (0<<TOIE2);
if(timer_counter==200) //200 = 1 sec
{
//reset timer_counter
timer_counter=0;
//update frame
/*Serial.println("Frame update event ...");
string_map_col_counter++;
if(string_map_col_counter>=30){string_map_col_counter=0;}
create_frame_buffer(string_map_col_counter);
update_frame_buffer();
display_and_hold_frame();*/
Serial.println("1 second tick");
}
else
{
//display_and_hold_frame();
Serial.println("timer tick");
}
//enable timer
TIMSK2 |= (1<<TOIE2);
}
as you see i have commented most of the stuff out because i am trying to debug the issue. when i open the serial port the only output i get is "prog" and just stops there.
the only thing i can think of that might be going wrong is that the timer is cont configured with ticks too fast so the serial.println never gets the time to finish. but as you can see i start the timer AFTER all these serial print statements.
also when i press the reset button on the board does it clear all the timer configs on board or does it remember them b/w resets ? any ideas what might be causing this.
-
\$\begingroup\$ At 9600 bps, it takes over 1 ms to transmit one character, so "Prog" in 5 ms sounds about right. Try increasing the serial port speed and/or sending shorter messages (e.g., just one character per timer tick). \$\endgroup\$Dave Tweed– Dave Tweed2012年10月03日 13:22:00 +00:00Commented Oct 3, 2012 at 13:22
-
\$\begingroup\$ @DaveTweed wow ! i didnt think along those lines. makes sense however if you would notice in my ISR function i am printing another line "timer tick". so if this is the case shouldnt it also print atleast some characters from "timer tick" before the ISR gets called again ? \$\endgroup\$Ankit– Ankit2012年10月03日 13:37:49 +00:00Commented Oct 3, 2012 at 13:37
-
\$\begingroup\$ I don't know much about how the Arduino Serial module works internally, but my guess would be that you're simply overloading its transmit buffer with all the stuff you're printing, and it's just "giving up". \$\endgroup\$Dave Tweed– Dave Tweed2012年10月03日 13:40:28 +00:00Commented Oct 3, 2012 at 13:40
-
\$\begingroup\$ @DaveTweed Dave, found the problem. Nested deep within my code, I have a delay(2) call which would obviously mess this up. Removing that and the extra long Serial calls fixed the issue. If you would put down your comments as a answer, I would accept it as your suggested got me thinking along the right lines ! \$\endgroup\$Ankit– Ankit2012年10月03日 15:42:20 +00:00Commented Oct 3, 2012 at 15:42
2 Answers 2
At 9600 bps, it takes over 1 ms to transmit one character, so getting just "Prog" in 5 ms sounds about right. Try increasing the serial port speed and/or sending shorter messages (e.g., just one character per timer tick).
I don't know much about how the Arduino Serial module works internally, but my guess would be that you're simply overloading its transmit buffer with all the stuff you're printing, and it's just "giving up".
I suspect it may be because you don't (appear to) clear the interrupt in your ISR, so the main loop runs up to the first interrupt then stays forever interrupting so nothing else happens.
Also, it's not the best practice to use the Serial.println function in the ISR (in case it blocks), I would set a flag and use it the main code. Generally you want your interrupts to be as small/fast as possible.
Just noticed you set the timer running after the calls to Serial ouput, so unless it's a non-blocking function with a buffer the above shouldn't stop it at least outputting the first few lines.
Make sure your interrupt is cleared anyway (if it doesn't clear automatically)
I will try to find the code for the Serial library and see what's going on - is there anything else happening in your code elsewhere that may make a difference? If so add it to the question.
EDIT - according to this page, since v1.0 the serial write is non-blocking with (I think I saw somewhere else) a 64 byte buffer, so the above may be the issue after all.
EDIT 2 - I had a look at (what I think is) the source available here, and the hardware serial does have a 64 byte buffer (or 16 bytes for certain variants it seems), so filling with anything up to 64 bytes at a time will not block (see the HardwareSerial::write
function).
-
\$\begingroup\$ Double checked my code. the interrupt is being cleared just fine. But thank you for the information regarding the Serial buffer size and non-blocking nature. Im sure would come in handy for future projects ! \$\endgroup\$Ankit– Ankit2012年10月03日 15:40:38 +00:00Commented Oct 3, 2012 at 15:40
-
\$\begingroup\$ @Ankit - where is it being cleared in the code above? Also where is the delay(2) you mention in the latest comment? \$\endgroup\$Oli Glaser– Oli Glaser2012年10月03日 15:55:13 +00:00Commented Oct 3, 2012 at 15:55
-
\$\begingroup\$ Wouldn't the interrupt be cleared automatically when ISR execution is started ? \$\endgroup\$Ankit– Ankit2012年10月03日 15:58:09 +00:00Commented Oct 3, 2012 at 15:58
-
\$\begingroup\$ It depends on the peripheral - sometimes it is, sometimes not - you do need to know for sure which though (I don't use AVR/Arduino so I'm not sure) I would check the timer documentation (and for any other interrupts you use do the same). If the code in the main loop is running okay now it sounds like it is automatically cleared in this case. \$\endgroup\$Oli Glaser– Oli Glaser2012年10月03日 16:00:29 +00:00Commented Oct 3, 2012 at 16:00
-
\$\begingroup\$ good point. just checked .. it does clear it automatically but i guess it doesn't hurt to do it manually just to be absolutely sure. thanks! \$\endgroup\$Ankit– Ankit2012年10月03日 16:02:52 +00:00Commented Oct 3, 2012 at 16:02