Go Down

Topic: How to use timer interrupts. (Read 1 time) previous topic - next topic

NeXT-Generation

Hey, all.

I'm new to Arduino, and electronics in general (Though I've been avidly using LEGO MindStorms for 7-years), so I'm sorry if these are very n00b questions.

Anyway, I want to drive a common-cathode 2-digit 7-segment LED display.  I think it would be easiest to use interrupts to trigger the changing of the digit.  i.e. do stuff for 5-milliseconds, and then turn off one digit, turn on the next, wait another five ms, turn off the second, turn the first back on, etc.

So, basically what I want to do is change the digit that is lit every 5-milliseconds, while doing other stuff in the backround.  I just need to know the code that sets up the interrupt, and shows how it's used.

Thank you.

NeXT-Generation.

Also known as on teh internetz:  inxt-generation, LEGONextGeneration, and NeXT-Generation.


NeXT-Generation

Thanks, but that doesn't completely answer my question.  As far as I can tell, the only timer example waits for the timer to overflow, not for a user-defined period.  Also, the ISR would need to have access to a variable that tells it what numbers to display.  Does it just need to be  a global variable?  Or does it need to have something special done to it?
Also known as on teh internetz:  inxt-generation, LEGONextGeneration, and NeXT-Generation.

pYro_65

Any variables the ISR changes ( and are used elsewhere ) should have the volatile modifier added.

NeXT-Generation


Any variables the ISR changes ( and are used elsewhere ) should have the volatile modifier added.


Like this?
Code: [Select]
volatile int NumToDisplay[2];
The value is accessed and modified normally, though, right?  It just needs to be declared this way?
Also known as on teh internetz:  inxt-generation, LEGONextGeneration, and NeXT-Generation.

pYro_65

yes, once declared volatile you can use it normally.

Jack Christensen


Thanks, but that doesn't completely answer my question.  As far as I can tell, the only timer example waits for the timer to overflow, not for a user-defined period.  Also, the ISR would need to have access to a variable that tells it what numbers to display.  Does it just need to be  a global variable?  Or does it need to have something special done to it?


Timers count at a specific frequency, which is user-selectable. Interrupts can occur either on overflow or when a specific value is reached, also user-selectable. Do the math on that and a pretty wide range of user-defined periods is possible.

Dean Camera and Nick Gammon both have good write-ups on timers and interrupts, and there is always the ultimate reference, i.e. the datasheet.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

NeXT-Generation



Thanks, but that doesn't completely answer my question.  As far as I can tell, the only timer example waits for the timer to overflow, not for a user-defined period.  Also, the ISR would need to have access to a variable that tells it what numbers to display.  Does it just need to be  a global variable?  Or does it need to have something special done to it?


Timers count at a specific frequency, which is user-selectable. Interrupts can occur either on overflow or when a specific value is reached, also user-selectable. Do the math on that and a pretty wide range of user-defined periods is possible.

Dean Camera and Nick Gammon both have good write-ups on timers and interrupts, and there is always the ultimate reference, i.e. the datasheet.


Thanks for the links.  They look like they'll be very helpful.  I'll report on whether I get it to work, or if I need more help.

Thanks everyone! :smiley-mr-green:
Also known as on teh internetz:  inxt-generation, LEGONextGeneration, and NeXT-Generation.

NeXT-Generation

I was able to jigger out some meaning from the texts, and came up with this:

Quote

volatile bool FirstDigitLastDisplayed;

void setup()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  
  // initialize timer1
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;

  OCR1A = 400;            // compare match register 16MHz/256/2Hz
  TCCR1B |= (1 << WGM12);   // CTC mode
  TCCR1B |= (1 << CS12);    // 256 prescaler
  TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
  interrupts();             // enable all interrupts
}

ISR(TIMER1_COMPA_vect)          // timer compare interrupt service routine
{
  if(FirstDigitLastDisplayed == false)
  {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(8, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(10, LOW);
  }
  else
  {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(8, HIGH);
    digitalWrite(9, LOW);
    digitalWrite(10, HIGH);
  }
  FirstDigitLastDisplayed = !FirstDigitLastDisplayed;
}

void loop()
{
  // The rest of my program here...
}



Each digit is completely lit, with no discernable flashing, at least to the human eye.  I don't completely understand how and why it works, but I've figured enough to be able to change the trigger time interval.  Thanks everyone for all the help!
Also known as on teh internetz:  inxt-generation, LEGONextGeneration, and NeXT-Generation.

PaulS

Quote
but I've figured enough to be able to change the trigger time interval.

The next step, then, is to learn about arrays and for loops. Much of what you are doing is repetitive. Your code is approximately 10 times as long as it needs to be.

NeXT-Generation


Quote
but I've figured enough to be able to change the trigger time interval.

The next step, then, is to learn about arrays and for loops. Much of what you are doing is repetitive. Your code is approximately 10 times as long as it needs to be.


You mean for setting the pins?  I know about arrays and for loops, but didn't think to apply them to that.  Thanks for the idea.
Also known as on teh internetz:  inxt-generation, LEGONextGeneration, and NeXT-Generation.

Go Up