Jump to content

YukariLED lighting control


Recommended Posts

This is a description of the LED controller I have designed for my layout. I call it YukariLED.


After starting to fit some buildings with lights, I quickly realised that I would need hundreds of light points for the layout. I also wanted these light points to be easily controllable to implement effects such as flashing lights, or be able to automatically switch on and off during the virtual day and night (I also have a programmable LED strip on the "ceiling" to generate day, dusk, night and dawn light effects).


This is the system I have designed. I found these modules from Adafruit: https://learn.adafruit.com/tlc5947-tlc59711-pwm-led-driver-breakout/overview

And the link to purchase the modules: https://www.adafruit.com/product/1455

After testing, I purchased 25 TLC59711 modules. Each can control 12 separate LEDs, each with a 16-bit PWM output. The modules are connected in daisy chain to a Raspberry Pi. The interconnection cables are standard 5-pin Dupont lines and can be purchased in various lengths from AliExpress (look for 2.54MM Wire Dupont Line 10cm/20cm/30cm female to female).



The module outputs are PWM (Pulse Width Modulation) outputs, meaning that you can control the LED's intensity by software, with 65536 levels, from off to full brightness.


The module outputs are current outputs (not voltage). This means that the module automatically computes and applies the voltage required to reach the desired current. Each output provides 15 mA (default value), and will never provide more current. This means that it is now impossible to burn LEDs! And no need to add resistors in series with the LEDs. As my power supply is 12 V, I can connect up to 3 LEDs in series to a single output, I can also connect short LED strips.


I have scattered the modules around the layout. I now have 15 of them (out of 25) installed for a total of 15 x 12 = 180 LED points. Some buildings (like to main station) have two modules inside.


The Adafruit page describes how to control the LEDs individually. In my case I use a program written in Python. Along the years, I have improved the user interface to include a touch screen but I will describe this in another post.


These are photos of the latest building I have fitted with lights. We can see the wires connected to the LEDs going down to the light module. Wiring LEDs is now actually pretty simple! After experimenting, I found out that in most cases LEDs have to be set to around 10% of their full brightness to be suitable for photos. This means just about 1 mA in average per LED!





Edited by Madsing
Corrected link
  • Like 8
  • Thanks 1
Link to comment

This is a schematic of the system. The Raspberry Pi is in the middle. The Adafruit modules are on the right (3 are shown here). On the left, I have added an INA219 module that allows the Raspberry Pi to monitor the overall power consumption of the LEDs.

We see that just four wires (out of the 5-pin connectors) are required to link the modules to the Raspberry Pi. Two of them are the power supply (+12V in my case), the other two are the SPI communication bus.

Screenshot 2019-06-13 at 8.51.03 PM.png

  • Like 2
Link to comment



excellent! Love this and something I’ve been dreaming of doing for lighting. The micro and chip arduinos are perfect for this and controlling them from a raspberry pi perfect! I really want to automate lighting levels without having to set a ton of pots and do it remotely till it’s just right. Also want to turn some lights on and off randomly to give the building some life. Also want to be able to set a day and night light level as day lighting (most building have a lot of internal lighting in the day) needs more to be visible at scale than what is needed at night. The arduinos are perfect for this and the Adafruit are nicely interconnectable.


yep my experience usually is 1ma range is right for lighting.


want to dive in someday when I have time to really get this done! Thanks for posting this, will look forward to more details!





Link to comment

The buildings are fantastically well done in any possible way, not only the light effects but the details added and the light weathering applied are spot on.

  • Like 2
Link to comment

These are a few photos of the Raspberry Pi controlling the LEDs.




Once this is in place, it is possible to control the brightness of any of the LEDs connected to the TLC59711 modules through software commands called by the Raspberry Pi.


One way is to use the Adafruit Python library provided with the modules. I didn't use it in my application as it was not available yet at that time. Instead, I directly drive the SPI bus using the standard SPI library. Either way, you end up with a function like SetLEDBrightness(module, port, brightness) that allows to set the brightness of the led connected to the given port (0 to 11) of a given TLC59711 module.


From there, it is possible change the brightness of the LEDs over the time and create interesting effects (there is no limit here 😀). This is what I have done:

  • Day/night transitions
  • Flashing LEDs (with slow on/off/on transition to simulate large spotlights)
  • LEDs inside buildings randomly switching on and off during the day/night transition
  • Neo lights flickering


My Raspberry Pi is connected to a 5” capacitive touch display for the user interface. Choose a HDMI display as the Raspberry Pi SPI bus is already used for connecting the TLC59711 modules. I use a 52Pi 5 inch 800*480 Display Capacitive Touch Screen Monitor for Raspberry Pi/PC Windows Plug & Play available from AliExpress.


