Arduino microcontroller with DS1337 RTC for LED Dimming

Discussion in 'Embedded Systems and Microcontrollers' started by stage3-s4, Sep 9, 2010.

  1. stage3-s4

    Thread Starter New Member

    Oct 1, 2009
    10
    0
    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.
     
  2. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Can you supply a schematic showing how you have assigned your IO to the LEDs and the RTC?

    hgmjr
     
  3. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    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
     
  4. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
  5. John Luciani

    Active Member

    Apr 3, 2007
    477
    0
    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.


    Code ( (Unknown Language)):
    1. #include <avr/interrupt.h>    
    2. #include <avr/io.h>  
    3.  
    4. #include <LED_debug.h>
    5. #include <TWI.h>
    6. #include <RTC.h>
    7.  
    8. #define ON  HIGH
    9. #define OFF LOW
    10.  
    11. #define int_enable   PCICR  |=  (1 << PCIE2)
    12. #define int_disable  PCICR  &= ~(1 << PCIE2)
    13.  
    14. #define RTC_ALARM1_OUTPUT 6 // PD6
    15. #define RTC_ALARM1_INT    PCINT22
    16.  
    17. #define RTC_ALARM2_OUTPUT 5 // PD5
    18. #define RTC_ALARM2_INT    PCINT21
    19.  
    20. // PCI2 triggers for PCINT23..16
    21. // PCI1 triggers for PCINT14..8
    22. // PCI0 triggers for PCINT7..0
    23.  
    24. LED_debug led;
    25. RTC       rtc;
    26.  
    27. unsigned char alarm_hour = 8;
    28. unsigned char alarm_flag = 0;
    29. unsigned char intdata = 0;
    30.  
    31. void setup() {
    32.  
    33.   // Compensating for the 12MHz XTAL
    34.   // 12800 = (16/12) * 9600
    35.   // 25600 = (16/12) * 19200
    36.  
    37.   Serial.begin(9600);
    38.  
    39.   // setup the TWI
    40.  
    41.   TWBR = TWI_TWBR;             // Set bit rate register (Baudrate). Defined in TWI.h  
    42.   TWDR = 0xFF;                 // Default content = SDA released.
    43.   TWCR = (1<<TWEN)|            // Enable TWI-interface and release TWI pins.
    44.          (0<<TWIE)|(0<<TWINT)| // Disable Interupt.
    45.          (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|  // No Signal requests.
    46.          (0<<TWWC);
    47.  
    48.  
    49.   // enable pullup on alarm1 output
    50.  
    51.   pinMode(RTC_ALARM1_OUTPUT, INPUT);
    52.   digitalWrite(RTC_ALARM1_OUTPUT, HIGH);
    53.  
    54.   // initialize the date
    55.    rtc.set_date(2010, 2, 24);
    56.  
    57.   // intialize the clock
    58.    rtc.set_time(16, 26, 20);
    59.  
    60.  
    61.   // Initialize the control register for a 32768Hz square wave
    62.   // and disable the square wave output
    63.  
    64.   // RTC_RS2 | RTC_RS1 ..... Rate Select, square wave output = 32768Hz
    65.   // RTC_INTCN ............. Interrupt Control (=1 interrupts activated,
    66.   //                         no square wave on INTB
    67.  
    68.   rtc.write_reg(RTC_REG_CONTROL, RTC_RS2 | RTC_RS1 | RTC_INTCN);
    69.  
    70.   // Setup ALARM1 to alarm when the seconds count equals 20
    71.   // and then enable the ALARM1
    72.  
    73.   // RTC_ALARM1_MODE4 ..... Alarm when hours, minutes, seconds match
    74.   // dow .................. 0
    75.   // hours ................ 0
    76.   // minutes .............. 0
    77.   // seconds .............. 20
    78.  
    79.   rtc.set_alarm1(RTC_ALARM1_MODE4, 0, alarm_hour, 0, 0); // alarm at 8AM
    80.   rtc.enable_alarm1();
    81.  
    82.   // Initialize the pin change interrupt mask for the
    83.   //  pin that is connected to the RTC /INTA output.
    84.  
    85.   PCMSK2 |= (1 << RTC_ALARM1_INT);
    86.  
    87.   // Enable the pin change interrupts
    88.  
    89.   int_enable;
    90.  
    91. }
    92.  
    93.  
    94. void loop() {
    95.   char timestr[22];
    96.   while(1) {
    97.     rtc.read_regs();
    98.     rtc.localtime(timestr);
    99.     Serial.print(timestr);
    100.     Serial.print("\n");
    101.     led.blink(1);
    102.     delay(1000);
    103.  
    104.     // If there was an alarm then print the alarm
    105.     // message, clear the alarms and re-enable the
    106.     // interrupts.
    107.  
    108.     if (alarm_flag) {
    109.       int_disable;
    110.       switch (alarm_hour) {
    111.       case  8:
    112.         Serial.print("begin sunrise\n");
    113.     alarm_hour = 9;
    114.     break;
    115.       case  9:
    116.         Serial.print("end sunrise\n");
    117.     alarm_hour = 20;
    118.     break;
    119.       case 20:
    120.         Serial.print("begin sunset\n");
    121.     alarm_hour = 21;
    122.     break;
    123.       case 21:
    124.         Serial.print("end sunset\n");
    125.     alarm_hour = 8;
    126.       default:
    127.         Serial.print("???\n");
    128.     alarm_hour = 8;
    129.       }
    130.       rtc.set_alarm1(RTC_ALARM1_MODE4, 0, alarm_hour, 0, 0);
    131.       alarm_flag = 0;
    132.       rtc.clear_alarm1();
    133.       delay(1000);
    134.       PCMSK2 |= (1 << RTC_ALARM1_INT);
    135.       int_enable;
    136.     }
    137.   }
    138. }
    139.  
    140.  
    141. // Both RTC alarms call this routine.  When this
    142. // routine is called the alarm flag is set and
    143. // the pin change mask is cleared.
    144.  
    145. // interrupt flag. The interrupt flags are read and
    146. // reset in the main loop.
    147.  
    148. ISR( PCINT2_vect )
    149. {
    150.   if (digitalRead(RTC_ALARM1_OUTPUT) == 0) {
    151.     alarm_flag |= (1<<RTC_ALARM1_OUTPUT);
    152.     PCMSK2 &= ~(1<<RTC_ALARM1_OUTPUT);
    153.   }
    154. }
    155.  
     
  6. John Luciani

    Active Member

    Apr 3, 2007
    477
    0
    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 *)
     
  7. stage3-s4

    Thread Starter New Member

    Oct 1, 2009
    10
    0
    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: Sep 10, 2010
  8. John Luciani

    Active Member

    Apr 3, 2007
    477
    0
    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 *)
     
  9. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    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
     
  10. John Luciani

    Active Member

    Apr 3, 2007
    477
    0
    Thanks.

    While looking for the mistake in the datasheet I did find the BOM error on the
    website.

    (* jcl *)
     
Loading...