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.

\$\endgroup\$
  • \$\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 Oct 3 '12 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 Oct 3 '12 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 Oct 3 '12 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 Oct 3 '12 at 15:42
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".

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

\$\endgroup\$
  • \$\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 Oct 3 '12 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 Oct 3 '12 at 15:55
  • \$\begingroup\$ Wouldn't the interrupt be cleared automatically when ISR execution is started ? \$\endgroup\$ – Ankit Oct 3 '12 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 Oct 3 '12 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 Oct 3 '12 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.