In addition, I use the tkinter package (https://wiki.python.org/moin/TkInter) to manage interactions with the user, i.e. icons, buttons. tkinter also contains a basic scheduler that allows to automatically call functions at programmable time intervals, very useful.




All this is illustrated in the following video:




  • Like 3
Link to comment
On 6/14/2019 at 8:08 AM, Khaul said:

The buildings are fantastically well done in any possible way, not only the light effects but the details added and the light weathering applied are spot on.

Thank you, Jeff and Khaul  😀

Edited by Madsing
Link to comment



The first version of the lighting I used for my Yukari layout was a standard RGB LED strip controlled by a TLC59711 PWM LED driver as described in the previous post. I thought that using this LED strip would provide adequate “white” lighting for daylight plus red and blue for sunset and night effects. It didn’t work well. It appeared that the shade of white that I could get from this kind of light strip is far too blue and all photos taken showed a very clear blue color cast.




Then, I decided to add a warm white LED strip next to the RGB one. With four channels (red, green, blue and white), I thought I could use white for daylight and red plus blue for sunset and night lighting. At that time, only warm white and cool white LEDs were available and after my bad experience with cool white I chose warm white. This again proved to be a wrong choice. Warm white is too yellowish compared to the natural sunlight I get during the day. Some structures such as the car park building where I used cool white LEDs to simulate neon lighting then appeared very blue on photos.


Last year, I saw a new kind of LED appear on the market: natural white. The shade of white of natural white LEDs is between warm white and cool white, and they are described as very close to natural daylight, hence their name. I wanted to keep the ability to simulate sunset, night and dawn and about a month ago I purchased a 5-meter RGBNW (red, green, blue, natural white) LED strip. This time, I chose a strip of individually controllable LEDs. This type of LED strip has three pins: +5V and GND for the power supply, and DI (data in) which is a digital serial signal that transmits to each LED the level of brightness it should take. Each LED receives a 32-bit command, 8 bits for red (256 levels), 8 bits for green, 8 bits for blue and 8 bits for white. Connected to an Arduino (itself connected to the Raspberry Pi controlling the lighting), I can individually control each of the 268 LEDs of my “SkyLED” light.


I purchased this LED strip from AliExpress. Look for "SK6812 RGBW led strip" (SK6812 is the name of the chip/protocol).

Link to SK6812 RGB LED Strip on AliExpress




I installed and tested these new LEDs last week. First conclusion: natural white is great. It is the right balance between cool white and warm white. In this one-minute video, I recorded the day to night transition as it is programmed now. First, sunset with orange and red hues, then night and moonlight with blue hues. My phone struggled a bit when capturing this video. It constantly tries to adjust its white balance so the effect is actually more subtle than it appears on the video.


My layout currently has no backdrop, and none of the buildings on the background has been detailed or lighted.



Many things remain to be done. Today, I don’t really take advantage of the fact that each LED is individually controllable. In the future, I plan to experiment with that feature, and (possibly) simulate moving clouds, or more directional lighting such as sunset from west and moonlight from east.


I also dream of installing a lighted backdrop, and being able to control its color.



Edited by Madsing
Corrected typos
  • Like 6
Link to comment

Very nice. I remember an article a few years back when rob leds strips were coming out of someone doing a lot of research on getting sunrise/sunset transitions just right. I think they were using a white balance meter to actually record some to get the subtle color changes. Changes a lot with atmospheric conditions and scene. I’ll look for the link or if I downloaded it.


The individually controllable leds are very cool. I have a 1m strip and a hardwired controller awhile back to mess with. I want to try some fiber optics to make some flash lighting on a dekotora truck and maybe a building.





Link to comment

I’ve not found it yet but I’ll go look on the old browser bookmarks and files. 


This bloke was trying to get the light that ends up lighting a scene with sunrise/sunset and not what you see in the sky looking at the sunrise or sunset. While intuitively it would seem that the orange looking sunset we should be awash in light that color, a lot of the light around us on the ground is also stuff reflected off other stuff (clouds, atmosphere, physical stuff around you on the ground) that end up changing the color and this is what he was trying to measure of what was bouncing off a whiteboard.


he had the same issue of trying to use warm and cool led strips to do his very long display box type layout (it was all the walls in like 2 good sized room so very long strip to illuminate). He had some mix of a few strips that was ok and the. He added rob strips to ad a bit of tinting to get it just right and play with his sunrise and sunset. This was like 10 years ago. He was really determined to get as realistic as possible.



Link to comment

This post really brings it all together. I'm going backwards in posts and just in awe. I'll have to try this out as well. I don't even have a permanent layout and I want to try it.


Do you know off hand if you can control a "flicker". I see mostly on/off/dimming, but say for misbehaving fluorescents or street lamps.


Also, as I mentioned in the other thread, I'd love to get my hands on your code. 😂



Link to comment

Thank you!

I have reactivated my Gihub account yesterday and I will post the Python code soon.

Yes, simulating misbehaving fluorescent street lamps should be possible. In the code, each light is defined with one line of code, which specifies the attributes of that light. A few examples:


{'name': 'Parking ceiling light 5 (top left)', 'mode': 'Constant', 'value': 300, 'module': 2, 'port': 2}

Meaning: The light called 'Parking ceiling light 5 (top left)' which is connected to the port #2 of the module #2, is constantly 'on' with a value of 300 (the maximum brightness is 1000).


{'name': 'Maintenance office parking lamp posts', 'mode': 'Random Day/Night', 'value_night': 200, 'value_day': 0, 'module': 6, 'port': 4},
Meaning: The light called 'Maintenance office parking lamp posts' which is connected to the port #4 of the module #6, will take the value 200 during the night and 0 (off) during the day, it will switch between day and night (and day) at random times.


{'name': 'Tower 1 red warning',  'mode': 'Cycle', 'time': [0.0, 2.0, 2.3, 2.7, 3.0], 'value': [300, 300, 0, 0, 300], 'module': 0, 'port': 4},
Meaning: The light called 'Tower 1 red warning' which is connected to the port #4 of the module #0, will take the value 300 (the maximum is 1000) at time 0 (seconds), stay at 300 for two seconds, then switch off (value zero) between the time 2.0 and 2.3 seconds, and so on...


As you can see, it is possible to define fairly complex lighting sequences.


  • Like 2
Link to comment

The Raspberry Pi code of this project is available in this Github repository: https://github.com/madsing98/YukariLEDP

It is Python 3 code divided into two files:

  • LEDController.py: This is the main program.
  • light_list.py: This file contains the list of the lights with their parameters.

In the same repository, you will find light_list_table.txt, which is a text file generated by the application. It is used for debugging only and lists all lights sorted by module and port. 

The other files are the resources: the gif files for the icons and the Roboto-Light true type font file.




This file defines a table containing the attributes of the lights to be controlled.
It is a python list declared by light_list = [light1, light2, light3, …]. Each element is a dict (python dictionary) containing the parameters of that light. Python is very flexible and different lights may have a different set of parameters.


For example:
light_list = [{'name': 'U/G left', 'mode': 'Constant', 'value': 0, 'value_on': 1000, 'switch': 'Switch 0', 'module': 0, 'port': 6}]
defines a list of one element (one light). The parameters of this light are:

  • name = 'U/G left'
  • mode = 'Constant'
  • value = 0
  • value_on = 1000
  • switch = 'Switch 0'
  • module = 0
  • port = 6


Other examples:
{'name': 'Parking ceiling light 5 (top left)', 'mode': 'Constant', 'value': 300, 'module': 2, 'port': 2}
Meaning: The light called 'Parking ceiling light 5 (top left)' which is connected to the port #2 of the module #2, is constantly 'on' with a value of 300 (the maximum brightness is 1000).
{'name': 'Maintenance office parking lamp posts', 'mode': 'Random Day/Night', 'value_night': 200, 'value_day': 0, 'module': 6, 'port': 4}
Meaning: The light called 'Maintenance office parking lamp posts' which is connected to the port #4 of the module #6, will take the value 200 during the night and 0 (off) during the day, it will switch between day and night (and day) at random times.
{'name': 'Tower 1 red warning',  'mode': 'Cycle', 'time': [0.0, 2.0, 2.3, 2.7, 3.0], 'value': [300, 300, 0, 0, 300], 'module': 0, 'port': 4}
Meaning: The light called 'Tower 1 red warning' which is connected to the port #4 of the module #0, will take the value 300 (the maximum is 1000) at time 0 (seconds), stay at 300 for two seconds, then switch off (value zero) between the time 2.0 and 2.3 seconds, and so on...




LEDController.py is the main program. Execute it with the command ‘python3 LEDController.py’.

  • It is based on the tkinter library (https://wiki.python.org/moin/TkInter), which is used for the GUI (graphical user interface) and for sequencing operations.
  • The GUI uses the 800 x 480-pixel display (connected to the HDMI port)
  • The application uses the SPI bus of the Raspberry Pi along with the ‘spidev’ library to send messages to the TLC59711 modules.
  • It uses an INA219 DC Current Sensor connected to the i2C interface of the Raspberry Pi to measure the total current consumption. The INA219 module is configured at line 57. If no module is detected, the variable ‘ina219Present’ is set to ‘False’ and the module is not used.
  • The application detects if it is running on a Raspberry Pi (line 10: sys.platform == 'linux') or not. If not, the variable ‘InSitu’ is set to ‘False’ and the TLC59711 modules and INA219 modules are not accessed. I use that feature to develop and debug the user interface on my Mac as it is much more confortable than the Raspberry Pi.

The main parts of the program are:

  • Line 1: Imports
  • Line 22: Definition of the GUI-related variables
  • Line 46: Initialization of the INA219 module
  • Line 63: Initialization of the SPI bus
  • Line 73: Initialization of tkinter, creation of the tkinter main window and frames.
  • Line 109: Initialization of the message (LEDCommand) to be sent to the TLC59711 modules. The variable NumberOfLEDModules must be set to the number of TLC59711 modules connected to the SPI bus.
  • Line 140: The function SetLEDBrightness(led, value) is used to set the light ‘led’ to the given intensity value. The intensity is a number between 0 (light off) and 1000 (light full on). It is gamma corrected in this function (default gamma = 1.8).
  • Line 187: The function RandomizeDayNightTime() computes the values and (random) times of the sequences for all 'Random Day/Night' LEDs.
  • Line 206: The function UpdateLED(c_time, led) computes the intensity of the light ‘led’ based on the current time ‘c_time’.
  • Lines 248-736: Management of buttons and events
  • Line 739: Beginning of the program and main loop
  • Thanks 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...