From fe740da06b654f4e6428ba8f2a6e7c02a2316440 Mon Sep 17 00:00:00 2001 From: Mephimeow Date: Wed, 29 Apr 2026 10:24:42 +0000 Subject: [PATCH] +move --- Move/ld2410b_counter.md | 88 +++++++++++++ Move/ld2410b_counter.yaml | 235 +++++++++++++++++++++++++++++++++++ scanner.md => QR /scanner.md | 0 scanner.py => QR /scanner.py | 0 4 files changed, 323 insertions(+) create mode 100644 Move/ld2410b_counter.md create mode 100644 Move/ld2410b_counter.yaml rename scanner.md => QR /scanner.md (100%) rename scanner.py => QR /scanner.py (100%) diff --git a/Move/ld2410b_counter.md b/Move/ld2410b_counter.md new file mode 100644 index 0000000..a5ba931 --- /dev/null +++ b/Move/ld2410b_counter.md @@ -0,0 +1,88 @@ +# LD2410B Conveyor Counter + +ESPHome прошивка для подсчета товаров на конвейере с помощью mmWave сенсора **Hi-Link LD2410B** + **ESP32**. Данные передаются через **MQTT**. + +## Схема подключения + +``` +ESP32 DevKit V1 LD2410B +────────────────────────────────── +GPIO17 (TX) ────► RX +GPIO16 (RX) ────► TX +GPIO18 ────► OUT (digital motion) +3.3V / 5V ────► VCC +GND ────► GND +GPIO2 ────► LED (status, onboard) +``` + +**Важно:** Питание LD2410B — **5V** (не 3.3V!). UART логика 3.3V — совместима с ESP32. + +## Как работает + +1. **UART** (256000 baud) — чтение дистанции и энергии движения для каждой "зоны" (gate) +2. **GPIO OUT** — быстрый бинарный сигнал присутствия +3. **Конечный автомат** определяет момент прохода товара: + - `State 0` — ожидание + - `State 1` — товар в зоне (energy > threshold) + - `State 2` — товар прошел (debounce 300ms) → +1 к счетчику + +## MQTT топики + +| Топик | Описание | +|---|---| +| `ld2410b/conveyor/sensor/items_count/state` | Общий счетчик товаров | +| `ld2410b/conveyor/sensor/moving_distance/state` | Дистанция до цели (cm) | +| `ld2410b/conveyor/sensor/trigger_distance/state` | Дистанция в зоне детекции | +| `ld2410b/conveyor/text_sensor/counter_status/state` | Строка статуса (state, energy, count) | +| `ld2410b/conveyor/button/reset_counter/command` | Сброс счетчика (payload: любая) | +| `ld2410b/conveyor/number/energy_threshold/command` | Порог энергии детекции | +| `ld2410b/conveyor/number/min_distance_cm/command` | Мин. дистанция зоны (cm) | +| `ld2410b/conveyor/number/max_distance_cm/command` | Макс. дистанция зоны (cm) | + +## Настройка порогов + +### Energy Threshold +- **По умолчанию:** 50 +- **Диапазон:** 10–100 +- Чем выше — тем меньше ложных срабатываний, но нужно больше энергии движения для детекции + +### Min / Max Distance +- **По умолчанию:** 75–200 см +- Установите диапазон, в котором товары проходят через луч +- LD2410B имеет минимальную дистанцию ~75 см (gate 0) + +## Установка + +```bash +# Установите ESPHome +pip install esphome + +# Скомпилируйте и залейте +esphome run ld2410b_counter.yaml +``` + +## secrets.yaml + +Создайте файл `secrets.yaml` рядом с конфигом: + +```yaml +mqtt_broker: "192.168.1.100" +mqtt_user: "esphome" +mqtt_pass: "your_password" +``` + +## Отладка + +1. Откройте веб-интерфейс ESP (по IP устройства) +2. Следите за `Counter Status` — строка вида `State: 1 | E: 65 | D: 120 | Count: 42` +3. Если счетчик не увеличивается: + - Уменьшите `Energy Threshold` + - Проверьте что товар попадает в диапазон `Min/Max Distance` +4. Если ложные срабатывания — увеличьте `Energy Threshold` или сузьте диапазон дистанций + +## Ограничения LD2410B + +- **Минимальная дистанция:** ~75 см +- **Угол обзора:** ~120° (для сужения используйте физический экран/тубус перед сенсором) +- **Не различает** направление движения (для этого нужен LD2450 с трекингом X/Y) +- **Макс. скорость конвейера:** зависит от размера товаров и debounce (300ms). Для быстрого конвейера уменьшите debounce в коде. diff --git a/Move/ld2410b_counter.yaml b/Move/ld2410b_counter.yaml new file mode 100644 index 0000000..9b88ca5 --- /dev/null +++ b/Move/ld2410b_counter.yaml @@ -0,0 +1,235 @@ +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 diff --git a/scanner.md b/QR /scanner.md similarity index 100% rename from scanner.md rename to QR /scanner.md diff --git a/scanner.py b/QR /scanner.py similarity index 100% rename from scanner.py rename to QR /scanner.py