Пару слов о трансивере nRF24l01+
Трансивер nRF24l01+
Что нужно для энергоэффективно работы с данным трансивером? Прочитать даташит. Если с первого раза не всё понятно, то можно поискать в интернете его перевод. Для уточнения нюансов опять смотрим даташит и только его. Далее. Необходимо скачать заголовочный файлик с адресами регистров. Подобный легко ищется на том же гитхабе.
Вопросы, которые возникают естественным образом при первом знакомстве с данным транисивером:
1. Как с ним общаться? У трансивера только один интерфейс - SPI. Максимальная частота тактирования - 10 МГц. Прежде, чем начать общение, необходимо ногу CSN трансивера прижать к земле. Здесь надо четко для себя уяснить один момент - по SPI трансивер общается всегда, когда подано на него питание. Первым же байтом трансивер всегда отдаёт значение регистра статуса.
2. На какую частоту программировать? Т.к. антенны для этого трансивера используются вай-файные, то и спектр их настройки также вайфайный с не выроженным максимумом примерно посередине (где-то 45 канал). Но т.к. каналы вай-фай в любой точке пространства может быть абсолютно любым, то я для себя принял решение, что буду использовать 83 канал. Этот же канал как раз находится на границе разрешенных для бесплатного (гражданского) использования.
3. Какие адреса труб задавать? Здесь обращаемся к даташиту. Он нам говорит, что адрес для pipe необходимо задавать так, чтобы трансивер не спутал его с преамбулой (преамбула в данном трансивере в виде меандра), но также не спутал с шумами. По умолчанию, в одном из регистров трансивера записан адрес С2С2С2С2xx. Его я и буду использовать.
Весь даташит я пересказывать не буду - нет такой задачи. Покажу самые сливки.
Открываем даташит и видим картинку с режимами работы трансивера:
Нас интересует исключительно передача. Смотрим на картинку и видим - подаем на трансивер напряжение питания и ждем 100 мс. В этот период времени с трансивером все так же можно общаться по SPI, но общение будет не продуктивным - трансивер ничего записывать не будет. Готов ли трансивер к работе или нет, проверяется просто - записываем в любой регистр любое не дефолтное значение и затем этот же регистр читаем - если считали то, что записали, значит трансивер вышел на режим. Если нет - ждем ещё. Если всё хорошо, то трансивер переходит в режим Power Down - режим, в котором выключено абсолютно всё, кроме SPI. Для перевода трансивера в один из режимов (в нашем случае это передатчик), его необходимо включить. После того, как мы его включили и до, собственно, начала передачи (для этого пин CE необходимо поднять как минимум на 10 vrc)? необходимо выдержать паузу 1.5 мс для запуска осциллятора. В этот период времени трансивер также можно конфигурировать, в том числе и радиочасть, загружать данные, читать из него.
Итак, пишем код.
Мы для себя четко уясним наше ТЗ - с трансивером общаемся как можно реже, пакет пересылаем без запроса подтверждения. Для градусника это не актуально. Не приняли пакет сейчас, примем в следующий раз. Температура окружающего воздуха всё равно так быстро не меняется. А если и меняются, то ничто не мешает это заложить в алгоритм и уменьшить интервал общения - все ж в наших руках!
Сейчас вы удивитесь, как необходимо мало кода для конфигурирования этого трансивера в качестве передатчика:
uint8_t Buf[5]; //.. CONFIG Buf[0] = (1<<nRF_MASK_RX_DR) | (0<<nRF_MASK_TX_DS) | (1<<nRF_MASK_MAX_RT) | // маски прерываний от событий (0<<nRF_PRIM_RX) | // Режим передатчика (1<<nRF_EN_CRC) | (0<<nRF_CRCO) | // Проверка CRC разрешена, 1 байт CRC (1<<nRF_PWR_UP); // Запускаем трансивер SPI_WriteArray(nRF_WR_REG(nRF_CONFIG), 1, Buf); // Отправляем команду. Пин CSN удерживается внутри функции Buf[0] = channel; // Установка частоты канала передачи SPI_WriteArray(nRF_WR_REG(nRF_RF_CH), 1, Buf); // см. Settings.h //.. RF_SETUP Настройки радиоканала Buf[0] = (0<<nRF_RF_DR) | ((0x03)<<nRF_RF_PWR0); // Скорость передачи 1 Mbps, мощность: 0dbm SPI_WriteArray(nRF_WR_REG(nRF_RF_SETUP), 1, Buf); //.. FEATURE Опции Buf[0] = (1<<nRF_EN_DYN_ACK); // Разрешаем отправку пакетов SPI_WriteArray(nRF_WR_REG(nRF_FEATURE), 1, Buf); // не требующих подтверждения //.. TX_ADDR Адрес канала удаленного приемника Buf[0] = 0xC2; Buf[1] = 0xC2; Buf[2] = 0xC2; Buf[3] = 0xC2; Buf[4] = 0xC2; SPI_WriteArray(nRF_WR_REG(nRF_TX_ADDR), 5, Buf); // Адрес канала для передачи
Первым делом включаем трансивер. Затем пишем канал передачи, скорость и мощность. Далее обязательная опция - разрешить отправку пакетов с данными, но без запроса автоподтверждения (флаг ACK в пакете). Далее формируем адрес удаленного pipe, на который будут отправляться наши данные. Всё! Наша ракета проверена, заправлена и объявлена подготовка к старту, чтобы из космоса транслировать байты в космос ( ээээ 0_o )! Значения всех остальных регистров на режим передачи не влияют никак и их значения нам фиолетово. А раз так, то и не будем тратить драгоценные такты на их запись!
Формат сообщения
Перед каждым, кто хочет собрать себе систему глупой хаты (дачи, усадьбы, гаража и проч.), непременно встает вопрос - как все устройства, входящие в такую систему, будут между собой общаться? В случае каких-то решений-полуфабрикатов вопрос стоит не так остро - разработчик предоставляет шаблон или вовсе готовый формат. В моем случае два решения - все сообщения свести к единому стандарту без оглядки на датчик и исполнительное устройство, либо же у каждого датчика будет своя посылка. В первом случае пакет сообщения будет выглядеть примерно так: {Адрес, команда/параметр, значение параметра}. Для выключателей, диммеров, термостатов, датчиков с одним каналом такое сообщение в самый раз. У нас же несколько каналов, которые содержат также дополнительную информацию. Для беспроводного общения чем короче пакет, тем больше вероятность его доставки. Но в таком случае общий объем передаваемой информации возрастает в связи с необходимостью каждый раз передавать адрес получателя, а также идентификатор передаваемого значения. Я же остановился на втором варианте - передавать всю информацию в одном пакете. Пакет выглядит так:
Структура пакета:
0 - адрес, старший байт
1 - адрес, младший байт
2 - тип
3 - температура, старший байт
4 - температура, младший байт
5 - влажность
6 - напряжение питания
7 - доп. сообщение (ошибка)
|__
0 бит бит PORF - загрузка по сбросу питания
1 бит бит EXTRF - перезагрузка по ресету
2 бит бит BORF - перезагрузка по детектору питания
3 бит бит WDRF - перезагрузка по вачдогу
4 бит
5 бит ошибка измерения Т
6 бит ошибка измерения RH
7 бит ошибка записи в регистр статуса
Итого всего 8 байт. Под адрес отведено 2 байта (ну а вдруг?), под тип датчика всего 1 байт. На приемной стороне необходимо применить тот алгоритм парсинга сообщения, тип которого указан в пакете.
0 Комментариев
Рекомендуемые комментарии
Комментариев нет
Присоединяйтесь к обсуждению
Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.