Files
Camper-Monitor/firmware/vanalign/esp32_ble.yaml
T
BiasFandClaude Opus 5 9406a749e5 Firmware des Neigungsmessers ins Projekt übernehmen
Die ESPHome-Firmware lag bisher im eigenständigen Projekt VanAllign-Pro.
Da die App der einzige Client ist, gehören Firmware und App zusammen:
ändert sich die Bluetooth-Schnittstelle, muss beides gemeinsam angefasst
werden.

Übernommen sind die Firmware selbst und die beiden Experimente zu
WLAN/BLE-Umschaltung und ESP-NOW, letztere nach experimente/ einsortiert
und als nicht betriebsnotwendig gekennzeichnet. Die WebBLE-Oberfläche
bleibt im Ursprungsprojekt - sie ist durch die App abgelöst und bringt
2 MB Bilder mit, die in einem iOS-Projekt nichts zu suchen haben.

Die .gitignore schliesst jetzt die ESPHome-Build-Verzeichnisse aus; im
Ursprungsprojekt fehlte das, dort liegen inzwischen 233 MB Bauartefakte
neben den Quellen.

Am neuen Ort mit esphome config gegengeprüft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 15:12:30 +02:00

236 lines
6.8 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VanAlign Pro Neigungsmessung über BLE
#
# ESP32-S3 mit MPU6050. Liefert Pitch und Roll als 32-Bit-Float
# (little-endian) und lässt sich über Bluetooth auf die aktuelle Lage
# kalibrieren.
#
# Die UUIDs sind gegenüber Version 1.0 unverändert, damit die vorhandene
# WebApp weiterläuft. Neu sind:
# * notify auf Pitch und Roll die Werte werden gesendet, sobald sie sich
# ändern, statt vom Client im Sekundentakt abgefragt zu werden.
# * eine funktionierende Kalibrierung über Bluetooth. Bisher war die
# Charakteristik zwar beschreibbar, hatte aber keine Aktion hinterlegt,
# und der Kalibrier-Knopf war nur über den Webserver erreichbar, der
# auskommentiert ist. Kalibrieren war damit gar nicht möglich.
# * die gespeicherten Offsets sind auslesbar, sodass ein Client zeigen
# kann, ob überhaupt schon kalibriert wurde.
esphome:
name: vanalign
friendly_name: "VanAlign Pro"
on_boot:
priority: -100
then:
- script.execute: publish_offsets
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
logger:
level: WARN
i2c:
sda: GPIO8
scl: GPIO9
scan: true
globals:
- id: pitch_offset
type: float
restore_value: yes
initial_value: '0.0'
- id: roll_offset
type: float
restore_value: yes
initial_value: '0.0'
sensor:
- platform: mpu6050
#address: 0x69
accel_x:
id: accel_x
internal: true
accel_y:
id: accel_y
internal: true
accel_z:
id: accel_z
internal: true
gyro_x:
id: mpu_gyro_x
internal: true
gyro_y:
id: mpu_gyro_y
internal: true
gyro_z:
id: mpu_gyro_z
internal: true
update_interval: 0.1s
- platform: template
name: "Neigung Pitch"
id: pitch
icon: mdi:caravan
unit_of_measurement: "°"
accuracy_decimals: 1
update_interval: 0.1s
lambda: |-
if (isnan(id(accel_x).state) || isnan(id(accel_y).state) || isnan(id(accel_z).state)) {
return NAN;
}
float raw = atan2(id(accel_y).state,
sqrt(pow(id(accel_x).state, 2) + pow(id(accel_z).state, 2)))
* (180.0 / 3.14159265);
return raw - id(pitch_offset);
filters:
- sliding_window_moving_average:
window_size: 8
send_every: 1
- exponential_moving_average:
alpha: 0.2
on_value:
# Ohne dieses Senden müsste der Client die Werte abfragen; die Anzeige
# ruckelt dann im Takt der Abfrage statt der Messung.
- ble_server.characteristic.set_value:
id: pitch_ble
value: !lambda |-
std::vector<uint8_t> v(sizeof(float));
float val = x;
memcpy(v.data(), &val, sizeof(float));
return v;
- platform: template
name: "Neigung Roll"
id: roll
icon: mdi:axis-x-rotate-clockwise
unit_of_measurement: "°"
accuracy_decimals: 1
update_interval: 0.1s
lambda: |-
if (isnan(id(accel_x).state) || isnan(id(accel_z).state)) {
return NAN;
}
float raw = atan2(-id(accel_x).state, id(accel_z).state) * (180.0 / 3.14159265);
return raw - id(roll_offset);
filters:
- sliding_window_moving_average:
window_size: 8
send_every: 1
- exponential_moving_average:
alpha: 0.2
on_value:
- ble_server.characteristic.set_value:
id: roll_ble
value: !lambda |-
std::vector<uint8_t> v(sizeof(float));
float val = x;
memcpy(v.data(), &val, sizeof(float));
return v;
script:
# Die aktuelle Lage wird zur neuen Null. Beide Wege Knopf und Bluetooth
# laufen hier zusammen, damit sie nicht auseinanderdriften.
- id: calibrate_level
then:
- lambda: |-
if (isnan(id(accel_x).state) || isnan(id(accel_y).state) || isnan(id(accel_z).state)) {
ESP_LOGW("vanalign", "Kalibrierung abgebrochen: keine Sensorwerte");
return;
}
id(pitch_offset) = atan2(id(accel_y).state,
sqrt(pow(id(accel_x).state, 2) + pow(id(accel_z).state, 2)))
* (180.0 / 3.14159265);
id(roll_offset) = atan2(-id(accel_x).state, id(accel_z).state) * (180.0 / 3.14159265);
ESP_LOGI("vanalign", "Kalibriert: pitch_offset=%.2f roll_offset=%.2f",
id(pitch_offset), id(roll_offset));
- script.execute: publish_offsets
- id: reset_calibration
then:
- lambda: |-
id(pitch_offset) = 0.0f;
id(roll_offset) = 0.0f;
ESP_LOGI("vanalign", "Kalibrierung zurückgesetzt");
- script.execute: publish_offsets
# Die gespeicherten Offsets für lesende Clients bereitstellen.
- id: publish_offsets
then:
- ble_server.characteristic.set_value:
id: offsets_ble
value: !lambda |-
std::vector<uint8_t> v(2 * sizeof(float));
float values[2] = { id(pitch_offset), id(roll_offset) };
memcpy(v.data(), values, sizeof(values));
return v;
esp32_ble_server:
manufacturer: "VanAlign"
model: "Pro"
services:
- uuid: 2a24b789-7aab-4535-af3e-ee76a35cc42d
advertise: true
characteristics:
- id: pitch_ble
uuid: cad48e28-7fbe-41cf-bae9-d77a6c233424
description: "Pitch"
read: true
notify: true
- id: roll_ble
uuid: cad48e28-7fbe-41cf-bae9-d77a6c233425
description: "Roll"
read: true
notify: true
# Zwei Floats: die gespeicherten Offsets. Damit kann ein Client
# anzeigen, ob und worauf kalibriert wurde.
- id: offsets_ble
uuid: cad48e28-7fbe-41cf-bae9-d77a6c233426
description: "Kalibrier-Offsets"
read: true
notify: true
# Ein Byte: 0 setzt die Kalibrierung zurück, alles andere kalibriert
# auf die aktuelle Lage.
- id: calib_ble
uuid: cad48e28-7fbe-41cf-bae9-d77a6c233427
description: "Kalibriere Neigung"
write: true
on_write:
then:
- lambda: |-
bool reset = !x.empty() && (x[0] == 0x00 || x[0] == '0');
if (reset) {
id(reset_calibration).execute();
} else {
id(calibrate_level).execute();
}
button:
- platform: template
name: "Kalibriere Neigung"
id: calib_button
on_press:
- script.execute: calibrate_level
- platform: template
name: "Kalibrierung zurücksetzen"
id: calib_reset_button
on_press:
- script.execute: reset_calibration
- platform: restart
name: "ESP Restart"
text_sensor:
- platform: template
name: "Firmware Version"
id: firmware_version
icon: mdi:tag
lambda: |-
return {"v1.1.0"};