doc: updated wiki
This commit is contained in:
1 parent
286ab8fb81
commit
a70300c259
1 file changed
+67
-25
+67
-25
@@ -26,12 +26,14 @@
|
|||||||
|
|
||||||
#### Формат передаваемого пакета
|
#### Формат передаваемого пакета
|
||||||
|
|
||||||
|
Пакет формируется в глобальной переменной `transmitted_data` типа `zh_rf_sensor_transmitted_data_t` из внешней библиотеки `zh_rf_config` и передаётся побайтово как массив байтов (`sizeof` структуры — 14 байт).
|
||||||
|
|
||||||
| Поле | Тип | Описание |
|
| Поле | Тип | Описание |
|
||||||
|------|-----|----------|
|
| ------ | ----- | ---------- |
|
||||||
| `data[0]` | `int16_t` | Идентификатор устройства (`DEVICE_ID = 6`) |
|
| `id` | `int16_t` | Идентификатор устройства (`DEVICE_ID = 6`) |
|
||||||
| `data[1]` | `int16_t` | Тип устройства (`DEVICE_TYPE = 4`) |
|
| `type` | `int16_t` | Тип устройства (`ZH_RF_SENSOR_TOUCH_SWITCH`) |
|
||||||
| `data[2]` | `int16_t` | Напряжение батареи × 100 (например, 330 = 3.30 В) |
|
| `battery_voltage` | `int16_t` | Напряжение батареи × 100 (например, 330 = 3.30 В) |
|
||||||
| `data[3]`–`data[6]` | `int16_t` | Зарезервированы (равны 0) |
|
| `value_1`–`value_4` | `int16_t` | Зарезервированы (равны 0) |
|
||||||
|
|
||||||
### Конфигурационные макросы
|
### Конфигурационные макросы
|
||||||
|
|
||||||
@@ -40,11 +42,12 @@
|
|||||||
| `GATEWAY_CHANNEL` | `120` | Радиоканал шлюза |
|
| `GATEWAY_CHANNEL` | `120` | Радиоканал шлюза |
|
||||||
| `GATEWAY_ADDRESS` | `0xDDEEFF` | 3-байтовый адрес шлюза |
|
| `GATEWAY_ADDRESS` | `0xDDEEFF` | 3-байтовый адрес шлюза |
|
||||||
| `DEVICE_ID` | `6` | Уникальный идентификатор устройства |
|
| `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_pad_interrupt_init()` | Настройка внешнего прерывания INT1 (PD3, rising edge) для пробуждения по касанию |
|
||||||
| `zh_spi_init()` | Инициализация аппаратного SPI в режиме мастера (Fosc/16) |
|
| `zh_spi_init()` | Инициализация аппаратного SPI в режиме мастера (Fosc/16) |
|
||||||
| `zh_nrf24_init()` | Инициализация трансивера nRF24L01+ в режим передачи |
|
| `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-операции
|
### Низкоуровневые SPI-операции
|
||||||
|
|
||||||
| Функция | Описание |
|
| Функция | Описание |
|
||||||
|---------|----------|
|
| --------- | ---------- |
|
||||||
| `zh_spi_transfer()` | Обмен одного байта по SPI (полный дуплекс) |
|
| `zh_spi_transfer()` | Обмен одного байта по SPI (полный дуплекс) |
|
||||||
| `zh_nrf24_write_register()` | Запись одного байта в регистр nRF24L01+ |
|
| `zh_nrf24_write_register()` | Запись одного байта в регистр nRF24L01+ |
|
||||||
| `zh_nrf24_write_buff_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 МГц.
|
- Предделитель частоты: 64 (ADPS[2:0] = 111), что даёт ~125 кГц при 8 МГц.
|
||||||
- Выполняются **две последовательные конверсии**: первая стабилизирует выборку, вторая даёт результат.
|
- Выполняются **две последовательные конверсии**: первая стабилизирует выборку, вторая даёт результат.
|
||||||
- Формула расчёта: `Vbat = (1024.0 × 1.1) / adc_value`.
|
- Формула расчёта: `Vbat = (1024.0 × 1.1) / adc_value`.
|
||||||
- При обрыве датчика (`adc == 0`) возвращается 0.0.
|
- При нулевой выборке (`adc == 0`) возвращается 0.0.
|
||||||
|
- После измерения АЦП отключается сбросом бита `ADEN`.
|
||||||
|
|
||||||
### Алгоритм передачи через nRF24L01+
|
### Алгоритм передачи через nRF24L01+
|
||||||
|
|
||||||
@@ -138,26 +142,38 @@ int main(void)
|
|||||||
zh_nrf24_init();
|
zh_nrf24_init();
|
||||||
// Конфигурируем режим сна Power-down
|
// Конфигурируем режим сна Power-down
|
||||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
||||||
sleep_enable();
|
|
||||||
// Включаем прерывания
|
|
||||||
sei();
|
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 (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (send_request == 1)
|
if (send_request == 1)
|
||||||
{
|
{
|
||||||
// Собираем и отправляем пакет
|
// Собираем и отправляем пакет
|
||||||
|
cli();
|
||||||
send_request = 0;
|
send_request = 0;
|
||||||
int16_t data[] = {DEVICE_ID, DEVICE_TYPE,
|
sei();
|
||||||
(int16_t)(zh_get_battery_voltage() * 100.0),
|
transmitted_data.battery_voltage =
|
||||||
0, 0, 0, 0};
|
(int16_t)(zh_get_battery_voltage() * 100.0);
|
||||||
zh_nrf24_send((uint8_t *)data, sizeof(data));
|
zh_nrf24_send((uint8_t *)&transmitted_data,
|
||||||
|
sizeof(transmitted_data));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Спим до следующего прерывания
|
// Спим до следующего прерывания
|
||||||
|
cli();
|
||||||
|
if (send_request == 0)
|
||||||
|
{
|
||||||
|
sleep_enable();
|
||||||
|
sei();
|
||||||
sleep_cpu();
|
sleep_cpu();
|
||||||
}
|
}
|
||||||
|
sei();
|
||||||
|
sleep_disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -165,9 +181,9 @@ int main(void)
|
|||||||
### Изменение конфигурации под другое устройство
|
### Изменение конфигурации под другое устройство
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// Измените идентификатор и тип для нового устройства
|
// Измените идентификатор для нового устройства
|
||||||
#define DEVICE_ID 7 // Уникальный ID в сети
|
#define DEVICE_ID 7 // Уникальный ID в сети
|
||||||
#define DEVICE_TYPE 4 // 4 = touch pad
|
// Тип устройства задаётся перечислением ZH_RF_SENSOR_TOUCH_SWITCH
|
||||||
#define GATEWAY_CHANNEL 120
|
#define GATEWAY_CHANNEL 120
|
||||||
#define GATEWAY_ADDRESS 0xDDEEFF
|
#define GATEWAY_ADDRESS 0xDDEEFF
|
||||||
```
|
```
|
||||||
@@ -176,16 +192,34 @@ int main(void)
|
|||||||
|
|
||||||
```c
|
```c
|
||||||
// Назначение пинов AVR для nRF24L01+:
|
// Назначение пинов AVR для nRF24L01+:
|
||||||
// PB2 (SS) -> CE (через резистор, или напрямую)
|
// PB2 (SS) -> CSN (управление SPI-селектом)
|
||||||
// PB3 (MOSI) -> MOSI
|
// PB3 (MOSI) -> MOSI
|
||||||
// PB5 (SCK) -> SCK
|
// PB5 (SCK) -> SCK
|
||||||
// PB1 -> CE (управление передачей)
|
// PB1 -> CE (управление передачей)
|
||||||
// PD2 -> IRQ (вход, активный низкий)
|
// PD2 -> IRQ (вход, активный низкий, с подтяжкой к VCC)
|
||||||
// PD3 -> INT1 (вход сенсорного датчика)
|
// PD3 -> INT1 (вход сенсорного датчика, rising edge)
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Логирование
|
||||||
|
|
||||||
|
Компонент не использует ESP-IDF логирование (прошивка для AVR, а не ESP32). Логирование отсутствует.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ошибки
|
||||||
|
|
||||||
|
Компонент не возвращает коды ошибок. Все функции имеют тип `void` или возвращают однобайтовый статус SPI (`uint8_t`) для низкоуровневых операций.
|
||||||
|
|
||||||
|
| Условие | Поведение |
|
||||||
|
| --------- | ---------- |
|
||||||
|
| Нулевое показание АЦП | `zh_get_battery_voltage()` возвращает 0.0 |
|
||||||
|
| Превышение таймаута передачи | Передача прерывается, пакет теряется |
|
||||||
|
| Неверный аргумент | Не применимо — все функции `static`, аргументы не валидируются |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Ограничения
|
## Ограничения
|
||||||
|
|
||||||
1. **Только передача (TX-only)** — компонент не принимает данные, шлюз не может отправить подтверждение на уровне приложения.
|
1. **Только передача (TX-only)** — компонент не принимает данные, шлюз не может отправить подтверждение на уровне приложения.
|
||||||
@@ -202,6 +236,7 @@ int main(void)
|
|||||||
|
|
||||||
- PlatformIO с плагином `platform-atmelavr`
|
- PlatformIO с плагином `platform-atmelavr`
|
||||||
- AVR-GCC (входит в состав PlatformIO)
|
- AVR-GCC (входит в состав PlatformIO)
|
||||||
|
- Библиотека `zh_rf_config` (подключается через `lib_deps` в `platformio.ini`)
|
||||||
- Программатор USBasp (или совместимый)
|
- Программатор USBasp (или совместимый)
|
||||||
- Фьюзы: LFUSE=`0xE2`, HFUSE=`0xDF`, EFUSE=`0x07` (8 МГц, без делителя)
|
- Фьюзы: 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
|
```c
|
||||||
// Зависимости — только стандартные заголовки AVR-libc:
|
// Зависимости: стандартные заголовки AVR-libc и конфигурация протокола
|
||||||
#include "avr/io.h"
|
#include "avr/io.h"
|
||||||
#include "avr/sleep.h"
|
#include "avr/sleep.h"
|
||||||
#include "avr/fuse.h"
|
#include "avr/fuse.h"
|
||||||
#include "avr/interrupt.h"
|
#include "avr/interrupt.h"
|
||||||
#include "util/delay.h"
|
#include "util/delay.h"
|
||||||
|
#include "zh_rf_config.h"
|
||||||
```
|
```
|
||||||
Reference in new issue
Block a user