Невероятно популярные беспроводные модули, идеальное, недорогое решение для объединение микроконтроллеров в беспроводную сеть, ниже код и дополнение к серии видео
Модули построены на микросхеме nRF24L01+, основное предназначение микросхемы беспроводная связь различных периферийных устройств, вроде беспроводных мышек и клавиатур.
Китайская промышленность выпускает несколько модификаций модулей на этих чипах, различающиеся способом монтажа, наличием усилителя мощности и коннектора для внешней антенны.
Слева типичный китайский модуль, средняя стоимость за такой один доллар. Справа модуль с усилителем мощности и коннектором для внешней антенны, за такой придется отдать около трех.
Основные характеристики модулей.
Рабочая частота: 2.4ггц
Выходная мощность передатчика: 0dBm (1mW), в версии с усилителем 20dBm (100mW)
Радиус действия в прямой видимости: до 30м, в версии с усилителем до 1000м
Скорость беспроводного соединения: 250kbps, 1Mbps или 2Mbps.
Количество каналов: 126
Распиновка модуля.
Модуль работает с микроконтроллером по средствам интерфейса SPI, соответственно модуль должен подключатся к интерфейсу SPI ардуины, который находится на определенных контактах микроконтроллера, на фото указаны номера выходов для Arduino UNO или других, базирующихся на микроконтроллере ATMega328. Не забываем что у Arduino leonardo, Mega, и тд, интерфейс SPI находится на других контактах.
Питание модуля 3,3 вольта, вообще к питанию модуль очень привередлив, крайне желательно использовать отдельный от Arduino стабилизатор, например на микросхеме AMS1117-3.3, также желательно припаять дополнительный керамический конденсатор фильтра на контакты питания.
Для работы с модулем в среде Arduino написано несколько библиотек, мне понравилась библиотека RF24, скачать можно тут или тут, краткое описание функций библиотеки на английском языке тут.
Также существует более оптимизированное и полностью совместимое ответвление от основной версии RF24, находится тут.
Ниже исходные коды, которые были показаны в роликах на ютубе.
Радиомодули nRF24L01+ и Arduino, часть 1
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> // https://github.com/maniacbug/RF24 const uint64_t pipe = 0xF0F1F2F3F4LL; // индитификатор передачи, "труба" RF24 radio(9, 10); // CE, CSN void setup(){ Serial.begin(9600); radio.begin(); delay(2); radio.setChannel(9); // канал (0-127) // скорость, RF24_250KBPS, RF24_1MBPS или RF24_2MBPS // RF24_250KBPS на nRF24L01 (без +) неработает. // меньше скорость, выше чувствительность приемника. radio.setDataRate(RF24_1MBPS); // мощьность передатчика RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, radio.setPALevel(RF24_PA_HIGH); radio.openReadingPipe(1,pipe); // открываем первую трубу с индитификатором "pipe" radio.startListening(); // включаем приемник, начинаем слушать трубу } // radio.stopListening(); // останавливает приём (нужно перед началом передачи) void loop() { int data; if (radio.available()){ // проверяем не пришло ли чего в буфер. radio.read(&data, sizeof(data)); // читаем данные, указываем сколько байт читать Serial.print("data: "); Serial.println(data); } }
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> // https://github.com/maniacbug/RF24 const uint64_t pipe = 0xF0F1F2F3F4LL; // индитификатор передачи, "труба" RF24 radio(9, 10); // CE, CSN void setup(){ Serial.begin(9600); radio.begin(); delay(2); radio.setChannel(9); // канал (0-127) // скорость, RF24_250KBPS, RF24_1MBPS или RF24_2MBPS // RF24_250KBPS на nRF24L01 (без +) неработает. // меньше скорость, выше чувствительность приемника. radio.setDataRate(RF24_1MBPS); // мощьность передатчика, RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, radio.setPALevel(RF24_PA_HIGH); radio.openWritingPipe(pipe); // открываем трубу на передачу. } void loop() { int data = analogRead(0); // читаем значение radio.write(&data, sizeof(data)); // отправляем данные и указываем сколько байт пакет Serial.print("data: "); Serial.println(data); }
Радиомодули nRF24L01+ и Arduino, часть 2, датчик DHT11
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> // https://github.com/maniacbug/RF24 #include <dht11.h> const uint64_t pipe = 0xF0F1F2F3F4LL; // индитификатор передачи, "труба" dht11 sensor; RF24 radio(9, 10); // CE, CSN void setup(){ Serial.begin(9600); radio.begin(); delay(2); radio.setChannel(9); // канал (0-127) // скорость, RF24_250KBPS, RF24_1MBPS или RF24_2MBPS // RF24_250KBPS на nRF24L01 (без +) неработает. // меньше скорость, выше чувствительность приемника. radio.setDataRate(RF24_1MBPS); // мощьность передатчика, RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, radio.setPALevel(RF24_PA_HIGH); radio.openWritingPipe(pipe); // открываем трубу на передачу. delay(1000); } void loop() { int data[2]; sensor.read(8); data[0] = int(sensor.temperature); // заполняем массив data[1] = int(sensor.humidity); radio.write(&data, sizeof(data)); // отправляем данные и указываем сколько байт пакет Serial.print("Humidity (%): "); Serial.println(data[1]); Serial.print("Temperature (oC): "); Serial.println(data[0]); delay(1000); }
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> // https://github.com/maniacbug/RF24 const uint64_t pipe = 0xF0F1F2F3F4LL; // индитификатор передачи, "труба" RF24 radio(9, 10); // CE, CSN void setup(){ Serial.begin(9600); radio.begin(); delay(2); radio.setChannel(9); // канал (0-127) // скорость, RF24_250KBPS, RF24_1MBPS или RF24_2MBPS // RF24_250KBPS на nRF24L01 (без +) неработает. // меньше скорость, выше чувствительность приемника. radio.setDataRate(RF24_1MBPS); // мощьность передатчика RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, radio.setPALevel(RF24_PA_HIGH); radio.openReadingPipe(1,pipe); // открываем первую трубу с индитификатором "pipe" radio.startListening(); // включаем приемник, начинаем слушать трубу } // radio.stopListening(); // останавливает приём (нужно перед началом передачи) void loop() { int data[2]; if (radio.available()){ // проверяем не пришло ли чего в буфер. radio.read(&data, sizeof(data)); // читаем данные и указываем сколько байт читать Serial.print("Humidity (%): "); Serial.println(data[1]); Serial.print("Temperature (oC): "); Serial.println(data[0]); } }
Радиомодули nRF24L01+ и Arduino, часть 3, работа с несколькими модулями
/// приемник _18b20_rx_2.ino #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> // https://github.com/maniacbug/RF24 #include <Wire.h> const uint64_t pipe01 = 0xF0F1F2F3F4LL; // идентификатор передачи, "труба" const uint64_t pipe02 = 0xF0F1F2F3F1LL; // могут различатся только на младший байт RF24 radio(9, 10); // CE, CSN void setup(){ Serial.begin(9600); radio.begin(); delay(2); radio.setChannel(9); // канал (0-127) radio.setDataRate(RF24_250KBPS); radio.setPALevel(RF24_PA_HIGH); radio.openReadingPipe(1,pipe01); // открываем трубу с индитификатором "pipe01" radio.openReadingPipe(2,pipe02); // открываем трубу с индитификатором "pipe02" // radio.openReadingPipe(0,pipe01); // или открываем все трубы разом radio.startListening(); // включаем приемник, начинаем слушать трубу } // radio.stopListening(); // останавливает приём (нужно перед началом передачи) void loop() { uint8_t pipeNum = 0; if (radio.available(&pipeNum)){ // проверяем не пришло ли чего в буфер. if (pipeNum == 1){ float temperature = 0; radio.read(&temperature, sizeof(temperature)); Serial.println(pipeNum); if (temperature < 0) Serial.print("-"); else Serial.print("+"); Serial.println(temperature); Serial.println(); } if (pipeNum == 2){ int data[2] = {0}; radio.read(&data, sizeof(data)); Serial.println(pipeNum); if (data[0] < 0) Serial.print("-"); else Serial.print("+"); Serial.print(data[0]); Serial.print("C "); Serial.print(data[1]); Serial.println("%"); Serial.println(); } } }
// передатчик температуры с 18b20 . _18b20_tx_p1.ino // без запроса #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> // https://github.com/maniacbug/RF24 #include <OneWire.h> const uint64_t pipe = 0xF0F1F2F3F4LL; // индитификатор передачи, "труба" RF24 radio(9, 10); // CE, CSN OneWire ds(2); void setup(){ // Serial.begin(9600); radio.begin(); delay(2); radio.setChannel(9); // канал (0-127) radio.setDataRate(RF24_1MBPS); radio.setPALevel(RF24_PA_HIGH); radio.openWritingPipe(pipe); // открываем трубу на передачу. } void loop(){ ////////////// 18b20 ////////////// byte addr[8]; byte data[12]; if (!ds.search(addr)) { // если 18b20 не найден float temperature = -128; radio.write(&temperature, sizeof(temperature)); delay(5000); } ds.reset_search(); ds.reset(); ds.select(addr); ds.write(0x44); delay(1000); ds.reset(); ds.select(addr); ds.write(0xBE); for (int i = 0; i < 9; i++) data[i] = ds.read(); int raw = (data[1] << 8) | data[0]; if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6]; float temperature = raw / 16.0; /////////////////////////////// // отправляем данные и указываем сколько байт пакет radio.write(&temperature, sizeof(temperature)); }
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> // https://github.com/maniacbug/RF24 const uint64_t pipe = 0xF0F1F2F3F4LL; // индитификатор передачи, "труба" RF24 radio(9, 10); // CE, CSN void setup(){ Serial.begin(9600); radio.begin(); delay(2); radio.setChannel(9); // канал (0-127) // скорость, RF24_250KBPS, RF24_1MBPS или RF24_2MBPS // RF24_250KBPS на nRF24L01 (без +) неработает. // меньше скорость, выше чувствительность приемника. radio.setDataRate(RF24_1MBPS); // мощьность передатчика RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, radio.setPALevel(RF24_PA_HIGH); radio.openReadingPipe(1,pipe); // открываем первую трубу с индитификатором "pipe" radio.startListening(); // включаем приемник, начинаем слушать трубу } // // для ПроМини void loop() { int data[2]; if (Serial.available() > 0){ // если чтото пришло в сериал int val = Serial.parseInt(); // читаем в переменную if (val == 1){ // если это 1 radio.stopListening(); // останавливает приём (нужно перед началом передачи) radio.openWritingPipe(pipe); // открываем трубу на передачу. radio.write(&val, sizeof(val)); // отправляем val и указываем сколько байт пакет radio.startListening(); // включаем приемник, начинаем слушать трубу } Serial.flush(); // очищаем буфер } if (radio.available()){ // проверяем не пришло ли чего в буфер. radio.read(&data, sizeof(data)); // читаем данные и указываем сколько байт читать Serial.print("Humidity (%): "); Serial.println(data[1]); Serial.print("Temperature (oC): "); Serial.println(data[0]); } }
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> // https://github.com/maniacbug/RF24 #include <dht11.h> const uint64_t pipe = 0xF0F1F2F3F4LL; // индитификатор передачи, "труба" dht11 sensor; RF24 radio(9, 10); // CE, CSN void setup(){ // Serial.begin(9600); radio.begin(); delay(2); radio.setChannel(9); // канал (0-127) // скорость, RF24_250KBPS, RF24_1MBPS или RF24_2MBPS // RF24_250KBPS на nRF24L01 (без +) неработает. // меньше скорость, выше чувствительность приемника. radio.setDataRate(RF24_1MBPS); // мощьность передатчика, RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM, radio.setPALevel(RF24_PA_HIGH); radio.openReadingPipe(1,pipe); // открываем первую трубу с индитификатором "pipe" radio.startListening(); // включаем приемник, начинаем слушать трубу // radio.openWritingPipe(pipe); // открываем трубу на передачу. } ////// для UNO void loop() { int data[2]; if (radio.available()){ // проверяем не пришло ли чего в буфер. int val; radio.read(&val, sizeof(val)); // читаем данные и указываем сколько байт читать if (val == 1){ // если пришло 1, radio.stopListening(); // останавливает приём (нужно перед началом передачи) sensor.read(8); // читаем градусник delay(1000); data[0] = int(sensor.temperature); // заполняем массив data[1] = int(sensor.humidity); //отправляем данные radio.openWritingPipe(pipe); // открываем трубу на передачу. radio.write(&data, sizeof(data)); // отправляем данные и указываем сколько байт пакет radio.startListening(); // включаем приемник, начинаем слушать трубу } } }
Радиомодули nRF24L01+ и Arduino, часть 4, работа с прерыванием.
/// пример из видео http://youtu.be/1M04kcHcRlw // #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> // https://github.com/maniacbug/RF24 #include <Wire.h> #include <LiquidCrystal_I2C.h> const uint64_t pipe01 = 0xF0F1F2F3F4LL; volatile boolean flag_tx, flag_fail, flag_rx; int i; //// RF24 radio(9, 10); // CE, CSN LiquidCrystal_I2C lcd(0x27, 16, 2); void setup(){ // настраиваем прерывание на 3 ноге attachInterrupt(1, check_radio, FALLING); Serial.begin(9600); lcd.begin(); lcd.backlight(); radio.begin(); delay(2); radio.setChannel(9); // канал (0-127) radio.setDataRate(RF24_250KBPS); radio.setPALevel(RF24_PA_HIGH); radio.openReadingPipe(1,pipe01); // открываем трубу с индитификатором "pipe01" radio.startListening(); // включаем приемник, начинаем слушать трубу } // radio.stopListening(); // останавливает приём (нужно перед началом передачи) void check_radio(){ // обработчик прерывания bool tx, fail, rx; radio.whatHappened(tx,fail,rx); // читаем регистр flag_tx = tx; // 1 если успешно отправили данные flag_fail = fail; // 1 если данные не отправленны flag_rx = rx; // 1 если пришли данные для чтения } void loop(){ if (flag_rx){ // если пришли данные для чтения float temperature = 0; // забераем их и выводим на экран radio.read(&temperature, sizeof(temperature)); lcd.setCursor(0, 0); if (temperature > 0) lcd.print("+"); lcd.print(temperature); lcd.print(" "); // Serial.println(temperature); // Serial.println(); flag_rx = 0; } if (flag_fail){ // если данные не отправленны flag_fail = 0; } if (flag_tx){ // если данные отправленны flag_tx = 0; } /////////////////// // можно занятся другими делами. lcd.setCursor(0, 1); i++; lcd.print(i); delay(250); }