Twitch-Chat-Controlled LEDs

by pfeiffer3000 in Circuits > LEDs

1079 Views, 8 Favorites, 0 Comments

Twitch-Chat-Controlled LEDs

IMG_0057.JPG

Build an addressable LED display that reacts to Twitch chat.

Supplies

Materials:

  1. 1 @ 10’ length of ¾” PVC tube available at most hardware stores
  2. 4 @ ¾” PVC 90 degree elbow fitting available at most hardware stores
  3. Electrical tape
  4. 12 @ Zip ties 6” or 8”
  5. 1 @ ws2812b addressable LED string often called ‘fairy lights’ like BFT-LIGHTING 50-LED string fairy lights - available from many online sellers
  6. 36 @ table tennis balls without writing or markings available from many online sellers
  7. 1 @ ESP32 with breakout/expansion board any ESP32 dev board that also comes with an expansion board with extra headers and power barrel jack - available from many online sellers
  8. 1 @ 5V 3A DC power supply with 2.5mm diameter, center-positive barrel jack
  9. 3 @ female Dupont connectors (optional) 2.54mm pitch

Tools:

  1. Soldering iron
  2. Solder
  3. Ratcheting PVC tube cutter
  4. Dupont crimper (optional)

Introduction

Fig 1 - single LED.JPG

This project allows Twitch chat users to control an array of addressable LEDs by leveraging an ESP32 microcontroller running WLED and a powerful Python library, TwitchIO.

To realize this project you’ll build a frame that will support a string of LED lights, adorn each LED with a table tennis ball for light diffusion, wire up an ESP32 and install WLED, and finally integrate some Python code to run a Twitch chatbot locally.

Build the PVC Frame

Fig 2 - cutters__.JPG

You’ll build a frame out of ¾” Sch 40 PVC tubing, which can be found at most hardware stores in 10’ lengths. It’s standard plumbing material, and has been in the maker toolkit for decades. If you’re going to be working with PVC tubing in any capacity, I suggest investing in a ratcheting PVC tube cutter; it’s one of the best tools I own. It makes cutting PVC tubes really easy, and it’s super satisfying to use!

Cut the ¾” PVC tube into four 60cm lengths. These are the four sides of the frame for the fairy light LEDs. Assemble them into a square with the four ¾” elbows at each corner. Push hard to make sure the tube is fully inserted into the elbow. For a more permanent design, you can add PVC cement to the joints. This will glue the tube inside the elbow, making it a permanent weld. I’ve skipped that step because I like the flexibility of being able to reuse the materials from this build in something else in the future.

Hang your frame on a wall or shelving, or hold it with a vice. This will allow you to string the LEDs from top to bottom without having to hold the frame in place manually. I suggest stringing the LEDs on the frame in the same orientation that you plan to display the finished piece so things don’t shift when you move it around.

Stringing LEDs

Fig 3 - frame__.JPG
Fig 4 - zip ties.JPG

String the LEDs from the bottom to the top of the frame. By putting the starting end of the LEDs near the bottom, it allows you to attach the ESP32 nearer to the floor so it doesn’t dangle in front of your display. Feel free to string the LEDs in the way that best fits your project. For this example, I started at the lower right, then zig-zagged from bottom to top, right to left. The LEDs are spaced at 4” intervals, so consider this as you design your pattern. From the bottom right corner, my LED string ascends to the top, travels along the top of the frame for 4” then heads straight back down to the bottom of the frame, travels along the bottom for 4”, then repeats twice more.

Hold the LED string in place with zip ties placed around the PVC tube and the LED string wires. Keep the ties loose for the moment; we’ll tighten them later when everything is in place. Allow enough room between the zip tie and the frame for an LED to pass through. The ties are helping to give a rough organization to your string pattern. Instead of a grid, you could try setting them up as a star, your awesome logo, or whatever you’d like.

Tighten the zip ties when you’ve finished your pattern. I wanted mine to be a grid, so I lined up each column with the previous, making sure the LEDs were horizontally and vertically aligned. Because the LEDs are spaced approximately 4” apart, I have one LED against the top and bottom of my frame for each leg that runs along it. Use electrical tape to manage wires between zip ties, to solidify the LED string in place, and to cover up the LEDs that lay against the frame.

Table Tennis Balls

Fig 5 - ttbals__.JPG
Fig 6 - ball scissors__.JPG
Fig 7 - nom__.JPG
Fig 8 - ttball closeup__.JPG
Fig 9 - frame ttballs__.JPG

