This commit is contained in:
Hendrik Rauh 2025-05-27 22:36:27 +02:00 committed by GitHub
commit c757460e17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 154 additions and 88 deletions

8
.gitmodules vendored
View file

@ -1,6 +1,6 @@
[submodule "lib/ArtNet"]
path = lib/ArtNet
url = https://github.com/psxde/ArtNet.git
path = lib/ArtNet
url = https://github.com/psxde/ArtNet.git
[submodule "lib/AsyncWebServer_ESP32_W5500"]
path = lib/AsyncWebServer_ESP32_W5500
url = https://github.com/psxde/AsyncWebServer_ESP32_W5500.git
path = lib/AsyncWebServer_ESP32_W5500
url = https://github.com/psxde/AsyncWebServer_ESP32_W5500.git

57
src/log.cpp Normal file
View file

@ -0,0 +1,57 @@
#include "log.h"
const char *getLogLevelString(log_level level)
{
switch (level)
{
case EMERGENCY:
return "EMRG";
case ALERT:
return "ALRT";
case CRITICAL:
return "CRIT";
case ERROR:
return "EROR";
case WARNING:
return "WRNG";
case NOTICE:
return "NOTI";
case INFO:
return "INFO";
case DEBUG:
return "DEBG";
default:
return "UKWN";
}
}
void setupLogger()
{
Serial.begin(9600);
while (!Serial)
{
// updateLed();
}
// delay(5000);
Serial.println("Logger initialized");
}
void writeSerialLog(const log_level level, const char *tag, const unsigned long timestamp, const char *formattedMessage)
{
Serial.printf("[%s][%s](%d)> %s\n", getLogLevelString(level), tag, timestamp, formattedMessage);
}
void logMessage(const log_level level, const char *tag, const char *message, ...)
{
const unsigned long timestamp = millis();
va_list args;
va_start(args, message);
int size = vsnprintf(nullptr, 0, message, args);
char *messageBuffer = new char[size + 1];
vsnprintf(messageBuffer, size + 1, message, args);
va_end(args);
writeSerialLog(level, tag, timestamp, messageBuffer);
delete[] messageBuffer;
}

27
src/log.h Normal file
View file

@ -0,0 +1,27 @@
#include <Arduino.h>
enum log_level
{
EMERGENCY,
ALERT,
CRITICAL,
ERROR,
WARNING,
NOTICE,
INFO,
DEBUG
};
namespace tag
{
const char *const SYSTEM = "SYS";
const char *const DMX = "DMX";
const char *const ARTNET = "ART";
const char *const SERVER = "SVR";
const char *const WIFI = "WIF";
const char *const ETHERNET = "ETH";
const char *const CONFIG = "CNF";
}
void setupLogger();
void logMessage(const log_level level, const char *tag, const char *message, ...);

View file

