Introduction: Neighborhood Wide Synchronized LEDs
I had some wireless LED bars that I thought I could put out for the holidays. But, in my yard, they could also just as well have been wired. So, what is the cooler challenge? LED decorations at all the houses on my block with a synchronized display! In this crazy year, it's a way to connect us together.
These are ESP8266 powered LED strands, and they are WiFi mesh connected, so they all show the same step in the animation sequence at the same time. Since they use mesh code to connect, they can be a few houses apart, and the messages are passed along from node to node.
They run on 5 volts, and I used power adaptors, but they can run for awhile on USB batteries too. So they are portable, run their own WiFi network that is not connected to the Internet, and can run off the grid.
All of our neighbors were excited to have this shared decoration, and it's really nice how you see all of them showing the same display as you walk along the street. I have some pictures here of a few in front of my house for testing, but it was really hard to photograph them down the street.
Step 1: Parts
ESP8266 D1 Mini - I used the D1 Mini modules since all I need is one I/O pin for the LEDs. This project could be done with no soldering using a terminal shield like this and a different ESP8266 module. There is a version of the D1 Mini with a better antenna - the D1 Mini Pro. It has a ceramic antenna and a U.FL connecter for an external antenna, but you need to move a surface mount 0 ohm resistor for the external antenna. With the ceramic antenna it has very roughly double the range. More discussion in a later step.
WS2811 LED Strands - I used WS2811 strands since they are waterproof (except for the JST connectors) and easy to work with. WS2812b "Neopixel" strips would use exactly the same code etc. I used 5v ones, but you can get them in 12v (use less current) - you would need a voltage converter for the ESP8266s, then. You can also get WS2811 LED strands with waterproof connectors if you would like. The LED strands I used have JST SM connectors on both ends - the female one is the input, though I have seen them wired the other way (male as input). The direction is also marked on the LEDs themselves. There are also power injection wires - I snipped the ends off so the tinned parts cannot short out. You can also buy them in packs of 10.
330 Ohm 1/4 Watt Resistor - this is used at the data pin on the ESP8266 to prevent any flickering of the LEDs.
JST SM 3 Pin Male Connector - These are to connect to the LED strips. Note that the "male" connector has a hood over it.
2.1mm CCTV Female Connector - these are used for the power connector. You could use some other connector system for this if you want.
5V Power Supply - the amp rating depends on how many LEDs you will have. A 2A one is probably OK for 50 or 100 LEDs that are never fully on (see the wiring step for more info).
JST SM 3 Pin Extension Wire or a 2.1mm extension wire - since the JST connector on the D1 Mini is close to the LEDs, you generally want an extension to allow the LEDs to be placed further away from the CPU. In my case, I ended up putting the CPU higher up in the decoration to get better WiFi range, so I kept the CPU near the LEDs and used a 2.1mm extension wire instead.
USB to 2.1mm Cable - this is optional - lets you power the strand from any USB source or battery.
3mm Heat Shrink Tubing - you only need about 1" of this to cover the resistor on the D1 Mini.
20mm Clear Heat Shrink Tubing - this is partly optional to protect the connectors on the D1 Mini. Make sure to clip around the reset switch after applying if the tubing compresses the switch.
Waterproof Box - to protect the power supply and CPU outside. Most of my neighbors just used plastic bags.
1/2" EMT conduit - a 29" piece fits on the candy cane shape - I used 4 zip ties to hold it on. I tried 1/2" PVC, and it fits, but touches the LEDs on both sides.
3/8" x 3' rebar - once the EMT is attached to the shape, you can pound the rebar in the ground and put the EMT pipe over it. 1/2" rebar will fit, but you will need to cut off any bent parts, and it is close - if it gets flattened or anything when pounding it in, it will be very tight. So, the 3/8" is more likely to easily clear the inside diameter of the EMT pipe.
Candy Cane shape - see the step on these, you can DIY a shape, drape them over a bush, or use a shape like this. You can also get pre-printed ones.
Step 2: Controller Assembly
The controller consists of the D1 Mini (ESP8266), a 2.1mm CCTV female power jack, a 330 ohm resistor, and a 3 Pin JST male connector.
The assumption for this project is that you will use 50-100 LEDs. If you want to use more, you will need to use power injection to power all the LEDs. See this other Instructable for a deeper discussion on that.
With 50 LEDs all on full white, they would draw 50 x 0.06A = 3amps. So, with a 2A adapter, we are assuming they will never be fully on. For 100 LEDs, the max is 6A, so even more care should be taken to only have some on at a time. Even with 100 LEDs at 0.02A each, we have 2 Amps being used. So, a higher current power supply is recommended, though I tuned the displays to not use all the LEDs or colors at once, dimmed them down a lot, and have started with 2A supplies with bigger ones in reserve. This is a great article on reducing power requirements.
The 330 ohm resistor inline with the data wire is to prevent flickering from electronic ringing since the data is a fairly high frequency. This is more of a factor with lots of LEDs, but is a good practice to add it.
I soldered the resistor to the D1 Mini directly, but left about 1/8" of the lead above the board so I could bend them flat. I used about 1" of 3mm heat shrink on the resistor to keep it from shorting out on the board.
I used 20mm clear heat shrink to protect the D1 Mini from touching metal etc. Be sure to check the reset switch on the side - you may need to cut the heat shrink slightly to make sure it in not pressing the switch. I needed that on all of mine.
Note that I did not seem to need a level shifter from the 3.3V ESP8266 outputs and the LEDs running at 5V (since the LED chip spec is to have the data line be no less than 70% of the supply). I did need a diode/sacrificial LED in previous projects (Step 3) with WS2812b strips, but the direct WS2811 chips in the LEDs seem OK so far.
You could do this without soldering! An ESP8266 terminal shield with a different CPU would work just as well. The D1 Mini form factor is nice and small, but they all work about the same.
Step 3: Alternate Controller Build
As described in later steps, a D1 Mini Pro with the ceramic antenna seems to have roughly double the range of the D1 Mini with the circuit board antenna. So, they are much better for the house distances in my neighborhood. Unfortunately, some of the inexpensive D1 Mini Pros I bought did not work with an external 5V power source, but they do work with the USB connector providing power. The D1 Minis do not have a 5v regulator, just a 3.3V one, and the USB to 5V pin has a fuse and a diode. I tried a few diodes, but had no luck with supplying 5V via the pin on the D1 Mini. So, I used a micro USB to 2.1/5.5mm cable to supply the power. This build is actually a bit simpler and works with the defective D1 Mini Pros I have.
Parts: (these links are Amazon Affiliate links, but cost you nothing and help support Instructables like these)
- A D1 Mini Pro - I am not sure which ones were better, but presumably this wiring setup will work with any of them.
- A micro USB to 2.1mm/5mm female plug cable
- A JST 3 pin male (pins + shroud) connector
- A 330 ohm resistor
- 1" of 3mm clear heat shrink tubing - I like clear now so you can see the resistor later.
- 1.5" of 20mm clear heat shrink tubing - this is optional.
- A 3" x 4" plastic bag and twist tie - I used these with all the controllers
The Build:
The JST wires had tinned ends, so soldering the +5 (red), and Gnd (white) to my Di Mini Pro was easy. I ran the wires from the back side and soldered them on the component side.
The resistor goes on Pin D6 for my code, and solder it with just a bit of wire above the board so it can be bent over later. I stripped and twisted the green wire from the JST cable on the other end of the resistor and soldered it close to the resistor. Make sure to put the 3mm heat shrink tubing on first!
With those 4 soldered connections done, you can shrink the 3mm heat shrink tubing and test.
Use the 20mm heat shrink tubing if you want to protect the board though in retrospect, putting it in the bag may be sufficient. Make sure to leave the micro USB port available, and watch out for the heat shrink around the reset switch. Also, I ran the wires all one one side by the switch to not block the USB port.
Once the D1 Mini Pro is programmed, you can add the micro USB to 2.1/5.5mm cable and place it in a bag with a twist tie for protection, or use some other waterproofing setup.
Step 4: Shapes
The LED strands can be free-form, or you can make them into shapes - either DIY, or from an online store. I ordered a few shapes from HolidayCoro - some small LED trees, a stocking, and a candy cane. The stocking took 50 LEDs nicely - the length of one strand. The small tree takes 100 LEDs, but you can just do half of it if you want - facing the street. In the end the candy cane was the neighbor favorite since it was a bit larger. 99 LEDs, and I left the last one on the back with the idea it could be used for debugging.
Since the shapes came in white, we decided to paint red stripes on them so they look better in the day time. I masked them out, did a quick fine sand, a wipe with acetone (full strength nail polish remover), and used two coats of spray paint that works on plastic. It seemed to adhere well. We did mostly on one side, and a few on the other side for a couple houses that had 2 of them.
Step 5: Code & WiFi
The D1 Mini uses an Espressif ESP8266 module. I programmed it using the Arduino IDE, so it feels like a powerful Arduino with WiFi built in. There are numerous instructions on the Internet on how to configure the Arduino IDE for the ESP8266 and D1 Mini so I will not repeat them here.
The code is based on a previous Instructable. It uses the Painless Mesh library to have all the CPUs talk to each other. I used the FastLED library since I had issues previously with the mesh library and the Neopixel library, and I did not re-test that this time.
I am not sure what the maximum is on the number of nodes. Some posts indicate that it will be limited by the number of messages and CPU types and maybe the cap is around 30-60 nodes. This application does not send a lot of messages - just the animation change, though there are some automatic ones like mesh change and time synch messages.
You can connect the LEDs to the D1 Mini while coding, but you may want an external supply if you have more than 50 since you will possibly exceed the supply from your computer's USB port and the power regulator on the D1 Mini. That being said, with my code not turning the LEDs on full, I was able to program 100 LEDs on the USB connection without issues.
The ESP8266 module has onboard WiFi. Since the mesh code (PainlessMesh) we are using creates an Access Point on each module, the range for a neighborhood wide reach is important. I used candy cane shapes, and put the CPU at the top to get the best range, and it was about 50-100 feet - a yard or two in my neighborhood. Higher and better line of sight (LOS) improves things. The range did cross the street in some cases (depended more on cars blocking the LOS).
There were a couple houses that were not synched due to WiFi obstructions, but the lights look nice even when not synched. I made a "repeater" node with just a D1 Mini on a stick powered by a USB battery. When placed between the houses, they were synched properly. For a more remote repeater you could possibly use a solar USB battery, though they do not charge very fast.
I was still seeing intermittent synchronization issues, then found this note on having too many nodes or having them spread out:
https://gitlab.com/painlessMesh/painlessMesh/-/wik...
Using that setup, it started working much better! This designates one particular node as the main one, so my code to negotiate the controlling node is unneeded, which can split up the mesh. I have attached an updated/alternate code sample. This approach requires that the main node be on for them to be synchronized, so the mesh is not as fault tolerant, but works better when spread out the way mine are. Be sure to edit the code for that version - only one node should be set to the root - see the comments in the code.
I also added one more update to the SetRoot variant: I added code to reset the ESP8266 if there have been no commands for 10 minutes. This gives the node a chance to re-discover the root node. This seemed to help with some of the more distant nodes.
At the end of the season, I was able to test some D1 Mini Pro modules. They have a ceramic antenna on the board, and you can also use a U.FL connector and external antenna if you move a zero ohm resistor. I tried a couple that had synching issues with the D1 Mini Pros with the ceramic antennas, and they worked better. I did some subsequent testing with one node across my house. Based on the results, we will switch to the D1 Mini Pro modules with the ceramic antennas next year.
- With a remote D1 Mini: Only the D1 Mini Pro with an external antenna saw it, and the signal strength was low.
- With a remote D1 Mini Pro with ceramic antenna: The D1 Mini, the D1 Mini Pro with ceramic antenna, and the D1 Mini Pro with an external antenna all saw it with roughly the same signal strength, so that was an improvement. The orientation of the boards (antennas) do matter to a degree.
- With a remote D1 Mini Pro with an external antenna: All the other boards saw it, but the signal strength was not much better than the tests with the onboard ceramic antenna, so I will not bother moving those zero ohm resistors and putting antennas on the candy canes.
Step 6: Final Assembly
Once you have the controller ready and programmed, all you need to do is connect the LEDs to the controller with the JST wires, and a 5v power supply on the 2.1mm jack.
The JST extension should be helpful to keep the controller and power adapter always from the LEDs. Or, to get the CPU higher up, I put a small plastic bag over them secured with a twist-tie, and used a 2.1mm extension cord to the power supply.
The waterproof box will help protect the adapter and CPU, but most of my neighbors used simple plastic bags.

