这是我们大三第一学期的课程设计题目:基于无线传输的多点温度采集系统
摘要
文中设计了一种基于无线传输的多点温度采集系统,通过温度传感器采集温度信号,使用无线传感器通讯,结合单片机来处理并通过上位机进行显示,实现了温度采集、多点测量和上位机实时检测的功能。该检测系统使用简单、方便,对于提高工业自动化水平和环境温度测量具有重大意义。
框架图

这次的课程设计分为三部分:硬件实现,软件实现,文案以及视频制作。我在这次课设中负责的是软件设计。
-
硬件部分介绍
1.控制器模块设计
单片机控制器主要用于温度数据的采集、传输以及接收,将接收到的数据通过上位机软件在上位机上显示。对于控制器的选择采用STC8 9C52,该单片机算术运算功能强,软件编程灵活、自由度大,可用软件编程实现各种算法和逻辑控制。相对于FPGA来说,它的芯片引脚少,在硬件很容易实现。并且它还具有功耗低、体积小、技术成熟和成本低等优点。
2.温度采集模块设计
本次设计采用的是Dallas公司生产的单总线数字温度传感器DS18B20,其温度测量范围为-55~+125℃。每个从机设有一个温度传感器,环境温度通过温度传感器DS18B20采集到从机单片机中进行处理。从机单独供电,这样设计稳定性好,抗干扰能力强。
3.无线收发模块设计
NRF24L01是一款新型单片射频收发器件,工作于2.4~2.5 GHz ISM频段。内置频率合成器、功率放大器、晶体振荡器、调制器等功能模块,并融合了增强型ShockBurst技术,其中输出功率和通信频道可通过程序进行配置。本设计系统把从温度传感器采集得到的数据经过无线模块NRF24L01传输到主机中。无线传输可以工作在一些高危领域,避免了有限传输的局限性,本设计能进行连续的数据传输,无线模块NRF24L01的传输精度高,性能稳定,成本低。
4.显示模块设计
本设计方案采用128x64LCD液晶显示器和上位机共同显示,液晶显示器功率低,驱动方法和硬件连接电路较为简单,显示屏幕大、可对汉字和字符进行显示。
5.串口通信电路设计
系统要把测量到的温度送到上位机上显示出来,就需要通过电脑与单片机之间的串口通信,单片机的工作电压是5 V,电脑串口的工作电压是12 V,需要通过电平转换芯片进行正常通信。
-
文案以及视频部分介绍 课程设计完毕之后,需要撰写报告,以及制做相应的视频。
-
软件部分介绍
当上位机收到数据后,需要和电脑进行串口通信,将上位机收到的数据通过串口传给电脑,然后使用编程语言处理数据,最后须将数据以折线图的形式展示出来。
我这里使用node.js的serialport模块对串口进行数据监听。
var SerialPort = require("serialport"); var serialPort = new SerialPort("COM3", { baudRate: 9600, //波特率 autoOpen:false }); serialPort.open(function(error){ if(error){ console.log("打开端口COM3错误:"+error); }else{ console.log("打开端口成功,正在监听数据中"); serialPort.on('data',function(data){ sendToClient(data) //将数据发往客户端,客户端进行数据在折线图上的实时显示。 insertDataToMysql(data);//将数据插到mysql数据库 }) } })使用websocket进行数据的实时通信,客户端收到数据后,使用echarts的setOption,使数据实时显示在图表上。 服务端
思路:先建立websocket连接,然后进行串口的监听,如果有数据,就利用ws.send(),将数据发往客户端。
const wss = new WebSocket.Server({ port: 7009 }); wss.on('connection', function connection(ws, req) { ws.on('message', function incoming(message) { if(flag) { serialPortopen(ws); //设置flag的原因是保证serialPortopen函数只被执行一次。 flag = false; } }); }); function serialPortopen(ws) { serialPort.open(function(error){ if(error){ console.log("打开端口COM3错误:"+error); }else{ console.log("打开端口成功,正在监听数据中"); serialPort.on('data',function(data){ let dataInfo = data.toString().trim(); name = dataInfo.charAt('0').trim(); let temSign = dataInfo.indexOf('T'); //T出现的下标 let cSign = dataInfo.indexOf('C'); //第一个C符号出现的下标 let lastColon = dataInfo.lastIndexOf(":");//最后一个冒号出现的下标 tem = dataInfo.substring(temSign+2,cSign+1).trim(); hum = dataInfo.substring(lastColon+1).trim(); console.log(name, tem, hum); sendToClient(ws) insertDataToMysql(name, tem, hum); }) } }) } var sendToClient = function(ws) { let d = new Date(); time = d.getFullYear() + "-" +(d.getMonth()+1) + "-" + d.getDate() + " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds(); let obj = { name: name, tem: tem, hum: hum, time:time } ws.send(JSON.stringify(obj)); }
客户端
```
connectionServer: function() {
var _this = this;
var ws = new WebSocket("ws://localhost:7009");
ws.onopen = function (e) {
ws.send("hello")
}
ws.onmessage = function(event) {
let data = JSON.parse(event.data);
let name = data.name;
_this[name+"temYList"].push(parseInt(data.tem));
_this[name+"humYList"].push(parseInt(data.hum));
_this[name+"timeList"].push(data.time);
_this.showChart(name); //将数据显示在图表上。
};
},
```
折线图的设计:使用echarts
这里我由于先入为主的思想,在这里踩了一天的坑,我一直认为数据实时显示,只需要给原来的数据追加一条数据就可以了。但其实不是,当数据发生变化时,必须重新setOption()。