ioPAC RTU Controllers
C/C++ Sample Code Programming Guide
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Data Structures | Macros | Typedefs | Functions | Variables
modbus_tcp_master.c File Reference

Modbus TCP Master Sample Application More...

#include <libmoxa_rtu.h>

Data Structures

struct  _MODBUS_TAB
 

Macros

#define MODBUS_TCP_IP   "192.168.13.44"
 
#define MODBUS_TCP_PORT   502
 
#define MODBUS_TCP_TIMEOUT   1000
 
#define DIM(x)   (sizeof(x)/sizeof(x[0]))
 

Typedefs

typedef struct _MODBUS_TAB MODBUS_TAB
 

Functions

int ipCheck (char *ip)
 
void gotoxy (int x, int y)
 
int modbusMasterInit (char *szIPAddr, int port, int idleTimeout, UINT32 *pHandle)
 
int modbusMasterUninit (UINT32 *pHandle)
 
int main (int argc, char **const argv)
 

Variables

MODBUS_TAB ModbusTab []
 

Detailed Description

Modbus TCP Master Sample Application

Date
03-27-2013
Author
Wanhan Hsieh
Version
V1.0
modbus_tcp.jpg
Modbus TCP Master Sample Application
Introduction:
The Modbus Slave creates two Modbus addresses, one for DIs (input register) and one for DOs (holding register).
Then, the Modbus Master polls for DI values and sets the DO statuses equal to the DI values.
Both the Slave and the Master use Moxa Modbus APIs (modbus_tcp_slave and modbus_tcp_master).
Example:
1. Using default: ./modbus_tcp_master
2. Setting port: ./modbus_tcp_master -p1234
Default:
IP of Modbus TCP Slave = 192.168.13.44
Port of Modbus TCP Slave = 502
Help:
root@Moxa:/tmp#./modbus_tcp_master -h
Modbus TCP master sample program.

Usage: ./modbus_tcp_master [OPTIONS]

Options:
        -i       IP of Modbus TCP Slave. Default IP = 192.168.13.44
        -p       Port of Modbus TCP Slave. Default slot = 502

Library:
ModbusTCPMaster APIs

Macro Definition Documentation

#define MODBUS_TCP_IP   "192.168.13.44"
#define MODBUS_TCP_PORT   502
#define MODBUS_TCP_TIMEOUT   1000
#define DIM (   x)    (sizeof(x)/sizeof(x[0]))

Typedef Documentation

typedef struct _MODBUS_TAB MODBUS_TAB

Function Documentation

