• electron调用C#应用程序实现串口通信


    最近转入零售行业开发了一系列产品,包含便利店收银软件会员系统供应链系统。为了追赶潮流,收银软件使用了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;

     

     
  • 相关阅读:
    Lvs+Keepalived+Mysql单点写入主主同步高可用方案
    【转贴】应用服务器内存泄露问题诊断一例
    Java的内存回收机制
    【转贴】两年内从零到每月十亿 PV 的发展来谈 Pinterest 的架构设计
    JavaScript模板引擎简介
    ETL随笔(一)zz
    看图说话:为什么大数据落地难?
    蚂蚁变大象:浅谈常规网站是如何从小变大的zz
    hadoop资料整理zz
    对REST的理解
  • 原文地址:https://www.cnblogs.com/Teddy/p/9367004.html
Copyright © 2020-2023  润新知