Vivarium/Terrarium light controller project

Hello everyone!

Nick here! I am absolutely new to the world of Arduino and programming, however I find the possibilities interesting and I hope to learn a lot here as time passes.

My intended project:

I have a vivarium with a breeding pair of golddust daygeckos.
The lighting for this vivarium is ExoTerras standard lighting with UVB bulbs and spotlights. These are on timers and I'm fine with that. What I would like to have is background lighting that cycles through sunrise/noon/sunset and moon lighting..

A am aware this has been done before. I have searched, googled, read, understood (some of it) and played around in the IDE. However I feel somewhat overwhelmed from all the info that some guidance is needed to get me back on track.

What I want to create:

  • A stand-alone light controller for background lighting (LED strip) that cycles through sunrise/noon/sunset/moon.
  • My first thoughts were to have a code that looped for 24hrs and I just connected it all at the right time of day to have it synced. However I have understood that many designs use a RTC like a DS1307 to automatically sync the code with the time of day. I am unsure how it works though. Is it connected to the internet or does it use stored values?

Equipment I have at my disposal

  • Arduino Uno with Arduino Starter Kit and Arduino Projects Book
  • 4,8m SMD5050 RGB LED strip with 144 LED's (30 LED's per meter)
  • Basic tools
  • A few different power supply units. One is a Luxorparts switching power supply (outputs 9-24V)
  • A few MOSFET's of the type IRLZ44N

I have come across several codes and looked through and tried to understand what is happening. I copied the parts I believed to be most important and played around with them in the IDE. I played around with a crossFade code and code from "Make Us Of"

/*
 

// Output
int redPin = 6;   // Red LED,   connected to digital pin 9
int grnPin = 9;  // Green LED, connected to digital pin 10
int bluPin = 5;  // Blue LED,  connected to digital pin 11

//overall brightness value, 0=off, 255=full
int Brightness = 255;

//individual brightness values for the red, green and blue LEDs for different States
int RDark = 0; //Total darkness
int GDark = 0; //Total darkness
int BDark = 0; //Total darkness

// Color arrays
int black[3]  = { 0, 0, 0 };
int white[3]  = { 100, 100, 100 };
int red[3]    = { 100, 0, 0 };
int green[3]  = { 0, 100, 0 };
int blue[3]   = { 0, 0, 100 };
int yellow[3] = { 40, 95, 0 };
int dimWhite[3] = { 30, 30, 30 };
int Night[3] = { 1, 1, 2 };
int Srise[3] = { 27, 11, 1 };
int Noon[3] = { 70, 40, 40 };
int Sset[3] = { 30, 10, 3 };
int SRR = 70;
int SRG = 30;
int SRB = 1;
int DTR = 180;
int DTG = 100;
int DTB = 80;
int SSR = 80;
int SSG = 25;
int SSB = 1;
int NTR = 1;
int NTG = 1;
int NTB = 2;
// etc.

// Set initial color
int redVal = black[0];
int grnVal = black[1]; 
int bluVal = black[2];

int wait = 20;      // 10ms internal crossFade delay; increase for slower fades
int hold = 0;       // Optional hold when a color is complete, before the next crossFade
int DEBUG = 1;      // DEBUG counter; if set to 1, will write values back via serial
int loopCount = 60; // How often should DEBUG report?
int repeat = 0;     // How many times should we loop before stopping? (0 for no stop)
int j = 0;          // Loop counter for repeat

// Initialize color variables
int prevR = redVal;
int prevG = grnVal;
int prevB = bluVal;

// Set up the LED outputs
void setup()
{
  pinMode(redPin, OUTPUT);   // sets the pins as output
  pinMode(grnPin, OUTPUT);   
  pinMode(bluPin, OUTPUT); 

  if (DEBUG) {           // If we want to see values for debugging...
    Serial.begin(9600);  // ...set up the serial ouput 
  }
}

// Main program: list the order of crossfades
void loop()
{

    for (int i=0;i<256; i++){
      
      analogWrite(redPin, NTR);
      analogWrite(grnPin, NTG);
      analogWrite(bluPin, NTB);
      delay(10);
    }

   crossFade(Night);
   crossFade(Srise);

   for (int i=0;i<256; i++){
      
      analogWrite(redPin, SRR);
      analogWrite(grnPin, SRG);
      analogWrite(bluPin, SRB);
      delay(10);
    }

    crossFade(Srise);
    crossFade(Noon);

    for (int i=0;i<256; i++){
      
      analogWrite(redPin, DTR);
      analogWrite(grnPin, DTG);
      analogWrite(bluPin, DTB);
      delay(120);
    }

    crossFade(Noon);
    crossFade(Sset);

    for (int i=0;i<256; i++){
      
      analogWrite(redPin, SSR);
      analogWrite(grnPin, SSG);
      analogWrite(bluPin, SSB);
      delay(10);
    }

    crossFade(Sset);
    crossFade(Night);


  if (repeat) { // Do we loop a finite number of times?
    j += 1;
    if (j >= repeat) { // Are we there yet?
      exit(j);         // If so, stop.
    }
  }
}


*/

