Skip to content
This repository was archived by the owner on Jul 30, 2021. It is now read-only.

Commit 3ef5894

Browse files
committed
function code 02 and 03
1 parent 54537f3 commit 3ef5894

File tree

5 files changed

+90
-20
lines changed

5 files changed

+90
-20
lines changed

src/ModbusMessage.cpp

+50-12
Original file line numberDiff line numberDiff line change
@@ -132,28 +132,68 @@ ModbusRequest::ModbusRequest(uint8_t length) :
132132
_address(0),
133133
_byteCount(0) {}
134134

135-
ModbusRequest04::ModbusRequest04(uint8_t slaveAddress, uint16_t address, uint16_t byteCount) :
135+
ModbusRequest02::ModbusRequest02(uint8_t slaveAddress, uint16_t address, uint16_t numberCoils) :
136+
ModbusRequest(8) {
137+
_slaveAddress = slaveAddress;
138+
_functionCode = READ_DISCR_INPUT;
139+
_address = address;
140+
_byteCount = numberCoils / 8 + 1;
141+
add(_slaveAddress);
142+
add(_functionCode);
143+
add(high(_address));
144+
add(low(_address));
145+
add(high(numberCoils));
146+
add(low(numberCoils));
147+
uint16_t CRC = CRC16(_buffer, 6);
148+
add(low(CRC));
149+
add(high(CRC));
150+
}
151+
152+
size_t ModbusRequest02::responseLength() {
153+
return 5 + _byteCount;
154+
}
155+
156+
ModbusRequest03::ModbusRequest03(uint8_t slaveAddress, uint16_t address, uint16_t numberRegisters) :
157+
ModbusRequest(12) {
158+
_slaveAddress = slaveAddress;
159+
_functionCode = READ_HOLD_REGISTER;
160+
_address = address;
161+
_byteCount = numberRegisters * 2; // register is 2 bytes wide
162+
add(_slaveAddress);
163+
add(_functionCode);
164+
add(high(_address));
165+
add(low(_address));
166+
add(high(numberRegisters));
167+
add(low(numberRegisters));
168+
uint16_t CRC = CRC16(_buffer, 6);
169+
add(low(CRC));
170+
add(high(CRC));
171+
}
172+
173+
size_t ModbusRequest03::responseLength() {
174+
return 5 + _byteCount;
175+
}
176+
177+
ModbusRequest04::ModbusRequest04(uint8_t slaveAddress, uint16_t address, uint16_t numberRegisters) :
136178
ModbusRequest(8) {
137179
_slaveAddress = slaveAddress;
138180
_functionCode = READ_INPUT_REGISTER;
139181
_address = address;
140-
_byteCount = byteCount;
182+
_byteCount = numberRegisters * 2; // register is 2 bytes wide
141183
add(_slaveAddress);
142184
add(_functionCode);
143185
add(high(_address));
144186
add(low(_address));
145-
add(high(_byteCount));
146-
add(low(_byteCount));
187+
add(high(numberRegisters));
188+
add(low(numberRegisters));
147189
uint16_t CRC = CRC16(_buffer, 6);
148190
add(low(CRC));
149191
add(high(CRC));
150192
}
151193

