diff --git a/.vscode/arduino.json b/.vscode/arduino.json index 570555d..6f5baf3 100644 --- a/.vscode/arduino.json +++ b/.vscode/arduino.json @@ -1,5 +1,5 @@ { "board": "esp8266:esp8266:d1", "configuration": "xtal=80,vt=flash,exception=disabled,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600", - "port": "/dev/cu.wchusbserial230" + "port": "/dev/cu.wchusbserial144220" } \ No newline at end of file diff --git a/.vscode/ipch/e89e887f3099ca3f/main.ipch b/.vscode/ipch/e89e887f3099ca3f/main.ipch deleted file mode 100644 index 6f548d3..0000000 Binary files a/.vscode/ipch/e89e887f3099ca3f/main.ipch and /dev/null differ diff --git a/.vscode/ipch/e89e887f3099ca3f/mmap_address.bin b/.vscode/ipch/e89e887f3099ca3f/mmap_address.bin deleted file mode 100644 index f8ee5b7..0000000 Binary files a/.vscode/ipch/e89e887f3099ca3f/mmap_address.bin and /dev/null differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..0505a2a --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# Audio2 Cabin Light System by lbsfilm + + +This is a simple system of lights for the phone system of Audio 2 + +There is a controller and 4 clients, all built into the light cylinders + +## Software + +The controller is running EspAsyncWebserver and the clients run a websocket client library. +There is no kind of encryption (HTTP Basic Auth can be enabeled in the code though) + +## Hardware + +All Boards are built uisng the ESP32 POE Board (non isolated) by OLIMEX + +### Pinings + +Every Board is connected to the Lamp by a single GPO, The power has to be taken from the 48Volts of the POE input and be regulated to 12V(?) for the Lamp \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index aa88a70..e0f970f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,34 +13,44 @@ platform = espressif32 board = esp32-poe framework = arduino -upload_port=/dev/tty.wchusbserial230 +upload_port=/dev/cu.wchusbserial144220 monitor_baud = 115200 +build_flags = -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG [env:controller] +platform = espressif32 +board = esp32-poe +framework = arduino + +monitor_baud = 115200 + src_filter = + lib_deps = ESP Async WebServer -[env:LIGHT1] +[env:light1] src_filter = + lib_deps = WebSockets -build_flags = -DROLE=LIGHT1 -[env:LIGHT2] + build_flags = -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG + +;build_flags = -DROLE=LIGHT1 + +[env:light2] src_filter = + lib_deps = WebSockets build_flags = -DROLE=LIGHT2 -[env:LIGHT3] +[env:light3] src_filter = + lib_deps = WebSockets build_flags = -DROLE=LIGHT3 -[env:LIGHT3] +[env:light4] src_filter = + lib_deps = WebSockets diff --git a/src/controller_main.cpp b/src/controller_main.cpp index 228159b..6d4d208 100644 --- a/src/controller_main.cpp +++ b/src/controller_main.cpp @@ -14,36 +14,35 @@ AsyncWebSocket ws("/ws"); const char *PARAM_MESSAGE = "message"; - -void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ - if(type == WS_EVT_CONNECT){ +void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { + if (type == WS_EVT_CONNECT) { Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); client->printf("Hello Client %u :)", client->id()); client->ping(); - } else if(type == WS_EVT_DISCONNECT){ + } else if (type == WS_EVT_DISCONNECT) { Serial.printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id()); - } else if(type == WS_EVT_ERROR){ - Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); - } else if(type == WS_EVT_PONG){ - Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); - } else if(type == WS_EVT_DATA){ - AwsFrameInfo * info = (AwsFrameInfo*)arg; + } else if (type == WS_EVT_ERROR) { + Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t *)arg), (char *)data); + } else if (type == WS_EVT_PONG) { + Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len) ? (char *)data : ""); + } else if (type == WS_EVT_DATA) { + AwsFrameInfo *info = (AwsFrameInfo *)arg; String msg = ""; - if(info->final && info->index == 0 && info->len == len){ - //the whole message is in a single frame and we got all of it's data - Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); + if (info->final && info->index == 0 && info->len == len) { + // the whole message is in a single frame and we got all of it's data + Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT) ? "text" : "binary", info->len); - if(info->opcode == WS_TEXT){ - for(size_t i=0; i < info->len; i++) { - msg += (char) data[i]; + if (info->opcode == WS_TEXT) { + for (size_t i = 0; i < info->len; i++) { + msg += (char)data[i]; } } - if(info->opcode == WS_TEXT) + if (info->opcode == WS_TEXT) client->text("I got your text message"); - + } else { - Serial.printf("Error: Message in multiple Frames"); + Serial.printf("Error: Message in multiple Frames"); } } } @@ -104,7 +103,20 @@ void setup() { Serial.println("mDNS responder started"); ws.onEvent(onWsEvent); + server.addHandler(&ws); + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { request->send(200, "text/plain", "Current Status: To Be done"); }); + + server.on("/allon", HTTP_GET, [](AsyncWebServerRequest *request) { + ws.textAll("blinkLamp"); + request->send(200, "text/plain", "Alarming All"); + }); + + server.on("/alloff", HTTP_GET, [](AsyncWebServerRequest *request) { + ws.textAll("noBlinkLamp"); + request->send(200, "text/plain", "Alarm stopped"); + }); + server.onNotFound(notFound); server.begin(); @@ -114,10 +126,4 @@ void setup() { void loop() {} - - - - /////////////////////////// - - diff --git a/src/light_main.cpp b/src/light_main.cpp index 747ab6a..08483c7 100644 --- a/src/light_main.cpp +++ b/src/light_main.cpp @@ -1,14 +1,26 @@ #include -#include #include +#include #define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT #define ETH_PHY_POWER 12 #include -WebSocketsClient webSocket; +#define blinkDuration 500 +#define connectDuration 1000 +#define lampOutputPin 12 +bool isBlinking = false; +bool lampState = false; + +long blinkTimer = 0; +long connectTimer = 0; + +bool foundIp = false; +IPAddress ip; + +WebSocketsClient webSocket; static bool eth_connected = false; @@ -50,38 +62,50 @@ void WiFiEvent(WiFiEvent_t event) { } } -void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { +void blinkLamp() { isBlinking = true; } - switch(type) { - case WStype_DISCONNECTED: - USE_SERIAL.printf("[WSc] Disconnected!\n"); - break; - case WStype_CONNECTED: { - USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); +void noBlinkLamp() { + isBlinking = false; + lampState = false; + digitalWrite(lampOutputPin, LOW); +} - // send message to server when Connected - webSocket.sendTXT("Connected"); - } - break; - case WStype_TEXT: - USE_SERIAL.printf("[WSc] get text: %s\n", payload); +void webSocketEvent(WStype_t type, uint8_t *payload, size_t length) { - // send message to server - // webSocket.sendTXT("message here"); - break; - case WStype_BIN: - USE_SERIAL.printf("[WSc] get binary length: %u\n", length); - hexdump(payload, length); - - // send data to server - // webSocket.sendBIN(payload, length); - break; - } + switch (type) { + case WStype_DISCONNECTED: + Serial.println("[WSc] Disconnected!"); + break; + case WStype_CONNECTED: { + Serial.print("[WSc] Connected to controller"); + webSocket.sendTXT("event: con lamp: 1"); + } break; + case WStype_TEXT: + Serial.print("[WSc] get text:"); + Serial.println((char *)payload); + if (strcmp((char *)payload, "blinkLamp") == 0) { + blinkLamp(); + Serial.println("Enable Blinking!"); + } else if (strcmp((char *)payload, "noBlinkLamp") == 0) { + noBlinkLamp(); + Serial.println("Disable Blinking!"); + } + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + Serial.println("[WSc] get binary "); + // send data to server + // webSocket.sendBIN(payload, length); + break; + } } void setup() { Serial.begin(115200); + pinMode(lampOutputPin, OUTPUT); + WiFi.onEvent(WiFiEvent); ETH.begin(); @@ -90,32 +114,68 @@ void setup() { } if (!MDNS.begin("a2clight")) { - Serial.println("Error setting up MDNS responder!, system halt"); + Serial.println("Error setting up MDNS responder!"); while (1) { delay(1000); } } - Serial.println("mDNS responder started"); +} - webSocket.begin("a2clcontroller.local", 80, "/ws"); - webSocket.onEvent(webSocketEvent); +void browseService(const char *service, const char *proto) { + Serial.printf("Browsing for service _%s._%s.local. ... ", service, proto); + int n = MDNS.queryService(service, proto); + if (n == 0) { + Serial.println("no services found"); + } else { + Serial.print(n); + Serial.println(" service(s) found"); + for (int i = 0; i < n; ++i) { + // Print details for each service found + Serial.print(" "); + Serial.print(i + 1); + Serial.print(": "); + Serial.print(MDNS.hostname(i)); + Serial.print(" ("); + Serial.print(MDNS.IP(i)); + Serial.print(":"); + Serial.print(MDNS.port(i)); + Serial.println(")"); - // use HTTP Basic Authorization this is optional remove if not needed - //webSocket.setAuthorization("user", "Password"); + if (MDNS.hostname(i) == "a2clcontroller") { + Serial.println("Trying to connect"); + Serial.println(MDNS.IP(i)); - // try ever 5000 again if connection has failed - webSocket.setReconnectInterval(5000); - - // start heartbeat (optional) - // ping server every 15000 ms - // expect pong from server within 3000 ms - // consider connection disconnected if pong is not received 2 times - webSocket.enableHeartbeat(15000, 3000, 2); - - // Add service to MDNS-SD - // MDNS.addService("http", "tcp", 80); + foundIp = true; + ip = MDNS.IP(i); + webSocket.begin(ip, 80, "/ws"); + webSocket.onEvent(webSocketEvent); + // webSocket.setAuthorization("user", "Password"); + webSocket.setReconnectInterval(3000); + // webSocket.enableHeartbeat(15000, 3000, 2); + } + } + } + Serial.println(); } void loop() { - webSocket.loop(); -} \ No newline at end of file + if (!foundIp && eth_connected && ((millis() - connectTimer) > connectDuration)) { + // browseService("http", "tcp"); + ip = MDNS.queryHost("a2clcontroller"); + Serial.println(ip); + foundIp = true; + webSocket.begin(ip, 80, "/ws"); + webSocket.onEvent(webSocketEvent); + // webSocket.setAuthorization("user", "Password"); + webSocket.setReconnectInterval(3000); + connectTimer = millis(); + } + + // webSocket.loop(); + + if (millis() - blinkTimer > blinkDuration) { + lampState = !lampState; + digitalWrite(lampOutputPin, lampState); + blinkTimer = millis(); + } +}