nodejs串口通信、SerialPort

记录:使用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};

 

你可能感兴趣的:(学习,开发摘录)