1
#include <WiFi.h>
#include <BluetoothSerial.h>
#include <Preferences.h>
#include <WiFiUdp.h>
#include <ArtnetWifi.h>
#include <FastLED.h>
#define CONFIG_PIN 0 // DIO pin to enter config mode (e.g. GPIO0)
// LED Strip
int numLeds = 10; // Default number of LEDs
const int numberOfChannels = numLeds * 3; // Total number of DMX channels you want to receive (1 led = 3 channels)
#define DATA_PIN 12 //The data pin that the WS2812 strips are connected to.
CRGB leds[numLeds]; //<<<<<<<<<<<<<<<<<<<<<<<<<<THIS B@STARD ##########################
// Artnet settings
ArtnetWifi artnet;
const int startUniverse = 0;
bool sendFrame = 1;
int previousDataLength = 0;
BluetoothSerial SerialBT;
// Preferences library instance for NVS storage
Preferences preferences;
String ssid, password;
IPAddress localIP, gateway, subnet, dns;
bool configMode = false;
void saveConfig() {
preferences.begin("wifi_conf", false);
preferences.putString("ssid", ssid);
preferences.putString("pass", password);
preferences.putUInt("ip", localIP);
preferences.putUInt("gw", gateway);
preferences.putUInt("mask", subnet);
preferences.putUInt("dns", dns);
preferences.putUInt("numLeds",numLeds);
preferences.end();
SerialBT.println("ā
Configuration saved.");
}
bool loadConfig() {
preferences.begin("wifi_conf", true);
ssid = preferences.getString("ssid", "");
password = preferences.getString("pass", "");
localIP = IPAddress(preferences.getUInt("ip", 0));
gateway = IPAddress(preferences.getUInt("gw", 0));
subnet = IPAddress(preferences.getUInt("mask", 0));
dns = IPAddress(preferences.getUInt("dns", 0));
numLeds = IPAddress(preferences.getUInt("numLeds", 0));
// numberOfChannels = IPAddress(preferences.getUInt("numberOfChannels", 0));
preferences.end();
return ssid.length() > 0;
}
void resetConfig() {
preferences.begin("wifi_conf", false);
preferences.clear();
preferences.end();
SerialBT.println("š WiFi settings cleared.");
}
IPAddress inputIP() {
SerialBT.println("Enter IP (xxx.xxx.xxx.xxx): ");
while (!SerialBT.available()) delay(100);
String ipStr = SerialBT.readStringUntil('\n');
ipStr.trim();
return IPAddress(
ipStr.substring(0, ipStr.indexOf('.')).toInt(),
ipStr.substring(ipStr.indexOf('.') + 1, ipStr.indexOf('.', ipStr.indexOf('.') + 1)).toInt(),
ipStr.substring(ipStr.indexOf('.', ipStr.indexOf('.') + 1) + 1, ipStr.lastIndexOf('.')).toInt(),
ipStr.substring(ipStr.lastIndexOf('.') + 1).toInt()
);
}
void connectToWiFi() {
Serial.printf("š Connecting to SSID: %s\n", ssid.c_str());
if (localIP != IPAddress(0, 0, 0, 0)) {
WiFi.config(localIP, gateway, subnet, dns);
Serial.println("š Using static IP settings");
}
WiFi.begin(ssid.c_str(), password.c_str());
int attempts = 20;
while (WiFi.status() != WL_CONNECTED && attempts-- > 0) {
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nā
Connected!");
Serial.print("š¶ IP Address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nā Failed to connect.");
}
}
void printMenu() {
String mac = WiFi.macAddress(); // Get MAC address
SerialBT.println("\n=== ESP32 WiFi Config Menu ===");
SerialBT.print("š MAC Address: ");
SerialBT.println(mac);
SerialBT.println("------------------------------");
SerialBT.println("1. Set SSID");
SerialBT.println("2. Set Password");
SerialBT.println("3. Set Static IP");
SerialBT.println("4. Set Subnet Mask");
SerialBT.println("5. Set Gateway");
SerialBT.println("6. Set DNS");
SerialBT.println("7. Save & Connect to WiFi");
SerialBT.println("8. Show Current Settings");
SerialBT.println("9. Reset WiFi/LED Settings");
SerialBT.println("0. Exit Menu");
SerialBT.println("------------------------------");
SerialBT.println("10. Set numLeds");
SerialBT.print(">> ");
}
void showConfig() {
SerialBT.println("\nš Current Configuration:");
SerialBT.printf("SSID: %s\n", ssid.c_str());
SerialBT.printf("Password: %s\n", password.c_str());
SerialBT.printf("IP Address: %s\n", localIP.toString().c_str());
SerialBT.printf("Gateway: %s\n", gateway.toString().c_str());
SerialBT.printf("Subnet: %s\n", subnet.toString().c_str());
SerialBT.printf("DNS: %s\n", dns.toString().c_str());
SerialBT.println("------------------------------");
SerialBT.printf("Number of LEDs: %d\n", numLeds);
}
void enterConfigMenu() {
SerialBT.begin("ESP32_Config");
SerialBT.println("š² Entering WiFi Config Mode via Bluetooth...");
printMenu();
bool inMenu = true;
while (inMenu) {
if (SerialBT.available()) {
char option = SerialBT.read();
SerialBT.read(); // consume newline
switch (option) {
case '1':
SerialBT.print("Enter SSID: ");
while (!SerialBT.available()) delay(10);
ssid = SerialBT.readStringUntil('\n'); ssid.trim();
break;
case '2':
SerialBT.print("Enter Password: ");
while (!SerialBT.available()) delay(10);
password = SerialBT.readStringUntil('\n'); password.trim();
break;
case '3': localIP = inputIP(); break;
case '4': subnet = inputIP(); break;
case '5': gateway = inputIP(); break;
case '6': dns = inputIP(); break;
case '7':
saveConfig();
connectToWiFi();
break;
case '8': showConfig(); break;
case '9': resetConfig(); break;
case '0':
inMenu = false;
SerialBT.println("š Exiting menu.");
break;
case '10':
SerialBT.print("Enter number of LEDs: ");
while (!SerialBT.available()) delay(10);
numLeds = SerialBT.readStringUntil('\n').toInt(); // Add this line to set numLeds
break;
default:
SerialBT.println("ā ļø Invalid option.");
}
if (inMenu) printMenu();
}
}
SerialBT.end();
}
void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data)
{
sendFrame = 1;
// set brightness of the whole strip
if (universe == 15)
{
FastLED.setBrightness(data[0]);
}
// read universe and put into the right part of the display buffer
for (int i = 0; i < length / 3; i++)
{
int led = i + (universe - startUniverse) * (previousDataLength / 3);
if (led < numLeds)
{
leds[led] = CRGB(data[i * 3], data[i * 3 + 1], data[i * 3 + 2]);
}
}
previousDataLength = length;
FastLED.show();
}
void setup() {
pinMode(CONFIG_PIN, INPUT_PULLDOWN);
Serial.begin(115200);
delay(100);
configMode = digitalRead(CONFIG_PIN);
Serial.printf("āļø Config Pin is %s\n", configMode ? "HIGH (Entering Config)" : "LOW (Running Main App)");
if (configMode) {
enterConfigMenu();
} else {
if (loadConfig()) {
Serial.println("š Loaded WiFi config. Connecting...");
connectToWiFi();
artnet.begin();
FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, numLeds);
// onDmxFrame will execute every time a packet is received by the ESP32
artnet.setArtDmxCallback(onDmxFrame);
} else {
Serial.println("ā ļø No config found. Please reboot with CONFIG_PIN HIGH to set.");
}
}
}
void loop() {
if (!configMode) {
// š Your main application logic goes here
// we call the read function inside the loop
artnet.read();
}
}
For immediate assistance, please email our customer support: [email protected]