Circadian light

Hello, I would like to create a circadian lighting sequence that changes between warm white and cold white depending on the time. Now my question: Can I create a 24-hour sequence when I connect my radio clock (RTC) and it is possible to have a value output that corresponds to the proportion of the respective color and can be copied to a dimming command. if so, how do I get the values on my course.

again in German

Hallo, ich möchte einen zirkadianen beleuchtungsverlauf erstellen der uhrzeit abhängig zwischen warmweis und kaltweiß wechselt. jetzt meine frage: kann ich einen 24std ablauf erstellen wenn ich meine funkuhr (RTC) anschliese und ist es möglich sich einen wert ausgeben zu lassen der dem anteil der jeweiligen farbe entspricht und sich auf einen dimmbefehl kopieren läst. wenn ja wie bekomme ich die werte auf meine kurfe.

got this code from Arduino – cycling through colours of the rainbow:

/*
  Rainbow

  Take a tricolour LED through the colours of the rainbow using an analogue input.

  The circuit:
   TBC

  Created 21 April 2012
  By Jason Judge

  This example code is in the public domain.

*/

// The three primary colour LEDs, driven as analgue outputs (actually PWM, but
// close enough for our analogue eyes).

const int ledPinRed = 11;    // Red LED connected to analogue out pin
const int ledPinGrn = 10;    // Green LED connected to analogue out pin
const int ledPinBlu = 9;     // Blue LED connected to analogue out pin

const int modeSwitchPin = 12;

// The Hue potentiometer goes on an analogue pin, taking the pin from
// 0V to 5V.

const int potPinHue = 0;

// Constants to define the ranges.

const int hueRedLow = 0;
const int hueRedHigh = 255;
const int hueBlue = 170;

// The size of the angle of one sector (1/6 of a colour wheel), and of a complete
// cycle of the colour wheel.

const int angleMin = 0;
const int angleSector = 60;
const int angleMax = 360;

const int brightMin = 0;
const int brightMax = 255;

// Work variables.

// The potentiometer value is mapped to the range 0 to 360 (degrees).
int potValueHue;

// The hue is the range 0 (red) to 170 (blue) in rainbow
// mode or 255 (red) in colour wheel mode.
// The brightness ranges from 0 (dark) to 255 (full brightness)

int hue, brightness;

// The saturation is fixed at 255 (full) to remove blead-through of different
// colours.
// It could be linked to another potentiometer if a demonstration of hue
// is desired.

const int saturation = 255;

// The brightess of each LED (0 to 255).

unsigned int r, g, b;

void setup()  {
  // Still need to set a baud rate, even for USB.
  Serial.begin(9600);

  // Set LED pins to output.
  pinMode(ledPinRed, OUTPUT);
  pinMode(ledPinGrn, OUTPUT);
  pinMode(ledPinBlu, OUTPUT);

  // Poteniometer analogue pin is an input.
  pinMode(potPinHue, INPUT);

  // TODO: mode switch in a digital input.
  pinMode(modeSwitchPin, INPUT);
}

void loop()  {
  // The Hue potentiometer value is mapped to degrees - 0 to 360 - for convenience.
  potValueHue = map(analogRead(potPinHue), 0, 1023, 0, 360);

  // Control the mode using a physical switch.

  if (digitalRead(modeSwitchPin)) {
    // Rainbow colour mode (infra-red to ultra-violet - well invisible to invisible ;-).

    // The hue ranges from red (0) at 60 degrees to blue (170) at 300 degrees.
    hue = constrain(map(potValueHue, angleSector, angleMax - angleSector, hueRedLow, hueBlue), hueRedLow, hueBlue);

    // Brightness - fade up 0-60 degrees
    brightness = constrain(map(potValueHue, angleMin, angleSector, brightMin, brightMax), brightMin, brightMax);

    // Brightness fade down 300-360 degrees
    brightness = brightness - constrain(map(potValueHue, angleMax - angleSector, angleMax, brightMin, brightMax), brightMin, brightMax);
  } else {
    // Colour wheel mode (red to red, wrapped around in a cycle).

    hue = map(potValueHue, angleMin, angleMax, hueRedLow, hueRedHigh);

    // The brightness is fixed at full for the colour wheel. This could be
    // linked to another poteniometer if that is a concept you wish to
    // demonstrate.
    brightness = 255;
  }

  // Do the conversion.
  HSBToRGB(hue, saturation, brightness, &r, &g, &b);

  analogWrite(ledPinRed, r);
  analogWrite(ledPinGrn, g);
  analogWrite(ledPinBlu, b);

  Serial.print(" bright=");
  Serial.print(brightness);
  Serial.print(" hue=");
  Serial.print(hue);
  Serial.print(" red=");
  Serial.print(r);
  Serial.print(" green=");
  Serial.print(g);
  Serial.print(" blue=");
  Serial.print(b);
  Serial.println("");
  delay(50);
}

// This function taken from here:
// http://eduardofv.com/read_post/179-Arduino-RGB-LED-HSV-Color-Wheel-

