scottlawsonbc / audio-reactive-led-strip

:musical_note: :rainbow: Real-time LED strip music visualization using Python and the ESP8266 or Raspberry Pi
MIT License
2.7k stars 641 forks source link

LED strip lights constantly #31

Closed frispete closed 7 years ago

frispete commented 7 years ago

Hi Scott, first of all, great project - well done!

Unfortunately, I'm stuck. A few LEDs of the strip are shining in slightly different colors, nothing else. Everything worked fine, I've used an Wemos D1, and console shows FPS values between 59 and 61. Visualizing is working fine, it acts according to the music, that is playing with vlc (even without jack, that's hard to get up with a 3 sound devices setup...)

The LED strip is the usual 1M 18W WS2812B 5050 RGB LED, hence it fits the config out of the box. The LAN setup was easy, and worked immediately..

Hmm, leaves the Wemos as the culprit, but after loading the WebSocketsServer lib, all worked fine. The D1 is quite nice, as it contains the USB with UART controller out of the box..

Here's a picture of the wiring: resized_20170213_001512 resized_20170213_003643

And here's the outcome: resized_20170213_001552

No need to do a video, it's a still image anyway ;)

Any idea, what's going wrong here?

scottlawsonbc commented 7 years ago

Are you able to control the LED strip without the visualization code?

frispete commented 7 years ago

Now, the problem escalated somehow, no LED light anymore. I've ordered some test equipment to check the LED strips. Some people mention problems with wire connection order, propose resistors in the data wire, etc. Did you follow some procedure or experience damaged strips/controller already?

frispete commented 7 years ago

BTW, I don't know, if it fits your project, but found this site about detailed timing analysis of the WS2812 controllers in case, you didn't notice already?

frispete commented 7 years ago

Okay, problem solved. It was a couple of problems including my incompetence, that resulted in this mess.

Works like a charm now. I've managed to have a rainbow effect in led.py now.. If you're interested in something like this, I can clean it up a bit, and send a PR.

frispete commented 7 years ago

While at it (don't want to open a new issue), did you thought about color distribution in the effects already? They seem to privilege the main colors R, G and B somewhat, but the rainbow has so many nice colors in between..

scottlawsonbc commented 7 years ago

What do you think of this? It's a demo video of a new version that I am working on. This new effect uses color much more intelligently than the current version.

frispete commented 7 years ago

This is looking GREAT (and the sound track is great, too, will get back to Big Wild, soon, thanks for the hint)! I hear DJ Koze/Reincarnations II at the moment, very nice as well ;)

I would be pleased to test that thing, want to put it on GH as a gist or in another branch?

frispete commented 7 years ago

Hi Scott, don't know, if I bother you too much, but I was able to experiment a bit with some ws2812b items. There are pretty cheap remote controller available, that manage to detect the number of attached LEDs. Any idea, how do they do this?

Atraii commented 7 years ago

Do you have a link to an example device? They may use a current draw to detect the number of LEDs. Or perhaps they simply have a set length they support up to. I don't think there's any way to detect this on the data line.

On Fri, Feb 17, 2017, 11:37 AM Hans-Peter Jansen notifications@github.com wrote:

Hi Scott, don't know, if I bother you too much, but I was able to experiment a bit with some ws2812b items. There are pretty cheap remote controller available, that manage to detect the number of attached LEDs. Any idea, how do they do this?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/scottlawsonbc/audio-reactive-led-strip/issues/31#issuecomment-280746047, or mute the thread https://github.com/notifications/unsubscribe-auth/AA6LtT-U2vSeyM1fxzQoEMEEXxp4-tPMks5rdfb_gaJpZM4L-q8K .

scottlawsonbc commented 7 years ago

The new version of the code is in the develop branch. Unfortunately, I'm extremely busy with school right now and haven't had a chance to document that code and I don't recommend trying to run it. The code has been completely overhauled and is very different from what is in the master branch. There is also no GUI support yet.

Sadly, I'm so busy with school that I probably won't be able to finish for another 2-3 months.

There are pretty cheap remote controller available, that manage to detect the number of attached LEDs. Any idea, how do they do this?

I had no idea these existed. Do you have a link to one of these devices?

frispete commented 7 years ago

Sure, just search for "SP103E controller". @Atraii A couple of built-in effects imply, that they "know" the number of LEDs (e.g. a rainbow effect (exactly one) and some Ping-Pong effect, where lights move to one end and pile up). Yes, the power draw could be a way, that could even be done with all lights of, but implies a pretty exact measurement.

@scottlawsonbc School's first. Thank you for sharing the code, will check this out later today. Don't worry about the code's state. I'm struggling with numpy a bit, never did anything before with it.

Any idea anybody, if there's a better way in numpy to set the pixel values in one go:

def rainbow(count = 1):
    value = 0.0
    step = 1.0 / (config.N_PIXELS / float(count))
    for i in range(config.N_PIXELS):
        # generate hsv color over hue range with max. saturation and reduced intensity
        rgb = list(colorsys.hsv_to_rgb(value, 1.0, 0.5))
        # scale value
        r, g, b = list(map(lambda v: int(v * 255), rgb))
        pixels[0, i] = r
        pixels[1, i] = g
        pixels[2, i] = b
        value += step
scottlawsonbc commented 7 years ago

This SP103E manual explains how to adjust the number of LEDs using the remote. I don't think it has auto-detection capability. To my knowledge, it isn't possible to automatically detect the number of LEDs because of how the WS2812B communication protocol works. It is simply not possible to propagate information backwards to the controller.

def rainbow(count = 1):
    value = 0.0
    step = 1.0 / (config.N_PIXELS / float(count))
    for i in range(config.N_PIXELS):
        # generate hsv color over hue range with max. saturation and reduced intensity
        rgb = list(colorsys.hsv_to_rgb(value, 1.0, 0.5))
        # scale value
        r, g, b = list(map(lambda v: int(v * 255), rgb))
        pixels[0, i] = r
        pixels[1, i] = g
        pixels[2, i] = b
        value += step

You won't be able to vectorize the rainbow() function because colorsys.hsv_to_rgb() returns a scalar value and does not accept numpy arrays. Technically, you can vectorize this using numpy.vectorize, but the performance is equivalent to using a for loop.

The scikit-image library does provide vectorized functions for converting between colorspaces.

Develop branch code

If you want to try the experimental code in the develop branch, there are a few important things to note:

Installation

You can install the code by running a single terminal command:

python -m pip install https://github.com/scottlawsonbc/audio-reactive-led-strip/tarball/develop

Usage

To run the visualization, either create a new .py file or enter this into a python shell:

import audioled
audio, fs = audioled.stream_audio(chunk_rate=90)
effect = audioled.effects.spectrum(pixels=144, fs=fs, chunk_rate=90)
device = audioled.devices.ESP8266(ip='192.168.0.150')
[device.show(pixels) for pixels in effect(audio)]

Audio device configuration

This line initializes the audio device and automatically detects the microphone sample rate (removing the need for a MIC_RATE setting).

audio, fs = audioled.stream_audio(chunk_rate=90)

Instead of automatically detecting the audio device, you can also specify a particular audio device index. This is helpful for Raspberry Pi users because it doesn't require them to change the system's default audio device.

audio, fs = audioled.stream_audio(chunk_rate=90, device_index=1)

chunk_rate is the refresh rate of the LED strip. This is called FPS in the master branch version. I renamed frames per second (FPS) because of ambiguity about what a frame is in the context of audio signal processing. chunk_rate = 90 means 90 LED updates per second.

Effect configuration

This line configures the visualization effect. Set the correct number of pixels, and make sure that chunk_rate matches the chunk_rate for the audio stream.

effect = audioled.effects.spectrum(pixels=144, fs=fs, chunk_rate=90)

Device configuration

I've made it much easier to add support for new devices. There is a different class for each hardware device that is supported, such as the ESP8266, Blinkstick, RaspberryPi, and FadeCandy.

Here are some examples:

device = audioled.devices.ESP8266(ip='192.168.0.150')
device = audioled.devices.FadeCandy()
device = audioled.devices.BlinkStick()

The RaspberryPi needs to know the number of pixels when the class is instantiated:

device = audioled.devices.RaspberryPi(pixels=60, pin=18, invert_logic=False, freq=800000, dma=5)

Running the visualization

The final line is what is responsible for running the visualization.

[device.show(pixels) for pixels in effect(audio)]

Bonus points if you can understand why a list comprehension runs the visualization!