使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序
只要你会javascript html css 就可以构建自己想要做的PC桌面和MACos app 应用,是不是很强大。
今天的重点是通过它来实现串口通信的功能,想要实现这部分功能不得不做些准备工作
下面跟我一步一步的来操作吧
想构建electron 必须要有支持的基础环境,node 和 npm
node想必大家并不陌生,前端的小伙伴太熟悉不过了,Node.js 就是运行在服务端的 JavaScript
检测你的电脑环境中是否安装了node.js
检测是否安装node,的命令是
node -v
我这里是win10 开发环境
打开命令行工具
我这里已经安装过了,看到有版本信息v10.16.1 说明已经安装成功
接下来再检查下是否安装了npm 工具
npm -v
我这里也已经安装了npm ,显示版本6.9.0
有的同学小伙伴不知道npm是什么
PS:是nodejs内置的软件包管理器, 在项目开发中,需要用到说明包就拿这个下载就行了,下面有介绍
好了,有了基础的环境,我们就开始构建一个桌面程序吧
在工作的根目录创建一个文件夹eletest
在创建一个普通的index.html 文件,这样就有了一个基本的前端界面,electron 在node.js基础上构建的,下面是应用的基本目录结构,我们已经创建了index.html
eletest/
├── package.json
├── main.js
└── index.html
mian.js文件也是electron的入口文件
const electron=require('electron')
// Module to control application life.
const app=electron.app
// Module to create native browser window.
const BrowserWindow=electron.BrowserWindow
const path=require('path')
const url=require('url')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow() {
// Create the browser window.
mainWindow=new BrowserWindow({
width: 1920,
height: 1080,
frame:false,
resizable: false,
fullscreen:true,
webPreferences: {
nodeIntegration: true,
// preload: path.join(__dirname, 'preload.js')
}
})
// and load the index.html of the app.
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// Open the DevTools.
mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function() {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow=null
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function() {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
app.quit()
})
app.on('activate', function() {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow===null) {
createWindow()
}
})
这里的方法 函数不在过多的解释了,复制代码到你创建的main.js中去就可以了,也可以去electron文档中查看对应的API
package.json 这是一个包构建信息的文件 在eletest文件下运行命令
npm init -y
就会自动生成package.json文件 ,是不是很简单啊
要想运行你写的hml界面 打开这个文件修改一处
"scripts": {
"start": "electron ."
},
这样就完成了几个基本的配置
下面安装electron 包了 运行命令
npm i --save-dev electron
你的运行结果和上面的图片里的信息说明就成功安装了electron 默认安装的最新稳定的依赖包
前期的工作都做完了,来运行它,看看是否出现我们想要的界面
运行命令
npm start
hello world! 是不是很熟悉,很惊喜,很意外。
出现了平时我们打开windows应用窗口
以上步骤都是构建一个electron的桌面应用的,串口是如何实现的呢?
如果你不熟悉串口是说明,先去补补串口的基本概念和相关信息
串口、COM口是指的物理接口形式(硬件)
你也可以打开设备管理器看到相应的串口,我这里有COM11和COM10 ,串口是成对出现的
了解了说明是串口后,来实现我们的应用串口通信吧
运行命令
npm install serialport
出现serialport 的版本信息 说明已经安装成功
electron 通信或者一些交互都是在node上完成的
查看了文档后 我们可以在html页面上
引入serialport包
设置要监听的串口端口 比如COM11
配置写端口基本信息
serialPost.on 接收发过来的信息,如果在控制台上打印出信息,就说明串口通信成功
再次运行electron npm start
打印控台看到 信息:打印端口成功,正在监听数据中,就说明实现了串口的通信最重要一部打开通道
为了验证是否能通信,我们找个串口精灵 发送一写信息 ,再次看控制台收到了发送的信息
如图 在测试串口工具中输入aaaa, 运行的控制台收到了aaaa ,说明已经成功实现串口通信。
是不是很简单,是不是很惊喜,是不是你在今后项目当中有需要串口通信的就可以复制粘贴了。
avaScript本身不提供直接访问串口的功能。然而,可以使用Web API和JavaScript与串口进行通信,一般需要在浏览器环境中进行。
const port=await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
使用Web Serial API进行串口通信需要在浏览器环境中运行,并且通常需要用户授权。不是所有浏览器都支持Web Serial API,而且它主要用于Web应用程序,而不是传统的本地JavaScript应用程序。
// 请求串口访问权限
async function requestSerialAccess() {
try {
const port=await navigator.serial.requestPort();
await port.open({ baudRate: 9600 }); // 打开串口连接
// 读取数据
const reader=port.readable.getReader();
while (true) {
const { value, done }=await reader.read();
if (done) {
break;
}
// 处理从串口读取的数据
console.log(value);
}
// 关闭串口连接
await port.close();
} catch (error) {
console.error("Error:", error);
}
}
// 添加事件监听器,用于在用户点击按钮时请求串口访问权限
const connectButton=document.getElementById("connect-button");
connectButton.addEventListener("click", requestSerialAccess);
首先我们创建了一个函数requestSerialAccess(),它请求串口访问权限,打开串口连接,然后使用一个循环来不断读取数据,将数据输出到控制台。最后,它在完成后关闭串口连接。
HTTP协议是互联网应用最为广泛的一种网络协议,由客户端发送请求消息,服务端针对客户端的请求进行响应回复。本文将基于EsDA开发平台,使用EPC6450-AWI开发板,以及图形化设计工具AWFlow Designer实现将串口数据转换为HTTP请求发送给云端,随后云端针对HTTP请求进行处理响应的功能。该项目主要用到了serial_in_ex,fscript,http_request,fileout,timer,filein和serial_out_ex节点,具体实现请见下文。
该项目是将串口数据通过作为HTTP客户端的EPC6450-AWI开发板去发送HTTP请求到云端服务器,在云端服务器上处理HTTP请求并下发响应数据。
该项目的主要步骤如下:
1、配置EPC6450-AWI的网口设备并连接到互联网
2、配置串口通信参数,包括波特率,数据位,停止位和校验等
3、从串口读取HTTP请求参数,在本项目中串口的输入数据如下:POST方法主要是输入body消息正文,GET方法主要是输入url统一资源定位符
4、http_request节点向云端服务器发起HTTP请求,云端服务器处理数据后发送响应到客户端,客户端接收来自云端服务器的响应数据
5、HTTP客户端接收响应数据后,将响应数据中转到文本中保存并输出到串口进行显示
在本文将不再赘述串口设备在EsDA的基础通信,读者可以阅读以下文章对串口节点和EsDA的一些基础项目进行熟络:
【EsDA应用】5分钟实现一个串口通信业务
【EsDA 应用】常用IO设备节点详解
EsDA MPC-ZC1应用——串口服务器(一)
在标有丝印为TF Card 丝印的卡槽处,插入SD卡
用户可随机选择EPC6450-AWI的可用串口设备,在本文将用UART5进行串口通信。在标有丝印为UTX5,URX5的串口模块上,将TTL转USB串口模块的TX与板子丝印为URX5连接,TTL转USB串口模块的RX与板子丝印为UTX5相连;并将TTL转USB串口模块另一端的USB
口接入电脑
在标有丝印为Type-C 的接口处,插上Type-C线,并将Type-C线的另一端USB口插入电脑
在标有丝印为NET0 或 NET1的RJ45插座处接上水晶头,网线另一端水晶接头插在PC的网络插座上
本文的网络搭建是将电脑wifi通过以太网与开发板进行网络共享,以此达到开发板的以太网口联网的目的
将TTL转USB串口模块接在丝印为DUART的调试串口上(TX接RX,RX接TX)
打开串口调试助手,检索并打开TTL转USB串口模块的设备端口号后,使用shell命令ip addr,查看网口的ip地址,根据下图可知,本文使用的网口设备ip地址是192.168.137.251
配置PC上的以太网的IP与开发板的IP地址在同一局域网下
将PC上的WLAN配置共享给与开发板连接的以太网
在串口调试助手输入shell指令ping www.baidu.com,ping成功即开发板联网成功
本项目业务主要分为两个部分:
POST方法请求项目:模拟传感器数据通过串口转HTTP客户端传送到HTTP服务器,服务器进行数据分析和处理。将串口数据作为HTTP请求的body参数,http_request节点在整理属性和输入参数后对自建的HTTP服务器发起POST方法的HTTP请求;服务器收到请求后,将串口数据保存到本地的文本文件以便后续查看,下发响应数据给客户端;客户端收到服务器的响应数据经过数据处理后打印到串口助手的界面进行查看。
GET方法请求项目:请求访问百度服务器。串口提供HTTP请求参数,http_request节点整理属性和输入参数对百度服务器发起GET方法的HTTP请求;http_request节点接收来自百度服务器的响应数据,将数据保存到指定的文本文件中存储再从文本中将数据输出到串口助手的界面上。
本项目由串口助手模拟将采集的传感器数据通过开发板的串口传输到开发板创建的HTTP客户端,HTTP客户端再通过POST方法将传感器数据作为body参数去请求本地搭建的HTTP服务器,HTTP服务器接收到请求后,将传感器数据存储到本地的index.html文件中,并将数据处理后作为响应体回发给客户端,HTTP客户端接收到响应消息后打印到串口助手上进行显示。
添加serial_in_ex,fscript,http_request,fileout,timer,filein和serial_out_ex节点到画布中并连线如下图。
在本文的serial_in_ex和serial_out_ex节点配置参数和操作一致,后面不再赘述serial_out_ex节点的配置操作。双击serial_in_ex节点,点击配置节点名旁边的铅笔图标。
选择用户使用的串口设备,根据实际需求配置波特率,奇偶校验等串口配置参数,本项目中的串口配置参数如下图所示。
双击serial_in_ex的消费者节点fscript,因为本项目主要是将采集到的传感器数据作为消息体参数发送到HTTP服务器进行处理,所以该fscript主要是将读取到的serial_in_ex串口数据赋值给http_request节点的body参数如下:
msg.body=istream_read_string(msg.istream, 100)
双击http_request节点,配置方法为POST,并设置用户想要访问的HTTP服务器URL(这里的HTTP服务器是笔者本地用python搭建的一个简易HTTP服务器),根据需要选择输出的内容类型,其他参数按需配置即可。
双击http_request节点的消费者节点fscript,该节点主要是存储http_request节点的输出参数msg.payloadLength,用于后续赋值给filein节点的输入参数读取的数据长度。
set(global.length, msg.payloadLength)
双击fileout节点,配置属性参数如下,在本项目中配置文件打开模式为从头写入且丢弃源文件内容,文件名选择开发板上自动挂载的/flow目录下的文件,数据来源选择payload形式。
双击timer节点,配置定时周期时长,定时用filein节点去读取存放HTTP响应的数据
双击timer的消费者节点fscript,配置filein节点的输入参数如下
set(msg.topic,"exec:read_data");var length=global.lengthset(msg.payload,length);
双击filein节点,配置需要读取的文件名
双击filein的消费者节点fscript,该节点主要将从filein节点读取到的数据转换给serial_out_ex节点
set(output.payload,str(msg.payload,true));
双击serial_out_ex节点,该节点配置参数与serial_in_ex节点一样
笔者用python脚本搭建了一个简易的HTTP服务器,主要功能是收到的POST请求中的消息体数据存储到本地的index.html文本中,并将收到的消息体数据处理后作为响应体回发给客户端。在PC端执行以下http_server.py的脚本即开启了本地的HTTP服务端。
from http.server import BaseHTTPRequestHandler, HTTPServerimport loggingclass S(BaseHTTPRequestHandler): def do_HEAD(self): self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() def do_POST(self): content_length=int(self.headers['Content-Length']) post_data=self.rfile.read(content_length) logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n", str(self.path), str(self.headers), post_data.decode('utf-8')) res="You Input: " + post_data.decode('utf-8') with open("index.html","a+") as f: f.write(post_data.decode('utf-8')) self.do_HEAD() self.wfile.write("{}".format(res).encode('utf-8')) def respond(self, opts): response=self.handle_http(opts['status'], self.path) self.wfile.write(response) def handle_http(self, status_code, path): self.send_response(status_code) self.send_header('Content-type', 'text/html') self.end_headers() content=''' <html><head><title>Title goes here.</title></head> <body><p>This is a test.</p> <p>You accessed path: {}</p> </body></html> '''.format(path) return bytes(content, 'UTF-8')def run(server_class=HTTPServer, handler_class=S, port=8080): print("run()") logging.basicConfig(level=logging.INFO) server_address=('', port) httpd=server_class(server_address, handler_class) logging.info('Starting http server...\n') try: httpd.serve_forever() except KeyboardInterrupt: pass httpd.server_close() print("httpd.server_close()") logging.info('Stopping http server...\n')if __name__=='__main__': from sys import argv if len(argv)==2: run(port=int(argv[1])) else: run()
将流图下载到目标开发板后,在串口调试助手输入HTTP请求的消息体(模拟的传感器数据)后,就可以在串口助手输出界面看到返回的响应内容如下:
本地的HTTP服务器端收到的来自客户端的请求信息如下:
打开PC本地的index.html文本,可以看到保存的传感器数据如下:
至此,串口转HTTP客户端的传感器数据上云的实验就已完全结束,接下来开启访问百度游览器的HTTP请求实验。
该项目主要是通过GET方法请求百度服务器,最后将百度服务器响应的消息进行打印显示,主要是将串口数据转换为HTTP请求,发送到服务器端,以实现与远程服务器的通信。
添加serial_in_ex,fscript,http_request,fileout,timer,filein和serial_out_ex节点到画布中并连线如下图。
在本文的serial_in_ex和serial_out_ex节点配置参数和操作一致,后面不再赘述serial_out_ex节点的配置操作。双击serial_in_ex节点,点击配置节点名旁边的铅笔图标。
选择用户使用的串口设备,根据实际需求配置波特率,奇偶校验等串口配置参数,本项目中的串口配置参数如下图所示。
双击serial_in_ex的消费者节点fscript,因为本项目主要是对HTTP协议的GET方法进行数据请求,而GET的请求参数是拼接在URL的后面,所以串口输入的主要是http_request节点的URL配置项,该fscript主要是读取serial_in_ex的串口数据,如下:
var str=istream_read_string(msg.istream, 100)msg.url=str
双击http_request节点,配置方法为GET,并设置用户想要访问的云端服务器URL,根据需要选择输出内容类型,其他参数按需配置即可。
双击http_request节点的消费者节点fscript,该节点主要是存储http_request节点的输出参数msg.payloadLength,用于后续赋值给filein节点的输入参数读取的数据长度。
set(global.length, msg.payloadLength)
双击fileout节点,配置属性参数如下,在本项目中配置文件打开模式为从头写入且丢弃源文件内容,文件名选择开发板上自动挂载的/flow目录下的文件,数据来源选择payload形式。
双击timer节点,配置定时周期时长,定时用filein节点去读取存放HTTP响应的数据
双击timer的消费者节点fscript,配置filein节点的输入参数如下
set(msg.topic,"exec:read_data");var length=global.lengthset(msg.payload,length);
双击filein节点,配置需要读取的文件名
双击filein的消费者节点fscript,该节点主要将从filein节点读取到的数据转换给serial_out_ex节点
set(output.payload,str(msg.payload,true));
双击serial_out_ex节点,该节点配置参数与serial_in_ex节点一样
将该流图下载到目标开发板后,在串口调试助手输入HTTP请求的云端URL后,可以看到返回的响应消息体如下。至此该实验到此结束。
*请认真填写需求信息,我们会在24小时内与您取得联系。