如何在 C# 中访问 Modbus TCP/IP 寄存器 4XXXXX.1?



我需要访问那些寄存器 4XXXXX.1、4XXXXX.2 和 4XXXXX.3...等等

等等我尝试使用 modscan64,我只能在 XXXXX 中输入数字作为整数,我无法在寄存器中输入十进制地址。

这是我当前的读取寄存器的 C# 方法,当我尝试读取地址中的十进制数时出现异常。我正在使用EasyModbus库。

public int[] ReadHoldingRegisters(int startingAddress, int quantity)
{
if (debug) StoreLogData.Instance.Store("FC3 (Read Holding Registers from Master device), StartingAddress: "+ startingAddress+", Quantity: " +quantity, System.DateTime.Now);
transactionIdentifierInternal++;
if (serialport != null)
if (!serialport.IsOpen)
{
if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened");
}
if (tcpClient == null & !udpFlag & serialport == null)
{
if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.ConnectionException("connection error");
}
if (startingAddress > 65535 | quantity >125)
{
if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now);
throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 125");
}
int[] response;
this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal);
this.protocolIdentifier = BitConverter.GetBytes((int) 0x0000);
this.length = BitConverter.GetBytes((int)0x0006);
this.functionCode = 0x03;
this.startingAddress = BitConverter.GetBytes(startingAddress);
this.quantity = BitConverter.GetBytes(quantity);
Byte[] data = new byte[]{   this.transactionIdentifier[1],
this.transactionIdentifier[0],
this.protocolIdentifier[1],
this.protocolIdentifier[0],
this.length[1],
this.length[0],
this.unitIdentifier,
this.functionCode,
this.startingAddress[1],
this.startingAddress[0],
this.quantity[1],
this.quantity[0],
this.crc[0],
this.crc[1]
};
crc = BitConverter.GetBytes(calculateCRC(data, 6, 6));
data[12] = crc[0];
data[13] = crc[1];
if (serialport != null)
{
dataReceived = false;
bytesToRead = 5 + 2 * quantity;
//                serialport.ReceivedBytesThreshold = bytesToRead;
serialport.Write(data, 6, 8);
if (debug)
{
byte [] debugData = new byte[8];
Array.Copy(data, 6, debugData, 0, 8);
if (debug) StoreLogData.Instance.Store("Send Serial-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now);                 
}
if (SendDataChanged != null)
{
sendData = new byte[8];
Array.Copy(data, 6, sendData, 0, 8);
SendDataChanged(this);
}
data = new byte[2100];
readBuffer = new byte[256];
DateTime dateTimeSend = DateTime.Now;
byte receivedUnitIdentifier = 0xFF;
while (receivedUnitIdentifier != this.unitIdentifier & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout))
{
while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout))
System.Threading.Thread.Sleep(1);  
data = new byte[2100];
Array.Copy(readBuffer, 0, data, 6, readBuffer.Length);
receivedUnitIdentifier = data[6];
}
if (receivedUnitIdentifier != this.unitIdentifier)
data = new byte[2100];
else
countRetries = 0;
}
else if (tcpClient.Client.Connected | udpFlag)
{
if (udpFlag)
{
UdpClient udpClient = new UdpClient();
IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port);
udpClient.Send(data, data.Length-2, endPoint);
portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port;
udpClient.Client.ReceiveTimeout = 5000;
endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut);
data = udpClient.Receive(ref endPoint);
}
else
{
stream.Write(data, 0, data.Length-2);
if (debug)
{
byte [] debugData = new byte[data.Length-2];
Array.Copy(data, 0, debugData, 0, data.Length-2);
if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now);                  
}
if (SendDataChanged != null)
{
sendData = new byte[data.Length-2];
Array.Copy(data, 0, sendData, 0, data.Length-2);
SendDataChanged(this);
}
Console.WriteLine("The data I get is " + BitConverter.ToString(data));
data = new Byte[256];
int NumberOfBytes = stream.Read(data, 0, data.Length);
if (ReceiveDataChanged != null)
{
receiveData = new byte[NumberOfBytes];
Array.Copy(data, 0, receiveData, 0, NumberOfBytes);
if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now);
ReceiveDataChanged(this);
}
}
}
if (data[7] == 0x83 & data[8] == 0x01)
{
if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.FunctionCodeNotSupportedException("Function code not supported by master");
}
if (data[7] == 0x83 & data[8] == 0x02)
{
if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid");
}
if (data[7] == 0x83 & data[8] == 0x03)
{
if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid");
}
if (data[7] == 0x83 & data[8] == 0x04)
{
if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.ModbusException("error reading");
}
if (serialport != null)
{
crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data[8]+3), 6));
if ((crc[0] != data[data[8]+9] | crc[1] != data[data[8]+10])& dataReceived)
{
if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now);
if (NumberOfRetries <= countRetries)
{
countRetries = 0;
throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed");
}
else
{
countRetries++;
return ReadHoldingRegisters(startingAddress, quantity);
}
}
else if (!dataReceived)
{
if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now);
if (NumberOfRetries <= countRetries)
{
countRetries = 0;
throw new TimeoutException("No Response from Modbus Slave");
}
else
{
countRetries++;
return ReadHoldingRegisters(startingAddress, quantity);
}

}
}

response = new int[quantity];
for (int i = 0; i < quantity; i++)
{
byte lowByte;
byte highByte;
highByte = data[9+i*2];
lowByte = data[9+i*2+1];
data[9+i*2] = lowByte;
data[9+i*2+1] = highByte;
response[i] = BitConverter.ToInt16(data,(9+i*2));
}           
return (response);          
}

modbus 规范提供了一个寻址前缀。 4XXXXX 表示您需要联系持有寄存器。也就是说,您需要具有通常地址的功能 3(读取保持寄存器(,开头没有"4"。 但是,您写的是 4XXXXX.1 - 这样的记录通常说您需要使用地址 XXXXX 保存寄存器的位号 2

最新更新