I am working on modbus protocol in C#. I am able to send a single request and get a response from it. I am using a DataReceivedHandler to read from incoming port
public ModBusEngine()
{
//serial port settings and opening it
port.ReadTimeout = 500;
port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
port.Open();
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
//port.ReadTimeout = 200;
// send request and waiting for response
// the request needs: slaveId, dataAddress, registerCount
Thread.Sleep(200);
Console.WriteLine("Bytes recieved are " + port.BytesToRead);
try
{
receivedBytes = port.BaseStream.Read(buffer, 0, (int)buffer.Length);
var receiveData = BitConverter.ToString(buffer, 0, receivedBytes);
var finalData = receiveData.Replace("-", "");
new Thread(() =>
{
SaveData(finalData);
}).Start();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
}
I am writing to a port in another method
private void ModbusMethod(Iterations iterations)
{
Console.WriteLine("Starting Modbuss Scheduling data...");
try
{
var items = new byte[]{ Convert.ToByte(iterations.hex), 0x03, 0x00, 0x00, 0x00, 0x03 };
//iterations.hex is device id
var crc = BitConverter.GetBytes(ModRTU_CRC(items, items.Length)); //ComputeChecksum(items);
var dataItems = items.Concat(crc).ToArray();
port.BaseStream.Write(dataItems, 0, dataItems.Length);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
}
I am successfully able to send are receive a response.
What I want to do now?
There are multiple registers from which I can get data from the device. These addresses are not completely in sequential order. For example, see below pictures
As shown in the above images addresses from 0000 to 0006 are in a sequence then the register is skipped 3 times and the next address is 0009 after that it's again sequential till the address 003A. Then again registers are skipped and start from 0100 to 012E in sequence.
I only want to read certain registers i.e. from 0000 to 0002 than from 000E to 003A and finally from 0100 to 012E. One way is to send the frame one by one and then do the needful with the data. But I want to send them in a single request.
I want to do the following.
Combining the request and send it in one frame
var req1 = new byte[]{ Convert.ToByte(iterations.hex), 0x03, 0x00, 0x00, 0x00, 0x03 };// msn and meter idvar req2 = new byte[]{ Convert.ToByte(iterations.hex), 0x03, 0x00, 0x0E, 0x00, 0x46 }; // energy valuesvar req3 = new byte[]{ Convert.ToByte(iterations.hex), 0x03, 0x01, 0x00, 0x00, 0x48 };// energy values other
var items = req1.concat(req2).concat(req3);
I am not sure that this approach will work or not. I don't know how to do it but I don't want to send the frame one by one as the handler is continuously reading the port.
- Collect all the requests data and then save the data.
Any help would be highly appreciated.


0x03. It supports contiguous read. The only two choices are : 1. read a bulk data from 0x0000~0x012E , or read different areas multiple times. I will write an answer for suggestion. - Louis Go01 03 00 00 00 61which includesmeter msntoL3 reactive energy half valueif I send the frame01 03 00 00 00 62themeterstopsresponding- Moeez