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.68k stars 644 forks source link

[hardware question] different LED strip? #256

Closed dogo77 closed 3 years ago

dogo77 commented 4 years ago

Hi, just today i saw that video on yt and thought: this will be my first raspberry hardware project ;) so now i have an raspberry 3 up and running with dietpi and python strandtest.py is running without error. Color wipe animations. Theater chase animations. Rainbow animations. Color wipe animations. Theater chase animations. Rainbow animations. Now – before i buy a brand new LED strip – i looked at what i already have at home and found 2 spare strips with 60 resp. 120 LEDs. BUT.
These are different to the ones you mention throughout the whole project. i have 4 cables labeled R G B + which is obviously not exactly the GND Data +5V scheme mentioned… ;)

My Question: can i somehow use these strips with audio-reactive-led-strip or is this project specifically for the WS2812B LED strip?

Thanks for your answer D.

gaijinsr commented 4 years ago

Hi, your strip is just a dumb LED strip without any decoding electronics, so you need to attach it to some control circuit and you will only be able to set all the LEDs to the same colour. I actually have one of those strips and I control it with audio-reactive-LED strip (and compatible software that expects UDP packets with the RGB values). I can very much recommend the H801 ESP8266 modules, e.g. https://www.ebay.de/itm/H801-LED-Strip-WiFi-Controller-Dimmer-Funkempfanger-Fernbedienung-Steuerung-DE/263986465603 The H801 contains an ESP8266 and five high power MOSFET transistors, you can connect your LED strip without any additional hardware. I wrote an Arduino sketch for the H801 (using some code snippets from this project) that will receive UDP packets and set the whole strip to the colour that would be written to the first LED if the strip was a WS2812 strip. When no data is received, the strip slowly cycles through different colours.

gaijinsr commented 4 years ago

` // SR 18Nov18, 21Jan19 // using code from systematic LEDs

include

include

include

include

/**** Network Information ****/ const char ssid = "xxx"; const char password = "yyy";

const char sensor_name = "LED_STRIP_DUMB"; const char ota_password = "ota_ota_ota";

const bool static_ip = false; const int udp_port = 7778;

/*** Definitions ****/

define SWITCH_PIN 0 // aka flash

define RED_PIN 15 // 16 for red onboard LED on NodeMCU

define GREEN_PIN 13 // or 14=W1, if G=13 is broken!!

define BLUE_PIN 12 // 2 for blue onboard LED

WiFiUDP port; int mode=1; // needs to be persistent

unsigned long last_change = 0; unsigned long last_packet = 0; char data[UDP_TX_PACKET_MAX_SIZE]; // large to be on the safe side, allocate once int packetSize; int red,green,blue;

/** Setup ****/ void setup() { Serial.begin(115200); pinMode(SWITCH_PIN, INPUT_PULLUP);

setup_wifi(); setup_ota(); port.begin(udp_port); }

void setup_wifi() { delay(10);

Serial.println(); Serial.print("Connecting to "); Serial.print(ssid);

WiFi.hostname(sensor_name); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password);

last_change=millis(); while (WiFi.status() != WL_CONNECTED && millis()-last_change<10000 ) { delay(500); Serial.print("."); }

Serial.println(""); Serial.println("WiFi connected:"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); }

void setup_ota() { ArduinoOTA.setHostname(sensor_name); ArduinoOTA.setPassword(ota_password);

ArduinoOTA.onStart([]() { Serial.println("Starting"); }); ArduinoOTA.onEnd([]() { Serial.println("\nEnd"); }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }); ArduinoOTA.onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); }

/** Main loop ****/

void loop() {

ArduinoOTA.handle();

// If button pressed, cycle mode if( (digitalRead(SWITCH_PIN) == LOW) && (millis() - last_change > 1000) ) { mode=(mode+1)%5; Serial.printf("Mode is now %u.\n",mode); last_change = millis(); }

// Handle UDP data packetSize = port.parsePacket(); if (packetSize >= 3 ){ last_packet=millis(); port.read(data, UDP_TX_PACKET_MAX_SIZE); red=data[0]; green=data[1]; blue=data[2]; // Serial.printf("Packet of size %u received: %u, %u, %u.\n", packetSize, red, green, blue); } else if (millis()-last_packet>1000) { int phase=millis()/(4<<(2mode)); if (mode>0){ red =abs(-(phase %768)+384) -128; if(red<0 || red > 1024){red=0;} // strangely, they appear large, not negative... green=abs(-((phase+256)%768)+384) -128-48; if(green<0 || green>1024){green=0;} // too intense compared to red blue =abs(-((phase+512)%768)+384) -128-48; if(blue<0 || blue> 1024){blue=0;} // Serial.printf("Phase= %u, Setting RBG: %u, %u, %u.\n", phase, red, green, blue); } else { red=0;green=0;blue=0; } delay(20); } analogWrite(RED_PIN, 4red); // 0-1023, 1023-4red etc. for internal LEDs analogWrite(GREEN_PIN,4green); analogWrite(BLUE_PIN, 4*blue); yield(); } `

