当前位置:AIGC资讯 > 数据采集 > 正文

温湿度节点数据采集

实验效果:

采用温湿度传感器模块和ZigBee模块组成一个数字量传感器采集节点,实现温湿度传感器的采集,并将采集数据通过自定义协议无线传输至汇聚节点。发送节点有数据发送时,LED1 亮100毫秒。

任务实施

打开上节课创建的工程。 编写程序

(1) 在 sensor.c 中增加头文件 

#include "hal_defs.h"
#include "hal_cc8051.h"
#include "hal_int.h"
#include "hal_mcu.h"
#include "hal_board.h"
#include "hal_led.h"
#include "hal_adc.h"
#include "hal_rf.h"
#include "basic_rf.h"
#include "hal_uart.h"
#include "TIMER.h"
#include "get_adc.h"
#include "sh10.h"
#include "UART_PRINT.h"
#include "util.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

( 2 ) 新增宏定义,定义点对点通讯地址设置、定义消息格式宏定义、各个数组的大小及

LED 灯闪烁宏。

/*点对点通讯地址设置*/
#define RF_CHANNEL 16 // 频道 11~26
#define PAN_ID 0xD0C2 //网络 id
#define MY_ADDR 0xC2BD //本机模块地址
#define SEND_ADDR 0xB4F3 //发送地址
/* 自定义消息格式 */
#define START_HEAD 0xCC//帧头
#define CMD_READ 0x01//读传感器数据
#define SENSOR_TEMP 0x01//温度
 #define SENSOR_RH 0x02//湿度
 #define SENSOR_FIRE 0x03//火焰
 /* LED n 闪烁 time 毫秒 宏 */
 #define FlashLed(n,time) do{\
 halLedSet(n);\
 halMcuWaitMs(time);\
 halLedClear(n);\
 }while(0)
 /*数组大小*/
 #define MAX_SEND_BUF_LEN 128 //无线数据最大发送长度
 #define MAX_RECV_BUF_LEN 128 //无线数据最大接收长度

( 3 ) 定义变量和数组。定义 basicRfCfg_t 变量、无线接收和发送缓存数组、定时器

超时标志的变量

static basicRfCfg_t basicRfConfig; 
static uint8 pTxData[MAX_SEND_BUF_LEN]; //定义无线发送缓冲区的大小
static uint8 pRxData[MAX_RECV_BUF_LEN]; //定义无线接收缓冲区的大小
uint8 APP_SEND_DATA_FLAG;

 (4) 新增计算校验和函数 CheckSum()

 /*****************************************************************************************
 *函数:uint8 CheckSum(uint8 *buf, uint8 len)
 *功能:计算校验和
 *输入:uint8 *buf-指向输入缓存区, uint8 len 输入数据字节个数
 *输出:无
 *返回:返回校验和
 *特殊说明:无
 *****************************************************************************************/
 uint8 CheckSum(uint8 *buf, uint8 len)
 {
 uint8 temp = 0;
 while(len--)
 {

 temp += *buf;
 buf++;
 }
 return (uint8)temp;
 }

( 5 ) 关键函数

① 定时器初 始化函数,主要通过设置 T4CTL 和 T4IE 寄存器完成初始化工作,定时器相

关的函数已经定义在 mylib 文件夹下的 TIMER.c 中。

 void Timer4_Init(void)
 {
 // Set prescaler divider value to 128 (32M/128 = 250KHZ)
 T4CTL |= 0xE0;
 T4CTL &= ~(0x10); // Stop timer
 T4CTL &= ~(0x08); // 禁止溢出中断
 T4CTL |= 0x04; //计数器清零
 T4IE = 0; // 禁止中断
 }
第4行设置定时器的分频值为128分频。 第5行暂停定时器。 第6行禁止计数器溢出中断。 第7行清除计数器。 第8行禁止定时器4中断。

在TIMER.c定义了变量SEND_DATA_FLAG和NUM,需要计时2秒,用于定时采集传感数据,Timer4经过上述函数初始化后,定时器一个节拍是(1/250000)S,8位定时器 的 溢 出 周 期 为 256 个 节 拍 , 每 进 一 次 定 时 器 中 断 就 经 历 :

256*(1/250000)=0.001024秒,这是进一次中断所需要的时间,进1953次中断大约是0.001024*1953≈2s。因此NUM在中断函数中由0累加到1953,则时间经过了

2秒,此时将SEND_DATA_FLAG置1,由此得出中断函数如下。

HAL_ISR_FUNCTION(T4_ISR, T4_VECTOR)
 {
 T4OVFIF = 0;
 T4IF = 0;
 NUM ++;
 if(NUM == 1953) //计时 2s
 {
 NUM = 0;
 SEND_DATA_FLAG = 1;

 Timer4_Off();
 }
 else
 {
 SEND_DATA_FLAG = 0;
 }
 }

② 在 sensor.c 中定义 BasicRF 初始化函数。

void ConfigRf_Init(void)
 {
 basicRfConfig.panId = PAN_ID; //zigbee 的 ID 号设置
 basicRfConfig.channel = RF_CHANNEL; //zigbee 的频道设置
 basicRfConfig.myAddr = MY_ADDR; //设置本机地址
 basicRfConfig.ackRequest = TRUE; //应答信号
 while(basicRfInit(&basicRfConfig) == FAILED); //检测 zigbee 的参数是否配置成功
 basicRfReceiveOn(); // 打开 RF
 }

