From 12a601860c090438f5efe8c224ac3a077d9c64e6 Mon Sep 17 00:00:00 2001 From: Philipp Kramer Date: Tue, 1 Oct 2024 15:13:57 +0200 Subject: [PATCH] working mqtt over ethernet --- platformio.ini | 8 ++ src/main.cpp | 217 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 204 insertions(+), 21 deletions(-) diff --git a/platformio.ini b/platformio.ini index f2303dd..15592be 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,8 +13,16 @@ platform = espressif32 board = esp32-poe-iso framework = arduino +monitor_speed = 115200 + + +build_flags = + '-D MQTT_BASETOPIC="lightbutton_test"' + lib_deps= ethernet BluetoothSerial SPI adafruit/Adafruit seesaw Library@^1.7.8 + + adafruit/Adafruit MQTT Library@^2.5.8 diff --git a/src/main.cpp b/src/main.cpp index 6d240cc..71626c7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,44 @@ #include "Adafruit_NeoKey_1x4.h" #include "seesaw_neopixel.h" +#include "Adafruit_MQTT.h" +#include "Adafruit_MQTT_Client.h" + + +/************************* WiFi Access Point *********************************/ + +#define WLAN_SSID "TheaterDo-ATD" +#define WLAN_PASS "PASSWORD" + +/************************* MQTT Setup *********************************/ + +#define MQTT_SERVER "nodered.atd.theaterdo.net" +#define MQTT_SERVERPORT 1883 // use 8883 for SSL + +#define MQTT_USERNAME "__USERNAME__" +#define MQTT_PASSWORD "__PASSWORD__" + + +static bool eth_connected = false; + + +// Create an ESP8266 WiFiClient class to connect to the MQTT server. +WiFiClient client; +// or... use WiFiFlientSecure for SSL +//WiFiClientSecure client; + +// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details. +//Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, MQTT_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD); +Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, MQTT_SERVERPORT); + + +Adafruit_MQTT_Publish statusPub = Adafruit_MQTT_Publish(&mqtt, MQTT_BASETOPIC"/status"); + +void WiFiEvent(WiFiEvent_t event); +void MQTT_connect(); + + +bool nokey_enabled=false; Adafruit_NeoKey_1x4 neokey; // Create the NeoKey object uint32_t Wheel(byte WheelPos); @@ -33,40 +71,149 @@ NeoKey1x4Callback blink(keyEvent evt) { void setup() { Serial.begin(115200); while (! Serial) delay(10); - + + + // Connect to WiFi access point. + /* + Serial.println(); Serial.println(); + Serial.print("Connecting to "); + Serial.println(WLAN_SSID); + + WiFi.begin(WLAN_SSID, WLAN_PASS); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(); + + Serial.println("WiFi connected"); + Serial.println("IP address: "); Serial.println(WiFi.localIP()); + */ + + // Add a handler for network events. This is misnamed "WiFi" because the ESP32 is historically WiFi only, + // but in our case, this will react to Ethernet events. + Serial.print("Registering event handler for ETH events..."); + WiFi.onEvent(WiFiEvent); + Serial.print("Starting ETH interface..."); + ETH.begin(); + + // Send Hello World Notification + + + + + if (! neokey.begin(0x30)) { // begin with I2C address, default is 0x30 Serial.println("Could not start NeoKey, check wiring?"); - while(1) delay(10); + nokey_enabled=false; + }else{ + nokey_enabled=true; + } + + if (nokey_enabled) + { + Serial.println("NeoKey started!"); + + // Pulse all the LEDs on to show we're working + for (uint16_t i=0; i 1000){ + last_status_send=millis(); + if (!eth_connected){ + Serial.println("Waiting for ethernet connection"); + }else{ + Serial.print(F("\nSending Hello!")); + Serial.print("..."); + if (! statusPub.publish("Hello")) { + Serial.println(F("Failed")); + } else { + Serial.println(F("OK!")); + } + } + } delay(10); // don't print too fast } +// React to Ethernet events:- +void WiFiEvent(WiFiEvent_t event) +{ + switch (event) { + + case ARDUINO_EVENT_ETH_START: + // This will happen during setup, when the Ethernet service starts + Serial.println("ETH Started"); + //set eth hostname here + ETH.setHostname("esp32-ethernet"); + break; + + case ARDUINO_EVENT_ETH_CONNECTED: + // This will happen when the Ethernet cable is plugged + Serial.println("ETH Connected"); + break; + + case ARDUINO_EVENT_ETH_GOT_IP: + // This will happen when we obtain an IP address through DHCP: + Serial.print("Got an IP Address for ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); + eth_connected = true; + + MQTT_connect(); + + + break; + + case ARDUINO_EVENT_ETH_DISCONNECTED: + // This will happen when the Ethernet cable is unplugged + Serial.println("ETH Disconnected"); + eth_connected = false; + break; + + case ARDUINO_EVENT_ETH_STOP: + // This will happen when the ETH interface is stopped but this never happens + Serial.println("ETH Stopped"); + eth_connected = false; + break; + + default: + break; + } +} + /******************************************/ @@ -83,4 +230,32 @@ uint32_t Wheel(byte WheelPos) { return seesaw_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3); } return 0; +} + + +// Function to connect and reconnect as necessary to the MQTT server. +// Should be called in the loop function and it will take care if connecting. +void MQTT_connect() { + int8_t ret; + + // Stop if already connected. + if (mqtt.connected()) { + return; + } + + Serial.print("Connecting to MQTT... "); + + uint8_t retries = 3; + while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected + Serial.println(mqtt.connectErrorString(ret)); + Serial.println("Retrying MQTT connection in 5 seconds..."); + mqtt.disconnect(); + delay(5000); // wait 5 seconds + retries--; + if (retries == 0) { + // basically die and wait for WDT to reset me + while (1); + } + } + Serial.println("MQTT Connected!"); } \ No newline at end of file