0
\$\begingroup\$

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.

asked Oct 3, 2012 at 13:08
\$\endgroup\$
4
  • \$\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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Oct 3, 2012 at 15:42

2 Answers 2

1
\$\begingroup\$

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".

answered Oct 3, 2012 at 15:46
\$\endgroup\$
0
\$\begingroup\$

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).

answered Oct 3, 2012 at 14:26
\$\endgroup\$
6
  • \$\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\$ Commented 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\$ Commented Oct 3, 2012 at 15:55
  • \$\begingroup\$ Wouldn't the interrupt be cleared automatically when ISR execution is started ? \$\endgroup\$ Commented 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\$ Commented 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\$ Commented Oct 3, 2012 at 16:02

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.