整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          electron開發(fā)桌面應用實現(xiàn)串口通信,看完你就學會了

          么是electron

          使用 JavaScript,HTML 和 CSS 構建跨平臺的桌面應用程序

          只要你會javascript html css 就可以構建自己想要做的PC桌面和MACos app 應用,是不是很強大。

          今天的重點是通過它來實現(xiàn)串口通信的功能,想要實現(xiàn)這部分功能不得不做些準備工作

          下面跟我一步一步的來操作吧

          electron串口通信實現(xiàn)步驟

          1. 安裝環(huán)境

          想構建electron 必須要有支持的基礎環(huán)境,node 和 npm

          node想必大家并不陌生,前端的小伙伴太熟悉不過了,Node.js 就是運行在服務端的 JavaScript

          檢測你的電腦環(huán)境中是否安裝了node.js

          檢測是否安裝node,的命令是

          node -v

          我這里是win10 開發(fā)環(huán)境

          打開命令行工具

          我這里已經(jīng)安裝過了,看到有版本信息v10.16.1 說明已經(jīng)安裝成功

          接下來再檢查下是否安裝了npm 工具

          npm -v


          我這里也已經(jīng)安裝了npm ,顯示版本6.9.0

          有的同學小伙伴不知道npm是什么

          PS:是nodejs內置的軟件包管理器, 在項目開發(fā)中,需要用到說明包就拿這個下載就行了,下面有介紹

          好了,有了基礎的環(huán)境,我們就開始構建一個桌面程序吧


          在工作的根目錄創(chuàng)建一個文件夾eletest

          在創(chuàng)建一個普通的index.html 文件,這樣就有了一個基本的前端界面,electron 在node.js基礎上構建的,下面是應用的基本目錄結構,我們已經(jīng)創(chuàng)建了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()
              }
          })
          

          這里的方法 函數(shù)不在過多的解釋了,復制代碼到你創(chuàng)建的main.js中去就可以了,也可以去electron文檔中查看對應的API

          package.json 這是一個包構建信息的文件 在eletest文件下運行命令

          npm init -y


          就會自動生成package.json文件 ,是不是很簡單啊

          要想運行你寫的hml界面 打開這個文件修改一處

          "scripts": {
              "start": "electron ."
            },

          這樣就完成了幾個基本的配置

          下面安裝electron 包了 運行命令

          npm i --save-dev electron

          你的運行結果和上面的圖片里的信息說明就成功安裝了electron 默認安裝的最新穩(wěn)定的依賴包

          前期的工作都做完了,來運行它,看看是否出現(xiàn)我們想要的界面

          運行命令

          npm start


          hello world! 是不是很熟悉,很驚喜,很意外。

          出現(xiàn)了平時我們打開windows應用窗口

          以上步驟都是構建一個electron的桌面應用的,串口是如何實現(xiàn)的呢?

          如果你不熟悉串口是說明,先去補補串口的基本概念和相關信息

          串口、COM口是指的物理接口形式(硬件)


          你也可以打開設備管理器看到相應的串口,我這里有COM11和COM10 ,串口是成對出現(xiàn)的

          了解了說明是串口后,來實現(xiàn)我們的應用串口通信吧

          運行命令

          npm install serialport

          出現(xiàn)serialport 的版本信息 說明已經(jīng)安裝成功

          electron 通信或者一些交互都是在node上完成的

          查看了文檔后 我們可以在html頁面上


          引入serialport包

          設置要監(jiān)聽的串口端口 比如COM11

          配置寫端口基本信息

          serialPost.on 接收發(fā)過來的信息,如果在控制臺上打印出信息,就說明串口通信成功

          再次運行electron npm start


          打印控臺看到 信息:打印端口成功,正在監(jiān)聽數(shù)據(jù)中,就說明實現(xiàn)了串口的通信最重要一部打開通道

          為了驗證是否能通信,我們找個串口精靈 發(fā)送一寫信息 ,再次看控制臺收到了發(fā)送的信息


          如圖 在測試串口工具中輸入aaaa, 運行的控制臺收到了aaaa ,說明已經(jīng)成功實現(xiàn)串口通信。

          是不是很簡單,是不是很驚喜,是不是你在今后項目當中有需要串口通信的就可以復制粘貼了。


          、準備工作

          本文將使用 nodejs 的 SerialPort 包來實現(xiàn)串口通訊功能。 Node SerialPort 是一個 JavaScript 庫,用于連接到在 NodeJS 和 Electron 中工作的串行端口,以下是準備環(huán)境:

          • Electron 開發(fā)環(huán)境
          • 電腦有串口通訊能力,一般使用USB-串口轉接板
          • windows 操作系統(tǒng)

          本文操作過程來自: https://girishjoshi.io/post/access-serialport-from-electron-application-and-creating-gui-for-micropython-repl-on-esp8266/

          二、 SerialPort 介紹

          文檔地址: https://serialport.io/docs/

          1. 核心軟件包

          (1) serialport

          主對象,使用流式傳輸支持跨平臺的串行端口訪問。

          (2) @serialport/stream

          為綁定提供的流式接口。

          (3) @serialport/bindings-cpp

          為nodejs、electron提供跨平臺的綁定支持。

          (4) @serialport/binding-mock

          為測試實現(xiàn)模擬綁定功能。

          (5) @serialport/bindings-interface

          一個typescript 接口用來實現(xiàn)自己的綁定時使用。

          2. 解析器包

          解析器用來對原始的二進制數(shù)據(jù)轉換成自己需要的消息格式。 包含以下解析器包,這里不進行詳解: - @serialport/parser-byte-length - @serialport/parser-cctalk - @serialport/parser-delimiter - @serialport/parser-inter-byte-timeout - @serialport/parser-packet-length - @serialport/parser-readline - @serialport/parser-ready - @serialport/parser-regex - @serialport/parser-slip-encoder - @serialport/parser-spacepacket

          3. 命令行工具

          比較有用的命令行工具,包括: - @serialport/list - @serialport/repl - @serialport/terminal

          三、創(chuàng)建一個demo程序

          1. 創(chuàng)建 electron 項目

          # Clone the Quick Start repository
          $ git clone https://github.com/electron/electron-quick-start
          # Go into the repository
          $ cd electron-quick-start
          # Install the dependencies and run
          $ npm install && npm start

          2. 安裝 serialport

          npm install --save serialport

          3. 安裝 electron-rebuild

          因為選擇npm版本不同,這里要對庫進行重編譯,要先安裝 electron-rebuild 工具。

          npm install --save-dev electron-rebuild  
          .\node_modules\.bin\electron-rebuild
          npm rebuild

          注意原文路徑中用的 / , 我在windows 系統(tǒng),改用 \

          4. 使用 node-gyp 編譯庫

          npm install node-gyp electron electron-rebuild serialport --build-from-source
          ./node_modules/.bin/electron-rebuild
          npm start

          5. 修改 main.js 配置

          修改 WebPreferences 如下:

          webPreferences: {
                preload: path.join(__dirname, 'preload.js'),
                nodeIntegration: true,
                contextIsolation: false
          }
          

          8. 寫測試程序

          <!DOCTYPE html>
          <html>
          <head>
            <meta charset="UTF-8">
            <title>Electron test serialport</title>
          </head>
          <body>
          <h1>Serial terminal</h1>
          
          
          <script>
            //load serialport module
            const {SerialPort} = require('serialport');
          
            SerialPort.list().then(_=>{console.info(_);});
            const serialPort = new SerialPort({path:'COM3', baudRate: 115200}, function (err) {
              if(err) {
                console.error(err);
              }
            });
            console.info(serialPort);
            serialPort.write("abc", (err)=>{
              if (err) {
                return console.log('Error on write: ', err.message)
              }
              console.log('message written')
            });
            serialPort.on('error', function(err) {
              console.log('Error: ', err.message)
            });
          
            serialPort.on('data', function (data){
              console.info('data', data);
            });
          
          </script>
          <script>
            require('./renderer.js')
          </script>
          </body>
          </html>

          7. 運行程序

          npm start

          項目結構:

          在這里插入圖片描述


          四、問題處理

          在執(zhí)行electron-rebuild時,可能需要安裝windows-build-tools。新版本的windows-build-tools支持Python3.*版本,但使用Python2.7比較保險。

          1. 安裝python2.7虛擬環(huán)境

          如果本機沒有Python2.7,則可以使用MiniAnaconda配置虛擬環(huán)境 。 先下載安裝MiniAnaconda工具,然后用命令行創(chuàng)建虛擬環(huán)境 :

          conda create -n py27 python=2.7
          conda activate py27

          2. 安裝windows-build-tools

          直接安裝windows-build-tools大概率會失敗,可按以下流程操作:

          在執(zhí)行npm install -g node-gpy后使用命令:

          npm install -g --production windows-build-tools@4.0.0
          1. 當命令行界面開始不動時,打開任務管理器,把Build Tools結束任務;
          2. 再打開.windows-build-tools文件夾中的build-tools-log.txt,添加Variable: IsInstalled = 1,保存,關閉; 解決方案參考:https://blog.csdn.net/web15085181368/article/details/123192964

          更多關于serialport的功能可參考官方文檔。

          串口調試助手是最核心的當然是串口數(shù)據(jù)收發(fā)與顯示的功能,pzh-py-com借助的是pySerial庫實現(xiàn)串口收發(fā)功能,今天痞子衡為大家介紹pySerial是如何在pzh-py-com發(fā)揮功能的。

          一、pySerial簡介


            pySerial是一套基于python實現(xiàn)serial port訪問的庫,該庫的設計者為Chris Liechti,該庫從2001年開始推出,一直持續(xù)更新至今,pzh-py-com使用的是pySerial 3.4。

            pySerial的使用非常簡單,可在其官網(wǎng)瀏覽一遍其提供的API: https://pythonhosted.org/pyserial/pyserial_api.html,下面痞子衡整理了比較常用的API如下:

          class Serial(SerialBase):

          # 初始化串口參數(shù)

          def __init__(self, *args, **kwargs):

          # 打開串口

          def open(self):

          # 關閉串口

          def close(self):

          # 獲取串口打開狀態(tài)

          def isOpen(self):

          # 設置input_buffer/output_buffer大小

          def set_buffer_size(self, rx_size=4096, tx_size=None):


          # 獲取input_buffer(接收緩沖區(qū))里的byte數(shù)據(jù)個數(shù)

          def inWaiting(self):

          # 從串口讀取size個byte數(shù)據(jù)

          def read(self, size=1):

          # 清空input_buffer

          def reset_input_buffer(self):


          # 向串口寫入data里所有數(shù)據(jù)

          def write(self, data):

          # 等待直到output_buffer里的數(shù)據(jù)全部發(fā)送出去

          def flush(self):

          # 清空output_buffer

          def reset_output_buffer(self):

            pySerial常用參數(shù)整理如下,需要特別強調的是任何運行時刻對如下參數(shù)進行修改,均是直接應用生效的,不需要重新調用open()和close()去激活,因為參數(shù)的修改在pySerial內部是通過與參數(shù)同名的方法實現(xiàn)的,而這些方法均調用了Serial里的一個叫_reconfigure_port()的方法實現(xiàn)的。

          參數(shù)名

          功能解釋

          備注/可設值

          port

          設備名

          /dev/ttyUSB0 on GNU/Linux or COM3 on Windows

          baudrate (int)

          波特率

          /

          bytesize

          數(shù)據(jù)位bit個數(shù)

          FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS

          stopbits

          停止位

          STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO

          parity

          奇偶校驗位

          PARITY_NONE, PARITY_EVEN, PARITY_ODD PARITY_MARK, PARITY_SPACE

          timeout (float)

          接收超時

          None:blocking mode

          0: non-blocking mode

          x: 超時時間x秒

          write_timeout (float)

          發(fā)送超時

          同timeout

          二、JaysPyCOM串口功能實現(xiàn)


            串口功能代碼實現(xiàn)主要分為三大部分:配置功能實現(xiàn)、接收功能實現(xiàn)、發(fā)送功能實現(xiàn)。在實現(xiàn)這些功能之前首先需要import兩個module,分別是serial、threading,serial就是pySerial庫;threading是python自帶線程庫,其具體作用下面代碼里會介紹。

            除此以外還定義兩個全局變量,s_serialPort和s_recvInterval,s_serialPort是串口設備object實例,s_recvInterval是線程間隔時間。

          import serial

          import threading


          s_serialPort = serial.Serial()

          s_recvInterval = 0.5

          2.1串口配置功能

            串口配置里主要就是實現(xiàn)GUI界面上"Open"按鈕的回調函數(shù),即openClosePort(),軟件剛打開時所有可用Port默認是Close狀態(tài),如果用戶選定了配置參數(shù)(串口號、波特率...),并點擊了"Open"按鈕,此時便會觸發(fā)openClosePort()的執(zhí)行,在openClosePort()里我們需要配置s_serialPort的參數(shù)并打開指定的串口設備。

          class mainWin(win.com_win):


          def setPort ( self ):

          s_serialPort.port = self.m_textCtrl_comPort.GetLineText(0)

          def setBaudrate ( self ):

          index = self.m_choice_baudrate.GetSelection()

          s_serialPort.baudrate = int(self.m_choice_baudrate.GetString(index))

          def setDatabits ( self ):

          # ...

          def setStopbits ( self ):

          # ...

          def setParitybits ( self ):

          # ...


          def openClosePort( self, event ):

          if s_serialPort.isOpen():

          s_serialPort.close()

          self.m_button_openClose.SetLabel('Open')

          else:

          # 獲取GUI配置面板里的輸入值賦給s_serialPort

          self.setPort()

          self.setBaudrate()

          self.setDatabits()

          self.setStopbits()

          self.setParitybits()

          # 打開s_serialPort指定的串口設備

          s_serialPort.open()

          self.m_button_openClose.SetLabel('Close')

          s_serialPort.reset_input_buffer()

          s_serialPort.reset_output_buffer()

          # 開啟串口接收線程(每0.5秒定時執(zhí)行一次)

          threading.Timer(s_recvInterval, self.recvData).start()

            上述代碼里需要特別講一下的是串口接收線程,我們知道串口設備s_serialPort一旦打開之后,只要該串口設備的RXD信號線上有數(shù)據(jù)傳輸,pySerial底層會自動將其存入s_serialPort對應的input_buffer里,但并不會主動通知我們。那我們怎么知道input_buffer里有沒有數(shù)據(jù)?此時就需要我們開啟一個定時執(zhí)行的線程,線程里會去查看input_buffer里是否有數(shù)據(jù),如果有數(shù)據(jù)便顯示出來,因此在串口設備打開的同時我們需要創(chuàng)建一個串口接收線程recvData()。

          2.2串口接收功能

            串口接收功能其實在串口配置里已經(jīng)提到了,主要就是串口接收線程recvData()的實現(xiàn),recvData()實現(xiàn)很簡單,只有一個注意點,那就是threading.Timer()的用法,這是個軟件定時器,它只能超時觸發(fā)一次任務的執(zhí)行,如果想讓任務循環(huán)觸發(fā),那么需要在任務本身里添加threading.Timer()的調用。

          def clearRecvDisplay( self, event ):

          self.m_textCtrl_recv.Clear()


          def setRecvFormat( self, event ):

          event.Skip()


          def recvData( self ):

          if s_serialPort.isOpen():

          # 獲取input_buffer里的數(shù)據(jù)個數(shù)

          num = s_serialPort.inWaiting()

          if num != 0:

          # 獲取input_buffer里的數(shù)據(jù)并顯示在GUI界面的接收顯示框里

          data = s_serialPort.read(num)

          self.m_textCtrl_recv.write(data)

          # 這一句是線程能夠定時執(zhí)行的關鍵

          threading.Timer(s_recvInterval, self.recvData).start()

          2.3串口發(fā)送功能

            串口發(fā)送功能相比串口接收功能就簡單多了,串口發(fā)送主要就是實現(xiàn)GUI界面上"Send"按鈕的回調函數(shù),即sendData(),代碼實現(xiàn)比較簡單,不予贅述。

          def clearSendDisplay( self, event ):

          self.m_textCtrl_send.Clear()


          def setSendFormat( self, event ):

          event.Skip()


          def sendData( self, event ):

          if s_serialPort.isOpen():

          # 獲取發(fā)送輸入框里的數(shù)據(jù)并通過串口發(fā)送出去

          lines = self.m_textCtrl_send.GetNumberOfLines()

          for i in range(0, lines):

          data = self.m_textCtrl_send.GetLineText(i)

          s_serialPort.write(str(data))

          else:

          self.m_textCtrl_send.Clear()

          self.m_textCtrl_send.write('Port is not open')

            目前串口收發(fā)與顯示實現(xiàn)均是基于字符方式,即發(fā)送輸入框、接收顯示框里僅支持ASCII碼字符串,關于Char/Hex顯示轉換的功能(setRecvFormat()/setSendFormat())并未加上,后續(xù)優(yōu)化里會進一步做。

            至此,串口調試工具pzh-py-com誕生之串口功能實現(xiàn)便介紹完畢了


          主站蜘蛛池模板: 亚洲日韩国产一区二区三区在线| 国产精品盗摄一区二区在线| 久久国产精品免费一区二区三区| 亚洲蜜芽在线精品一区| 亚洲av无码一区二区三区不卡| 在线精品亚洲一区二区| 国产欧美一区二区精品仙草咪 | 国产一区二区三区韩国女主播| 三上悠亚精品一区二区久久| 国产爆乳无码一区二区麻豆| 精品无码人妻一区二区三区品| 一区五十路在线中出| 国产一区二区中文字幕| 国产一区二区成人| 精品一区精品二区| 精品国产福利第一区二区三区| 青青青国产精品一区二区| 国产精品亚洲一区二区三区久久 | 精品乱码一区二区三区在线| 一区二区精品久久| 免费无码AV一区二区| 一区二区三区观看免费中文视频在线播放 | 色一情一乱一伦一区二区三区日本| 国产一区二区三区美女| 日本一区二区在线| 国产伦精品一区二区三区四区 | 亚洲av无码天堂一区二区三区| 亚洲美女一区二区三区| 亚洲午夜电影一区二区三区| 美女福利视频一区| 亚洲AV无码一区二区乱孑伦AS| 少妇无码AV无码一区| 国产日韩精品一区二区三区在线| 亚洲AV无码一区二区三区在线观看| 国产91久久精品一区二区| 中文字幕无线码一区二区| 国产精品第一区揄拍无码| 国产免费私拍一区二区三区| 午夜无码一区二区三区在线观看| 天堂不卡一区二区视频在线观看| 精品一区二区无码AV|