大家好, 我需要读取通过Modbus通讯的寄存器的值。 代码如下               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;
                port.Open();
                
                //set a new Modbus RTU master 
                Modbus.Device.ModbusSerialMaster master =            Modbus.Device.ModbusSerialMaster.CreateRtu(port);
                              //slave settings using ReadInputRegisters to read Modbus slave device's input register values
                byte slaveId = Convert.ToByte(SlaveID2.Text.ToString());
                ushort startAddress = 0;
                ushort numRegisters = 125;
               // handling the process of reading registers values  1-256 registers
                //every time can only read 125 registers. so dividing the reading into many times                ushort[] registers = master.ReadHoldingRegisters(slaveId, startAddress, numRegisters);   
                string itemString,itemString1, itemString2;
                for (int i = 0; i < numRegisters; i++)
                {  
                itemString = registers[i].ToString();
                for (int j = 0; j < numRegisters;j++ )
                {
                    if ((Convert.ToString(0 + i + 40001)) == dataGridView1.Rows[j].Cells[0].Value.ToString())
                    {
                        dataGridView1.Rows[j].Cells[4].Value = itemString;
                    }
                    }
             
                this.listBox1.Items.Add(itemString);
            }
问题是我下载的是NModbus 的Library,但是当我把numRegidters 改到大于125时系统就说最大为125.。。请问有人知道怎么办才能读取255个寄存器的值吗—— 万分感谢,十万火急...C#Modbus NModbus numRegisters

解决方案 »

  1.   

    分批读取:ushort[] registers1 = master.ReadHoldingRegisters(slaveId, 0, 125);
    ushort[] registers2 = master.ReadHoldingRegisters(slaveId, 125, 125);
    ushort[] registers3 = master.ReadHoldingRegisters(slaveId, 250, 6);
      

  2.   

    你也可以把registers定义成二维数组
    事实上,许多modbus的slave对一次性读取的寄存器数量有限制
      

  3.   


    谢谢xky96,
    我已经试过了分批读取。 但是会得到一些错误: 这里我需要把得到的数值放到datagridview第四列。所以需要比较。                ushort[] registers = master.ReadHoldingRegisters(slaveId, startAddress, numRegisters);   
                    string itemString,itemString1, itemString2;
                    for (int i = 0; i < numRegisters; i++)
                    {  
                    itemString = registers[i].ToString();
                    for (int j = 0; j < numRegisters;j++ )
                    {
                        if ((Convert.ToString(0 + i + 40001)) == dataGridView1.Rows[j].Cells[0].Value.ToString())
                        {
                            dataGridView1.Rows[j].Cells[4].Value = itemString;
                        }
                        }
                 
                    this.listBox1.Items.Add(itemString);
                }              
                            ushort[] registers1 = master.ReadHoldingRegisters(slaveId, 125, numRegisters);                for (int i = 0; i < numRegisters; i++)
                    {
                        itemString1 = registers1[i].ToString();                    for (int j = 0; j < dataGridView1.Rows.Count; j++)
                        {
                            
                                if ((Convert.ToString(0 + i + 40001)) == dataGridView1.Rows[j].Cells[0].Value.ToString())
                                {
                                    dataGridView1.Rows[j].Cells[4].Value = itemString1;
                                }
                                                }                    this.listBox1.Items.Add(itemString1);
                    }                ushort[] registers2 = master.ReadHoldingRegisters(slaveId, 250, 6);
                    for (int i = 0; i < 6; i++)
                    {
                        itemString2 = registers2[i].ToString();
                        for (int j = 250; j < (6+ 250); j++)
                        {
                            if ((Convert.ToString(151 + i + 40001)) == dataGridView1.Rows[j].Cells[0].Value.ToString())
                            {
                                dataGridView1.Rows[j].Cells[4].Value = itemString2;
                            }
                        }                    this.listBox1.Items.Add(itemString2);
                    }
                  
    总之就是
    Exception of type 'Modbus.SlaveException' was thrown.
    Function Code: 131
    Exception Code: 1 - The function code received in the query is not an allowable action for the server (or slave). This may be because the function code is only applicable to newer devices, and was not implemented in the unit selected. It could also indicate that the server (or slave) is in the wrong state to process a request of this type, for example because it is unconfigured and is being asked to return register values.
    请问您知道这是什么意思吗—,这是什么样的错误呢。 多谢了
      

  4.   

    原因很多:
    可能是modbus地址(slaveId)错误,slave设备没有配置好?;
    或者起始地址startAddress错误(首地址可能必须1开始);
    也可能一次性读取的寄存器数目小于125;
    读取地址超出slave端可读寄存器地址范围?
      

  5.   


    我是用Modbus Slave 这个软件暂时代替PLC功能的,用 VSPD创建虚拟接口。我不太明白一次性读取寄存器数目125,是指从40001-40125吗,我的PLC有些寄存器不存在,例如40004,40005.这样的话读取的时候会只读存在的寄存器125个呢还是按照顺序一个个都读取,如果寄存器不存在就不会有任何输出—,就像我设置寄存器数目125,但是实际读取的寄存器在我的application里只有100个...万分感谢,请给些指点。
      

  6.   

    先要了解手头的PLC,查下手册,哪些寄存器可读(有些可能是只写的,读这些寄存器肯定出错)
    125个寄存器是连续地址,中间不能间隔如果你要读的100个寄存器分散在不同区段,就要分批读
      

  7.   

    明白了,我现在已经可以读出255个寄存器的值了。但是我现在还有另一个问题,当我测试自己的软件时,那个slave 软件只能处在ReadHolding register或者ReadInput Register 或者01, 02.状态中的一个。而我需要读取所有寄存器的值,就是说slave 的状态必须是01,02,03,04 同时。这个我可以怎么测试呢,怎么才能让4种寄存器的值可以全部显示。希望你明白我说的什么意思。谢谢!
      

  8.   

    应该用不同方法读取吧,比如:ReadInputRegisters、ReadHoldingRegisters