Help with LEDs on model railway project

You are welcome. I´m 60++ and enjoy coding in C++.
Lay back and rethink about my explantion given.
Have nice day.

modelClock.stamp = currentTime;
    if (currentTime =(modelClock.minutes = 0 , modelClock.hours = 2))
  digitalWrite (LED1, HIGH);
  else digitalWrite (LED1, LOW);

Nope, still not there... and now i do need to lay down, maybe a nights rest will let my brain come up with the solution. Otherwise feel free to dangle the carrot a bit lower.. :sweat_smile:

The fields in the struct that @paulpaulson built for you that tell you the time are hour and minute in your accelerated timeframe, which you have clearly deduced. You will need to compare each of them to the time that you want events to happen. You can ignore currentTime, which is really just millis and now irrelevant.

You can check those two time components against whatever time you want something to happen. This will be fine for a few LEDs and a good way to get started. It will however be a disaster when you're trying to control fifty because the code will be long and have time numbers scattered all over it which will make it hard to understand, hard to debug and hard to change.

Once you have got the modelClock turning lights on and off at a time, we can help make it both a little more complex to code, but far easier to maintain and understand.

I´ve made a new edtion of the model clock.
To make the desgn and testing more easy a potentiometer is implemented. This pot generates a time change from min to max simply. This can be used for simulated appearence of a black hole at your model railway too. :nerd_face:

  ATTENTION: This Sketch contains elements of C++.
#define ProjectName "Help with LEDs on model railway project"
constexpr unsigned long ModelTimeSkale  {1000}; // time in msec = 1 minute in real
constexpr byte TimeAcceleratorPin {A5};
constexpr unsigned long TimeAcceleratorMin {1};
constexpr unsigned long TimeAcceleratorMax {1000};
unsigned long currentTime;
struct CLOCK {
  byte hours;
  byte minutes;
  unsigned long duration;
  unsigned long stamp;
} modelClock{0, 0, ModelTimeSkale, 0};

void setup() {
  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
void loop () {
  currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
  if (currentTime - modelClock.stamp >= (unsigned long) map(analogRead(TimeAcceleratorPin),0,1023,TimeAcceleratorMin,TimeAcceleratorMax)) {
    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");

Have a nice day and enjpy coding in C++.

In work for the day now... Won't be able to test any of this until later... Never mind the model world, the coding is turning into a black hole😂

It worked.... :scream:

if (modelClock.hours==2)  
  digitalWrite (LED1, HIGH);

Nice. Progress. How about some minutes in there?

I know only took a few days!

Minutes now too!

if (modelClock.hours==2 && modelClock.minutes==30)  
  digitalWrite (LED1, HIGH);

I'm very impressed altogether, haha

Whats the next step?

I'm thinking trying to get the leds to fade over time now...

You can use analogWrite for fade effects. Just make sure that the LED is connected to a PWM capable pin. They should be marked with a tilda (~).

Then you'll need a bunch of ifs for different times. This will become tedious, and then it will be time for arrays :wink:

I wrote a project before that faded LEDs that i was hoping i would be able to recycle the code for. It did use delays im realising now im looking at it. It was along the lines of..

int brightness =0;
int fadeAmount =1;

analogWrite(led, brightness);
 if (brightness<=0){
brightness = brightness + fadeAmount;

Will this be useful?

*Understand the bit about pwm pins, and have the wall lights hooked up to transistor modules so they are fadeable..

I don't think so. Using delay in your code may compromise the millis controlled model clock - small debouncing ones can be ok, but generally, it'll be harmful.

I suggest that to get things fading, you start out with setting the brightness to several different hard coded levels over perhaps five (virtual) minutes with five separate if statements. Later on, it'll need to be more clever I expect, but see what you can do with it.

Thought as much after starting my millis() journey...

I will try your suggestion now and see how it works?

The other thing i was thinking, and maybe you can tell me why this is not a good idea, could the map function not be used in this instance?

I'm not taking all of everybodys advice for granted, it is very much appreciated and i feel i should follow every message with a thank you! Thank you!

Maybe. I am not sure what your overall design will be. It might be worth separating the control of the three sunlight lamps from the streetlight and house LEDs and you could indeed use map to fade them in and out as the time of day progresses.

The bit I was poking at more earlier is how to generalize control of fifty LEDs. I had been thinking that the sun stuff would be wrapped with that. Maybe that's not sensible. It will no doubt evolve.

if (modelClock.hours==2 && modelClock.minutes==30)  
  analogWrite (LED1, brightness1);
if (modelClock.hours==3 && modelClock.minutes==00)  
  analogWrite (LED1, brightness2);
if (modelClock.hours==3 && modelClock.minutes==30)  
  analogWrite (LED1, brightness3);

So, this does obviously work! Like you said, it's a bit clunky, but at least i understand it! :+1:

Map does work.. Heres an initial attempt...

int brightness = map(modelClock.hours, 2, 10, 0, 15);
if (modelClock.hours == 0 ||modelClock.hours == 1 ||modelClock.hours == 11 ||modelClock.hours >= 12 )
digitalWrite(LED1, LOW);
analogWrite(LED1, brightness);

Need to figure out dim down now..

You didn't take your time to do simpler things first. Learn each thing solid, mess with each project/lesson to stretch it out and find the edges. Only then add the new thing that should have the only unknown in the project. When you have more than one unknown, you can be "fixing" the wrong code.
Write like that. Build the code a part at a time and get it working before adding the next part. The worst thing is to write a huge mass of code and -then- trying to debug the whole, been there, wasted a lot of time days to weeks at a time.

We don't reset the millis clock. We time intervals using unsigned math and we don't have problems timing across rollovers same as with a 12 hour clock we know at 2 that it's been 4 hours since 10.

Interval = End - Start ----- always works to the limit of the timer variable
32-bit unsigned long millis() allows 49.71-some DAYS interval.
32-bit micros() allows over 71 minute intervals

There are 1440000 ms in 24 minutes and 1440 minutes in a day. A 24 minute day's minute is 1000 real ms. Does this give you a nice handle on timing?

PS: RGB leds can let you do sunrise/sunset colors.

I like your suggestion re RGB leds to get the right colours for sunrise sunset. Thinking about how to fit the wiring they would need into the whole scheme of things.

I got map to fade the led up based on the modelclock using, but can't figure out how to get it to fade back down again.

Should i be using for loops?

Same way as fade up. For fade up you picked the hours for the fade and mapped them to zero to fifteen. To do it the other way, pick your hours and map from fifteen to zero.

I did try this, but they seemed to be conflicting with each other.. Confusing each other.. I'll try post an example of my attempt shortly