Interrupt Service Routine (ISR) crashing

Hi,

I’m relatively new to Arduino and I am working on a project. I want to make a wakeup light.
Therefore, I built an arduino controlled light dimmer (see http://www.instructables.com/id/Arduino-controlled-light-dimmer-The-circuit/ and Arduino Real Time Clock (RTC) Tutorial using DS1307)

I’ve also tried different RTC libraries. But the thing is my ISR crashes and nothing happens anymore.

I’m using the uno and nano. Both crash.

Can you please help me?

#include <RTClib.h>
#include <Time.h>
#include <Wire.h>


const uint8_t AC_LOAD = PD3;    // Output to Opto Triac pin
uint8_t dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF

const char *monthName[12] = {
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
const uint8_t tl_load = 0;
const uint16_t tl_comp = 31250;


  RTC_DS1307 rtc;
  char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};


void setup()
{
  Serial.begin(9600);
  Serial.println("setup");


  
  
    // initialize timer1 
//  Serial.println("Disable timer interrupts.");
//  noInterrupts();           // disable all interrupts
//  Serial.println("Timer interrupts disabled.");

  // reset Timer1 control Reg A
  TCCR1A = 0;

  // set to prescaler of 256
  TCCR1B |= (1 << CS12);
  TCCR1B &= ~(1 << CS11);
  TCCR1C &= ~(1 << CS10);

  // reset Timer1 and set compare value
  TCNT1 = tl_load;
  OCR1A = tl_comp;

  //enable timer1 compare interrupt
  TIMSK1 = (1 << OCIE1A);

  //enable global interrups
  sei();

   
  if (! rtc.begin()) 
  {
    Serial.println("Couldn't find RTC");

    while (1);
  }
  if (! rtc.isrunning()) 
  {
    Serial.println("RTC is NOT running!");

  }
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));//auto update from computer time
    //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));// to set the time manualy 

  
  while (!Serial) ; // wait for serial
  delay(200);
  
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  attachInterrupt(digitalPinToInterrupt(PD2), zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
  
}

ISR(TIMER1_COMPA_vect)        // interrupt service routine 
{
  
  Serial.println("ISR start");
  TCNT1 = tl_load;
 
  printTime();
  Serial.println("ISR done");
  
}


void zero_crosss_int()  
{
  //function to be fired at the zero crossing to dim the light
  //the interrupt function must take no parameters and return nothing
  // Firing angle calculation : 1 full 50Hz wave =1/50=20ms 
  // Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle) 
  // For 60Hz => 8.33ms (10.000/120)
  // 10ms=10000us
  // (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65

  int dimtime = (75*dimming);    // For 60Hz =>65    
  delayMicroseconds(dimtime);    // Wait till firing the TRIAC    
  digitalWrite(AC_LOAD, HIGH);   // Fire the TRIAC
  delayMicroseconds(10);         // triac On propogation delay 
         // (for 60Hz use 8.33) Some Triacs need a longer period       
  digitalWrite(AC_LOAD, LOW);    // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
}


void loop()  {
  for (int i=128; i >= 15; i--){
    dimming= i;
    delay(70);
  }

}

void printTime(){
  DateTime now = rtc.now();

  Serial.print(now.hour());
  Serial.print(':');
  Serial.print(now.minute());
  Serial.print(':');
  Serial.println(now.second());
}

It is not a good idea to print anything from within an ISR.

Any variable that is accessed from within an ISR, e.g. dimming, should be declared volatile.

Pete

Thanks, good input!

How can I achieve to update a display by timer interrupt if printing in ISR is not a good idea?

why is it not a good idea?

Even declaring

volatile DateTime now;

doesn't work.

why is it not a good idea?

It causes your ISR to hang. Printing depends on interrupts, which are turned off in an ISR.

Set a global flag in the ISR telling the main program that it is time to print, then print from within the main program.

Avoid Instructables like a disease. Most of them are crap, and some can actually lead you to damage your equipment.

adrianka:
Thanks, good input!

How can I achieve to update a display by timer interrupt if printing in ISR is not a good idea?

why is it not a good idea?

Even declaring

volatile DateTime now;

doesn't work.

Read Nick Gammon's excellent tips on using interrupts before going any further.
If rtc.now() uses I2C, then using it in an interrupt handler will also likely cause a hang.

el_supremo:
Any variable that is accessed from within an ISR, e.g. dimming, should be declared volatile.

volatile uint8_t dimming = 128;

Pete

Thank you!

the reply with the global flags really helped. Issue solved!