记录:使用nodejs和SerialPort进行串口通信
不是项目必须,只是为了方便开发写的,写的不好处凑合看吧
先安装上SerialPort:
npm i serialport -S然后引入后就可以写代码了,功能有:
1、接收到串口命令后自动发送回复命令
2、网页上收到发送的命令回复命令
我是用的express,重要的代码都在这里,有注释:
const express = require('express');
const router = express.Router();
const { commandProcessing, autoSendCommand } = require('./command');
const SerialPort = require('serialport');
const serialPort = new SerialPort('COM4', {
//波特率,可在设备管理器中对应端口的属性中查看
baudRate: 115200,
dataBits: 8,
autoOpen: false,
});
//连接串口后进行写入指令操作
serialPort.open((err) => {
console.log('IsOpen:', serialPort.isOpen);
if (err) {
console.log("打开端口COM4错误:" + err);
}
});
//#region :指令监听
/**
* 指令监听
* @see count :接收到数据的次数
* @see sendTime :接收到数据的时间
* @see reciveData :接收到数据的核验字符(大写),一组数据的开头是'5AA5'并且结尾是'7E'
* @see reciveArr :接收到数据的总结,存储在数组中
* @param data :SerialPort的函数自带返回数据
* */
let count = 0;
let sendTime = Date.now();
let reciveData = '';
let reciveArr = [];
serialPort.on('data', (data) => {
//接收到数据并拼接
reciveData = reciveData + data.toString('hex').toUpperCase();
let theData = '';
//如果拼接后的数据startsWith('5AA5')并且endsWith('7E')并且长度>=18就存储这个数据
//并且下发对应commandProcessing处理过的命令,最后重置reciveData为''。
if (reciveData.startsWith('5AA5') && reciveData.endsWith('7E') && reciveData.length >= 18) {
theData = commandProcessing(reciveData);//处理一下接收的数据返回需要下发的命令string
if (theData != '') {
//发送APP发过来的命令处理后的命令
sendCommand(theData);
//自动延时完成过程命令
let autoData = autoSendCommand(theData);
delaySend(autoData);
}
reciveArr.push(reciveData);
count++;
let elapsed = Date.now() - sendTime;
console.log(`时间:${elapsed}ms,第${count}次数据接收:${reciveArr[reciveArr.length - 1]}`);
reciveData = '';
}
});
//#endregion
//错误监听
serialPort.on('error', (error) => {
console.log('error: ' + error)
});
/**
* 接收到网页传递过来的命令,下发过去
* */
router.route('/send1').post((req, res) => {
let theBuffer = new Buffer(req.body.command, "hex");
serialPort.write(theBuffer, function (error) {
//指令下发
if (error) {
console.log("发送错误" + error)
} else {
console.log("需要下发的命令:" + req.body.command);
res.json({
result: 1
});
}
})
});
/**
*@param bufferStr :需要传递的命令,字符串格式
* */
let sendCommand = (bufferStr) => {
let theBuffer = new Buffer(bufferStr, "hex");
serialPort.write(theBuffer, function (error) {
//指令下发
if (error) {
console.log("发送错误" + error)
} else {
console.log("自动下发的命令:" + bufferStr);
}
})
};
/**
* @param autoData | String :延时发送的命令
* */
let delaySend = (autoData) => {
if (autoData != '') {
setTimeout(() => {
console.log("延时下发的命令:" + autoData);
sendCommand(autoData);
}, 3000);
//如果是预冲量达到就发送预冲结束,进入准备中
if (autoData == '5AA503700E1300917E') {
setTimeout(() => {
console.log("延时下发的命令:" + autoSendCommand(autoData));
sendCommand(autoSendCommand(autoData));
}, 6000);
//接着发送准备完成
setTimeout(() => {
console.log("延时下发的命令:" + '5AA503700E21009F7E');
sendCommand('5AA503700E21009F7E');
}, 11000);
}
}
}
module.exports = router;
command.js的代码:
/**
* @param data :接收到的APP发送过来的命令,string类型
* @return result:返回的需要下发的命令,需要去除字符串中的全部空格,string类型
* */
const command = (data) => {
let result = '';
switch (data) {
case '5AA50350070100587E'://开始自检
result = '5AA503700E01007F7E';//自检中
break;
case '5AA50350071100687E'://开始预冲
result = '5AA503700E11008F7E';//预冲中
break;
default:
result = '';
break;
}
return result.replace(/\s/g, "");
}
/**
* 自动完成流程命令,处理的命令是commandProcessing函数处理后返回的命令
* @param data :判断当前字符串,自动发送命
* */
const autoSendCommand = (data) => {
let result = '';
switch (data) {
case '5AA503700E01007F7E'://如果是自检中,3s后发送自检完成命令
result = '5AA503700E0300817E';
break;
case '5AA503700E11008F7E'://如果是预冲中,3s后发送预冲量达到命令
result = '5AA503700E1300917E';
break;
case '5AA503700E1300917E'://如果是预冲量达到,发送预冲结束命令
result = '5AA503700E1200907E';
break;
default:
result = '';
break;
}
return result;
}
module.exports = {commandProcessing: command, autoSendCommand};
版权声明:本文为qq_36022290原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。