Skip to content

Commit 0cbccf8

Browse files
committed
feat: Service 기능 구현 중
- ReadCoils - ReadDiscreteInputs - ReadHoldingRegisters - ReadInputRegisters - WriteSingleCoil - WriteSingleRegister - WriteMultipleCoils 구현 완료 - Packet 구조 변경 - 읽기 쓰기 멀티에 따라 구조 변화 네임스페이스 및 클래스 메서드 추가/변경 여러 파일의 네임스페이스가 `ModBusMaster.Data`에서 `ModBusSlave.Data`로 변경되었습니다. `RequestPacket` 클래스에 멀티 코일 및 레지스터 쓰기를 위한 생성자와 멀티 쓰기 프레임을 생성하는 메서드가 추가되었습니다. `RequestPacketBuilder` 클래스에 `SetByteCount` 및 `SetWriteData` 메서드가 추가되었습니다. `ResponsePacket` 클래스에 읽기 및 쓰기 프레임을 생성하는 메서드가 추가되었습니다. `SerialPortConnector` 클래스에 `VirtualDevice` 및 `Service` 객체가 추가되었습니다. `Service` 클래스의 `Response` 메서드와 각 기능 코드에 대한 메서드가 `RequestPacket`을 매개변수로 받도록 변경되었습니다. `VirtualDevice` 클래스의 네임스페이스가 `ModBusSlave`에서 `ModBusSimSlave`로 변경되었습니다.
1 parent 3ddf741 commit 0cbccf8

File tree

7 files changed

+244
-72
lines changed

7 files changed

+244
-72
lines changed