@ -21,6 +21,7 @@
#include <esp_dmx.h>
#include <LittleFS.h>
#include "log.h"
#include "websocket.h"
#include "routes/config.h"
#include "routes/networks.h"
@ -159,31 +160,30 @@ void onButtonPress()
void setup()
{
setupLogger();
setStatus(Status::Starting);
pinMode(PIN_LED, OUTPUT);
updateLed();
Serial.begin(9600);
logMessage(INFO, tag::SYSTEM, "Interface starting...");
// Get ETH mac
delay(1000);
esp_efuse_mac_get_default(mac);
esp_read_mac(mac, ESP_MAC_ETH);
Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x ESP MAC ETH\n",
mac[0], mac[1], mac[2],
mac[3], mac[4], mac[5]);
logMessage(DEBUG, tag::CONFIG, "%02x:%02x:%02x:%02x:%02x:%02x ESP MAC ETH",
mac[0], mac[1], mac[2],
mac[3], mac[4], mac[5]);
esp_read_mac(mac, ESP_MAC_WIFI_SOFTAP);
Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x ESP MAC SOFTAP\n",
mac[0], mac[1], mac[2],
mac[3], mac[4], mac[5]);
logMessage(DEBUG, tag::CONFIG, "%02x:%02x:%02x:%02x:%02x:%02x ESP MAC SOFTAP",
mac[0], mac[1], mac[2],
mac[3], mac[4], mac[5]);
esp_read_mac(mac, ESP_MAC_WIFI_STA); // ESP_MAC_BASE
Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x ESP MAC BASE\n",
mac[0], mac[1], mac[2],
mac[3], mac[4], mac[5]);
logMessage(DEBUG, tag::CONFIG, "%02x:%02x:%02x:%02x:%02x:%02x ESP MAC BASE",
mac[0], mac[1], mac[2],
mac[3], mac[4], mac[5]);
// LED
config.begin("dmx", true);
@ -204,7 +204,7 @@ void setup()
}
if (digitalRead(PIN_BUTTON) == LOW)
{
Serial.println("Reset config");
logMessage(NOTICE, tag::CONFIG, "Resetting config");
config.begin("dmx", false);
config.clear();
config.end();
@ -225,14 +225,6 @@ void setup()
attachInterrupt(PIN_BUTTON, onButtonPress, FALLING);
// wait for serial monitor
unsigned long startTime = millis();
while (millis() - startTime <= 5000)
{
updateLed();
}
Serial.println("Starting DMX-Interface...");
config.begin("dmx", true);
universe1 = config.getUInt("universe-1", DEFAULT_UNIVERSE1);
@ -241,8 +233,8 @@ void setup()
direction1 = static_cast<Direction>(config.getUInt("direction-1", DEFAULT_DIRECTION1));
direction2 = static_cast<Direction>(config.getUInt("direction-2", DEFAULT_DIRECTION2));
Serial.printf("Port A: Universe %d %s\n", universe1, (direction1 == Input) ? "DMX -> Art-Net" : "Art-Net -> DMX");
Serial.printf("Port B: Universe %d %s\n", universe2, (direction2 == Input) ? "DMX -> Art-Net" : "Art-Net -> DMX");
logMessage(INFO, tag::CONFIG, "Port A: Universe %d %s", universe1, (direction1 == Input) ? "DMX -> Art-Net" : "Art-Net -> DMX");
logMessage(INFO, tag::CONFIG, "Port B: Universe %d %s", universe2, (direction2 == Input) ? "DMX -> Art-Net" : "Art-Net -> DMX");
Connection connection = static_cast<Connection>(config.getUInt("connection", DEFAULT_CONNECTION));
IpMethod ipMethod = static_cast<IpMethod>(config.getUInt("ip-method"), DEFAULT_IP_METHOD);
@ -250,8 +242,7 @@ void setup()
char hostname[30];
snprintf(hostname, sizeof(hostname), "ChaosDMX-%02X%02X", mac[4], mac[5]);
DEFAULT_SSID = hostname;
Serial.print("Hostname: ");
Serial.println(hostname);
logMessage(INFO, tag::CONFIG, "Hostname: %s", hostname);
String ssid = config.getString("ssid", DEFAULT_SSID);
String pwd = config.getString("password", DEFAULT_PASSWORD);
@ -266,33 +257,32 @@ void setup()
switch (connection)
{
case WiFiSta:
Serial.println("Initialize as WiFi Station");
logMessage(DEBUG, tag::SYSTEM, "Initialize as WiFi Station");
WiFi.setHostname(hostname);
WiFi.begin(ssid, pwd);
Serial.println("SSID: " + ssid + ", pwd: " + pwd);
logMessage(INFO, tag::CONFIG, "SSID: %s; PWD: %s", ssid, pwd);
if (ipMethod == Static)
{
WiFi.config(ip, gateway, subnet);
Serial.println("IP: " + ip.toString() + ", gateway: " + gateway + ", subnet: " + subnet);
logMessage(INFO, tag::CONFIG, "IP: %s; gateway: %s; subnet: %s", ip.toString(), gateway, subnet);
}
logMessage(DEBUG, tag::WIFI, "Connecting...");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
delay(50);
updateLed();
}
logMessage(INFO, tag::WIFI, "Connected!");
broadcastIp = String(WiFi.broadcastIP().toString().c_str());
Serial.println("");
Serial.print("WiFi connected, IP = ");
Serial.println(WiFi.localIP());
Serial.print("MAC address: ");
Serial.println(WiFi.macAddress());
Serial.print("Broadcast IP: ");
Serial.println(broadcastIp);
logMessage(INFO, tag::WIFI, "IP: %s", WiFi.localIP().toString());
logMessage(INFO, tag::WIFI, "MAC: %X", WiFi.macAddress());
logMessage(INFO, tag::WIFI, "Broadcast IP: %s", broadcastIp);
break;
case Ethernet:
{
Serial.println("Initialize as ETH");
logMessage(DEBUG, tag::SYSTEM, "Initialize as ETH");
ESP32_W5500_onEvent();
if (ETH.begin(ETH_MISO, ETH_MOSI, ETH_SCK, ETH_SS, ETH_INT, ETH_SPI_CLOCK_MHZ, SPI2_HOST, mac))
@ -300,64 +290,56 @@ void setup()
}
else
{
Serial.println("Failed to configure Ethernet");
logMessage(CRITICAL, tag::ETHERNET, "Failed to configure Ethernet");
}
ETH.setHostname(hostname);
// ESP32_W5500_waitForConnect();
uint8_t timeout = 5; // in s
Serial.print("Wait for connect");
logMessage(DEBUG, tag::ETHERNET, "Wait for connect");
// TODO: use millis
while (!ESP32_W5500_eth_connected && timeout > 0)
{
delay(1000);
timeout--;
Serial.print(".");
}
Serial.println();
if (ESP32_W5500_eth_connected)
{
Serial.println("DHCP OK!");
logMessage(DEBUG, tag::ETHERNET, "DHCP OK!");
}
else
{
Serial.println("Set static IP");
logMessage(DEBUG, tag::ETHERNET, "Set static IP");
ETH.config(ip, gateway, subnet);
}
logMessage(DEBUG, tag::ETHERNET, "Ethernet Successfully Initialized");
broadcastIp = ETH.broadcastIP().toString();
Serial.print("Local IP : ");
Serial.println(ETH.localIP());
Serial.print("Subnet Mask : ");
Serial.println(ETH.subnetMask());
Serial.print("Gateway IP : ");
Serial.println(ETH.gatewayIP());
Serial.print("DNS Server : ");
Serial.println(ETH.dnsIP());
Serial.print("MAC address : ");
Serial.println(ETH.macAddress());
Serial.print("Broadcast IP: ");
Serial.println(broadcastIp);
Serial.println("Ethernet Successfully Initialized");
logMessage(INFO, tag::ETHERNET, "Local IP: %s", ETH.localIP().toString());
logMessage(INFO, tag::ETHERNET, "Subnet Mask: %s", ETH.subnetMask().toString());
logMessage(INFO, tag::ETHERNET, "Gateway IP: %s", ETH.gatewayIP().toString());
logMessage(DEBUG, tag::ETHERNET, "DNS Server: %s", ETH.dnsIP().toString());
logMessage(DEBUG, tag::ETHERNET, "MAC address: %X", ETH.macAddress());
logMessage(DEBUG, tag::ETHERNET, "Broadcast IP: %s", broadcastIp);
break;
}
default:
Serial.println("Initialize as WiFi AccessPoint");
logMessage(DEBUG, tag::SYSTEM, "Initialize as WiFi AccessPoint");
WiFi.softAPsetHostname(hostname);
WiFi.softAP(ssid, pwd);
// AP always with DHCP
// WiFi.softAPConfig(ip, gateway, subnet);
broadcastIp = WiFi.softAPBroadcastIP().toString();
Serial.print("WiFi AP enabled, IP = ");
Serial.println(WiFi.softAPIP());
Serial.print("MAC address: ");
Serial.println(WiFi.softAPmacAddress());
Serial.print("Broadcast IP: ");
Serial.println(broadcastIp);
logMessage(DEBUG, tag::WIFI, "WiFi AP enabled");
logMessage(INFO, tag::CONFIG, "IP: %s", WiFi.softAPIP().toString());
logMessage(DEBUG, tag::CONFIG, "MAC address: %X", WiFi.softAPmacAddress());
logMessage(DEBUG, tag::CONFIG, "Broadcast IP: %s", broadcastIp);
break;
}
// Initialize DMX ports
Serial.println("Initialize DMX...");
logMessage(DEBUG, tag::DMX, "Initialize DMX...");
#ifdef CONFIG_IDF_TARGET_ESP32S2
@ -370,19 +352,20 @@ void setup()
dmx_driver_install(dmx2, &dmx_config, personalities, personality_count);
dmx_set_pin(dmx2, 17, 18, -1);
Serial.printf("DMX driver 1 installed: %d\n", dmx_driver_is_installed(dmx1));
Serial.printf("DMX driver 2 installed: %d\n", dmx_driver_is_installed(dmx2));
logMessage(DEBUG, tag::DMX, "DMX driver 1 installed: %d", dmx_driver_is_installed(dmx1));
logMessage(DEBUG, tag::DMX, "DMX driver 2 installed: %d", dmx_driver_is_installed(dmx2));
Serial.printf("DMX driver 1 enabled: %d\n", dmx_driver_is_enabled(dmx1));
Serial.printf("DMX driver 2 enabled: %d\n", dmx_driver_is_enabled(dmx2));
logMessage(DEBUG, tag::DMX, "DMX driver 1 enabled: %d", dmx_driver_is_enabled(dmx1));
logMessage(DEBUG, tag::DMX, "DMX driver 2 enabled: %d", dmx_driver_is_enabled(dmx2));
#else
dmx1.init(21, 33, Serial1);
dmx2.init(17, 18, Serial2);
#endif
logMessage(DEBUG, tag::DMX, "DMX initialized");
// Initialize Art-Net
Serial.println("Initialize Art-Net...");
logMessage(DEBUG, tag::ARTNET, "Initialize Art-Net...");
artnet.begin();
// if Artnet packet comes to this universe, this function is called
@ -403,10 +386,12 @@ void setup()
dmx_send(dmx2);
dmx_wait_sent(dmx2, DMX_TIMEOUT_TICK); });
}
logMessage(DEBUG, tag::ARTNET, "Initialized Art-Net");
if (!LittleFS.begin(true))
{
Serial.println("An Error has occurred while mounting LittleFS");
setStatus(Status::Critical);
logMessage(CRITICAL, tag::SYSTEM, "An Error has occurred while mounting LittleFS");
return;
}
@ -432,14 +417,14 @@ void setup()
{
if (request->url() == "/config" && request->method() == HTTP_PUT) {
onPutConfig(request, data, len, index, total);
Serial.println("restarting ESP...");
logMessage(INFO, tag::SYSTEM, "Restarting ESP...");
ESP.restart();
} });
initWebSocket(&server);
server.begin();
Serial.println("Server started!");
logMessage(DEBUG, tag::SERVER, "Webserver started!");
// scan networks and cache them
WiFi.scanNetworks(true);
@ -447,20 +432,17 @@ void setup()
setStatus(Status::Normal);
// Internal temperature RP2040
/*float tempC = analogReadTemp(); // Get internal temperature
Serial.print("Temperature Celsius (ºC): ");
Serial.println(tempC);*/
// float tempC = analogReadTemp(); // Get internal temperature
// logIT(DEBUG, SYSTEM, "Temperature Celsius: %d °C", tempC);
// Internal temperature ESP32 https://www.espboards.dev/blog/esp32-inbuilt-temperature-sensor/
Serial.print("Temperature: ");
float result = 0;
temp_sensor_read_celsius(&result);
Serial.print(result);
Serial.println(" °C");
logMessage(DEBUG, tag::SYSTEM, "Temperature: %.2f °C", result);
Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
Serial.printf("ChipRevision %d, Cpu Freq %d, SDK Version %s\n", ESP.getChipRevision(), ESP.getCpuFreqMHz(), ESP.getSdkVersion());
Serial.printf("Flash Size %d, Flash Speed %d\n", ESP.getFlashChipSize(), ESP.getFlashChipSpeed());
logMessage(DEBUG, tag::SYSTEM, "Internal Total heap: %d; internal Free Heap: %d", ESP.getHeapSize(), ESP.getFreeHeap());
logMessage(DEBUG, tag::SYSTEM, "SPIRam Total heap: %d; SPIRam Free Heap: %d", ESP.getPsramSize(), ESP.getFreePsram());
logMessage(DEBUG, tag::SYSTEM, "ChipRevision: %d; Cpu Freq: %d; SDK Version: %s", ESP.getChipRevision(), ESP.getCpuFreqMHz(), ESP.getSdkVersion());
logMessage(DEBUG, tag::SYSTEM, "Flash Size: %d; Flash Speed: %d", ESP.getFlashChipSize(), ESP.getFlashChipSpeed());
}
void transmitDmxToArtnet(dmx_port_t dmxPort, byte *dmx_data, uint8_t artnetUniverse)
@ -486,7 +468,7 @@ void transmitDmxToArtnet(dmx_port_t dmxPort, byte *dmx_data, uint8_t artnetUnive
connect or disconnect your DMX devices. If you are consistently getting
DMX errors, then something may have gone wrong with your code or
something is seriously wrong with your DMX transmitter. */
Serial.printf("A DMX error occurred on port %d.\n", dmxPort);
logMessage(ERROR, tag::DMX, "A DMX error occurred on port %d", dmxPort);
}
}
}