/******************************************************/ /* Modbus/TCP to Modbus/RTU protocol head file */ /* For 7188E (with Xserver structure) */ /* */ /* Note: head file version is different to */ /* lib file version. */ /* */ /******************************************************/ /* Ver 1.7.1 [2009,09,29] by Kevin [Default firmware] Bugs fixed: none Change: none Improve: none New: none [Programming] Bugs fixed: 1. ModbusASCII_Master_Send, ModbusASCII_Master Can not send more than 121 AO registers. 2. ModbusTCP_Master2Slave Condition: Using several commands in the same connection. For example: ModbusTCP_Master2Slave(0,....) //to read DI ModbusTCP_Master2Slave(0,....) //to read AI ModbusTCP_Master2Slave*0,....) //to write Do If one command gets error code from the Modbus/TCP slave device, it will close the TCP/IP connection. Other commands use the same connection will lose the connection too, even they didn't get any error code from the Modbus/TCP slave device. Now: 1. The error code get from the Modbus/TCP slave device will add to the return code of the function and other commands will not effected. 2. you can use ModbusTCP_Master2Slave in easy way. The old demo program shows a complex way. You have to control the process to execute the commands. The new demo program shows the easy way. You can call the function line by line. ModbusTCP_Master2Slave(0,....) //to read DI ModbusTCP_Master2Slave(0,....) //to read AI ModbusTCP_Master2Slave*0,....) //to write Do [***]To use the easier way, you have to use lib version 1.7.1 or later. [***]return code also been changed. Change: 1. ModbusTCP_Master2Slave return code changed 0 = No Error (no change) 1~255 = error code returned from device <0 = error code returned from lib (no change) 1 canceled: the condition will never happen. 502 (new, original is 2): Command already sent, but no data received 503 (new): parameters of previous command not match parameters of this commnad. Improve: 1. Modbus_Response_Event When the COM port enable mode is Gateway (Modbus/TCP to Modbus/RTU), users can get an event of SendModbusResponse in function Modbus_Response_Event. New: 1. Modbus_Memory_Size The function can be call after InitModbus. It is used to check whether the Modbus request overs the max. address. If the Modbus request overs the max. address, responses error code 02. --------------------------------------------------------------------- Version 1.7.1 [29,Sep,2009] by Kevin change: extern MODBUS_TYPE mtModbusPort[9]; becomes extern MODBUS_TYPE far mtModbusPort[9]; Since Modbus library version 1.7.1, you must use this one. --------------------------------------------------------------------- Version 1.6.9 [22,Sep,2009] by Kevin 1. add C++ declaration to the most begining and end of the .h file. #ifdef __cplusplus extern "C" { #endif //..... original contents. #ifdef __cplusplus } #endif The modbus library is compiled in C, not C++. If you want to develop a C++ program and include the library, the declaration can make it work. --------------------------------------------------------------------- Version 1.6.8 [8,Sep,2006] by Kevin 1. Add one constant define _Console 5 --------------------------------------------------------------------- Version 1.6.7 [16,Aug,2006] by Kevin 1. Add global variables lModbusRequest_TimeTicks --------------------------------------------------------------------- Version 1.6.6 [04,Jul,2006] by Kevin 1. All controller use same head file For Modbus/RTU ===> MBRTU.h For Modbus/TCP ===> MBTCP.h 2. Remove variable MAX_REGISTER_COUNT. From version 1.6.4, the registers are declared by user's self. So, MAX_REGISTER_COUNT is useless. 3. Improve ModbusRTU_Master2Slave and ModbusASCII_Master2Slave (a) add non-blocked communication mode. there is one iWait parameter can decide to use blocked (original mode) or non-blocked (new mode). (b) add functions ModbusRTU_Master_Send ModbusRTU_Master_Receive ModbusASCII_Master_Send ModbusASCII_Master_Receive Please refer to function comments for details. --------------------------------------------------------------------- Version 1.6.4 [17,Feb,2006] by Kevin 1. Add command buffer for Modbus/RTU Gateway Each COM port can store 4 commands in the buffer. While several Modbus masters use same COM port gateway, the buffer can store the commands and then bypass them to Modbus/RTU device that connected to the COM port. The function can avoid data collision. For programming 1. support XS structor. 2. add RefreshWDT to ModbusRTU_Master2Slave. this can avoid reset by WDT when the timeout parameter is more than 0.8 second. 3. add Debug information for Modbus/AsCII Master to Slave. 4. change InitModbus the function now needs four extra parameters. 5. add Modbus/TCP master to slave function --------------------------------------------------------------------- Version 1.6.3 [29,Sep,2005] by Kevin Change ModbusMaster2Slave: Rename to ModbusRTU_Master2Slave, Add a lTimeout parameter. Add ModbusASCII_Master2Slave --------------------------------------------------------------------- Version 1.6.2 [23,Aug,2005] by Kevin Add functions for Modbus/TCP master (1) ModbusTCP_Init (2) ModbusTCP_Master2Slave (3) ModbusTCP_Close --------------------------------------------------------------------- Version 1.6.0 [08,Apr,2005] by Kevin Remove #define MODBUS_ACTION_IDLE 0 #define MODBUS_ACTION_CHECK_REQUEST_FROM_MASTER 1 #define MODBUS_ACTION_SEND_REQUEST_2DEVICE 2 #define MODBUS_ACTION_CHECK_RESPONSE_FROM_DEVICE 3 #define MODBUS_ACTION_SCAN_MASTER 10 #define MODBUS_ACTION_2MEMORY 41 //For 7188/XA/XB/XC only They are used in the Modbus lirbray. Demo programs don't need it. --------------------------------------------------------------------- Version 1.5.9 [22,Sep,2004] by Kevin Provides a Modbus/RTU library (MBR7Ennn.Lib and MBRTU_7E.h) for 7188EX. It can be integrated to user's program that not developed on the Xserver architecture. --------------------------------------------------------------------- Version 1.5.8 [26,Jun,2004] by Kevin Modify function ModbusMaster2Slave: supports modbus function code 5 and 6. cleafy return value before: always return 0 now: return different value to identify different situation, such as timeout, CRC check error, exception code, etc. Add global variables iModbusRequest_Fun iModbusRequest_Addr iModbusRequest_IOCount --------------------------------------------------------------------- Version 1.5.7 [22,Jun,2004] by Kevin add global variables iModbusRequest_Fun iModbusRequest_Addr; iModbusRequest_IOCount; ModbusMaster2Slave supports modbus function code 5 and 6. --------------------------------------------------------------------- Version 1.5.5 [24,Nov,2003] by Kevin Remove functions Set_DebugPort Set_ModbusUpLinkPort Remove variables iModbusUpLinkPort iDebugPort Modify Set_EnableMode adds two new modes (UpLink, Debug) to replace function Set_DebugPort and Set_ModbusUpLinkPort. Modify comment of MODBUS_TYPE Modify comment of function CheckModbusRequest Change function name Set_StationCountPerCOMPort === Changed to ===> Set_StationPerCOMPort Set_EnableMode === Changed to ===> Set_COMEnableMode Set_Timeout === Changed to ===> Set_ModbusTimeout --------------------------------------------------------------------- Version 1.5.3 [13,Jun,2003] by Kevin Add function CheckModbusRequest. --------------------------------------------------------------------- Version 1.5.2 [5,Jun,2003] by Kevin Add comment to ModbusMaster2Slave --------------------------------------------------------------------- Version: 1.5.1 [30,Apr,2003] by Kevin Change declaration 1. MAX_REGISTER_COUNT: constant ==> int 2. iMemory_DI, iMemory_DO, iMemory_AI, iMemory_AO ==> to pointer --------------------------------------------------------------------- Version: 1.5.0 [20,Feb,2003] by Kevin Change: iModbusInternalID ==> iModbusNetID --------------------------------------------------------------------- Version: 1.3.0 [16,Oct,2002] by Kevin */ #ifdef __cplusplus extern "C" { #endif #define MODBUS_DATA_LENGTH 256 // modbus data max length (byte) #define _Modbus_Command_Buffer 4 typedef struct t_ModbusPacket { int EnableMode; // =1 to eanble COM port as a modbus port int Socket[_Modbus_Command_Buffer]; int COMPort[_Modbus_Command_Buffer]; int Status[_Modbus_Command_Buffer]; // to identify which process the kernal is running int Length[_Modbus_Command_Buffer]; // Data length, doesn't include Modbus/TCP leading 6 bytes and 2 CRC bytes int Timeout; STOPWATCH Timer; int Current_Index; unsigned char Data[_Modbus_Command_Buffer][MODBUS_DATA_LENGTH]; } MODBUS_TYPE; extern MODBUS_TYPE far mtModbusPort[9]; // 7188 series has a maximum of 8 COM ports // Constant for EnableMode #define _VxComm 0 //==> VxComm #define _ModbusRTU_Gateway 1 //==> Modbus/RTU Gateway #define _Programming 2 //==> Programming #define _ModbusRTU_Slave 3 //==> UpLink (to be a Modbus/RTU slave port) #define _Debug 4 //==> Debug (print out some message for debug) #define _Console 5 //==> Consol (ET-6000 uses it to do simple config) #define _ModbusASCII_Slave 6 //==> UpLink (to be a Modbus/ASCII slave port) #define _UpLink _ModbusRTU_Slave #define _ModbusRTU _ModbusRTU_Gateway //Following 3 variables record the information //of last Modbus/TCP or Modbus/RTU request. extern unsigned int iModbusRequest_Fun; // 1 ==> Reads multi DO from internal register (iMemory_DO) // 2 ==> Reads multi DI from internal register (iMemory_DI) // 3 ==> Reads multi AO from internal register (iMemory_AO) // 4 ==> Reads multi AI from internal register (iMemory_AI) // 5 ==> Write one DO to internal register (iMemory_DO) // 6 ==> Write one AO to internal register (iMemory_AO) //15 ==> Writes multi DO to internal register (iMemory_DO) //16 ==> Writes multi AO to internal register (iMemory_AO) extern unsigned int iModbusRequest_Addr; extern unsigned int iModbusRequest_IOCount; extern unsigned long lModbusRequest_TimeTicks; extern int iModbusNetID; extern int iProtocolMode; extern int iTotalCOMPort; extern int iEnableUpLinkPort; extern unsigned long lModbusRequest_TimeTicks; extern unsigned long lCRCError,lTimeoutError; //===============================================// // Prototype of functions // //===============================================// int InitModbus(unsigned char far *iPointer_DI, unsigned char far *iPointer_DO, int far *iPointer_AI, int far *iPointer_AO); /* step 1. declare 4 global arrays step 2. give the 4 array pointers to InitModbus. For example: unsinged char far Array_DI[100]; unsinged char far Array_DO[100]; int far Array_AI[100]; int far Array_AO[100]; main() { InitModbus(Array_DI,Array_DO,Array_AI,Array_AO); //Giving initial values. Array_DI[0]=1; Array_DO[10]=0; Array_AI[5]=100; Array_AO[20]=-500; .... .... } */ void CheckModbusASCIIRequest(int iPort); #define CheckModbusRequest CheckModbusRTURequest void CheckModbusRTURequest(int iPort); /* iPort: Is any Modbus/RTU request from COM port ? The enable mode of the COM port must be set in UpLink. Two methods to set the enable mode Method 1: Using the Modbus Utility (after version 1.2.6) Method 2: Calling function Set_COMEnableMode in the C program The destination that the Modbus request will be passed is decided by the NetID (or called Station number) in the Modbus request and the global variable ,iStationCountPerCOMPort. You can set the two key values in the Modbus Utility. Enter this function when iModbusAction=MODBUS_ACTION_IDLE Sets iModbusAction=MODBUS_ACTION_CHECK_REQUEST_FROM_PC when gets correct modbus request. */ void SendModbusRequest(int iPort); /* Enter this function when mtModbusPort[iPort].Status=MODBUS_ACTION_CHECK_REQUEST_FROM_MASTER Sets mtModbusPort[iPort].Status=MODBUS_ACTION_SEND_REQUEST_2DEVICE when finish sending out modbus request. */ void CheckResponseTimeout(int iPort); /* Enter this function when mtModbusPort[iPort].Status=MODBUS_ACTION_SEND_REQUEST_2DEVICE Sets mtModbusPort[iPort].Status=MODBUS_ACTION_IDLE when timeout is up. */ void CheckModbusResponse(int iPort); /* Enter this function when mtModbusPort[iPort].Status=MODBUS_ACTION_SEND_REQUEST_2DEVICE Sets mtModbusPort[iPort].Status=MODBUS_ACTION_CHECK_RESPONSE_FROM_DEVICE when receiving correct modbus response. Sets mtModbusPort[iPort].Status=MODBUS_ACTION_IDLE when error. */ void SendModbusResponse(int iPort); /* Enter this function when iModbusAction=MODBUS_ACTION_CHECK_RESPONSE_FROM_DEVICE Sets mtModbusPort[iPort].Status=MODBUS_ACTION_IDLE when finish sending out modbus response. */ int Set_NetID(int iNetID); /* Sets Modbus NetID. If the iNetID doesn't match the current setting, this function changes the current setting and sotre the setting to the EEPROM. If the iNetID matchs the current setting, holds the currnet setting. iNetID: 0~255 Return: 0 ==> success -1 ==> writes the setting to EEPROM failure */ #define Set_StationCountPerCOMPort Set_StationPerCOMPort int Set_StationPerCOMPort(int iCount); /* Sets station counter per COM port. If the iCount doesn't match the current setting, this function changes the current setting and sotre the setting to the EEPROM. If the iCount matchs the current setting, holds the currnet setting. iCount: 1~255 Return: 0 ==> success -1 ==> writes the setting to EEPROM failure */ #define Set_EnableMode Set_COMEnableMode int Set_COMEnableMode(int iPort, int iMode); /* Sets COM port enable mode. If the iMode doesn't match the current setting, this function changes the current setting and sotre the setting to the EEPROM. If the iMode matchs the current setting, holds the currnet setting. iPort: 1 ~ total COM Port iMode: 0 (_VxComm) ==> VxComm (This is valid for 7188E/8000E) 1 (_ModbusRTU) ==> Modbus/RTU converter 2 (_Programming) ==> Programming The Modbus kernel doesn't control the COM port. Users can use the COM port to control other RS-232/485 devices. 3 (_UpLink) ==> UpLink Be a Modbus/RTU slave port. Modbus clients or masters (HMI or SCADA software) can send Modbus requests to the COM port. 4 (_Debug) ==> Debug The Modbus kernel prints out some messages while communicating with Modbus clients or masters. The messages includes (0) receives Modbus request response to Modbus clients or masters (1) by passes Modbus request to COM port (2) Send Modbus request to COM port (3) Check Modbus response from COM port (4) Send Modbus response to Modbus client or masters. Return: 0 ==> success -1 ==> writes the setting to EEPROM failure */ #define Set_Timeout Set_ModbusTimeout int Set_ModbusTimeout(int iPort, int iTimeout); /* Sets COM port timeout. If the iTimeout doesn't match the current setting, this function changes the current setting and sotre the setting to the EEPROM. If the iTimeout matchs the current setting, holds the currnet setting. iPort: 1 ~ iTotalCOMPort iTimeout: 5~32767 (ms) Return: 0 ==> success -1 ==> writes the setting to EEPROM failure */ //==================================================// // // // Modbus master functions // // for Modbus/RTU // // for Modbus/ASCII // // for Modbus/TCP // //==================================================// int ModbusRTU_Master(int iPort,unsigned char cNetID, unsigned char cFunction, int iLocalMemoryBaseAddress, int iRemoteMemoryBaseAddress,int iIOCount,unsigned long lTimeout,int iWait); /* This functions can send Modbus/RTU request to Modbus/Slave devices. 1. You just only change internal registers (iMemory_DI, iMemory_DO, iMemory_AI, iMemory_AO) then call this function to send out request to turn on coils or write analog registers. 2. Sends out iPort: 1 ==> COM1 2 ==> COM2 ... Sends request to which COM port? cNetID: 0~0xFF, the NetID (Station Number) of destination Modbus/Slave device. cFunction: 1 ==> Reads several DO from device, then puts to iMemory_DO. 2 ==> Reads several DI from device, then puts to iMemory_DI. 3 ==> Reads several AO from device, then puts to iMemory_AO. 4 ==> Reads several AI from device, then puts to iMemory_AI. 5 ==> Writes one DO from iMemory_DO to device. 6 ==> Writes one AO from iMemory_AO to device. 15 ==> Writes several DO from iMemory_DO to device. 16 ==> Writes several AO from iMemory_AO to device. 102 ==> Reads several DI from device, then puts to iMemory_DO (Use Fun 2). 104 ==> Reads several AI from device, then puts to iMemory_AO (Use Fun 4). 105 ==> Writes one DO from iMemory_DI to device's DO (Use Fun 5). 106 ==> Writes one AO from iMemory_AI to device's AO (Use Fun 6). 115 ==> Writes several DO from iMemory_DI to device's DO (Use Fun 15). 116 ==> Writes several AO from iMemory_AI to device's AO (Use Fun 16). iLocalMemoryBaseAddress: internal register base address that you want to deal. iRemoteMemoryBaseAddress: register base address of device that you want to deal. iIOCount: count of coils or registers that you want to deal. lTimeout: unit=ms iWait: 0=non-blocked communication mode if there is no data in COM port input buffer, return the function immediatly. 1=blocked communication mode wait to receive data till timeout, even there is no data in COM port input buffer. Return value: -1: CRC error -2: Receiving response timeout (no data) 0~255: Exception code from the Modbus slave device. 500: COM port is busy, cann't send command. 501: Command not sent yet. 502: Command already sent, but no data received. 503: parameters of previous command not match parameters of this commnad. (return code 500~503 are for wait=0 (non-blocked) mode) */ int ModbusRTU_Master_Send(int iPort,unsigned char cNetID, unsigned char cFunction, int iLocalMemoryBaseAddress, int iRemoteMemoryBaseAddress,int iIOCount); int ModbusRTU_Master_Receive(int iPort,unsigned char cNetID, unsigned char cFunction, int iLocalMemoryBaseAddress, int iRemoteMemoryBaseAddress,int iIOCount, unsigned long lTimeout,int iWait); int ModbusASCII_Master(int iPort,unsigned char cNetID, unsigned char cFunction, int iLocalMemoryBaseAddress, int iRemoteMemoryBaseAddress,int iIOCount,unsigned long lTimeout,int iWait); /* This functions can send Modbus/RTU request to Modbus/Slave devices. 1. You just only change internal registers (iMemory_DI, iMemory_DO, iMemory_AI, iMemory_AO) then call this function to send out request to turn on coils or write analog registers. 2. Sends out iPort: 1 ==> COM1 2 ==> COM2 ... Sends request to which COM port? cNetID: 0~0xFF, the NetID (Station Number) of destination Modbus/Slave device. cFunction: 1 ==> Reads several DO from device, then puts to iMemory_DO. 2 ==> Reads several DI from device, then puts to iMemory_DI. 3 ==> Reads several AO from device, then puts to iMemory_AO. 4 ==> Reads several AI from device, then puts to iMemory_AI. 5 ==> Writes one DO from iMemory_DO to device. 6 ==> Writes one AO from iMemory_AO to device. 15 ==> Writes several DO from iMemory_DO to device. 16 ==> Writes several AO from iMemory_AO to device. 102 ==> Reads several DI from device, then puts to iMemory_DO (Use Fun 2). 104 ==> Reads several AI from device, then puts to iMemory_AO (Use Fun 4). 105 ==> Writes one DO from iMemory_DI to device's DO (Use Fun 5). 106 ==> Writes one AO from iMemory_AI to device's AO (Use Fun 6). 115 ==> Writes several DO from iMemory_DI to device's DO (Use Fun 15). 116 ==> Writes several AO from iMemory_AI to device's AO (Use Fun 16). iLocalMemoryBaseAddress: internal register base address that you want to deal. iRemoteMemoryBaseAddress: register base address of device that you want to deal. iIOCount: count of coils or registers that you want to deal. lTimeout: unit=ms iWait: 0=non-blocked communication mode if there is no data in COM port input buffer, return the function immediatly. 1=blocked communication mode wait to receive data till timeout, even there is no data in COM port input buffer. Return value: -1: LRC error -2: Receiving response timeout (no data) 0~255: Exception code from the Modbus slave device. 500: COM port is busy, cann't send command. 501: Command not sent yet. 502: Command already sent, but no data received. 503: parameters of previous command not match parameters of this commnad. (return code 500~503 are for wait=0 (non-blocked) mode) */ int ModbusASCII_Master_Send(int iPort,unsigned char cNetID, unsigned char cFunction, int iLocalMemoryBaseAddress, int iRemoteMemoryBaseAddress,int iIOCount); int ModbusASCII_Master_Receive(int iPort,unsigned char cNetID, unsigned char cFunction, int iLocalMemoryBaseAddress, int iRemoteMemoryBaseAddress,int iIOCount,unsigned long lTimeout,int iWait); int ModbusTCP_Init(int iIndex,unsigned char *cRemote_IP,int iRemote_TCPPort, unsigned long lConnect_Timeout,unsigned long lReConnect_Time_Interval); /* Give Modbus/TCP intial values. there are 8 connections available. You can assign several connection to one IP address or one connection to each IP address. iIndex: 0~7. The library can assign totaly 8 connections. cRemote_IP: IP address for remote device. For example: "192.168.255.100" iRemote_TCPPort: TCP port for remote device. For example: 502 lConnect_Timeout: Timeout to connect to remote device. unit: ms lReConnect_Time_Interval: Time interval to reconnect to remote device when the return: 0= ok. other = Error. */ int ModbusTCP_Master2Slave(int iIndex,unsigned char cNetID, unsigned char cFunction, int iLocalMemoryBaseAddress, int iRemoteMemoryBaseAddress, int iIOCount, unsigned long lTimeout); /* This functions can send Modbus/TCP request to Modbus/Slave devices. 1. You just only change internal registers (iMemory_DI, iMemory_DO, iMemory_AI, iMemory_AO) then call this function to send out request to turn on coils or write analog registers. 2. Sends out iIndex: 0~7. The library can assign totaly 8 connections. Each connection's configuration is defined by function ModbusTCP_Init. cNetID: 0~0xFF, the NetID (Station Number) of destination Modbus/Slave device. cFunction: 1 ==> Reads several DO from device, then puts to iMemory_DO. 2 ==> Reads several DI from device, then puts to iMemory_DI. 3 ==> Reads several AO from device, then puts to iMemory_AO. 4 ==> Reads several AI from device, then puts to iMemory_AI. 5 ==> Writes one DO from iMemory_DO to device. 6 ==> Writes one AO from iMemory_AO to device. 15 ==> Writes several DO from iMemory_DO to device. 16 ==> Writes several AO from iMemory_AO to device. 102 ==> Reads several DI from device, then puts to iMemory_DO (Use Fun 2). 104 ==> Reads several AI from device, then puts to iMemory_AO (Use Fun 4). 105 ==> Writes one DO from iMemory_DI to device's DO (Use Fun 5). 106 ==> Writes one AO from iMemory_AI to device's AO (Use Fun 6). 115 ==> Writes several DO from iMemory_DI to device's DO (Use Fun 15). 116 ==> Writes several AO from iMemory_AI to device's AO (Use Fun 16). iLocalMemoryBaseAddress: internal register base address that you want to deal. iRemoteMemoryBaseAddress: register base address of device that you want to deal. iIOCount: count of coils or registers that you want to deal. lTimeout: 1~65535. unit: ms timeout to receive response from Modbus/Slave device. return: 0: No Error. Send the command ok, and receive the response ok. 502: Command already sent, but no data received. Keep to receive the response next time. 503: parameters of previous command not match parameters of this commnad. -1: connect to slave device error, try to re-connect next time interval. -2: connection is not builded. Cannot send command. -3: connect to the device ok, send command error, try to re-connect the device next time interval. -4: send command ok, wait response timeout, try to re-connect the device next time interval. -5: send command ok, receive response error. -6: the connection is closed or not initialized. You must call ModbusTCP_Init first then this function. */ int ModbusTCP_Close(int iIndex); /* Close the connection. iIndex: 0~7. The library can assign totaly 8 connections. */ void Modbus_Request_Event(char* CommandData,int* CommandLength); /* char* CommandData: For Modbus/TCP, it includes 6 leading bytes. (needful) For Modbus/RTU, it includes 6 leading bytes. (needless) int* CommandLength: For Modbus/TCP, it includes 6 leading bytes. For Modbus/RTU, it includes 6 leading bytes. Following related global variables are also usefull: extern unsigned int iModbusRequest_Fun; extern unsigned int iModbusRequest_Addr; extern unsigned int iModbusRequest_IOCount; extern unsigned long lModbusRequest_TimeTicks; */ void Modbus_Response_Event(char* ResponseData,int* ResponseLength); /* char* ResponseData: For Modbus/TCP, it includes 6 leading bytes. For Modbus/RTU, it doesn't include 6 leading bytes int* CommandLength: For Modbus/TCP, it includes 6 leading bytes. For Modbus/RTU, it doesn't include 6 leading bytes */ void Modbus_Memory_Size(int iMemory_Size_DI, int iMemory_Size_DO, int iMemory_Size_AI, int iMemory_Size_AO); /* Sets the sizes for 4 global arrays. step 1. declare 4 global arrays step 2. give the 4 array pointers to InitModbus. step 3. set the sizes after calling the InitModbus() function For example: unsinged char far Array_DI[100]; unsinged char far Array_DO[100]; int far Array_AI[100]; int far Array_AO[100]; main() { InitModbus(Array_DI,Array_DO,Array_AI,Array_AO); Modbus_Memory_Size(100, 100, 100, 100); .... .... } */ #ifdef __cplusplus } #endif