|
| 1 | +#include "WiFi.h" |
| 2 | +#include "mongoose.h" |
| 3 | + |
| 4 | +#define WIFI_SSID "wifi_network_name" // Change this |
| 5 | +#define WIFI_PASS "wifi_password" // And this |
| 6 | + |
| 7 | +#define MQTT_SERVER "mqtt://broker.hivemq.com:1883" |
| 8 | +#define MQTT_SUB_TOPIC "mg/rx" // Subscribe to this topic |
| 9 | +#define MQTT_PUB_TOPIC "mg/tx" // Publish to this topic |
| 10 | + |
| 11 | +#define LED_PIN 0 |
| 12 | + |
| 13 | +struct mg_mgr mgr; |
| 14 | +struct mg_connection *mqtt_connection; |
| 15 | + |
| 16 | +void mqtt_publish(const char *message) { |
| 17 | + struct mg_mqtt_opts opts = {}; |
| 18 | + opts.topic = mg_str(MQTT_PUB_TOPIC); |
| 19 | + opts.message = mg_str(message); |
| 20 | + if (mqtt_connection) mg_mqtt_pub(mqtt_connection, &opts); |
| 21 | +} |
| 22 | + |
| 23 | +// Crude function to get available RAM, for quick profiling |
| 24 | +size_t getFreeRAM(void) { |
| 25 | + size_t size = 0, increment = 100; |
| 26 | + void *p; |
| 27 | + while ((p = malloc(size)) != NULL) free(p), size += increment; |
| 28 | + return size; |
| 29 | +} |
| 30 | + |
| 31 | +// Implement LED control over MQTT: "on" and "off" commands |
| 32 | +void handle_command(struct mg_str msg) { |
| 33 | + if (msg.len == 3 && memcmp(msg.buf, "off", 3) == 0) { |
| 34 | + digitalWrite(LED_PIN, LOW); |
| 35 | + mqtt_publish("done - off"); |
| 36 | + } else if (msg.len == 2 && memcmp(msg.buf, "on", 2) == 0) { |
| 37 | + digitalWrite(LED_PIN, HIGH); |
| 38 | + mqtt_publish("done - on"); |
| 39 | + } |
| 40 | + MG_INFO(("Free RAM: %u bytes", getFreeRAM())); |
| 41 | +} |
| 42 | + |
| 43 | +static void mqtt_ev_handler(struct mg_connection *c, int ev, void *ev_data) { |
| 44 | + if (ev == MG_EV_MQTT_OPEN) { |
| 45 | + MG_INFO(("%lu CONNECTED to %s", c->id, MQTT_SERVER)); |
| 46 | + struct mg_mqtt_opts opts = {}; |
| 47 | + opts.topic = mg_str(MQTT_SUB_TOPIC); |
| 48 | + mg_mqtt_sub(c, &opts); |
| 49 | + MG_INFO(("%lu SUBSCRIBED to %s", c->id, MQTT_SUB_TOPIC)); |
| 50 | + } else if (ev == MG_EV_MQTT_MSG) { |
| 51 | + // Received MQTT message |
| 52 | + struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data; |
| 53 | + MG_INFO(("%lu RECEIVED %.*s <- %.*s", c->id, (int) mm->data.len, |
| 54 | + mm->data.buf, (int) mm->topic.len, mm->topic.buf)); |
| 55 | + handle_command(mm->data); |
| 56 | + } else if (ev == MG_EV_CLOSE) { |
| 57 | + MG_INFO(("%lu CLOSED", c->id)); |
| 58 | + mqtt_connection = NULL; |
| 59 | + } |
| 60 | +} |
| 61 | + |
| 62 | +void reconnect_if_not_connected(void) { |
| 63 | + if (mqtt_connection == NULL) { |
| 64 | + struct mg_mqtt_opts opts = {}; |
| 65 | + opts.clean = true; |
| 66 | + mqtt_connection = |
| 67 | + mg_mqtt_connect(&mgr, MQTT_SERVER, &opts, mqtt_ev_handler, NULL); |
| 68 | + } |
| 69 | +} |
| 70 | + |
| 71 | +void setup() { |
| 72 | + pinMode(LED_PIN, OUTPUT); |
| 73 | + Serial.begin(115200); |
| 74 | + while (!Serial) delay(50); |
| 75 | + |
| 76 | + WiFi.mode(WIFI_STA); |
| 77 | + WiFi.begin(WIFI_SSID, WIFI_PASS); |
| 78 | + while (WiFi.status() != WL_CONNECTED) Serial.print("."), delay(100); |
| 79 | + |
| 80 | + Serial.println("\nConnected to the WiFi network"); |
| 81 | + Serial.print("IP Address: "); |
| 82 | + Serial.println(WiFi.localIP()); |
| 83 | + |
| 84 | + mg_mgr_init(&mgr); |
| 85 | + mg_log_set(MG_LL_DEBUG); |
| 86 | + mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL); |
| 87 | +} |
| 88 | + |
| 89 | +void loop() { |
| 90 | + mg_mgr_poll(&mgr, 1); // Process network events |
| 91 | + reconnect_if_not_connected(); // Reconnect to MQTT server if needed |
| 92 | +} |
| 93 | + |
| 94 | +extern "C" int lwip_hook_ip6_input(struct pbuf *p, struct netif *inp) |
| 95 | + __attribute__((weak)); |
| 96 | +extern "C" int lwip_hook_ip6_input(struct pbuf *p, struct netif *inp) { |
| 97 | + if (ip6_addr_isany_val(inp->ip6_addr[0].u_addr.ip6)) { |
| 98 | + pbuf_free(p); |
| 99 | + return 1; |
| 100 | + } |
| 101 | + return 0; |
| 102 | +} |
0 commit comments