最近轉入零售行業開發了一系列產品,包含便利店收銀軟體、會員系統、供應鏈系統。為了追趕潮流,收銀軟體使用了electron平臺開發,界面效果、開發效率確實不錯;但是涉及到串口通訊時遇到了麻煩,electron不能直接使用node.js的串口模塊。網上有一些文章推薦編譯electron源碼來實現串口模塊 ...
最近轉入零售行業開發了一系列產品,包含便利店收銀軟體、會員系統、供應鏈系統。為了追趕潮流,收銀軟體使用了electron平臺開發,界面效果、開發效率確實不錯;但是涉及到串口通訊時遇到了麻煩,electron不能直接使用node.js的串口模塊。網上有一些文章推薦編譯electron源碼來實現串口模塊的集成,向這條路走的過程中發現困難重重,嘗試多次都沒有成功,於是放棄。
經過一系列的google並測試後,終於通過調用第三方應用程式的方式實現:electron啟動C#開發的程式、C#程式直接與串口通訊並將串口接收的內容返回給electron。經過一段時間使用,程式表現穩定,終於了卻一樁心事。下麵分享一下心得。
electron與串口的通信原理比較簡單,分三步完成:
1. electron應用中啟動命令行程式(c#實現),並監聽命令行輸出;
2. 從electron中給命令行發送指令;
3. 命令行程式打開串口,並監聽串口返回與用戶輸入指令,實時將操作結果與串口輸出到命令行;
electron中程式段:
const spawn = require('child_process').spawn, var childProcess = spawn('D:\\SerialPortDemo.exe', ['COM4',9600]); // 啟動serialPortDemo.exe程式(C#開發),並傳入兩個參數:串口號與波特率; childProcess.stdout.on('data', (data) => { console.log(""+data); }); // 監聽serialPortDemo.exe的輸出,並將輸出列印出來 // 讓下方程式休眠一段時間後執行,可以看到C#的輸出; setTimeout(function(){ childProcess.stdin.write('quit'); // 給C#程式輸入'quit'命令 childProcess.stdin.end(); // 完成輸入後必須調用end方法,否則C#程式無法監聽到用戶輸入 }, 30000)
C#命令行程式段:
using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; namespace SerialPortDemo { class Program { private static SerialPort _SerialPort = null; static void Main(string[] args) { _SerialPort = new SerialPort(args[0], int.Parse(args[1]), Parity.None, 8, StopBits.One); _SerialPort.DataReceived += _SerialPort_DataReceived; ThreadPool.QueueUserWorkItem(new WaitCallback(OpenPort), _SerialPort); // 新開線程打開串口,並監聽接收數據 string command = string.Empty; while ((command = Console.ReadLine()) != string.Empty) // 主線程監聽用戶輸入,根據輸入內容判定下方流程 { Console.WriteLine(command); if (command == "close") { if (_SerialPort.IsOpen) { _SerialPort.Close(); } } else if (command == "quit") { if (_SerialPort.IsOpen) { _SerialPort.Close(); } return; } } } static void OpenPort(object paremeter) { if (!_SerialPort.IsOpen) { _SerialPort.Open(); } } private static void _SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { byte[] bytes = new byte[_SerialPort.BytesToRead]; _SerialPort.Read(bytes, 0, bytes.Length); string str = System.Text.Encoding.Default.GetString(bytes); Console.WriteLine(str); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } }
註:C#程式中應當讓串口的操作在子線程中進行,串口接收事件阻塞子線程;接收輸入命令的操作在主線程中進行,並阻塞主線程;
下方是在收銀軟體中做的測試截圖,從Console中可以看出能夠實時顯示從COM3串口來的數據。順便打個廣告:收銀軟體、會員系統、供應鏈系統均提供OEM,有興趣的同學可以加微信聯繫: 18189279823;