/* BLOCK COMMENT
ATTENTION: This Sketch contains elements of C++.
https://www.learncpp.com/cpp-tutorial/
https://forum.arduino.cc/t/help-with-leds-on-model-railway-project/927497
*/
// This define controls Serial output to check data
// and also switches time to 00:
// 0 = debug output disabled
// 1 = debug output enabled
#define debug 0
#include <TM1637Display.h>
#define CLK 10
#define DIO 11
TM1637Display display(CLK, DIO);
#define LED1 2
#define LED2 3
#define LED3 4
int timeA = 6;
int timeB = 9;
int timeC = 11;
int timeD = 14;
int timeE = timeA + 2;
int timeF = timeB + 2;
int timeG = timeC + 2;
int timeH = timeD + 2;
int timeI = timeE + 2;
int timeJ = timeF + 2;
int timeK = timeG + 2;
int timeL = timeH + 2;
int x = 2;
int y = 10;
int z = 3;
#define ProjectName "Help with LEDs on model railway project"
// HARDWARE AND TIMER SETTINGS
// YOU MAY NEED TO CHANGE THESE CONSTANTS TO YOUR HARDWARE AND NEEDS
constexpr unsigned long ModelTimeScale {2}; // time per simulated sec in msec
// 1 modelMinute = 60 x 100 msec about 6 sec in real world
// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
uint16_t sunRiseCountDownSeconds = 60*60; // 6 minutes x 60 seconds
uint16_t sunSetCountDownSeconds = 60*60; // 6 minutes x 60 seconds
struct Clock_type {
byte hours = 0;
byte minutes = 1;
byte seconds = 1;
boolean ChangeColors = false;
boolean sunRiseEnabled = false;
boolean sunSetEnabled = false;
uint16_t CountDownSeconds = 0;
unsigned long duration = ModelTimeScale;
unsigned long stamp = 0;
};
struct Clock_type modelClock;
#include <FastLED.h>
#define NUM_LEDS 30
#define LED_PIN1 6
#define LED_PIN2 7
#define BRIGHTNESS 100
CRGB leds1[NUM_LEDS];
CRGB leds2[NUM_LEDS];
DEFINE_GRADIENT_PALETTE( autumnrose_gp ) {
0, 0, 0, 0,
0, 71, 3, 1,
45, 128, 5, 2,
84, 186, 11, 3,
127, 215, 27, 8,
153, 224, 69, 13,
188, 229, 84, 6,
226, 242, 135, 17,
254, 247, 161, 79,
255, 0, 0, 0
};
CRGBPalette16 myPal = autumnrose_gp;
void ResetModelClock(){
modelClock.hours = 0;
modelClock.minutes = 0;
modelClock.seconds = 0;
modelClock.ChangeColors = false;
modelClock.sunRiseEnabled = false;
modelClock.sunSetEnabled = false;
modelClock.CountDownSeconds = 0;
modelClock.duration = ModelTimeScale;
modelClock.stamp = 0;
}
void setup() {
Serial.begin(115200);
Serial.println(F("."));
Serial.print(F("File : ")), Serial.println(__FILE__);
Serial.print(F("Date : ")), Serial.println(__DATE__);
Serial.print(F("Project: ")), Serial.println(ProjectName);
pinMode (LED_BUILTIN, OUTPUT); // used as heartbeat indicator
FastLED.addLeds<WS2812, LED_PIN1, GRB>(leds1, NUM_LEDS);
FastLED.addLeds<WS2812, LED_PIN2, GRB>(leds2, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS );
FastLED.show();
pinMode (LED1, OUTPUT);
pinMode (LED2, OUTPUT);
pinMode (LED3, OUTPUT);
ResetModelClock(); // Just to be sure ;-)
if (debug) {
modelClock.hours = 0;
modelClock.minutes = 59;
modelClock.seconds = 30;
};
}
void GetTimeAndBlinkLED() {
currentTime = millis();
digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
}
void PrintModelClockToSerial(){
if (modelClock.hours < 10) Serial.print("0");
Serial.print(modelClock.hours); Serial.print(":");
if (modelClock.minutes < 10) Serial.print("0");
Serial.print(modelClock.minutes); Serial.print(":");
if (modelClock.seconds < 10) Serial.print("0");
Serial.print(modelClock.seconds); Serial.println(" o´clock");
}
void HandleCountDown(){
if (modelClock.CountDownSeconds > 0) modelClock.CountDownSeconds--;
modelClock.ChangeColors = (modelClock.CountDownSeconds > 0);
}
void HandleModelClock() {
if (currentTime - modelClock.stamp >= modelClock.duration) {
modelClock.stamp = currentTime;
modelClock.seconds++;
modelClock.seconds %= 60;
if (!modelClock.seconds) {
modelClock.minutes++;
modelClock.minutes %= 60;
if (!modelClock.minutes){
modelClock.hours++;
modelClock.hours %= 24;
}
}
PrintModelClockToSerial();
HandleCountDown();
}
}
void HandleDebugClock(){
if (modelClock.hours == 1 && modelClock.minutes == 10){
modelClock.hours = 5;
modelClock.minutes = 59;
modelClock.seconds = 30;
};
if (modelClock.hours == 7 && modelClock.minutes == 10){
modelClock.hours = 17;
modelClock.minutes = 59;
modelClock.seconds = 30;
};
}
void printColor(CRGB aColor){
Serial.print(" R = ");Serial.print(aColor.red);
Serial.print(" G = ");Serial.print(aColor.green);
Serial.print(" B = ");Serial.println(aColor.blue);
}
void sunRise() {
// Changes only once per modelClock.second allowed
modelClock.ChangeColors = false;
// The code line below maps the decreasing countdown value to a range from 0 .. 255
// as CountDownSeconds = 1 is the lowest value here
// it is mapped to gradientIndex 255 as we want an increasing index
uint16_t gradientIndex = map(modelClock.CountDownSeconds,sunRiseCountDownSeconds,1,0,255);
CRGB color = CRGB::Black;
if (gradientIndex < 255) {
color = ColorFromPalette(myPal, gradientIndex);
fill_solid(leds1, NUM_LEDS, color);
};
if (debug) { Serial.print("sunRise gradientIndex = "); Serial.print(gradientIndex); printColor(color);};
fill_solid(leds1, NUM_LEDS, color);
FastLED.show();
}
void sunSet() {
modelClock.ChangeColors = false; // Only once per second!!!
// The code line below maps the decreasing countdown value to a range from 255 .. 0
// as CountDownSeconds = 1 is the lowest value here
// it is mapped to gradientIndex 0 as we want a decreasing index
uint16_t gradientIndex = map(modelClock.CountDownSeconds,sunRiseCountDownSeconds,1,255,0);
CRGB color2 = ColorFromPalette(myPal, gradientIndex);
fill_solid(leds2, NUM_LEDS, color2);
FastLED.show();
if (debug) { Serial.print("sunSet gradientIndex = "); Serial.print(gradientIndex);printColor(color2);};
}
void HandleLight() {
switch (modelClock.hours) {
case 0: modelClock.sunRiseEnabled = true;
break;
case 6: if (modelClock.sunRiseEnabled) {
modelClock.sunRiseEnabled = false; // So that this routine runs only once
modelClock.sunSetEnabled = true; // and the sketch is prepared for 4 o'clock
modelClock.CountDownSeconds = sunRiseCountDownSeconds;
};
if (modelClock.ChangeColors) sunRise();
break;
case 18: if (modelClock.sunSetEnabled) {
modelClock.sunRiseEnabled = true; // So the sketch is prepared for 1 o'clock
modelClock.sunSetEnabled = false; // and that this routine runs only once
modelClock.CountDownSeconds = sunSetCountDownSeconds;
};
if (modelClock.ChangeColors) sunSet();
break;
default: // Do nothing
break;
}
}
void loop () {
GetTimeAndBlinkLED();
HandleModelClock();
if (debug) HandleDebugClock();
HandleLight();
{
display.setBrightness(1,true);
display.showNumberDecEx(modelClock.minutes, 0, true, 2, 2);
display.showNumberDecEx(modelClock.hours, 0x40, true, 2, 0);
}
//LED1
{
int brightness = map(modelClock.hours, timeA, timeB, 0, z);
int brightness2 = map(modelClock.hours, timeC, timeD, z, 0);
if (modelClock.hours == 00)
{
analogWrite(LED1, 0);
}
if (modelClock.hours >= timeA && modelClock.hours<= timeB )
{
analogWrite(LED1, brightness);
}
if (modelClock.hours >= timeB && modelClock.hours<= timeC)
{
analogWrite(LED1, z);
}
if (modelClock.hours >=timeC && modelClock.hours<= timeD)
{
analogWrite(LED1, brightness2);
}
if (modelClock.hours >=timeD && modelClock.hours<= 24)
{
analogWrite(LED1, 0);
}
}
//LED2
{
int brightness3 = map(modelClock.hours, timeE, timeF, 0, y);
int brightness4 = map(modelClock.hours, timeG, timeH, y, 0);
if (modelClock.hours == 00)
{
analogWrite(LED2, 0);
}
if (modelClock.hours >= timeE && modelClock.hours<= timeF )
{
analogWrite(LED2, brightness3);
}
if (modelClock.hours >= timeF && modelClock.hours<= timeG)
{
analogWrite(LED2, y);
}
if (modelClock.hours >=timeG && modelClock.hours<= timeH)
{
analogWrite(LED2, brightness4);
}
if (modelClock.hours >timeH && modelClock.hours<= 24)
{
analogWrite(LED2, 0);
}
}
//LED3
{
int brightness5 = map(modelClock.hours, timeI, timeJ, 0, x);
int brightness6 = map(modelClock.hours, timeK, timeL, x, 0);
if (modelClock.hours == 00)
{
analogWrite(LED3, 0);
}
if (modelClock.hours >= timeI && modelClock.hours<= timeJ )
{
analogWrite(LED3, brightness5);
}
if (modelClock.hours >= timeJ && modelClock.hours<= timeK)
{
analogWrite(LED3, x);
}
if (modelClock.hours >=timeK && modelClock.hours<= timeL)
{
analogWrite(LED3, brightness6);
}
if (modelClock.hours >timeL && modelClock.hours<= 24)
{
analogWrite(LED3, 0);
}
}
}
[/code]