use of timer and to check code please

Hi. ive just read about timers today and been reading as much as i can find, most of it is confusing at first but think i’am getting my head around it. i’ve writen some code with notes . would like to know if i am going in the right direction with it.

cheers

// Arduino timer CTC interrupt example
// www.engblaze.com
// www.engblaze.com/microcontroller-tutorial-avr-and-arduino-timer-interrupts/


// mega 2560 data sheet
// www.atmel.com/Images/doc2549.pdf
// intrupts on page 105

// mega is 16Mhz
// tmr1     = 16bit max count 65536 / 16,000,000 = each clock resets or overflow @ 0.0041 of a second
// tmr0,2   = 8bit  max count   256 / 16,000,000 = each clock resets or overflow  @ 0.000016 of a second
// tmr3,4,5 = 16bit max count 65536

// prescaling
// bitNames CS10,CS11,CS12 (0,0,0)no clock source (0,0,1)no prescaling , (0,1,0)=8 (0,1,1)64 , (1,0,0)256 , (1,0,1)1024 ,  (1,1,0)(1,1,1) external clocks rise or fall
// using scalar 1024
//
// 1024*65536 = 67,108,864 counts per cylce per second
//
// 16m / 67108864 = 4.194304 seconds per timer reset/overflow
//
// 65535/4.194304 = 15624 counts from tmr1 using scaler 1024
// 
//
//


// avr-libc library includes
#include <avr/io.h>
#include <avr/interrupt.h>
 
#define LEDPIN 13

// assign variable as volatile so ISR can change the variables value
volatile int seconds=0;
 
void setup()
{
    Serial.begin(9600);
    pinMode( LEDPIN ,OUTPUT );
    // initialize Timer1
    cli();          // disable global interrupts
    TCCR1A = 0;     // set entire TCCR1A register to 0  TCCR1* is a 16bit max nnumber 65535
    TCCR1B = 0;     // same for TCCR1B
 
    // set compare match register to desired timer count:
    OCR1A = 15624;
    // turn on CTC mode:
    TCCR1B |= (1 << WGM12);
    // Set CS10 and CS12 bits for 1024 prescaler:
    TCCR1B |= (1 << CS10);
    TCCR1B |= (1 << CS12); // sets CS10=1, CS12=1 dont have to do CS11 since its already 0 (CS10,CS11,CS12)=(101) = 1024
    // enable timer compare interrupt:
    TIMSK1 |= (1 << OCIE1A);// sets a value for whe clock resets back to zero i think
    // enable global interrupts:
    sei();
    Serial.println("Serial Connected");
}

void loop()
{
    
}

ISR(TIMER1_COMPA_vect)
{
    // +1 every second
    seconds++;
    
    if(seconds == 55){ //every 55 seconds
      one();
    }
    else if (seconds == 60){ // every minute
        seconds = 0;
        two();
    }else
     Serial.print(".");
    
    // blinks every second and flips its state by using this  ---> !
    digitalWrite(LEDPIN, !digitalRead(LEDPIN));
}

void one(){
  Serial.println();
  Serial.println("Send Data to sql server");
}

void two(){
  Serial.println();
  Serial.println("collect data from Digital Inputs");
}
// using scalar 1024
//
// 1024*65536 = 67,108,864 counts per cylce per second
no, thats clocks per oveflow
//
// 16m / 67108864 = 4.194304 seconds per timer reset/overflow
16,000,000 / 67,108,864 = 0.238418 (overflows /second) , so yes 4.19.. seconds between overflows
//
// 65535/4.194304 = 15624 counts from tmr1 using scaler 1024
per second you mean? not quite, its 15625 = 16,000,000 / 1,024
// 
//

You mustn't call Serial.print in an ISR, that will hang the system.

    if(seconds == 55){ //every 55 seconds

That won't be every 55 seconds. It will occur every 60 seconds. Every minute your code will call one() and then five seconds later it will call two(). But, as MarkT has pointed out, you must not use Serial in an interrupt routine.

Pete

i found out about the serial while adding other code, now using them functions to change boolean for if statments in the loop instead.
cheers :slight_smile: