Arduino microcontroller with DS1337 RTC for LED Dimming

Thread Starter

stage3-s4

Joined Oct 1, 2009
10
Hello, I'm currently working with an ardunio microcontroller with a DS1377 RTC. The board I'm using is here: http://wiblocks.luciani.org/NB1/NB1A-index.html. I'm able to write a program that will dim the LEDs using the analogwrite function. I'm trying to accomplish a way that I can have the LEDs come on at a set time of the day gradually, and stay on for a set period of time and then turn off gradually. This is to basically simulate sun rise and sun set.

Just to give an example:

8am- leds turn on gradually reaching full intenstiy by 9am.

8pm- leds turn off gradually reaching completely off by 9pm.

It seems a bit involved when I try to read how to use the interrupt function and I really have a poor programming background. Any help would be greatly appreciated.
 

hgmjr

Joined Jan 28, 2005
9,027
Oops! I just took a closer look at the board you are using and see that the RTC is already included on the controller board. By the way, there is a typo in the manual for the board. The RTC part number is DS-1337 not RTC-1377.

hgmjr
 

John Luciani

Joined Apr 3, 2007
475
In your example you have two modes -- sunrise (8AM-9AM) and sunset (8PM-9PM).
Tracking the mode can be done using the RTC alarm mode 4.

When you are in sunrise or sunset mode you could change the LED intensity once per
minute using RTC alarm mode 2.

The code below is a modification of the example at
http://wiblocks.luciani.org/docs/app-notes/nb1a-rtc-alarms.html
It should print out the mode when the alarm goes off. It does not implement
the intensity changing.

NB: This code is BC -- Before Cappuccino.


Rich (BB code):
#include <avr/interrupt.h>    
#include <avr/io.h>  

#include <LED_debug.h>
#include <TWI.h>
#include <RTC.h>

#define ON  HIGH
#define OFF LOW

#define int_enable   PCICR  |=  (1 << PCIE2)
#define int_disable  PCICR  &= ~(1 << PCIE2)

#define RTC_ALARM1_OUTPUT 6 // PD6
#define RTC_ALARM1_INT    PCINT22

#define RTC_ALARM2_OUTPUT 5 // PD5
#define RTC_ALARM2_INT    PCINT21

// PCI2 triggers for PCINT23..16
// PCI1 triggers for PCINT14..8
// PCI0 triggers for PCINT7..0 

LED_debug led;
RTC       rtc;

unsigned char alarm_hour = 8;
unsigned char alarm_flag = 0;
unsigned char intdata = 0;

void setup() {

  // Compensating for the 12MHz XTAL
  // 12800 = (16/12) * 9600
  // 25600 = (16/12) * 19200

  Serial.begin(9600);

  // setup the TWI 

  TWBR = TWI_TWBR;             // Set bit rate register (Baudrate). Defined in TWI.h  
  TWDR = 0xFF;                 // Default content = SDA released.
  TWCR = (1<<TWEN)|            // Enable TWI-interface and release TWI pins.
         (0<<TWIE)|(0<<TWINT)| // Disable Interupt.
         (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|  // No Signal requests.
         (0<<TWWC);


  // enable pullup on alarm1 output

  pinMode(RTC_ALARM1_OUTPUT, INPUT);
  digitalWrite(RTC_ALARM1_OUTPUT, HIGH);

  // initialize the date
   rtc.set_date(2010, 2, 24);

  // intialize the clock
   rtc.set_time(16, 26, 20);


  // Initialize the control register for a 32768Hz square wave
  // and disable the square wave output

  // RTC_RS2 | RTC_RS1 ..... Rate Select, square wave output = 32768Hz
  // RTC_INTCN ............. Interrupt Control (=1 interrupts activated,
  //                         no square wave on INTB

  rtc.write_reg(RTC_REG_CONTROL, RTC_RS2 | RTC_RS1 | RTC_INTCN);

  // Setup ALARM1 to alarm when the seconds count equals 20
  // and then enable the ALARM1

  // RTC_ALARM1_MODE4 ..... Alarm when hours, minutes, seconds match
  // dow .................. 0
  // hours ................ 0
  // minutes .............. 0
  // seconds .............. 20
  
  rtc.set_alarm1(RTC_ALARM1_MODE4, 0, alarm_hour, 0, 0); // alarm at 8AM
  rtc.enable_alarm1();

  // Initialize the pin change interrupt mask for the
  //  pin that is connected to the RTC /INTA output. 

  PCMSK2 |= (1 << RTC_ALARM1_INT);

  // Enable the pin change interrupts

  int_enable;

}


void loop() {
  char timestr[22];
  while(1) {
    rtc.read_regs();
    rtc.localtime(timestr);
    Serial.print(timestr);
    Serial.print("\n");
    led.blink(1); 
    delay(1000);

    // If there was an alarm then print the alarm
    // message, clear the alarms and re-enable the
    // interrupts.

    if (alarm_flag) {
      int_disable;
      switch (alarm_hour) {
      case  8: 
        Serial.print("begin sunrise\n");
	alarm_hour = 9;
	break;
      case  9: 
        Serial.print("end sunrise\n");
	alarm_hour = 20;
	break;
      case 20:
        Serial.print("begin sunset\n");
	alarm_hour = 21;
	break;
      case 21:
        Serial.print("end sunset\n");
	alarm_hour = 8;
      default:
        Serial.print("???\n");
	alarm_hour = 8;
      }
      rtc.set_alarm1(RTC_ALARM1_MODE4, 0, alarm_hour, 0, 0);
      alarm_flag = 0;
      rtc.clear_alarm1();
      delay(1000);
      PCMSK2 |= (1 << RTC_ALARM1_INT);
      int_enable;
    }
  }
}


// Both RTC alarms call this routine.  When this 
// routine is called the alarm flag is set and 
// the pin change mask is cleared. 

// interrupt flag. The interrupt flags are read and 
// reset in the main loop.

ISR( PCINT2_vect )
{
  if (digitalRead(RTC_ALARM1_OUTPUT) == 0) {
    alarm_flag |= (1<<RTC_ALARM1_OUTPUT);
    PCMSK2 &= ~(1<<RTC_ALARM1_OUTPUT);
  }
}
 

John Luciani

Joined Apr 3, 2007
475
By the way, there is a typo in the manual for the board. The RTC part number is DS-1337 not RTC-1377.

hgmjr
You wouldn't happen to know the page in the manual with the typo? I used find
and did not see 1377 in the pdf file. I did see 1377 on the component list
that is on the site. I will have that corrected when I upload the new product
pages (which should be later today).

Thanks.

(* jcl *)
 

Thread Starter

stage3-s4

Joined Oct 1, 2009
10
Thanks John, that seems to help quiet a bit. All I would have to do is implement the dimming subroutine into that code correct?
I think this was the biggest problem I was having. I wasnt sure how to code it so I could change the intensity by minute instead of just running a analogwrite subroutine with a delay in it.
 
Last edited:

John Luciani

Joined Apr 3, 2007
475
All I would have to do is implement the dimming subroutine into that code correct?
Assuming my quick changes work ;)

I would probably change the case statement a little. When you get the 8AM
alarm 1. set the mode to sunrise, 2. set the alarms to interrupt every minute
set a counter to 0. Each alarm should now -- 1. increment the counter and
set the intensity to count/60. When the count gets to 60 -- 1. clear the mode,
2. set the alarms to interrupt at 8PM.

When you get the 8PM alarm -- 1. set the mode to sunset, 2. set the alarms to
interrupt every minute and set a counter to 60. Now for each alarm 1. decrement
the counter and set the intensity to count/60. When the count gets to 0 -- clear
the mode, 2. set the alarms to interrupt at 8AM.

For the mode maybe let 0 = between sunset and sunrise, 1 = sunrise, 2=between sunrise and sunset and 3=sunset. This could help you in branching.

(* jcl *)
 

hgmjr

Joined Jan 28, 2005
9,027
You wouldn't happen to know the page in the manual with the typo? I used find
and did not see 1377 in the pdf file. I did see 1377 on the component list
that is on the site. I will have that corrected when I upload the new product
pages (which should be later today).

Thanks.

(* jcl *)
I think the error was only present in the title to this thread. I will correct the title of the thread to avoid confusion.

hgmjr
 
Top