嘿!您似乎在 United States,您想使用我们的 English 网站吗?
Switch to English site
Skip to main content

使用 XinaBox 构建 LoRa 无线监控系统的原型第二部分:发送数据

Main23_2430ca1117f911b38f5c17bec9f5ea6d2f8e4ca1.jpg

使用模块化电子平台,快速构建远程无线传感器系统的原型。

第 1 部分概述了我们的应用案例,并探讨了 LoRa 无线调制技术,论述该技术的应用优势,然后探讨部分可用的 XinaBox 硬件。

在本文中,我们将讨论如何对 CR02 模块或“☒芯片”——具有集成微控制器和无线电——进行编程,然后通过 LoRa 无线链路发送和接收数据。

设置

IP01CR02_9d110cd278346f520f09bc46ca9b111221d226ba.jpg

首先,我们需要通过 xBUS 连接器 (174-4977) 将 IP01 (174-3703) 编程器连接到 CR02 (174-3699) 。此外,我们还要连接合适的天线,比如调到 868MHz 频段的 SMA 鞭形天线 (054-2563) ,方能运行 LoRa 示例。

AntennaDetail_f69ce59a3cdfbb14fffb614346c6fbf42399335c.jpg

当然,如果我们要同时测试数据的发送和接收,实际上需要两套上述零件!

此外,我们还要安装 Arduino IDE 或者某些其他可以编程 Arduino 兼容板的软件。例如,使用 PlatformIO IDE 在理论上也可以达到目的。

PLWM-P2_RadioHeadDownload_e3ee16139a43e1a6071a238d2815e4fa1fcf4e55.jpg

我们将使用名为 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 的设备,数字也许会更高)。

你好,世界

CR02Blink_6c920636bc6433a7565640d72aa1ce2fe5f5518f.jpg

完成设置后,我们将讨论“你好,硬件世界”——LED 闪烁!

实际上,CR02 有一个三色 LED,因此所示的闪烁示例比 Arduino IDE 随附的 LED 略大,但是功能基本相同,每种颜色轮流闪烁,依次循环。请注意,在上传草图时,IP01 上的 LED 会在短时间内快速闪烁,如果没有,这就意味着存在硬件错误或端口权限问题。

现在,我们来探讨如何通过 LoRa 无线电来发送和接收数据。

LoRa 服务器

CR02Server_9ddb90a28c83e8b7c44c435c711fda650038b46c.jpg

我们从“服务器”草图示例开始。首先,这包括无线模块使用的 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 客户端

CR02Client_2eb95c9cef63f0eef1740afda4520cb7b3b2e950.jpg

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 的测试,可能需要进行一些修改。

下期预告

在本系列的下一篇文章中,我们会讨论将外围设备加入到机组中,并且无线监控系统将逐一完善。

— Andrew Back

Open source (hardware and software!) advocate, Treasurer and Director of the Free and Open Source Silicon Foundation, organiser of Wuthering Bytes technology festival and founder of the Open Source Hardware User Group.