1. 产品简介
这是一款简单易用的双模远距离无线通信模块,专为户外物联网应用设计,提供稳定可靠、低功耗的长距离通信解决方案。基于LoRa调制技术,模块专为US915频段设计,适用于北美和其他使用该频段的地区。其主要特点如下:
公里级远距离传输
模块提供城区1.5公里、开阔地带4.5公里的有效传输距离,适用于户外物联网项目。注:实际传输距离会受到天气、车流量、建筑密度等环境因素影响。
双模灵活配置(LoRa/LoRaWAN)
支持LoRa点对点(P2P)直连与LoRaWAN组网两种通信模式,灵活配置,满足不同应用需求。
-
在LoRa模式下,模块可以实现一对一、一对多、多对一及桥接通信;
-
在LoRaWAN模式下,模块支持A类和C类工作模式,作为数据采集节点连接网关,转发数据至TTN、ChirpStack等物联网云平台。
简单易用,快速部署
内置LoRa/LoRaWAN协议栈,无需底层开发,支持Arduino IDE、Mind+和MakeCode图形化编程,降低开发和上手难度。此外,模块提供标准I2C和UART通信接口,兼容大部分流行主控,例如Micro:bit、Arduino UNO和ESP32等。便于快速集成至现有物联网项目,提高项目部署效率。
户外IoT通信解决方案
户外物联网场景痛点 | 传统方案 | 本产品解决方案 |
---|---|---|
部署成本高 | 需布线/中继设备,部署复杂且成本高 | 完全无线部署且成本低 |
传输距离短 | WiFi<100m,且网络不稳定 | 公里级稳定传输 |
设备续航短 | 4G/WiFi通信耗电量高 | LoRa/LoRaWAN通信耗电量低 |
适用于长距离、低功耗的物联网通信场景,如农场环境监测、气象站数据采集、工业监测、花园种植监测等项目。
2. 产品特性
- 兼容3.3V和5V电平
- 支持UART和I2C两种通讯方式
- 板载PCB天线,模块一体化设计
- 城区1.5公里/开阔地带4.5公里有效覆盖
- 适用北美和其他使用US915频段的地区
- 支持LoRa一对一、一对多、多对一和桥接通信
- 支持ABP和OTAA两种LoRaWAN入网方式
- 主控兼容性广,支持Micro:bit、Arduino UNO和ESP32等其他主控
- 简单易用,支持Arduino IDE、Mind+以及MakeCode图形化编程
3. 应用场景
- 农作物生长监测
- 大棚温湿度监测
- 生态区环境监测
- 蜜蜂蜂箱自动监测
- LoRaWAN气象站
- 花园种植项目
- 户外物联网教学
4. 功能指示图
引脚名称 | 引脚全称 | 引脚功能 |
---|---|---|
T/D | UATR_TX/I2C_SDA | TX,数据发送引脚/SDA,数据传输引脚 |
R/C | UATR_RX/I2C_SCL | RX,数据接收引脚/SCL,I2C时钟引脚 |
- | DGND | 电源负极,连接主控的GND数字地 |
+ | VCC | 电源正极,DC 3.3V~5V(需与主控系统电平一致) |
指示灯名称 | 指示灯全称 | 指示灯功能 |
PWR | Power | 红色电源指示灯,电源输入时常亮 |
ACT | Active | 绿色状态指示灯,分别提示三种状态:1、发送入网包时闪烁1秒;2、入网成功时常亮5秒;3、发送数据或接收数据时闪烁300ms |
注意:拨码开关默认为 I2C 模式,可以在 I2C 和 UART 之间切换。切换后重启模块。
5. 技术规格
基本参数
供电电压 | DC 3.3V~5V |
---|---|
通讯方式 | I2C/UART |
供电/通讯接口 | PH2.0-4P |
安装孔径 | 3.0mm |
安装孔间距 | 35mm |
产品尺寸 | 42x62mm |
产品净重 | 10g |
LoRa参数
射频芯片 | SX1262 |
---|---|
工作频率 | 915MHz |
支持地区 | 北美及其他适用US915频段的地区 |
调制方式 | LoRa调制 |
扩频因子 | 7~12 |
最大发射功率 | +22dBm |
接收灵敏度 | -137dBm(SF=12/BW=125kHz) |
6. 产品尺寸图
7. LoRa点对点(P2P)使用教程
7.1.1 硬件准备
- FireBeetle 2 ESP32-E(SKU:DFR0654)×3
- Gravity:LoRaWAN节点模块(US915)(DFR1115-915) ×3
- Gravity: DHT11温湿度传感器(SKU:DFR0067)×1
- Gravity:LTR390-UV紫外线传感器(SKU:SEN0540)×1
- PH2.0-4P排线 ×3
- USB数据线 ×3
7.1.2 软件准备
- 下载Arduino IDE: 点击下载Arduino IDE
- 安装SDK:点击进入FireBeetle 2 ESP32-E WIKI页面 查找SDK安装教程
- 下载Arduino库:点击下载DFRobot_LWNode库 点击链接查看:如何安装库?
7.1.3 一发一收应用例程
在LoRa通信模式下,每个节点设备需设置自定义地址(范围1~255):
地址 | 说明 |
---|---|
0 | 非法地址(不可用) |
1~244 | 可重复使用的有效地址,比如将2个节点的地址都设置为3 |
255 | 广播地址(发送至255时全网段设备均可接收) |
故本节例程介绍:适用两个FireBeetle 2 ESP32-E主控各扩展一个节点模块(地址分别为1和2),通过差异化地址配置实现温湿度传感器的定向长距离数据传输。
硬件连接:
- 发送端:
- 接收端:
示例代码:
发送端程序:设置节点地址为1,向地址为2的节点发送数据
#include <DFRobot_LWNode.h>
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 4
#define FREQ 914900000
DFRobot_LWNode_IIC node(1); //设置节点地址为1
void setup( void ) {
Serial.begin(115200);
delay(5000);
node.begin(/*communication IIC*/&Wire,/*debug UART*/&Serial);
const uint32_t loraConfig[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(loraConfig[0]) ||
!node.setEIRP(loraConfig[1]) ||
!node.setBW(loraConfig[2]) ||
!node.setSF(loraConfig[3]) ||
!node.start()) {
Serial.println("LoRa init failed");
delay(2000);
}
}
void loop( void ){
DHT.read(DHT11_PIN); //获取DHT11温湿度传感器数据
Serial.print(DHT.humidity,1);
Serial.print(",\t");
Serial.println(DHT.temperature,1);
String DHT11_DATE=String(DHT.humidity)+"%"+" "+String(DHT.temperature) + "℃";
delay(2000);
node.sendPacket(2, DHT11_DATE); //发送温湿度数据给地址为2的节点
node.sleep(5000);
}
接收端程序:节点地址为2的设备烧录以下代码
#include <DFRobot_LWNode.h>
#define FREQ 914900000
DFRobot_LWNode_IIC node(2);//设置节点地址为2
void rxCBFunc(uint8_t from, void *buffer, uint16_t size, int8_t rssi, int8_t snr){
char *p = (char *)buffer;
Serial.print("recv from: ");
Serial.println(from, HEX);
Serial.print("recv data: ");
for(uint8_t i = 0; i < size; i++){
Serial.print(p[i]);
}
Serial.println();
Serial.println("Text:");
Serial.println((char *)buffer);
Serial.print("rssi=");Serial.println(rssi);
Serial.print("snr=");Serial.println(snr);
}
void setup( void ){
Serial.begin(115200);
delay(5000);
node.begin(/*communication IIC*/&Wire,/*debug UART*/&Serial);
const uint32_t config[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(config[0]) ||
!node.setEIRP(config[1]) ||
!node.setBW(config[2]) ||
!node.setSF(config[3]) ||
!node.start()) {
Serial.println("LoRa init failed, retrying...");
delay(2000);
}
node.setRxCB(rxCBFunc);
}
void loop( void ){
node.sleep(5000);
}
**运行结果:**通信成功,发送端和接收端的串口打印信息如下
7.1.4 一发两收应用例程
关于节点的一对多通信模式,可分为两种类型:
- 单发多收模式:一个节点发送数据,多个节点同时接收。
- 单收多发模式:一个节点接收数据,多个节点同时发送。
本实例演示的是第一种单发多收模式:将地址为1的节点设置为发送端,地址为2的两个节点(节点2和节点3)作为接收端,实现"一发两收"的通信场景。
硬件连接:
这里采用的是UART通讯方式。
- 发送端:
- 接收端(第一组和第二组都为以下连接方式):
示例代码:
发送端程序:设置节点地址为1,向地址为2的节点发送温湿度传感器的数据
#include <DFRobot_LWNode.h>
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 4
#define FREQ 914900000
DFRobot_LWNode_UART node(1); //设置节点地址为1
void setup( void ) {
Serial.begin(115200);
Serial1.begin(9600, SERIAL_8N1, /*rx =*/D6, /*tx =*/D7);
delay(5000);
node.begin(/*communication UART*/&Serial1,/*debug UART*/&Serial);
const uint32_t config[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(config[0]) ||
!node.setEIRP(config[1]) ||
!node.setBW(config[2]) ||
!node.setSF(config[3]) ||
!node.start()) {
Serial.println("LoRa init failed, retrying...");
delay(2000);
}
}
void loop( void ){
DHT.read(DHT11_PIN); //获取DHT11温湿度传感器数据
Serial.print(DHT.humidity,1);
Serial.print(",\t");
Serial.println(DHT.temperature,1);
String DHT11_DATE=String(DHT.humidity)+"%"+" "+String(DHT.temperature) + "℃";
delay(2000);
node.sendPacket(2, DHT11_DATE); //发送温湿度数据给地址为2的节点
node.sleep(5000);
}
接收端第一组和第二组使用以下程序(注意设置不同的串口):节点地址为2,接收来自节点地址为1的数据。
#include <DFRobot_LWNode.h>
#define FREQ 914900000
DFRobot_LWNode_UART node(2);//设置节点地址为2
void rxCBFunc(uint8_t from, void *buffer, uint16_t size, int8_t rssi, int8_t snr){
char *p = (char *)buffer;
Serial.print("recv from: ");
Serial.println(from, HEX);
Serial.print("recv data: ");
for(uint8_t i = 0; i < size; i++){
Serial.print(p[i]);
}
Serial.println();
Serial.print("rssi=");Serial.println(rssi);
Serial.print("snr=");Serial.println(snr);
}
void setup( void ){
Serial.begin(115200);
Serial1.begin(9600, SERIAL_8N1, /*rx =*/D6, /*tx =*/D7);
delay(5000);
node.begin(/*communication UART*/&Serial1,/*debug UART*/&Serial);
const uint32_t config[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(config[0]) ||
!node.setEIRP(config[1]) ||
!node.setBW(config[2]) ||
!node.setSF(config[3]) ||
!node.start()) {
Serial.println("LoRa init failed, retrying...");
delay(2000);
}
node.setRxCB(rxCBFunc);
}
void loop( void ){
node.sleep(5000);
}
运行结果:
发送端串口打印信息:
接收端第一组串口打印信息:
接收端第二组串口打印信息:
7.1.5 两发一收应用例程
本实例演示的是第二种单收多发模式:将地址为1和2的节点设置为发送端,地址为3的节点作为接收端,实现"两发一收"的通信场景。
硬件连接:
- 发送端:
- 接收端:
示例代码:
发送端第一组程序:设置节点地址为1,向地址为3的节点发送温湿度传感器的数据
#include <DFRobot_LWNode.h>
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 4
#define FREQ 914900000
DFRobot_LWNode_UART node(1); //设置节点地址为1
void setup( void ) {
Serial.begin(115200);
Serial1.begin(9600, SERIAL_8N1, /*rx =*/D6, /*tx =*/D7);
delay(5000);
node.begin(/*communication UART*/&Serial1,/*debug UART*/&Serial);
const uint32_t loraConfig[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(loraConfig[0]) ||
!node.setEIRP(loraConfig[1]) ||
!node.setBW(loraConfig[2]) ||
!node.setSF(loraConfig[3]) ||
!node.start()) {
Serial.println("LoRa init failed");
delay(2000);
}
}
void loop( void ){
DHT.read(DHT11_PIN); //获取DHT11温湿度传感器数据
Serial.print(DHT.humidity,1);
Serial.print(",\t");
Serial.println(DHT.temperature,1);
String DHT11_DATE=String(DHT.humidity)+"%"+" "+String(DHT.temperature) + "℃";
delay(2000);
node.sendPacket(3, DHT11_DATE); //发送温湿度数据给地址为3的节点
node.sleep(5000);
}
发送端第二组程序:设置节点地址为2,向地址为3的节点发送紫外线传感器的数据。
#include <DFRobot_LWNode.h>
#define FREQ 914900000
#include "DFRobot_LTR390UV.h"
DFRobot_LTR390UV ltr390(/*addr = */LTR390UV_DEVICE_ADDR, /*pWire = */&Wire);
DFRobot_LWNode_UART node(2);
void setup( void ) {
Serial.begin(115200);
Serial1.begin(9600, SERIAL_8N1, /*rx =*/D6, /*tx =*/D7);
delay(5000);
node.begin(/*communication UART*/&Serial1,/*debug UART*/&Serial);
const uint32_t loraConfig[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(loraConfig[0]) ||
!node.setEIRP(loraConfig[1]) ||
!node.setBW(loraConfig[2]) ||
!node.setSF(loraConfig[3]) ||
!node.start()) {
Serial.println("LoRa init failed");
delay(2000);
}
while(ltr390.begin() != 0){
Serial.println(" Sensor initialize failed!!");
delay(1000);
}
Serial.println(" Sensor initialize success!!");
ltr390.setALSOrUVSMeasRate(ltr390.e18bit,ltr390.e100ms);//18位数据,采样时间100ms
ltr390.setALSOrUVSGain(ltr390.eGain3);//3倍增益
ltr390.setMode(ltr390.eUVSMode);//设置测量紫外线模式
}
void loop( void ){
uint32_t uv = 0;
uv = ltr390.readOriginalData();//获取紫外线数据原始数据
Serial.println(uv);
String ltr390_DATE = String(uv);
delay(2000);
node.sendPacket(3, ltr390_DATE); //发送紫外线传感器的数据给地址为3的节点
node.sleep(5000);
}
接收端程序:将接收端的节点地址设置为3,并处于接收消息状态。
#include <DFRobot_LWNode.h>
#define FREQ 914900000
DFRobot_LWNode_UART node(3);//设置节点地址为3
void rxCBFunc(uint8_t from, void *buffer, uint16_t size, int8_t rssi, int8_t snr){
char *p = (char *)buffer;
Serial.print("recv from: ");
Serial.println(from, HEX);
Serial.print("recv data: ");
for(uint8_t i = 0; i < size; i++){
Serial.print(p[i]);
}
Serial.println();
Serial.println("Text:");
Serial.println((char *)buffer);
Serial.print("rssi=");Serial.println(rssi);
Serial.print("snr=");Serial.println(snr);
}
void setup( void ){
Serial.begin(115200);
Serial1.begin(9600, SERIAL_8N1, /*rx =*/D6, /*tx =*/D7);
delay(5000);
node.begin(/*communication UART*/&Serial1,/*debug UART*/&Serial);
const uint32_t loraConfig[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(loraConfig[0]) ||
!node.setEIRP(loraConfig[1]) ||
!node.setBW(loraConfig[2]) ||
!node.setSF(loraConfig[3]) ||
!node.start()) {
Serial.println("LoRa init failed");
delay(2000);
}
node.setRxCB(rxCBFunc);
}
void loop( void ){
node.sleep(5000);
}
运行结果:
发送端第一组串口打印信息:
发送端第二组串口打印信息:
接收端串口打印信息:可以接收来自发送端第一组和第二组的数据
7.1.6 数据搭桥应用例程
前面介绍了节点数据的接收和发送,除了这样的玩法之外,节点还可以通过数据搭桥来实现更远距离的通信。
在本节例程中,将3个节点分别记作节点A、节点B、节点C,设备地址分别设置为1、2、3,来实现数据搭桥A→B→C,即将节点A的数据转给节点B,再由中间设备节点B转发给节点C,这样超过通信距离的节点C可以接收到来自节点A的数据,相当于扩展了通信距离。
硬件连接:
- 节点A:
- 节点B和节点C均采用以下连接方式:
示例代码:
节点A程序:设置节点地址为1,向地址为2的节点B发送温湿度传感器的数据。
#include <DFRobot_LWNode.h>
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 4
#define FREQ 914900000
DFRobot_LWNode_UART node(1); //设置节点地址为1
void setup( void ) {
Serial.begin(115200);
Serial1.begin(9600, SERIAL_8N1, /*rx =*/D6, /*tx =*/D7);
delay(5000);
node.begin(/*communication UART*/&Serial1,/*debug UART*/&Serial);
const uint32_t loraConfig[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(loraConfig[0]) ||
!node.setEIRP(loraConfig[1]) ||
!node.setBW(loraConfig[2]) ||
!node.setSF(loraConfig[3]) ||
!node.start()) {
Serial.println("LoRa init failed");
delay(2000);
}
}
void loop( void ){
DHT.read(DHT11_PIN); //获取DHT11温湿度传感器数据
Serial.print(DHT.humidity,1);
Serial.print(",\t");
Serial.println(DHT.temperature,1);
String DHT11_DATE=String(DHT.humidity)+"%"+" "+String(DHT.temperature) + "℃";
delay(2000);
node.sendPacket(2, DHT11_DATE); //发送温湿度数据给地址为2的节点
node.sleep(1000);
}
节点B程序:设置节点地址为2,接收来自节点A的数据,然后向地址为3的节点C发送该数据。
#include <DFRobot_LWNode.h>
#define FREQ 914900000
DFRobot_LWNode_UART node(2);//设置节点地址为2
char p[36];
void rxCBFunc(uint8_t from, void *buffer, uint16_t size, int8_t rssi, int8_t snr){
memcpy(p,buffer,size); //内存拷贝,把buffer的数据给copy到p数组里面
Serial.print("recv from: ");
Serial.println(from, HEX);
Serial.print("recv data: ");
for(uint8_t i = 0; i < size; i++){
Serial.print(p[i]);
}
Serial.println();
Serial.print("rssi=");Serial.println(rssi);
Serial.print("snr=");Serial.println(snr);
}
void setup( void ){
Serial.begin(115200);
Serial1.begin(9600, SERIAL_8N1, /*rx =*/D6, /*tx =*/D7);
delay(5000);
node.begin(/*communication UART*/&Serial1,/*debug UART*/&Serial);
const uint32_t loraConfig[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(loraConfig[0]) ||
!node.setEIRP(loraConfig[1]) ||
!node.setBW(loraConfig[2]) ||
!node.setSF(loraConfig[3]) ||
!node.start()) {
Serial.println("LoRa init failed");
delay(2000);
}
node.setRxCB(rxCBFunc);
}
void loop( void ){
node.sleep(5000);
node.sendPacket(3, p); //将接收到的消息转发给地址为3的节点
}
节点C程序:节点地址设置为3,并处于接收消息状态,接收来自节点B的数据。
#include <DFRobot_LWNode.h>
#define FREQ 914900000
DFRobot_LWNode_UART node(3);//设置节点地址为3
void rxCBFunc(uint8_t from, void *buffer, uint16_t size, int8_t rssi, int8_t snr){
char *p = (char *)buffer;
Serial.print("recv from: ");
Serial.println(from, HEX);
Serial.print("recv data: ");
for(uint8_t i = 0; i < size; i++){
Serial.print(p[i]);
}
Serial.println();
Serial.print("rssi=");Serial.println(rssi);
Serial.print("snr=");Serial.println(snr);
}
void setup( void ){
Serial.begin(115200);
Serial1.begin(9600, SERIAL_8N1, /*rx =*/D6, /*tx =*/D7);
delay(5000);
node.begin(/*communication UART*/&Serial1,/*debug UART*/&Serial);
const uint32_t loraConfig[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(loraConfig[0]) ||
!node.setEIRP(loraConfig[1]) ||
!node.setBW(loraConfig[2]) ||
!node.setSF(loraConfig[3]) ||
!node.start()) {
Serial.println("LoRa init failed");
delay(2000);
}
node.setRxCB(rxCBFunc);
}
void loop( void ){
node.sleep(5000);
}
运行结果:
节点A串口打印信息:
节点B串口打印信息:接收到节点A的数据,并转发出去
节点C串口打印信息:接收到了节点B的数据。
8. LoRaWAN使用教程
8.1 FireBeetle ESP32-E主板使用教程
8.1.1 硬件准备
- FireBeetle 2 ESP32-E(SKU: DFR0654)×1
- Gravity:LoRaWAN节点模块(US915)(DFR1115-915) ×1
- PH2.0-4P排线 ×1
- USB数据线 ×1
8.1.2 软件准备
- 下载Arduino IDE: 点击下载Arduino IDE
- 安装SDK:点击进入FireBeetle 2 ESP32-E WIKI页面 查找SDK安装教程
- 下载Arduino库:点击下载DFRobot_LWNode库 点击链接查看:如何安装库?
8.1.3 硬件连接
I2C通讯示例(以下例程中均采用这种连接方式)
管脚连接说明:
- 节点模块:SDA引脚---(连接)---主控:21/SDA
- 节点模块:SCL引脚---(连接)---主控:22/SCL
- 节点模块:- 引脚---(连接)---主控:GND
- 节点模块:+引脚---(连接)---主控:3V3
UART通讯示例
管脚连接说明:
- 节点模块:TX 引脚---(连接)---主控:14/D6
- 节点模块:RX 引脚---(连接)---主控:13/D7
- 节点模块:- 引脚---(连接)---主控:GND
- 节点模块:+引脚---(连接)---主控:3V3
8.1.3.1 OTAA入网
**注意:**使用该例程前,需要在网关端选择手动添加设备时选择OTAA模式入网。
例程1:OTAA入网并发送数据到网关
示例代码:
#include "DFRobot_LWNode.h"
#define REGION US915
#define DATARATE DR3
#define SUBBAND 2
const char _APPEUI[]={"DFDFDFDF00000000"} ;
const char _APPKEY[]={"0102030405060708090A0B0C0D0E0F10"};
uint8_t _DEVEUI[16]={0x0};
DFRobot_LWNode_IIC node(_APPEUI,_APPKEY);
void setup(void){
Serial.begin(115200);
node.begin(/*communication IIC*/&Wire,/*debug UART*/&Serial);
while(!node.setRegion(REGION)){
delay(2000);
Serial.println("REGION set fail");
}
if(!node.setAppEUI(_APPEUI)){
Serial.println("AppEUI set fail");
}
if(!node.setAppKEY(_APPKEY)){
Serial.println("AppKEY set fail");
}
if(!node.setDevType(CLASS_C)){
Serial.println("DevType set fail");
}
while (!node.setDataRate(DATARATE)) {
delay(2000);
Serial.println("DataRate set fail");
}
while (!node.setEIRP(DBM16)) {
delay(2000);
Serial.println("EIRP set fail");
}
while(!node.setSubBand(SUBBAND)){
Serial.println("SubBand set fail");
}
while(!node.enableADR(false)){
delay(2000);
Serial.println("ADR set fail");
}
while(!node.setPacketType(UNCONFIRMED_PACKET)){
delay(2000);
Serial.println("Packet type set fail");
}
if(node.getDevEUI(_DEVEUI)){
Serial.print("deveui:");
for(uint8_t i=0;i<8;i++){
Serial.print(_DEVEUI[i],HEX);
}
Serial.println();
}
if(node.join()){
Serial.println("JOIN......"); //入网
}
while(!node.isJoined()){
delay(5000);
}
}
void loop(){
node.sendPacket("hello"); ////发送消息给网关
node.sleep(10 * 1000);
uint8_t buf[3]={1,2,3};
node.sendPacket(buf,3)
node.sleep(10 * 1000);
}
运行结果:
节点端:串口打印显示入网成功,并且间隔10秒发送数据给网关。
例程2:OTAA 入网后通过轮询方式从网关接收数据
示例代码:
#include "DFRobot_LWNode.h"
#define REGION US915
#define DATARATE DR3
#define SUBBAND 2
const char _APPEUI[]={"DFDFDFDF00000000"} ;
const char _APPKEY[]={"0102030405060708090A0B0C0D0E0F10"};
uint8_t _DEVEUI[8]={0x0};
uint8_t buf[256]={0x0};
DFRobot_LWNode_IIC node(_APPEUI,_APPKEY);
void setup(void){
Serial.begin(115200);
node.begin(/*communication IIC*/&Wire,/*debug UART*/&Serial);
while(!node.setRegion(REGION)){
delay(2000);
Serial.println("REGION set fail");
}
while(!node.setDevType(CLASS_C)){
delay(2000);
Serial.println("DevType set fail");
}
while(!node.setSubBand(SUBBAND)){
delay(2000);
Serial.println("SubBand set fail");
}
if(node.join()){
Serial.println("JOIN......"); //入网
}
while(!node.isJoined()){
delay(5000);
}
Serial.println("join success");
}
void loop(){
uint8_t len = node.readData(buf); //读取缓冲区是否接到数据
if(len > 0){
Serial.print("\nreceive ");Serial.print(len,HEX);Serial.println(" bytes \nHEX:");
for(uint8_t i = 0;i<len;i++){
Serial.print(buf[i],HEX);
}
Serial.println();
Serial.println("Text:");
Serial.println((char *)buf);
}
delay(500);
}
运行结果:
节点端:串口信息打印join success,然后节点进入轮询读取缓冲区是否接收到数据状态
8.1.3.2 ABP入网
**注意:**使用该例程前,需要在网关端选择手动添加设备时选择ABP模式入网。
例程1:ABP入网并向网关发送数据
示例代码:
#include "DFRobot_LWNode.h"
const char NWKSKEY[]={"87888888888888888888888888888888"};
const char APPSKEY[]={"89888888888888888888888888888888"};
uint32_t devAddr = 0xDF000011;
uint8_t _DEVEUI[16]={0x0};
#define REGION US915
#define DATARATE DR3
#define SUBBAND 2
DFRobot_LWNode_IIC node(devAddr, NWKSKEY, APPSKEY);
void setup(void) {
Serial.begin(115200);
node.begin(/*communication IIC*/&Wire,/*debug UART*/&Serial);
while(!node.setRegion(REGION)){
delay(2000);
Serial.println("REGION set fail");
}
if (!node.setAppSKey(APPSKEY)) {
Serial.println("APPSKEY set fail");
}
if (!node.setNwkSKey(NWKSKEY)) {
Serial.println("NWKSKEY set fail");
}
if (!node.setDevAddr(devAddr)) {
Serial.println("devAddr set fail");
}
while (!node.setDataRate(DATARATE)) {
delay(2000);
Serial.println("DataRate set fail");
}
while (!node.setEIRP(DBM16)) {
delay(2000);
Serial.println("EIRP set fail");
}
while(!node.setSubBand(SUBBAND)) {
delay(2000);
Serial.println("SubBand set fail");
}
while(!node.enableADR(false)) {
delay(2000);
Serial.println("ADR set fail");
}
while(!node.setPacketType(UNCONFIRMED_PACKET)) {
delay(2000);
Serial.println("Packet type set fail");
}
if (node.getDevEUI(_DEVEUI)) {
Serial.print("deveui:");
for (uint8_t i = 0; i < 8; i++) {
Serial.print(_DEVEUI[i], HEX);
}
Serial.println();
}
}
void loop() {
node.sendPacket("hello");//发送消息给网关
node.sleep(10 * 1000);
uint8_t buf[3] = {1, 2, 3};
node.sendPacket(buf, 3);
node.sleep(10 * 1000);
}
运行结果:
节点端:串口打印显示入网成功,并且间隔10秒发送数据给网关。
例程2:OTAA 入网后通过轮询方式从网关接收数据
示例代码:
#include "DFRobot_LWNode.h"
const char NWKSKEY[]={"87888888888888888888888888888888"} ;
const char APPSKEY[]={"89888888888888888888888888888888"};
uint32_t devAddr = 0xDF000011;
uint8_t _DEVEUI[16]={0x0};
uint8_t buf[256];
#define REGION US915
#define DATARATE DR3
#define SUBBAND 2
DFRobot_LWNode_IIC node(devAddr,NWKSKEY,APPSKEY);
void setup(void){
Serial.begin(115200);
delay(5000);
node.begin(/*communication IIC*/&Wire,/*debug UART*/&Serial);
while(!node.setRegion(REGION)){
delay(2000);
Serial.println("REGION set fail");
}
while(!node.setDevType(CLASS_C)){
delay(2000);
Serial.println("DevType set fail");
}
Serial.println("join success");
}
void loop(){
uint8_t len = node.readData(buf); //读取缓冲区是否接到数据
if(len > 0){
Serial.print("\nreceive ");Serial.print(len);Serial.println(" bytes \nHEX:");
for(uint8_t i = 0; i < len; i++){
Serial.print(buf[i],HEX);
}
Serial.println();
Serial.println("Text:");
Serial.println((char *)buf);
}
node.sleep(500);
}
运行结果:
节点端:串口打印消息join success,然后节点进入轮询读取缓冲区是否接收到数据状态。
10. API函数库
/**
* @fn setRegion
* @brief 设置 LoRaWAN 区域。
* @param region 区域枚举值
* @return 如果成功则返回 true,否则返回 false
*/
bool setRegion(eRegion_t region);
/**
* @fn setFreq
* @brief 设置频率。
* @param freq 频率值
* @return 如果成功则返回 true,否则返回 false
*/
bool setFreq(uint32_t freq);
/**
* @fn setBW
* @brief 设置带宽。
* @param bw 带宽值
* @return 如果成功则返回 true,否则返回 false
*/
bool setBW(uint32_t bw);
/**
* @fn setSF
* @brief 设置扩频因子。
* @param sf 扩频因子值
* @return 如果成功则返回 true,否则返回 false
*/
bool setSF(uint8_t sf);
/**
* @fn setRxCB
* @brief 设置接收回调函数。当网关向节点发送数据时会调用此函数。
* @param callback 回调函数指针
*/
void setRxCB(rxCB *callback);
/**
* @fn setRxCB
* @brief 为特定情况设置接收回调函数。
* @param callback 回调函数指针
*/
void setRxCB(rxCB3 *callback);
/**
* @fn setAppEUI
* @brief 设置应用 EUI。
* @param appeui 应用 EUI
* @return 如果成功则返回 true,否则返回 false
*/
bool setAppEUI(const char *appeui);
/**
* @fn setAppKEY
* @brief 设置应用密钥。
* @param appkey 应用密钥
* @return 如果成功则返回 true,否则返回 false
*/
bool setAppKEY(const char *appkey);
/**
* @fn setDevType
* @brief 设置设备类型。
* @param classType 设备类别枚举值
* @return 如果成功则返回 true,否则返回 false
*/
bool setDevType(eDeviceClass_t classType);
/**
* @fn setDataRate
* @brief 设置数据速率。
* @param dataRate 数据速率枚举值
* @return 如果成功则返回 true,否则返回 false
*/
bool setDataRate(eDataRate_t dataRate);
/**
* @fn setEIRP
* @brief 设置发射功率。
* @param EIRP 发射功率值
* @return 如果成功则返回 true,否则返回 false
*/
bool setEIRP(uint8_t EIRP);
/**
* @fn setSubBand
* @brief 设置子频段。
* @param subBand 子频段值
* @return 如果成功则返回 true,否则返回 false
*/
bool setSubBand(uint8_t subBand);
/**
* @fn enableADR
* @brief 启用或禁用自适应数据速率(ADR)。
* @param adr 如果为 true,则启用 ADR;如果为 false,则禁用 ADR
* @return 如果成功则返回 true,否则返回 false
*/
bool enableADR(bool adr);
/**
* @fn setDevAddr
* @brief 设置设备地址。
* @param devAddr 设备地址
* @return 如果成功则返回 true,否则返回 false
*/
bool setDevAddr(const uint32_t devAddr);
/**
* @fn setAppSKey
* @brief 设置应用会话密钥。
* @param appSKey 应用会话密钥
* @return 如果成功则返回 true,否则返回 false
*/
bool setAppSKey(const char *appSKey);
/**
* @fn setNwkSKey
* @brief 设置网络会话密钥。
* @param nwkSKey 网络会话密钥
* @return 如果成功则返回 true,否则返回 false
*/
bool setNwkSKey(const char *nwkSKey);
/**
* @fn join
* @brief 启动 LoRaWAN 加入过程。设备将自动尝试加入网络。
* @return 如果成功启动则返回 true,否则返回 false
*/
bool join();
/**
* @fn start
* @brief 启动设备操作。
* @return 如果成功则返回 true,否则返回 false
*/
bool start();
/**
* @fn setLoRaAddr
* @brief 设置 LoRa 地址。
* @param addr LoRa 地址
* @return 如果成功则返回 true,否则返回 false
*/
bool setLoRaAddr(uint8_t addr);
/**
* @fn isJoined
* @brief 检查设备是否已经加入网络。
* @return 如果已加入则返回 true,否则返回 false
*/
bool isJoined();
/**
* @fn sendPacket
* @brief 发送数据包。
* @param v 要发送的值
* @return 如果成功则返回 true,否则返回 false
*/
bool sendPacket(double v);
bool sendPacket(int32_t v);
bool sendPacket(uint32_t v);
bool sendPacket(void *buffer, uint8_t size);
/**
* @fn sendPacket
* @brief 向特定地址发送数据包。
* @param addr 目标地址
* @param v 要发送的值
* @return 如果成功则返回 true,否则返回 false
*/
bool sendPacket(uint8_t addr, double v);
bool sendPacket(uint8_t addr, int32_t v);
bool sendPacket(uint8_t addr, uint32_t v);
bool sendPacket(uint8_t addr, void *buffer, uint8_t size);
/**
* @fn sendPacket
* @brief 发送字符串数据包。
* @param data 要发送的字符串数据
* @return 如果成功则返回 true,否则返回 false
*/
bool sendPacket(String data);
/**
* @fn sendPacket
* @brief 向特定地址发送字符串数据包。
* @param addr 目标地址
* @param data 要发送的字符串数据
* @return 如果成功则返回 true,否则返回 false
*/
bool sendPacket(uint8_t addr, String data);
/**
* @fn sendATCmd
* @brief 发送通用 AT 命令。
* @param cmd 预格式化的 AT 命令,不包含 \r\n
* @return AT 命令的响应
*/
String sendATCmd(String cmd);
/**
* @fn sendATCmdTest
* @brief 发送测试 AT 命令。
* @param cmd 测试 AT 命令
* @return 测试 AT 命令的响应
*/
String sendATCmdTest(char *cmd);
/**
* @fn setPacketType
* @brief 设置数据包类型。
* @param type 数据包类型(CONFIRMED_PACKET 或 UNCONFIRMED_PACKET)
* @return 如果成功则返回 true,否则返回 false
*/
bool setPacketType(ePacketType_t type = UNCONFIRMED_PACKET);
/**
* @fn getDevEUI
* @brief 获取设备 EUI。
* @return 设备 EUI 字符串
*/
String getDevEUI();
/**
* @fn getNetID
* @brief 获取网络 ID。
* @return 3 字节网络 ID 信息
*/
uint32_t getNetID();
/**
* @fn getDevAddr
* @brief 获取设备地址。在 OTAA 模式下,此地址由网关分配。
* @return 4 字节设备地址信息
*/
uint32_t getDevAddr();
/**
* @fn getDataRate
* @brief 获取当前数据速率。
* @return 当前数据速率
*/
uint8_t getDataRate();
/**
* @fn getEIRP
* @brief 获取当前发射功率。
* @return 当前发射功率
*/
uint8_t getEIRP();
/**
* @fn getRSSI
* @brief 获取接收信号强度指示(RSSI)。
* @return RSSI 值
*/
int16_t getRSSI();
/**
* @fn getSNR
* @brief 获取信噪比(SNR)。
* @return SNR 值
*/
int8_t getSNR();
/**
* @fn atTest
* @brief 执行 AT 测试命令。
* @return 测试命令的结果
*/
bool atTest();
11. 产品兼容性
本产品理论上支持所有的3.3V和5V的Arduino主控。以下表格列举了该产品在不同的主控中的测试情况。
主控板名称 | 功能正常 | 功能异常 | 未经验证 |
---|---|---|---|
Arduino Uno | √ | ||
Arduino MEGA2560 | √ | ||
Arduino Leonardo | √ | ||
FireBeetle-ESP8266 | √ | ||
FireBeetle-ESP32 | √ | ||
FireBeetle 2 ESP32-E | √ | ||
micro:bit | √ |
12. 资料下载
13. 常见问题
-
问:拨码开关切换通讯方式后,为什么不起作用?
答:在模块上电的情况下切换通讯方式之后,需要给模块重新上电才会生效。
-
问:模块的通信距离是多少?
稳定通信距离 极限通信距离 EU868版本 城区1.2公里/开阔地带4公里 城区1.4公里/开阔地带4.4公里 US915版本 城区1.5公里/开阔地带4.5公里 城区2公里/开阔地带4.7公里 以上测试数据仅供参考,通信距离受环境影响很大(车流量、天气情况、基站干扰等因素),实际距离要以实际部署为准。
14. 更多
还没有客户对此产品有任何问题,欢迎通过qq或者论坛联系我们!
更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。