SimpleModbusSlave allows you to communicate to any slave using the Modbus RTU protocol. The crc calculation is based on https://os.mbed.com/users/jpelletier/code/CRC/ The functions implemented are functions 3 and 16. read holding registers and preset multiple registers of the Modbus RTU Protocol. This implementation DOES NOT fully comply with the Modbus specifications.
SimpleModbusSlave.h@0:7c5265097fd2, 2017-10-10 (annotated)
- Committer:
- gugani
- Date:
- Tue Oct 10 12:22:31 2017 +0000
- Revision:
- 0:7c5265097fd2
- Child:
- 1:85e226914fb7
Initial Commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gugani | 0:7c5265097fd2 | 1 | #ifndef SIMPLE_MODBUS_SLAVE_H |
gugani | 0:7c5265097fd2 | 2 | #define SIMPLE_MODBUS_SLAVE_H |
gugani | 0:7c5265097fd2 | 3 | |
gugani | 0:7c5265097fd2 | 4 | /* |
gugani | 0:7c5265097fd2 | 5 | SimpleModbusSlave allows you to communicate |
gugani | 0:7c5265097fd2 | 6 | to any slave using the Modbus RTU protocol. |
gugani | 0:7c5265097fd2 | 7 | |
gugani | 0:7c5265097fd2 | 8 | The crc calculation is based on the work published |
gugani | 0:7c5265097fd2 | 9 | by jpmzometa at |
gugani | 0:7c5265097fd2 | 10 | http://sites.google.com/site/jpmzometa/arduino-mbrt |
gugani | 0:7c5265097fd2 | 11 | |
gugani | 0:7c5265097fd2 | 12 | By Juan Bester : bester.juan@gmail.com |
gugani | 0:7c5265097fd2 | 13 | |
gugani | 0:7c5265097fd2 | 14 | The functions implemented are functions 3 and 16. |
gugani | 0:7c5265097fd2 | 15 | read holding registers and preset multiple registers |
gugani | 0:7c5265097fd2 | 16 | of the Modbus RTU Protocol, to be used over the Arduino serial connection. |
gugani | 0:7c5265097fd2 | 17 | |
gugani | 0:7c5265097fd2 | 18 | This implementation DOES NOT fully comply with the Modbus specifications. |
gugani | 0:7c5265097fd2 | 19 | |
gugani | 0:7c5265097fd2 | 20 | Specifically the frame time out have not been implemented according |
gugani | 0:7c5265097fd2 | 21 | to Modbus standards. The code does however combine the check for |
gugani | 0:7c5265097fd2 | 22 | inter character time out and frame time out by incorporating a maximum |
gugani | 0:7c5265097fd2 | 23 | time out allowable when reading from the message stream. |
gugani | 0:7c5265097fd2 | 24 | |
gugani | 0:7c5265097fd2 | 25 | These library of functions are designed to enable a program send and |
gugani | 0:7c5265097fd2 | 26 | receive data from a device that communicates using the Modbus protocol. |
gugani | 0:7c5265097fd2 | 27 | |
gugani | 0:7c5265097fd2 | 28 | SimpleModbusSlave implements an unsigned int return value on a call to modbus_update(). |
gugani | 0:7c5265097fd2 | 29 | This value is the total error count since the slave started. It's useful for fault finding. |
gugani | 0:7c5265097fd2 | 30 | |
gugani | 0:7c5265097fd2 | 31 | This code is for a Modbus slave implementing functions 3 and 16 |
gugani | 0:7c5265097fd2 | 32 | function 3: Reads the binary contents of holding registers (4X references) |
gugani | 0:7c5265097fd2 | 33 | function 16: Presets values into a sequence of holding registers (4X references) |
gugani | 0:7c5265097fd2 | 34 | |
gugani | 0:7c5265097fd2 | 35 | All the functions share the same register array. |
gugani | 0:7c5265097fd2 | 36 | |
gugani | 0:7c5265097fd2 | 37 | Exception responses: |
gugani | 0:7c5265097fd2 | 38 | 1 ILLEGAL FUNCTION |
gugani | 0:7c5265097fd2 | 39 | 2 ILLEGAL DATA ADDRESS |
gugani | 0:7c5265097fd2 | 40 | 3 ILLEGAL DATA VALUE |
gugani | 0:7c5265097fd2 | 41 | |
gugani | 0:7c5265097fd2 | 42 | Note: |
gugani | 0:7c5265097fd2 | 43 | The Arduino serial ring buffer is 128 bytes or 64 registers. |
gugani | 0:7c5265097fd2 | 44 | Most of the time you will connect the arduino to a master via serial |
gugani | 0:7c5265097fd2 | 45 | using a MAX485 or similar. |
gugani | 0:7c5265097fd2 | 46 | |
gugani | 0:7c5265097fd2 | 47 | In a function 3 request the master will attempt to read from your |
gugani | 0:7c5265097fd2 | 48 | slave and since 5 bytes is already used for ID, FUNCTION, NO OF BYTES |
gugani | 0:7c5265097fd2 | 49 | and two BYTES CRC the master can only request 122 bytes or 61 registers. |
gugani | 0:7c5265097fd2 | 50 | |
gugani | 0:7c5265097fd2 | 51 | In a function 16 request the master will attempt to write to your |
gugani | 0:7c5265097fd2 | 52 | slave and since a 9 bytes is already used for ID, FUNCTION, ADDRESS, |
gugani | 0:7c5265097fd2 | 53 | NO OF REGISTERS, NO OF BYTES and two BYTES CRC the master can only write |
gugani | 0:7c5265097fd2 | 54 | 118 bytes or 59 registers. |
gugani | 0:7c5265097fd2 | 55 | |
gugani | 0:7c5265097fd2 | 56 | Using the FTDI converter ic the maximum bytes you can send is limited |
gugani | 0:7c5265097fd2 | 57 | to its internal buffer which is 60 bytes or 30 unsigned int registers. |
gugani | 0:7c5265097fd2 | 58 | |
gugani | 0:7c5265097fd2 | 59 | Thus: |
gugani | 0:7c5265097fd2 | 60 | |
gugani | 0:7c5265097fd2 | 61 | In a function 3 request the master will attempt to read from your |
gugani | 0:7c5265097fd2 | 62 | slave and since 5 bytes is already used for ID, FUNCTION, NO OF BYTES |
gugani | 0:7c5265097fd2 | 63 | and two BYTES CRC the master can only request 54 bytes or 27 registers. |
gugani | 0:7c5265097fd2 | 64 | |
gugani | 0:7c5265097fd2 | 65 | In a function 16 request the master will attempt to write to your |
gugani | 0:7c5265097fd2 | 66 | slave and since a 9 bytes is already used for ID, FUNCTION, ADDRESS, |
gugani | 0:7c5265097fd2 | 67 | NO OF REGISTERS, NO OF BYTES and two BYTES CRC the master can only write |
gugani | 0:7c5265097fd2 | 68 | 50 bytes or 25 registers. |
gugani | 0:7c5265097fd2 | 69 | |
gugani | 0:7c5265097fd2 | 70 | Since it is assumed that you will mostly use the Arduino to connect to a |
gugani | 0:7c5265097fd2 | 71 | master without using a USB to Serial converter the internal buffer is set |
gugani | 0:7c5265097fd2 | 72 | the same as the Arduino Serial ring buffer which is 128 bytes. |
gugani | 0:7c5265097fd2 | 73 | |
gugani | 0:7c5265097fd2 | 74 | The functions included here have been derived from the |
gugani | 0:7c5265097fd2 | 75 | Modbus Specifications and Implementation Guides |
gugani | 0:7c5265097fd2 | 76 | |
gugani | 0:7c5265097fd2 | 77 | http://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf |
gugani | 0:7c5265097fd2 | 78 | http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf |
gugani | 0:7c5265097fd2 | 79 | http://www.modbus.org/docs/PI_MBUS_300.pdf |
gugani | 0:7c5265097fd2 | 80 | */ |
gugani | 0:7c5265097fd2 | 81 | |
gugani | 0:7c5265097fd2 | 82 | |
gugani | 0:7c5265097fd2 | 83 | |
gugani | 0:7c5265097fd2 | 84 | // function definitions |
gugani | 0:7c5265097fd2 | 85 | void modbus_configure(long baud, char _slaveID, char _TxEnablePin, unsigned int _holdingRegsSize, unsigned char _lowLatency); |
gugani | 0:7c5265097fd2 | 86 | unsigned int modbus_update(unsigned int *holdingRegs); |
gugani | 0:7c5265097fd2 | 87 | |
gugani | 0:7c5265097fd2 | 88 | |
gugani | 0:7c5265097fd2 | 89 | #endif |