大家好,我需要做一个application,去读取Modbus协议端slave PLC 的寄存器的值。 效果是: Tab1 里面有一个datagridview区显示Holding Register 的值,Tab2 里面有一个datagridview去显示InputRegister的值...就这样一共4个tab.
还有,我怎么才能让程序持续的读取寄存器的值呢—,现在是读一次之后连接就断开了,怎么才能持续保持PLC于软件的时刻连接呢——-
请问哪位高人指点下,我怎么可以同步的读取所有tab里面值,这样就可以任意在不同tab之间转换区查看寄存器的值。请大侠们给点建议啊被困了好久啦啦!
感激不尽啊!!
DataGridViewModbus 

解决方案 »

  1.   

    可以分批读到4个DataTable中,再分别与DataGridView绑定,就可以显示了。尽量不要直接修改DataGridView。至于为什么连接会断,串口连接是由应用程序控制的,检查你的程序。
    可以先用“串口调试工具”调试
      

  2.   


    谢谢您的回复,我现在的情况是必须对datagridview操作了,把值放到某一列作为整个表的一部分。我指的会断是因为没有thread 或者timer的缘故,系统不会自动读取,只能我每次按一下button它读一下.我想我需要添加thread...但是自己对thread 不懂怎么用...谢谢啦
      

  3.   

    如果寄存器值实时变化的话,那么一般是用Timer读的
    否则一次读完就行
      

  4.   


    多谢,那您能不能给些Timer用法的例子或者材料,我应该怎么设置timer,大概思路如何设定timer 呢。 它跟我的badurate是不是有关系,是不是每次读完所有值之后,一定时间之后继续循环读。如何确定这段时间的长短呢...多谢了。 
      

  5.   


    多谢,那您能不能给些Timer用法的例子或者材料,我应该怎么设置timer,大概思路如何设定timer 呢。 它跟我的badurate是不是有关系,是不是每次读完所有值之后,一定时间之后继续循环读。如何确定这段时间的长短呢...多谢了。 
    vs中有timer组件,        private void button4_Click(object sender, EventArgs e)
            {
                timer1.Enabled = false;
                timer1.Interval = 5000;
                timer1.Enabled = true;
            }        private void timer1_Tick(object sender, EventArgs e)
            {
                Console.WriteLine("read data from com port");
            }
      

  6.   


    多谢,那您能不能给些Timer用法的例子或者材料,我应该怎么设置timer,大概思路如何设定timer 呢。 它跟我的badurate是不是有关系,是不是每次读完所有值之后,一定时间之后继续循环读。如何确定这段时间的长短呢...多谢了。 
    vs中有timer组件,        private void button4_Click(object sender, EventArgs e)
            {
                timer1.Enabled = false;
                timer1.Interval = 5000;
                timer1.Enabled = true;
            }        private void timer1_Tick(object sender, EventArgs e)
            {
                Console.WriteLine("read data from com port");
            }多谢回复,我觉得需要是很可能是thread timer和thread 有什么区别吗—。能否指点下,如何使用thread...急救啊啊
      

  7.   

    事实上我觉得你应该用Timer。
    Enabled=true     启动计时器
    Interval=??      设置读取周期,单位毫秒。与串口波特率无关
    这两个属性可以代码实现,也可以设计器中设置。读取周期根据寄存器更新频率有关。
    寄存器读取代码写在timer1_Tick方法中Timer比thread简单,资料到处都是。直接做实验好过你这样的研究
      

  8.   


    谢谢回复,
    我自己是一直在一边编写程序,一边测试。 我原本是在一个函数里读取寄存器值得,要是用timer的话我觉得只要调用这个函数就可以了吧。 但是一直得到一个问题关于port.open().
    我的函数是这样的,麻烦你稍微看下
      public void ModbusSerialMasterReadRegisters()
            {            SerialPort port = new SerialPort(ComBox.Text);
                // configure serial port and open port 
                port.BaudRate = Convert.ToInt16(BaudBox.Text.ToString());
                port.DataBits = 8;
                port.Parity = Parity.None;
                port.StopBits = StopBits.One;
                //set a new Modbus RTU master 
                Modbus.Device.ModbusSerialMaster master = Modbus.Device.ModbusSerialMaster.CreateRtu(port);
                port.Open();
                byte slaveId = Convert.ToByte(SlaveID2.Text.ToString());
                ushort startAddress = 0;
                ushort numRegisters = 125;
                if (!port.IsOpen)
                {
                    port.Open();
                    #region read value to datagridview 
                }
                else
                {
               read value to datagridview 
                }
     
    private void timer1_Tick_1(object sender, EventArgs e)
           { 
               ModbusSerialMasterReadRegisters();
       
               }能否看下,为什么每次连接timer interval 之后, 就报错port.open()。难道不是应该在1000ms之后再次读取数据吗—。 多谢!
      

  9.   


    port.Open();
    byte slaveId = Convert.ToByte(SlaveID2.Text.ToString());
    ushort startAddress = 0;
    ushort numRegisters = 125;
    if (!port.IsOpen)
    {
         port.Open();  //前面已经打开过了,如果前面没有打开,这里也不会打得开
         #region read value to datagridview 
    }
    else
    {
        //read value to datagridview 
    }你目前在ModbusSerialMasterReadRegisters()方法中写的代码都不应该在timer1_Tick_1中出现,可以在Form_Load事件处理方法、某个按钮的Click事件处理方法、或者其它地方,总之,这些串口、Modbus对象的准备工作应该在正式通讯完成。
    至于timer1_Tick_1中的代码很简单,只管读取寄存器、处理读取到的数据。
    前提是要保证Timer有效前(Enable=true),串口已经正常打开!!!
    另外,最后结束读取寄存器时,要先禁止Timer(Timer的Enable=false),然后关闭串口(port.Close()),顺序不能错。你这里的错误: 串口不允许重复打开,而Timer是定时触发的,你在Timer中试图不停地打开串口,当然报错
      

  10.   


    我不太明白你说的那个顺序,是不是先打开串口,之后Timer enable,之后timer interval, 之后禁止timer,之后读取数值,之后关闭串口——?还有我把那个函数放到button click 里面,是所有的吗,包括参数收集的准本工作,还有读取处理数据呢—还是只要准备,读取的在timer_Tick_1里面就ok. 还有 那个timer enable 和port 开关应该在那个函数里面——我改了自己的程序,现在跟自己的PLC接上之后没死机,或者报错说port 关闭。。还有我怎么知道自己现在available 的串口是哪个呢—如何查看...
    多谢,上了2天课程,没来得及回复
      

  11.   


    我不太明白你说的那个顺序,是不是先打开串口,之后Timer enable,之后timer interval, 之后禁止timer,之后读取数值,之后关闭串口——?还有我把那个函数放到button click 里面,是所有的吗,包括参数收集的准本工作,还有读取处理数据呢—还是只要准备,读取的在timer_Tick_1里面就ok. 还有 那个timer enable 和port 开关应该在那个函数里面——我改了自己的程序,现在跟自己的PLC接上之后没死机,或者报错说port 关闭。。还有我怎么知道自己现在available 的串口是哪个呢—如何查看...
    多谢,上了2天课程,没来得及回复请问楼上的看到我的问题了吗..我还是没有解决这个问题...多谢了