Real Time Clock controlling LEDs

Hi!

I'm new to the world of Arduino, and would love to get som help on a project I have.

What I am making is a device that will turn an RGB LED to a certain colour (red, green or blue) depending on the time of day and/or whether a button has been pressed.

Scenario 1:
At midnight the program will "reset" and the RED LED will turn ON (others off).

Scenario 2:
If a button is pressed, the GREEN LED will turn ON (others off), as long as the time is less than 15:00 (when something else shall happen, e.g. RED LED turns on).

...and other similar scenarios.

I have got the RTC up and running using RTClib, and know how to read/use time from it. However, I am not experienced enough to know what commands (conditionals?) to use. Do i use "IF" command? If so; how? :slight_smile:

I have also read abous "switch/case", but I don't really understand how to use this, and cannot find any descent tutorials on Youtube..

I would be very pleased if someone could help me out here, and possibly explain how the code works. :slight_smile: I am very willing to learn!

Below is what I am working with now. The IF statements were only tests to see if i could use data from the clock like that. The issue is that the LED turns off again when the given time is not true anymore..

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

RTC_DS1307 rtc;

const int rLED = 13;
const int gLED = 12;
const int bLED = 8;
const int button = 7;

void setup () {
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, INPUT);
  Serial.begin(57600);
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
  rtc.begin();

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop () {
    DateTime now = rtc.now();
    
    Serial.print(now.day(), DEC);
    Serial.print('-');
    Serial.print(now.month(), DEC);
    Serial.print('-');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
    
    // if the time/date is at the given point, rLED will be on, else it will be off
    if(now.minute() == 45) {
      digitalWrite(rLED, HIGH);
    }
      else {
      digitalWrite(rLED, LOW);
    }
    
    // when clock hits given time, rLED will go on, other LEDs will be off
    if(now.hour() == 2 && now.minute() == 0 && now.second() == 0) {
      digitalWrite(rLED, HIGH);
      digitalWrite(gLED, LOW);
      digitalWrite(bLED, LOW);
    }
    
    
    
    
    Serial.println();
    delay(1000);
}

bellduck:
I am very willing to learn!

That's good.

For conditionals you can either use "if-else", or "switch", both can be used for the same purpouse. One good way to learn is by viewing examples.

Here's an example for if-else.

//Turning an LED on or off by pressing a button

#define TRUE   1
#define FALSE  0

const int button = 10;
const int led = 13;

void setup(){
pinMode(button,INPUT_PULLUP);
pinMode(led,OUTPUT);
}

void loop(){
boolean a=digitalRead(button);

if(a==TRUE){
digitalWrite(led,HIGH);
}

else if(a==FALSE) {
digitalWrite(led,LOW);
}

}

Same example with switch:

//Turning an LED on or off by pressing a button

#define TRUE   1
#define FALSE  0

const int button = 10;
const int led = 13;

void setup(){
pinMode(button,INPUT_PULLUP);
pinMode(led,OUTPUT);
}

void loop(){
boolean a=digitalRead(button);

switch(a){

case TRUE: digitalWrite(led,HIGH);
       break;

case FALSE: digitalWrite(led,LOW);
       break;

default: break;
}

}
    if(now.minute() == 45) {
      digitalWrite(rLED, HIGH);
    }
      else {
      digitalWrite(rLED, LOW);
    }

The code in loop() runs hundreds of times per second. Each time this statement runs it will force the red LED on if the time is xx:45:xx and force it OFF if the time is anything else. The red LED will be on for one minute per hour. If you turn it on outside the minute it will only stay on for a very small fraction of a second before this statement turns it off again. You have to realize how your bits of code interact with each other.

Thank you both for your replies. :slight_smile:

I understand how that IF statement I made works, but how can I make the LED stay on with the push of a button or at a specific time of day?

Also, what does the "break" statement do?

The trick is to turn the LED on only once when you want it to go on and turn it OFF only when you want it to go OFF. For example if you want the light to turn ON at 45 minutes past each hour and OFF at 46 minutes past each hour:

void loop () {
  static boolean TurnedOnAtXX45XX = false;  // Not turned on yet
    // If the time is 45 minutes past the hour, turn on the LED if it was not already turned on
    if(now.minute() == 45 && !TurnedOnAtXX45XX ) {
      digitalWrite(rLED, HIGH);
      TurnedOnAtXX45XX = true;
    }
   // If the time is 46 minutes past the hour, turn off the LED if it was turned on at 45 past the hour
    if(now.minute() == 46 && TurnedOnAtXX45XX ) {
      digitalWrite(rLED, LOW);
      TurnedOnAtXX45XX = false;
    }
}

I figured I could use "state", whick made things much easier. :slight_smile:

I have now got my project up and running. However, there is one thing I can't figure out. As mentioned, I've used "state"-integers, but I can't get it to blink or fade..

For instance: If the hour count is 15, red LED should start blinking (or even better: fading). Of course, until another action interrupts it.
I have figured I should not use delay, as that will "slow down" the whole code.

Would be very pleased if someone could help me out here! :smiley:

bellduck:
I figured I could use "state", whick made things much easier. :slight_smile:

I have now got my project up and running. However, there is one thing I can't figure out. As mentioned, I've used "state"-integers, but I can't get it to blink or fade..

For instance: If the hour count is 15, red LED should start blinking (or even better: fading). Of course, until another action interrupts it.
I have figured I should not use delay, as that will "slow down" the whole code.

Would be very pleased if someone could help me out here! :smiley:

Avoid delay and use millis(). Look for the "blink without delay" example on Arduino.

Thank you, but I was already aware of this. :slight_smile:

Problem is I cannot get it to work, it only turns off my LED. Below is what i tried, with an IF statement calling the redBlink function.

long blinkInterval = 1000;
long previousMillis = 0;

void redBlink() {
  gState = LOW;
  bState = LOW;
  
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > blinkInterval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
  }
    // if the LED is off turn it on and vice-versa:
 
    if (rState == LOW){
      rState = HIGH;
    }
    else{
      rState = LOW;
    }
}

What am I missing here? :slight_smile:

Can someone give us a code for my project that is an RTC LED code to start increasingly fade brighter 30 minutes before a set time? And then when it reaches that set time to turn off.