Use the pointy end of a pair of sharp scissors to poke a hole in a table tennis ball, then cut a semicircle from top to bottom. The cut will travel along half of one great circle of the ball (pole-to-pole). I used a pair of surplus medical scissors because they have a good poky end, and they cut cleanly. But any sharply-pointed scissors will work. Sharp warning: don’t poke your hand as you push through the ball! Always poke away from your body.

Squeeze the ball at the poles to help it nom around the LED. The ball should grab the wire and stay in place with the LED string extending out of the ball’s poles. A little glue could help cement it in place for a more permanent solution. Turn the balls so the seam is pointing away from view.

Continue for each LED in your pattern. For a string of 50 LEDs, it made the most sense for me to make a square grid of 6x6 LEDs. With the five LEDs along the frame, I’m actively using 41 LEDs. You can cut off the final 9 LEDs and use them in another project, or push them out of the way for the moment. In my example, I wound them up the left side of the frame to manage the loose wires while maintaining the full length of the LED string. If you’re using your final project on camera, then consider tucking them behind the frame. You can spray paint the frame or wrap it in fabric to further add some flair to your build, or leave it looking industrial and raw.

ESP32 Circuitry

Fig 10 - expansion board__.JPG
Fig 11 - expansion board with connector__.JPG

You can wire your own circuit to power the LEDs and the ESP32 using a female barrel jack, a large capacitor, and a few wires. However, it can be easier to use one of the expansion boards that comes with certain models of ESP32s from online vendors. These boards allow the ESP32 dev module to mount on top of the expansion board. It also provides several rows of male headers to attach peripherals like buttons, sensors, or in the case of this project, the wires that lead to the LEDs. The benefit of the expansion board is that it has a couple of convenience components built in (like power regulator and capacitors), so you can power the ESP32 and the LEDs from the same power supply without needing to construct a separate circuit. The yellow jumper seen in Fig. 10 should be set to the lower position, connecting V to 5V (instead of connecting V to 3.3V). This determines the voltage that is supplied to the male headers, labeled as “V”, and will eventually be connected to the LEDs, which require 5V to operate.

The expansion board provides 5V to the ESP32 and the LEDs. The ESP32 dev module has onboard circuitry that regulates the voltage down to the 3.3V at which it operates. Don’t try to power the LEDs from the ESP32 output pins. They can’t deliver enough current to support the LEDs in operation. Drawing too much current through the ESP32s GPIO pins can damage the dev module. It’s best to power the LEDs from an external power supply, like we’re setting up in this project. The 5V 3A power supply in the materials list will plug into the 2.5mm barrel jack on the expansion board and be able to power everything.

Addressable LEDs usually come with a couple of loose connectors that are not attached to the LEDs. They have a 3-prong female connector on one end and three bare wires on the other end. The three bare wires are typically arranged with +5V on one side (usually colored red), GND on the other side (usually black, white, or unmarked), and the data signal in the middle (usually green or unmarked). The colors vary by manufacturer, so check the orientation before you commit to plugging them in.

Attach the bare wires on the female connector to the expansion board. You can solder the wires directly to the expansion board’s male headers or crimp Dupont connectors onto their ends. I chose to use the Dupont connectors because it makes the build more flexible while testing. To do this, you’ll need a Dupont crimping tool and female Dupont receptacles. The +5V wire (red) connects to the “V” row of headers. The GND wire (white) connects to the “G” row. Finally, the data signal wire connects to the “S” row. In some of the addressable LED builds I’ve seen, the connector wires will have one twist where the +5V wire overlaps the data signal wire as seen in the image.

Power Considerations

The number of LEDs determines the power draw that you’ll need from a power source like a wall wart power supply. Batteries don’t tend to have enough juice to sustain a light display like this one for an extended time. However, I had great luck using a commercial battery pack (like one used for charging a phone) that powered a WLED sign with 100 LEDs outdoors for several hours in the cold at full brightness. This might be especially useful if you’re planning on wearing your LEDs on camera.

Each addressable LED consumes 50-60mA at full brightness. So, my 41-LED string consumes a little less than 2500mA at maximum. Later, you’ll see how to limit the current draw in the WLED software to 2500mA for an extra level of safety. If you keep the brightness somewhere below full value (like 127 out of 255), then you’ll never need the full 3000mA (3A) supplied by the power supply. Power supplies like this will only provide as much current to the circuit as it needs. So, we can use less current than the power supply is rated for, but not more. In this build example, the 41 LEDs (36 visible + 5 hidden) use under 2500mA (2.5A) at full brightness. Full brightness translates to white light at a brightness of 255 out of 255.