int calculateStep(int prevValue, int endValue) {
  int step = endValue - prevValue; // What's the overall gap?
  if (step) {                      // If its non-zero, 
    step = 1020/step;              //   divide by 1020
  } 
  return step;
}



int calculateVal(int step, int val, int i) {

  if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
    if (step > 0) {              //   increment the value if step is positive...
      val += 1;           
    } 
    else if (step < 0) {         //   ...or decrement it if step is negative
      val -= 1;
    } 
  }
  // Defensive driving: make sure val stays in the range 0-255
  if (val > 255) {
    val = 255;
  } 
  else if (val < 0) {
    val = 0;
  }
  return val;
}

/* crossFade() converts the percentage colors to a 
*  0-255 range, then loops 1020 times, checking to see if  
*  the value needs to be updated each time, then writing
*  the color values to the correct pins.
*/

void crossFade(int color[3]) {
  // Convert to 0-255
  int R = (color[0] * 255) / 100;
  int G = (color[1] * 255) / 100;
  int B = (color[2] * 255) / 100;

  int stepR = calculateStep(prevR, R);
  int stepG = calculateStep(prevG, G); 
  int stepB = calculateStep(prevB, B);

  for (int i = 0; i <= 1020; i++) {
    redVal = calculateVal(stepR, redVal, i);
    grnVal = calculateVal(stepG, grnVal, i);
    bluVal = calculateVal(stepB, bluVal, i);

    analogWrite(redPin, redVal);   // Write current values to LED pins
    analogWrite(grnPin, grnVal);      
    analogWrite(bluPin, bluVal); 

    delay(wait); // Pause for 'wait' milliseconds before resuming the loop

    if (DEBUG) { // If we want serial output, print it at the 
      if (i == 0 or i % loopCount == 0) { // beginning, and every loopCount times
        Serial.print("Loop/RGB: #");
        Serial.print(i);
        Serial.print(" | ");
        Serial.print(redVal);
        Serial.print(" / ");
        Serial.print(grnVal);
        Serial.print(" / ");  
        Serial.println(bluVal); 
      } 
      DEBUG += 1;
    }
  }
  // Update current values for next loop
  prevR = redVal; 
  prevG = grnVal; 
  prevB = bluVal;
  delay(hold); // Pause for optional 'wait' milliseconds before resuming the loop
}

I realize that this is ab it of a messy first but I greatly appreciate any form of guidance, tips or advice I might get.

BR
Nick

Use a DS3231 RTC, and it'll run on time for years.

I don't know the power supply you referenced, but 144 LEDs are gonna need a lot of power - on the order of 80-100 watts. Make sure your power supply can handle that plus all the overhead for the rest of the stuff. You'll need 5 volts for the Arduino stuff, and a 3 volt battery to keep the RTC alive (lasts 6 years or more.)

ChrisTenone:
Use a DS3231 RTC, and it'll run on time for years.

I don't know the power supply you referenced, but 144 LEDs are gonna need a lot of power - on the order of 80-100 watts. Make sure your power supply can handle that plus all the overhead for the rest of the stuff. You'll need 5 volts for the Arduino stuff, and a 3 volt battery to keep the RTC alive (lasts 6 years or more.)

Thank you for your suggestion. I have a DS3231 on its way now.

The LED strip is part of a kit I bought some time ago, that has a IR transmitter/receiver similar to this:

The actual power supply for my kit looks like this
Can I use the same power supply for this project?

BR Nick

I did some measurements and decided on using about 60 LED's (a 2m long strip).