dogo77 commented 4 years ago

Thank you for your quick answer, i'll think about it!

Nawor3565 commented 4 years ago

@gaijinsr Hi there, I'm also trying to setup a "dumb" LED strip, but unfortunately unable to buy one of the H801 controllers in the USA for some reason (I could buy from China, but that could take a long time to arrive). I'm trying to find a suitable replacement, but I don't have much experience with Arduinos. To clarify, the H801 controller has a built-in ESP8266, and you directly flashed the script to it? If so, I believe I would have to find a different controller that uses an ESP8266. Is there any way to determine what micro-controller a specific module uses, apart from buying one and opening it up? The FUT037 seems pretty similar to the H801 in terms of features. What do you think?

Assuming I can't find an alternative to the H801, would it be feasible to essentially re-create the H801 with off-the-shelf components? Without a schematic of the controller, it would be a lot of work to figure out exactly what I would need, but maybe I'm overlooking a simpler solution. Thank you!

gaijinsr commented 4 years ago

Hi Nawor, you are correct, the H801 has a built-in ESP8266 and I flashed the sketch onto it with the Arduino IDE. You certainly could take any ESP8266 module and connect a couple of MOSFETs to it, but the H801 is really incredibly good value for money. If I was you, I would order a NodeMCU or other generic 8266 module locally to have something to play with on short notice and an H801 in China for "production". The MagicHome LED controllers also have ESP8266 modules in them, but they cannot drive currents as high as the H801. Yes, you cannot really tell what controller a given module uses, but since the ESP is so cheap and versatile, a very large percentage of this class of gadgets uses it.

Nawor3565 commented 4 years ago

@gaijinsr Hello! Thank you for the response, I finally had time to work on the H801. However, I encountered a couple problems and I was hoping you could help. I originally flashed the ESP with your code from above, however I could not get any output from the serial monitor no matter what I tried, so I couldn't figure out what IP the ESP had been assigned. So, I modified the code to give it a static IP, which you can see here.

At first, this worked, and I could ping the ESP from my PC. However, after I spent some time installing Python dependencies, I found that the Python test script wouldn't work, and I could no longer ping the ESP. Instead, the ESP is now broadcasting its own unsecured wifi network with the name ESP-3193AC. I tried flashing the exact same code again, but it still refuses to connect to my own wifi and still broadcasts its own.

I'm still fairly new to Arduino, but looking at the code, I can't figure out anything that could make the ESP change its behavior like this. Would you mind providing some insight into what might have gone wrong, and how I could possibly fix it? Thank you!

gaijinsr commented 4 years ago

Hi Nawor, since you managed to flash the ESP, your serial connection must be OK, so my first suggestion would be to fix the serial monitor, this would make things so much easier. What do you see when you open the serial monitor console in the Arduino IDE? Are you sure you have selected 115200 for the baud rate (as in the sketch)? You do not really need the output of the ESP to find out the IP address that has been assigned to it, the Web interface of your router will also show you which devices have been assigned which addresses. I do not know what could have caused the strange behaviour with not using your fixed address and opening its own network instead, but you should not assign your own address, anyway. Your router assigns addresses via DHCP, and when you use fixed addresses instead, you mess things up.

Nawor3565 commented 4 years ago

Yup, it's pretty strange. The serial connection is fine, the TXD light on my TTL adapter even blinks when I turn the ESP on, meaning it should be receiving serial. Made sure the baud was the same, even tried changing it in the monitor and code to use 9600, but it didn't help. The serial monitor is just blank, even using Putty or a simple Python script didn't work. Do you think it may be a driver issue?

gaijinsr commented 4 years ago

