使用SerialPort类,读取称重器的值。使用“串口调试助手”读值是稳定的。用我的程序读值就会在0和正确值之间跳来跳去,稳定不了。请高手帮忙看看。
代码如下:
            //初始化
            myPort.BaudRate = 9600;//int.Parse(comboBox2.Text);
            myPort.DataBits = 8;//int.Parse(comboBox3.Text);
            myPort.StopBits = StopBits.One;//(StopBits)Enum.Parse(typeof(StopBits), comboBox4.Text);
            myPort.Parity = Parity.None; //(Parity)Enum.Parse(typeof(Parity), comboBox5.Text);
            myPort.PortName = comName;// "COM3";//comName;//comboBox1.Text;
            myPort.Handshake = SetPortHandshake(myPort.Handshake);
            //myPort.RtsEnable = true; // 打开RTS ,这步很重要
           
//读值方法一
   private string GetValueFromPC(SerialPort sp)
        {
            int DataLength = sp.BytesToRead;            int i = 0;
            int len = 0;
            StringBuilder sb = new StringBuilder();            while (i < DataLength)
            {                byte[] ds = new byte[1024];                len = sp.Read(ds, 0, 1024);                sb.Append(Encoding.ASCII.GetString(ds, 0, len));                i += len;            }
            return sb.ToString();        }
//读值方法二:
        private string GetValueFromNB(SerialPort sp)
        {
            return myPort.ReadLine();
        }
//调用方法:
 private void DataReceived()
        {
            //string data = string.Empty;
            //以下为USB 转 COM 要用的代码
            try
            {
                //先判断订单的 sku 是否扫描结束:
                if (iOrderDetail.GetNoPackCountbyOrderKey(curOrderInfo.OrderKey) == 0)
                {
                    string data_str = null;
                    //台式机
                    if (myPort.PortName.Contains('1') || myPort.PortName.Contains('2'))
                    {
                        data_str = this.GetValueFromPC(myPort);
                    }
                    else
                    {//笔记本
                        data_str = this.GetValueFromNB(myPort);
                    }                    if (data_str.Trim() != string.Empty)
                    {
                        number = GetWeightNumber(data_str);
                        ShowWeigth(number.ToString());
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }

解决方案 »

  1.   

    serialPort1.ReceivedBytesThreshold = 1;
      

  2.   

    我这没有现成的例子,不通的称重器返回的数据可能也是不一样的,可以调试一下,或者把返回的结果输出一下,看看没有获得的值是不是都一样,是不是所有的值都是有效值。        public static string BytesToStr(byte[] bytes)
            {
                string str = string.Empty;
                foreach (byte b in bytes)
                {
                    str += b.ToString("X2") + " ";
                }
                return str.TrimEnd(' ');
            }
      

  3.   


    class MySerializePort
    {
        public string Read(char a_cEndChar)
        {
            char t_sRx = '\0';
            int t_i4Cnt = 0;
            try
            {
                while (t_i4Cnt < 255)
                {
                    t_sRx = (char)m_SerialPort.ReadByte();
                    if (t_sRx == a_cEndChar) break;
                    t_i4Cnt++;
                }
            }
            catch (Exception)
            {
                throw;
            }
            return t_sRx.ToString();
        }
    }
    String t_sResponse = mySerialPort.Read( (char)0x2A );利用ReadByte读到结尾字串出现,在结束读取
    才不会有读值不稳定的情况......
      

  4.   

    你的两种读法都会造成不稳定的情况
    int DataLength = sp.BytesToRead;
    myPort.ReadLine();
    都不能确保资料已经完全到serialize port的receive buffer中
    第一个是传回现在receive buffer中已有的资料长度
    第二个是读一行现在receive buffer中的资料假设资料AAABBBCCC
    Buff ==> Buff                     ==>  Buff
    AAA      AAABB                    AAABBBCCC
             readline or BytesToRead
    很有可能你呼叫read的时候buff中的资料还未完全.....
      

  5.   

    public string Read(char a_cEnd1Char, char a_cEnd2Char)
    {
        char[] t_sBuffer = new char[255];
        //String t_sReturn = "";
        bool t_bFundChar = false;
        int t_i4Length = 0;
        int  t_i4Cnt = 0;
        try
        {
            while (t_i4Cnt < 255)
            {
                t_sBuffer[t_i4Cnt++] = (char)m_SerialPort.ReadByte();            t_sBuffer[t_i4Cnt] = '\0';            if (t_sBuffer[t_i4Cnt - 1] == a_cEnd1Char) break;
                if (t_sBuffer[t_i4Cnt - 1] == a_cEnd2Char) break;
            }
        }
        catch (Exception)
        {
            throw;
        }
        for (t_i4Length = 0; t_i4Length < t_sBuffer.Length; t_i4Length++)
        {
            if (t_sBuffer[t_i4Length] == a_cEnd1Char || t_sBuffer[t_i4Length] == a_cEnd2Char)
            {
                t_bFundChar = true;
                break;
            }
        }
        if (t_bFundChar == false) return "";
        return new string(t_sBuffer, 0, t_i4Length);
    }
    刚贴错函数了.....
    这个才是....sorry...
      

  6.   

    建议串口操作不要用serialport组建, 可以用微软的mscommon32.ocx
      

  7.   

    去掉while,用如下代码试一试:
    private string GetValueFromPC(SerialPort sp)
      {
       int DataLength = sp.BytesToRead;  int len = 0;
      StringBuilder sb = new StringBuilder();
      byte[] ds = new byte[1024];  len = sp.Read(ds, 0, 1024);  sb.Append(Encoding.ASCII.GetString(ds, 0, len));
      sp.DiscardInBuffer();
      sp.DiscardOutBuffer();
      return sb.ToString();
    }
      

  8.   

    再问下,不知道 Read(char a_cEnd1Char, char a_cEnd2Char),这两个参数需要传什么。
      

  9.   

    两个都传‘\r\n’?  怎么把\r\n转换成char类型啊?
      

  10.   

    我这样调 没问题吧?  
    data_str = this.Read('\r', '\n');
    引用 7 楼 cloudhsu 的回复:C# code
    public string Read……
    [/Quote]
      

  11.   

    我运行程序,程序报错:请求的资源在使用中。我这样调 没问题吧?   
    data_str = this.Read('\r', '\n');
      

  12.   

    晕 可以用SerialPort的DataReceived时间来补抓数据哈
    称重器发送的数据有一定的格式吧?
    我假设格式哈:
    A1  LH      D0...DN   CS      A2
    桢头 数据长度 数据域 CS(校验位) 结束位 
    部分代码:
                Thread.Sleep(50);
                byte[] bufferhear = new byte[2];//包头
                rs485_Port.Read(bufferhear, 0, bufferhear.Length);
                if (!(bufferhear[0] == 0xFE))
                {//桢头不正确
                    return;
                }
                byte[] dataByte = new Byte[2 + bufferhear[2]];
                //接受所有数据
                while (rs485_Port.BytesToRead != (bufferhear[2] + 2))
                {//串口没接受完数据 继续延迟时间接收
                    Thread.Sleep(50);
                    if (rs485_Port.BytesToRead > bufferhear[2] + 2)
                    {
                        break;
                    }
                }
                rs485_Port.Read(dataByte, 2, bufferhear[2] + 2);//获取余下数据
                Array.Copy(bufferhear, 0, dataByte, 0, bufferhear.Length);
                //接下来是数据解析
      

  13.   

    上面是DataReceived事件的代码 
    rs485_Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
      

  14.   

    我得出bufferhear[0] 的值是10,48,52这种形式的。不是0xFE这种格式。