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

#define mins_adjust 15         // Input pin for minutes adjust button

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
  
 
  pinMode(mins_adjust,INPUT);   // Set the adjust buttons as inputs
  

  mins_increase = digitalRead(mins_adjust);   // Read the adjust buttons
  
  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);
    mins_increase = digitalRead(mins_adjust);   // Increase the values of mins as necessary
    
  }
}

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! :wink: