目录

  • 1 课程简介
    • 1.1 课程简介
    • 1.2 课程标准
    • 1.3 职业证书对接
    • 1.4 课程分工
  • 2 数据采集
    • 2.1 数据采集之数字量传感数据采集
    • 2.2 数据采集之模拟量传感数据采集
    • 2.3 数据采集之模拟量转换为数字量
    • 2.4 数据采集之开关量传感数据采集
  • 3 STM32微控制器基本外设应用开发
    • 3.1 STM32基础知识
    • 3.2 任务1 开发环境搭建和工程建立
    • 3.3 任务2 LED流水灯应用开发
    • 3.4 任务3 按键控制LED灯亮灭
    • 3.5 任务4 串行通信控制LED流水灯应用开发
    • 3.6 任务5 电池电量检测应用开发
  • 4 RS-485总线通信应用
    • 4.1 RS-485基本知识
    • 4.2 RS-485通信协议及网关通信协议
    • 4.3 Modbus通信协议
    • 4.4 任务1 案例分析及工程代码编写
    • 4.5 任务2 系统搭建及云平台项目创建
  • 5 CAN总线通信应用
    • 5.1 CAN总线基本知识
    • 5.2 CAN通信帧
    • 5.3 CAN控制器和收发器
    • 5.4 任务1 案例分析及工程代码编写
    • 5.5 任务2 系统搭建及云平台项目创建
    • 5.6 任务3 CAN通信数据抓包与解析
  • 6 BasicRF的无线通信应用
    • 6.1 BasicRF基础知识
    • 6.2 任务1创建工程项目
    • 6.3 任务2 温湿度节点数据采集
    • 6.4 任务3 火焰节点数据采集
    • 6.5 任务4 传感器节点组网
    • 6.6 任务5 传感数据汇聚
  • 7 WiFi数据通信
    • 7.1 WI-FI基础知识
    • 7.2 使用AT指令配置WI-FI工作模式
    • 7.3 WI-FI接入云平台
  • 8 NB-IoT联网通信
    • 8.1 NB-IoT技术简介
    • 8.2 利尔达NB-IoT模组介绍
    • 8.3 任务1 “智慧路灯”AT指令代码编写
    • 8.4 任务2.烧写智能路灯
    • 8.5 任务3NB-IoT接入云平台
  • 9 LoRa 通信技术
    • 9.1 基础知识
    • 9.2 项目分析与LoRa驱动移植
    • 9.3 任务2 LoRa温湿度传感器节点应用程序开发
    • 9.4 任务3 LoRa光照传感器节点数据采集
    • 9.5 任务4 LoRa网关节点汇聚传感器数据
    • 9.6 讨论
任务4 LoRa网关节点汇聚传感器数据
  • 1 知识介绍
  • 2 PPT
  • 3 教学视频
  • 4 名人名言

本节主要任务为智慧植物园区下的子系统,主要完成园区环境数据汇聚并在显示屏上进行数据显示,并将数据上传云平台。

任务4 LoRa网关节点汇聚传感器数据

作为网关汇聚节点,如图 8-21所示,它是不采集数据用的,主要数据来源为,温湿度节点及光照节点发过来的数据;这里我们需要将接收到的数据解析出来,把关键数据保留下来,在将数据进行组帧,需要满足网关串口通信协议。

网关节点图8-21网关节点图

对任务进行分析:需要完成如下任务:

  • 数据接收及处理。满足LoRa通信协议,汇聚节点才能正确接收,解析出所需数据;

  • 数据帧重组及上传。汇聚节点与网关的通信方式为RS485通信,需要符合网关串口通信协议,所以需要重新组帧;

  • led屏显示相应的信息。注意:显示中文信息,需要使用字模提取将中文转换成显示对于的值,否则不能显示中文汉字。

基础知识讲解

通讯协议:

LoRa 模块通讯协议 :分别为请求帧和响应帧。

  • 请求命令结构为 HEAD+CMD+NET_ID+LORA_ADDR+LEN+DATA+CHK,具体的构成如表 8-8所示:


8-8LoRa通信协议请求命令帧格式

HEAD

CMD

NET_ID_H

NET_ID_L

LORA_ADDR

LEN

DATA

CHK

0

1

2

3

4

5

6~(n-1)

n

1字节

1字节

1字节

1字节

1字节

1字节

n-6字节

1字节

0x55

命令编号

网络ID

高字节

网络ID

低字节

LoRa地址

数据域长度

数据域

SUM


  • 响应命令结构为 HEAD+CMD+NET_ID+LORA_ADDR+ACK+LEN+DATA+CHK具体的构成如表 8-9所示:


8-9LoRa通信协议响应命令帧格式

HEAD

CMD

NET_ID_H

NET_ID_L

LORA_ADDR

ACK

LEN

DATA

CHK

0

1

2

3

4

5

6

7~(n-1)

n

1字节

1字节

1字节

1字节

1字节

1字节

1字节

n-7字节

1字节

0x55

命令

编号

网络ID

高字节

网络ID

低字节

LoRa地址

响应

数据域

长度

数据域

SUM


RS-485网络上报物联网网关通讯协议,协议如表 8-10所示。

8-10RS-485网络上报物联网网关通讯协议

START

ADDR0

ADDR1

CMD

LEN

TYPE

DATA0

DATA1

CHK

起始位

地址位(2个字节)

0x02

数据长度

传感器类型

传感数据(2个字节)

校验位


协议各字段含义如下:

START:为起始位;

ADDR:为地址位;

CMD:命令类型,取固定值0x02;

LEN:数据长度,固定为09;

TYPE:传感器类型;

DATA:传感数据;

校验位:从START字节开始到CHK字节之前的累加和,该累加和与0xFF按位与运算(保留低8位),得到的接到的结果就是CHK的值了。

数据汇聚并在显示屏上进行数据显示,并将数据上传云平台具体实施过程如下:

步骤1 代码编写

本步骤应用程序在温湿度传感器节点应用程序的基础上修改即可完成应用程序编写,全部在main.c文件中进行修改。根据任务需求,把主要功能函数分为2部分:1、轮询传感器节点函数;2、 接收/解析/显示接收到的信息函数。

1、 轮询传感器节点LoRa_ReadSensorProcess()函数。该函数实现的功能是不定时向传感网络节点1和传感网络节点2发送读传感数据指令,在串口上显示“读取网络ID为xx地址,为x的传感节点”字样信息,并在OLED第1行和第2行显示ID和Addr的值。

代码分析:原先的代码中的 LoRa_GetSensorDataProcess()是用于定时采集传感器数据的进程函数,网关节点程序中不需要这个函数。在main.c中删除该函数及相关内容。重新定义进程函数“LoRa_ReadSensorProcess(uint8_t AddrMin, uint8_t AddrMax) ”(程序如下所示)用于轮询传感节点,该函数有两个参数:1)是轮询的起始地址,2)轮询的最后一个地址,将该函数添加到main函数中。接下来对该函数中的主要代码进行解析,为了减少同信道通信冲突概率,给定一个随机间隔时间去轮询两个传感节点的传感数据,这里用了一个randr()函数。然后,实现了在串口显示读取传感节点的网络ID和地址,定义了一个32个字符型数据的缓冲,将“ID:网络ID,Addr:设备地址”字符放在StrBuf缓冲中,再把StrBuf缓冲的数据在OLED上显示。接下来这两行代码是要清除显示屏上的第3、4行的内容。通过LoRa_SendRead函数(程序如下所示)将要发送读取传感器数据命令给传感节点1。最后轮询设备地址,加1,点亮发送数据指示灯,等待进入查询第2个传感节点网络的传感数据。完成函数的相关功能。找到main函数的代码位置,添加进轮询传感节点的函数,删除原先传感节点采集传感数据的进程函数。