void HSBToRGB(
  unsigned int inHue, unsigned int inSaturation, unsigned int inBrightness,
  unsigned int *oR, unsigned int *oG, unsigned int *oB )
{
  if (inSaturation == 0)
  {
    // achromatic (grey)
    *oR = *oG = *oB = inBrightness;
  }
  else
  {
    unsigned int scaledHue = (inHue * 6);
    unsigned int sector = scaledHue >> 8; // sector 0 to 5 around the color wheel
    unsigned int offsetInSector = scaledHue - (sector << 8);	// position within the sector
    unsigned int p = (inBrightness * ( 255 - inSaturation )) >> 8;
    unsigned int q = (inBrightness * ( 255 - ((inSaturation * offsetInSector) >> 8) )) >> 8;
    unsigned int t = (inBrightness * ( 255 - ((inSaturation * ( 255 - offsetInSector )) >> 8) )) >> 8;

    switch ( sector ) {
      case 0:
        *oR = inBrightness;
        *oG = t;
        *oB = p;
        break;
      case 1:
        *oR = q;
        *oG = inBrightness;
        *oB = p;
        break;
      case 2:
        *oR = p;
        *oG = inBrightness;
        *oB = t;
        break;
      case 3:
        *oR = p;
        *oG = q;
        *oB = inBrightness;
        break;
      case 4:
        *oR = t;
        *oG = p;
        *oB = inBrightness;
        break;
      default:    // case 5:
        *oR = inBrightness;
        *oG = p;
        *oB = q;
        break;
    }
  }
}

personally I used it for the 'colour wheel' code but in your case I guess you could tweak the above code for the 'rainbow' feature and

  • map the 'hue' variable to the time of day to sent its colour
  • as in the above code use a pot to set the 'brightness' dimming

hope that helps....

Thanks this helps to mix the colors but I don't know how to ad a color to a time
for example I need 30% Warmwhite and 60% Couldwhite at 16:00
and 50%WW 40%CW at 20:00

is there no way to use something like a table ?

kipumm:
Thanks this helps to mix the colors but I don't know how to ad a color to a time
for example I need 30% Warmwhite and 60% Couldwhite at 16:00
and 50%WW 40%CW at 20:00

is there no way to use something like a table ?

the code I posted gives the full colour spectrum as it is said in the comments.
so as a first step you would need to find out what 'hue', 'brightness' (and saturation) values to get the various colours you want.
as to your question, yes you could then use arrays to create a look up table to map 'time' to corresponding 'hue', 'brightness' (and saturation) values.

hope that helps...

I think that "White" will be RGB: 255/255/255. It will get 'warm' if you fade down the blue (255/255/200) and will get 'cold' if you fade down the red+green=yellow (200/200/255). That gets you about 110 shades of white (55 between Cold and White, and 55 between White and Warm).

If you want it Cold at noon and Warm at midnight:

const byte RedPin = 3;
const byte GreenPin = 5;
const byte BluePin = 9;


void setup()
{
  // Set up the RTC
}


void loop()
{
  // Read the time from the RTC
  int Hour, Minute;
  
  int TimeOfDayInMinutes = Hour * 60 + Minute; // 1440 in 24 hours
  int rg=0, b=0;


  if (TimeOfDayInMinutes < 6 * 60) // Before 6AM
  {
    // Early morning, fading from Warm to White
    rg = 255;
    b = 200 + (55ul * TimeOfDayInMinutes) / (6 * 60); // Fade up from 200 to 255
  }
  else if (TimeOfDayInMinutes < 12 * 60) // Before Noon
  {
    // Late morning, fading from White to Cold
    rg = 255 - (55ul * (TimeOfDayInMinutes-(6*60))) / (6 * 60); // Fade up from 255 to 200
    b = 255;
  }
  else if (TimeOfDayInMinutes < 18 * 60) // Before 6PM
  {
    // Early afternoon, fading from Cold to White
    rg = 200 + (55ul * (TimeOfDayInMinutes-(12*60))) / (6 * 60); // Fade up from 200 to 255
    b = 255;
  }
  else if (TimeOfDayInMinutes < 24 * 60) // Before Midnight
  {
    // Evening, fading from White to warm
    rg = 255;
    b = 255 - (55ul * (TimeOfDayInMinutes-(18*60))) / (6 * 60); // Fade blue down from 255 to 200
  }


  analogWrite(RedPin, rg);
  analogWrite(GreenPin, rg);
  analogWrite(BluePin, b);
}

Thanks Johnwasser this is exact the idea I was looking for. actually I have two LED Stripes in CW WW but that doesn't effect the code much. I can't figure out what 55ul is doing ? can you give me a short explanation so I can understand what I write there :slight_smile:

I was just using an "unsigned long" constant to make sure the math doesn't overflow. It isn't a problem since 55 * 'six hours worth of minutes' fits easily in a signed int. You can change the 55ul to 55.

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