1
1
/*
2
2
Modbus.cpp - Source for Modbus Base Library
3
3
Copyright (C) 2014 André Sarmento Barbosa
4
+ Copyright (C) 2023 Pascal JEAN aka epsilonrt
4
5
*/
5
6
#include " Modbus.h"
6
7
@@ -73,6 +74,7 @@ word Modbus::reg (word address) {
73
74
}
74
75
}
75
76
77
+ // INLINE --------------------
76
78
void Modbus::addHreg (word offset, word value) {
77
79
this ->addReg (offset + 40001 , value);
78
80
}
@@ -132,6 +134,7 @@ word Modbus::ireg (word offset) {
132
134
return reg (offset + 30001 );
133
135
}
134
136
#endif
137
+ // INLINE --------------------
135
138
136
139
137
140
void Modbus::receivePDU (byte * frame) {
@@ -203,6 +206,17 @@ void Modbus::exceptionResponse (byte fcode, byte excode) {
203
206
_reply = MB_REPLY_NORMAL;
204
207
}
205
208
209
+ /*
210
+ Func 17: Report Server ID
211
+ Request
212
+ Function code 1 Byte 0x11
213
+ Response
214
+ Function code 1 Byte 0x11
215
+ Byte Count 1 Byte
216
+ Server ID device specific
217
+ Run Indicator Status 1 Byte 0x00 = OFF, 0xFF = ON
218
+ Additional Data
219
+ */
206
220
void Modbus::reportServerId () {
207
221
// Clean frame buffer
208
222
free (_frame);
@@ -241,6 +255,18 @@ int Modbus::setAdditionalServerData (const char data[]) {
241
255
return 0 ;
242
256
}
243
257
258
+ /*
259
+ Func 03: Read Holding Registers
260
+ Request
261
+ Function code 1 Byte 0x03
262
+ Starting Address 2 Bytes 0x0000 to 0xFFFF
263
+ Quantity of Registers 2 Bytes 1 to 125 (0x7D)
264
+ Response
265
+ Function code 1 Byte 0x03
266
+ Byte count 1 Byte 2 x N*
267
+ Register value N* x 2 Bytes
268
+ *N = Quantity of Registers
269
+ */
244
270
void Modbus::readRegisters (word startreg, word numregs) {
245
271
// Check value (numregs)
246
272
if (numregs < 0x0001 || numregs > 0x007D ) {
@@ -288,6 +314,16 @@ void Modbus::readRegisters (word startreg, word numregs) {
288
314
_reply = MB_REPLY_NORMAL;
289
315
}
290
316
317
+ /* Func 06: Write Single Register
318
+ Request
319
+ Function code 1 Byte 0x06
320
+ Register Address 2 Bytes 0x0000 to 0xFFFF
321
+ Register Value 2 Bytes 0x0000 to 0xFFFF
322
+ Response
323
+ Function code 1 Byte 0x06
324
+ Register Address 2 Bytes 0x0000 to 0xFFFF
325
+ Register Value 2 Bytes 0x0000 to 0xFFFF
326
+ */
291
327
void Modbus::writeSingleRegister (word reg, word value) {
292
328
// No necessary verify illegal value (EX_ILLEGAL_VALUE) - because using word (0x0000 - 0x0FFFF)
293
329
// Check Address and execute (reg exists?)
@@ -302,9 +338,22 @@ void Modbus::writeSingleRegister (word reg, word value) {
302
338
return ;
303
339
}
304
340
305
- _reply = MB_REPLY_ECHO;
341
+ _reply = MB_REPLY_ECHO; // reply with received frame
306
342
}
307
343
344
+ /* Func 16: Write Multiple registers
345
+ Request
346
+ Function code 1 Byte 0x10
347
+ Starting Address 2 Bytes 0x0000 to 0xFFFF
348
+ Quantity of Registers 2 Bytes 0x0001 to 0x007B
349
+ Byte Count 1 Byte 2 x N*
350
+ Registers Value N* x 2 Bytes value
351
+ *N = Quantity of Registers
352
+ Response
353
+ Function code 1 Byte 0x10
354
+ Starting Address 2 Bytes 0x0000 to 0xFFFF
355
+ Quantity of Registers 2 Bytes 1 to 123 (0x7B)
356
+ */
308
357
void Modbus::writeMultipleRegisters (byte * frame, word startreg, word numoutputs, byte bytecount) {
309
358
// Check value
310
359
if (numoutputs < 0x0001 || numoutputs > 0x007B || bytecount != 2 * numoutputs) {
@@ -347,6 +396,17 @@ void Modbus::writeMultipleRegisters (byte * frame, word startreg, word numoutput
347
396
}
348
397
349
398
#ifndef USE_HOLDING_REGISTERS_ONLY
399
+ /* Func 01: Read Coils
400
+ Request
401
+ Function code 1 Byte 0x01
402
+ Starting Address 2 Bytes 0x0000 to 0xFFFF
403
+ Quantity of coils 2 Bytes 1 to 2000 (0x7D0)
404
+ Response
405
+ Function code 1 Byte 0x01
406
+ Byte count 1 Byte N*
407
+ Coil Status n Byte n = N or N+1
408
+ *N = Quantity of Outputs / 8, if the remainder is different of 0 -> N = N+1
409
+ */
350
410
void Modbus::readCoils (word startreg, word numregs) {
351
411
// Check value (numregs)
352
412
if (numregs < 0x0001 || numregs > 0x07D0 ) {
@@ -407,6 +467,18 @@ void Modbus::readCoils (word startreg, word numregs) {
407
467
_reply = MB_REPLY_NORMAL;
408
468
}
409
469
470
+ /* Func 02: Read Discrete Inputs
471
+ Request
472
+ Function code 1 Byte 0x02
473
+ Starting Address 2 Bytes 0x0000 to 0xFFFF
474
+ Quantity of Inputs 2 Bytes 1 to 2000 (0x7D0)
475
+ Response
476
+ Function code 1 Byte 0x02
477
+ Byte count 1 Byte N*
478
+ Input Status N* x 1 Byte
479
+ *N = Quantity of Inputs / 8 if the remainder is different of 0 N = N+1
480
+ Error
481
+ */
410
482
void Modbus::readInputStatus (word startreg, word numregs) {
411
483
// Check value (numregs)
412
484
if (numregs < 0x0001 || numregs > 0x07D0 ) {
@@ -464,6 +536,17 @@ void Modbus::readInputStatus (word startreg, word numregs) {
464
536
_reply = MB_REPLY_NORMAL;
465
537
}
466
538
539
+ /* Func 04: Read Input Registers
540
+ Request
541
+ Function code 1 Byte 0x04
542
+ Starting Address 2 Bytes 0x0000 to 0xFFFF
543
+ Quantity of Input Registers 2 Bytes 0x0001 to 0x007D
544
+ Response
545
+ Function code 1 Byte 0x04
546
+ Byte count 1 Byte 2 x N*
547
+ Input Registers N* x 2 Bytes
548
+ *N = Quantity of Input Registers
549
+ */
467
550
void Modbus::readInputRegisters (word startreg, word numregs) {
468
551
// Check value (numregs)
469
552
if (numregs < 0x0001 || numregs > 0x007D ) {
@@ -510,6 +593,16 @@ void Modbus::readInputRegisters (word startreg, word numregs) {
510
593
_reply = MB_REPLY_NORMAL;
511
594
}
512
595
596
+ /* Func 05: Write Single Coil
597
+ Request
598
+ Function code 1 Byte 0x05
599
+ Output Address 2 Bytes 0x0000 to 0xFFFF
600
+ Output Value 2 Bytes 0x0000 or 0xFF00
601
+ Response
602
+ Function code 1 Byte 0x05
603
+ Output Address 2 Bytes 0x0000 to 0xFFFF
604
+ Output Value 2 Bytes 0x0000 or 0xFF00
605
+ */
513
606
void Modbus::writeSingleCoil (word reg, word status) {
514
607
// Check value (status)
515
608
if (status != 0xFF00 && status != 0x0000 ) {
@@ -529,9 +622,21 @@ void Modbus::writeSingleCoil (word reg, word status) {
529
622
return ;
530
623
}
531
624
532
- _reply = MB_REPLY_ECHO;
625
+ _reply = MB_REPLY_ECHO; // reply with received frame
533
626
}
534
627
628
+ /* Func 15: Write Multiple Coils
629
+ Request
630
+ Function code 1 Byte 0x0F
631
+ Starting Address 2 Bytes 0x0000 to 0xFFFF
632
+ Quantity of Outputs 2 Bytes 0x0001 to 0x07B0
633
+ Byte Count 1 Byte N* (Quantity of Outputs / 8, if the remainder is different of 0 -> N = N+1)
634
+ Outputs Value N* x 1 Byte
635
+ Response
636
+ Function code 1 Byte 0x0F
637
+ Starting Address 2 Bytes 0x0000 to 0xFFFF
638
+ Quantity of Outputs 2 Bytes 0x0001 to 0x07B0
639
+ */
535
640
void Modbus::writeMultipleCoils (byte * frame, word startreg, word numoutputs, byte bytecount) {
536
641
// Check value
537
642
word bytecount_calc = numoutputs / 8 ;
0 commit comments