Скетч для передатчика
В нашем эксперименте мы просто отправим традиционное сообщение «Hello World» от передатчика к приемнику.
Вот скетч, который мы будем использовать для нашего передатчика:
//Include Libraries #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> //create an RF24 object RF24 radio(9, 8); // CE, CSN //address through which two modules communicate. const byte address = "00001"; void setup() { radio.begin(); //set the address radio.openWritingPipe(address); //Set module as transmitter radio.stopListening(); } void loop() { //Send message to receiver const char text[] = "Hello World"; radio.write(&text, sizeof(text)); delay(1000); }
Код начинается с подключения библиотек. Библиотека SPI.h управляет связью SPI, а nRF24L01.h и RF24.h модулем:
//Include Libraries #include <SPI.h> #include <nRF24L01.h> #include <RF24.h>
Далее нам нужно создать объект RF24. Объект принимает два номера контактов в качестве параметров, к которым подключены сигналы CE и CSN:
//create an RF24 object RF24 radio(9, 8); // CE, CSN
Затем нам нужно создать байтовый массив, который будет представлять адрес канала, через который будут связываться два модуля nRF24L01 +:
//address through which two modules communicate. const byte address = "00001";
Мы можем изменить значение этого адреса на любую 5-буквенную строку, например «node1». Адрес необходим, если у вас есть несколько модулей в сети. Благодаря адресу вы можете выбрать конкретный модуль, с которым вы хотите общаться, поэтому в нашем случае у нас будет один и тот же адрес как для передатчика, так и для приемника.
Далее в функции setup() нам нужно инициализировать радиообъект, используя radio.begin() и используя radio.openWritingPipe() функцию, мы устанавливаем адрес передатчика:
//set the address radio.openWritingPipe(address);
Наконец, мы будем использовать radio.stopListening() функцию, которая устанавливает модуль в качестве передатчика:
//Set module as transmitter radio.stopListening();
В разделе loop () мы создаем массив символов, которым мы назначаем сообщение «Hello World». Используя radio.write() функцию, мы отправим это сообщение приемнику.
Первый аргумент здесь — это сообщение, которое мы хотим отправить. Второй аргумент — это количество байтов, присутствующих в этом сообщении:
const char text[] = "Hello World"; radio.write(&text, sizeof(text));
С помощью этого метода вы можете отправлять до 32 байтов за раз. Потому что это максимальный размер одного пакета, который может обработать nRF24L01 +. Если вам нужно подтверждение, что получатель получил данные, функция radio.write() возвращает bool значение. Если он возвращает TRUE, данные достигли получателя. Если он возвращает FALSE, данные были потеряны.
3Режимы работы и управление приёмопередатчиком nRF24L01
Приёмопередатчик может находиться в четырёх состояниях: выключен, ожидание, приём, передача. Чип nRF24L01 имеет встроенную машину состояний, которая обеспечивает корректный переход между этими состояниями. Пользователь управляет состояниями, загружая в управляющие регистры специальные команды.
Режим ожидания (standby mode)
Есть два режима ожидания.
Первый режим ожидания (Standby-I) используется для снижения потребления. В этом режиме чип принимает команды по SPI, быстро переходит в режим передачи, и так же быстро возвращается обратно в режим ожидания 1. Для перехода в этот режим нужно подать на CE «HIGH» и в регистре CONFIG установить бит PWR_UP в «1».
Второй режим ожидания (Standby-II) более энергозатратен по сравнению с первым: чип работает полностью, и устройство готово к приёму и передаче практически моментально (около 130 мкс). Как только в передающем буфере оказываются данные, микросхема nRF24L01 начинает передачу. Для перехода в этот режим нужно держать CE в «HIGH» и в регистре CONFIG должен быть установлен бит PWR_UP в «1».
Режим приёма (RX mode)
Это режим, в котором чип nRF24L01 используется как приёмник. При этом он постоянно сканирует эфир на наличие валидных пакетов. Как только валидный пакет будет найден, он помещается в свободный слот приёмного буфера. Если буфер полностью заполнен, то пакет игнорируется.
Для перехода в режим приёма нужно установить биты PWR_UP и PRIM_RX в «1», и вывод CE установить в «HIGH». Режим будет держаться до тех пор, пока контроллер не переключит его в другой (например, режим ожидания или выключения).
Режим передачи (TX mode)
Режим передачи используется для передачи данных.
Для перехода в режим приёма нужно установить бит PWR_UP в «1», бит PRIM_RX в «0», и вывод CE установить в «HIGH». Данные передаются пакетами максимальной длиной по 32 байта. Режим будет держаться до тех пор, пока передаётся пакет. По окончанию передачи пакета чип перейдёт в режим ожидания 2 (standby-II).
Важно не держать nRF24L01 в режиме передачи дольше 4 мс! Чип поддерживает расширенный режим Enhanced ShockBurst, который соблюдает это требование. Кроме того, этот режим обеспечивает автоматическую обработку пакетов
В таблице ниже сведены все условия для управления режимами чипа.
Режимы работы nRF24L01
Режим
Регистр PWR_UP
Регистр PRIM_RX
Вывод CE
Состояние буфера
Передача
1
1
1
Не важно
Приём
1
1
Передача всех данных из передающего буфера.
Приём
1
1, импульсом минимум на 10 мкс
Передача 1 пакета данных из передающего буфера. Ожидание-2
1
1
Буфер передачи пуст
Ожидание-1
1
Не важно
Нет данных для передачи
Выключен
Не важно
Не важно
Не важно. Продолжение следует..
Продолжение следует…
Приводим в исполнение
Загрузите скетч в каждый узел. При первом запуске подключите его к последовательному порту, чтобы установить ему адрес.
RF24network/examples/sensornet/ PLATFORM: Getting Started Board VERSION: 013b4d3 *** No valid address found. Send node address via serial of the form 011<cr>
После этого вы увидите полученные данные:
1733003: APP Received #16 24.23C / 3.21V from 053 1733709: APP Received #37 23.82C / 2.70V from 043 1734297: APP Received #109 24.46C / 3.06V from 013 1735108: APP Received #55 25.16C / 3.06V from 033 1735224: APP Received #134 22.66C / 2.71V from 031 1735286: APP Received #287 25.10C / 3.24V from 01 1735565: APP Received #299 24.79C / 3.36V from 03 1736871: APP Received #71 25.78C / 3.07V from 023 1737094: APP Received #137 22.89C / 3.01V from 041 1737119: APP Received #120 23.69C / 2.98V from 011 1737247: APP Received #17 24.23C / 3.21V from 053 1738025: APP Received #38 23.82C / 2.70V from 043 1738361: APP Received #110 24.45C / 3.06V from 013 1739286: APP Received #288 25.11C / 3.24V from 01 1739404: APP Received #56 25.16C / 3.06V from 033 1739565: APP Received #300 24.78C / 3.36V from 03 1739574: APP Received #135 22.68C / 2.71V from 031 1741043: APP Received #72 25.77C / 3.07V from 023 1741213: APP Received #138 22.87C / 3.01V from 041 1741490: APP Received #121 23.68C / 2.98V from 011 1741492: APP Received #18 24.21C / 3.21V from 053
Приемная часть: подключение модуля nRF24L01 к Arduino Uno
Приемная часть: подключение модуля nRF24L01 Arduino Uno. Схема соединенийПриемная часть: подключение модуля nRF24L01 Arduino Uno. Собранный макет
Как было сказано ранее, nRF24L01 взаимодействует с помощью интерфейса SPI. Для связи через SPI на Arduino Nano и UNO используются выводы 11, 12 и 13. Следовательно, мы подключаем выводы MOSI, MISO и SCK от nRF к выводам 11, 12 и 13 соответственно. Выводы CE и CS настраиваются пользователем, здесь я использовал выводы 7 и 8, но вы можете использовать любые выводы, изменив программу. Модуль nRF питается от вывода 3,3V на Arduino, что в большинстве случаев работать будет. Если нет, то можно попробовать отдельный источник питания. Помимо интерфейса nRF, я также подключил серводвигатель к выводу 7 и запитал его через вывод 5V на Arduino. Аналогично схема передатчика показана ниже.
Датчик напряжения
Мне хотелось следить за уровнем заряда батареи каждого узла, чтобы я мог видеть, когда пришло время заменить батареи. Чтобы сделать это, я подключил VIN от моего источника питания, к «Датчику напряжения» с помощью делителя напряжения:
Я использовал 1М / 470K делители, что позволит снизить 3.44V до 1.1V, а затем использовать 1.1V внутреннее опорное напряжение. Это идеально подходит для моих целей, так как я не использую напряжение свыше 3.44V. В моем случае, когда analogRead (A3) возвращает 1024, у меня есть 3.44V. Вот как это работает в примере SensorNet:
// What voltage is a reading of 1023? const unsigned voltage_reference = 5 * 256; // 5.0V // How many measurements to take. 64*1024 = 65536, so 64 is the max we can fit in a uint16_t. const int num_measurements = 64; ... // Take the voltage reading i = num_measurements; reading = 0; while(i--) reading += analogRead(voltage_pin); // Convert the voltage reading to volts*256 message.voltage_reading = ( reading * voltage_reference ) >> 16;
Сначала, я делаю 64 чтения чтобы получить хорошую выборку. Второе преимущество выборки из 64 показаний, это то что он использует все 16 бит uint16_tб так что значение 0x8000 составляет половину от максимального 1.1V.
Receiver loop() — Цикл приема
Еще, мы посмотрим на пример приемника, он похож на скетч передатчика, с разницей в цикле loop(). Он следит за пакетами, и берет с радио модуля и выводит на консоль.
void loop(void) { // Pump the network regularly network.update(); // Is there anything ready for us? while ( network.available() ) { // If so, grab it and print it out RF24NetworkHeader header; payload_t payload; network.read(header,&payload,sizeof(payload)); Serial.print("Received packet #"); Serial.print(payload.counter); Serial.print(" at "); Serial.println(payload.ms); } }
Адресация
Сеть RF24 прекрасно работает с несколькими узлами, но она была разработана для умного дома полного модулей. Узлы автоматически сконфигурированы в топологии дерева, в зависимости от их адреса. Узлы общаться напрямую только со своим родителем и своими детьми. А уже сеть будет автоматически отправлять сообщения в нужное место.
Узел 00 это базовый узел. Узлы 01-05 непосредственно взаимодействуют с узлом 00, но не друг с другом. Таким образом чтобы узлу 01 передать сообщение на узел 02, нужно будет пройти через узел 00. Узлы 011, 021, 031 и так далее — это дети узла 01. Таким образом, для узла 011, чтобы отправить сообщение на узел 02, сообщение пойдет к 01, а потом к 00, и только после этого на 02.
На практике, я обозначал узлы «маршрутизаторы» номерами 01-05, которые были размещены на каждом этаже, и имели мощные антенны. Тогда все узлы на этом этаже общались с родителем этажа. Фото выше стандарт узла V3 с питанием от специального «блока питания», чтобы подключать в настенную розетку, и радио модуль с усиленной антенной.
Построение сети беспроводных датчиков
«Sensornet» это пример начала построения сети датчиков. Этот пример демонстрирует, как отправить показания датчиков на базу из сети с любым числом узлов. Датчика температуры подключен к аналоговому входу 2, а датчик напряжения подключен к аналоговому входу 3. Каждый узел посылает пинг в базу каждые 4 секунды, этот интервал хорошо использовать для тестирования, но на практике вы можете установить интервал и больше. Дочерние узлы будут спать между передачами, для экономии заряда аккумулятора.
База просто пишет пинг в консоль, и отслеживает потерю пакетов. Таким образом, мы можем контролировать работу сети во время тестирования. В реальном приложении, вы можете, сохранить или передать эти данные куда вам нужно.
Принцип работы и основные настройки nRF24L01 +
Частота 2.4ГГц очень популярна и на ней работает достаточно большое количество приборов, например: WiFi, радиоуправляемые модели, и тому подобное. Как они не мешают друг другу? Дело в том, что частота 2.4ГГц — это условное обозначение. На самом деле, имеется в виду диапазон частот, близкий к 2.4ГГц. nRF24L01+ работает на частотах 2.400-2.4835ГГц. Частота, на которой будут работать ваши модули, определяется номером канала. Каналы имеют шаг в 1МГц. То есть если Вы выбираете канал 0 — это частота 2.400ГГц, если канал 76 — 2.476ГГц. Разумеется, нужно выбирать свободную волну (канал) — иначе связь будет не стабильной или вообще отсутствовать.
Вы можете выбрать одну из трех скоростей передачи данных. Чем меньше скорость — тем больше чувствительность. То есть, при скорости 250kbps модули будут работать на большей дистанции, чем при более высоких скоростях.
На дальность работы модулей также влияет настройки выходной мощности модуля. Вы можете выбрать мощность в зависимости от приоритетов. То есть, если для вас важнее максимальная дальность, то надо выбрать максимальную мощность. Если приоритетной является экономичность, а дальность — несколько метров, разумно выбрать меньшую мощность сигнала. Интересное наблюдение в режиме приема данных (RX) модуль потребляет больший ток, чем в режиме передачи (TX).
Модуль nRF24L01+ в один момент времени может находиться в одном из режимов:
Power Down — выключен
Standby — спящий режим
RX Mode — режим ресивера (приемника)
TX Mode — режим трансмиттера (передатчика)
Диаграмма переходов из режима в режим изображенны на рисунке:
Информационный пакет, который передает модуль nRF24L01+ имеет следующий формат:
Preamble — Преамбула представляет собой последовательность битов и используется для синхронизации демодуляторов приемников.
Address — Адрес приемника. Адрес гарантирует, что пакет получит нужен приемник. Вы можете настроить длину адреса 3, 4 или 5 байт. Надо стараться чтобы адреса были уникальны. Но иногда Адреса могут быть одинаковые в нескольких nRF24L01+ если этого требуют Ваши задачи.
Packet Control Field — контрольное поле. Содержит: 6 бит, определяющих длину пакета (имеется в виду длина пакета полезных данных (от 0 до 32 байт)); 2 бита PID, используемые для определения является ли пакет новым или пересланным повторно; 1 бит — флаг NO_ACK.
Payload — полезный «груз». То есть данные, которые передает микроконтроллер. Может быть от 0 до 32 байт. Длину Payload можно настроить.
CRC — CRC является обязательным механизмом обнаружения ошибок в пакете. Длина CRC — 1 или 2 байта и зависит от общей длины пакета.
Для того, чтобы переданный пакет был принят нужным приемником, настройки приемника должны быть такими же, как и у передатчика. Если параметры пакета будут отличаться, приемник не сможет его обработать. Также надо корректно указывать адреса (об этом чуть ниже).
Если одновременно будут передавать несколько передатчиков, или возникнут другие препятствия, произойдет коллизия. Приемник не сможет получить пакет. Поэтому nRF24L01+ имеет настройку автоматической повторной отправки пакета (Aoto Retransmission (ART)). Эти настройки указывают с каким интервалом и сколько раз пытаться отправить пакет.
Как отмечалось в самом начале nRF24L01+ может работать на одном канале с 6-ю nRF24L01+. Для этого все модуля должны работать на одном канале, но каждый nRF24L01+ должен иметь уникальный адрес. Относительно адресации в документации приведена наглядная диаграмма:
Обратите внимание, что адреса для Data Pipe 1 — Pipe 5 отличаются друг от друга лишь последним байтом. Этого требует документация на nRF24L01+
На этой диаграмме модуль отмеченный как PRX прослушивает эфир для указанных адресов RX_ADDR_P0..RX_ADDR_P5. Каждый из PTX1..PTX6 отправляет пакеты на адреса TX_ADDR. Модуль, который работает как PRX тоже может отправлять модулям пакеты по их адресам.
Если все настройки (разумеется, кроме адресов) будут одинаковыми — модули будут работать нормально. Основные проблемы возникают когда настройки передатчика и приемника имеют отличия. Также проблемы могут возникнуть, если вы выбрали канал, который занят и радиопомехи мешают радиосвязи.
Исходный код программы (скетча)
Arduino
/* Sending Sensor Data to Nordic BLE android app by CircuitDigest(http://www.circuitdigest.com/)
works with nRF24L01. and the works for Nordic’s
It reads temperature from a DHT11 and sends it via BTLE.
Works with Nordic Semiconductor apps such as
«nRF Connect for Mobile» and «nRF Temp 2.0 for BLE»
Pin Mapping:
GND -> GND on the Arduino
VCC -> 3.3v on the Arduino
CE -> PIN 9 on the Arduino
CSN -> PIN 10 on the Arduino
SCK -> PIN 13 on the Arduino Uno
MOSI -> PIN 11 on the Arduino Uno
MISO -> PIN 12 on the Arduino Uno
IRQ -> not used
*/
#include <SPI.h>
#include <RF24.h>
#include <BTLE.h>
#include <DHT.h> // dht11 temperature and humidity sensor library
#define DHTPIN 4 // контакт, к которому подключен датчик dht11
#define DHTTYPE DHT11 // select dht type as DHT 11 or DHT22
DHT dht(DHTPIN, DHTTYPE);
RF24 radio(9, 10); // CE, CSN
BTLE btle(&radio);
void setup() {
Serial.begin(9600);
delay(1000);
Serial.print(«BLE and DHT Starting… «);
Serial.println(«Send Temperature Data over BTLE»);
dht.begin(); // initialise DHT11 sensor
btle.begin(«CD Temp»); // 8 chars max (максимум 8 символов)
Serial.println(«Successfully Started»);
}
void loop() {
float temp = dht.readTemperature(); //считываем данные температуры
if (isnan(h) || isnan(t)) { // Check if any reads failed and exit early (to try again).
Serial.println(F(«Failed to read from DHT sensor!»));
return;
}
Serial.print(» Temperature: «); Serial.print(t); Serial.println(«Â°C «);
nrf_service_data buf;
buf.service_uuid = NRF_TEMPERATURE_SERVICE_UUID;
buf.value = BTLE::to_nRF_Float(temp);
if (!btle.advertise(0x16, &buf, sizeof(buf))) {
Serial.println(«BTLE advertisement failed..!»);
}
btle.hopChannel();
delay(2000);
}
1 |
/* Sending Sensor Data to Nordic BLE android app by CircuitDigest(http://www.circuitdigest.com/) DHTdht(DHTPIN,DHTTYPE); RF24radio(9,10);// CE, CSN BTLEbtle(&radio); voidsetup(){ Serial.begin(9600); delay(1000); Serial.print(«BLE and DHT Starting… «); Serial.println(«Send Temperature Data over BTLE»); dht.begin();// initialise DHT11 sensor btle.begin(«CD Temp»);// 8 chars max (максимум 8 символов) Serial.println(«Successfully Started»); } voidloop(){ floattemp=dht.readTemperature();//считываем данные температуры if(isnan(h)||isnan(t)){// Check if any reads failed and exit early (to try again). Serial.println(F(«Failed to read from DHT sensor!»)); return; } Serial.print(» Temperature: «);Serial.print(t);Serial.println(«Â°C «); nrf_service_databuf; buf.service_uuid=NRF_TEMPERATURE_SERVICE_UUID; buf.value=BTLE::to_nRF_Float(temp); if(!btle.advertise(0x16,&buf,sizeof(buf))){ Serial.println(«BTLE advertisement failed..!»); } btle.hopChannel(); delay(2000); } |
Подключение nRF24L01 к Ардуино
Вывод MOSI с платы nRF24L01 подключается к пину 11 для Ардуино Uno, Nano и на 51 для Arduino Mega. Контакт SCK нужно подключить к 13 для Ардуино Uno, Nano и 52 для Arduino Mega. MISO – к 12 для Ардуино Uno, Nano и 50 для Arduino Mega. Контакты CE и CSN подключаются к любому цифровому пину Ардуино. Питание – на 3,3 В. Если используется плата Arduino Mini, придется использовать внешний стабилизатор напряжения, так как на плате отсутствует выход 3,3В. Также к пинам питания можно добавить конденсатор на 10 мкФ и более для обеспечения стабильной и качественной работы. Модуль с припаянным конденсатором изображен на рисунке.
Питание для NRF2401
Внешний вид макета представлен на рисунке ниже.
При подключении важно не перепутать напряжение – 5 Вольт могут вывести модуль из строя
Подключение к Ардуино через адаптер NRF24L01
Адаптер специально разрабатывался для модуля NRF24L01+. На нем имеется специальный стабилизатор напряжения и удобно расположены выходы к контроллерам и платам Ардуино.
Как видно, на адаптере имеется 2 вида разъемов. Двухрядный разъем используется для подключения радиомодуля, однорядный – для соединения с Ардуино. Отдельно расположены выходы на питание (5В) и землю.
Для подключения радиомодуль NRF24L01+ нужно вставить в соответствующий двухуровневый разъем. При помощи проводов адаптер подключается к плате Ардуино к тем же выводам, которые нужны для подключения напрямую к модулю. Для подключения к Arduino Uno, Nano: MISO-12, MOSI-11, SCK-13,выводы CE –к D10 и CSN – D9, вывод VCC к Arduino (+5V), а вывод GND к Arduino (GND).
Объяснение программы для Raspberry Pi
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Программировать плату Raspberry Pi в нашем проекте мы будем с использованием языка Python3. Также можно использовать и язык C/C++ как и в плате Arduino, однако в данном случае преимуществом написания программы на языке python является то, что на нем написана специальная библиотека для работы с модулями nRF24l01, которую можно скачать с ее официальной страницы на github. Но здесь необходимо отметить, что наша программа на python и указанная библиотека должны находиться в одном и том же каталоге, иначе программа на python не сможет найти библиотеку. После скачивания библиотеки извлеките ее из архива и создайте отдельный каталог, в котором будут храниться все программы и библиотеки вашего проекта. Когда установка библиотеки будет закончена, можно приступать к написанию программы.
Первым делом в программе необходимо подключить (импортировать) все используемые библиотеки.
Python
import RPi.GPIO as GPIO
import time
import spidev
from lib_nrf24 import NRF24
1 |
importRPi.GPIO asGPIO importtime importspidev fromlib_nrf24 importNRF24 |
Далее установим режим работы контактов (GPIO mode) платы Raspberry Pi «Broadcom SOC channel», что будет означать что мы будем обращаться к контактам платы по их физическим номерам (а не по их номерам на плате).
Python
GPIO.setmode(GPIO.BCM)
1 | GPIO.setmode(GPIO.BCM) |
Далее в программе мы зададим адреса каналов (pipe address) – они будут нужны для взаимодействия с приемной частью проекта на основе платы Arduino. Адреса укажем в шестнадцатеричном коде.
Python
pipes = , ]
1 | pipes=0xE0,0xE0,0xF1,0xF1,0xE0,0xF1,0xF1,0xF0,0xF0,0xE0 |
Инициализируем модуль nRF24l01 используя контакты GPIO08 в качестве CE и GPIO25 в качестве CSN.
Python
radio.begin(0, 25)
1 | radio.begin(,25) |
Установим размер пакета (payload size) 32 бита, адрес канала 76, скорость передачи данных 1 Мбит/с и выходную мощность модуля на минимум.
Python
radio.setPayloadSize(32)
radio.setChannel(0x76)
radio.setDataRate(NRF24.BR_1MBPS)
radio.setPALevel(NRF24.PA_MIN)
1 |
radio.setPayloadSize(32) radio.setChannel(0x76) radio.setDataRate(NRF24.BR_1MBPS) radio.setPALevel(NRF24.PA_MIN) |
Откроем каналы и начнем в них запись данных. Также будем выводить на экран основные параметры (details) работы модуля nRF24l01.
Python
radio.openWritingPipe(pipes)
radio.printDetails()
1 |
radio.openWritingPipe(pipes) radio.printDetails() |
Подготовим сообщение в форме строки. Это сообщение мы будем передавать плате Arduino UNO.
Python
sendMessage = list(«Hi..Arduino UNO»)
while len(sendMessage) < 32:
sendMessage.append(0)
1 |
sendMessage=list(«Hi..Arduino UNO») whilelen(sendMessage)<32 sendMessage.append() |
Начнем запись информации в радио модуль и будем продолжать запись пока не закончится вся строка для передачи. Одновременно с этим зафиксируем текущее время и выведем на экран сообщение об успешной передаче (в целях отладки).
Python
while True:
start = time.time()
radio.write(sendMessage)
print(«Sent the message: {}».format(sendMessage))
send
radio.startListening()
1 |
whileTrue start=time.time() radio.write(sendMessage) print(«Sent the message: {}».format(sendMessage)) send radio.startListening() |
Если передача сообщения завершена и радио канал закрыт (не доступен) более 2-х секунд, то выведем на экран сообщение о том, что время истекло (timed out).
Python
while not radio.available(0):
time.sleep(1/100)
if time.time() — start > 2:
print(«Timed out.») # print error message if radio disconnected or not functioning anymore
break
1 |
whilenotradio.available() time.sleep(1100) iftime.time()-start>2 print(«Timed out.»)# print error message if radio disconnected or not functioning anymore break |
Закрываем прослушивание (listening) радио канала, закрываем соединение и заново открываем соединение спустя 3 секунды чтобы передать другое сообщение.
Python
radio.stopListening() # close radio
time.sleep(3) # give delay of 3 seconds
1 |
radio.stopListening()# close radio time.sleep(3)# give delay of 3 seconds |
Программное обеспечение
Получите RF24 библиотеку из GitHub. Существует достаточно документации на эту ссылку, а также указатель на страницу загрузки. Распакуйте архив в папку вашего Arduino IDE (моя в /home/users/maniacbug/Source/Arduino/libraries), и перезагрузите Arduino IDE.
В меню Файл, выберите пункт «Примеры», затем «RF24», и, наконец, “GettingStarted”. После этого загрузится GettingStarted пример. Выглядит примерно так. Взгляните на примере GettingStarted в документации во всех деталях.
/** * Пример Приступая к работе с nRF24L01+. * * Это пример того, как использовать класс RF24. Написан этот пример к двум * различным узлам. Переключите один из узлов в режиме "передачи" переключение * происходит с помощью serial monitor и отправки 'T'. Узел посылает пинг и * текущее время в понг узел, который отвечает, посылая данные обратно. Узел * пинг может посмотреть, как долго длился весь цикл передачи. ** / #include "SPI.h"; #include "nRF24L01.h" #include "RF24.h" #include "printf.h" // // Hardware configuration // // Подключение nRF24L01 к SPI шине к пинам 9 и 10 RF24 radio(9,10);
Загрузить пример, запустите serial monitor, установите скорость 57600, и вы должны увидеть это:
RF24/examples/GettingStarted/ ROLE: Pong back STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0 RX_ADDR_P0-1 = 0xf0f0f0f0d2 0xf0f0f0f0e1 RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6 TX_ADDR = 0xf0f0f0f0d2 RX_PW_P0-6 = 0x08 0x08 0x00 0x00 0x00 0x00 EN_AA = 0x3f EN_RXADDR = 0x03 RF_CH = 0x4c RF_SETUP = 0x07 CONFIG = 0x0f DYNPD/FEATURE = 0x00 0x00 Data Rate = 1MBPS Model = nRF24L01 CRC Length = 16 bits PA Power = PA_HIGH
Если вы вместо этого везде видите много нулей, то что-то не так с вашим соединением. Дважды проверьте все снова! В ходе создания этого материала, я даже перепутал два провода и пришлось перепаять их. Если вы подключили все правильно, вы увидите номера так же, как те, что выше.
Шаг 2
По схеме, аналогичной первой, собираем второй радиоузел. Это будет передатчик. В его контроллер загружаем скетч передатчика (под спойлером).
Передатчик без пауз в работе передает сигнал на канале 6f (112).
Подаем питание на сканер эфира и передатчик. Присмотритесь что творится на канале 6f и соседних с ним каналах. Сканер эфира при включенном передатчике рано или поздно прорисует единички или другие одноразрядные числа в шестнадцатиричном исчислении в области 6f, на который запрограммирован передатчик. Наберитесь терпения на 1 — 2 минуты, особенно при работе со сканером из примеров.
Увидев сигнал от передатчика делаем следующий шаг.
Программирование nRF24L01 для Arduino
Использовать эти модули с Arduino очень просто благодаря доступной готовой библиотеке, созданной maniacbug на GitHub. Нажмите на ссылку, чтобы загрузить библиотеку в виде zip-каталога, и добавьте её в Arduino IDE с помощью Скетч (Sketch) → Подключить библиотеку (Include Library) → Добавить ZIP библиотеку (Add .ZIP library). После добавления библиотеки мы можем начать программирование для проекта. Мы должны написать две программы, одна для передающей части, а другая для приемной части. Однако, как я уже говорил ранее, каждый модуль может работать как и передатчик, и приемник. Обе программы приведены в конце страницы, в коде передатчика будет закомментирован код приемника, а в программе приемника будет закомментирован код передатчика. Вы можете использовать его, если хотите, чтобы в вашем проекте модуль работал в обоих режимах. Работа программы описана ниже.
Как и во всех программах, мы начинаем с включения заголовочных файлов. Поскольку nRF использует протокол SPI, мы включили заголовочный файл SPI, а также библиотеку, которую только что загрузили. Библиотека servo используется для управления серводвигателем.
Далее идет важная строка, в которой мы указываем выводы CE и CS. На нашей принципиальной схеме CE подключен к выводу 7, а CS – к выводу 8.
Все переменные, которые связаны с библиотекой RF, должны быть объявлены как составная структура. В данной программе переменная используется для отправки и получения данных от RF модуля.
Каждый RF модуль имеет уникальный адрес, используя который можно отправлять данные на соответствующее устройство. Поскольку у нас здесь только одна пара, мы устанавливаем адрес, равный нулю, как на передатчике, так и приемнике, но если у вас несколько модулей, вы можете установить ID на любую уникальную строку, состоящую из шести цифр.
Затем внутри функции мы инициализируем RF модуль и настраиваем его на работу в диапазоне 115, который свободен от шума, а также настраиваем модуль для работы в режиме минимального энергопотребления с минимальной скоростью 250 кбит/с.
Функция записывает переданные ей данные. Как говорилось ранее, nRF имеет 6 различных каналов, в которые мы можем записывать и считывать данные, здесь мы использовали в качестве адреса для записи данных. В приемной части для получения данных мы должны использовать тот же адрес в функции .
Функция считывает данные и помещает их в переменную. Снова из 6 различных каналов, используя которые мы может считывать и записывать данные, здесь мы использовали в качестве адреса для чтения данных. Этот означает, что передатчик другого модуля записал что-то по этому адресу, и, следовательно, мы читаем это что-то с того же адреса.
Помимо этих строк, в программе используются другие строки для считывания положения потенциометра и преобразования этого показания в значение в диапазоне от 0 до 180 с помощью функции и отправки его на приемный модуль, где мы соответствующим образом управляем сервоприводом.
Сделайте еще один
Хорошо, теперь делается все снова так же, делаем еще одну плату, для другой Arduino, так наш первый блок сможет с кем то говорить.
Старт второго блока, так как и выше, и запустить последовательный монитор на 57600. Нажмите клавишу «Т», как только текст отладки будет успешно выполнен. «Т» переключит этот блок в режиме передачи, который посылает пинг к другим блоку. Также убедитесь, что другой блок все еще работает.
Скоро вы увидите счастливую болтовню, радио-модули делают свое дело:
Now sending 90...ok...Got response 90, round-trip delay: 28 Now sending 1122...ok...Got response 1122, round-trip delay: 26 Now sending 2152...ok...Got response 2152, round-trip delay: 27 Now sending 3182...ok...Got response 3182, round-trip delay: 29 Now sending 4214...ok...Got response 4214, round-trip delay: 27 Now sending 5244...ok...Got response 5244, round-trip delay: 29 Now sending 6277...ok...Got response 6277, round-trip delay: 26 Now sending 7307...ok...Got response 7307, round-trip delay: 26 Now sending 8337...ok...Got response 8337, round-trip delay: 29 Now sending 9369...ok...Got response 9369, round-trip delay: 27 Now sending 10399...ok...Got response 10399, round-trip delay: 29 Now sending 11431...ok...Got response 11431, round-trip delay: 27 Now sending 12462...ok...Got response 12462, round-trip delay: 28