Typically, one power supply will work for one LED strip. If you keep the brightness low, then you can possibly use one power supply for two LED strips. For more LEDs than that, you’ll either need more current, like a 10A power supply, or you’ll need to inject power periodically along the LED string, which potentially means adding more 5V power supplies. This is done most easily at the beginning of a new LED string. The LED strings for this project have extra wires protruding from their connectors that are intended for you to attach an external power supply. Do the math to find out how much current you’ll need for your installation: (number of LEDs) * 60mA = (total current in mA). If you have a particularly long string of LEDs (i.e. several hundred LEDs), then consider using 12V LEDs instead of the ones rated for 5V that I’ve used here.

If you design and 3D print an enclosure for your ESP32, make sure it has openings for the ESP32 to vent. An ESP32 dev module in normal operation can reach temperatures of 50C. In an enclosed space, it can heat up quickly. Alternatively, you can leave the dev board visible so your friends can marvel at how cool you are for building sophisticated electronic setups!

Install WLED on the ESP32

The WLED Project is a framework that installs a webserver on an ESP32 microcontroller. It allows you to control and configure addressable LEDs (sometimes called NeoPixes) on your local Wi-Fi network. You can upload WLED onto an ESP32 from a computer’s web browser, attach addressable LEDs (like Adafruit’s NeoPixels or other LED strips with the ws2812b protocol), then control the whole thing with a phone app, computer, or in our case via Twitch chat. WLED has a lot of great information and documentation here: https://kno.wled.ge/.

To install WLED on an ESP32, use the WLED Project’s online installer: https://install.wled.me/. Use a USB cable to connect your ESP32 to your computer, then follow the prompts from the installer. Choose the com port that starts with CP2102 or CP2104. In a couple of minutes, WLED will be flashed onto the ESP32!

Note: If you’ve never used an ESP32 with your computer, you might need to download and install drivers that allow you to treat the ESP32’s USB connection as a serial port. Download the CP210x drivers from its official website here: https://www.silabs.com/developer-tools/usb-to-uart-bridge-vcp-drivers

If you need more help, Random Nerd Tutorials has an excellent walkthrough (among other excellent content) about how to install the drivers: https://randomnerdtutorials.com/install-esp32-esp8266-usb-drivers-cp210x-windows/

After the installation finishes, the installation webpage will ask you to set up WiFi for the ESP32. Connect it to your local network, then select ‘Visit Device’. We need the IP address of the ESP32 for a future step. To find it, after loading the WLED user interface, select Config->WiFi Setup. Scroll down to find, ‘Client IP’. Mine had a value of 192.168.0.72, so I’ll use this value as my example from here on. Keep track of the IP address, or come back here when you need to find it again.

WLED has an excellent app that allows you to operate your LEDs from your phone. It has the same functionality as the webpage you were just using. As a bonus, WLED integrates well with Home Assistant. So if you’re into home automation, this is a great addition to your setup. Nothing I describe in this article will interfere with Home Assistant setups, so you can do both simultaneously.

Configure some things in the WLED UI:

  1. Navigate to Config -> LED Preferences
  2. Set the “Maximum PSU Current” to 2500mA. See the information about power supplies above for more information on this setting.
  3. Set “Length” to 41. This sets the number of LEDs to illuminate. Change this if your build is smaller or larger accordingly.
  4. Set “Data GPIO” to 13. You can choose whichever GPIO pin you’d like to use. I choose pin 13 because it’s close to the power jack, which makes designing 3D enclosures a bit easier–all the wires that come out of the enclosure are close together.
  5. Create Presets. Back on the main WLED page, navigate through the Color palette and Effect mode listings. You can pick whatever looks good to you. I picked three presets for this demonstration. Create a preset by tapping “+ Preset” under the Presets tab in the WLED UI.
  6. Preset 1 → Select ‘Aurora’ (one of my favorites).
  7. Preset 2 → Select ‘Solid’, then set the Fx color to blue in the Color palette. Name this preset, “Solid Blue”.
  8. Preset 3 → Select ‘Rainbow’, adjust the sliders at the bottom of the Effect mode window to your liking, then save the preset.

Add as many presets as you’d like. You can create playlists of presets that are themselves presets you can use later. You’ll be able to change the active preset in the code by using the names or IDs of the presets you created.

Python Code

