热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

NodeJs串口通信

前言:最近这两天在研究如何实现web页面和串口间通信,在网上也查了各种资料,electron、nw或者chromeserial,发现对于我来说都太难实现了,一来可用的资料太少,二来

前言:最近这两天在研究如何实现web页面和串口间通信,在网上也查了各种资料,electron、nw或者chrome serial,发现对于我来说都太难实现了,一来可用的资料太少,二来安装东西老是出问题,算了还是放弃吧,自己用常用且最熟悉的方式来实现吧,作为一名前端码农,选用的肯定是node作为服务器了,然后网页请求方式用ajax或websocket都可以,实现方式下文都有。
先说说基本需求:硬件:usb插口的led蜂鸣器(就一个单片机),有红黄蓝三种灯,通过下发相应的指令,实现亮相应的登或者响起蜂鸣器

一. node下先跑通

1) 安装serialport

npm install serialport

2)新建server.js文件

var SerialPort = require('serialport')
//Opening a Port
var serialPort = new SerialPort('COM4', {
//波特率,可在设备管理器中对应端口的属性中查看
baudRate : 9600,
autoOpen:false
})
//连接串口后进行写入指令操作
serialPort.open(function (err) {
console.log('IsOpen:',serialPort.isOpen)
console.log('err:',err)
if(!err){
//16进制Buffer流
const buf1 = new Buffer("01050000ff008C3A","hex") //打开红灯
const buf11 = new Buffer("010500000000CDCA","hex") //关闭红灯
const buf2 = new Buffer("01050001f000D80A","hex") //打开黄灯
const buf21 = new Buffer("0105000100009C0A","hex") //关闭黄灯
const buf3 = new Buffer("01050002f000280A","hex") //打开绿灯
const buf31 = new Buffer("0105000200006C0A","hex") //关闭绿灯
const bufs = [buf1,buf2,buf3]
// const bufs = [buf11,buf21,buf31]
var i = 0
eachWrite(bufs[i])
function eachWrite(item) {
console.log(item)
serialPort.write(item, function (error, result) {
i++
if(i>=bufs.length)return
//指令是一条一条下发的
setTimeout(function () {
eachWrite(bufs[i])
},40)
})
}
}
})
//指令监听
serialPort.on('data',function (data) {
console.log('data received: '+data)
})
//错误监听
serialPort.on('error',function (error) {
console.log('error: '+error)
})
//获取端口列表
SerialPort.list(function (error, ports) {
ports.forEach(function(port) {
console.log(port.comName);
console.log(port.pnpId);
console.log(port.manufacturer);
});
})

3)执行代码

node server.js

4)运行代码 最终结果
《NodeJs串口通信》

二. websocket方式

1) 安装nodejs-websocket

npm install nodejs-websocket

2)新建文件websocket.js

var ws=require('nodejs-websocket');
var SerialPort = require('serialport')
var server = ws.createServer(function (conn, res) {
conn.on("text",function(str){
broadcast(server,str.split(','));
server.emit('my other event', { my: 'data' });
});
conn.on("close",function(code,reason){
console.log('connection closed');
})
//处理错误事件信息
conn.on('error',function(err){
console.log('throw err',err);
})
}).listen(5000);
/* **指令下发 * msg:string ; eg: '01050000ff008C3A,01050001f000D80A' * server:socket server * */
function broadcast(server, msg) {
var recData = [];
msg.map(function (item, index) {
//发送数据到客户端
server.connections.forEach(function (conn) {
conn.sendText(item);
})
//16进制Buffer流
const str = new Buffer(item,"hex")
recData.push(str)
})
var i = 0
eachWrite(recData[i])
function eachWrite(item) {
serialPort.write(item, function (error, result) {
i++
if(i>=recData.length)return
//指令是一条一条下发的
setTimeout(function () {
eachWrite(recData[i])
},40)
})
}
}
//Opening a Port
var serialPort = new SerialPort('COM4', {
baudRate : 9600,
autoOpen:false
})
//连接串口
serialPort.open(function (err) {
console.log('IsOpen:',serialPort.isOpen)
})
//指令监听
serialPort.on('data',function (data) {
console.log('data received: '+data)
})
//错误监听
serialPort.on('error',function (error) {
console.log('error: '+error)
})
//获取端口列表
SerialPort.list(function (error, ports) {
ports.forEach(function(port) {
console.log(port.comName);
console.log(port.pnpId);
console.log(port.manufacturer);
});
})

3)新建html文件,index.html


