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


2051 posts

Uber Geek


#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.







My thoughts are no longer my own and is probably representative of our media-controlled government

Create new topic
20 posts


  #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


Backblaze Unlimited Backup. World’s easiest cloud backup. Get peace of mind knowing your files are backed up securely in the cloud (affiliate link).
26418 posts

Uber Geek


  #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.




145 posts

Master Geek


  #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++) {







2051 posts

Uber Geek


  #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.





My thoughts are no longer my own and is probably representative of our media-controlled government

Create new topic

News and reviews »

New Air Traffic Management Platform and Resilient Buildings a Milestone for Airways
Posted 6-Dec-2023 05:00

Logitech G Launches New Flagship Console Wireless Gaming Headset Astro A50 X
Posted 5-Dec-2023 21:00

NordVPN Helps Users Protect Themselves From Vulnerable Apps
Posted 5-Dec-2023 14:27

First-of-its-Kind Flight Trials Integrate Uncrewed Aircraft Into Controlled Airspace
Posted 5-Dec-2023 13:59

Prodigi Technology Services Announces Strategic Acquisition of Conex
Posted 4-Dec-2023 09:33

Samsung Announces Galaxy AI
Posted 28-Nov-2023 14:48

Epson Launches EH-LS650 Ultra Short Throw Smart Streaming Laser Projector
Posted 28-Nov-2023 14:38

Fitbit Charge 6 Review 
Posted 27-Nov-2023 16:21

Cisco Launches New Research Highlighting Gap in Preparedness for AI
Posted 23-Nov-2023 15:50

Seagate Takes Block Storage System to New Heights Reaching 2.5 PB
Posted 23-Nov-2023 15:45

Seagate Nytro 4350 NVMe SSD Delivers Consistent Application Performance and High QoS to Data Centers
Posted 23-Nov-2023 15:38

Amazon Fire TV Stick 4k Max (2nd Generation) Review
Posted 14-Nov-2023 16:17

Over half of New Zealand adults surveyed concerned about AI shopping scams
Posted 3-Nov-2023 10:42

Super Mario Bros. Wonder Launches on Nintendo Switch
Posted 24-Oct-2023 10:56

Google Releases Nest WiFi Pro in New Zealand
Posted 24-Oct-2023 10:18

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.