1

I built a sketch using some timer ISR code to get a trigger every second. (for the Atmega328 chip I use the following code I got form the internets. It works)

It runs fine and I get a trigger/callback every second.

void setupAtmega328()
{
#ifdef __AVR_ATmega328P__

// traceDebug("setupAtmega328() entry");

    cli();  // stop interrupts

// traceDebug("setupAtmega328() 1");

            //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 CS12 and CS10 bits for 1024 prescaler
    TCCR1B |= (1 << CS12) | (1 << CS10);
    // enable timer compare interrupt
    TIMSK1 |= (1 << OCIE1A);
//  traceDebug("setupAtmega328() 2");
    sei();//allow interrupts    
//  traceDebug("setupAtmega328() 3");

#endif
}

I also wanted to add the capability of a real time clock (RTC) so I got a DS3231.

I downloaded and ran the sample app from this RTCLib on github

The sample code works fine when running under the Arduino IDE

However, when I add the RTC code to my sketch I don't get the results I want/expect.

Specifically, the program seems to hang/halt at the call to:

cli(); 

I am new to the Arduino platform and not sure what I am missing.
What do I need to do to get the RTC to work in conjunction with an ISR?

I wired the RTC according to the directions from Adafruit's site

I have other arduino boards that use different ISRs, but I have not tried them yet with the rtc since the 328 seems to be the standard arduino boars that is used to do initial work/testing.

How can I use the 3231 RTC AND a 1 second ISR/callback?

EDIT: I removed the trace/serial output - I had originally added those to track the code to see where I got but i think I exacerbated or added problems in doing that.

for those interested the code is at https://github.com/tjurik/Intervalometer

  • Provide your whole sketch. – TisteAndii Oct 5 '16 at 2:50
  • 2
    Calling Serial.print after you call cli is ill advised. Serial requires interrupt to send the data (if I remember correctly). Try removing the serial.prints between cli and sei, or at least make the text shorter so the buffer doesn't fill up. PS you can setup the DS3231 to send a pulse every second to the SQW pin. You can connect this pin to one of the Arduino interrupt pins. That way you get a very accurate 1Hz interrupt call. – Gerben Oct 5 '16 at 8:43
  • @gerben - using the rtc to send the 1hz interrupts would be far more desirable! thanks. i will try that. – Tim Oct 5 '16 at 15:56
1

In the Arduino you don't have control how are some essential parts implemented.

For example delay function requires interrupts to be enabled or it'll be deadlocked (for sure).

Serials are little bit better, it'll be working until send buffer gets full. For devices with small RAM it's 16B only! And your traceDebug is little bit longer.

In general ISR should be as short as possible and it's mainly used for setting some flag to be handled in main loop later.

volatile bool flag = false;

ISR(...) {
  flag = true;
}

int main() {
  init();

  while (1) {
    if (flag) {
      do_something();
      flag = false;
    }
  }
}
  • Yeah, that is how i wrote the code - and then when trying to debug the problem I added serial output which I think made more problems! – Tim Oct 5 '16 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.