audio-reactive-led-strip icon indicating copy to clipboard operation
audio-reactive-led-strip copied to clipboard

Trying to adapt repo with MQTT

Open Oleenick opened this issue 6 years ago • 3 comments
trafficstars

For the past couple days I've been trying to do something simple in concept.

I'd like to have my LED Strip run through animations configured by the adafruit MQTT service.

When music plays from the source (my computer) I'd like it to display that rather than the animations.

I've got these concepts running separately but somehow, no matter how I arrange the code, I can't get both to work this way. Either MQTT wont connect or the LED strip won't respond to music.

This has really been frustrating me so I'd deeply appreciate it if someone could pull me out of this.

Thanks in advance!

Oleenick avatar Dec 17 '18 10:12 Oleenick

Would you be able to post your current code and we can have a look at it?

joeybab3 avatar Dec 23 '18 04:12 joeybab3

Its a bit of a hot mess but here it is:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <WiFiUdp.h>
#include "ws2812_i2s.h"

#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

// Set to the number of LEDs in your LED strip
#define NUM_LEDS 300
// Maximum number of packets to hold in the buffer. Don't change this.
#define BUFFER_LEN 1024
// Toggles FPS output (1 = print FPS over serial, 0 = disable output)
#define PRINT_FPS 1

// Wifi and socket settings
const char* ssid     = "Nope :P";
const char* password = "You wish";
unsigned int localPort = 7777;
char packetBuffer[BUFFER_LEN];

// LED strip
static WS2812 ledstrip;
static Pixel_t pixels[NUM_LEDS];
WiFiUDP port;

// Network information
// IP must match the IP in config.py
IPAddress ip(192, 168, 1, 7);
// Set gateway to your router's gateway
IPAddress gateway(192, 168, 1, 254);
IPAddress subnet(255, 255, 255, 0);

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883                   // use 8883 for SSL
#define AIO_USERNAME    "Nope again"
#define AIO_KEY         "still no"
/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// or... use WiFiFlientSecure for SSL
//WiFiClientSecure client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/

// Setup a feed called 'photocell' for publishing.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
// Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/photocell"); LISTENING

// Setup a feed called 'onoff' for subscribing to changes.
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/LED Test");

/*************************** Sketch Code ************************************/

// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
// for some reason (only affects ESP8266, likely an arduino-builder bug).
void MQTT_connect();

void setup() {
Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
   // WiFi.config(ip, gateway, subnet);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println(F("Adafruit MQTT demo"));

    // Connect to WiFi access point.
    Serial.println(); Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

  Serial.print("Connecting to MQTT... ");

    Serial.println();
  
    Serial.println("MQTT WiFi connected");
    Serial.println("MQTT IP address: "); Serial.println(WiFi.localIP());
  
    // Setup MQTT subscription for onoff feed.
    mqtt.subscribe(&onoffbutton);
    
    
    
    Serial.println("");
    // Connect to wifi and print the IP address over serial
    
    Serial.println("");
    Serial.print("LED Connected to ");
    Serial.println(ssid);
    Serial.print("LED IP address: ");
    Serial.println(WiFi.localIP());
    port.begin(localPort);
    ledstrip.init(NUM_LEDS);    
}



// LEDs
uint8_t N = 0;
#if PRINT_FPS
    uint16_t fpsCounter = 0;
    uint32_t secondTimer = 0;
#endif


//MQTT
uint32_t x=0;

void loop() {
  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();

  // this is our 'wait for incoming subscription packets' busy subloop
  // try to spend your time here

  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) {
    if (subscription == &onoffbutton) {
      Serial.print(F("Got: "));
      Serial.println((char *)onoffbutton.lastread);
      

      // Read data over socket
                      int packetSize = port.parsePacket();
                      // If packets have been received, interpret the command
                      if (packetSize) {
                          int len = port.read(packetBuffer, BUFFER_LEN);
                          for(int i = 0; i < len; i+=4) {
                              packetBuffer[len] = 0;
                              N = packetBuffer[i];
                              pixels[N].R = (uint8_t)packetBuffer[i+1];
                              pixels[N].G = (uint8_t)packetBuffer[i+2];
                              pixels[N].B = (uint8_t)packetBuffer[i+3];
                          } 
                          ledstrip.show(pixels);
                  
                                      #if PRINT_FPS
                                      fpsCounter++;
                                      #endif
                                      
                          
                      }
                      #if PRINT_FPS
                          if (millis() - secondTimer >= 1000U) {
                              secondTimer = millis();
                              Serial.printf("FPS: %d\n", fpsCounter); 
   
                              fpsCounter = 0;
                            
                      #endif
                  }
                      


      
    // Gets the state on the button then writes its value to LED  
      uint16_t state = atoi((char *)onoffbutton.lastread);
      digitalWrite(LED_BUILTIN, state);
    
    
    }
  }
}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0) {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
  Serial.println("MQTT Connected!");
}

Oleenick avatar Dec 23 '18 06:12 Oleenick

The way I've tried simply doesn't work, but my intention is to have Adafruit MQTT (controlled with IFTTT) changing the mode of the LED strip, but when packets are received from this Audio Visualizer, it should override the current LED strip animation set my MQTT and start.

I was considering using two boards - my esp8266 for this repo, and another esp32 to do the MQTT/effects part which can toggle the output of the visualisation logic - but then this repo wouldn't activate with receiving sound packets.

I considered excluding this awesome repo but I just love it! Thanks for anyone's help in advance.

Oleenick avatar Dec 24 '18 00:12 Oleenick