int ipCheck ( char *  ip)
void gotoxy ( int  x,
int  y 
)
int modbusMasterInit ( char *  szIPAddr,
int  port,
int  idleTimeout,
UINT32 pHandle 
)
int modbusMasterUninit ( UINT32 pHandle)
int main ( int  argc,
char **const  argv 
)
/*******************************************************************************
* Copyright Moxa Inc.
*
* Modbus TCP Master Sample Application
*
* Date Author Comment
* 03-27-2013 Wanhan Hsieh Created.
******************************************************************************/
#include <libmoxa_rtu.h>
//#define MODBUS_TCP_IP "192.168.127.254"
#define MODBUS_TCP_IP "192.168.13.44"
#define MODBUS_TCP_PORT 502
#define MODBUS_TCP_TIMEOUT 1000
#define DIM(x) (sizeof(x)/sizeof(x[0]))
typedef struct _MODBUS_TAB
{
UINT8 group;
UINT16 addr;
UINT32 reg;
{
{ MODBUS_INPUT_REGISTER, 0x0800, 0 },
{ MODBUS_HOLDING_REGISTER, 0x0810, 0 },
};
int ipCheck(char *ip)
{
int count = 3;
char *pch;
pch = ip;
while(count)
{
pch = strstr(pch, ".");
if(pch == NULL) return -1;
pch++;
count--;
}
return 0;
}
void gotoxy(int x, int y)
{
printf("%c[%d;%df", 0x1B, y, x);
}
int modbusMasterInit(char *szIPAddr, int port, int idleTimeout, UINT32 *pHandle)
{
int rc = 0;
int unitID = 1;
{
printf("MX_RTU_Modbus_Master_Init(), return code = %d\n", rc);
}
else
{
rc = MX_RTU_Modbus_Tcp_Master_Open(szIPAddr, port, idleTimeout, pHandle);
{
printf("MX_RTU_Modbus_Tcp_Master_Open(%s, %d, %d), return code = %d\n",
szIPAddr, port, idleTimeout, rc);
}
else
{
rc = MX_RTU_Modbus_Tcp_Master_Ioctl(*pHandle, unitID, idleTimeout);
{
printf("MX_RTU_Modbus_Tcp_Master_Ioctl(%d, %d, %d), return code = %d\n",
*pHandle, unitID, idleTimeout, rc);
}
}
}
return rc;
}
int modbusMasterUninit(UINT32 *pHandle)
{
int rc = 0;
printf("MX_RTU_Modbus_Tcp_Master_Close(%d), return code = %d\n", *pHandle, rc);
return rc;
}
/*******************************************************************************
*
* Sample code for Modbus TCP Master
*
******************************************************************************/
int main(int argc, char **const argv)
{
int rc, i;
UINT8 szIPAddr[20];
int port = MODBUS_TCP_PORT;
UINT32 handle;
int idleTimeoutMS = MODBUS_TCP_TIMEOUT;
int tabSize = DIM(ModbusTab);
UINT32 *pDIValue;
UINT32 *pDOValue;
UINT32 lastDOValue;
memset(szIPAddr, 0, sizeof(szIPAddr));
sprintf(szIPAddr, MODBUS_TCP_IP);
while(-1 != (rc = getopt(argc, argv, "hi:p:")))
{
switch(rc)
{
case 'i':
if(ipCheck(optarg) < 0)
{
printf("Invalid IP\r\n");
return -1;
}
memset(szIPAddr, 0, sizeof(szIPAddr));
strncpy(szIPAddr, optarg, strlen(optarg));
break;
case 'p':
port = atoi(optarg);
if(port < 0)
{
printf("Error parameter: port: %d\n", port);
return -1;
}
break;
case '?':
case 'h':
default:
printf("Modbus TCP master sample program.\n\n");
printf("Usage: ./modbus_tcp_master [OPTIONS]\n\n");
printf("Options:\n");
printf("\t%-8s IP of Modbus TCP Slave. Default IP = %s\n",
"-i", szIPAddr);
printf("\t%-8s Port of Modbus TCP Slave. Default port = %d\n",
"-p", port);
printf("\n");
return;
}
}
system("clear");
printf("%-10s: %s\n", "Slave IP", szIPAddr);
printf("%-10s: %d\n", "Slave port", port);
pDIValue = &(ModbusTab[0].reg);
pDOValue = &(ModbusTab[1].reg);
lastDOValue = *pDOValue;
rc = modbusMasterInit(szIPAddr, port, idleTimeoutMS, &handle);
printf("ModbusMasterInit(), return code = %d.\n\n", rc);
// print the frame
gotoxy(0, 4);
printf("========================================");
for(i = 0; i < tabSize; i++)
printf("\n[0x%02X%04X] -> ", ModbusTab[i].group, ModbusTab[i].addr);
gotoxy(0, 4 + tabSize + 1);
printf("========================================");
// Start to polling (remote) DI and set (remote) DO
for(i = 0; tabSize > 0; i++)
{
if(i >= tabSize)
i = 0;
switch(ModbusTab[i].group)
{
rc = MX_RTU_Modbus_Tcp_Master_Read_Coils(handle, ModbusTab[i].addr,
1, (UINT8*) & (ModbusTab[i].reg));
printf("MX_RTU_Modbus_Tcp_Master_Read_Coils(%d, 0x%04X, %d), return code = %d.\n",
handle, ModbusTab[i].addr, 1, rc);
break;
rc = MX_RTU_Modbus_Tcp_Master_Read_Discrete_Inputs(handle, ModbusTab[i].addr,
1, (UINT8*) & (ModbusTab[i].reg));
printf("MX_RTU_Modbus_Tcp_Master_Read_Discrete_Inputs(%d, 0x%04X, %d), return code = %d.\n",
handle, ModbusTab[i].addr, 1, rc);
break;
ModbusTab[i].addr, 1, (UINT16*) & (ModbusTab[i].reg));
printf("MX_RTU_Modbus_Tcp_Master_Write_Holding_Regs(%d, 0x%04X, %d), return code = %d.\n",
handle, ModbusTab[i].addr, 1, rc);
ModbusTab[i].addr, 1, (UINT16*) & (ModbusTab[i].reg));
printf("MX_RTU_Modbus_Tcp_Master_Read_Holding_Regs(%d, 0x%04X, %d), return code = %d.\n",
handle, ModbusTab[i].addr, 1, rc);
break;
ModbusTab[i].addr, 1, (UINT16*) & (ModbusTab[i].reg));
printf("MX_RTU_Modbus_Tcp_Master_Read_Input_Regs(%d, 0x%04X, %d), return code = %d.\n",
handle, ModbusTab[i].addr, 1, rc);
break;
default:
printf("Error Modbus group: %d\n", ModbusTab[i].group);
continue;
}
break;
gotoxy(15, i + 5); // reposition cursor
printf("0x%04X", ModbusTab[i].reg);
fflush(0);
if(*pDIValue == 0x0BAD)
*pDOValue = 0xFFFF;
else
*pDOValue = *pDIValue;
usleep(200000);
}
rc = modbusMasterUninit(&handle);
printf("ModbusMasterUninit(%d), return code = %d.\n\n", handle, rc);
return 0;
}

Variable Documentation

MODBUS_TAB ModbusTab[]
Initial value:
=
{
{ MODBUS_INPUT_REGISTER, 0x0800, 0 },
{ MODBUS_HOLDING_REGISTER, 0x0810, 0 },
}