You can find the code for this project here: https://github.com/pfeiffer3000/Twitch-LEDs

The software for the Twitch chatbot is written in Python. The Twitch sections of the code are based on the wonderful work done by the TwitchIO team (https://TwitchIO.dev/), especially from Chillymosh and Mysty. Check their projects and documentation for more information about how to use this awesome framework!

The software establishes a connection with Twitch chat servers, does some authentication behind the scenes, then listens to the chat. If a chat message starts with “!LED”, then the bot sends a command to the WLED device to change the preset. For example, if a chat user typed, “!LED 3”, then the chatbot would recognize this message, and reach out to the ESP32 to tell WLED to display the third preset (or the preset with an ID of 3), which was our Rainbow preset from earlier. The chat user could also type “!LED Rainbow” to achieve the same result.

While the goal of this article is to change presets in response to chat messages, WLED allows you to have more granular control over its settings through editing and uploading JSON data via API calls. There are a lot of possibilities if you’d like to get creative.

Note: The Twitch part of the code won’t work right out of the box. You’ll first need to obtain a few data pieces that allow you to interact with the Twitch API (Application Programming Interface). You can find more information at the github link for this project https://github.com/pfeiffer3000/Twitch-LEDs. You can also check out the workflow set up by the devs at TwichIO here: https://twitchio.dev/en/latest/getting-started/quickstart.html#quickstart.

There are two python modules in the github repository that you’ll use in the project:

wled_connect.py – This handles connections to the ESP32 running WLED. It has functionality that allows you to test things such as: check the connection between the computer and the ESP32; change preconfigured WLED presets; or list the presets stored on the device. The computer running wled_connect.py will need to be on the same network as the ESP32 so they can talk to each other over WiFi. In the ‘main()’ function of wled_connect.py, manually type the IP address of your ESP32 (ex: 192.168.0.72), then run the program. You can find the IP address of the ESP32 from the WLED Config settings (we did this earlier when we set up WLED). Once running, the wled_connect.py will prompt you to enter the ID or name of a preset that you’d like to display. Type the number of a preset to watch it change. If you’re just using bot_Twitch_v3.py (the other Python module), then you’ll never need to set the IP address of the ESP32, nor will you need to run this program as a standalone at all; its intended job is to support the code in other programs.

bot_Twitch_v3.py – This is the main guts of the Twitch chatbot based on the TwitchIO library. It handles establishing a connection to the Twitch servers, reading the chat in real time, and dealing with logic as needed. You can do all sorts of cool things here that are similar to the bots you’ve seen on other peoples’ Twitch channels. I haven’t found anything in other chatbots that I can’t emulate with TwitchIO and Python. Check https://TwitchIO.dev for more info on all the amazing stuff they have packed into their library. This bot_Twitch_v3.py program focuses on reading the chat for the specific command, “!LED”. Any text following that command will be read by the program and then sent to the ESP32. To get it working you’ll need to add a few things in the code: your specific Twitch API access token; the IP address of the ESP32 running WLED; and the Twitch channel you want to connect to.

Before you can run the bot you’ll need to follow the quickstart instructions from TwitchIO, which can be found here: https://twitchio.dev/en/latest/getting-started/quickstart.html. They walk you through establishing a connection on your local computer for the first time.

Note: Changes in local networks, like power loss or resetting your WiFi router, might result in your ESP32 obtaining a different IP address. If your code isn’t working, this is a good place to start troubleshooting.

Run the program bot_Twitch_v3.py, and if all goes well, then you’ll have a working connection between your Twitch chat and WLED!

Conclusion

Fig 12 - Before and After__.JPG

Enjoy wowing your Twitch audience with your chat-enabled LED setup and watching them discover that they have control over your ambience! The customizability of your setup rivals, and often outperforms, commercially available products. As a bonus: you’re not giving your data to 3rd party chatbots, devices, and services. The TwitchIO framework allows you to build your own full-featured Python chatbot, so explore fun ideas or integrations with more WLED projects or other IOT devices. Have a great stream!

Mike Pfeiffer runs the Physical Computing Makerspace at the University of Massachusetts, Amherst Manning College of Information and Computer Sciences, where he and his team developed this idea. Special thanks to the Physical Computing Makerspace stellar employees, Omer Sezer and Georges Ouweijan for their inspiration and help in making this project.

You can see an expanded, functional version of this project in Mike’s Twitch DJ stream on Saturday nights at 8:00pm EDT/EST at https://twitch.tv/djpfeifdnb.