void LoRa_ReadSensorProcess(uint8_t AddrMin, uint8_t AddrMax) 
{
 static uint16_t time = 1000;
 static uint8_t addr = 1;
 if(User0Timer_MS > time)
 {
   User0Timer_MS = 0;
   time = randr(1000, 4000);//给定一个随机间隔时间,减少通行道通信冲突概率
#ifndef TRANSPARENCY
   printf("读取网络ID为:0x%o4X,地址为%d的传感器节点\r\n", MY_NET_ID, addr);
#endif
   //显示屏提示轮询地址和网络号
   char StrBuf[32];
   memset(StrBuf, "\0", 32);
   sprintf(StrBuf, "ID:%04X, Addr:%d", MY_NET_ID, addr);
   OLED_ShowString(0, 2, (uint8_t *)StrBuf);
   //清除显示屏第3、4行的内容
   memset(StrBuf, " ", 32);
   OLED_ShowString(0, 4, (uint8_t *)StrBuf);
   LoRa_SendRead(MY_NET_ID, addr++);
   if(addr > AddrMax)
   {
     addr = AddrMin;
   }
   GpioToggle(&Led1);  //发送数据切换亮灯指示
 }
}
void LoRa_SendRead(uint16_t NetId, uint8_t addr)
{
 uint8_t TxBuffer[BUFFER_SIZE];
 TxBuffer[0] = START_HEAD;
 TxBuffer[1] = CMD_READ;
 TxBuffer[2] = (uint8_t)(NetId>>8);
 TxBuffer[3] = (uint8_t)NetId;
 TxBuffer[4] = addr;
 TxBuffer[5] = CheckSum((uint8_t *)TxBuffer, 5);
 Radio.Send(TxBuffer, 6);
}

2、接收/解析/显示接收到的信息函数。LoRa_DataParse()(程序如下所示),该函数的功能为:对网关收到传感节点响应数据后需要进行解析,并对数据进行有效数据提取和过滤,并校验。接收到正确的响应数据后,把数据域提取出来,将数据域数据显示在OLED显示屏的第3、4行上,并在串口上显示收到LoRa无线数据的字节数和数据。

void LoRa_DataParse(uint8_t *LoRaRxBuf,uint16_t len)
{
 uint8 t *DestData = NULL;
 #define HEAD_DATA  *DestData         //帧头
 #define CMD_DATA  *(DestData+1)     //命令
 #define NETH_DATA  *(DestData+2)     //网络ID高字节
 #define NETL_DATA  *(DestData+3)     //网络ID低字节
 #define ADDR_DATA  *(DestData+4)     //地址
 #define ACK_DATA  *(DestData+5)     //响应
 #define LEN_DATA  *(DestData+6)     //长度
 #define DATASTAR_DATA  *(DestData+7)     //数据域起始

 DestData = ExtractCmdframe((uint8_t *)LoRaRxBuf, len, START_HEAD);
 if(DestData != NULL)  //检索到数据帧头
   {
     if((DestData - LoRaRxBuf) > (len - 6)) return;  //数据长度不足构成完整数据帧
     if(DestData != CMD_READ) return; //命令错误
     if(CheckSum((uint8_t *)DestData, 6 + DestData[6]) != (*(DestData + 6 + (*(DestData + 6))))) return;   //校验不通过
     if(((((uint16_t)NETH_DATA) << 8) + NETH_DATA) != MY_NET_ID) return;  //网络ID不一致
     
     //传感数据显示到OLED屏山
     char OledBuf[32];
     memset(OledBuf, ' ', 32);
     memcpy(OledBuf+1, &DATASTAR_DATA, (LEN_DATA - 1) > 30?30:(LEN_DATA - 1));
     OLED_ShowString(0, 4, (uint8_t *)OledBuf);
#ifndef TRANSPARENCY
     //打印接收到的信息到调试助手
     char output[BUFFER_SIZE*5] = {0};
     memset(output, '\0', BUFFER_SIZE*5);
     GetHexStr((uint8_t *)LoRaRxBuf, len, (uint8_t *)output);
     printf("收到%d个字节的LoRa无线数据:%s\r\n", len, (const char *)output);
     //提取响应数据中的传感器数据
     uint8_t StrBuf[BUFFER_SIZE*5] = {0};
     memset(StrBuf, '\0', BUFFER_SIZE*5);
     memcpy(StrBuf, &DATASTAR_DATA, LEN_DATA-1);
     printf("网络ID=0x%04X,源地址=%d\r\n",((((uint16_t)NETH_DATA)<<8)+NETH_DATA), ADDR_DATA);
     printf("传感数据:%s\r\n", StrBuf);
#else
     USART1_SendStr((uint8_t *)DestData, 7+(*(DestData + 6)));  //透传
#endif  /*ENGINEER_DEBUG != false*/
   }
}

