Broadcast audio data to multiple ESP8266s for LED light control?

Hi, I'm new here. I'm trying to modify an existing sound-reactive LED light project to better fit my own needs. I've built 6 battery-powered LED light bars that are each receiving audio data via UDP from another (7th) ESP8266 that has an audio line-in on A0 input. It's working beautifully so far! Except the current code requires each light to have a "Client ID #", and if one light runs out of batteries or disconnects, even momentarily, then they all freeze.

Is there a way to set it up without requiring a fixed number of clients? And in a way that allows some to go offline without stalling the whole thing? In theory I'd like an open-ended connection that could have an unlimited number of clients "listening" to the data stream and not worry about any disconnections. Quality of the data transfer is not really important in this case, as long as most of the lights are receiving most of the data most of the time. Is such a thing even possible?

#include <FastLED.h>
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
#include "reactive_common.h"

#define READ_PIN 0
#define BUTTON_PIN 5
#define BUTTON_PIN 5
#define BEAT_PIN 14

#define NUMBER_OF_CLIENTS 6     // SET # of lamps

const int checkDelay = 5000;     
const int buttonDoubleTapDelay = 200;      
const int numOpModes = 4;     

unsigned long lastChecked;
unsigned long buttonChecked;
bool buttonClicked = false;
bool queueDouble = false;
bool clickTrigger;
bool doubleTapped;

bool beatDetect = false;  

WiFiUDP UDP;

struct led_command {
  uint8_t opmode;
  uint32_t data;
};

//struct beat_command {
//  uint8_t opmode;
//  bool beatDetect;
//};


bool heartbeats[NUMBER_OF_CLIENTS];

static int opMode = 1;     // default 1

void setup()
{
  pinMode(READ_PIN, INPUT);
  pinMode(BUTTON_PIN, INPUT );

  /* WiFi Part */
  Serial.begin(115200);
  Serial.println();
  Serial.print("Setting soft-AP ... ");
  WiFi.persistent(false);
  WiFi.mode(WIFI_AP);
  WiFi.softAP("sound_reactiveA", "123456789");     // "sound_reactiveA" or "sound_reactiveB"
  Serial.print("Soft-AP IP address = ");
  Serial.println(WiFi.softAPIP());
  UDP.begin(7171);
  resetHeartBeats();
  waitForConnections();
  lastChecked = millis();
  buttonChecked = 0;
}


void loop()
{
  uint32_t analogRaw;

  Serial.println(analogRaw);

  buttonCheck();
  if (millis() - lastChecked > checkDelay) {
    if (!checkHeartBeats()) {
      waitForConnections();
    }
    lastChecked = millis();
  }

  switch (opMode) {
    case 1:
      analogRaw = analogRead(READ_PIN);
      Serial.println(analogRaw);
      if (analogRaw <= 1)     // 3
        break;
      sendLedData(analogRaw, opMode);
      break;
    case 2:
      sendLedData(0, opMode);
      //      delay(10);
      break;
    case 3:
      sendLedData(0, opMode);
      //      delay(10);
      break;
    case 4:
      analogRaw = analogRead(READ_PIN);
      Serial.println(analogRaw);
      if (analogRaw <= 1)
        break;
      sendLedData(analogRaw, opMode);
      break;
  }
  delay(4);
}

void sendLedData(uint32_t data, uint8_t op_mode)
{
  struct led_command send_data;
  send_data.opmode = op_mode;
  send_data.data = data;
  for (int i = 0; i < NUMBER_OF_CLIENTS; i++)      ///// Maybe this is the problem???
  {
    IPAddress ip(192, 168, 4, 2 + i);
    UDP.beginPacket(ip, 7001);
    UDP.write((char*)&send_data, sizeof(struct led_command));
    UDP.endPacket();
  }
}

void waitForConnections() {
  while (true) {
    readHeartBeat();
    if (checkHeartBeats()) {
      return;
    }
    delay(checkDelay);
    resetHeartBeats();
  }
}

void resetHeartBeats() {
  for (int i = 0; i < NUMBER_OF_CLIENTS; i++) {
    heartbeats[i] = false;
  }
}

void readHeartBeat() {
  struct heartbeat_message hbm;
  while (true) {
    int packetSize = UDP.parsePacket();
    if (!packetSize) {
      break;
    }
    UDP.read((char *)&hbm, sizeof(struct heartbeat_message));
    if (hbm.client_id > NUMBER_OF_CLIENTS) {
      Serial.println("Error: invalid client_id received");
      continue;
    }
    heartbeats[hbm.client_id - 1] = true;
  }
}

bool checkHeartBeats() {
  for (int i = 0; i < NUMBER_OF_CLIENTS; i++) {
    if (!heartbeats[i]) {
      return false;
    }
  }
  resetHeartBeats();
  return true;
}


void buttonCheck()
{
  int but = digitalRead(BUTTON_PIN);
  if (but == 1) {
    if (millis() - buttonChecked < buttonDoubleTapDelay && buttonClicked == false ) {
      doubleClicked();
      doubleTapped = true;
    }
    clickTrigger = true;
    buttonClicked = true;
    buttonChecked = millis();
  }

  else if (but == 0) {
    if (millis() - buttonChecked > buttonDoubleTapDelay && clickTrigger) {
      if (!doubleTapped) {
        clicked();
      }
      clickTrigger = false;
      doubleTapped = false;
    }
    buttonClicked = false;
  }
}

void clicked() {
  if (opMode == numOpModes)
    opMode = 1;
  else
    opMode++;
  Serial.printf("Setting opmode %d \n", opMode);
}

void doubleClicked() {

}

You should be able to send broadcast UDP packets to your subnet using an adress like 192.168.1.255 - not sure what other changes may be required though.h.

You may want to look at Multicast rather than broadcast though

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.