#include #include "esp_system.h" #include "esp_log.h" #include "driver/rmt_tx.h" #include "led_strip.h" #include "driver/gpio.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "bmi270.h" #include "common/common.h" #define WS2812_GPIO 27 #define LED_COUNT 1 #define HW_ESP_SPOT_C5 0 #define HW_ESP_SPOT_S3 1 #define HW_ESP_ASTOM_S3 0 #if HW_ESP_SPOT_C5 #define I2C_INT_IO 3 #define I2C_MASTER_SCL_IO 26 #define I2C_MASTER_SDA_IO 25 #elif HW_ESP_SPOT_S3 #define I2C_INT_IO 5 #define I2C_MASTER_SCL_IO 1 #define I2C_MASTER_SDA_IO 2 #elif HW_ESP_ASTOM_S3 #define I2C_INT_IO 16 #define I2C_MASTER_SCL_IO 0 #define I2C_MASTER_SDA_IO 45 #endif #define I2C_MASTER_FREQ_HZ (100 * 1000) static bmi270_handle_t bmi_handle = NULL; static i2c_bus_handle_t i2c_bus = NULL; static led_strip_handle_t led_strip; static const char *TAG = "gesture_led"; static led_strip_handle_t configure_led(void) { led_strip_config_t strip_config = { .strip_gpio_num = WS2812_GPIO, .max_leds = 1, .led_model = LED_MODEL_WS2812, .color_component_format = { .format = { .r_pos = 1, // GRB排列 .g_pos = 0, .b_pos = 2, .num_components = 3, }, }, .flags = {.invert_out = false}, }; led_strip_spi_config_t spi_config = { .clk_src = SPI_CLK_SRC_DEFAULT, .spi_bus = SPI2_HOST, .flags = {.with_dma = true} }; led_strip_handle_t led_strip; ESP_ERROR_CHECK(led_strip_new_spi_device(&strip_config, &spi_config, &led_strip)); ESP_LOGI(TAG, "LED strip initialized (SPI)"); return led_strip; } // 设置LED颜色 static void set_led_color(led_strip_handle_t led_strip, uint8_t r, uint8_t g, uint8_t b) { ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, 0, r, g, b)); ESP_ERROR_CHECK(led_strip_refresh(led_strip)); } // BMI270 初始化 static esp_err_t i2c_sensor_bmi270_init(void) { const i2c_config_t i2c_bus_conf = { .mode = I2C_MODE_MASTER, .sda_io_num = I2C_MASTER_SDA_IO, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_io_num = I2C_MASTER_SCL_IO, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = I2C_MASTER_FREQ_HZ }; i2c_bus = i2c_bus_create(I2C_NUM_0, &i2c_bus_conf); if (!i2c_bus) { ESP_LOGE(TAG, "I2C bus create failed"); return ESP_FAIL; } bmi270_i2c_config_t i2c_bmi270_conf = { .i2c_handle = i2c_bus, .i2c_addr = BMI270_I2C_ADDRESS, }; if (bmi270_sensor_create(&i2c_bmi270_conf, &bmi_handle) != ESP_OK || !bmi_handle) { ESP_LOGE(TAG, "BMI270 create failed"); return ESP_FAIL; } return ESP_OK; } void gesture_task(void *arg) { uint16_t int_status = 0; struct bmi2_feat_sensor_data sens_data = { .type = BMI2_WRIST_GESTURE }; const char *gesture_output[6] = { "unknown_gesture", "push_arm_down", "pivot_up", "wrist_shake_jiggle", "flick_in", "flick_out" }; // 配置并启动手势识别 struct bmi2_sens_config config = {.type = BMI2_WRIST_GESTURE}; uint8_t sens_list[] = {BMI2_ACCEL, BMI2_WRIST_GESTURE}; bmi270_sensor_enable(sens_list, 2, bmi_handle); bmi270_get_sensor_config(&config, 1, bmi_handle); config.cfg.wrist_gest.wearable_arm = BMI2_ARM_LEFT; bmi270_set_sensor_config(&config, 1, bmi_handle); struct bmi2_sens_int_config sens_int = { .type = BMI2_WRIST_GESTURE, .hw_int_pin = BMI2_INT1 }; bmi270_map_feat_int(&sens_int, 1, bmi_handle); ESP_LOGI(TAG, "Gesture detection started"); while (1) { bmi2_get_int_status(&int_status, bmi_handle); if (int_status & BMI270_WRIST_GEST_STATUS_MASK) { bmi270_get_feature_data(&sens_data, 1, bmi_handle); int gesture = sens_data.sens_data.wrist_gesture_output; ESP_LOGI(TAG, "Detected gesture: %s", gesture_output[gesture]); switch (gesture) { case 0: // unknown set_led_color(led_strip, 0, 0, 0); break; case 1: // push_arm_down 红色 set_led_color(led_strip, 255, 0, 0); break; case 2: // pivot_up 绿色 set_led_color(led_strip, 0, 255, 0); break; case 3: // wrist_shake_jiggle 蓝色 set_led_color(led_strip, 0, 0, 255); break; case 4: // flick_in 黄色 set_led_color(led_strip, 255, 255, 0); break; case 5: // flick_out 紫色 set_led_color(led_strip, 128, 0, 128); break; default: set_led_color(led_strip, 0, 0, 0); break; } vTaskDelay(pdMS_TO_TICKS(500)); set_led_color(led_strip, 0, 0, 0); } vTaskDelay(pdMS_TO_TICKS(100)); } } void app_main(void) { ESP_ERROR_CHECK(i2c_sensor_bmi270_init()); led_strip = configure_led(); xTaskCreate(gesture_task, "gesture_task", 4096, NULL, 5, NULL); }