(6) 主函数

Main 函数是程序运行的起始位置,运行传感数据采集应用程序前,需要先初始化各个功能模块,halBoardInit()初始化了LED灯、串口、开启总中断,ConfigRf_Init()初始化了无线收发器的初始参数,Timer4_Init()对定时器4进行初始化,完成定时器4的初始化后用Timer4_On()打开定时器4。

初始化完成后需要执行无限循环任务,这个任务就是每隔 2 秒采集传感数据并通过无线通信功能和串口发送出去, basicRfSendPacket()用来发送无线数据, uart_printf()用来往串口打印调试信息,uart_printf()的用法和 printf()一样。用 GetSendDataFlag() 查询APP_SEND_DATA_FLAG的值,每当APP_SEND_DATA_FLAG为1的时候,系统经历了2秒的时间。call_sht11()用来采集温湿度数据,变量sensor_val、sensor_tem分别存放相对湿度和温度。工程源码中使用宏定义“CC2530_DEBUG”来控制是否在串口上打印调试信息。

针对上述功能在sensor.c编写出如下main函数功能代码。

void main(void)
{
halBoardInit(); //模块相关资源的初始化
ConfigRf_Init(); //无线收发参数的配置初始化
Timer4_Init(); //定时器初始化
Timer4_On(); //打开定时器
while(1)
{ APP_SEND_DATA_FLAG = GetSendDataFlag();

if(APP_SEND_DATA_FLAG == 1) //定时时间到
 { /*【传感器采集、处理】 开始*/
 uint16 sensor_val,sensor_tem;
 call_sht11((unsigned int *)(&sensor_tem),(unsigned int *)(&sensor_val)); //取温湿度数据
 #ifdef CC2530_DEBUG
 //把采集数据传化成字符串,以便于在串口上显示观察
 uart_printf("温湿度传感器,温度:%d℃, 湿度:%d%%\r\n", sensor_tem, sensor_val);
 #endif /*CC2530_DEBUG*/
 memset(pTxData, '\0', MAX_SEND_BUF_LEN);
 pTxData[0]=START_HEAD;//帧头
 pTxData[1]=CMD_READ;//命令
 pTxData[2]=8;//长度
 pTxData[3]=2;//2 组传感数据
 pTxData[4]=SENSOR_TEMP;//传感类型
 pTxData[5]=sensor_tem;
 pTxData[6]=SENSOR_RH;//传感类型
 pTxData[7]=sensor_val;
 pTxData[8]=CheckSum((uint8 *)pTxData, pTxData[2]); //把数据通过 zigbee 发送出去
 basicRfSendPacket((unsigned short)SEND_ADDR, (unsigned char *)pTxData, pTxData[2]+1);
FlashLed(1,100);//无线发送指示,LED1 亮 100ms
Timer4_On(); //打开定时
} /*【传感器采集、处理】 结束*/
}
}

代码分析:

第11-12行,条件编译,通过call_sht11 ()函数用来读取温湿度数据。

第13行,条件编译,用来控制是否编译打印调试信息功能。

第18-26行,将采集的值获取通过自定义协议数据封装。

第28行,把采集数据通过basicRfSendPacket函数发送出去。

第30行,打开定时器。

3. 建立与配置模块设备

(1)建立模块设备

将sensor.c从workspace下的app组中移除,复制Project文件夹下的sensor.c

为副本,并将这个副本重命名为temprh_sensor.c,最后重新添加到workspace下的app 组中。

选择菜单“ProjectàEdit Configurations”,弹出项目的配置对话框,图5-11项目配置对话框所示,系统会检测出项目中存在的模块设备。

单击“New”按钮,在弹出的对话框中输入模块名称为:“temprh_sensor”,基于

Deubg模块进行配置,然后单击“OK”按钮完成模块设备的建立,对话框图5-12温湿度传

感器模块配置对话框所示。在项目配置对话框中就可以自动检测出刚才建立的模块设备

“temprh_sensor”。

 图 5-11 项目配置对话框

 图 5-12 温湿度传感器模块配置对话框

为了给模块设备设置对应的条件编译参数,在此需要进行如下设置:

在项目工作组中选择“temprh_sensor”模块,单击右键选择“Options”,在弹出的对话框中选择“C/C++ Compile”类别,在右边的窗口中选择“Preprocessor”选项中的

“Definedsymbols:”中输入 “CC2530_DEBUG”,具体设置如图5-13所示。

 图 5-13 温湿度传感器模块“Options”设置

4. 编译和下载程序

将插有温湿度传感器模块的 ZigBee 模块固定在 NEWLab 平台,在 Workspace 中选择 “temprh_sensor”模块,编译程序无误后,给NEWLab平台上电,下载程序到ZigBee模块中。

打开串口调试助手,设置波特率为115200后点击,可以看到采集到的温湿度数据显示出来了,如图5-14所示。

图 5-14 程序运行结果

验证通过后,需要把条件编译选项中的“CC2530_DEBUG”去掉,变成 “xCC2530_DEBUG”,如图 5-15 所示。

图 5-15 去掉 CC2530_DEBUG 条件编译选项

更新时间 2023-11-08