From 2784a4bb79b733be247579e2b1d62bdd0d31dbd5 Mon Sep 17 00:00:00 2001 From: Vincent Winter Date: Wed, 5 Nov 2025 10:59:53 +0100 Subject: [PATCH] fix(esp32-IMU): Add toggle functionality MQTT/Serial using boot button --- IMU/main/mpu6886.c | 184 ++++++++++++++++++++++++++++----------------- IMU/main/mpu6886.h | 11 +++ 2 files changed, 127 insertions(+), 68 deletions(-) diff --git a/IMU/main/mpu6886.c b/IMU/main/mpu6886.c index 93a8fa9..c6a0297 100644 --- a/IMU/main/mpu6886.c +++ b/IMU/main/mpu6886.c @@ -1,67 +1,115 @@ #include "mpu6886.h" -#ifdef CONFIG_ENV_MQTT_ENABLED - static void wifi_init() - { - ESP_ERROR_CHECK(nvs_flash_init()); - ESP_ERROR_CHECK(esp_netif_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); +static void IRAM_ATTR button_isr_handler(void* arg) { + uint32_t gpio_num = (uint32_t)arg; + // Keep it short — avoid delays, logging, malloc, etc. + mqtt_toggle = !mqtt_toggle; + toggle_completed = false; + esp_rom_printf("Button pressed! GPIO: %lu\n", gpio_num); +} - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); +static void init_button(void) { + gpio_config_t io_conf = { + .intr_type = GPIO_INTR_NEGEDGE, // Trigger on falling edge + .mode = GPIO_MODE_INPUT, + .pin_bit_mask = (1ULL << BOOT_BUTTON_GPIO), + .pull_up_en = GPIO_PULLUP_ENABLE, // Use pull-up since button pulls low + .pull_down_en = GPIO_PULLDOWN_DISABLE + }; + gpio_config(&io_conf); - #ifdef CONFIG_WIFI_AP_MODE - esp_netif_create_default_wifi_ap(); + // Install GPIO ISR service + gpio_install_isr_service(0); // Pass 0 for default interrupt flags + // Attach the interrupt handler + gpio_isr_handler_add(BOOT_BUTTON_GPIO, button_isr_handler, (void*)BOOT_BUTTON_GPIO); +} - wifi_config_t wifi_config = { 0 }; - strncpy((char*)wifi_config.ap.ssid, CONFIG_WIFI_AP_SSID, sizeof(wifi_config.ap.ssid)); - wifi_config.ap.ssid_len = strlen(CONFIG_WIFI_AP_SSID); - strncpy((char*)wifi_config.ap.password, CONFIG_WIFI_AP_PASSWORD, sizeof(wifi_config.ap.password)); - wifi_config.ap.max_connection = 4; - if (strlen(CONFIG_WIFI_AP_PASSWORD) == 0) { - wifi_config.ap.authmode = WIFI_AUTH_OPEN; - } else { - wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK; - } +static void wifi_init() +{ + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI("WIFI", "AP started SSID:%s", CONFIG_WIFI_AP_SSID); - #else - esp_netif_create_default_wifi_sta(); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - wifi_config_t wifi_config = { - .sta = { - .ssid = CONFIG_WIFI_SSID, - .password = CONFIG_WIFI_PASSWORD, - }, - }; +#ifdef CONFIG_WIFI_AP_MODE + wifi_netif = esp_netif_create_default_wifi_ap(); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_ERROR_CHECK(esp_wifi_connect()); - ESP_LOGI("WIFI", "STA started, connecting to: %s", CONFIG_WIFI_SSID); - #endif + wifi_config_t wifi_config = { 0 }; + strncpy((char*)wifi_config.ap.ssid, CONFIG_WIFI_AP_SSID, sizeof(wifi_config.ap.ssid)); + wifi_config.ap.ssid_len = strlen(CONFIG_WIFI_AP_SSID); + strncpy((char*)wifi_config.ap.password, CONFIG_WIFI_AP_PASSWORD, sizeof(wifi_config.ap.password)); + wifi_config.ap.max_connection = 4; + if (strlen(CONFIG_WIFI_AP_PASSWORD) == 0) { + wifi_config.ap.authmode = WIFI_AUTH_OPEN; + } else { + wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK; } - static void mqtt_app_start(void) - { - esp_mqtt_client_config_t mqtt_cfg = { 0 }; + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + ESP_LOGI("WIFI", "AP started SSID:%s", CONFIG_WIFI_AP_SSID); +#else + wifi_netif = esp_netif_create_default_wifi_sta(); - mqtt_cfg.broker.address.uri = CONFIG_MQTT_BROKER_URI; + wifi_config_t wifi_config = { + .sta = { + .ssid = CONFIG_WIFI_SSID, + .password = CONFIG_WIFI_PASSWORD, + }, + }; - s_mqtt_client = esp_mqtt_client_init(&mqtt_cfg); - if (s_mqtt_client == NULL) { - ESP_LOGW("MQTT", "failed to init mqtt client"); - return; - } - esp_mqtt_client_start(s_mqtt_client); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + ESP_ERROR_CHECK(esp_wifi_connect()); + ESP_LOGI("WIFI", "STA started, connecting to: %s", CONFIG_WIFI_SSID); +#endif + wifi_initialized = true; +} + +static void wifi_deinit(void) +{ + ESP_ERROR_CHECK(esp_wifi_stop()); + ESP_ERROR_CHECK(esp_wifi_deinit()); + + if (wifi_netif != NULL) { + esp_netif_destroy_default_wifi(wifi_netif); + wifi_netif = NULL; } -#endif // CONFIG_ENV_MQTT_ENABLED + ESP_ERROR_CHECK(esp_event_loop_delete_default()); + // ESP_ERROR_CHECK(esp_netif_deinit()); + ESP_ERROR_CHECK(nvs_flash_deinit()); + ESP_LOGI("WIFI", "Wi-Fi stopped and deinitialized"); + wifi_initialized = false; +} + +static void mqtt_app_start(void) +{ + esp_mqtt_client_config_t mqtt_cfg = { 0 }; + + mqtt_cfg.broker.address.uri = CONFIG_MQTT_BROKER_URI; + + s_mqtt_client = esp_mqtt_client_init(&mqtt_cfg); + if (s_mqtt_client == NULL) { + ESP_LOGW("MQTT", "failed to init mqtt client"); + return; + } + esp_mqtt_client_start(s_mqtt_client); +} + +static void mqtt_app_stop(void) +{ + if (s_mqtt_client != NULL) { + esp_mqtt_client_stop(s_mqtt_client); + esp_mqtt_client_destroy(s_mqtt_client); + s_mqtt_client = NULL; + } +} static esp_err_t mpu6886_write_byte(mpu6886_t* dev, uint8_t reg, uint8_t data) { uint8_t tx[2] = { reg, data }; @@ -141,7 +189,7 @@ esp_err_t mpu6886_init(mpu6886_t* dev, i2c_port_t i2c_port) { // Auto select clock if (mpu6886_write_byte(dev, MPU6886_PWR_MGMT_1, 0x01) != ESP_OK) return ESP_FAIL; - // Default config: set to ±2G accel, ±250DPS gyro (device may have different settings; we'll detect them) + // Default config: set to ±2G accel, ±250DPS gyro mpu6886_write_byte(dev, MPU6886_ACCEL_CONFIG, 0x00); mpu6886_write_byte(dev, MPU6886_GYRO_CONFIG, 0x00); @@ -242,14 +290,7 @@ void app_main(void) return; } - -#ifdef CONFIG_ENV_MQTT_ENABLED - wifi_init(); - // Start MQTT client (will retry until network is available) - mqtt_app_start(); -#endif - - + init_button(); mpu6886_t mpu; mpu.i2c_port = I2C_NUM_0; mpu.address = MPU6886_ADDR; @@ -260,25 +301,28 @@ void app_main(void) return; } - - mpu6886_calibrate_gyro(&mpu, 100, 10); mpu6886_calibrate_accel(&mpu, 100, 10); vec3_t accel, gyro; float temp; while (1) { + if (mqtt_toggle && !toggle_completed && !wifi_initialized) { + wifi_init(); + mqtt_app_start(); + ESP_LOGI("BOOT", "Boot button pressed: starting in MQTT mode"); + toggle_completed = true; + } else if (!mqtt_toggle && !toggle_completed && wifi_initialized) { + mqtt_app_stop(); + wifi_deinit(); + ESP_LOGI("BOOT", "Boot button not pressed: starting in serial-only mode"); + toggle_completed = true; + } mpu6886_read_accel(&mpu, &accel); mpu6886_read_gyro(&mpu, &gyro); mpu6886_read_temp(&mpu, &temp); -#ifndef CONFIG_ENV_MQTT_ENABLED - printf("{\"accel\":{\"x\":%8.3f,\"y\":%8.3f,\"z\":%8.3f},\"gyro\":{\"x\":%8.3f,\"y\":%8.3f,\"z\":%8.3f},\"Temp\":%8.2f}\n", - accel.x, accel.y, accel.z, - gyro.x, gyro.y, gyro.z, - temp); -#else - if (s_mqtt_client != NULL) { + if (mqtt_toggle && s_mqtt_client != NULL) { char payload[256]; int n = snprintf(payload, sizeof(payload), "{\"accel\":{\"x\":%8.3f,\"y\":%8.3f,\"z\":%8.3f},\"gyro\":{\"x\":%8.3f,\"y\":%8.3f,\"z\":%8.3f},\"Temp\":%8.2f}", @@ -291,8 +335,12 @@ void app_main(void) } else { ESP_LOGW("MQTT", "payload truncated or encoding error"); } + } else { + printf("{\"accel\":{\"x\":%8.3f,\"y\":%8.3f,\"z\":%8.3f},\"gyro\":{\"x\":%8.3f,\"y\":%8.3f,\"z\":%8.3f},\"Temp\":%8.2f}\n", + accel.x, accel.y, accel.z, + gyro.x, gyro.y, gyro.z, + temp); } -#endif vTaskDelay(pdMS_TO_TICKS(500)); } } diff --git a/IMU/main/mpu6886.h b/IMU/main/mpu6886.h index c8d5963..0e9ed71 100644 --- a/IMU/main/mpu6886.h +++ b/IMU/main/mpu6886.h @@ -13,6 +13,9 @@ #include "mqtt_client.h" #include #include +#include "driver/gpio.h" +#include "esp_rom_sys.h" + #define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< GPIO number used for I2C master clock */ #define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< GPIO number used for I2C master data */ @@ -22,6 +25,8 @@ #define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ #define I2C_MASTER_TIMEOUT_MS 1000 +#define BOOT_BUTTON_GPIO 0 // GPIO number for boot mode selection button + #define MPU6886_ADDR 0x68 // MPU6886 Registers @@ -66,6 +71,12 @@ typedef struct { vec3_t accel_offset; } mpu6886_t; +bool mqtt_toggle = false; +bool toggle_completed = false; +bool wifi_initialized = false; + +esp_netif_t* wifi_netif = NULL; + static esp_mqtt_client_handle_t s_mqtt_client = NULL; // Function declarations