11/*
22 Modbus.cpp - Source for Modbus Base Library
33 Copyright (C) 2014 André Sarmento Barbosa
4+ Copyright (C) 2023 Pascal JEAN aka epsilonrt
45*/
56#include " Modbus.h"
67
@@ -73,6 +74,7 @@ word Modbus::reg (word address) {
7374 }
7475}
7576
77+ // INLINE --------------------
7678void Modbus::addHreg (word offset, word value) {
7779 this ->addReg (offset + 40001 , value);
7880}
@@ -132,6 +134,7 @@ word Modbus::ireg (word offset) {
132134 return reg (offset + 30001 );
133135}
134136#endif
137+ // INLINE --------------------
135138
136139
137140void Modbus::receivePDU (byte * frame) {
@@ -203,6 +206,17 @@ void Modbus::exceptionResponse (byte fcode, byte excode) {
203206 _reply = MB_REPLY_NORMAL;
204207}
205208
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+ */
206220void Modbus::reportServerId () {
207221 // Clean frame buffer
208222 free (_frame);
@@ -241,6 +255,18 @@ int Modbus::setAdditionalServerData (const char data[]) {
241255 return 0 ;
242256}
243257
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+ */
244270void Modbus::readRegisters (word startreg, word numregs) {
245271 // Check value (numregs)
246272 if (numregs < 0x0001 || numregs > 0x007D ) {
@@ -288,6 +314,16 @@ void Modbus::readRegisters (word startreg, word numregs) {
288314 _reply = MB_REPLY_NORMAL;
289315}
290316
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+ */
291327void Modbus::writeSingleRegister (word reg, word value) {
292328 // No necessary verify illegal value (EX_ILLEGAL_VALUE) - because using word (0x0000 - 0x0FFFF)
293329 // Check Address and execute (reg exists?)
@@ -302,9 +338,22 @@ void Modbus::writeSingleRegister (word reg, word value) {
302338 return ;
303339 }
304340
305- _reply = MB_REPLY_ECHO;
341+ _reply = MB_REPLY_ECHO; // reply with received frame
306342}
307343
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+ */
308357void Modbus::writeMultipleRegisters (byte * frame, word startreg, word numoutputs, byte bytecount) {
309358 // Check value
310359 if (numoutputs < 0x0001 || numoutputs > 0x007B || bytecount != 2 * numoutputs) {
@@ -347,6 +396,17 @@ void Modbus::writeMultipleRegisters (byte * frame, word startreg, word numoutput
347396}
348397
349398#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+ */
350410void Modbus::readCoils (word startreg, word numregs) {
351411 // Check value (numregs)
352412 if (numregs < 0x0001 || numregs > 0x07D0 ) {
@@ -407,6 +467,18 @@ void Modbus::readCoils (word startreg, word numregs) {
407467 _reply = MB_REPLY_NORMAL;
408468}
409469
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+ */
410482void Modbus::readInputStatus (word startreg, word numregs) {
411483 // Check value (numregs)
412484 if (numregs < 0x0001 || numregs > 0x07D0 ) {
@@ -464,6 +536,17 @@ void Modbus::readInputStatus (word startreg, word numregs) {
464536 _reply = MB_REPLY_NORMAL;
465537}
466538
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+ */
467550void Modbus::readInputRegisters (word startreg, word numregs) {
468551 // Check value (numregs)
469552 if (numregs < 0x0001 || numregs > 0x007D ) {
@@ -510,6 +593,16 @@ void Modbus::readInputRegisters (word startreg, word numregs) {
510593 _reply = MB_REPLY_NORMAL;
511594}
512595
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+ */
513606void Modbus::writeSingleCoil (word reg, word status) {
514607 // Check value (status)
515608 if (status != 0xFF00 && status != 0x0000 ) {
@@ -529,9 +622,21 @@ void Modbus::writeSingleCoil (word reg, word status) {
529622 return ;
530623 }
531624
532- _reply = MB_REPLY_ECHO;
625+ _reply = MB_REPLY_ECHO; // reply with received frame
533626}
534627
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+ */
535640void Modbus::writeMultipleCoils (byte * frame, word startreg, word numoutputs, byte bytecount) {
536641 // Check value
537642 word bytecount_calc = numoutputs / 8 ;
0 commit comments