<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style> form{ margin: 30px auto; width: 35%; } style>
head>
<body>
<br>
<form class="form">
<fieldset>
<legend>wobsocket 控制legend>
<br>
<br>
<div>
<input type="button" onclick="clickDend('01050000ff008C3A,01050001f000D80A')" value="红黄灯">
<input type="button" onclick="clickDend('01050001f000D80A')" value="黄灯">
<input type="button" onclick="clickDend('01050002f000280A')" value="绿灯">
<input type="button" onclick="clickDend('01050003f300793A')" value="蜂鸣器">
<input type="button" onclick="clickDend('0105000300003DCA')" value="关闭蜂鸣器">
<input type="button" onclick="clickDend('010500000000CDCA,0105000100009C0A,0105000200006C0A,0105000300003DCA')" value="关闭所有">
div>
<br>
<ul id="content">ul>
<input type="text" placeholder="请输入发送的消息" class="message" id="message"/>
<input type="button" value="发送" id="send" class="connect"/>
<input type="button" value="连接" id="connect" class="connect"/>
fieldset>
form>
<script> var oUl=document.getElementById('content'); var oCOnnect=document.getElementById('connect'); var oSend=document.getElementById('send'); var oInput=document.getElementById('message'); var ws=null; oConnect.Onclick=function(){ ws=new WebSocket('ws://localhost:5000'); ws.Onopen=function(){ oUl.innerHTML+="

  • 客户端已连接
  • "; } ws.Onmessage=function(evt){ oUl.innerHTML+="
  • "+evt.data+"
  • "
    ; } ws.Onclose=function(){ oUl.innerHTML+="
  • 客户端已断开连接
  • "
    ; }; ws.Onerror=function(evt){ oUl.innerHTML+="
  • "+evt.data+"
  • "
    ; }; }; oSend.Onclick=function(){ if(ws){ ws.send(oInput.value); } } function clickDend(val){ console.log(val) if(ws){ // ws.send('010500000000CDCA,0105000100009C0A,0105000200006C0A,0105000300003DCA'); ws.send(val); } } script>
    body>
    html>

    4)启动服务,执行代码

    node server.js

    5)运行页面
    《NodeJs串口通信》

    三. http方式

    1) 安装express,cors

    npm install express cors

    2)新建http.js文件

    var express = require('express')
    var cors = require('cors') //解决跨域
    var app = express();
    var port = process.env.PORT || 1124;
    var SerialPort = require('serialport')
    var serveStatic = require('serve-static');
    var bodyParser = require('body-parser');
    app.use(bodyParser.urlencoded({extended: true}));
    app.use(bodyParser.json({limit: '1mb'}));
    app.use('/static',serveStatic('public'));
    app.listen(port)
    app.use(cors())
    app.post('/ledControl/on.do',function (req,res) {
    const str = req.body.data
    if(setContrl(str.split(','))){
    res.send({
    code:100,
    data:'开启成功!',
    message:'信息'
    })
    return
    }
    res.send({
    code:101,
    data:'开启失败!',
    message:'信息'
    })
    })
    /* **指令下发 * msg:string ; eg: '01050000ff008C3A,01050001f000D80A' * */
    function setContrl(msg){
    return new Promise(function (resolve,reject) {
    let recData=[];
    msg.map(function (item, index) {
    //16进制Buffer流
    const str = new Buffer(item,"hex")
    recData.push(str)
    })
    var i = 0
    eachWrite(recData[i])
    function eachWrite(item) {
    serialPort.write(item, function (error, result) {
    i++
    if(i>=recData.length){
    resolve(true)
    return
    }
    //指令是一条一条下发的
    setTimeout(function () {
    eachWrite(recData[i])
    },40)
    })
    }
    //错误监听
    serialPort.on('error',function (error) {
    console.log('error: '+error)
    resolve(false)
    })
    })
    }
    //Opening a Port
    var serialPort = new SerialPort('COM4', {
    baudRate : 9600,
    autoOpen:false
    })
    //连接串口
    serialPort.open(function (err) {
    console.log('IsOpen:',serialPort.isOpen)
    })
    //指令监听
    serialPort.on('data',function (data) {
    console.log('data received: '+data)
    })
    //获取端口列表
    SerialPort.list(function (error, ports) {
    ports.forEach(function(port) {
    console.log(port.comName);
    console.log(port.pnpId);
    console.log(port.manufacturer);
    });
    })

    3)补充上面index.html文件


    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <style> form{ margin: 30px auto; width: 35%; } style>
    head>
    <body>
    <form action="">
    <fieldset>
    <legend>http控制legend>
    <br>
    <br>
    <div id="httpCtrol">
    <input type="button" sy-val = '01050001f000D80A' value="黄灯">
    <input type="button" sy-val = '01050002f000280A' value="绿灯">
    <input type="button" sy-val = '010500000000CDCA,0105000100009C0A,0105000200006C0A,0105000300003DCA' value="关闭所有">
    div>
    fieldset>
    form>
    <br>
    <form class="form">
    <fieldset>
    <legend>wobsocket 控制legend>
    <br>
    <br>
    <div>
    <input type="button" onclick="clickDend('01050000ff008C3A,01050001f000D80A')" value="红黄灯">
    <input type="button" onclick="clickDend('01050001f000D80A')" value="黄灯">
    <input type="button" onclick="clickDend('01050002f000280A')" value="绿灯">
    <input type="button" onclick="clickDend('01050003f300793A')" value="蜂鸣器">
    <input type="button" onclick="clickDend('0105000300003DCA')" value="关闭蜂鸣器">
    <input type="button" onclick="clickDend('010500000000CDCA,0105000100009C0A,0105000200006C0A,0105000300003DCA')" value="关闭所有">
    div>
    <br>
    <ul id="content">ul>
    <input type="text" placeholder="请输入发送的消息" class="message" id="message"/>
    <input type="button" value="发送" id="send" class="connect"/>
    <input type="button" value="连接" id="connect" class="connect"/>
    fieldset>
    form>
    <script src="jquery.min.js">script>
    <script> var oUl=document.getElementById('content'); var oCOnnect=document.getElementById('connect'); var oSend=document.getElementById('send'); var oInput=document.getElementById('message'); var ws=null; oConnect.Onclick=function(){ ws=new WebSocket('ws://localhost:5000'); ws.Onopen=function(){ oUl.innerHTML+="

  • 客户端已连接
  • "; } ws.Onmessage=function(evt){ oUl.innerHTML+="
  • "+evt.data+"
  • "
    ; } ws.Onclose=function(){ oUl.innerHTML+="
  • 客户端已断开连接
  • "
    ; }; ws.Onerror=function(evt){ oUl.innerHTML+="
  • "+evt.data+"
  • "
    ; }; }; oSend.Onclick=function(){ if(ws){ ws.send(oInput.value); } } function clickDend(val){ console.log(val) if(ws){ // ws.send('010500000000CDCA,0105000100009C0A,0105000200006C0A,0105000300003DCA'); ws.send(val); } } script>
    <script> $(function () { $('#httpCtrol input').on('click',function () { var $this = $(this) $.ajax({ method:'post', url:'http://localhost:1124/ledControl/on.do', data:{data:$this.attr('sy-val')}, success:function (res) { console.log(res) } }) }) }) script>
    body>
    html>

    4)启动服务

    node server.js

    《NodeJs串口通信》

    代码地址:https://github.com/kylvia/webForSerialPort.git


    推荐阅读
    • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
    • 如何使用Java获取服务器硬件信息和磁盘负载率
      本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
    • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
    • 本文介绍了在使用vue和webpack进行异步组件按需加载时可能出现的报错问题,并提供了解决方法。同时还解答了关于局部注册组件和v-if指令的相关问题。 ... [详细]
    • web.py开发web 第八章 Formalchemy 服务端验证方法
      本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
    • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
      本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
    • Metasploit攻击渗透实践
      本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
    • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
    • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
    • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
    • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
      本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
    • 服务器上的操作系统有哪些,如何选择适合的操作系统?
      本文介绍了服务器上常见的操作系统,包括系统盘镜像、数据盘镜像和整机镜像的数量。同时,还介绍了共享镜像的限制和使用方法。此外,还提供了关于华为云服务的帮助中心,其中包括产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题和视频帮助等技术文档。对于裸金属服务器的远程登录,本文介绍了使用密钥对登录的方法,并提供了部分操作系统配置示例。最后,还提到了SUSE云耀云服务器的特点和快速搭建方法。 ... [详细]
    • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
    • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
    • 本文介绍了如何使用jQuery和AJAX来实现动态更新两个div的方法。通过调用PHP文件并返回JSON字符串,可以将不同的文本分别插入到两个div中,从而实现页面的动态更新。 ... [详细]
    author-avatar
    扫地僧2502896033
    这个家伙很懒,什么也没留下!
    PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有