В этом уроке мы сделаем передатчик и приемник Lora, используя модуль Lora SX1278 и модуль Wifi NodeMCU ESP8266. Тип связи - точка-точка, и данные будут передаваться по беспроводной сети с одного конца (передатчика) на другой конец (приемник).
За последние несколько лет появилось несколько коммуникационных технологий для взаимодействия между устройствами Интернета вещей (IoT). Наиболее популярными из них являются технология Wi-Fi и модуль Bluetooth. Но у них есть несколько ограничений, таких как ограниченный радиус действия, ограниченное количество точек доступа и высокое энергопотребление. Поэтому компания Semtech представила технологию LoRa, чтобы решить все эти проблемы. Используя одну батарею, устройство на основе данной технологии работает более года.
В этом уроке мы будем использовать интерфейсный модуль LoRa SX1278 с платой NodeMCU ESP8266. Мы создадим схему передатчика и приемника. Передаваемые параметры мы будем отображать на 0,96″ I2C OLED-дисплее. Мы возьмем два примера для изучения связи Lora SX1278 и ESP8266. Сначала мы передадим простой пакет и проверим, получены ли данные на стороне приемника или нет. Затем мы добавим датчик влажности и температуры DHT11 в схему передатчика и отправим значение влажности и температуры по беспроводной сети на сторону приемника.
Ранее на нашем сайте мы рассматривали подключение модуля LoRa SX1278 к следующим микроконтроллерам и платам:
Необходимые компоненты
- NodeMCU ESP8266 (купить на AliExpress).
- Датчик температуры и влажности DHT11 (купить на AliExpress).
- Модуль LoRa SX1278 (433MHz) – 2 шт. (купить на AliExpress).
- Модуль OLED дисплея SSD1306 128×64 с интерфейсом I2C (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Модуль LoRa Semtech SX1278
Модуль SX1278
Трансиверы SX1276/77/78/79 оснащены модемом дальнего действия LoRa®, который обеспечивает сверхбольшую дальность связи с расширенным спектром и высокую помехоустойчивость при минимальном потреблении тока.
SX1278 может достигать чувствительности более -148 дБм с использованием недорогого кристалла. Высокая чувствительность в сочетании со встроенным усилителем мощности +20 дБм обеспечивает лидирующий в отрасли бюджет связи, что делает его оптимальным для любого приложения, требующего дальности или надежности. Lora SX1278 также обеспечивает значительные преимущества как в блокировке, так и в селективности по сравнению с обычными методами модуляции, решая традиционный компромисс дизайна между дальностью, помехоустойчивостью и потреблением энергии. Узнайте больше об этом в даташите на данный модуль - Semtech SX1278 Datasheet.
Распиновка Semtech SX1278
На рынке доступны различные версии и типы плат SX1278. Но в основном все они имеют одинаковую распиновку, как LoRa SX1278 — это модуль SPI. Я использую эту плату, как показано на фотографиях ниже.
Эта версия модуля SX1278 имеет 12 контактов для взаимодействия с микроконтроллером и два дополнительных контакта для антенны.
Датчик влажности и температуры DHT11
DHT11 — это базовый, сверхбюджетный цифровой датчик температуры и влажности. Он использует емкостный датчик влажности и термистор для измерения окружающего воздуха и выдает цифровой сигнал на контакт данных (аналоговые входные контакты для считывания с него данных не требуются).
Он довольно прост в использовании, но требует тщательного расчета времени для сбора данных. Единственный реальный недостаток этого датчика в том, что вы можете получать от него новые данные только раз в 2 секунды, поэтому при использовании библиотеки показания датчика могут быть устаревшими до 2 секунд.
0,96-дюймовый OLED-дисплей
Это 0,96-дюймовый OLED-дисплейный модуль. Дисплейный модуль может быть подключен к любому микроконтроллеру с использованием протоколов SPI/IIC. Он имеет разрешение 128×64. В комплект входит дисплейная плата, дисплей, 4-контактный (или 7-контактный для работы с использованием интерфейса SPI) штекерный разъем, предварительно припаянный к плате.
OLED ( Organic Light-Emitting Diode) — это технология самоизлучающего света, состоящая из тонкой многослойной органической пленки, помещенной между анодом и катодом. В отличие от технологии LCD, OLED не требует подсветки. OLED обладает высоким потенциалом применения практически для всех типов дисплеев и рассматривается как окончательная технология для следующего поколения плоских дисплеев.
Простой передатчик-приемник на LoRa SX1278 и ESP8266
Давайте разберемся на этом простом примере. Сначала мы просто подключим модуль Lora SX1278 к плате NodeMCU ESP8266. Схема соединений и код приведены ниже.
Схема передатчика
Вот простая схема передатчика. Соберите схему, как показано на рисунке ниже.
Подключение довольно простое. Подключите выводы OLED SDA и SCL к D2 и D1 Nodemcu соответственно. Аналогично подключите Lora SX1278 и NodeMCU ESP8266 следующим образом.
1 2 3 4 5 6 7 8 |
NodeMCU Pins SX1278 Pins GND GND 3.3V VCC D8 NSS D7 MOSI D6 MISO D5 SCK D0 RST |
Схема приемника
Вот простая схема приемника. Соберите схему, как показано на рисунке ниже.
Подключение довольно простое. Подключение Lora SX1278 и NodeMCU ESP8266 выглядит следующим образом.
1 2 3 4 5 6 7 8 9 |
NodeMCU Pins SX1278 Pins GND GND 3.3V VCC D8 NSS D7 MOSI D6 MISO D5 SCK D0 RST D2 DIO0 |
Код передатчика
Перед использованием этого кода добавьте следующие библиотеки в Arduino IDE:
1. Библиотека Lora: Загрузить
2. Библиотека SSD1306 OLED: Загрузить
3. Библиотека Adafruit GFX: Загрузить
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
#include <SPI.h> #include <LoRa.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #define ss 15 #define rst 16 #define dio0 2 int counter = 0; void setup() { Serial.begin(115200); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } while (!Serial); Serial.println("LoRa Sender"); LoRa.setPins(ss, rst, dio0); if (!LoRa.begin(433E6)) { Serial.println("Starting LoRa failed!"); delay(100); while (1); } display.display(); delay(2); display.clearDisplay(); } void loop() { Serial.print("Sending packet: "); Serial.println(counter); display.clearDisplay(); display.setTextSize(2); // Normal 1:1 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(F("Pkt No:")); display.print(counter); // send packet LoRa.beginPacket(); LoRa.print(F("Pkt No:")); LoRa.println(counter); LoRa.endPacket(); counter++; delay(3000); } |
Код приемника
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <SPI.h> #include <LoRa.h> #define ss 15 #define rst 16 #define dio0 2 void setup() { Serial.begin(115200); while (!Serial); Serial.println("LoRa Receiver Callback"); LoRa.setPins(ss, rst, dio0); if (!LoRa.begin(433E6)) { Serial.println("Starting LoRa failed!"); while (1); } // register the receive callback LoRa.onReceive(onReceive); // put the radio into receive mode LoRa.receive(); } void loop() { // do nothing } void onReceive(int packetSize) { // received a packet Serial.print("Received packet '"); // read packet for (int i = 0; i < packetSize; i++) { Serial.print((char)LoRa.read()); } // print RSSI of packet Serial.print("' with RSSI "); Serial.println(LoRa.packetRssi()); } |
Результаты и наблюдения
После загрузки кода секция передатчика начнет отправлять данные, а секция приемника начнет получать данные.
Аналогичным образом вы можете открыть последовательный монитор и наблюдать переданные и полученные пакеты с номерами.
Отправка данных о влажности и температуре датчика DHT11 с помощью SX1278 и ESP8266
Вот схема передатчика для данного проекта.
Подключение довольно простое. Подключите выводы OLED дисплея SDA и SCL к контактам D2, D1 Nodemcu соответственно. Подключите выходной вывод DHT11 к D3 Nodemcu, как показано на схеме. Аналогично подключите Lora SX1278 и NodeMCU ESP8266, как указано выше.
Схема приемника останется точно такой же, как и в предыдущем примере, никаких изменений в нее вносить не нужно.
Код передатчика
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
#include <SPI.h> #include <LoRa.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <DHT.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET LED_BUILTIN // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #define DHTPIN 0 //pin where the dht11 is connected #define ss 15 #define rst 16 #define dio0 2 int counter = 0; DHT dht(DHTPIN, DHT11); void setup() { Serial.begin(115200); dht.begin(); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } while (!Serial); Serial.println("LoRa Sender"); LoRa.setPins(ss, rst, dio0); if (!LoRa.begin(433E6)) { Serial.println("Starting LoRa failed!"); delay(100); while (1); } display.display(); delay(2); display.clearDisplay(); } void loop() { float h = dht.readHumidity(); float t = dht.readTemperature(); if (isnan(h) || isnan(t)) { Serial.println("Failed to read from DHT sensor!"); return; } Serial.print("Temperature: "); Serial.print(t); Serial.print(" degrees Celcius, Humidity: "); Serial.println(h); Serial.println(); Serial.print("Sending packet: "); Serial.println(counter); display.clearDisplay(); display.setTextSize(2); // Normal 1:1 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(F("Pkt No:")); display.print(counter); display.setCursor(0,20); display.print("Tem:"); display.print(t); display.print("C"); display.setCursor(0,40); display.print("Hum:"); display.print(h); display.print("%"); display.display(); // send packet LoRa.beginPacket(); LoRa.print(F("Pkt No:")); LoRa.println(counter); LoRa.print("Temp: "); LoRa.print(t); LoRa.println("°C"); LoRa.print("Hum: "); LoRa.print(h); LoRa.print("%"); LoRa.println(""); LoRa.endPacket(); counter++; delay(3000); } |
Код приемника
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#include <SPI.h> #include <LoRa.h> #define ss 15 #define rst 16 #define dio0 4 void setup() { Serial.begin(115200); while (!Serial); Serial.println("LoRa Receiver Callback"); LoRa.setPins(ss, rst, dio0); if (!LoRa.begin(433E6)) { Serial.println("Starting LoRa failed!"); while (1); } // register the receive callback LoRa.onReceive(onReceive); // put the radio into receive mode LoRa.receive(); } void loop() { // do nothing } void onReceive(int packetSize) { // received a packet Serial.println("Received packet '"); // read packet for (int i = 0; i < packetSize; i++) { Serial.print((char)LoRa.read()); } } |
Результаты и наблюдения
После загрузки кода секция передатчика начнет отправлять данные, а секция приемника начнет получать данные. Значение влажности и температуры можно будет наблюдать на OLED-экране.
Аналогичным образом вы можете открыть последовательный монитор и наблюдать переданные и полученные данные о влажности, температуре с номерами пакетов.