Here is my parts list for building these and making them look nice.
The project boxes I ordered are no longer available. They were Zulkit 5Pcs Project Boxes ABS Plastic Electrical Project Case Power Junction Box Black 2.36 x 1.42 x 0.67 inch (60 x 36 x 17 mm)
https://www.amazon.com/gp/product/B081PX9YFV
https://www.amazon.com/gp/product/B06Y4716V7
https://www.amazon.com/gp/product/B081BBF4R3
LED Master
// Load libraries
#include <ESP8266WiFi.h>
#include <Adafruit_NeoPixel.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoOTA.h>
#include <espnow.h>
// Replace with your network credentials
const char* ssid = "wifi";
const char* password = "pass";
// Set web server port number to 80
AsyncWebServer server(80);
// ESP Now Clients
uint8_t broadcastAddress1[] = {0x48, 0x3F, 0xDA, 0x54, 0x64, 0xCB};
//Structure
typedef struct leddata {
int led;
int r;
int g;
int b;
} leddata;
leddata sendled;
//Setup for Strand
#define PIN 4
#define NUMPIXELS 30
String brightness = "10";
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
char macStr[18];
Serial.print("Packet to:");
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.print(macStr);
Serial.print(" send status: ");
if (sendStatus == 0){
Serial.println("Delivery success");
}
else{
Serial.println("Delivery fail");
}
}
void setup() {
Serial.begin(115200);
// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
pixels.begin();
pixels.clear();
pixels.setBrightness(brightness.toInt());
pixels.show();
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
esp_now_register_send_cb(OnDataSent);
esp_now_add_peer(broadcastAddress1, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "Hello, world");
});
server.on("/clear", HTTP_GET, [] (AsyncWebServerRequest *request) {
request->send(200, "text/plain", "clear");
pixels.clear();
pixels.show();
});
server.on("/bright", HTTP_GET, [] (AsyncWebServerRequest *request) {
request->send(200, "text/plain", "Bright");
if (request->hasParam("LEVEL")) {
brightness = request->getParam("LEVEL")->value();
} else {
brightness = "50";
}
pixels.setBrightness(brightness.toInt());
pixels.show();
});
server.on("/led", HTTP_GET, [] (AsyncWebServerRequest *request) {
String getled;
String getr;
String getg;
String getb;
if (request->hasParam("LED")) {
getled = request->getParam("LED")->value();
} else {
getled = NUMPIXELS + 1;
}
if (request->hasParam("R")) {
getr = request->getParam("R")->value();
} else {
getr = "0";
}
if (request->hasParam("G")) {
getg = request->getParam("G")->value();
} else {
getg = "0";
}
if (request->hasParam("B")) {
getb = request->getParam("B")->value();
} else {
getb = "0";
}
request->send(200, "text/plain", "set " + getled + getr + getg + getb);
pixels.setPixelColor(getled.toInt(), pixels.Color(getr.toInt(), getg.toInt(), getb.toInt()));
pixels.show();
sendled.led = getled.toInt();
sendled.r = getr.toInt();
sendled.g = getg.toInt();
sendled.b = getb.toInt();
esp_now_send(0, (uint8_t *) &sendled, sizeof(sendled));
});
server.onNotFound(notFound);
server.begin();
// Port defaults to 8266
// ArduinoOTA.setPort(8266);
// Hostname defaults to esp8266-[ChipID]
// ArduinoOTA.setHostname("myesp8266");
// No authentication by default
// ArduinoOTA.setPassword((const char *)"123");
ArduinoOTA.onStart([]() {
Serial.println("Start");
});
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();
}
void loop(){
ArduinoOTA.handle();
}
LED Slave
#include <ESP8266WiFi.h>
#include <espnow.h>
#include <Adafruit_NeoPixel.h>
//Setup for Strand
#define PIN 4
#define NUMPIXELS 30
String brightness = "10";
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
//Structure
typedef struct leddata {
int led;
int r;
int g;
int b;
} leddata;
leddata sentled;
// Callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
memcpy(&sentled, incomingData, sizeof(sentled));
pixels.setPixelColor(sentled.led, pixels.Color(sentled.r, sentled.g, sentled.b));
pixels.show();
}
void setup() {
Serial.begin(115200);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
WiFi.disconnect();
// Init ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
WiFi.disconnect();
pixels.begin();
pixels.clear();
pixels.setBrightness(brightness.toInt());
pixels.show();
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
}