# How to divide clock interrupt down?

Need to divide clock interrupt down, as the original code was for a 32kHz watch crystal instead of a normal 16Mhz crystal.

Can someone talk me though it?

``````#include "LedControl.h"        // Include the LedControl library
LedControl lc=LedControl(12,11,10,1); // Set up an LED object on pins 12,11,10

int seconds_ones;
int minutes_ones;

int seconds_tens;              // Initialise values for tens and ones units of h,m,s
int minutes_tens;              // these are the values actually sent to the LEDs

volatile unsigned char tick;
unsigned char seconds = 0;
unsigned char minutes = 0;     // Inititialise actual values for h,m,s
unsigned char hours = 0;
int hours_increase = 0;
int mins_increase = 0;

ISR (TIMER2_OVF_vect) {        // When timer2 overflows...
tick++;                      // increment tick
display_time ();             // send the time to the LEDs to be displayed

}

void set_time() {              // Function for setting the time

while(hours_increase==HIGH || mins_increase==HIGH){  // If either of the adjust buttons are high

if (hours_increase==HIGH){            // Increase hours if hours button pressed
hours = hours + 1;
}
if (mins_increase==HIGH){            // Increase minutes if minutes button pressed
minutes = minutes + 1;
}

display_time();                      // Send the time to the LEDs

delay(750);

}
}

void display_time () {                     // Function to display the time

seconds_ones = seconds % 10;           // Get the 1's digit of seconds
if (seconds>=10){                      // If seconds greater than 10
seconds_tens = seconds / 10;}         // Get 10's digit of seconds
else {
seconds_tens = 0;}                   // Otherwise 10s is 0

minutes_ones = minutes % 10;           // Repeat for minutes
if (minutes>=10){
minutes_tens = minutes / 10 ;}
else {
minutes_tens = 0;}

lc.setDigit(0,0,(byte)seconds_ones,false);  // Send digits to LEDs
lc.setDigit(0,1,(byte)seconds_tens,false);
lc.setDigit(0,2,(byte)minutes_ones,false);
lc.setDigit(0,3,(byte)minutes_tens,false);

}

void setup_timer2 () {                  // Set up function
TCCR2A = 0;
TCCR2B = 0;                           // stop timer
TCNT2 = 0;                            // reset timer2 counter
ASSR = (1 << AS2);                    // select external clock source
TIMSK2 = (1 << TOIE2);                // enable timer2 overflow interrupt
TCCR2B = (1 << CS22) | (1 << CS20);   // prescaler = 128, restarts timer
}

void setup () {

setup_timer2 ();                     // Set up the timer options
lc.shutdown(0,false);                // Turn on the LEDs
lc.setIntensity(0,15);               // Set intensity to full
set_time();                          // Run the time set function
}

void loop () {

if (tick) {                             // If a tick has occured
seconds = seconds + 1;                // Increment the seconds
tick = 0;                             // reset the tick flag
if (seconds>59){                      // If a minute has passed
seconds = 0;                          // Send seconds back to 0
minutes = minutes + 1;                // Increment the minutes
if (minutes >59){                     // If an hour has passed
hours = hours + 1;                  // Increment the hours
minutes = 0;                        // Send the minutes back to 0
if (hours > 23){;                   // If a day has passed
hours = 0;                          // Set hours back to 0
}
}
}
}
}
``````

Work out how much you need to divide by, and if you can’t do it with the pre-scaler, simply count that many interrupts before doing anything.
Don’t forget to reset the counter.

Thank you AWOL, But how would you explain that to someone who is a little slow?

Say you want a 1Hz “tick”, but the closest you can get with the timer and pre-scaler is 48Hz.

In “setup ()” reset a count “tickCount”.
Each time your interrupt service routine executes, increment “tickCount”.
If “tickCount” is 48, reset it to zero, and do whatever it was you wanted to do every second.

Im still lost :’(

The 16MHz clock does not divide evenly to a multiple of a second and the frequency is much too high for the arduino timers to produce a pulse per second. That’s the bad news, the good news is that you don’t need a timer to do what you want.
Here is a version of loop that uses the Arduino millis function to increment your variables.

``````void loop () {
if( millis() - prevMillis >= 1000)
{
seconds = seconds + 1;                // Increment the seconds
prevMillis += 1000;

if (seconds>59)                      // If a minute has passed
{
seconds = 0;                          // Send seconds back to 0
minutes = minutes + 1;                // Increment the minutes
if (minutes > 59)                     // If an hour has passed
{
hours = hours + 1;                  // Increment the hours
minutes = 0;                        // Send the minutes back to 0
if (hours > 23)
{
hours = 0;                          //  // If a day has passed Set hours back to 0
}
}
}
}
display_time ();
delay(1000);
}
``````

Thank you mem, that code make lots more seance to me!

Do I just replace my existing ‘void loop()’ or do i need to remove void setup_timer2 too and add something to setup?

…as I get the error

`````` In function 'void loop()':
error: 'prevMillis' was not declared in this scop
``````

when i just replace my existing ‘void loop()’

THANK YOU ALL FOR YOUR HELP AND TIME! :-*

remove : volatile unsigned char tick;
and replace it with:
unsigned long prevMillis = 0;

You can remove the functions that related to timer2. There is nothing needed in setup other than that required for your led display.

have fun!

YOU STARS!

Thank you for fixing my poor excuse for code,it is now counting up and displaying perfectly with this code

`````` #include "LedControl.h"        // Include the LedControl library
LedControl lc=LedControl(12,11,10,1); // Set up an LED object on pins 12,11,10

int seconds_ones;
int minutes_ones;

int seconds_tens;              // Initialise values for tens and ones units of h,m,s
int minutes_tens;              // these are the values actually sent to the LEDs

unsigned long prevMillis = 0;
unsigned char seconds = 0;
unsigned char minutes = 0;     // Inititialise actual values for m,s
int mins_increase = 0;

void set_time() {}

void display_time () {                     // Function to display the time

seconds_ones = seconds % 10;           // Get the 1's digit of seconds
if (seconds>=10){                      // If seconds greater than 10
seconds_tens = seconds / 10;}         // Get 10's digit of seconds
else {
seconds_tens = 0;}                   // Otherwise 10s is 0

minutes_ones = minutes % 10;           // Repeat for minutes
if (minutes>=10){
minutes_tens = minutes / 10 ;}
else {
minutes_tens = 0;}

lc.setDigit(0,0,(byte)seconds_ones,false);  // Send digits to LEDs
lc.setDigit(0,1,(byte)seconds_tens,false);
lc.setDigit(0,2,(byte)minutes_ones,false);
lc.setDigit(0,3,(byte)minutes_tens,false);

}

void setup () {
lc.shutdown(0,false);                // Turn on the LEDs
lc.setIntensity(0,15);               // Set intensity to full
set_time();                          // Run the time set function
}

void loop () {
if( millis() - prevMillis >= 1000)
{
seconds = seconds + 1;                // Increment the seconds
prevMillis += 1000;

if (seconds>59)                      // If a minute has passed
{
seconds = 0;                          // Send seconds back to 0
minutes = minutes + 1;                // Increment the minutes
if (minutes > 59)                     // If an hour has passed
{
minutes = 0;                        // Send the minutes back to 0

{

}
}
}
}
display_time ();
delay(1000);
}
``````

going to try and get it to count down now…so that should be fun, but think i can do it thanks to some tips from Rusty in Texas, but sure i will harass you guys if i get suck!