Not sure about your specific serial adapter, but I would have expected the RX light to blink when the ESP sends data... If it was a driver issue, I do not think that the flashing would have worked. Why don't you re-flash the ESP with the DHCP configuration and then keep the working serial connection active. The serial monitor in the Arduino IDE should really work, then.

Nawor3565 commented 4 years ago

Thank you! I was able to get it working with the unmodified code ~(which is here)~, since the markdown is messing with it in the above comment). I wasn't able to get the serial monitor to work, but I did what you originally said and was able to use my router's web page to figure out what IP it was assigned (I can also assign it a static IP from the router itself using the ESP's MAC address, which shouldn't cause issues).

The only thing left to do is some tinkering with the Python config file to make the lights look correct, but otherwise everything seems perfect!

Nawor3565 commented 4 years ago

It turns out that the above code has a small issue that makes the LEDs not work right. Here's the fixed code in case anyone needs it:

// SR 18Nov18, 21Jan19
// using code from systematic LEDs

#include <Arduino.h>
#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

/************ Network Information ************************/
const char* ssid = "INSERT_WIFI_SSID";
const char* password = "INSERT_WIFI_PASSWORD";

const char* sensor_name = "LED_STRIP_DUMB";
const char* ota_password = "ota_ota_ota";

const bool static_ip = false;
const int udp_port = 7778;

/*********************************** Definitions ********************************/

#define SWITCH_PIN 0   // aka flash

#define RED_PIN    15 // 16 for red onboard LED on NodeMCU 
#define GREEN_PIN  13 // or 14=W1, if G=13 is broken!!
#define BLUE_PIN   12 //  2 for blue onboard LED

WiFiUDP port;
int mode=1;    // needs to be persistent

unsigned long last_change = 0;
unsigned long last_packet = 0;
char data[UDP_TX_PACKET_MAX_SIZE]; // large to be on the safe side, allocate once
int packetSize;
int red,green,blue;

/********************************** Setup ****************************************/
void setup() {
  Serial.begin(115200);
  pinMode(SWITCH_PIN, INPUT_PULLUP);

  setup_wifi();
  setup_ota();
  port.begin(udp_port);
}

void setup_wifi() {
  delay(10);

  Serial.println();
  Serial.print("Connecting to ");
  Serial.print(ssid);

  WiFi.hostname(sensor_name);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  last_change=millis();
  while (WiFi.status() != WL_CONNECTED && millis()-last_change<10000 ) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected:");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void setup_ota() {
  ArduinoOTA.setHostname(sensor_name);
  ArduinoOTA.setPassword(ota_password);

  ArduinoOTA.onStart([]() {
    Serial.println("Starting");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
}

/********************************** Main loop ****************************************/

void loop() {

  ArduinoOTA.handle();

  // If button pressed, cycle mode
  if( (digitalRead(SWITCH_PIN) == LOW) && (millis() - last_change > 1000) ) {
    mode=(mode+1)%5;
    Serial.printf("Mode is now %u.\n",mode);
    last_change = millis(); }

  // Handle UDP data
  packetSize = port.parsePacket();
  if (packetSize >= 3 ){
    last_packet=millis();
    port.read(data, UDP_TX_PACKET_MAX_SIZE);
    red=data[1]; green=data[2]; blue=data[3];
    // Serial.printf("Packet of size %u received: %u, %u, %u.\n", packetSize, red, green, blue);
  } else if (millis()-last_packet>1000) {
  int phase=millis()/(4<<(2*mode));
    if (mode>0){
      red  =abs(-(phase      %768)+384) -128;       if(red<0   || red > 1024){red=0;}    // strangely, they appear large, not negative...
      green=abs(-((phase+256)%768)+384) -128-48;    if(green<0 || green>1024){green=0;}  // too intense compared to red
      blue =abs(-((phase+512)%768)+384) -128-48;    if(blue<0  || blue> 1024){blue=0;}
      // Serial.printf("Phase= %u, Setting RBG: %u, %u, %u.\n", phase, red, green, blue);
    } else { red=0;green=0;blue=0; }
  delay(20);
  }
  analogWrite(RED_PIN,  4*red); // 0-1023, 1023-4*red etc. for internal LEDs
  analogWrite(GREEN_PIN, 4*green); 
  analogWrite(BLUE_PIN, 4*blue); 
  yield();
}
joeybab3 commented 3 years ago

Closing as the main question was answered, strips must be addressable to use with this project.