Files
rostpoliplast/Move/ld2410b_counter.yaml
T
Mephimeow fe740da06b +move
2026-04-29 10:24:42 +00:00

236 lines
6.1 KiB
YAML

esphome:
name: ld2410b-counter
friendly_name: "LD2410B Conveyor Counter"
esp32:
board: esp32dev
framework:
type: arduino
# Подключение LD2410B по UART
uart:
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 256000
parity: NONE
stop_bits: 1
# GPIO OUT пин для быстрого детектирования движения
binary_sensor:
- platform: gpio
pin: GPIO18
name: "LD2410B Motion GPIO"
id: motion_gpio
device_class: motion
internal: true
ld2410:
sensor:
# Дистанция до движущейся цели
- platform: ld2410
moving_distance:
name: "Moving Distance"
id: moving_dist
# Дистанция до неподвижной цели
- platform: ld2410
still_distance:
name: "Still Distance"
id: still_dist
# Энергия движения в зоне 0 (ближняя зона, 0.75-1.5м)
- platform: ld2410
g0:
move_energy:
name: "Gate 0 Move Energy"
id: g0_energy
internal: true
still_energy:
name: "Gate 0 Still Energy"
id: g0_still
internal: true
# Энергия движения в зоне 1 (1.5-2.25м)
- platform: ld2410
g1:
move_energy:
name: "Gate 1 Move Energy"
id: g1_energy
internal: true
# Счетчик прошедших товаров
- platform: template
name: "Items Count"
id: items_count
icon: "mdi:counter"
unit_of_measurement: "items"
accuracy_decimals: 0
state_class: total_increasing
device_class: count
# Дистанция срабатывания (для отладки)
- platform: template
name: "Trigger Distance"
id: trigger_dist
icon: "mdi:ruler"
unit_of_measurement: "cm"
accuracy_decimals: 0
update_interval: 0.5s
# MQTT
mqtt:
broker: !secret mqtt_broker
username: !secret mqtt_user
password: !secret mqtt_pass
topic_prefix: ld2410b/conveyor
# Глобальные переменные для логики подсчета
globals:
- id: item_count_total
type: int
restore_value: true
initial_value: "0"
- id: item_state
type: int
restore_value: no
initial_value: "0"
- id: last_trigger_time
type: unsigned long
restore_value: no
initial_value: "0"
- id: energy_threshold
type: float
restore_value: no
initial_value: "50.0"
- id: distance_min_cm
type: float
restore_value: no
initial_value: "75.0"
- id: distance_max_cm
type: float
restore_value: no
initial_value: "200.0"
text_sensor:
# Статус счетчика
- platform: template
name: "Counter Status"
id: counter_status
icon: "mdi:information"
update_interval: 1s
# Кнопки управления
button:
- platform: template
name: "Reset Counter"
id: reset_counter
on_press:
- lambda: |-
id(item_count_total) = 0;
id(items_count).publish_state(0);
# Number для настройки порогов из Home Assistant / MQTT
number:
- platform: template
name: "Energy Threshold"
id: energy_threshold_ui
min_value: 10
max_value: 100
step: 5
initial_value: 50
set_action:
- lambda: id(energy_threshold) = x;
- platform: template
name: "Min Distance (cm)"
id: dist_min_ui
min_value: 50
max_value: 150
step: 5
initial_value: 75
set_action:
- lambda: id(distance_min_cm) = x;
- platform: template
name: "Max Distance (cm)"
id: dist_max_ui
min_value: 100
max_value: 500
step: 10
initial_value: 200
set_action:
- lambda: id(distance_max_cm) = x;
# Основной цикл подсчета + статус
interval:
- interval: 50ms
then:
- lambda: |-
// Получаем текущие значения
float energy = id(g0_energy).state;
float dist = id(moving_dist).state;
// Проверка валидности дистанции
bool valid_dist = (dist >= id(distance_min_cm)) && (dist <= id(distance_max_cm));
// Обновляем отладочный сенсор дистанции
id(trigger_dist).publish_state(valid_dist ? dist : 0);
// Конечный автомат: 0 = ожидание, 1 = объект в зоне, 2 = debounce после прохода
unsigned long now = millis();
int current_state = id(item_state);
// Объект вошел в зону (энергия выше порога + дистанция в пределах)
if (current_state == 0 && energy > id(energy_threshold) && valid_dist) {
id(item_state) = 1;
id(last_trigger_time) = now;
}
// Объект ушел из зоны — инкремент счетчика
if (current_state == 1 && energy < (id(energy_threshold) * 0.5)) {
id(item_state) = 2;
id(item_count_total)++;
id(items_count).publish_state(id(item_count_total));
id(last_trigger_time) = now;
}
// Debounce: ждем 300мс после прохода перед новым детектом
if (current_state == 2 && (now - id(last_trigger_time)) > 300) {
id(item_state) = 0;
}
// Сброс stuck состояния (объект "завис" в зоне больше 5 сек)
if (current_state == 1 && (now - id(last_trigger_time)) > 5000) {
id(item_state) = 0;
}
- interval: 1s
then:
- lambda: |-
std::string status = "State: " + std::to_string(id(item_state)) +
" | E: " + std::to_string(id(g0_energy).state, 0) +
" | D: " + std::to_string(id(moving_dist).state, 0) +
" | Count: " + std::to_string(id(item_count_total));
id(counter_status).publish_state(status.c_str());
# Светодиод статуса (GPIO2 на ESP32 devkit)
output:
- platform: gpio
pin: GPIO2
id: status_led
light:
- platform: binary
id: led_status
output: status_led
internal: true
logger:
level: INFO