[PR] Add MQTT/Serial toggle using the boot button #12

Merged
wessel merged 3 commits from 2-imu-reader/esp32-IMU into 2-imu-reader/master 2025-11-05 12:22:41 +01:00
3 changed files with 130 additions and 80 deletions

View File

@@ -6,33 +6,25 @@ menu "ESP32 IMU Project Configuration"
config I2C_MASTER_SCL config I2C_MASTER_SCL
int "SCL GPIO Num" int "SCL GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 4 default 22
help help
GPIO number for I2C Master clock line. GPIO number for I2C Master clock line.
config I2C_MASTER_SDA config I2C_MASTER_SDA
int "SDA GPIO Num" int "SDA GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 5 default 21
help help
GPIO number for I2C Master data line. GPIO number for I2C Master data line.
config I2C_MASTER_FREQUENCY config I2C_MASTER_FREQUENCY
int "Master Frequency" int "Master Frequency"
default 400000 default 100000
help help
I2C Speed of Master device. I2C Speed of Master device.
endmenu endmenu
config ENV_MQTT_ENABLED
bool "Enable MQTT Communication"
default y
help
Enable this option to use MQTT for communication.
If disabled, communication will use usb uart connection.
menu "MQTT Configuration" menu "MQTT Configuration"
depends on ENV_MQTT_ENABLED
config MQTT_BROKER_URI config MQTT_BROKER_URI
string "MQTT Broker URI" string "MQTT Broker URI"
default "mqtt://192.168.4.2:1883" default "mqtt://192.168.4.2:1883"
@@ -47,7 +39,6 @@ menu "ESP32 IMU Project Configuration"
endmenu endmenu
menu "WiFi Access Point Configuration" menu "WiFi Access Point Configuration"
depends on ENV_MQTT_ENABLED
config WIFI_AP_MODE config WIFI_AP_MODE
bool "Enable WiFi AP Mode" bool "Enable WiFi AP Mode"
default y default y

View File

@@ -1,6 +1,29 @@
#include "mpu6886.h" #include "mpu6886.h"
#ifdef CONFIG_ENV_MQTT_ENABLED
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);
}
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);
// 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);
}
static void wifi_init() static void wifi_init()
{ {
@@ -12,7 +35,7 @@
ESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_ERROR_CHECK(esp_wifi_init(&cfg));
#ifdef CONFIG_WIFI_AP_MODE #ifdef CONFIG_WIFI_AP_MODE
esp_netif_create_default_wifi_ap(); wifi_netif = esp_netif_create_default_wifi_ap();
wifi_config_t wifi_config = { 0 }; wifi_config_t wifi_config = { 0 };
strncpy((char*)wifi_config.ap.ssid, CONFIG_WIFI_AP_SSID, sizeof(wifi_config.ap.ssid)); strncpy((char*)wifi_config.ap.ssid, CONFIG_WIFI_AP_SSID, sizeof(wifi_config.ap.ssid));
@@ -30,7 +53,7 @@
ESP_ERROR_CHECK(esp_wifi_start()); ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI("WIFI", "AP started SSID:%s", CONFIG_WIFI_AP_SSID); ESP_LOGI("WIFI", "AP started SSID:%s", CONFIG_WIFI_AP_SSID);
#else #else
esp_netif_create_default_wifi_sta(); wifi_netif = esp_netif_create_default_wifi_sta();
wifi_config_t wifi_config = { wifi_config_t wifi_config = {
.sta = { .sta = {
@@ -45,6 +68,24 @@
ESP_ERROR_CHECK(esp_wifi_connect()); ESP_ERROR_CHECK(esp_wifi_connect());
ESP_LOGI("WIFI", "STA started, connecting to: %s", CONFIG_WIFI_SSID); ESP_LOGI("WIFI", "STA started, connecting to: %s", CONFIG_WIFI_SSID);
#endif #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;
}
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) static void mqtt_app_start(void)
@@ -61,7 +102,14 @@
esp_mqtt_client_start(s_mqtt_client); esp_mqtt_client_start(s_mqtt_client);
} }
#endif // CONFIG_ENV_MQTT_ENABLED 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) { static esp_err_t mpu6886_write_byte(mpu6886_t* dev, uint8_t reg, uint8_t data) {
uint8_t tx[2] = { reg, 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 // Auto select clock
if (mpu6886_write_byte(dev, MPU6886_PWR_MGMT_1, 0x01) != ESP_OK) return ESP_FAIL; 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_ACCEL_CONFIG, 0x00);
mpu6886_write_byte(dev, MPU6886_GYRO_CONFIG, 0x00); mpu6886_write_byte(dev, MPU6886_GYRO_CONFIG, 0x00);
@@ -242,14 +290,7 @@ void app_main(void)
return; return;
} }
init_button();
#ifdef CONFIG_ENV_MQTT_ENABLED
wifi_init();
// Start MQTT client (will retry until network is available)
mqtt_app_start();
#endif
mpu6886_t mpu; mpu6886_t mpu;
mpu.i2c_port = I2C_NUM_0; mpu.i2c_port = I2C_NUM_0;
mpu.address = MPU6886_ADDR; mpu.address = MPU6886_ADDR;
@@ -260,25 +301,28 @@ void app_main(void)
return; return;
} }
mpu6886_calibrate_gyro(&mpu, 100, 10); mpu6886_calibrate_gyro(&mpu, 100, 10);
mpu6886_calibrate_accel(&mpu, 100, 10); mpu6886_calibrate_accel(&mpu, 100, 10);
vec3_t accel, gyro; vec3_t accel, gyro;
float temp; float temp;
while (1) { while (1) {
if (mqtt_toggle && !toggle_completed && !wifi_initialized) {
wifi_init();
mqtt_app_start();
ESP_LOGI("BOOT", "Boot button pressed: starting 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 serial-only mode");
toggle_completed = true;
}
mpu6886_read_accel(&mpu, &accel); mpu6886_read_accel(&mpu, &accel);
mpu6886_read_gyro(&mpu, &gyro); mpu6886_read_gyro(&mpu, &gyro);
mpu6886_read_temp(&mpu, &temp); mpu6886_read_temp(&mpu, &temp);
#ifndef CONFIG_ENV_MQTT_ENABLED if (mqtt_toggle && s_mqtt_client != NULL) {
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) {
char payload[256]; char payload[256];
int n = snprintf(payload, sizeof(payload), 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}", "{\"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 { } else {
ESP_LOGW("MQTT", "payload truncated or encoding error"); 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)); vTaskDelay(pdMS_TO_TICKS(500));
} }
} }

View File

@@ -13,6 +13,9 @@
#include "mqtt_client.h" #include "mqtt_client.h"
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#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_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 */ #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_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_TIMEOUT_MS 1000 #define I2C_MASTER_TIMEOUT_MS 1000
#define BOOT_BUTTON_GPIO 0 // GPIO number for boot mode selection button
#define MPU6886_ADDR 0x68 #define MPU6886_ADDR 0x68
// MPU6886 Registers // MPU6886 Registers
@@ -66,6 +71,12 @@ typedef struct {
vec3_t accel_offset; vec3_t accel_offset;
} mpu6886_t; } 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; static esp_mqtt_client_handle_t s_mqtt_client = NULL;
// Function declarations // Function declarations