代码分析:对接收到数据帧内的数据进行宏定义,增强代码的可读性。然后实现对接收数据进行有效数据提取、过滤和校验,如对针头命令、数据长度、网络ID校验码等数据的校验。先定义一个32个长度的字符型数据,然后通过memset函数将32个字符初始化数据格式。最后把接收到的数据通过memcpy()函数存放到OledBuf缓冲区中。当数据长度超过30个,则只取30个数据,并在OLED液晶上的第3行和第4行显示。最后用“#define TRANSPARENCY”这个宏定义控制网关,将接收到的传感数据透传到串口上。当改为定义“#define xTRANSPARENCY”时,网关不透传感数据,但是打印调试信息到串口上,方便用户调试数据。

以上完成了光照传感器节点的应用程序的编写,就完成了编译工程,无错误后即可进行下一步。

步骤2 硬件连接和程序下载

硬件连接,首先下载网关节点程序,网关节点应用程序开发完成后,将程序下载到LoRa模块中,下载方法与温湿度传感器节点和光照传感器节点相同。然后连接NEWLab平台电源线,通讯旋钮开关旋转至通讯模式,连接 USB 转串口连接线,将LoRa温湿度传感器节点、LoRa光照传感器节点、LoRa网关节点全部放置NEWLab主机上,如图 8-22所示。本节的任务是在基于温湿度传感器节点的工程源码基础上进行,要求网关轮流读取温湿度传感器节点、光照传感器节点的传感器数据,将收到的传感器数据在OLED屏上显示,并透传到串口上。最后稍写程序,通电运行。

LoRa模块OLED屏显示数据及硬件环境8-22LoRa模块OLED屏显示数据及硬件环境

步骤3 数据上报

程序烧录完成后,打开串口调试助手,根据实际选择串口号,拨特率设置为:115200,点击打开串口,可以看到窗口助手窗口显示出传感器数据。注意:OLED 显示屏的驱动程序只支持 ASCII字符的显示,不支持中文和其他编码。温度数据的单位为:℃,由于OLED显示屏的驱动程序没有“℃”这个符号对应的字库,所以当网关收到温度数据并显示在OLED屏上时,会出现部分乱码的情况。

传感数据通过物联网网关上报到云平台。首先,在工程中需要将user_define.h中的宏定义“xTRANSPARENCY”改为TRANSPARENCY,才能实现数据透传,将程序修改后重新编译,并下载网关代码到LoRa模块上,然后将作为网关的LoRa模块放置在NEWLab主机上,把LoRa模块的RS485+和RS485-连接到路由网关的RS485的A2、B2接口。将前面下载好程序的LoRa温湿度传感节点、LoRa光照传感节点放至NEWLab主机上。路由网关的WAN口通过网线连接外网,LAN通过网线连接PC机,需确保 PC 机与网关处于同一个网段。因网关默认开启DHCP功能,建议PC机采用自动获取IP地址。

首先,新建项目,打开浏览器,输入网址:www.nlecloud.com。没有账号的用户需要先注册账户,登录云平台,点击开发者中心的开发设置,确认ApiKey未过期,点击开发者中心,然后点击新增项目按钮,即可新建一个项目,在弹出的添加项目对话框中填写:“项目名称”、“行业类别”及“联网方案”信息,设置“项目名称”为:园区环境监测,“行业类别”选择:工业物联,“联网方案”选择:以太网,最后点击“下一步”按钮。

其次,添加设备。填入设备名称:“园区环境监测”,勾选通讯协议:“TCP”,设备标识:“LoRa001”,确保设备标识符要唯一,最后点击“确定添加设备”。在设备管理界面记录下:设备ID、设备标识、传输密钥和后续配置,用于配置网关。

最后,配置物联网网关,接入云平台,打开浏览器,在地址栏输入:“192.168.14.200:8400”,进入网关配置,点击左侧的云平台接入,在配置界面中输入平台账号和密码,即登录云平台的账号和密码,输入设备ID、设备标识、传输密钥,选择通讯协议为TCP,点击“设置”按钮,完成网关的配置。等待网关系统自动重启,大约20秒时间。网关重启后,刷新网页可看到网关设备在线。点击当前设备,可看到其自动识别到了连接的传感器设备、温湿度传感器和光照传感器。点击下发设备,打开实时数据开关,可以看到传感器采集到的实时数据,并且网页数据每隔5秒刷新一次。点击历史数据,也可以查看传感器采集的历史数据信息。