在Modbus通信中轮询期间指示故障 [英] To indicate the fault during polling in Modbus communication

查看:183
本文介绍了在Modbus通信中轮询期间指示故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,



如果我从奴隶那里收到的数据包含数据,那么任何人都可以在多个设备的轮询过程中告诉我,1,1被认为是某些设备的故障状况&如果它的0,0,0,0被认为是该特定设备的健康状况。由于遵循的通信协议是RS485,我将轮询到247个设备。在这种情况下,我每800毫秒轮询每个设备以发送查询&接收奴隶的回答。一旦收到的数据为零就无所事事。如果数据中包含1,则执行某些操作而不会导致任何延迟或独立于轮询过程工作。我面临的问题是我已经启动了一个用于轮询每个设备的计时器。此外,如果数据包含基于数据中存在的索引1的1,我正在改变该特定按钮的背景颜色,连续显示为对此闪烁,也使用了计时器。所以他们没有独立工作。闪烁计时器取决于轮询计时器以执行其任务。我如何实现这个目标..?



提前致谢。



先生我已经删除了所有的我用过的计时器&我只使用连续运行它的线程但仍然存在更改按钮返回颜色事件的问题。这是因为向数据库输入数据。按钮背变色事件不统一,如何统一发生。



编辑后的代码如下所示:



Hi all,

Can anybody tell me during polling process of multiple devices if the data that i receive from the slaves if it contains data i.e., 1,1,1,1 which is considered to be the fault condition of some device & if its 0,0,0,0 it is considered to be healthy condition of that particular device. Since communication protocol followed is RS485 i will be polling upto 247 devices. In such a condition i am polling each device every 800ms for sending query & receiving answer from slave. Once the received data has zero do nothing & if data has 1's in it, do something without causing any delay or work independently of the polling process. The problem what i am facing is i have started a timer for polling each device & also if the data contains 1's based on the index of 1 present in the data i am changing the backcolor of that particular button continuously appear as if its flashing for this also a timer is used. So they are not working independently. The flashing timer depends on the polling timer for performing its task. How do i achieve this..?

Thanks in advance.

Sir i have removed all the timers i had used & i am using only threads running it continuously but still the issue exists in the changing the button back color event. Is this because of entering data to database. The button back color changing event is not uniform so how to make that happen uniformly.

The edited code is shown below:

