Add accelerometer deadzone via UART and ESP-NOW.

Filter BMA456 logs by configurable LSB threshold; master can set deadzone
for local sensor or slaves using ACCEL_DEADZONE (UART) and ESP-NOW broadcast
until unicast delivery is restored.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-18 23:06:25 +02:00
co-authored by Cursor
parent e5db0b21c7
commit ee38ce551a
24 changed files with 838 additions and 73 deletions
+53 -4
View File
@@ -18,6 +18,11 @@ static const char *TAG = "[BMA456]";
static i2c_master_dev_handle_t bma456_dev_handle;
static bool s_bma456_ready;
static struct bma4_dev bma456_struct;
static uint32_t s_accel_deadzone = BMA456_DEFAULT_ACCEL_DEADZONE;
static int16_t s_last_x;
static int16_t s_last_y;
static int16_t s_last_z;
static bool s_have_last_sample;
volatile uint8_t interrupt_status = 0;
uint8_t int_line;
@@ -134,6 +139,49 @@ static esp_err_t check_bma4(const char *api_name, int8_t rslt) {
return ESP_FAIL;
}
static int16_t axis_delta(int16_t a, int16_t b) {
int32_t d = (int32_t)a - (int32_t)b;
return (int16_t)(d < 0 ? -d : d);
}
static bool sample_exceeds_deadzone(int16_t x, int16_t y, int16_t z) {
if (!s_have_last_sample) {
return true;
}
return axis_delta(x, s_last_x) > (int16_t)s_accel_deadzone ||
axis_delta(y, s_last_y) > (int16_t)s_accel_deadzone ||
axis_delta(z, s_last_z) > (int16_t)s_accel_deadzone;
}
bool bma456_is_ready(void) { return s_bma456_ready; }
void bma456_set_accel_deadzone(uint32_t deadzone_lsb) {
s_accel_deadzone = deadzone_lsb;
s_have_last_sample = false;
if (s_bma456_ready) {
ESP_LOGI(TAG, "accel deadzone applied: %lu LSB", (unsigned long)deadzone_lsb);
}
}
uint32_t bma456_get_accel_deadzone(void) { return s_accel_deadzone; }
void bma456_report_accel_if_changed(int16_t x, int16_t y, int16_t z) {
if (!s_bma456_ready) {
return;
}
if (!sample_exceeds_deadzone(x, y, z)) {
return;
}
s_last_x = x;
s_last_y = y;
s_last_z = z;
s_have_last_sample = true;
ESP_LOGI(TAG, "ACC X=%d Y=%d Z=%d (deadzone %lu)", x, y, z,
(unsigned long)s_accel_deadzone);
}
static void remove_bma456_device(void) {
if (bma456_dev_handle != NULL) {
i2c_master_bus_rm_device(bma456_dev_handle);
@@ -153,10 +201,11 @@ void read_sensor_task(void *params) {
while (1) {
ret = bma4_read_accel_xyz(&sens_data, &bma456_struct);
bma4_error_codes_print_result("bma4_read_accel_xyz", ret);
ESP_LOGI("ACC", "X: %d, Y: %d, Z: %d", sens_data.x, sens_data.y,
sens_data.z);
if (ret == BMA4_OK) {
bma456_report_accel_if_changed(sens_data.x, sens_data.y, sens_data.z);
} else {
bma4_error_codes_print_result("bma4_read_accel_xyz", ret);
}
if (interrupt_status) {
ESP_LOGI("INTERRUPT", "Da war der Interrupt resetting");