Second Prize in the
Holiday Decorations Speed Challenge
28 Comments
Question 1 year ago
Hi - great stuff! I run a large holiday show using Lightorama software - a single house show running wired (E1.31), connected with CAT 5 cable to a series of network boxes and then on to controllers and props. What are you using as a data source and how can I synchronize my current display with my neighbors such that he can get that same signal? Thanks! Bob
Answer 1 year ago
These are much less sophisticated - they setup up their own (non Internet connected) WiFi Network and talk to each other. With your setup, I imagine you would need to run network cabling around, though there may be some WiFi or wireless Ethernet/Cat5 option.
Reply 1 year ago
Thank you sir - I found a way to "share" my show with a neighbor - by using a point-to-point bridge with very low latency I can send the signal across the street. Appreciate all that you do - keep innovating! Bob
1 year ago
Love the Idea, Any suggestions on parts suppliers?
Can you run a candy Cane on a USB 5V Battery? What is the run time?
I guess like "2600mah Metal Power Charger Bank Mobile USB External Battery Power Bank"
Reply 1 year ago
Thanks. I have links for most of the parts in the Parts List section, but they are widely available, except the plastic candy cane shapes. You can definitely run them on a 5v / USB battery - I do that a lot for testing etc. I do not have a 2,600 mAh USB battery, but I can test on a small 3,200 mAh one I have and reply later.
Reply 1 year ago
It will depend on the exact LED on/off time, brightness, battery freshness and all, but FWIW with the code I have posted, my old lipstick sized 2,600 mAh USB battery lasted 4 hours.
Reply 1 year ago
Do the Cane's need to be reprogrammed every time the battery goes dead?
Reply 1 year ago
Nope - the ESP8266 microcontrollers are very similar to an Arduino - they store the code in non-volatile memory and startup running it every time.
2 years ago
I loaded the code ( LED_Synch_Mesh_Combined_Neighborhood_Instructables_SetRoot.ino.ino ) to five D1 minis. I changed the code on one of them to #define bISROOT true. None of them will synch. On the one I changed #define bISROOT true, I reverted it back to "false" and still none will synch. I did not change anything else in the code. I also tried LED_Synch_Mesh_Combined_Neighborhood_Instructables.ino without changing any code, still no synch.
Troubleshooting I was watching the serial monitor and noticed no mesh commands. I modified the #include "painlessMesh.h" to #include and now I see mesh commands in the serial monitor, but they still never synch nor do they seem to identify the other nodes.
08:35:52.355 -> CONNECTION: scanComplete(): num = 15
08:35:52.355 -> CONNECTION: Found 0 nodes
08:35:52.355 -> CONNECTION: connectToAP(): No unknown nodes found scan rate set to normal
08:36:07.321 -> CONNECTION: stationScan(): HolidayLeds
08:36:09.510 -> CONNECTION: scanComplete(): Scan finished
08:36:09.510 -> CONNECTION: scanComplete():-- > Cleared old APs.
08:36:09.557 -> CONNECTION: scanComplete(): num = 16
08:36:09.557 -> CONNECTION: Found 0 nodes
08:36:09.557 -> CONNECTION: connectToAP(): No unknown nodes found scan rate set to normal
08:36:17.564 -> Sending message to change display_mode to 6
08:36:17.564 -> COMMUNICATION: sendBroadcast(): msg=6
08:36:19.571 -> Sending message to change display_mode to 8
08:36:19.571 -> COMMUNICATION: sendBroadcast(): msg=8
I'm trying this in my basement, the nodes are within five feet of each other. Any idea what I'm missing?
Thanks!
Reply 2 years ago
The changed code is uploaded - just added a "123" to the MESH_PASSSWORD, and a comment! The SetRoot variant also has one new update. I added some code to reset the ESP8266 if there have been no commands for 10 minutes. That allows them a chance to re-connect to the mesh and find the root node if they are isolated.
Reply 2 years ago
By the way, I'm doing some playing around and strips with unequal lights sync well too, but it seems to be best if the lights is a multiple of 4.
Reply 2 years ago
Thanks for trying it! OK, it's so obscure - I think the MESH_PASSWORD needs to be at least 8 characters, and I changed it for the Instructables upload, so, just add a few characters and try again. I'll update the code samples and re-upload.
Reply 2 years ago
Oh my, that was so simple I never thought about it. They are working perfectly, thank you!
2 years ago
In a neighborhood like mine (90ft lots) 50-100 foot range limits you to 6 houses on your street: yours, your two next door neighbors and the three across the street. But that would certainly make a nice display. However, practical questions are: Will your neighbors want them, who pays for them, and will WiFi range really be enough (based on my experience I question it).
Reply 2 years ago
Good questions!
- Yeah, as an engineer, asking around can be daunting :-) I had some neighbors go around and "sell" them, but everyone was immediately on board.
- We asked for people to pay for the parts, but did not require it. They all did.
- You are right on the WiFi range. It has been up and down here. For awhile, it was perfect, then a couple were off, so I added a repeater node. Now they seem more off (even two next to eachother), so I have some debugging to do. Not sure if it's a couple new nodes that were added, the weather, parked cars etc. They are 2.4Ghz WiFi, so any plants or cars will be an issue. There are D1 Min Pro modules that have a U.FL antenna plug, but you need to move a surface mount resistor. Longer range, but still LOS. My tests were up/down too, and we decided that even if they re not synched, they look nice!
Reply 2 years ago
Update (and noted in the Instructable) - I found this note, and implemented the setRoot on one node, and it works a LOT better now: https://gitlab.com/painlessMesh/painlessMesh/-/wikis/Root-nodes
The alternate code has been added to that step.
2 years ago
I love the idea, but what was the cost to make just one of these?? This will let me know if it is worth trying to tackle...
Reply 2 years ago
There are parts links above, but the cost was about $50. That is for 100 LEDs. Going to 50 (one strand) would cost less.
2 years ago
We NEED this guy in our neighborhood!
Reply 2 years ago
Thanks :-) ... or any Maker with this Instructable!