前言:最近这两天在研究如何实现web页面和串口间通信,在网上也查了各种资料,electron、nw或者chrome serial,发现对于我来说都太难实现了,一来可用的资料太少,二来安装东西老是出问题,算了还是放弃吧,自己用常用且最熟悉的方式来实现吧,作为一名前端码农,选用的肯定是node作为服务器了,然后网页请求方式用ajax或websocket都可以,实现方式下文都有。
先说说基本需求:硬件:usb插口的led蜂鸣器(就一个单片机),有红黄蓝三种灯,通过下发相应的指令,实现亮相应的登或者响起蜂鸣器
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)运行代码 最终结果
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+="
body>
html>
4)启动服务,执行代码
node server.js
5)运行页面
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+="
<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
代码地址:https://github.com/kylvia/webForSerialPort.git