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.69k stars 642 forks source link

Control the leds with your phone #79

Open kadaradam opened 6 years ago

kadaradam commented 6 years ago

I've made an app for android to control the leds with your phone when there is no music playing. Actually this is my first ever android app, that I finished developing, and it functions. If you want take apk I can send it to you.

image alt text

watahboy commented 6 years ago

Sure I got a spare tablet I can use to check that out. I'm trying to figure out an offline way to control this headless, but this is definitely a start at looking into external controls.

kadaradam commented 6 years ago

I don't know why, but the datagramSocket.send function for some reason didn't work on my Nexus 7 tablet. The code is fine, and the app works well on other devices.

Anyway here it is: https://drive.google.com/open?id=0BwrczrZIvaIoQktISkQ0bzNJNjA I'll soon release the source code too.

MoonieGZ commented 6 years ago

This is a really good idea, I'd be interested in the source, mind mentioning me when you release it? Thanks

kadaradam commented 6 years ago

Here you go: https://github.com/kadaradam/ws2812b-Controller

I just quickly uploaded the code, will add more info to the repo later.

MoonieGZ commented 6 years ago

Thanks a lot!

aballiet commented 6 years ago

Sounds very interesting ! I made a set-up with a rpi3 only, how can I adapt/use your app with a headless pi ? Should I create a nodeJS server or something like this ?

kadaradam commented 6 years ago

Oh yeah, this would not work with the pi setup in this form. You would have to create an udp server, then process the data (led num, rgb colors) coming from the android app, and finally update the leds on the pi using the Adafruit libary.

You can code all of this in pyton. UDP server: https://pymotw.com/2/socket/udp.html Tutorial to control leds on the pi: https://learn.adafruit.com/neopixels-on-raspberry-pi/software

Lemme know if you need help.

aballiet commented 6 years ago

Thank you for your fast and clear answer. Is your application already using udp to communicate (when we provide the ip and port number in your application) ? If so, I just have to create a python program which will manage both udp server and neopixel activities on the strip? 😁

kadaradam commented 6 years ago

Yeah, it does. The android app sends a data to the udp server which leds should light up in what color. That's how the visualization works on Arduino.

Since you are running the visualization (which includes the processing ofc) on the Pi, there is no need to send over the processed data to an another device, because the led strip is connected directly to the pi.

So yeah, you just have to create separate python program (you can use any program language, which supports udp servers), to listen for the incoming requests coming from the app.

Here is the udp server code for the Arduino: https://github.com/scottlawsonbc/audio-reactive-led-strip/blob/master/arduino/ws2812_controller/ws2812_controller.ino

Try to code this in your preferred programming language.

aballiet commented 6 years ago

Hey !

I'm able to receive data sent from your app on my raspberry pi, but I have troubles to parse them... It seems to be difficult in python. If you have an idea, this is the received one with a simple 'print' :

received data sample code

kadaradam commented 6 years ago

Yes, because the received value is in bytes. Also the app sends the data in the following format:

i = index r = red value g = green value b = blue value

irgbirgbirgb... ... till you run out of leds.

So you gotta extract them in the following way:

for i in range(0, len(data), 4):  
        index = int(data[i])  
        r = int(data[i + 1])  
        g = int(data[i + 2])  
        b = int(data[i + 3])  
        print(index)  
        print(r)  
        print(g)  
        print(b)
aballiet commented 6 years ago

Thank you for your answer 👍 I'm sorry to ask you so many questions.... but I've tried a lot of different methods in order to parse the string from the bytes without luck... None of ASCII, latin, utf-8 worked... If you have an idea :)

I'm quite discovering this kind of encode/decode stuff so... Best regards

kadaradam commented 6 years ago

What do you mean? The code I sent you above is not working? It works perfectly for me: image

Now you just gotta use the Adafruit libary and light up the leds.

aballiet commented 6 years ago

No it is not working for me :( I didn't ake any modification in the code of the app. And my server is just like yours.... full code

invalid literal

kadaradam commented 6 years ago

import socket
import sys

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

server_address = ('192.168.1.111', 7777)
print('starting up on %s port %s' % server_address)
sock.bind(server_address)

while True:
    print('\nwaiting to receive message')
    data, address = sock.recvfrom(1024)

    print('received %s bytes from %s' % (len(data), address))

    for i in range(0, len(data), 4):
        index = int(data[i])
        r = int(data[i + 1])
        g = int(data[i + 2])
        b = int(data[i + 3])
        print(index)
        print(r)
        print(g)
        print(b)

Here is the complet code. If it's still not working, what version of python do you use?

aballiet commented 6 years ago

Python 2.7.13 I will upgrade it, maybe that is the problem... Thank you again

UPDATE : after upgrading my version to 3.6 it is working :D

kadaradam commented 6 years ago

Oh yeah, you don't need to do that. I'm not much a python guy, so I did some digging and found the solution for python 2.7.

Just the swap the code I previously pasted to this:

for i in range(0, len(data), 4):
        ldata = map(ord, data)
        print ldata[0]
        print ldata[1]
        print ldata[2]
        print ldata[3]

Edit: Oh shit, i ve just realized that is not gonna work for every leds. I'll fix it and update the post tomorrow, when i'll be on pc.

aballiet commented 6 years ago

Hey! I've tested your solution, it doesn't work for every leds unless I put an another loop. This allows me to apply a unique color to the entire strip :blush:

kadaradam commented 6 years ago

Yeah I know, that's why I edited my post later. I was kinda tired sorry. :D

No need for another loop:

ldata = map(ord, data)
for i in range(0, len(data), 4):
        print (ldata[i])
        print (ldata[i + 1])
        print (ldata[i + 2])
        print (ldata[i + 3])
aballiet commented 6 years ago

Everything works now, thank you very much 👍 .

Chris265 commented 5 years ago

Hello @kadaradam, can you help me? Your app does not communicate with the udp server. I use your created code. I have it set up on my Raspberry. I would appreciate an answer. Thank you!