Jump to content
Sign in to follow this  
  • entries
    8
  • comments
    7
  • views
    845

Пару слов о трансивере nRF24l01+

parovoZZ

505 views

Трансивер nRF24l01+
Что нужно для энергоэффективно работы с данным трансивером? Прочитать даташит. Если с первого раза не всё понятно, то можно поискать в интернете его перевод. Для уточнения нюансов опять смотрим даташит и только его. Далее. Необходимо скачать заголовочный файлик с адресами регистров. Подобный легко ищется на том же гитхабе.
Вопросы, которые возникают естественным образом при первом знакомстве с данным транисивером:
1. Как с ним общаться? У трансивера только один интерфейс - SPI. Максимальная частота тактирования - 10 МГц. Прежде, чем начать общение, необходимо ногу CSN трансивера прижать к земле. Здесь надо четко для себя уяснить один момент - по SPI трансивер общается всегда, когда подано на него питание. Первым же байтом трансивер всегда отдаёт значение регистра статуса.
2. На какую частоту программировать? Т.к. антенны для этого трансивера используются вай-файные, то и спектр их настройки также вайфайный с не выроженным максимумом примерно посередине (где-то 45 канал). Но т.к. каналы вай-фай в любой точке пространства может быть абсолютно любым, то я для себя принял решение, что буду использовать 83 канал. Этот же канал как раз находится на границе разрешенных для бесплатного (гражданского) использования.
3. Какие адреса труб задавать? Здесь обращаемся к даташиту. Он нам говорит, что адрес для pipe необходимо задавать так, чтобы трансивер не спутал его с преамбулой (преамбула в данном трансивере в виде меандра), но также не спутал с шумами. По умолчанию, в одном из регистров трансивера записан адрес С2С2С2С2xx. Его я и буду использовать.

Весь даташит я пересказывать не буду - нет такой задачи. Покажу самые сливки.
Открываем даташит и видим картинку с режимами работы трансивера:

nrf.thumb.png.694758a5226aeb60411ced5c80c70860.png

Нас интересует исключительно передача. Смотрим на картинку и видим - подаем на трансивер напряжение питания и ждем 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 Comments


Recommended Comments

There are no comments to display.

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Add a comment...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...