152-
ModbusResponse* ModbusRequest04::makeResponse() {
194+
size_t ModbusRequest04::responseLength() {
153195
// slaveAddress (1) + functionCode (1) + byteCount (1) + length x 2 + CRC (2)
154-
uint8_t responseLength = 3 + (_byteCount * 2) + 2;
155-
ModbusResponse* response = new ModbusResponse(responseLength, this);
156-
return response;
196+
return 5 + _byteCount;
157197
}
158198

159199
ModbusResponse::ModbusResponse(uint8_t length, ModbusRequest* request) :
@@ -165,9 +205,7 @@ bool ModbusResponse::isComplete() {
165205
if (_buffer[1] > 0x80 && _index == 4) { // 4: slaveAddress(1), errorCode(1), CRC(2)
166206
return true;
167207
}
168-
if (_index > _buffer[2] + 4) {
169-
return true;
170-
}
208+
if (_index == _request->responseLength()) return true;
171209
return false;
172210
}
173211

@@ -191,7 +229,7 @@ bool ModbusResponse::isSucces() {
191229

192230
bool ModbusResponse::checkCRC() {
193231
uint16_t CRC = CRC16(_buffer, _length - 2);
194-
if (low(CRC) == _buffer[_length - 2] && high(CRC) == _buffer[_length -1 ]) {
232+
if (low(CRC) == _buffer[_length - 2] && high(CRC) == _buffer[_length -1]) {
195233
return true;
196234
} else {
197235
return false;

src/ModbusMessage.h

+18-3
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class ModbusResponse; // forward declare for use in ModbusRequest
4949

5050
class ModbusRequest : public ModbusMessage {
5151
public:
52-
virtual ModbusResponse* makeResponse() = 0;
52+
virtual size_t responseLength() = 0;
5353

5454
protected:
5555
explicit ModbusRequest(uint8_t length);
@@ -59,10 +59,25 @@ class ModbusRequest : public ModbusMessage {
5959
uint16_t _byteCount;
6060
};
6161

62+
// read discrete coils
63+
class ModbusRequest02 : public ModbusRequest {
64+
public:
65+
explicit ModbusRequest02(uint8_t slaveAddress, uint16_t address, uint16_t numberCoils);
66+
size_t responseLength();
67+
};
68+
69+
// read holding registers
70+
class ModbusRequest03 : public ModbusRequest {
71+
public:
72+
explicit ModbusRequest03(uint8_t slaveAddress, uint16_t address, uint16_t numberRegisters);
73+
size_t responseLength();
74+
};
75+
76+
// read input registers
6277
class ModbusRequest04 : public ModbusRequest {
6378
public:
64-
explicit ModbusRequest04(uint8_t slaveAddress, uint16_t address, uint16_t byteCount);
65-
ModbusResponse* makeResponse();
79+
explicit ModbusRequest04(uint8_t slaveAddress, uint16_t address, uint16_t numberRegisters);
80+
size_t responseLength();
6681
};
6782

6883
class ModbusResponse : public ModbusMessage {

src/esp32ModbusRTU.cpp

+18-3
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,23 @@ void esp32ModbusRTU::begin() {
5050
if (_interval == 0) _interval = 1; // minimum of 1msec interval
5151
}
5252

53-
bool esp32ModbusRTU::readInputRegister(uint8_t slaveAddress, uint16_t address, uint16_t byteCount) {
54-
ModbusRequest* request = new ModbusRequest04(slaveAddress, address, byteCount);
53+
bool esp32ModbusRTU::readDiscreteInputs(uint8_t slaveAddress, uint16_t address, uint16_t numberCoils) {
54+
ModbusRequest* request = new ModbusRequest02(slaveAddress, address, numberCoils);
55+
if (xQueueSend(_queue, reinterpret_cast<void*>(&request), (TickType_t)0) != pdPASS) {
56+
return false;
57+
}
58+
return true;
59+
}
60+
bool esp32ModbusRTU::readHoldingRegisters(uint8_t slaveAddress, uint16_t address, uint16_t numberRegisters) {
61+
ModbusRequest* request = new ModbusRequest03(slaveAddress, address, numberRegisters);
62+
if (xQueueSend(_queue, reinterpret_cast<void*>(&request), (TickType_t)0) != pdPASS) {
63+
return false;
64+
}
65+
return true;
66+
}
67+
68+
bool esp32ModbusRTU::readInputRegisters(uint8_t slaveAddress, uint16_t address, uint16_t numberRegisters) {
69+
ModbusRequest* request = new ModbusRequest04(slaveAddress, address, numberRegisters);
5570
if (xQueueSend(_queue, reinterpret_cast<void*>(&request), (TickType_t)0) != pdPASS) {
5671
return false;
5772
}
@@ -93,7 +108,7 @@ void esp32ModbusRTU::_send(uint8_t* data, uint8_t length) {
93108
}
94109

95110
ModbusResponse* esp32ModbusRTU::_receive(ModbusRequest* request) {
96-
ModbusResponse* response = request->makeResponse();
111+
ModbusResponse* response = new ModbusResponse(request->responseLength(), request);
97112
while (true) {
98113
while (_serial->available()) {
99114
response->add(_serial->read());

src/esp32ModbusRTU.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ class esp32ModbusRTU {
5151
explicit esp32ModbusRTU(HardwareSerial* serial, int8_t rtsPin = -1);
5252
~esp32ModbusRTU();
5353
void begin();
54-
bool readInputRegister(uint8_t slaveAddress, uint16_t address, uint16_t byteCount);
54+
bool readDiscreteInputs(uint8_t slaveAddress, uint16_t address, uint16_t numberCoils);
55+
bool readHoldingRegisters(uint8_t slaveAddress, uint16_t address, uint16_t numberRegisters);
56+
bool readInputRegisters(uint8_t slaveAddress, uint16_t address, uint16_t numberRegisters);
5557
void onData(MBRTUOnData handler);
5658
void onError(MBOnError handler);
5759

src/esp32ModbusTypeDefs.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace esp32Modbus {
3131

3232
enum MBFunctionCode : uint8_t {
3333
READ_COIL = 0x01,
34-
READ_DISC_INPUT = 0x02,
34+
READ_DISCR_INPUT = 0x02,
3535
READ_HOLD_REGISTER = 0x03,
3636
READ_INPUT_REGISTER = 0x04,
3737
WRITE_COIL = 0x05,

0 commit comments

Comments
 (0)