说明:请自行严格验证本代码的准确性,本人不对此做任何保证和负责!!!



本代码里,ReceivedBytesThreshold设为1 

串口数据处理用的线程:

            System.Threading.Thread SP_DataReceived1_timeout_t1 = new System.Threading.Thread(new System.Threading.ThreadStart(SP_DataReceived1_timeout));

            SP_DataReceived1_timeout_t1.Start();  :

 
        public class OP_with_com_name
        {
            public int recv_ok1 = 0;
            public OpenSP OP_s = new OpenSP();
            //public int botelv_for_recv_delay = 0;

            public string com_name1 = "";

            public string cur_Cmd;

            public AutoResetEvent AutoResetEvent1 = new AutoResetEvent(false);


            public byte[] recv_bytes = new byte[0];

            // public int is_ret_notok_once = 0;

            public int recv_length_for_delay = 70;

            public int is_scan_packet = 0;

            public object lock_obj1 = new object();

            public DateTime last_recv_time=DateTime.Now;
            public List<byte> recv_bytes_for_addon=new List<byte>();

            public int is_have_recv_bytes = 0;
        }


       public OP_with_com_name prod_comm_obj = new OP_with_com_name();


 

        public void conn_prod_comm1()  //打开串口

        {

          

            try

            {

                if (prod_comm_obj.OP_s.SP.IsOpen)

                {

                    return;

                }

                prod_comm_obj.com_name1 = "prod_comm";

                prod_comm_obj.OP_s.SP.DataReceived -= SP_DataReceived1;

          

                //comport1.Open(int.Parse(libcls.get_ini_set("sets.ini", "com1").Trim().ToLower().Replace("com", "")), int.Parse(libcls.get_ini_set("sets.ini", "com1_botelv").Trim()));

                if (prod_comm_obj.OP_s.OpenPort(G_jiaozhun_canshuo_input_t.prod_comm, G_jiaozhun_canshuo_input_t.prod_botelv, G_jiaozhun_canshuo_input_t.stopBits.ToString() , 8, G_jiaozhun_canshuo_input_t.parity.ToString()))

                {

                    prod_comm_obj.OP_s.SP.ReadTimeout=220;

                    prod_comm_obj.OP_s.SP.ReceivedBytesThreshold = 1;

                    prod_comm_obj.OP_s.SP.DataReceived += SP_DataReceived1;

                }

            }

            catch (Exception eee)

            {

            }

        }

 ‌  //串口数据处理用的线程: 

        public void SP_DataReceived1_timeout() 
        {
            OP_with_com_name rttobj = prod_comm_obj;// get_op_obj_by_com_name(get_comname_by_index(0));

            while (isrunning == 1)
            {
                System.Threading.Thread.Sleep(20);

                try
                {
                    if (prod_comm_obj.is_have_recv_bytes == 1)
                    {

                       

                      //120ms没收到新数据则认为一帧结束:

                    if ((DateTime.Now - prod_comm_obj.last_recv_time).TotalMilliseconds >= 120)
                        {


                            prod_comm_obj.is_have_recv_bytes = 0;


                            try
                            {

                                int count = prod_comm_obj.recv_bytes_for_addon.Count;// rttobj.OP_s.SP.Read(recvbuf, 0, 600);


                                byte[] recvbuf = new byte[count];

                                Array.Copy(prod_comm_obj.recv_bytes_for_addon.ToArray(), 0, recvbuf, 0, count);


                                prod_comm_obj.recv_bytes_for_addon.Clear();


                                string tempStr = string.Empty;
                                for (int i = 0; i < count; i++)
                                {
                                    tempStr += recvbuf[i].ToString("X2") + " ";

                                }

                                if (button10opencomms.Text == "关闭串口")
                                {

                                    if (textBox2recv_485.Text.Length >= 1024 * 2048)
                                    {

                                        textBox2recv_485.Clear();


                                    }
                                    if (prod_comm_obj.is_scan_packet != 1)
                                    {
                                        textBox2recv_485.AppendText(">>" + tempStr + "\r\n");

                                        textBox2recv_485.ScrollToCaret();
                                    }

                                }

                                // rttobj.recv_ok1 = 1;


                                // libcls.MessageBoxw(tempStr);


                                if (count <= 3)
                                {


                                        continue;

                                   // return;

                                }


                                int crc16 = recvbuf[count - 1] * 256 + recvbuf[count - 2];


                                byte[] recvbuf_withnocrc = new byte[count - 2];

                                for (int i = 0; i < (count - 2); i++)
                                {
                                    recvbuf_withnocrc[i] = recvbuf[i];

                                }


                                byte[] ssdata_Crc = CRC16Helper.CRC16_a(recvbuf_withnocrc);
                                int ssdata_Crcint = ssdata_Crc[1] + ssdata_Crc[0] * 256;
                                if (ssdata_Crcint == crc16)//rttobj.cur_Cmd == "Q" ||    , cur_Cmd=='Q'时表示切换相时crc有点问题
                                {


                                    rttobj.recv_bytes = new byte[count - 4];


                                    Array.Copy(recvbuf, 2, rttobj.recv_bytes, 0, count - 4);


                                    rttobj.recv_ok1 = 1;


                                    rttobj.AutoResetEvent1.Set();


                                }
                                else
                                {
                                    //crc 16 错误不记录,只有最终重试发送且提示发送失败时的才记录:
                                    //MuNiuMaLib.fvdou_append_error_to_log_txtH("SP_DataReceived1 err", tempStr+   " crc16 err \r\n");


                                }

                            }
                            catch (Exception eee)
                            {

                                // MessageBox.Show(eee.Message);
                                //MuNiuMaLib.fvdou_append_error_to_log_txt(eee.Message + " in SP_DataReceived1 com1" + eee.StackTrace);
                                MuNiuMaLib.fvdou_append_error_to_log_txtH("SP_DataReceived1 err", eee.Message + eee.StackTrace + "\r\n");


                            }

                        }


                    }


                }
                catch { } 


            }

             


        }

     //串口收到数据时的回调函数:

       


        private void SP_DataReceived1(object sender, SerialDataReceivedEventArgs e)
        {
            OP_with_com_name rttobj = prod_comm_obj;// get_op_obj_by_com_name(get_comname_by_index(0));


            try
            {
                rttobj.last_recv_time = DateTime.Now;


                byte[] recvbuf = new byte[rttobj.OP_s.SP.BytesToRead];


                int count = rttobj.OP_s.SP.Read(recvbuf, 0, rttobj.OP_s.SP.BytesToRead);//这个可能报错,所以加try

                for (int i = 0; i < count; i++)
                {
                    rttobj.recv_bytes_for_addon.Add(recvbuf[i]);


                }


            }
            catch(Exception eee)
            {
                MuNiuMaLib.fvdou_append_error_to_log_txtH("SP_DataReceived1 err2", eee.Message + eee.StackTrace + "\r\n");


               // RestartSerialPort();


            }

            try
            {
                rttobj.is_have_recv_bytes = 1;
            }
            catch (Exception eee)
            {
                MuNiuMaLib.fvdou_append_error_to_log_txtH("SP_DataReceived1 err2", eee.Message + eee.StackTrace + "\r\n");
            }

            //Sleep(70+6* prod_comm_obj.recv_length_for_delay)还是偶尔分包,改为Sleep(70+8* prod_comm_obj.recv_length_for_delay)后正常:

            //System.Threading.Thread.Sleep(70+8* prod_comm_obj.recv_length_for_delay);//等待串口包收完!!!!40ms时读继电器状态有时不准?

        }


        public List<byte> send_data_to_prod(byte comm_dev_addr,string cmd_name,byte modbus_cmd_code, byte[] sendbuf,int is_in_auto_jiaozhuan_ing_t,int is_only_send_sendbuf_bytes,int is_scan_packet,int not_need_huifu)
        {


            conn_prod_comm1();


            List<byte> ret_data = new List<byte>();

            int is_recv_fail_count = 0;
            int max_resend_1 = 5;//4 偶尔发失败,5把!
            string tempStr = string.Empty;

            lock (prod_comm_obj.lock_obj1)
            {
                int max_resend_ccc = 0;

                prod_comm_obj.is_scan_packet = is_scan_packet;


                while (max_resend_ccc <= max_resend_1 )
                {
                    max_resend_ccc++;

                    prod_comm_obj.cur_Cmd = cmd_name;

                    prod_comm_obj.recv_ok1 = 0;


                    prod_comm_obj.AutoResetEvent1.Reset();

                    if (is_only_send_sendbuf_bytes == 0)
                    {
                        byte[] dataSend = new byte[2 + sendbuf.Length + 2];
                        dataSend[0] = comm_dev_addr;

                        dataSend[1] = modbus_cmd_code;

                        Array.Copy(sendbuf, 0, dataSend, 2, sendbuf.Length);

                        byte[] recvbuf_withnocrc = new byte[2 + sendbuf.Length];

                        for (int i = 0; i < (2 + sendbuf.Length); i++)
                        {
                            recvbuf_withnocrc[i] = dataSend[i];

                        }


                        byte[] ssdata_Crc = CRC16Helper.CRC16_a(recvbuf_withnocrc);
                        //int ssdata_Crcint = ssdata_Crc[0] + ssdata_Crc[1] * 256;

                        dataSend[2 + sendbuf.Length] = ssdata_Crc[1];

                        dataSend[3 + sendbuf.Length] = ssdata_Crc[0];


                        prod_comm_obj.OP_s.SP.Write(dataSend, 0, dataSend.Length);


                        tempStr = "";
                        for (int i = 0; i < dataSend.Length; i++)
                        {
                            tempStr += dataSend[i].ToString("X2") + " ";

                        }

                    }


                    if (is_only_send_sendbuf_bytes == 1)
                    {
                        byte[] dataSend = new byte[sendbuf.Length + 2];


                        Array.Copy(sendbuf, 0, dataSend, 0, sendbuf.Length);


                        byte[] ssdata_Crc = CRC16Helper.CRC16_a(sendbuf);
                        //int ssdata_Crcint = ssdata_Crc[0] + ssdata_Crc[1] * 256;

                        dataSend[0 + sendbuf.Length] = ssdata_Crc[1];

                        dataSend[1 + sendbuf.Length] = ssdata_Crc[0];

                        if (not_need_huifu == 1)
                        {
                            prod_comm_obj.OP_s.SP.Write(dataSend, 0, dataSend.Length);

                            Thread.Sleep(80);


                            prod_comm_obj.OP_s.SP.Write(dataSend, 0, dataSend.Length);
                        }


                        tempStr = "";
                        for (int i = 0; i < dataSend.Length; i++)
                        {
                            tempStr += dataSend[i].ToString("X2") + " ";

                        }


                    }


                    if (not_need_huifu == 1)
                    {

                        break;


                    }


                    if (is_in_auto_jiaozhuan_ing_t == 1 && G_is_Run1_or_Pause2_or_Stop0 == 0)
                    {


                        break;

                    }

                    if(is_scan_packet==1&& G_pasue_scan == 1)
                    {


                        break;

                    }

                    bool is_recv_oked = prod_comm_obj.AutoResetEvent1.WaitOne(500 + 8 * prod_comm_obj.recv_length_for_delay);//Sleep(70+6* prod_comm_obj.recv_length_for_delay)还是偶尔分包,改为Sleep(70+8* prod_comm_obj.recv_length_for_delay)后正常:

                    //MessageBox.Show(is_recv_oked.ToString());

                    if (is_recv_oked && prod_comm_obj.recv_ok1 == 1&& prod_comm_obj.recv_bytes.Length>0)
                    {
                        ret_data.AddRange(prod_comm_obj.recv_bytes);
                        

                        break;
                    }
                    else
                    {
                        is_recv_fail_count++;

                    }
                        //只有最终重试发送且提示发送失败时的才记录,recv_ok1==0时不记录

                        System.Threading.Thread.Sleep(240 + 8 * prod_comm_obj.recv_length_for_delay);//Sleep(70+6* prod_comm_obj.recv_length_for_delay)还是偶尔分包,改为Sleep(70+8* prod_comm_obj.recv_length_for_delay)后正常:

                }

            }

            if (is_recv_fail_count>=(max_resend_1-1))
            {
                //只有最终重试发送且提示发送失败时的才记录:
                MuNiuMaLib.fvdou_append_error_to_log_txtH("SP_DataReceived1 err", " send or recv not ok:"+ tempStr + " \r\n");

            }

            return ret_data;


        }


        public List<byte> write_prod(string cmd_name, int is_in_auto_jiaozhuan_ing_t,int modbus_reg_addr,int val)
        {

            prod_comm_obj.recv_length_for_delay = 1;

            List<byte> ret_dat = send_data_to_prod((byte)G_jiaozhun_canshuo_input_t.prod_addr, cmd_name, 0x06, new byte[] {

            (byte)((modbus_reg_addr>>8)&0xff),
            (byte)((modbus_reg_addr)&0xff),


            (byte)((val>>8)&0xff),
            (byte)((val)&0xff)


            }, is_in_auto_jiaozhuan_ing_t,0,0,0);


            return ret_dat;

        }


        public List<byte> read_prod(string cmd_name, int is_in_auto_jiaozhuan_ing_t, int modbus_reg_addr)
        {

            prod_comm_obj.recv_length_for_delay = 1;

            List<byte> ret_dat = send_data_to_prod((byte)G_jiaozhun_canshuo_input_t.prod_addr, cmd_name, 0x03, new byte[] {

            (byte)((modbus_reg_addr>>8)&0xff),
            (byte)((modbus_reg_addr)&0xff),


            (byte)(0),
            (byte)(1)


            }, is_in_auto_jiaozhuan_ing_t,0,0, 0);


            return ret_dat;

        }


 

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