Help with using a counter with a Timer Interrupt ISR

Hello, I am new to this! I am trying to make a temperature sensor read the temperature every 15 minutes for a 24 hour period. As for the 24 hours, I am using an array so that is ok. However, I am required to use a timer interrupt for measuring every 15 minutes. I have set up the interrupt to fire every 1 second and I am trying to use a counter within the ISR to count to 900 (15x60). (Note: I am using the value of 10 to test instead of 900).

However, if I include:

if (counter = 10){
arr[i] = Wire.read();
}

after counter++ in the ISR, the counter goes straight to the value 10 and stays at that.

The counter does work by itself but seems to fail whenever anything is put after it. I tried to call the counter in a different function and it would not print. Also, I tried to call it in the loop but it obviosuly just runs constantly, not just printing every 10 seconds.

I will need to reset the counter after 900 seconds (10 in this test case) and I am unsure how to do so with these issues.

I have included the code below but note as I can't get past this issue, it obviously does not run smoothly. If anybody has any comments or help, please let me know!

#include <Wire.h>
int addr=0x4d;
bool sensorOK = false;
int arr[96];
int counter = 0;
int i =0;

void setup() {
  // initialize Timer1
noInterrupts(); // disable all interrupts
//set timer1 interrupt at 1Hz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);  
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);

  Serial.begin(9600);
  interrupts(); // enable all interrupts
  
  Wire.begin();

  Wire.beginTransmission(addr);
  int err= Wire.endTransmission();
    if (err == 0)
    {
      Serial.println("Found Sensor at address");
      sensorOK = true;
    }
    else{
      Serial.println("Sensor not found");
    }
}

ISR(TIMER1_COMPA_vect){
  counter++; //Counter increases by 1 every second   

  if (counter = 10){
    Serial.print(counter)
  }
}


void loop() 
{
  if (sensorOK){
    for (i = 0; i < 95; i++){
      if (counter = 10){
        Wire.requestFrom(addr, 1);
        if (Wire.available())
        arr[i] = Wire.read();
        
        Serial.print("Reading ");
        Serial.print(i);
        Serial.print(" out of 96: ");
        Serial.print("Temperature is ");
        Serial.print(arr[i]);
        Serial.print("°C");
      
        int f= (arr[i]*1.8)+32;
        Serial.print(" and ");
        Serial.print(f);
        Serial.println("°F");
      }
    }
  }
}

Hi,
Please use code tags when posting code (the "</>" icon).

Please use code tags when posting code, like this:

counter++; //Counter increases by 1 every second

if (counter = 10){
Serial.print(counter)
  1. variables shared between interrupt routines and the main code must be declared volatile
  2. Never attempt to perform serial I/O in an interrupt routine.
  3. "=" is used to assign values. Use "==" for comparisons.
  4. Statements end in ";"

Thank you, just fixed it!

Ah such simple mistakes I didn't pick up on! Thank you so much! Just a question - if you cant perform Serial I/O in an interrupt service routine, how can you complete this? I would assume putting this in another function and then calling that function within the ISR but that does not work. Any ideas?

Set a flag in the ISR (remember it must be volatile).

Check for the flag in the loop and do the print and clear the flag.

Willem.

The problem with serial I/O inside an interrupt function is that serial I/O (usually) depends on interrupts, and interrupts are turned off while executing code in an interrupt function.

Here is an example illustrating the suggestion by Willem43:

volatile char reset_flag = 0; //global variables declared outside of any function
volatile unsigned int count = 0;
...
//within ISR
count++;
if (count > 1000) {
   reset_flag = 1;
  count = 0;
}
...
// within loop()
if (reset_flag) {
Serial.println("Count reset in ISR");
reset_flag = 0;
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.