Geekzone: technology news, blogs, forums
Guest
Welcome Guest.
You haven't logged in yet. If you don't have an account you can register now.


SepticSceptic

2263 posts

Uber Geek
+1 received by user: 779

Trusted

#298809 18-Jul-2022 14:59
Send private message

I have a Small Model Railway, 15 buildings, all with 1 LED, some with 2.
All connected with an Arduino Nano and a  TLC5974 24 channel PWM controller. I used PWM so I could set the desired brightness, rather than trying to tweak resistor values.
Extra, higher drain LED chains, such as street lights, are driven via the Arduino I/O pins via a ULN2003 driver board.
These are all working in  a demo mode, sequencing from one to the next, with 1024 step PWM ( 4 steps to full bright)
I'm looking for a smarter way to setup a 24-hour lighting sequence (compressed into an hour or two), but not sure as to the most appropriate program flow structure to choose.
Normally, I'd set one LED, use delay(xxxx) and then move to the next , but that's not efficient, and I'd probably run out of program space

 

For Next loops ?
While Wend ?
Do While ?
Matrix/Array ?

 

I was thinking something like defining the name, then the start time, end time and brightness. - 4095 is full brightness.

 

DEFINE Farmhouse_interior, 1800,2300,4095
DEFINE Farmhouse_exterior, 1900,2100,2048

 

Would this need the use of a timer or interrupt ?

 

Or something totally different?

 

I'm pretty much at the absolute beginner stage of C programming, other than tweaking existing Arduino sketches, that's about it ..

 

Looking for some pointers(?) to overcome the initial hurdle.

 

Cheers

 

SS.

 

 


Create new topic
MrMatt
27 posts

Geek
+1 received by user: 4


  #2943519 18-Jul-2022 16:39
Send private message

Hi SS,

 

You're on the right track with timers and interrupts - that would likely do it. I haven't used interrupts on an Arduino though (although I've used them on other embedded C micros).

 

The other thing that you could do is use the Arduino millis() function.  This basically returns the number of milliseconds since startup. If you continuously check for millis() in the main loop section, you could respond based on this. I can't guarantee this is the most efficient coding, but I can't see why it wouldn't work...

 

For instance, say you wanted it compressed into 2 hours:

 

24hours in a normal day / 2 hours = 12 times as fast. Therefore, your virtual time since startup would be 12*millis()  / 1000 / 60 to get it into virtual minutes for instance, and store this in an unsigned long (e.g I'll call this time). Make sure that time doesn't go above 24*60 = 1440 minutes by applying a modulo command (If the time variable increases to 1450 minutes for instance, the modulo command turns this to 10 - pretty much just the remainder of the division operation.)

 

From here, take this time variable, and apply some math function to it to calculate the PWM duty required. Or if you only want the lights to change at certain times, use a couple of if / else if functions

 

In summary, here's some rough pseudo code:

 

 

unsigned long timeMinutes;

 

int hour;

 

int minute;

 

int compressedHours = 2; //Number of hours you want to compress a day into

 

int multiplier = 24/compressedHours;

 

void setup(){

 

//All your setup stuff

 

}

 

void loop(){

 

time = multiplier * millis() /1000/60;

 

time = time%1440; //1440 minutes in a day. Note this is the time of day in minutes

 

hour = time/60; //Should give the hour of the day

 

minute = time%60; //Should give the minute of the hour

 

//Do some math with the above to set you PWMs as needed, e.g:

 

if(hour>=18 && hour <23){

 

//set pwm to 4095

 

}

 

else if ...

 

}

 

 

 

 

Hopefully this helps! Apologies for the rough code




richms
29104 posts

Uber Geek
+1 received by user: 10217

Trusted
Lifetime subscriber

  #2943522 18-Jul-2022 16:52
Send private message

I had typed something that seemed to disappear. Grrr.

 

Anyway, Friend did this, there was a scheduling library that he found that just needed multiplication put somewhere in it to make 24 hrs take about 10 mins to cycle thru.

 

Library had objects get made for each device that was being controlled - I haven't done object stuff in arduino beyond modding examples so not sure how it went, the objects had times put on them and then triggered at that time on those days.

 

Used an ESP board, as it had wifi, moved to MQTT later on from either home assistant or node red to drive the flow along with controlling other lighting.

 

Used neopixel like pixels - warm white/white/amber LEDs on a little board inside each building so all off 1 pin.

 

I was only involved in the wiring side of it as he had no clue with soldering irons, good on the painting and sculpting and coding tho.

 

 





Richard rich.ms

nova
260 posts

Ultimate Geek
+1 received by user: 143

Trusted

  #2943560 18-Jul-2022 20:19
Send private message

I agree with the answers above, and to add to them, my preference would be to store you light definitions in an array like the example below. Once you have them this way you could use with a scheduler library, or do the math yourself

 

 

struct LightSchedule {

 

int pin;

 

int start;

 

int end;

 

int brightness;

 

};

 

 

 

LightSchedule myLights[] = {

 

{ 1, 1800,2300,4095 },  // farmhouse interior

 

{ 2, 1900,2100,2048 }, // farmhouse exterior

 

{ -1, 0, 0, 0} // sentinel value to mark end of array, always keep as last value and check for -1 when looping through array

 

};

 

 

 

for (int i =0; myLights[i].pin != -1; i++) {

 

  schedule.add(myLights[i]);

 

}

 




SepticSceptic

2263 posts

Uber Geek
+1 received by user: 779

Trusted

  #2944372 20-Jul-2022 16:50
Send private message

Many thanks for all your replies, a great starting point.

 

This will probably take me a while to work through, and I probably should be smart about things and get the pseudo-code / structure out first.

 

Again, thanks for the ideas.

 

 

 

SS


Create new topic








Geekzone Live »

Try automatic live updates from Geekzone directly in your browser, without refreshing the page, with Geekzone Live now.



Are you subscribed to our RSS feed? You can download the latest headlines and summaries from our stories directly to your computer or smartphone by using a feed reader.