mirror of
https://github.com/HendrikRauh/dmx-interface.git
synced 2025-05-19 10:32:56 +00:00
Merge pull request #35 from HendrikRauh/DMX-3-configuration-WebUI
Dmx 3 configuration web UI
This commit is contained in:
commit
dbb4a773d6
8 changed files with 237 additions and 80 deletions
1
data/icons/refresh.svg
Normal file
1
data/icons/refresh.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#FFF"><path d="M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z"/></svg>
|
After Width: | Height: | Size: 330 B |
|
@ -8,6 +8,7 @@
|
||||||
<script type="module" src="/input-visibility.js" defer></script>
|
<script type="module" src="/input-visibility.js" defer></script>
|
||||||
<script type="module" src="/loading-screen.js" defer></script>
|
<script type="module" src="/loading-screen.js" defer></script>
|
||||||
<script type="module" src="/load-data.js" defer></script>
|
<script type="module" src="/load-data.js" defer></script>
|
||||||
|
<script type="module" src="/networks.js" defer></script>
|
||||||
<script type="module" src="/submit.js" defer></script>
|
<script type="module" src="/submit.js" defer></script>
|
||||||
<script type="module" src="/reset.js" defer></script>
|
<script type="module" src="/reset.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -32,8 +33,8 @@
|
||||||
<h1>Konfiguration</h1>
|
<h1>Konfiguration</h1>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Verbindung</legend>
|
<legend>Verbindung</legend>
|
||||||
<label for="ip-method"
|
<label>
|
||||||
>IP-Zuweisung:
|
<span>IP-Zuweisung:</span>
|
||||||
<select
|
<select
|
||||||
name="ip-method"
|
name="ip-method"
|
||||||
id="input-ip-method"
|
id="input-ip-method"
|
||||||
|
@ -45,7 +46,7 @@
|
||||||
</label>
|
</label>
|
||||||
<div data-field="input-ip-method" data-values="0">
|
<div data-field="input-ip-method" data-values="0">
|
||||||
<label>
|
<label>
|
||||||
IP-Adresse:
|
<span>IP-Adresse:</span>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="ip"
|
name="ip"
|
||||||
|
@ -54,7 +55,7 @@
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
Subnetzmaske:
|
<span>Subnetzmaske:</span>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="subnet"
|
name="subnet"
|
||||||
|
@ -63,7 +64,7 @@
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
Gateway:
|
<span>Gateway:</span>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="gateway"
|
name="gateway"
|
||||||
|
@ -73,7 +74,7 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<label>
|
<label>
|
||||||
Verbindungsmethode:
|
<span>Verbindungsmethode:</span>
|
||||||
<select
|
<select
|
||||||
name="connection"
|
name="connection"
|
||||||
id="input-connection"
|
id="input-connection"
|
||||||
|
@ -86,7 +87,7 @@
|
||||||
</label>
|
</label>
|
||||||
<div data-field="input-connection" data-values="1">
|
<div data-field="input-connection" data-values="1">
|
||||||
<label>
|
<label>
|
||||||
SSID:
|
<span>SSID:</span>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="ssid"
|
name="ssid"
|
||||||
|
@ -97,17 +98,24 @@
|
||||||
</div>
|
</div>
|
||||||
<div data-field="input-connection" data-values="0">
|
<div data-field="input-connection" data-values="0">
|
||||||
<label>
|
<label>
|
||||||
Netzwerk:
|
<span>Netzwerk:</span>
|
||||||
<select
|
<select
|
||||||
name="ssid"
|
name="ssid"
|
||||||
id="input-network"
|
id="select-network"
|
||||||
title="Netzwerk"
|
title="Netzwerk"
|
||||||
></select>
|
></select>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
id="refresh-networks"
|
||||||
|
class="icon-button"
|
||||||
|
>
|
||||||
|
<img src="/icons/refresh.svg" alt="Neu laden" />
|
||||||
|
</button>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div data-field="input-connection" data-values="0|1">
|
<div data-field="input-connection" data-values="0|1">
|
||||||
<label>
|
<label>
|
||||||
Password:
|
<span>Password:</span>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
name="password"
|
name="password"
|
||||||
|
|
60
data/networks.js
Normal file
60
data/networks.js
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
const networkDropdown = document.querySelector("#select-network");
|
||||||
|
const refreshButton = document.querySelector("#refresh-networks");
|
||||||
|
const refreshIcon = refreshButton.querySelector("img");
|
||||||
|
|
||||||
|
let isLoading = false;
|
||||||
|
|
||||||
|
refreshButton.addEventListener("click", async () => {
|
||||||
|
updateNetworks();
|
||||||
|
});
|
||||||
|
|
||||||
|
function insertNetworks(networks) {
|
||||||
|
networks.unshift(""); // add empty option
|
||||||
|
networkDropdown.textContent = ""; // clear dropdown
|
||||||
|
|
||||||
|
for (const ssid of networks) {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.value = ssid;
|
||||||
|
option.innerText = ssid;
|
||||||
|
networkDropdown.appendChild(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadNetworks() {
|
||||||
|
if (isLoading) return;
|
||||||
|
|
||||||
|
isLoading = true;
|
||||||
|
refreshButton.classList.remove("error-bg");
|
||||||
|
refreshIcon.classList.add("spinning");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch("/networks", {
|
||||||
|
method: "GET",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
throw Error(`response status: ${res.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const networks = await res.json();
|
||||||
|
|
||||||
|
refreshIcon.classList.remove("spinning");
|
||||||
|
isLoading = false;
|
||||||
|
// remove duplicate values
|
||||||
|
return Array.from(new Set(networks));
|
||||||
|
} catch (e) {
|
||||||
|
refreshIcon.classList.remove("spinning");
|
||||||
|
refreshButton.classList.add("error-bg");
|
||||||
|
isLoading = false;
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateNetworks() {
|
||||||
|
const networks = await loadNetworks();
|
||||||
|
if (networks) {
|
||||||
|
insertNetworks(networks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateNetworks();
|
|
@ -3,6 +3,7 @@
|
||||||
--color-on-primary: white;
|
--color-on-primary: white;
|
||||||
--color-background: #222;
|
--color-background: #222;
|
||||||
--color-danger: #fa2b58;
|
--color-danger: #fa2b58;
|
||||||
|
--icon-button-size: 2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
@ -38,11 +39,16 @@ fieldset {
|
||||||
label {
|
label {
|
||||||
display: block;
|
display: block;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label span {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
select {
|
select {
|
||||||
width: clamp(200px, 100%, 400px);
|
width: clamp(200px, 100%, 400px);
|
||||||
|
@ -60,6 +66,10 @@ select:focus {
|
||||||
border-color: var(--color-primary);
|
border-color: var(--color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select:has(+ .icon-button) {
|
||||||
|
width: calc(clamp(200px, 100%, 400px) - var(--icon-button-size) - 8px);
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
border: none;
|
border: none;
|
||||||
inset: none;
|
inset: none;
|
||||||
|
@ -143,10 +153,14 @@ label.switch input:checked + .slider::before {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2.error {
|
.error {
|
||||||
color: var(--color-danger);
|
color: var(--color-danger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error-bg {
|
||||||
|
background-color: var(--color-danger) !important;
|
||||||
|
}
|
||||||
|
|
||||||
button.reload {
|
button.reload {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
@ -195,3 +209,17 @@ button.reload {
|
||||||
transform: rotate(360deg);
|
transform: rotate(360deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-button {
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 0;
|
||||||
|
width: var(--icon-button-size);
|
||||||
|
height: var(--icon-button-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinning {
|
||||||
|
animation-name: spin;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
}
|
||||||
|
|
|
@ -12,5 +12,5 @@
|
||||||
platform = espressif32
|
platform = espressif32
|
||||||
board = lolin_s2_mini
|
board = lolin_s2_mini
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps =
|
lib_deps =
|
||||||
bblanchon/ArduinoJson @ ^7.2.0
|
bblanchon/ArduinoJson @ ^7.2.0
|
||||||
|
|
165
src/main.cpp
165
src/main.cpp
|
@ -7,8 +7,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <AsyncWebServer_ESP32_W5500.h>
|
#include <AsyncWebServer_ESP32_W5500.h>
|
||||||
//#include "w5500/esp32_w5500.h"
|
// #include "w5500/esp32_w5500.h"
|
||||||
//#include <ESPAsyncWebServer.h>
|
// #include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
#include <ArtnetWiFi.h>
|
#include <ArtnetWiFi.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
@ -23,33 +23,37 @@ DMXESPSerial dmx1;
|
||||||
DMXESPSerial dmx2;
|
DMXESPSerial dmx2;
|
||||||
|
|
||||||
// Button
|
// Button
|
||||||
#define PIN_LED 7
|
#define PIN_LED 7
|
||||||
#define PIN_BUTTON 5
|
#define PIN_BUTTON 5
|
||||||
|
|
||||||
uint8_t brightness_led = 20;
|
uint8_t brightness_led = 20;
|
||||||
bool status_led;
|
bool status_led;
|
||||||
|
|
||||||
hw_timer_t * timer = NULL; //H/W timer defining (Pointer to the Structure)
|
hw_timer_t *timer = NULL; // H/W timer defining (Pointer to the Structure)
|
||||||
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
|
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
|
||||||
void IRAM_ATTR onTimer() { //Defining Inerrupt function with IRAM_ATTR for faster access
|
void IRAM_ATTR onTimer()
|
||||||
portENTER_CRITICAL_ISR(&timerMux);
|
{ // Defining Inerrupt function with IRAM_ATTR for faster access
|
||||||
status_led = !status_led;
|
portENTER_CRITICAL_ISR(&timerMux);
|
||||||
if (!status_led) {
|
status_led = !status_led;
|
||||||
analogWrite(PIN_LED, brightness_led);
|
if (!status_led)
|
||||||
} else {
|
{
|
||||||
analogWrite(PIN_LED, 0);
|
analogWrite(PIN_LED, brightness_led);
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL_ISR(&timerMux);
|
else
|
||||||
|
{
|
||||||
|
analogWrite(PIN_LED, 0);
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL_ISR(&timerMux);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ethernet stuff
|
// Ethernet stuff
|
||||||
#define ETH_SCK 36
|
#define ETH_SCK 36
|
||||||
#define ETH_SS 34
|
#define ETH_SS 34
|
||||||
#define ETH_MOSI 35
|
#define ETH_MOSI 35
|
||||||
#define ETH_MISO 37
|
#define ETH_MISO 37
|
||||||
#define ETH_INT 38
|
#define ETH_INT 38
|
||||||
#define ETH_SPI_HOST SPI2_HOST
|
#define ETH_SPI_HOST SPI2_HOST
|
||||||
#define ETH_SPI_CLOCK_MHZ 25
|
#define ETH_SPI_CLOCK_MHZ 25
|
||||||
byte mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
byte mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||||
|
|
||||||
AsyncWebServer server(80);
|
AsyncWebServer server(80);
|
||||||
|
@ -61,39 +65,59 @@ uint8_t universe1;
|
||||||
uint8_t universe2;
|
uint8_t universe2;
|
||||||
Direction direction1;
|
Direction direction1;
|
||||||
Direction direction2;
|
Direction direction2;
|
||||||
//const uint16_t size = 512;
|
// const uint16_t size = 512;
|
||||||
//uint8_t data[DMXCHANNELS];
|
// uint8_t data[DMXCHANNELS];
|
||||||
|
|
||||||
void ledBlink(int ms) {
|
void ledBlink(int ms)
|
||||||
if(timer == NULL) {
|
{
|
||||||
timer = timerBegin(0, 80, true); // timer 0, prescalar: 80, UP counting
|
if (timer == NULL)
|
||||||
timerAttachInterrupt(timer, &onTimer, true); // Attach interrupt
|
{
|
||||||
|
timer = timerBegin(0, 80, true); // timer 0, prescalar: 80, UP counting
|
||||||
|
timerAttachInterrupt(timer, &onTimer, true); // Attach interrupt
|
||||||
}
|
}
|
||||||
if(ms == 0) {
|
if (ms == 0)
|
||||||
|
{
|
||||||
timerAlarmDisable(timer);
|
timerAlarmDisable(timer);
|
||||||
analogWrite(PIN_LED, 0);
|
analogWrite(PIN_LED, 0);
|
||||||
} else if(ms == 1) {
|
}
|
||||||
|
else if (ms == 1)
|
||||||
|
{
|
||||||
timerAlarmDisable(timer);
|
timerAlarmDisable(timer);
|
||||||
analogWrite(PIN_LED, brightness_led);
|
analogWrite(PIN_LED, brightness_led);
|
||||||
} else {
|
}
|
||||||
ms = ms*1000;
|
else
|
||||||
timerAlarmWrite(timer, ms, true); // Match value= 1000000 for 1 sec. delay.
|
{
|
||||||
timerAlarmEnable(timer); // Enable Timer with interrupt (Alarm Enable)
|
ms = ms * 1000;
|
||||||
}
|
timerAlarmWrite(timer, ms, true); // Match value= 1000000 for 1 sec. delay.
|
||||||
|
timerAlarmEnable(timer); // Enable Timer with interrupt (Alarm Enable)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
Serial.begin(9600);
|
||||||
|
|
||||||
// Get ETH mac
|
// Get ETH mac
|
||||||
esp_read_mac(mac, ESP_MAC_ETH);
|
esp_read_mac(mac, ESP_MAC_ETH);
|
||||||
|
|
||||||
// LED
|
// LED
|
||||||
analogWrite(PIN_LED, brightness_led);
|
analogWrite(PIN_LED, brightness_led);
|
||||||
delay(5000);
|
// delay(5000);
|
||||||
ledBlink(500);
|
ledBlink(500);
|
||||||
|
|
||||||
|
// Button
|
||||||
|
pinMode(PIN_BUTTON, INPUT_PULLUP);
|
||||||
|
if (digitalRead(PIN_BUTTON) == LOW)
|
||||||
|
{
|
||||||
|
ledBlink(100);
|
||||||
|
delay(2000);
|
||||||
|
Serial.println("Reset config");
|
||||||
|
config.begin("dmx", false);
|
||||||
|
config.clear();
|
||||||
|
config.end();
|
||||||
|
}
|
||||||
|
|
||||||
// Serial console
|
// Serial console
|
||||||
Serial.begin(9600);
|
|
||||||
Serial.print("Start DMX-Interface");
|
Serial.print("Start DMX-Interface");
|
||||||
delay(1000);
|
delay(1000);
|
||||||
Serial.println("...");
|
Serial.println("...");
|
||||||
|
@ -109,15 +133,15 @@ void setup()
|
||||||
Serial.print("Port A: Universe ");
|
Serial.print("Port A: Universe ");
|
||||||
Serial.print(universe1);
|
Serial.print(universe1);
|
||||||
Serial.print(" ");
|
Serial.print(" ");
|
||||||
Serial.println((direction1==Input)?"DMX -> Art-Net":"Art-Net -> DMX");
|
Serial.println((direction1 == Input) ? "DMX -> Art-Net" : "Art-Net -> DMX");
|
||||||
|
|
||||||
Serial.print("Port B: Universe ");
|
Serial.print("Port B: Universe ");
|
||||||
Serial.print(universe2);
|
Serial.print(universe2);
|
||||||
Serial.print(" ");
|
Serial.print(" ");
|
||||||
Serial.println((direction2==Input)?"DMX -> Art-Net":"Art-Net -> DMX");
|
Serial.println((direction2 == Input) ? "DMX -> Art-Net" : "Art-Net -> DMX");
|
||||||
|
|
||||||
Connection connection = static_cast<Connection>(config.getUInt("connection", WiFiAP));
|
Connection connection = static_cast<Connection>(config.getUInt("connection", WiFiAP));
|
||||||
IpMethod ipMethod = static_cast<IpMethod>(config.getUInt("ip-method"), Static);
|
IpMethod ipMethod = static_cast<IpMethod>(config.getUInt("ip-method"), DHCP);
|
||||||
|
|
||||||
WiFi.macAddress(mac);
|
WiFi.macAddress(mac);
|
||||||
char hostname[30];
|
char hostname[30];
|
||||||
|
@ -126,7 +150,7 @@ void setup()
|
||||||
Serial.println(hostname);
|
Serial.println(hostname);
|
||||||
|
|
||||||
String ssid = config.getString("ssid", hostname);
|
String ssid = config.getString("ssid", hostname);
|
||||||
String pwd = config.getString("pwd", "mbgmbgmbg");
|
String pwd = config.getString("password", "mbgmbgmbg");
|
||||||
|
|
||||||
// Default IP as defined in standard https://art-net.org.uk/downloads/art-net.pdf, page 13
|
// Default IP as defined in standard https://art-net.org.uk/downloads/art-net.pdf, page 13
|
||||||
IPAddress defaultIp(2, mac[3], mac[4], mac[5]);
|
IPAddress defaultIp(2, mac[3], mac[4], mac[5]);
|
||||||
|
@ -141,24 +165,17 @@ void setup()
|
||||||
// wait for serial monitor
|
// wait for serial monitor
|
||||||
delay(5000);
|
delay(5000);
|
||||||
|
|
||||||
// Button
|
|
||||||
pinMode(PIN_BUTTON,INPUT_PULLUP);
|
|
||||||
if(digitalRead(PIN_BUTTON) == LOW){
|
|
||||||
ledBlink(100);
|
|
||||||
delay(2000);
|
|
||||||
Serial.println("Start AP-Mode");
|
|
||||||
connection = WiFiAP;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (connection)
|
switch (connection)
|
||||||
{
|
{
|
||||||
case WiFiSta:
|
case WiFiSta:
|
||||||
Serial.println("Initialize as WiFi Station");
|
Serial.println("Initialize as WiFi Station");
|
||||||
WiFi.setHostname(hostname);
|
WiFi.setHostname(hostname);
|
||||||
WiFi.begin(ssid, pwd);
|
WiFi.begin(ssid, pwd);
|
||||||
|
Serial.println("SSID: " + ssid + ", pwd: " + pwd);
|
||||||
if (ipMethod == Static)
|
if (ipMethod == Static)
|
||||||
{
|
{
|
||||||
WiFi.config(ip, gateway, subnet);
|
WiFi.config(ip, gateway, subnet);
|
||||||
|
Serial.println("IP: " + ip.toString() + ", gateway: " + gateway + ", subnet: " + subnet);
|
||||||
}
|
}
|
||||||
while (WiFi.status() != WL_CONNECTED)
|
while (WiFi.status() != WL_CONNECTED)
|
||||||
{
|
{
|
||||||
|
@ -173,28 +190,36 @@ void setup()
|
||||||
Serial.println(WiFi.macAddress());
|
Serial.println(WiFi.macAddress());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Ethernet: {
|
case Ethernet:
|
||||||
|
{
|
||||||
Serial.println("Initialize as ETH");
|
Serial.println("Initialize as ETH");
|
||||||
ESP32_W5500_onEvent();
|
ESP32_W5500_onEvent();
|
||||||
|
|
||||||
if (ETH.begin( ETH_MISO, ETH_MOSI, ETH_SCK, ETH_SS, ETH_INT, ETH_SPI_CLOCK_MHZ, ETH_SPI_HOST, mac )) { // Dynamic IP setup
|
if (ETH.begin(ETH_MISO, ETH_MOSI, ETH_SCK, ETH_SS, ETH_INT, ETH_SPI_CLOCK_MHZ, ETH_SPI_HOST, mac))
|
||||||
}else{
|
{ // Dynamic IP setup
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Serial.println("Failed to configure Ethernet");
|
Serial.println("Failed to configure Ethernet");
|
||||||
}
|
}
|
||||||
ETH.setHostname(hostname);
|
ETH.setHostname(hostname);
|
||||||
|
|
||||||
//ESP32_W5500_waitForConnect();
|
// ESP32_W5500_waitForConnect();
|
||||||
uint8_t timeout = 5; // in s
|
uint8_t timeout = 5; // in s
|
||||||
Serial.print("Wait for connect");
|
Serial.print("Wait for connect");
|
||||||
while (!ESP32_W5500_eth_connected && timeout > 0) {
|
while (!ESP32_W5500_eth_connected && timeout > 0)
|
||||||
|
{
|
||||||
delay(1000);
|
delay(1000);
|
||||||
timeout--;
|
timeout--;
|
||||||
Serial.print(".");
|
Serial.print(".");
|
||||||
}
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
if (ESP32_W5500_eth_connected) {
|
if (ESP32_W5500_eth_connected)
|
||||||
|
{
|
||||||
Serial.println("DHCP OK!");
|
Serial.println("DHCP OK!");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Serial.println("Set static IP");
|
Serial.println("Set static IP");
|
||||||
ETH.config(ip, gateway, subnet);
|
ETH.config(ip, gateway, subnet);
|
||||||
}
|
}
|
||||||
|
@ -218,15 +243,15 @@ void setup()
|
||||||
WiFi.softAPsetHostname(hostname);
|
WiFi.softAPsetHostname(hostname);
|
||||||
WiFi.softAP(ssid, pwd);
|
WiFi.softAP(ssid, pwd);
|
||||||
// AP always with DHCP
|
// AP always with DHCP
|
||||||
//WiFi.softAPConfig(ip, gateway, subnet);
|
// WiFi.softAPConfig(ip, gateway, subnet);
|
||||||
broadcastIp = WiFi.softAPBroadcastIP().toString();
|
broadcastIp = WiFi.softAPBroadcastIP().toString();
|
||||||
Serial.print("WiFi AP enabled, IP = ");
|
Serial.print("WiFi AP enabled, IP = ");
|
||||||
Serial.println(WiFi.softAPIP());
|
Serial.println(WiFi.softAPIP());
|
||||||
Serial.print("MAC address: ");
|
Serial.print("MAC address: ");
|
||||||
Serial.println(WiFi.softAPmacAddress());
|
Serial.println(WiFi.softAPmacAddress());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize DMX ports
|
// Initialize DMX ports
|
||||||
Serial.println("Initialize DMX...");
|
Serial.println("Initialize DMX...");
|
||||||
dmx1.init(21, 33, Serial0);
|
dmx1.init(21, 33, Serial0);
|
||||||
|
@ -237,31 +262,31 @@ void setup()
|
||||||
artnet.begin();
|
artnet.begin();
|
||||||
|
|
||||||
// if Artnet packet comes to this universe, this function is called
|
// if Artnet packet comes to this universe, this function is called
|
||||||
if (direction1 == Output) {
|
if (direction1 == Output)
|
||||||
|
{
|
||||||
artnet.subscribeArtDmxUniverse(universe1, [&](const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote)
|
artnet.subscribeArtDmxUniverse(universe1, [&](const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < size; ++i)
|
for (size_t i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
dmx1.write((i + 1), data[i]);
|
dmx1.write((i + 1), data[i]);
|
||||||
}
|
}
|
||||||
dmx1.update();
|
dmx1.update(); });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direction2 == Output) {
|
if (direction2 == Output)
|
||||||
|
{
|
||||||
artnet.subscribeArtDmxUniverse(universe2, [&](const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote)
|
artnet.subscribeArtDmxUniverse(universe2, [&](const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < size; ++i)
|
for (size_t i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
dmx2.write((i + 1), data[i]);
|
dmx2.write((i + 1), data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
dmx2.update();
|
dmx2.update(); });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if Artnet packet comes, this function is called to every universe
|
// if Artnet packet comes, this function is called to every universe
|
||||||
//artnet.subscribeArtDmx([&](const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote) {});
|
// artnet.subscribeArtDmx([&](const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote) {});
|
||||||
|
|
||||||
if (!SPIFFS.begin(true))
|
if (!SPIFFS.begin(true))
|
||||||
{
|
{
|
||||||
|
@ -284,10 +309,14 @@ void setup()
|
||||||
|
|
||||||
ESP.restart(); });
|
ESP.restart(); });
|
||||||
|
|
||||||
|
server.on("/networks", HTTP_GET, [](AsyncWebServerRequest *request)
|
||||||
|
{ onGetNetworks(request); });
|
||||||
|
|
||||||
server.onRequestBody([](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)
|
server.onRequestBody([](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)
|
||||||
{
|
{
|
||||||
if (request->url() == "/config" && request->method() == HTTP_PUT) {
|
if (request->url() == "/config" && request->method() == HTTP_PUT) {
|
||||||
onPutConfig(request, data, len, index, total);
|
onPutConfig(request, data, len, index, total);
|
||||||
|
Serial.println("restarting ESP...");
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
} });
|
} });
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
#include "WiFi.h"
|
||||||
|
|
||||||
Preferences config;
|
Preferences config;
|
||||||
|
|
||||||
|
@ -161,3 +162,31 @@ void onPutConfig(AsyncWebServerRequest *request, uint8_t *data, size_t len, size
|
||||||
request->send(400, "text/plain", e.what());
|
request->send(400, "text/plain", e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onGetNetworks(AsyncWebServerRequest *request)
|
||||||
|
{
|
||||||
|
JsonDocument doc;
|
||||||
|
JsonArray array = doc.to<JsonArray>();
|
||||||
|
|
||||||
|
int numberOfNetworks = WiFi.scanComplete();
|
||||||
|
if (numberOfNetworks == WIFI_SCAN_FAILED)
|
||||||
|
{
|
||||||
|
WiFi.scanNetworks(true);
|
||||||
|
}
|
||||||
|
else if (numberOfNetworks)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < numberOfNetworks; ++i)
|
||||||
|
{
|
||||||
|
array.add(WiFi.SSID(i));
|
||||||
|
}
|
||||||
|
WiFi.scanDelete();
|
||||||
|
if (WiFi.scanComplete() == WIFI_SCAN_FAILED)
|
||||||
|
{
|
||||||
|
WiFi.scanNetworks(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String jsonString;
|
||||||
|
serializeJson(doc, jsonString);
|
||||||
|
request->send(200, "application/json", jsonString);
|
||||||
|
}
|
||||||
|
|
|
@ -35,4 +35,6 @@ void onGetConfig(AsyncWebServerRequest *request);
|
||||||
|
|
||||||
void onPutConfig(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total);
|
void onPutConfig(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total);
|
||||||
|
|
||||||
|
void onGetNetworks(AsyncWebServerRequest *request);
|
||||||
|
|
||||||
// #endif
|
// #endif
|
Loading…
Add table
Reference in a new issue