Software_and_hardware/Версия_3.0/libraries/Modbus-Master-Slave-for-Arduino-master/ModbusRtu.h

229 lines
7.2 KiB
C++

/**
* @file ModbusRtu.h
* @version 1.21
* @date 2016.02.21
* @author Samuel Marco i Armengol
* @contact sammarcoarmengol@gmail.com
* @contribution Helium6072
* @contribution gabrielsan
*
* @description
* Arduino library for communicating with Modbus devices
* over RS232/USB/485 via RTU protocol.
*
* Further information:
* http://modbus.org/
* http://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
*
* @license
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version
* 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* @defgroup setup Modbus Object Instantiation/Initialization
* @defgroup loop Modbus Object Management
* @defgroup buffer Modbus Buffer Management
* @defgroup discrete Modbus Function Codes for Discrete Coils/Inputs
* @defgroup register Modbus Function Codes for Holding/Input Registers
*
*/
#ifndef MODBUS_RTU_H
#define MODBUS_RTU_H
#include <inttypes.h>
#include "Arduino.h"
/**
* @struct modbus_t
* @brief
* Master query structure:
* This includes all the necessary fields to make the Master generate a Modbus query.
* A Master may keep several of these structures and send them cyclically or
* use them according to program needs.
*/
typedef struct
{
uint8_t u8id; /*!< Slave address between 1 and 247. 0 means broadcast */
uint8_t u8fct; /*!< Function code: 1, 2, 3, 4, 5, 6, 15 or 16 */
uint16_t u16RegAdd; /*!< Address of the first register to access at slave/s */
uint16_t u16CoilsNo; /*!< Number of coils or registers to access */
uint16_t *au16reg; /*!< Pointer to memory image in master */
}
modbus_t;
enum
{
RESPONSE_SIZE = 6,
EXCEPTION_SIZE = 3,
CHECKSUM_SIZE = 2
};
/**
* @enum MESSAGE
* @brief
* Indexes to telegram frame positions
*/
enum MESSAGE
{
ID = 0, //!< ID field
FUNC, //!< Function code position
ADD_HI, //!< Address high byte
ADD_LO, //!< Address low byte
NB_HI, //!< Number of coils or registers high byte
NB_LO, //!< Number of coils or registers low byte
BYTE_CNT //!< byte counter
};
/**
* @enum MB_FC
* @brief
* Modbus function codes summary.
* These are the implement function codes either for Master or for Slave.
*
* @see also fctsupported
* @see also modbus_t
*/
enum MB_FC
{
MB_FC_NONE = 0, /*!< null operator */
MB_FC_READ_COILS = 1, /*!< FCT=1 -> read coils or digital outputs */
MB_FC_READ_DISCRETE_INPUT = 2, /*!< FCT=2 -> read digital inputs */
MB_FC_READ_REGISTERS = 3, /*!< FCT=3 -> read registers or analog outputs */
MB_FC_READ_INPUT_REGISTER = 4, /*!< FCT=4 -> read analog inputs */
MB_FC_WRITE_COIL = 5, /*!< FCT=5 -> write single coil or output */
MB_FC_WRITE_REGISTER = 6, /*!< FCT=6 -> write single register */
MB_FC_WRITE_MULTIPLE_COILS = 15, /*!< FCT=15 -> write multiple coils or outputs */
MB_FC_WRITE_MULTIPLE_REGISTERS = 16 /*!< FCT=16 -> write multiple registers */
};
enum COM_STATES
{
COM_IDLE = 0,
COM_WAITING = 1
};
enum ERR_LIST
{
ERR_NOT_MASTER = -1,
ERR_POLLING = -2,
ERR_BUFF_OVERFLOW = -3,
ERR_BAD_CRC = -4,
ERR_EXCEPTION = -5
};
enum
{
NO_REPLY = 255,
EXC_FUNC_CODE = 1,
EXC_ADDR_RANGE = 2,
EXC_REGS_QUANT = 3,
EXC_EXECUTE = 4
};
const unsigned char fctsupported[] =
{
MB_FC_READ_COILS,
MB_FC_READ_DISCRETE_INPUT,
MB_FC_READ_REGISTERS,
MB_FC_READ_INPUT_REGISTER,
MB_FC_WRITE_COIL,
MB_FC_WRITE_REGISTER,
MB_FC_WRITE_MULTIPLE_COILS,
MB_FC_WRITE_MULTIPLE_REGISTERS
};
#define T35 5
#define MAX_BUFFER 64 //!< maximum size for the communication buffer in bytes
/**
* @class Modbus
* @brief
* Arduino class library for communicating with Modbus devices over
* USB/RS232/485 (via RTU protocol).
*/
class Modbus
{
private:
Stream *port; //!< Pointer to Stream class object (Either HardwareSerial or SoftwareSerial)
uint8_t u8id; //!< 0=master, 1..247=slave number
uint8_t u8txenpin; //!< flow control pin: 0=USB or RS-232 mode, >1=RS-485 mode
uint8_t u8state;
uint8_t u8lastError;
uint8_t au8Buffer[MAX_BUFFER];
uint8_t u8BufferSize;
uint8_t u8lastRec;
uint16_t *au16regs;
uint16_t u16InCnt, u16OutCnt, u16errCnt;
uint16_t u16timeOut;
uint32_t u32time, u32timeOut, u32overTime;
uint8_t u8regsize;
void sendTxBuffer();
int8_t getRxBuffer();
uint16_t calcCRC(uint8_t u8length);
uint8_t validateAnswer();
uint8_t validateRequest();
void get_FC1();
void get_FC3();
int8_t process_FC1( uint16_t *regs, uint8_t u8size );
int8_t process_FC3( uint16_t *regs, uint8_t u8size );
int8_t process_FC5( uint16_t *regs, uint8_t u8size );
int8_t process_FC6( uint16_t *regs, uint8_t u8size );
int8_t process_FC15( uint16_t *regs, uint8_t u8size );
int8_t process_FC16( uint16_t *regs, uint8_t u8size );
void buildException( uint8_t u8exception ); // build exception message
public:
Modbus(uint8_t u8id, Stream& port, uint8_t u8txenpin =0);
void start();
void setTimeOut( uint16_t u16timeOut); //!<write communication watch-dog timer
uint16_t getTimeOut(); //!<get communication watch-dog timer value
boolean getTimeOutState(); //!<get communication watch-dog timer state
int8_t query( modbus_t telegram ); //!<only for master
int8_t poll(); //!<cyclic poll for master
int8_t poll( uint16_t *regs, uint8_t u8size ); //!<cyclic poll for slave
uint16_t getInCnt(); //!<number of incoming messages
uint16_t getOutCnt(); //!<number of outcoming messages
uint16_t getErrCnt(); //!<error counter
uint8_t getID(); //!<get slave ID between 1 and 247
uint8_t getState();
uint8_t getLastError(); //!<get last error message
void setID( uint8_t u8id ); //!<write new ID for the slave
void setTxendPinOverTime( uint32_t u32overTime );
void end(); //!<finish any communication and release serial communication port
//
// Deprecated functions
// Deprecated: Use constructor: "Modbus m(0,Serial,0)" instead.
Modbus(uint8_t u8id=0, uint8_t u8serno=0, uint8_t u8txenpin=0) __attribute__((deprecated));
// Deprecated: Use "start()" instead.
template<typename T_Stream>
void begin(T_Stream* port_, long u32speed_) __attribute__((deprecated));
// Deprecated: Use "start()" instead.
template<typename T_Stream>
void begin(T_Stream* port_, long u32speed_, uint8_t u8txenpin_) __attribute__((deprecated));
// Deprecated: Use "start()" instead.
void begin(long u32speed = 19200) __attribute__((deprecated));
};
#endif // MODBUS_RTU_H