commit 32ba4133809c5d2cf9ace0ae8f4b116ba11ed673 Author: Fabian Müller Date: Thu Mar 21 01:38:53 2024 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e9df25d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.pio/ +credentials.h diff --git a/README.md b/README.md new file mode 100644 index 0000000..c76f549 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# ESP8266 LED Marquee Sign Controller diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..03517ed --- /dev/null +++ b/platformio.ini @@ -0,0 +1,22 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env] +platform = espressif8266 +framework = arduino +monitor_speed = 115200 +upload_speed = 500000 + +# Serial1 (sign data) maps to D4 by default +[env:d1_mini] +board = d1_mini + +[env:nodemcuv2] +board = nodemcuv2 diff --git a/src/credentials.h.example b/src/credentials.h.example new file mode 100644 index 0000000..dd11ebf --- /dev/null +++ b/src/credentials.h.example @@ -0,0 +1,8 @@ +#pragma once + +namespace credentials { + const String ssid = "my SSID"; + const String psk = "my PSK"; + + const String mdnsHostname = "led-marquee-sign"; +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..2172d63 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,52 @@ +#include +#include +#include + +#include "credentials.h" +#include "webserver.h" +#include "util.h" + +static ESP8266WiFiMulti wifiMulti; + +void setup() { + // serial console, for use via USB (also exposed to TXD0/RXD0 GPIOs) + Serial.begin(115200); + + // transmit-only UART port, used for communication with the LED sign + // the BAUD rate was deducued from the communication sent to the USB 12V UART adapter by the available Windows + // software + Serial1.begin(9600); + + // configure WiFi and connect to the network + wifiMulti.addAP(credentials::ssid.c_str(), credentials::psk.c_str()); + Serial.println("Connecting to Wi-Fi network..."); + while (wifiMulti.run() != WL_CONNECTED) { + delay(1000); + Serial.print("."); + } + Serial.println(); + Serial.print("Connected to "); + Serial.print(WiFi.SSID()); + Serial.print(", IP address: "); + Serial.println(WiFi.localIP()); + + // might be handy to have the IP written on the sign + sendTextToSign(WiFi.localIP().toString()); + + // publish this service using mDNS so that it's easy to find it in the LAN + if (MDNS.begin(credentials::mdnsHostname)) { + Serial.println("mDNS started up successfully"); + } else { + Serial.println("Error: failed to start mDNS"); + } + + // configure HTTP endpoints + configureWebServer(); + + // don't forget to start the webserver! + webServer.begin(); +} + +void loop() { + webServer.handleClient(); +} diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..f023365 --- /dev/null +++ b/src/util.h @@ -0,0 +1,18 @@ +#pragma once + +enum Brightness { + Normal, + Bright, +}; + +void sendTextToSign(String text, Brightness brightness = Bright) { + // debugging + Serial.print("Sending text \""); + Serial.print(text); + Serial.println("\""); + + // TODO: find out how the brightness attribute in the LED sign is encoded in the UART signal + Serial1.print("f01A\\s"); + Serial1.print(text); + Serial1.print("\r\r\r"); +} diff --git a/src/webserver.h b/src/webserver.h new file mode 100644 index 0000000..f6d48c3 --- /dev/null +++ b/src/webserver.h @@ -0,0 +1,68 @@ +#pragma once + +#include "util.h" + +static ESP8266WebServer webServer(80); + +// use an anonymous namespace for the module's "private" methods +// this prevents the methods from ending up in the global namespace +namespace { + void handleNotFound() { + webServer.send(404, "text/plain", "urm... nope"); + } + + void handleIndex() { + String htmlText = R"( + + + + LED Marquee Sign Controller + + + +

LED Marquee Sign Controller

+
+
+
+ + +
+ +
+ + +
+ +
+ +
+
+
+ + + )"; + webServer.send(200, "text/html", htmlText); + } + + void handleFormSend() { + sendTextToSign("HELLO FORM"); + + // redirect back to root page + webServer.sendHeader("Location", "/"); + webServer.send(303); + } + + // RESTful API endpoint -- returns a proper status code rather than a redirect + void handleApiSend() { + sendTextToSign("HELLO API"); + webServer.send(200, "text/plain", "ok"); + } +} + +void configureWebServer() { + webServer.onNotFound(handleNotFound); + + webServer.on("/", HTTPMethod::HTTP_GET, handleIndex); + webServer.on("/", HTTPMethod::HTTP_POST, handleFormSend); + webServer.on("/send", HTTPMethod::HTTP_POST, handleApiSend); +}