Data/PacketHelpers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace ModBusMaster.Data
1+
namespace ModBusSlave.Data
22
{
33
internal static class PacketHelpers
44
{

Data/RequestPacket.cs

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
namespace ModBusMaster.Data
1+
namespace ModBusSlave.Data
22
{
33
class RequestPacket
44
{
55
private byte[] _frame;
66
private byte _slaveAddr;
77
private byte _functionCode;
88
private byte[] _data;
9+
private byte _byteCount;
10+
private byte[] _writeData;
911
private byte[] _crc;
1012

1113
private RequestPacket(byte slaveAddr, byte functionCode, byte[] data)
@@ -19,18 +21,47 @@ private RequestPacket(byte slaveAddr, byte functionCode, byte[] data)
1921
Array.Copy(_frame, _frame.Length - 2, _crc, 0, 2);
2022
}
2123

22-
public RequestPacket(byte[] frame)
24+
// 멀티 코일 & 레지스터 쓰기를 위한 생성자
25+
private RequestPacket(byte slaveAddr, byte functionCode, byte[] data, byte byteCnt, byte[] writeData)
2326
{
24-
_frame = frame;
25-
_slaveAddr = frame[0];
26-
_functionCode = frame[1];
27-
_data = new byte[frame.Length - 5];
28-
Array.Copy(frame, 2, _data, 0, _data.Length);
27+
_slaveAddr = slaveAddr;
28+
_functionCode = functionCode;
29+
_data = data;
30+
_byteCount = byteCnt;
31+
_writeData = writeData;
32+
33+
_frame = GetMultiWriteFrame();
2934
_crc = new byte[2];
30-
Array.Copy(frame, frame.Length - 2, _crc, 0, 2);
35+
Array.Copy(_frame, _frame.Length - 2, _crc, 0, 2);
36+
3137
}
3238

33-
public byte[] GetFrame()
39+
public RequestPacket(byte[] frame)
40+
{
41+
if (frame[1] == 0x0F || frame[1] == 0x10)
42+
{
43+
_slaveAddr = frame[0];
44+
_functionCode = frame[1];
45+
_data = new byte[frame.Length - 7];
46+
Array.Copy(frame, 2, _data, 0, _data.Length);
47+
_byteCount = frame[frame.Length - 4];
48+
_writeData = new byte[frame.Length - 7 - 1];
49+
Array.Copy(frame, 3 + _data.Length, _writeData, 0, _writeData.Length);
50+
_crc = new byte[2];
51+
Array.Copy(frame, frame.Length - 2, _crc, 0, 2);
52+
}
53+
else
54+
{
55+
_slaveAddr = frame[0];
56+
_functionCode = frame[1];
57+
_data = new byte[frame.Length - 5];
58+
Array.Copy(frame, 2, _data, 0, _data.Length);
59+
_crc = new byte[2];
60+
Array.Copy(frame, frame.Length - 2, _crc, 0, 2);
61+
}
62+
}
63+
64+
private byte[] GetFrame()
3465
{
3566
byte[] frame = new byte[1 + 1 + _data.Length + 2]; // SlaveAddr + FunctionCode + Data + CRC
3667

@@ -45,6 +76,24 @@ public byte[] GetFrame()
4576
return frame;
4677
}
4778

79+
private byte[] GetMultiWriteFrame()
80+
{
81+
byte[] frame = new byte[1 + 1 + _data.Length + 1 + _writeData.Length + 2]; // SlaveAddr + FunctionCode + Data + CRC
82+
83+
frame[0] = _slaveAddr;
84+
frame[1] = _functionCode;
85+
Array.Copy(_data, 0, frame, 2, _data.Length);
86+
87+
frame[2 + _data.Length] = _byteCount;
88+
Array.Copy(_writeData, 0, frame, 3 + _data.Length, _writeData.Length);
89+
90+
ushort crc = PacketHelpers.CalcCRC(frame, 0, frame.Length - 2);
91+
frame[frame.Length - 2] = (byte)(crc & 0xFF);
92+
frame[frame.Length - 1] = (byte)(crc >> 8);
93+
94+
return frame;
95+
}
96+
4897

4998
public byte[] Frame
5099
{
@@ -82,6 +131,8 @@ public class RequestPacketBuilder
82131
private byte _slaveAddr;
83132
private byte _functionCode;
84133
private byte[] _data;
134+
private byte _byteCount;
135+
private byte[] _writeData;
85136

86137
public RequestPacketBuilder SetSlaveAddr(byte slaveAddr)
87138
{
@@ -101,9 +152,23 @@ public RequestPacketBuilder SetData(byte[] data)
101152
return this;
102153
}
103154

155+
public RequestPacketBuilder SetByteCount(byte byteCount)
156+
{
157+
_byteCount = byteCount;
158+
return this;
159+
}
160+
161+
public RequestPacketBuilder SetWriteData(byte[] writeData)
162+
{
163+
_writeData = writeData;
164+
return this;
165+
}
166+
104167
public RequestPacket Build()
105168
{
106-
return new RequestPacket(_slaveAddr, _functionCode, _data);
169+
return _functionCode == 0x0F || _functionCode == 0x10 ?
170+
new RequestPacket(_slaveAddr, _functionCode, _data, _byteCount, _writeData) :
171+
new RequestPacket(_slaveAddr, _functionCode, _data);
107172
}
108173
}
109174
}

Data/ResponsePacket.cs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace ModBusMaster.Data
1+
namespace ModBusSlave.Data
22
{
33
class ResponsePacket
44
{
@@ -16,7 +16,18 @@ private ResponsePacket(byte slaveArr, byte functionCode, byte dataLength, byte[]
1616
_dataLength = dataLength;
1717
_data = data;
1818

19-
_frame = GetFrame();
19+
_frame = GetReadFrame();
20+
_crc = new byte[2];
21+
Array.Copy(_frame, _frame.Length - 2, _crc, 0, 2);
22+
}
23+
24+
private ResponsePacket(byte slaveArr, byte functionCode, byte[] data)
25+
{
26+
_slaveAddr = slaveArr;
27+
_functionCode = functionCode;
28+
_data = data;
29+
30+
_frame = GetWriteFrame();
2031
_crc = new byte[2];
2132
Array.Copy(_frame, _frame.Length - 2, _crc, 0, 2);
2233
}
@@ -33,8 +44,9 @@ public ResponsePacket(byte[] frame)
3344
Array.Copy(frame, 3 + _dataLength, _crc, 0, 2);
3445
}
3546

36-
public byte[] GetFrame()
47+
private byte[] GetReadFrame()
3748
{
49+
3850
byte[] frame = new byte[1 + 1 + 1 + _data.Length + 2]; // SlaveAddr + FunctionCode + DataLength + Data + CRC
3951

4052
frame[0] = _slaveAddr;
@@ -49,6 +61,20 @@ public byte[] GetFrame()
4961
return frame;
5062
}
5163

64+
private byte[] GetWriteFrame()
65+
{
66+
byte[] frame = new byte[1 + 1 + _data.Length + 2]; // SlaveAddr + FunctionCode + Data + CRC
67+
frame[0] = _slaveAddr;
68+
frame[1] = _functionCode;
69+
Array.Copy(_data, 0, frame, 2, _data.Length);
70+
71+
ushort crc = PacketHelpers.CalcCRC(frame, 0, frame.Length - 2);
72+
frame[frame.Length - 2] = (byte)(crc & 0xFF);
73+
frame[frame.Length - 1] = (byte)(crc >> 8);
74+
75+
return frame;
76+
}
77+
5278
public byte[] Frame
5379
{
5480
get { return _frame; }
@@ -118,7 +144,9 @@ public ResponsePacketBuilder SetData(byte[] data)
118144

119145
public ResponsePacket Build()
120146
{
121-
return new ResponsePacket(_slaveAddr, _functionCode, _dataLength, _data);
147+
return _functionCode == 0x05 || _functionCode == 0x06 || _functionCode == 0x0F || _functionCode == 0x10 ?
148+
new ResponsePacket(_slaveAddr, _functionCode, _data) :
149+
new ResponsePacket(_slaveAddr, _functionCode, _dataLength, _data);
122150
}
123151
}
124152
}

SerialPortConnector.cs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
using ModBusMaster.Data;
1+
using ModBusSimSlave;
2+
using ModBusSlave.Data;
23
using System.Diagnostics;
34
using System.IO.Ports;
45

56
namespace ModBusSlave
67
{
78
public class SerialPortConnector
89
{
9-
SerialPort seriallPort = new SerialPort();
10+
private SerialPort seriallPort = new();
11+
private VirtualDevice device = new(1, 10, 10);
12+
private Service service;
1013

1114
public SerialPortConnector()
1215
{
@@ -18,6 +21,15 @@ public SerialPortConnector()
1821
seriallPort.ReadTimeout = 500;
1922
seriallPort.WriteTimeout = 500;
2023
seriallPort.DataReceived += DataReceivedHandler;
24+
25+
device.InputRegisters[0] = Convert.ToUInt16(DateTime.Now.Year);
26+
device.InputRegisters[1] = Convert.ToUInt16(DateTime.Now.Month);
27+
device.InputRegisters[2] = Convert.ToUInt16(DateTime.Now.Day);
28+
device.InputRegisters[3] = Convert.ToUInt16(DateTime.Now.Hour);
29+
device.InputRegisters[4] = Convert.ToUInt16(DateTime.Now.Minute);
30+
device.InputRegisters[5] = Convert.ToUInt16(DateTime.Now.Second);
31+
32+
service = new Service(device);
2133
}
2234

2335
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
@@ -41,25 +53,15 @@ private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
4153
packet.Data.ToList().ForEach(e => Debug.Write($"{e} "));
4254
Debug.WriteLine("");
4355

44-
VirtualDevice device = new VirtualDevice(1, 10, 10);
45-
46-
device.InputRegisters[0] = Convert.ToUInt16(DateTime.Now.Year);
47-
device.InputRegisters[1] = Convert.ToUInt16(DateTime.Now.Month);
48-
device.InputRegisters[2] = Convert.ToUInt16(DateTime.Now.Day);
49-
device.InputRegisters[3] = Convert.ToUInt16(DateTime.Now.Hour);
50-
device.InputRegisters[4] = Convert.ToUInt16(DateTime.Now.Minute);
51-
device.InputRegisters[5] = Convert.ToUInt16(DateTime.Now.Second);
52-
53-
Service service = new Service(device, packet);
54-
ResponsePacket? response = service.Response();
56+
ResponsePacket? response = service.Response(packet);
5557

5658
if (response == null)
5759
{
5860
Debug.WriteLine("응답 데이터 없음");
5961
return;
6062
}
6163

62-
byte[] frame = response.GetFrame();
64+
byte[] frame = response.Frame;
6365
Debug.WriteLine("응답 데이터");
6466
frame.ToList().ForEach(e => Debug.Write($"{e} "));
6567
Debug.WriteLine("");

0 commit comments

Comments
 (0)