From 537ba64a5458ff70ad3d6a3ac514151843b0ef50 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Wed, 5 Mar 2025 10:31:48 -0300 Subject: [PATCH] add test for ESP32 --- test/arduino/Makefile | 48 ++++---- .../arduino/esp32-http/mongoose_config.h | 2 + .../arduino/nano-w5500-mqtt/mongoose.c | 1 + .../arduino/nano-w5500-mqtt/mongoose.h | 1 + .../arduino/nano-w5500-mqtt/mongoose_config.h | 19 ++++ .../arduino/nano-w5500-mqtt/w5500-mqtt.ino | 103 ++++++++++++++++++ .../arduino/w5500-mqtt/mongoose_config.h | 2 +- 7 files changed, 155 insertions(+), 21 deletions(-) create mode 120000 tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose.c create mode 120000 tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose.h create mode 100644 tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose_config.h create mode 100644 tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/w5500-mqtt.ino diff --git a/test/arduino/Makefile b/test/arduino/Makefile index 15bc3799..6bf50430 100644 --- a/test/arduino/Makefile +++ b/test/arduino/Makefile @@ -1,4 +1,6 @@ -PROJECTS ?= arduino-xiao #arduino-nano #arduino-esp32 arduino-teensy41 +# arduino-nano fails on the flash size department, need to reduce unused function footprint (sha256, sha384 ?) +# teensy41 board management seems to be for 2.0 +PROJECTS ?= seeeduino-xiao esp32 ROOT ?= $(realpath $(CURDIR)/../..) ARD ?= $(realpath $(CURDIR)) @@ -11,38 +13,44 @@ arduino: mv arduino-* $@ ./arduino/arduino --pref "compiler.warning_level=all" --save-prefs -arduino-xiao-board: +seeeduino-xiao-board: ./arduino/arduino --pref "boardsmanager.additional.urls=https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json" --save-prefs ./arduino/arduino --install-boards Seeeduino:samd + touch seeeduino-xiao-board -#esp32-board: -# ./arduino/arduino --pref "boardsmanager.additional.urls=https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" --save-prefs -# ./arduino/arduino --install-boards esp32:esp32 -# -#teensy-board: -# ./arduino/arduino --pref "boardsmanager.additional.urls=https://www.pjrc.com/teensy/package_teensy_index.json" --save-prefs -# ./arduino/arduino --install-boards teensy:avr +esp32-board: + ./arduino/arduino --pref "boardsmanager.additional.urls=https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" --save-prefs + ./arduino/arduino --install-boards esp32:esp32 + touch esp32-board -arduino-xiao: arduino arduino-xiao-board +teensy-board: + ./arduino/arduino --pref "boardsmanager.additional.urls=https://www.pjrc.com/teensy/package_teensy_index.json" --save-prefs + ./arduino/arduino --install-boards teensy:avr + touch teensy-board + +seeeduino-xiao: arduino seeeduino-xiao-board cd $(ROOT)/tutorials/mqtt/mqtt-client/arduino/sim800-mqtt && $(ARD)/arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 sim800-mqtt.ino cd $(ROOT)/tutorials/http/http-server/arduino/w5500-http && $(ARD)/arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 w5500-http.ino cd $(ROOT)/tutorials/mqtt/mqtt-client/arduino/w5500-mqtt && $(ARD)/arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 w5500-mqtt.ino arduino-nano: arduino - cd $(ROOT)/tutorials/http/http-server/arduino/w5500-http && $(ARD)/arduino/arduino --pref compiler.cpp.extra_flags=-DMG_ENABLE_LOG=0 --verbose --verify --board arduino:avr:nano w5500-http.ino - cd $(ROOT)/tutorials/mqtt/mqtt-client/arduino/w5500-mqtt && $(ARD)/arduino/arduino --pref compiler.cpp.extra_flags=-DMG_ENABLE_LOG=0 --verbose --verify --board arduino:avr:nano w5500-mqtt.ino + cd $(ROOT)/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt && $(ARD)/arduino/arduino --pref compiler.cpp.extra_flags=-DMG_ENABLE_LOG=0 --verbose --verify --board arduino:avr:nano nano-w5500-mqtt.ino -#arduino-esp32: arduino esp32-board -# cd $(ROOT)/tutorials/http/http-server/arduino/esp32-http && $(ARD)/arduino/arduino --verbose --verify --board esp32-http.ino -# cd $(ROOT)/tutorials/mqtt/mqtt-client/arduino/esp32-mqtt && $(ARD)/arduino/arduino --verbose --verify --board esp32-mqtt.ino -# -#arduino-teensy41: arduino teensy-board -# cd $(ROOT)/tutorials/http/http-server/arduino/teensy41-http && $(ARD)/arduino/arduino --verbose --verify --board teensy41-http.ino +esp32: arduino esp32-board + cd $(ROOT)/tutorials/mqtt/mqtt-client/arduino/esp32-mqtt && $(ARD)/arduino/arduino --verbose --verify --board esp32:esp32:node32s esp32-mqtt.ino + # Needs a board with 'LED_BUILTIN', yet somehow invocation is missing that definition (lack of include somehow amended by the IDE) + #cd $(ROOT)/tutorials/http/http-server/arduino/esp32-http && $(ARD)/arduino/arduino --verbose --verify --board esp32:esp32:esp32 esp32-http.ino + +teensy41: arduino teensy-board + cd $(ROOT)/tutorials/http/http-server/arduino/teensy41-http && $(ARD)/arduino/arduino --verbose --verify --board teensy41-http.ino clean: rm -rf arduino -cleanall: clean #otherwise some parts of xiao-board installation will fail as already installed - rm -rf ~/.arduino* ~/.oracle_jre_usage +# Board support gets installed in your home dir. +# We fool make satisfying a dependency using touch above, otherwise board installation fails as it is already installed +# To really get rid of the installed board stuff run 'make cleanall' +cleanall: clean + rm -rf ~/.arduino* ~/.oracle_jre_usage seeeduino-xiao-board esp32-board teensy-board diff --git a/tutorials/http/http-server/arduino/esp32-http/mongoose_config.h b/tutorials/http/http-server/arduino/esp32-http/mongoose_config.h index 1149a330..52f33cac 100644 --- a/tutorials/http/http-server/arduino/esp32-http/mongoose_config.h +++ b/tutorials/http/http-server/arduino/esp32-http/mongoose_config.h @@ -1,3 +1,5 @@ #pragma once +#include "Arduino.h" + #define MG_ARCH MG_ARCH_ESP32 diff --git a/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose.c b/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose.c new file mode 120000 index 00000000..fe5764e5 --- /dev/null +++ b/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose.c @@ -0,0 +1 @@ +../../../../../mongoose.c \ No newline at end of file diff --git a/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose.h b/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose.h new file mode 120000 index 00000000..4cd6a2b4 --- /dev/null +++ b/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose.h @@ -0,0 +1 @@ +../../../../../mongoose.h \ No newline at end of file diff --git a/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose_config.h b/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose_config.h new file mode 100644 index 00000000..e58a6157 --- /dev/null +++ b/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/mongoose_config.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Arduino.h" + +#include +#include +#include +#include + +#define MG_ARCH MG_ARCH_CUSTOM +#define MG_ENABLE_TCPIP 1 +#define MG_ENABLE_DRIVER_W5500 1 +#define MG_ENABLE_TCPIP_DRIVER_INIT 0 +#define MG_ENABLE_TCPIP_PRINT_DEBUG_STATS 0 +#define MG_ENABLE_CUSTOM_MILLIS 1 +#define MG_ENABLE_CUSTOM_RANDOM 1 +#define MG_TLS MG_TLS_NONE // no room for TLS +#define MG_IO_SIZE 128 + diff --git a/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/w5500-mqtt.ino b/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/w5500-mqtt.ino new file mode 100644 index 00000000..48307651 --- /dev/null +++ b/tutorials/mqtt/mqtt-client/arduino/nano-w5500-mqtt/w5500-mqtt.ino @@ -0,0 +1,103 @@ +#include +#include "mongoose.h" + +#define MQTT_SERVER "mqtt://broker.hivemq.com:1883" +#define MQTT_SUB_TOPIC "mg/rx" // Subscribe to this topic +#define MQTT_PUB_TOPIC "mg/tx" // Publish to this topic +#define SS_PIN 2 // Slave select pin +#define LED_PIN 21 // LED pin + +struct mg_connection *mqtt_connection; +struct mg_tcpip_spi spi = { + NULL, // SPI metadata + [](void *) { digitalWrite(SS_PIN, LOW); SPI.beginTransaction(SPISettings()); }, + [](void *) { digitalWrite(SS_PIN, HIGH); SPI.endTransaction(); }, + [](void *, uint8_t c) { return SPI.transfer(c); }, // Execute transaction +}; +struct mg_mgr mgr; // Mongoose event manager +struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // Network interface + +uint64_t mg_millis(void) { + return millis(); +} +bool mg_random(void *buf, size_t len) { // For TLS + uint8_t *p = (uint8_t *) buf; + while (len--) *p++ = (unsigned char) (rand() & 255); + return true; +} + +void mqtt_publish(const char *message) { + struct mg_mqtt_opts opts = {}; + opts.topic = mg_str(MQTT_PUB_TOPIC); + opts.message = mg_str(message); + if (mqtt_connection) mg_mqtt_pub(mqtt_connection, &opts); +} + +// Crude function to get available RAM, for quick profiling +size_t getFreeRAM(void) { + size_t size = 0, increment = 100; + void *p; + while ((p = malloc(size)) != NULL) free(p), size += increment; + return size; +} + +// Implement LED control over MQTT: "on" and "off" commands +void handle_command(struct mg_str msg) { + if (msg.len == 3 && memcmp(msg.buf, "off", 3) == 0) { + digitalWrite(LED_PIN, LOW); + mqtt_publish("done - off"); + } else if (msg.len == 2 && memcmp(msg.buf, "on", 2) == 0) { + digitalWrite(LED_PIN, HIGH); + mqtt_publish("done - on"); + } + MG_INFO(("Free RAM: %u bytes", getFreeRAM())); +} + +static void mqtt_ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_MQTT_OPEN) { + MG_INFO(("%lu CONNECTED to %s", c->id, MQTT_SERVER)); + struct mg_mqtt_opts opts = {}; + opts.topic = mg_str(MQTT_SUB_TOPIC); + mg_mqtt_sub(c, &opts); + MG_INFO(("%lu SUBSCRIBED to %s", c->id, MQTT_SUB_TOPIC)); + } else if (ev == MG_EV_MQTT_MSG) { + // Received MQTT message + struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data; + MG_INFO(("%lu RECEIVED %.*s <- %.*s", c->id, (int) mm->data.len, + mm->data.buf, (int) mm->topic.len, mm->topic.buf)); + handle_command(mm->data); + } else if (ev == MG_EV_CLOSE) { + MG_INFO(("%lu CLOSED", c->id)); + mqtt_connection = NULL; + } +} + +void reconnect_if_not_connected(void) { + if (mif.state == MG_TCPIP_STATE_READY && mqtt_connection == NULL) { + struct mg_mqtt_opts opts = {}; + opts.clean = true; + mqtt_connection = + mg_mqtt_connect(&mgr, MQTT_SERVER, &opts, mqtt_ev_handler, NULL); + } +} + +void setup() { + Serial.begin(115200); // Initialise serial + while (!Serial) delay(50); // for debug output + + SPI.begin(); // Iniitialise SPI + pinMode(SS_PIN, OUTPUT); // to communicate with W5500 Ethernet module + pinMode(LED_PIN, OUTPUT); // Initialise LED + + mg_mgr_init(&mgr); // Initialise Mongoose event manager + mg_log_set(MG_LL_DEBUG); // Set debug log level + mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL); // Log serial + mif.driver = &mg_tcpip_driver_w5500; // Use W5500 built-in driver + mif.driver_data = &spi; // Pass SPI interface to W5500 driver + mg_tcpip_init(&mgr, &mif); // Initialise built-in TCP/IP stack +} + +void loop() { + mg_mgr_poll(&mgr, 1); // Process network events + reconnect_if_not_connected(); // Reconnect to MQTT server if needed +} diff --git a/tutorials/mqtt/mqtt-client/arduino/w5500-mqtt/mongoose_config.h b/tutorials/mqtt/mqtt-client/arduino/w5500-mqtt/mongoose_config.h index d9e625d8..093742f7 100644 --- a/tutorials/mqtt/mqtt-client/arduino/w5500-mqtt/mongoose_config.h +++ b/tutorials/mqtt/mqtt-client/arduino/w5500-mqtt/mongoose_config.h @@ -16,5 +16,5 @@ #define MG_ENABLE_CUSTOM_MILLIS 1 #define MG_ENABLE_CUSTOM_RANDOM 1 // #define MG_TLS MG_TLS_BUILTIN -#define MG_IO_SIZE 128 +#define MG_IO_SIZE 256