#region Start and Stop Procedures
        private void StartPoll()
        {            
            pollCount = 0;
            slaves = 0;
            MyPollThread = new Thread(new ThreadStart(MyPollcallback));
            if (mb.Open(cboPort.SelectedItem.ToString(), Convert.ToInt32(cboBaud.SelectedItem.ToString()),
                8, Parity.None, StopBits.One))
            {
                //Disable double starts:
                btnOk.Enabled = false;
                btnCancel.Enabled = true;
                //Set polling flag:
                isPolling = true;
                MyPollThread.Start();     
            }
            MainWindow frmParent = (MainWindow)this.MdiParent;
            frmParent.stswarning.Text = mb.modbusStatus;
        }

      private void MyPollcallback()
        {
            while (true)
            {
                if (slaves == btn.Length)
                {
                    slaves = 0;
                    // Array.Clear(errorIndexOne, 0, errorIndexOne.Length);
                    Array.Clear(errorIndexTwo, 0, errorIndexTwo.Length);
                    Array.Clear(errorIndexZero, 0, errorIndexZero.Length);
                }               
                PollFunction();
                Thread.Sleep(/* milliseconds to wait */ 250); // Check every 250ms.
            }
        }

        private void StopPoll()
        {
            if (isPolling)  // check if polling was enabled
            {
                isPolling = false;              
                MyPollThread.Abort();
                mb.Close();
                btnOk.Enabled = true;
                btnCancel.Enabled = false;              
                for (int n = 0; n < btn.Length; n++)
                {
                    btn[n].BackColor = Color.LimeGreen;
                }

            }
            MainWindow frmParent = (MainWindow)this.MdiParent;
            frmParent.stswarning.Text = mb.modbusStatus;
        }
        #endregion


        #region Poll Function
        public bool testflag = false;
        private void PollFunction()
        {
            //Update GUI:  
            DoGUIClear();
            pollCount++;

            //Create array to accept read values: 
            int[] disablebtnindx = new int[72];
            ushort pollStart;
            ushort pollLength;
            pollStart = 0;      
 
            try
            {
                SID = Convert.ToByte(slaveaddress[slaves]);
                add = slaves;
                
            }
            catch (Exception ex)
            {
                slaves = 0;                
            }

            pollLength = Convert.ToUInt16(polllength[slaves]);           
            short[] slaveData =  new short[pollLength];

            //Read registers and display data in desired format: 
            try
            {
                while (!mb.SendFc3(SID, pollStart, pollLength, ref slaveData)) ;
            }

            catch (Exception err)
            {
                DoGUIStatus("Error in modbus read: " + err.Message);
            }
            slaves++;
                               
            dtButtonName = ReturnDataTable("select distinct BtnName, BtnIndex from Configuration where AnnName='" + deviceName[add] + "'");
            int[] match = new int[dtButtonName.Rows.Count];
            if (dtButtonName.Rows.Count >= 0)
            {
                //Check for the same btn text Name,if it is true change the colour
                for (int i = 0; i < dtButtonName.Rows.Count; i++)
                {
                    match[i] = Convert.ToInt32(dtButtonName.Rows[i]["BtnIndex"].ToString());
                }
            }
            
                if (slaveData.All(s => s == 0))
                   {
                       errorIndexZero[add] = SID;
                       this.Invoke(new EventHandler(ResetChangeBtnColor));
                   }
               
                else if (slaveData.Any(s => s == 1))
                   {
                       errorList.Clear();                      
                       Thread MyThread = new Thread(new ThreadStart(MyCallbackFunction));     
                       errorIndexOne[add] = SID;
                       testflag = true;                     
                       for (int i = 0; i < pollLength; i++)
                       {                          
                           if (slaveData[i] == 1) errorList.Add(i);                           
                       }

                       if (Enumerable.SequenceEqual(errorList, match))
                       {
                          
                       }
                       else
                       {
                           if (!bgWorker.IsBusy)
                           {                             
                               MyThread.Start();
                           }
                       }                       
                }

                else if (slaveData.Any(s => s == 2))
                 {
                     errorIndexTwo[add] = SID;
                     for (int i = 0; i < pollLength; i++)
                     {                       
                         if (slaveData[i] == 2) errorList.Add(i);
                     }

                     if (Enumerable.SequenceEqual(errorList, match))
                     {
                     }
                     else
                     {
                         this.Invoke(new EventHandler(AcceptChangeBtnColor));
                     }        
                 }       
            }       
        #endregion

         int counter = 0;
        private void MyCallbackFunction()
        {          
            counter++;
            Dataloggingfunction();          
            for (int n = 0; n < btn.Length; n++)
            {
                if (btn[n].Tag.ToString() == Convert.ToString(errorIndexOne[n]))
                //if (errorList.Contains(n))
                {
                    if (counter % 2 == 0)
                    {
                        btn[n].BackColor = Color.Red;
                    }
                    else
                    {
                        btn[n].BackColor = Color.LimeGreen;
                    }
                }
            }
        }

        private void Dataloggingfunction()
        {
             if (faultsRecorded.Count != errorList.Count)
             {

                 DataTable source = ReturnDataTable("select RowColumns from AnnunciatorsDescription where  AnnunName='" + btn[add].Text + "'");

                 if (source.Rows.Count > 0)
                 {
                     string descriptionName = source.Rows[0]["RowColumns"].ToString();

                     string[] splitRows = descriptionName.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                     string[] splitColumns = splitRows[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                     windowdescription = new string[splitRows.Length * splitColumns.Length];

                     int count = 0;
                     for (int i = 0; i < splitRows.Length; i++)
                     {
                         string[] splitColumns1 = splitRows[i].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                         for (int index = 0; index < splitColumns.Length; index++)
                         {
                             windowdescription[count] = splitColumns1[index];
                             count++;
                         }
                     }
                 }

                 StringBuilder sb = new StringBuilder();           
                 var diff = errorList.Except<int>(faultsRecorded).ToList<int>();
                 for (int n = 0; n < diff.Count(); n++) //diff.Count()
                 {                    
                     sb.AppendLine(windowdescription[diff[n]].ToString()).Append(",");                  
                 }
                 faultsRecorded.AddRange(diff);
                 if (!bgWorker.IsBusy)
                 {
                     bgWorker.RunWorkerAsync(sb.ToString());
                 }               
              }            
        }          
 
    void Bgupdater_DoWork(object sender, DoWorkEventArgs e)
        {           
            var message = e.Argument as string;
            LogMessage(message);
        }
        
        private void LogMessage(string slaves)
        {
            if (!string.IsNullOrEmpty(slaves))
            {
                List<string> slaveList = slaves.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();

                foreach (string slave in slaveList)
                {
                    if (!string.IsNullOrEmpty(slave))
                    {
                        string str = "insert into ErrorLog values('" + btn[add].Text + "','" + slave + "','" + DateTime.Now.ToShortDateString() + "','" + DateTime.Now.ToShortTimeString() + "')";
                        DataBaseHandling(str);
                    }
                }
            }
        }</string></int></int>

推荐答案

请摆脱计时器并使用单独的线程,我在对这个问题的评论中解释的原因。


-SA
Please get rid of the timers and use separate threads, by the reasons I explained in my comments to the question.

—SA


这篇关于在Modbus通信中轮询期间指示故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