From a70300c2592dd2c5c3bd10e2aaedb8be2b7794ff Mon Sep 17 00:00:00 2001 From: Alexey Zholtikov Date: Wed, 21 Oct 2026 20:13:58 +0300 Subject: [PATCH] doc: updated wiki --- wiki_ru.md | 96 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 27 deletions(-) diff --git a/wiki_ru.md b/wiki_ru.md index dbb1de0..f14ec12 100644 --- a/wiki_ru.md +++ b/wiki_ru.md @@ -26,12 +26,14 @@ #### Формат передаваемого пакета +Пакет формируется в глобальной переменной `transmitted_data` типа `zh_rf_sensor_transmitted_data_t` из внешней библиотеки `zh_rf_config` и передаётся побайтово как массив байтов (`sizeof` структуры — 14 байт). + | Поле | Тип | Описание | -|------|-----|----------| -| `data[0]` | `int16_t` | Идентификатор устройства (`DEVICE_ID = 6`) | -| `data[1]` | `int16_t` | Тип устройства (`DEVICE_TYPE = 4`) | -| `data[2]` | `int16_t` | Напряжение батареи × 100 (например, 330 = 3.30 В) | -| `data[3]`–`data[6]` | `int16_t` | Зарезервированы (равны 0) | +| ------ | ----- | ---------- | +| `id` | `int16_t` | Идентификатор устройства (`DEVICE_ID = 6`) | +| `type` | `int16_t` | Тип устройства (`ZH_RF_SENSOR_TOUCH_SWITCH`) | +| `battery_voltage` | `int16_t` | Напряжение батареи × 100 (например, 330 = 3.30 В) | +| `value_1`–`value_4` | `int16_t` | Зарезервированы (равны 0) | ### Конфигурационные макросы @@ -40,11 +42,12 @@ | `GATEWAY_CHANNEL` | `120` | Радиоканал шлюза | | `GATEWAY_ADDRESS` | `0xDDEEFF` | 3-байтовый адрес шлюза | | `DEVICE_ID` | `6` | Уникальный идентификатор устройства | -| `DEVICE_TYPE` | `4` | Код типа устройства (touch pad) | + +Тип устройства задаётся не макросом, а значением перечисления `ZH_RF_SENSOR_TOUCH_SWITCH` из библиотеки `zh_rf_config`. ### Управление памятью -Компонент не использует динамическую память. Все данные хранятся в стеке и регистрах микроконтроллера. Флаг `send_request` объявлен как `static volatile uint8_t` для корректного доступа из ISR и главного цикла. +Компонент не использует динамическую память. Все данные хранятся в статической области и регистрах микроконтроллера. Глобальная переменная `transmitted_data` заполняется один раз при старте (идентификатор и тип), в рабочем цикле обновляется только поле `battery_voltage`. Флаг `send_request` объявлен как `static volatile uint8_t` для корректного доступа из ISR и главного цикла. --- @@ -55,7 +58,7 @@ ### Инициализация | Функция | Описание | -|---------|----------| +| --------- | ---------- | | `zh_pad_interrupt_init()` | Настройка внешнего прерывания INT1 (PD3, rising edge) для пробуждения по касанию | | `zh_spi_init()` | Инициализация аппаратного SPI в режиме мастера (Fosc/16) | | `zh_nrf24_init()` | Инициализация трансивера nRF24L01+ в режим передачи | @@ -70,12 +73,12 @@ | Функция | Описание | |---------|----------| -| `zh_nrf24_send()` | Передача буфера через nRF24L01+ с полным циклом TX | +| `zh_nrf24_send()` | Передача буфера через nRF24L01+ с полным циклом TX: Power Up, `FLUSH_TX`, загрузка `W_TX_PAYLOAD`, импульс CE, ожидание флага TX_DS/MAX_RT по пину IRQ, сброс статуса и переход в Power Down | ### Низкоуровневые SPI-операции | Функция | Описание | -|---------|----------| +| --------- | ---------- | | `zh_spi_transfer()` | Обмен одного байта по SPI (полный дуплекс) | | `zh_nrf24_write_register()` | Запись одного байта в регистр nRF24L01+ | | `zh_nrf24_write_buff_register()` | Запись многобайтового буфера в регистр nRF24L01+ | @@ -98,11 +101,12 @@ ### Алгоритм измерения напряжения батареи -- ADC конфигурируется с внутренним опорным напряжением 1,1 В на канале AVcc (MUX[3:1] = 111). +- ADC конфигурируется с внутренним опорным напряжением 1,1 В на канале внутреннего источника 1,1 В (`REFS0=1`, `MUX[3:1]=111`), вход AVcc сравнивается с опорой. - Предделитель частоты: 64 (ADPS[2:0] = 111), что даёт ~125 кГц при 8 МГц. - Выполняются **две последовательные конверсии**: первая стабилизирует выборку, вторая даёт результат. - Формула расчёта: `Vbat = (1024.0 × 1.1) / adc_value`. -- При обрыве датчика (`adc == 0`) возвращается 0.0. +- При нулевой выборке (`adc == 0`) возвращается 0.0. +- После измерения АЦП отключается сбросом бита `ADEN`. ### Алгоритм передачи через nRF24L01+ @@ -138,25 +142,37 @@ int main(void) zh_nrf24_init(); // Конфигурируем режим сна Power-down set_sleep_mode(SLEEP_MODE_PWR_DOWN); - sleep_enable(); - // Включаем прерывания sei(); + // Глобальная структура из zh_rf_config + zh_rf_sensor_transmitted_data_t transmitted_data = + {DEVICE_ID, ZH_RF_SENSOR_TOUCH_SWITCH, 0, 0, 0, 0, 0}; + for (;;) { if (send_request == 1) { // Собираем и отправляем пакет + cli(); send_request = 0; - int16_t data[] = {DEVICE_ID, DEVICE_TYPE, - (int16_t)(zh_get_battery_voltage() * 100.0), - 0, 0, 0, 0}; - zh_nrf24_send((uint8_t *)data, sizeof(data)); + sei(); + transmitted_data.battery_voltage = + (int16_t)(zh_get_battery_voltage() * 100.0); + zh_nrf24_send((uint8_t *)&transmitted_data, + sizeof(transmitted_data)); } else { // Спим до следующего прерывания - sleep_cpu(); + cli(); + if (send_request == 0) + { + sleep_enable(); + sei(); + sleep_cpu(); + } + sei(); + sleep_disable(); } } } @@ -165,9 +181,9 @@ int main(void) ### Изменение конфигурации под другое устройство ```c -// Измените идентификатор и тип для нового устройства +// Измените идентификатор для нового устройства #define DEVICE_ID 7 // Уникальный ID в сети -#define DEVICE_TYPE 4 // 4 = touch pad +// Тип устройства задаётся перечислением ZH_RF_SENSOR_TOUCH_SWITCH #define GATEWAY_CHANNEL 120 #define GATEWAY_ADDRESS 0xDDEEFF ``` @@ -176,16 +192,34 @@ int main(void) ```c // Назначение пинов AVR для nRF24L01+: -// PB2 (SS) -> CE (через резистор, или напрямую) +// PB2 (SS) -> CSN (управление SPI-селектом) // PB3 (MOSI) -> MOSI // PB5 (SCK) -> SCK -// PB1 -> CE (управление передачей) -// PD2 -> IRQ (вход, активный низкий) -// PD3 -> INT1 (вход сенсорного датчика) +// PB1 -> CE (управление передачей) +// PD2 -> IRQ (вход, активный низкий, с подтяжкой к VCC) +// PD3 -> INT1 (вход сенсорного датчика, rising edge) ``` --- +## Логирование + +Компонент не использует ESP-IDF логирование (прошивка для AVR, а не ESP32). Логирование отсутствует. + +--- + +## Ошибки + +Компонент не возвращает коды ошибок. Все функции имеют тип `void` или возвращают однобайтовый статус SPI (`uint8_t`) для низкоуровневых операций. + +| Условие | Поведение | +| --------- | ---------- | +| Нулевое показание АЦП | `zh_get_battery_voltage()` возвращает 0.0 | +| Превышение таймаута передачи | Передача прерывается, пакет теряется | +| Неверный аргумент | Не применимо — все функции `static`, аргументы не валидируются | + +--- + ## Ограничения 1. **Только передача (TX-only)** — компонент не принимает данные, шлюз не может отправить подтверждение на уровне приложения. @@ -202,6 +236,7 @@ int main(void) - PlatformIO с плагином `platform-atmelavr` - AVR-GCC (входит в состав PlatformIO) +- Библиотека `zh_rf_config` (подключается через `lib_deps` в `platformio.ini`) - Программатор USBasp (или совместимый) - Фьюзы: LFUSE=`0xE2`, HFUSE=`0xDF`, EFUSE=`0x07` (8 МГц, без делителя) @@ -217,13 +252,20 @@ pio run -e ATmega328P -t upload ### Подключение в проекте -Компонент является самодостаточной прошивкой — не подключается как библиотека. Для интеграции в другой проект скопируйте `src/main.c` и адаптируйте макросы конфигурации. +Компонент является самодостаточной прошивкой — не подключается как библиотека. Для интеграции в другой проект скопируйте `src/main.c`, добавьте зависимость `zh_rf_config` и адаптируйте макросы конфигурации. + +```ini +; platformio.ini +lib_deps = + https://github.com/aZholtikov/zh_rf_config +``` ```c -// Зависимости — только стандартные заголовки AVR-libc: +// Зависимости: стандартные заголовки AVR-libc и конфигурация протокола #include "avr/io.h" #include "avr/sleep.h" #include "avr/fuse.h" #include "avr/interrupt.h" #include "util/delay.h" +#include "zh_rf_config.h" ```