Help please for RGB and timing tips

Hello all,
This is my first attempt at an Arduino project.

I want to create a code to change RGB lights over the course of the day. The code I created works as is, but I want to add 2 more pieces:

  1. I want to start the code at certain times of day (eventually I want to get the time via GPS, but lets walk before we run!)
    Something like "if current hour =6, then run 0600 time RGB array".

  2. More importantly I want to gradually fade from one RGB array color set to the next one. I know I can man-handle each time set, but there has to be a more elegant way to do it.
    I want to:

  • Compare Last RGB Array setting to New RGB Array setting.

  • Determine value difference between New RGB Array and Last RGB Array.

  • Increment or decrement by that value difference (or stay the same if values are the same), over X amount of time. I put a delay in there temporarily, but want to get rid of that.

For some reason I cannot upload the code, but I will paste the bulk of it.

I've scoured the internet for codes, tutorials, videos, etc., but I'm running stuck.
Please help, or point me in the right direction! Thanks

#include<TimeLib.h>

int fadeTime_ms = 3000; //increase to increase delay time (ms)
int redled = 3;
int greenled = 5;
int blueled = 6;
int i;

//28 Array settings in all

//00-03:00 3:30 4:00 4:30 5:00 5:30 6:00 6:30 7:00 7:30 7:45 8-830 9:00 9:30 10-1730 18:00 18:30 19:00 19:30 20:00 20:15 20:30 21:00 21:30 22:00 22:30 23:00 23:30
int redarray[] {0, 0, 0, 0, 0, 0, 50, 120, 150, 200, 215, 225, 230, 240, 255, 255, 255, 225, 225, 220, 215, 200, 180, 150, 0, 0, 0, 0};
int greenarray[] {0, 0, 0, 0, 0, 0, 50, 120, 150, 200, 215, 225, 230, 240, 255, 255, 255, 225, 225, 220, 215, 200, 180, 150, 0, 0, 0, 0};
int bluearray[] {100, 110, 120, 130, 140, 150, 150, 150, 150, 150, 150, 150, 200, 225, 255, 200, 150, 150, 150, 150, 150, 150, 150, 140, 130, 120, 115, 100};

// the setup routine runs once when you press reset
void setup() {

Serial.begin(9600);
}

void loop() {

//28 Arrays in all

//Time:0000-0300
analogWrite(redled, redarray[0]);
analogWrite(greenled, greenarray[0]);
analogWrite(blueled, bluearray[0]);
delay(fadeTime_ms);
Serial.println("0300");

//Time:0330
analogWrite(redled, redarray[1]);
analogWrite(greenled, greenarray[1]);
analogWrite(blueled, bluearray[1]);
delay(fadeTime_ms);
Serial.println("0330");

//Time:0400
analogWrite(redled, redarray[2]);
analogWrite(greenled, greenarray[2]);
analogWrite(blueled, bluearray[2]);
delay(fadeTime_ms);
Serial.println("0400");

//Time:0430
analogWrite(redled, redarray[3]);
analogWrite(greenled, greenarray[3]);
analogWrite(blueled, bluearray[3]);
delay(fadeTime_ms);
Serial.println("0430");

//Time:0500
analogWrite(redled, redarray[4]);
analogWrite(greenled, greenarray[4]);
analogWrite(blueled, bluearray[4]);
delay(fadeTime_ms);
Serial.println("0500");

//Time:0530
analogWrite(redled, redarray[5]);
analogWrite(greenled, greenarray[5]);
analogWrite(blueled, bluearray[5]);
delay(fadeTime_ms);
Serial.println("0530");

etc, through 2400 hours

Hello stevenorman
Post your current sketch, well formated, with comments and in so called code tags "</>" and a schematic, not a Fritzy diagram, to see how we can help.
Have a nice day and enjoy coding in C++.
Дайте миру шанс

RTC (Real Time Clock) to keep time of day. Arduinos are not great time keepers. GPS will likely not work indoors, only outdoors with a clear view of the sky.

OK. Good to know. Thanks!

You should be able to use the time to calculate which array index is currently in force rather than explicitly coding for each time interval. A common technique to simplify the calculation is to derive minutes (or seconds) since midnight.

As noted above, GPS may not work indoors so you will need an RTC. I have a large skylight that permits GPS reception and sometimes it works right next to a window, but even then it's flakey. You might use GPS to set the time on the RTC if it has a fix though, even if you have to move the apparatus to a spot with reception.

Thank you! It’s on my wish list, but as I stated, this is my first attempt at coding. Any advice as to a sample code to accomplish that?

here is a demo-code that creates a pure software RTC. Depending on the used board and if this board has ceramic resonator or a chrystal as clock-source the deviation will be up to minutes per day from exact time.

calculating "MinutesOfDay by hour * 60 + minutes is much easier to compare than hours and minutes separately

/* This software belongs to the public domain
 * Attention: a software-RTC like this one 
 * which uses the onboard-oscillator of the microcontroller-board
 * has a deviation from exact time of up to multiple seconds per day
 * This means of you want real time with a higher precision use a
 * hardware based RTC which will be much more precise
 */

unsigned long RTC_Timer  = 0;
unsigned long MyTestTimer;

int RTC_Hour   = 0;
int RTC_Minute = 59;
int RTC_Second = 50;
int RTC_10nth_Seconds = 0;
int minutesOfDay;
long secondsOfDay;


// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - periodStartTime >= TimePeriod )
  {
    periodStartTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  }
  else return false;            // not expired
}


void PrintRTC_Data() {
  Serial.print("Software RTC time: ");
  Serial.print(RTC_Hour);
  Serial.print(":");
  Serial.print(RTC_Minute);
  Serial.print(":");
  Serial.print(RTC_Second);

  minutesOfDay = RTC_Hour * 60 + RTC_Minute;
  secondsOfDay = RTC_Hour * 3600 + RTC_Minute * 60 + RTC_Second;

  Serial.print(" minutesOfDay:");
  Serial.print(minutesOfDay);

  Serial.print("  secondsOfDay:");
  Serial.print(secondsOfDay);  
  Serial.println();
  
}


void SoftRTC() {
  if ( TimePeriodIsOver(RTC_Timer, 100) ) { // once every 100 milliseconds 
    RTC_10nth_Seconds ++;                   // increase 1/10th-seconds counter
    
    if (RTC_10nth_Seconds == 10) {          // if 1/10th-seconds reaches 10
      RTC_10nth_Seconds = 0;                // reset 1/10th-seconds counterto zero
      RTC_Second++;                         // increase seconds counter by 1

      if (RTC_Second == 60) {               // if seconds counter reaches 60
        RTC_Minute++;                       // increase minutes counter by 1
        RTC_Second = 0;                     // reset seconds counter to zero
      }
    }

    if (RTC_Minute == 60) {                 // if minutes counter reaches 60
      RTC_Hour++;                           // increase hour counter by 1
      RTC_Minute = 0;                       // reset minutes counter to zero
    }

    if (RTC_Hour == 24) {                   // if hours counter reaches 24 
      RTC_Hour = 0;                         // reset hours counter to zero
    }
  }
}


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
}


void loop() {
  SoftRTC(); // must be called very regular and repeatedly to update the 0.1 second time-ticks
             // this means you CAN'T use delay(). 
             // Each and every single delay() must be replaced NON-blocking timing
  if ( TimePeriodIsOver(MyTestTimer, 1000) ) { // if 1000 milliseconds have passed by
    PrintRTC_Data();                           // print time
  }

}

best regards Stefan

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.