1. 前言
随着当今社会的发展,对温度的测量、控制的精准度的需求变得越来越高。温度是企业生产过程、科学实验、日常的生活中都很常见也很重要的物理参数。
铂电阻测温仪是工业应用中最方便的温度测控仪表。由于其在精密测温方面的准确性,已被用作国际温标的定义。随着科学技术的不断发展和生产技术的不断提高,对温度计的要求越来越高。目前铂电阻温度计精度高、稳定性好。本文采用 STM32 单片机、配合 NBIOT 模块和铂电阻温度传感器 PT100 开发设计了企业云端气体检测温度监测系统。铂电阻传感器是利用电阻率随温度变化的特性(电阻温度效应)制成的一种热电阻传感器。温度测量范围约为-200-850 摄氏度。测温范围广,广泛用于温度基准和标准测量。采集的温度通过液晶显示屏显示温度数据,数据显示精度达到±0.1°。
当前文章接下来就详细介绍基于物联网的铂电阻温度监测系统的设计方案和软硬件实现方案。
当前设计的这个测温仪,主要是用来测量高温气体温度,也可以用来测量水温、固态发热体的温度,一般用在、电子电路印刷焊接流水线上、热水工厂、锅炉类企业、烟囱上等地方。 设备本身采用 BC20 模块连接华为云物联网服务器,将测量的温度上传云端服务器保存,根据时间段对温度曲线进行分析,了解温度变化规律,实现超高温、低温预警等操作。
测温仪和 STM32 开发板的实物图如下:
测量的温度,绘制曲线效果:
2. 硬件选型
目前的硬件为了快速搭建出上面设计预想的环境,都采用模块方式搭建开发,采用了一块 STM32 开发板,一块 LCD 显示屏,一个 BC20-NBIOT 模块,一个铂电阻测温模块。
2.1 铂电阻测温模块
铂电阻,简称铂热敏电阻,其阻值会随着温度的变化而变化。有 PT100 和 PT1000 系列产品,适用于医疗、电机、工业、测温、卫星、气象、电阻计算等高精度温度设备。 Pt 后的 100 表示 0℃时其电阻值为 100 欧,100℃时其电阻值约为 138.5 欧。其工作原理:当 PT100 在 0℃时,其电阻为 100 欧姆。它的电阻会随着温度的升高而上升,并且它的电阻会匀速增加。热电阻是一种常用于中低温的温度传感器。它的工作原理是基于电阻的热效应,即电阻的阻值随温度的变化而变化。铂金热敏电阻的热阻精度最高,具有抗振动、稳定性好、耐高压等特点。因此,它被制成各种标准温度计进行测量和校准。本文选用的铂热敏电阻为 PT100,0℃时的阻值为 100Ω。在 0℃~100℃之间变化时,最大非线性偏差小于 0.5℃。与热电偶不同,PT100 是无源传感器,因此需要设计额外的激励来产生电信号输出。
当前设计选用 PT100 铂电阻和 max31865 温度传感器模块读取温度数据。
Max31865 是一款简单易用的热敏电阻到数字输出转换器,针对铂电阻温度传感器 (RTD) 进行了优化。用于外部电阻设置的 RTD 的灵敏度。高精度 ADC 将 RTD 电阻与参考电阻的比率转换为数字输出。 Max31865 输入具有高达 ± 45V 的过压保护,并提供可配置的 RTD 和电缆开路/短路状况检测。采集的温度值送单片机处理并通过 LCD 显示;系统供电电路采用宽电压直流输入,由集成三端稳压芯片 lm7805 稳压,为单片机和显示模块供电;设计简单,既可以验证设计功能,又可以降低设计成本。
2.2 STM32 开发板
2.3 BC20 模块
3. 华为云-物联网服务器端
当前这个设备设计是用来测量工厂内烟囱的气体温度,工厂内有多个烟囱,为了方便统一了解温度情况,这些烟囱上的设备都会将温度信息实时上传到云端,云端进行统一处理,最后在办公室通过数据大屏显示出来,绘制温度变化曲线。目前还没有去对接华为云的数值化大屏,我这里采用自己开发的上位机显示温度的曲线,主要是目前设备也只有一台,自己开发一个上位机通过应用侧的接口读取服务器上的数据,本地再绘制温度显示界面即可。
接下来就介绍如何使用华为云物联网平台创建产品、设备、配置模型文件等步骤。
3.1 创建产品
华为云官网地址: https://activity.huaweicloud.com
打开官网后,就点击又上脚登录,没有账号就先注册。再点击产品,找到物联网产品。
点击免费试用。
点击产品页面,点击右上角创建产品。
填充设备信息。
接下来在产品页面定义模型,设置设备上传的数据属性。
添加属性。
添加成功。
3.2 创建设备
点击左边设备选型,再点击右上角创建设备。
填充设备的参数。
创建成功后保持设备属性信息。
{
"device_id": "62a0c1f9906b9e29ac74dd0d_tmp_dev1",
"secret": "12345678"
}
复制代码
设备创建成功。
3.3 订阅主题与发布主题
BC20 模块通过 MQTT 协议连接华为云物联网平台,要完成数据交互,需要知道华为云物联网平台的服务器 IP 地址,端口号,订阅的主题格式,发布主题的格式,登录的密匙三元组等信息。
【1】MQTT 服务器域名端口号信息官网介绍文档:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-portal/instance/detail?id=8fe87243-d97d-4c1e-bb34-186a60ca2d14&type=public
华为云物联网平台的域名是: 161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com
华为云物联网平台的IP地址是:121.36.42.100
端口号是1883
复制代码
【2】订阅的主题格式与发布主题格式官网介绍文档: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112
根据当前设备的信息总结,得到的格式信息如下:
//订阅主题: 平台下发消息给设备
$oc/devices/62a0c1f9906b9e29ac74dd0d_tmp_dev1/sys/messages/down
//设备上报数据
$oc/devices/62a0c1f9906b9e29ac74dd0d_tmp_dev1/sys/properties/report
//上报的属性消息 (一次可以上报多个属性,在json里增加就行了)
{"services": [{"service_id": "tmp","properties":{"tmp":180.56}}]}
复制代码
【3】MQTT 协议登录的三元组信息华为云提供了 MQTT 协议参数的生成工具,非常方便,根据提示填入参数一键生成三元组。
MQTT 设备登陆密匙生成地址: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/
得到 MQTT 三元组信息如下:
ClientId 62a0c1f9906b9e29ac74dd0d_tmp_dev1_0_0_2022060815
Username 62a0c1f9906b9e29ac74dd0d_tmp_dev1
Password 7c0934c36219afb4f776fc21d6a13cea9c7152add8dc79957255fa17a7c48bba
复制代码
这 3 个信息可以直接当做 MQTT 协议登录的参数填充,连接服务器。
3.4 模拟设备登录
在开发硬件设备端程序前,先使用 MQTT 客户端模拟测试,测试是否能正常的上传数据到服务器。
使用的软件名称为: MQTT客户端_v2.5(协议3.1.1).exe
。
根据软件提示,填入对应的参数登录即可。
接着打开华为云的网页端,即可看到设备已经在线,并且收到了上传的数据。
4. 硬件设备端软件开发
MQTT 协议连接华为云 IOT 源码工程: https://download.csdn.net/download/xiaolong1126626497/81993720
4.1 硬件连线
硬件连接方式:
1. TFT 1.44 寸彩屏接线
GND 电源地
VCC 接5V或3.3v电源
SCL 接PC8(SCL)
SDA 接PC9(SDA)
RST 接PC10
DC 接PB7
CS 接PB8
BL 接PB11
2. 板载LED灯接线
LED1---PA8
LED2---PD2
3. 板载按键接线
K0---PA0
K1---PC5
K2---PA15
4. MAX31865测温模块
PA2(TX)--RXD 模块接收脚
PA3(RX)--TXD 模块发送脚
GND---GND 地
VCC---VCC 电源(5.0V)
5. BC20模块接线说明:
GND----GND
PB10----BC20_RXD
PB11----BC20_TXD
复制代码
4.2 整体程序设计
测温采用 PT100 热电阻,配合 MAX31865 完成温度测量,编程软件采用 keil5,编程语言采用 C 语言,主控芯片采用 STM32F103RCT6。MAX31865 采集温度后通过串口协议输出。本身支持一套完整的 AT 指令集,支持温度查询、报警上限、下限的设置,默认的波特率是 9600。系统上电后先对 MAX31865 进行初始化,LCD 屏初始化,BC20-NBIOT 模块初始化、如果 MAX31865 检测失败就一直循环检测,并且在 LCD 屏上显示温度传感器初始化状态,当传感器初始化成功之后,就进入到下面的主程序,在主循环里每 500ms 的频率读取一次温度,然后实时显示在 LCD 屏,并通过 BC20 上传到物联网服务器。当 MAX31865 检测到的温度高于阀值或者低于阀值,MAX31865 控制板上会通过 LED 灯进行显示。程序里新建了 MAX31865.c 和 MAX31865.h 头文件,里面封装了 MAX31865 初始化检测、指令判断、温度读取等函数接口。
//温度传感器硬件检测代码
while(1)
{
key=MAX31865_Init();
if(key==0)break;
delay_ms(1000);
printf("MAX31865检测失败.\r\n");
}
printf("MAX31865检测成功.\r\n");
/*
函数功能: MAX31865命令发送函数
函数返回值:0表示成功 1表示失败
*/
u8 MAX31865_SendCmd(char *cmd)
{
u8 i,j;
for(i=0;i<10;i++) //检测的次数--发送指令的次数
{
USARTx_StringSend(USART2,cmd);
for(j=0;j<100;j++) //等待的时间
{
delay_ms(50);
if(USART2_RX_FLAG)
{
USART2_RX_BUFFER[USART2_RX_CNT]='\0';
USART2_RX_FLAG=0;
USART2_RX_CNT=0;
if(strstr((char*)USART2_RX_BUFFER,"OK"))
{
return 0;
}
}
}
}
return 1;
}
复制代码
4.3 铂电阻测温代码
整个系统的调试信息通过 LCD 屏和串口两种方式显示。拿到 MAX31865 模块后,先使用串口调试助手进行调试。PT100 采用 3 线制接线,与 MAX31865 机芯连接,正常 MAX31865 上电之后发送 AT\r\n,MAX31865 会返回 OK,通过返回的 OK 来检测 MAX31865 是否正常。然后在发送测温指令 AT+T,MAX31865 收到之后会返回+T=23.4 这样的数据,后面的 23.4 就是当前铂电阻测量的温度信息。如果要设置报警的上限和下限,可以通过 AT+TERRUP+26\r\n,后面的 26 就是设置的温度上限阀值(高报警门限)。AT+TERRDOWN+-24\r\n,后面的-25 就是设置的温度下限报警阀值。 MAX31865 模块采用 5V 供电,提供了串口输出接口,可以接 PT100、PT1000 等热电偶测温线。 在 max31865 函数的设计了核心的几个函数, 初始化、读温度、检测硬件等。
测量的温度显示:
#include "MAX31865.h"
/*
函数功能: MAX31865命令发送函数
函数返回值:0表示成功 1表示失败
*/
u8 MAX31865_SendCmd(char *cmd)
{
u8 i,j;
for(i=0;i<10;i++) //检测的次数--发送指令的次数
{
USARTx_StringSend(USART2,cmd);
for(j=0;j<100;j++) //等待的时间
{
delay_ms(50);
if(USART2_RX_FLAG)
{
USART2_RX_BUFFER[USART2_RX_CNT]='\0';
USART2_RX_FLAG=0;
USART2_RX_CNT=0;
if(strstr((char*)USART2_RX_BUFFER,"OK"))
{
return 0;
}
}
}
}
return 1;
}
/*
函数功能: MAX31865硬件初始化检测函数
函数返回值:0表示成功 1表示失败
*/
u8 MAX31865_Init(void)
{
return MAX31865_SendCmd("AT\r\n");
}
//测量的温度
char MAX31865_Temp[10];
//获取一次温度
char *MAX31865_GetTemp(void)
{
int i=0;
char *p;
int cnt = 0;
strcpy(MAX31865_Temp,"\0");
/*获取温度*/
if(MAX31865_SendCmd("AT+T\r\n"))
{
return MAX31865_Temp; //失败
}
//提取温度 +T=24.62\r\nOK
p=strstr((char*)USART2_RX_BUFFER,"+T=");
if(p)
{
p += 3;
for ( i = 0; i < 10; i++)
{
if (*p == '\r')break;
else if (*p == '\n')break;
else if (*p == '\0')break;
else
{
MAX31865_Temp[cnt++] = *p;
}
p++;
}
MAX31865_Temp[cnt++] = '\0';
}
return MAX31865_Temp;
}
复制代码
4.4 BC20 代码
【1】BC20 拿到后先进行调试,测试模块是否 OK,直接通过 USB 转 TTLC 连接电脑串口调试助手。
查询模块是否正常
AT
OK
获取卡号,查询卡是否插好
AT+CIMI
460041052911195
OK
激活网络
AT+CGATT=1
OK
获取网络激活状态
AT+CGATT?
+CGATT: 1
OK
查询网络质量
AT+CSQ
+CSQ: 26,0
OK
AT+CEREG=? //检查网络状态
+CEREG: 0,1 //找网成功
OK
激活GPS,要等一段时间
AT+QGNSSC=1
OK
查询激活状态,1表示成功激活
AT+QGNSSC?
+QGNSSC: 1
OK
获取一次GPS定位语句
AT+QGNSSRD="NMEA/RMC"
+QGNSSRD: $GNRMC,120715.00,A,3150.78179,N,11711.93433,E,0.000,,310818,,,A,V*19
OK
复制代码
【2】初始化没有问题之后,接下来通过 AT 指令连接物联网服务器,测试网络。
连接MQTT服务器
AT+QMTOPEN=0,"a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com",1883
OK
+QMTOPEN: 0,0
登录MQTT服务器
命令格式: AT+QMTCONN=<tcpconnectID>,<clientID>,<username>,<password>
AT+QMTCONN=0,"6210e8acde9933029be8facf_dev1_0_0_2022021913","6210e8acde9933029be8facf_dev1","6cea55404b463e666cd7a6060daba745bbaa17fe7078dfef45f8151cdf19673d"
OK
+QMTCONN: 0,0,0
订阅主题
命令格式: AT+QMTSUB=<tcpconnectID>,<msgID>,"<topic1>”,<qos1>[,"<topic2>”,<qos2>…]
AT+QMTSUB=0,1,"$oc/devices/62a0c1f9906b9e29ac74dd0d_tmp_dev1/sys/messages/down",2
OK
+QMTSUB: 0,1,0,2
发布主题
命令格式:AT+QMTPUB=<tcpconnectID>,<msgID>,<qos>,<retain>,"<topic>","<msg>"
先发送指令:
AT+QMTPUB=0,0,0,0,"$oc/devices/62a0c1f9906b9e29ac74dd0d_tmp_dev1/sys/properties/repor"
等待返回 ">"
接着发送数据.不需要加回车。
"{"services": [{"service_id": "tmp","properties":{"tmp":180.56}}]}"
数据发送完毕,再发送结束符。 十六进制的值--0x1a 。某些串口调试助手可以适应ctrl+z 快捷键输入0xA
等待模块返回"OK",到此数据发送完成。
OK
+QMTPUB: 0,0,0
复制代码
只要指令的流程明白了,接着就将指令封装成函数,使用 STM32 串口发送即可。
5.上位机开发
上位机采用 QT 软件开发,通过华为云应用侧提供的接口获取服务器的温度数据,进行处理,显示。
5.1 安装 QT 开发环境
目前我使用的开发环境是:QT 5.12.6 ,其他版本也可以的。
QT5.12.6 的下载地址:
https://download.qt.io/archive/qt/5.12/5.12.6/
复制代码
打开下载链接后选择下面的版本进行下载:
qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details
复制代码
软件安装时断网安装,否则会提示输入账户。安装的时候,第一个复选框里勾选一个 mingw 32 编译器即可,其他的不管默认就行,直接点击下一步继续安装。
如果只是在 windows 下开发,最简单的安装就只选择 MinGW 编译器即可,其他的编译器不用勾选。
5.2 应用侧开发(查询设备属性)
目前获取服务器的数据,可以采用查询属性接口和查询影子设备属性接口。查询设备属性是同步接口,需要设备实时响应上传数据,影子设备是保存设备最后一次上传到服务器的数据。我这里采用查询影子设备的属性,读取最后一次上传的温度即可。
官方地址:https://support.huaweicloud.com/api-iothub/iot_06_v5_0079.html
5.3 实现代码
代码就只是贴出了两个主要的函数,获取 token 和查询设备属性的代码,界面显示代码,数据解析代码这些就不贴出了,这些只是附带的效果代码。
/*
功能: 获取token
*/
void Widget::GetToken()
{
//表示获取token
function_select=3;
QString requestUrl;
QNetworkRequest request;
//设置请求地址
QUrl url;
//获取token请求地址
requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens")
.arg(SERVER_ID);
//自己创建的TCP服务器,测试用
//requestUrl="http://10.0.0.6:8080";
//设置数据提交格式
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));
//构造请求
url.setUrl(requestUrl);
request.setUrl(url);
QString text =QString("{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":"
"{\"user\":{\"domain\": {"
"\"name\":\"%1\"},\"name\": \"%2\",\"password\": \"%3\"}}},"
"\"scope\":{\"project\":{\"name\":\"%4\"}}}}")
.arg(MAIN_USER)
.arg(IAM_USER)
.arg(IAM_PASSWORD)
.arg(SERVER_ID);
//发送请求
manager->post(request, text.toUtf8());
}
//获取影子设备数据
void Widget::on_pushButton_addr_clicked()
{
//表示影子设备数据获取
function_select=0;
QString requestUrl;
QNetworkRequest request;
//设置请求地址
QUrl url;
//获取token请求地址
requestUrl = QString("https://iotda.%1.myhuaweicloud.com/v5/iot/%2/devices/%3/shadow")
.arg(SERVER_ID)
.arg(PROJECT_ID)
.arg(Device_id);
//自己创建的TCP服务器,测试用
//requestUrl="http://10.0.0.6:8080";
//设置数据提交格式
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
//设置token
request.setRawHeader("X-Auth-Token",Token);
//构造请求
url.setUrl(requestUrl);
request.setUrl(url);
//发送请求
manager->get(request);
}
复制代码
最终上位机实现的效果:
评论