#ifndef __MB_XS_H #define __MB_XS_H #ifdef __cplusplus extern "C" { #endif #ifndef _COM_DATA_ #define _COM_DATA_ typedef struct COM_DATA { unsigned long baud; char databit; char parity; char stopbit; unsigned char sum; } *pCOM_DATA, COM_DATA; #endif extern COM_DATA ComData[]; #define _VxComm 0 #define _ModbusRTU_Gateway 1 /* ==> Modbus/RTU Gateway */ #define _Programming 2 /* ==> Programming */ #define _ModbusRTU_Slave 3 /* ==> Modbus/RTU slave */ #define _Debug 4 /* ==> Debug (print debug message) */ #define _Console 5 /* ==> Reserved */ #define _ModbusASCII_Slave 6 /* ==> Modbus/ASCII slave */ void VcomSaveComData(int iPort); int VcomCmdModbus(TCPREADDATA *p); 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]; void XS_UserInit(int argc, char *argv[]) { 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 StopModbus(void); /* Release the resource which the Modbus kernal occupied. StopModbus() should be called before exiting the program. Note: StopModbus() is available for the versions later than Modbus lib 1.7.3. */ void ModbusLoopFun(void); /* ModbusLoopFun() is responsible for handling the event loop, and it ensures that Modbus messages related to events are delivered to targets within the Modbus kernel. ModbusLoopFun() must be called repeatedly in the main loop of the code in order to process the Modbus messages. Note: ModbusLoopFun() is available for the versions later than Modbus lib 1.7.3. */ int Set_NetID(int iNetID); /* Set 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 */ 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 CheckModbusASCIIRequest(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. */ int ModbusTCP_Init(int index, unsigned char *Remote_IP, int Remote_Port, 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. index: 0~7. The library can assign totaly 8 connections. Remote_IP: IP address of remote slave device. For example: "192.168.255.100" Remote_TCPPort: Modbus/TCP Port of remote slave device. For example: 502 lConnect_Timeout: The length of time to wait for a connection to the slave device. (unit: ms) lReConnect_Time_Interval: The reconnect interval is the amount of time between attempts by the master to reconnect with the slave device. return: 0: On success, it returns 0 -1: An invalid index is specified */ int ModbusTCP_Master2Slave(int index, unsigned char NetID, unsigned char Function, 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 index: 0~7. The library can assign totaly 8 connections. Each connection's configuration is defined by function ModbusTCP_Init. NetID: 0~0xFF, the NetID (Station Number) of destination Modbus/Slave device. Function: 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: The period of which the master is waiting for a response from the slave device. return: 0: Receive a normal response without any error 1~6: An exception response is recevied from slave device 502: Send a query to a slave device without a communication error, and wait for a response 503: Parameters of previous command not match parameters of this commnad -2: A query has already been sent to a slave device without a communication error, but no response was received during the timeout period -3: Connection to slave is not established -5: An invalid connection is detected -6: An invalid index is specified */ int ModbusTCP_Close(int index); /* Close the connection. index: 0~7. The library can assign totaly 8 connections. return: 0: On success, it returns 0. -1: An invalid index is specified */ 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 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/ASCII 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) */ void SendModbusRequest(int iPort); /* SendModbusRequest() is responsible for sending Modbus queries to slave devices over serial port, and it is available while the enable mode is set to Modbus/RTU gateway. In the versions later than 1.7.3, SendModbusRequest() is integrated into ModbusLoopFun(). */ void CheckResponseTimeout(int iPort); /* CheckResponseTimeout() is used to determine whether the slave device is responding to a Modbus query. If the waiting before receiving the response is longer than the given tiemout, the received response will be dropped. This function is available while the enable mode is set to Modbus/RTU gateway. In the versions later than 1.7.3, CheckResponseTimeout() is integrated into ModbusLoopFun(). */ void CheckModbusResponse(int iPort); /* CheckModbusResponse() is responsible for receiving response from the slave device, and it is available while the enable mode is set to Modbus/RTU gateway. In the versions later than 1.7.3, CheckModbusResponse() is integrated into ModbusLoopFun(). */ void SendModbusResponse(int iPort); /* SendModbusResponse() is responsible for transmitting the response received from the slave device to the host via Ethernet, and it is available while the enable mode is set to Modbus/RTU gateway. In the versions later than 1.7.3, SendModbusResponse() is integrated into ModbusLoopFun(). */ #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 mode is available to 7188E/7186EX/8000E) 1 (_ModbusRTU_Gateway) ==> Modbus TCP to RTU gateway 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 (_ModbusRTU_Slave) ==> Modbus/RTU salve 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 debug 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 5 (_Console) ==> Reserved 6 (_ModbusASCII_Slave) ==> Modbus/ASCII salve 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 */ 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]; void XS_UserInit(void) { InitModbus(Array_DI, Array_DO, Array_AI, Array_AO); Modbus_Memory_Size(100, 100, 100, 100); .... .... } */ #ifdef __cplusplus } #endif #endif