Help with LEDs on model railway project

{
    int brightness = map(modelClock.hours, 2, 10, 0, 15);
    int brightness2 = map(modelClock.hours, 14, 20, 15, 0);


  if (modelClock.hours==00)
{
  analogWrite(LED1, 0);
}
if (modelClock.hours >=2)    
    {
      analogWrite(LED1, brightness);
    }
    if (modelClock.hours >= 14);
    {
      analogWrite(LED1, brightness2);
    }
  }```

No joy..

Lose the semicolon:

    if (modelClock.hours >= 14);

didn't do it either..

if (modelClock.hours == 00)
{
  analogWrite(LED1, 0);
}
if (modelClock.hours >= 02 || < = 9 )    
    {
      analogWrite(LED1, brightness);
    }
    if (modelClock.hours == 10)
    {
      analogWrite(LED1, 15);
    }
if (modelClock.hours >=14 || < = 20)
{
  analogWrite(LED1, brightness2);
}
  
  }

Do the hours to trigger need to be in a range like this? This won't let me up load as there is a problem with it, but for demo purposes

Oops

This:

if (modelClock.hours >= 02 || < = 9 )   

Should probably be:

if (modelClock.hours >= 2 && modelClock.hours<= 9 )   

Same pattern for the other one too.

This seems to have done the trick! Thank you!

So guess who is isolating with covid and has some spare time for arduino learning! :joy:

I installed some rgb led strips as was suggested above and am trying to figure out the best way to get them into my code to do sunrise and sunset.

I have been having fun with fastled.h so I have them wired correctly... Not as simple as mapping the other leds was it seems though...

I did find this example, but can't figure out how to adjust the colours as they're a bit extreme. The palettes I could do with help with. How to do the opposite of this ie sunset Then how to trigger it all from my modelclock

I use Fastled to get the .show() function but I put the values in the led array for red, green, blue and adjust them by value. One of the fastled source files has a big table of color names and values if you want names.

Having trouble defining gradients and using the solid_fill function...

Would happily pay someone for a zoom tutorial on this, is that possible?

I have no experience with FastLED, but with some assistance by google this may probably help:

The declaration of HeatColors_p at github -> colorpalettes.cpp can be found around line 149:

extern const TProgmemRGBPalette16 HeatColors_p FL_PROGMEM =
{
    0x000000,
    0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000,
    0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00,
    0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFFFFFF
};

You may copy this into your sketch, change the name (e.g. to myHeatColors_p), adjust the 0xRRGGBB entries and refer to this palette:

 CRGB color = ColorFromPalette(myHeatColors_p, heatIndex);

If "how to do the opposite" means to reverse the illumination sequence, just try changing the sketch you linked in post #49 as follows:


... 

 // current gradient palette color index
  static uint8_t heatIndex = 255; // start at 255

...

  // slowly decrease the heat
  EVERY_N_SECONDS(interval) {
    // stop decrementing at 0, if you do not want start with 255 again
    if(heatIndex > 0) {
      heatIndex--;
    }
...

So this is what I have so far...

Next step is get it in working with the modelclock..


#include <FastLED.h>

#define NUM_LEDS 30
#define LED_PIN1 6
#define LED_PIN2 7

CRGB leds1[NUM_LEDS];
CRGB leds2[NUM_LEDS];

uint8_t paletteIndex = 0;

DEFINE_GRADIENT_PALETTE( SummerSunset_gp ) {
    0,   0,  0,  0,
    0, 163, 23,  1,
   33, 206, 34,  5,
   70, 255, 48, 17,
   95, 255, 45, 31,
  100, 255, 44, 52,
  106, 249, 40, 23,
  122, 244, 37,  7,
  137, 249, 65,  6,
  163, 255,100,  4,
  207, 100, 44,  3,
  255,  22, 11,  3};



DEFINE_GRADIENT_PALETTE( honeycomb_gp ) {
    0,   0,  0,  0,
   31,   7,  1,  0,
   63,  45,  4,  0,
   97, 100, 16,  0,
  131, 186, 36,  0,
  149, 220, 56,  0,
  167, 255, 81,  0,
  181, 255,112,  1,
  196, 255,151,  1,
  204, 252,175,  1,
  211, 249,201,  0,
  227, 249,219, 20,
  243, 252,239,115,
  249, 252,246,178,
  255, 255,255,255};


CRGBPalette16 myPal = honeycomb_gp;
CRGBPalette16 myPal2 = SummerSunset_gp  ;

void setup() {
 FastLED.addLeds<WS2812, LED_PIN1, GRB>(leds1, NUM_LEDS);
 FastLED.addLeds<WS2812, LED_PIN2, GRB>(leds2, NUM_LEDS);

}


void loop() {

sunrise();
sunset();
FastLED.show();
}


void sunrise()
{

  static const uint8_t sunriseLength = 6;
  static const uint8_t interval = (sunriseLength * 60) / 256;

  static uint8_t heatIndex = 0;
  CRGB color = ColorFromPalette(myPal, heatIndex);
  fill_solid(leds1, NUM_LEDS, color);

EVERY_N_SECONDS(interval) {

  if(heatIndex < 255) {
    heatIndex++;
  }
  }
}



void sunset()
{

  static const uint8_t sunsetLength = 6;
  static const uint8_t interval2 = (sunsetLength * 60) / 256;

  static uint8_t heatIndex2 = 255;
  CRGB color2 = ColorFromPalette(myPal2, heatIndex2);
  fill_solid(leds2, NUM_LEDS, color2);

EVERY_N_SECONDS(interval2) {

  if(heatIndex2 > 0) {
    heatIndex2--;
  }
  }
}
 
 

Another problem I now need to solve... After the sunrise transition.. How can I get those leds to turn off when they reach heatIndex 255?

I tried another if statement with a black colour palette, and even just a solid_fill to black but neither worked... Stumped once again

At what value of "heatIndex do your LEDs switch off?

If you have your board connected to a PC via Serial you can easily put

Serial.begin(115200);

in the setup() routine and put

Serial.println(heatIndex); // heatIndex in sunrise() or heatIndex2 in sunset();

just before or behind the line fill_solid(..) . Open the serial monitor and check at which value you find the "darknessValue" you are looking for :wink:

Then it should be only

  static uint8_t heatIndex2 =  darknessValue; // 
  CRGB color2 = ColorFromPalette(myPal2, heatIndex2);
  fill_solid(leds2, NUM_LEDS, color2);

As I stated, I cannot test this, but from what I see in theory this should work ... (which you may prove or not ...). In addition I also had to find out whether the way you define the gradients is ok. For me it would be easier and more safe to change the hex data in the TProgmemRGBPalette16 example above ... As it is getting late now in Europe I will quit ...

Good luck!

I figured out the above with fill_solid to black and an if statement. I had it working on its own. Then i had it working on its own with the clock.

Then i put it together with the three 'sun' lights i had previously programmed to the clock. It works fine until the first 'sun' light turns on, then the strips start going crazy. Flashing multiple colours.

If someone can check to see if one part of my code is interfering with another i would appreciate it so much...This is the 4th day of working to get this and i feel like im so close..

#define sun1 2
#define sun2 3
#define sun3 4
int timeA = 6;
int timeB = 11;
int timeC = 12;
int timeD = 15;
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 timeInit = 0;
int x = 4;


#define ProjectName "Help with LEDs on model railway project"

constexpr unsigned long ModelTimeSkale  {1000}; // time in msec = 1 minute in real world

// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
struct CLOCK {
  byte hours;
  byte minutes;
  unsigned long duration;
  unsigned long stamp;
} modelClock{0, 0, ModelTimeSkale, 0};

#include <FastLED.h>

#define NUM_LEDS 30
#define LED_PIN1 6
#define LED_PIN2 7
#define BRIGHTNESS  80


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 setup() {
  Serial.begin(9600);
  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
  pinMode (sun1, OUTPUT);
  pinMode (sun2, OUTPUT);
  pinMode (sun3, OUTPUT);
  //FastLED
 FastLED.addLeds<WS2812, LED_PIN1, GRB>(leds1, NUM_LEDS);
 FastLED.addLeds<WS2812, LED_PIN2, GRB>(leds2, NUM_LEDS);
 FastLED.setBrightness(BRIGHTNESS );
}

void loop () {
  currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
  if (currentTime - modelClock.stamp >= modelClock.duration) {
    modelClock.stamp = currentTime;
    ++ modelClock.minutes %= 60;
    if (!modelClock.minutes)  ++ modelClock.hours %= 24;
    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.println(" o´clock");
  }

  //LED1
  {
    int brightness = map(modelClock.hours, timeA, timeB, 0, x);
  int brightness2 = map(modelClock.hours, timeC, timeD, x, 0);

if (modelClock.hours == 00)
{
  analogWrite(sun1, 0);
}
if (modelClock.hours >= timeA && modelClock.hours<= timeB )  
    {
      analogWrite(sun1, brightness);
    }
    if (modelClock.hours > timeB && modelClock.hours < timeC)
    {
      analogWrite(sun1, x);
    }
if (modelClock.hours >=timeC && modelClock.hours<= timeD)
{
  analogWrite(sun1, brightness2);
}
if (modelClock.hours >=timeD && modelClock.hours<= 24)
{
  analogWrite(sun1, 0);
}
 
  }
    //LED2
  {
    int brightness3 = map(modelClock.hours, timeE, timeF, 0, 20);
  int brightness4 = map(modelClock.hours, timeG, timeH, 20, 0);

if (modelClock.hours == 00)
{
  analogWrite(sun2, 0);
}
if (modelClock.hours >= timeE && modelClock.hours<= timeF )  
    {
      analogWrite(sun2, brightness3);
    }
    if (modelClock.hours > timeF && modelClock.hours < timeG)
    {
      analogWrite(sun2, 20);
    }
if (modelClock.hours >=timeG && modelClock.hours<= timeH)
{
  analogWrite(sun2, brightness4);
}
if (modelClock.hours >timeH && modelClock.hours<= 24)
{
  analogWrite(sun2, 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(sun3, 0);
}
if (modelClock.hours >= timeI && modelClock.hours<= timeJ )  
    {
      analogWrite(sun3, brightness5);
    }
    if (modelClock.hours > timeJ && modelClock.hours < timeK)
    {
      analogWrite(sun3, x);
    }
if (modelClock.hours >=timeK && modelClock.hours<= timeL)
{
  analogWrite(sun3, brightness6);
}
if (modelClock.hours >timeL && modelClock.hours<= 24)
{
  analogWrite(sun3, 0);
}
 
  }      

FastLED.show();


 if(modelClock.hours>=6){
sunRise();
}
if(modelClock.hours >= 18){
  sunSet();
  }
}
void sunRise()
{

  static const uint8_t sunriseLength = 6;
  static const uint8_t interval = (sunriseLength * 60) / 256;

  static uint8_t heatIndex = 0;
  CRGB color = ColorFromPalette(myPal, heatIndex);
  fill_solid(leds1, NUM_LEDS, color);

EVERY_N_SECONDS(interval) {

  if(heatIndex < 255) {
    heatIndex++;
  }
}
if(heatIndex==255){
 fill_solid( leds1, NUM_LEDS, CRGB::Black);
}
}

void sunSet()
{

  static const uint8_t sunsetLength = 6;
  static const uint8_t interval2 = (sunsetLength * 60) / 256;

  static uint8_t heatIndex2 = 255;
  CRGB color2 = ColorFromPalette(myPal, heatIndex2);
  fill_solid(leds2, NUM_LEDS, color2);

EVERY_N_SECONDS(interval2) {

  if(heatIndex2 > 0) {
    heatIndex2--;
  }
  }
}

CRGB elements have 3 bytes, .red, .green, .blue, and you seem to think use 4?

Fastled -- CGRB Class

Make all of your times millis and use const unsigned longs to name and hold special values like Hour (3600 seconds * 1000 millis/sec) and Day (86400000).

Arduino unsigned long counts from 0 to over 4 billion, takes 49.71-some DAYS to roll over, that is the longest interval you can count with millis(). As long as you do the -unsigned subtraction-, the same code works through rollover or not. An hour or day is some number of millis.

In 24x time, an hour is 60000 real ms.

Take some working on morphing RGB to different RGB in millis timed steps first.
You have + or - possible changes to make on 3 colors at once. To set up, you have variables to hold how much change each needs to complete the change in X (say 60) steps. If red goes from 30 to 200, that's 170 in 60 steps, red+3 per step limited to 200.

Then you can set a CRGB (3 bytes) color for every hour in an array of hours and morph on time, program only needs to run by the model hour.

You do know what an array is?

Thanks for your replies. Going to try respond to them now.

A lot of what i was trying with the palettes came from this video series, specifically the below link. In it he uses palettes and calls them with the crgb function. They have 4 values as i believe they are using the hue value as well?

https://www.youtube.com/watch?v=Ukq0tH2Tnkc&ab_channel=ScottMarley