你觉得这篇文章怎么样? 帮助我们为您提供更好的内容。
Thank you! Your feedback has been received.
There was a problem submitting your feedback, please try again later.
你觉得这篇文章怎么样?
使用模块化电子平台,快速构建远程无线传感器系统的原型。
第 1 部分概述了我们的应用案例,并探讨了 LoRa 无线调制技术,论述该技术的应用优势,然后探讨部分可用的 XinaBox 硬件。
在本文中,我们将讨论如何对 CR02 模块或“☒芯片”——具有集成微控制器和无线电——进行编程,然后通过 LoRa 无线链路发送和接收数据。
设置
首先,我们需要通过 xBUS 连接器 (174-4977) 将 IP01 (174-3703) 编程器连接到 CR02 (174-3699) 。此外,我们还要连接合适的天线,比如调到 868MHz 频段的 SMA 鞭形天线 (054-2563) ,方能运行 LoRa 示例。
当然,如果我们要同时测试数据的发送和接收,实际上需要两套上述零件!
此外,我们还要安装 Arduino IDE 或者某些其他可以编程 Arduino 兼容板的软件。例如,使用 PlatformIO IDE 在理论上也可以达到目的。
我们将使用名为 RadioHead 的库,提供通过各种常用数据无线电发送和接收分组信息的功能,包括集成到我们正在使用的 CR02 芯片中的 RFM95W。目前,我们似乎需要使用 在 XinaBox GitHub 组织下托管的 RadioHead 叉。
有不同的方法在 Arduino IDE 中安装新库,但最简单的方法是下载 ZIP 归档文件,然后在 IDE 中选择 Sketch(草图)→ Include Library(包含库)→ Add .ZIP Library(添加 .ZIP 库)。
在 Tools(工具)→ Board(板)菜单下,我们需要选择“Arduino Pro 或 Pro Mini”,确保通过 Tools(工具)→ Port(端口)选择恰当的端口。在 Linux 下,IP01 应列举为 /dev/ttyUSB0(如果连接了另一个基于 FTDI 的设备,数字也许会更高)。
你好,世界
完成设置后,我们将讨论“你好,硬件世界”——LED 闪烁!
实际上,CR02 有一个三色 LED,因此所示的闪烁示例比 Arduino IDE 随附的 LED 略大,但是功能基本相同,每种颜色轮流闪烁,依次循环。请注意,在上传草图时,IP01 上的 LED 会在短时间内快速闪烁,如果没有,这就意味着存在硬件错误或端口权限问题。
现在,我们来探讨如何通过 LoRa 无线电来发送和接收数据。
LoRa 服务器
我们从“服务器”草图示例开始。首先,这包括无线模块使用的 RadioHead 库,然后定义一些常量,比如操作频率,和 CR02 一样使用 868MHz 频段。
#include <RH_RF95.h>
#define LED_BUILTIN 16
#define CR02_FREQUENCY 868.0
uint8_t tempdata[30];
接下来在 setup() 中,我们配置用于调试的 LED 引脚和串行端口,然后开始初始化无线电模块并配置其频率和传输功率。
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
if (!CR02.init()) {
Serial.println("init failed");
}
// The default transmitter power is 13dBm, using PA_BOOST.
// If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
// you can set transmitter powers from 5 to 23 dBm:
// Failure to do that will result in extremely low transmit powers.
//CR02.setModemConfig(CR02.Bw31_25Cr48Sf512);
CR02.setFrequency(CR02_FREQUENCY);
CR02.setTxPower(23, false);
}
此外,还有一条注释行,允许设置链路带宽和 LoRa 扩频因子 (SF) 为非默认值。简而言之,扩频因子越大,链路预算就越多,因此范围越长,但代价是带宽减少,空中传输的时间更长。
就开发目的而言,默认的扩频因子是可以的,但这可以针对特定环境进行优化,结合频谱一起使用,以获得最佳的范围和能耗水平。一般来说,传输时间越短越好。然而,如果您想确保信息顺利发送出去,而带宽和电池寿命为次要要求时——例如,报警/警报系统——您可以始终使用最高的 SF。
关于如何使用 setModemConfig() 调用来配置 CR02 LoRa 无线电的详细说明,请参阅 RadioHead 文档。
现在,我们来讨论主循环。在这里,我们寻找一条传入的消息,在收到消息时,打开 LED,把消息连同收到的信号强度指示 (RSSI) 写出到串行端口,然后关闭 LED,最后发送回复。就是这么简单!
void loop()
{
if (CR02.available())
{
// Should be a message for us now
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (CR02.recv(buf, &len))
{
digitalWrite(LED_BUILTIN, HIGH);
Serial.print("got request: ");
Serial.println((char*)buf);
Serial.print("RSSI: ");
Serial.println(CR02.lastRssi(), DEC);
// Send a reply
sprintf(tempdata, "%s", "Hello Client");
CR02.send(tempdata, sizeof(tempdata));
CR02.waitPacketSent();
Serial.println("Sent a reply");
digitalWrite(LED_BUILTIN, LOW);
}
else
{
Serial.println("recv failed");
}
}
}
LoRa 客户端
CRO2 客户端示例非常类似,如您所想,它将发送一条消息,然后等待响应。我们看一下它的主循环:
void loop()
{
Serial.println("Sending to CR02_server");
// Send a message to CR02_server
sprintf(tempdata, "%s", "Hello Server");
CR02.send(tempdata, sizeof(tempdata));
CR02.waitPacketSent();
// Now wait for a reply
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (CR02.waitAvailableTimeout(3000))
{
// Should be a reply message for us now
if (CR02.recv(buf, &len))
{
digitalWrite(LED_BUILTIN, HIGH);
Serial.print("got reply: ");
Serial.println((char*)buf);
Serial.print("RSSI: ");
Serial.println(CR02.lastRssi(), DEC);
}
else
{
Serial.println("recv failed");
}
}
else
{
Serial.println("No reply, is CR02_server running?");
}
digitalWrite(LED_BUILTIN, LOW);
delay(400);
}
您会再次发现,这非常简单,我们可以从服务器中将消息响应连同信号的 RSSI 一起打印出来。
更多高级选项
以上是简单示例,不提供加密/消息身份验证或任何类型的寻址。对于许多系统而言,这也许足够,但是如果需要更多高级功能,可以使用利用加密技术和提供可靠的数据报服务的 RadioHead 示例,包括简单的节点寻址支持。但是,这些示例还没有经过 CR02 的测试,可能需要进行一些修改。
下期预告
在本系列的下一篇文章中,我们会讨论将外围设备加入到机组中,并且无线监控系统将逐一完善。