最近做一个B/S的项目,需要读取电子秤的值,之前一直没做过,也没有经验,于是在网上找到很多  大致分两种

  1. 使用ActiveX控件,JS调用MSCOMM32.dll的串口控件对串口进行控制
  2. 使用C#语言的控件对串口进行控制,然后使用JS+AJAX与C#进行交互获得串口数据

详情见  使用JS获得串口数据 javascript:void(0)    但是小弟用这两种办法都获取到数据

串口配置如下:

1                  serialPort1.PortName = "COM1";          //端口名称
2             serialPort1.BaudRate = 1200;            //波特率
3             serialPort1.Parity = Parity.None;       //奇偶效验
4             serialPort1.StopBits = StopBits.One;    //效验
5             serialPort1.DataBits = 8;               //每个字节的数据位长度

 

最后换种思路:使用C#写一个ActiveX控件(吉日老师提醒)最后嵌入网页中读取数据   如下:

  1. 第一步:新建项目,如下图,选择windows下的类库项目。
  2. 在项目中添加一个类:IObjectSafety.cs 
  3. IObjectSafety.cs代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace MyActive
{
    //Guid唯一,不可变更,否则将无法通过IE浏览器的ActiveX控件的安全认证  
    [ComImport, Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IObjectSafety
    {
        [PreserveSig]
        void GetInterfacceSafyOptions(int riid,out int pdwSupportedOptions,out int pdwEnabledOptions);
    }
}

javaScript串口数据包解析 js读取串口数据_控件

  1. 添加一个用户控件 MyActiveXControl.cs 
  2. 修改 MyActiveXControl.cs 代码,让其继承IObjectSafety,定义相应的Guid,该Guid就是ActiveX的classid 
using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Drawing;
 using System.Data;
 using System.Text;
 using System.Windows.Forms;
 using System.Runtime.InteropServices;

namespace MyActiveX
 {
     [Guid("218849AF-1B2C-457B-ACD5-B42AC8D17EB7"), ComVisible(true)]
     public partial class MyActiveXControl : UserControl,IObjectSafety
     {
         public MyActiveXControl()
         {
             InitializeComponent();
         }

        #region IObjectSafety 成员 用于ActiveX控件安全信任
        public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
         {
             pdwSupportedOptions = 1;
             pdwEnabledOptions = 2;
         }

        public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
         {
             throw new NotImplementedException();
         }
         #endregion
     }
 }

javaScript串口数据包解析 js读取串口数据_控件

至此   Active控件制作完毕      下面我们添加文本框、按钮、SerialPort、Timer控件进行测试                                     

javaScript串口数据包解析 js读取串口数据_System_03

javaScript串口数据包解析 js读取串口数据_控件_04

  1. 添加响应的事件代码如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using MyActive;

namespace MyActiveX
{
    //不可改变
    [Guid("218849AF-1B2C-457B-ACD5-B42AC8D17EB7"), ComVisible(true)]
    public partial class MyActiveXControl : UserControl, IObjectSafety
    {
        
        public MyActiveXControl()
        {
            InitializeComponent();
        }

        public delegate void HandleInterfaceUpdataDelegate(string text);//定义一个委托
                     
        private HandleInterfaceUpdataDelegate interfaceUpdataHandle;//声明

        bool isClose = false;//是否关闭

        #region IObjectSafety 成员 用于ActiveX控件安全信任
        public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
        {
            pdwSupportedOptions = 1;
            pdwEnabledOptions = 2;
        }

        public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
        {
            throw new NotImplementedException();
        }
        #endregion
        
        
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(UpdateTextBox);//实例化委托对象 

                serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
                if (!serialPort1.IsOpen)
                {
                    serialPort1.Open();
                }
                button2.Enabled = true;
                button1.Enabled=false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
            timer1.Enabled = true;
            
        }
        /// <summary>
        /// 控件加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MyActiveXControl_Load(object sender, EventArgs e)
        {
            setOrgComb();
        }
        /// <summary>
        /// 初始化串口
        /// </summary>
        private void setOrgComb()
        {
            serialPort1.PortName = "COM1";          //端口名称
            serialPort1.BaudRate = 1200;            //波特率
            serialPort1.Parity = Parity.None;       //奇偶效验
            serialPort1.StopBits = StopBits.One;    //效验
            serialPort1.DataBits = 8;               //每个字节的数据位长度
        }
        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="text"></param>
        private void UpdateTextBox(string text)
        {
            //richTextBox1.Text = text + "\n\t" + richTextBox1.Text;
            richTextBox1.Text = text;
        }

        /// <summary>
        /// 接收数据是发生
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //获取接收缓冲区中数据的字节数
            if (serialPort1.BytesToRead > 5)
            {

                string strTemp = serialPort1.ReadExisting();//读取串口
                double weight = -1;//获取到的重量
                foreach (string str in strTemp.Split('='))//获取稳定的值
                {
                    double flog = 0;
                    //数据是否正常
                    if(double.TryParse(str, out flog)&&str.IndexOf('.')>0&&str[str.Length-1]!='.')
                    {
                        //数据转换   串口获取到的数据是倒叙的  因此进行反转
                        char[] charArray = str.ToCharArray();
                        Array.Reverse(charArray);
                        string left = new string(charArray).Split('.')[0];
                        string right = new string(charArray).Split('.')[1];
                        if (right.Length==2)
                        {
                            weight = int.Parse(left) + int.Parse(right) / 100.0;
                        }
                    }
                }
                if(weight>=0)
                {
                    //在拥有控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托。                    
                    this.Invoke(interfaceUpdataHandle, weight.ToString());//取到数据   更新
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                button1.Enabled = true;
                button2.Enabled = false;
                serialPort1.Close();
                timer1.Enabled = false;
               
                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (isClose)
            {
                return;
            }
            try
            {
                string send = "" + (char)(27) + 'p';
                send = serialPort1.ReadExisting();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                button2_Click(null, null);
            }
        }
    }
}

javaScript串口数据包解析 js读取串口数据_控件

  1. 至此读取串口数据的Active控件制作完毕   下面我们来制作一个安装包,新建一个安装项目
  2. 在安装项目的文件系统中添加刚才之前我们制作的ActiveX的DLL:MyActiveX.dll
    (特别注意:在文件添加进来后,右击文件选择属性,设置其属性Register值为:vsdraCOM)

 

javaScript串口数据包解析 js读取串口数据_html5 API 串口_06

    9.    生成安装程序,在项目MyActiveX\Setup1\Debug下找到Setup1.msi,双击安装它。
         然后在该目录下新建一个html文件(test.html)用于测试我们的ActiceX控件。HTML代码如下:

javaScript串口数据包解析 js读取串口数据_串口_07

javaScript串口数据包解析 js读取串口数据_控件

<html>
 <title>Powered by yyzq.net Email:yq@yyzq.net</title>
 <head>
 </head>
 <body>
 <div>
 <object id="yyzq" classid="clsid:218849AF-1B2C-457B-ACD5-B42AC8D17EB7"
         width="320"
         height="240"
         codebase="Setup1.msi">
 </object>
 </div>
 </body>
 </html>

javaScript串口数据包解析 js读取串口数据_控件

在IE浏览器下打开test.html,点击start     开始监听

javaScript串口数据包解析 js读取串口数据_html5 API 串口_10

 

javaScript串口数据包解析 js读取串口数据_html5 API 串口_11

虽功未成,亦未敢藏私,众侠诸神通尽录于此,竟成一笈,名葵花宝典,以飨后世。