| ioPAC RTU Controllers C/C++ Sample Code Programming Guide

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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

Copyright
  Moxa Inc.

Date
  03-27-2013

Author
  Wanhan Hsieh

Version
  V1.0
  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_TAB;
MODBUS_TAB ModbusTab[] =
{
{ 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;
rc = MX_RTU_Modbus_Master_Init();
if(rc != MODBUS_MASTER_ERR_OK)
{
printf("MX_RTU_Modbus_Master_Init(), return code = %d\n", rc);
}
else
{
rc = MX_RTU_Modbus_Tcp_Master_Open(szIPAddr, port, idleTimeout, pHandle);
if(rc != MODBUS_MASTER_ERR_OK)
{
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);
if(rc != MODBUS_MASTER_ERR_OK)
{
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;
rc = MX_RTU_Modbus_Tcp_Master_Close(*pHandle);
if(rc != MODBUS_MASTER_ERR_OK)
printf("MX_RTU_Modbus_Tcp_Master_Close(%d), return code = %d\n", *pHandle, rc);
MX_RTU_Modbus_Master_Uninit();
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;
UINT8 exceptionCode = 0;
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 0;
}
}
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);
if(rc != MODBUS_MASTER_ERR_OK)
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)
{
case MODBUS_COIL:
rc = MX_RTU_Modbus_Tcp_Master_Read_Coils(handle, ModbusTab[i].addr,
1, (UINT8*) & (ModbusTab[i].reg), &exceptionCode);
if(rc != MODBUS_MASTER_ERR_OK)
printf("MX_RTU_Modbus_Tcp_Master_Read_Coils(%d, 0x%04X, %d), return code = %d, exception code = %d.\n",
handle, ModbusTab[i].addr, 1, rc, exceptionCode);
break;
case MODBUS_INPUT_COIL:
rc = MX_RTU_Modbus_Tcp_Master_Read_Discrete_Inputs(handle, ModbusTab[i].addr,
1, (UINT8*) & (ModbusTab[i].reg), &exceptionCode);
if(rc != MODBUS_MASTER_ERR_OK)
printf("MX_RTU_Modbus_Tcp_Master_Read_Discrete_Inputs(%d, 0x%04X, %d), return code = %d, exception code = %d.\n",
handle, ModbusTab[i].addr, 1, rc, exceptionCode);
break;
case MODBUS_HOLDING_REGISTER:
rc = MX_RTU_Modbus_Tcp_Master_Write_Holding_Regs(handle,
ModbusTab[i].addr, 1, (UINT16*) & (ModbusTab[i].reg), &exceptionCode);
if(rc != MODBUS_MASTER_ERR_OK)
printf("MX_RTU_Modbus_Tcp_Master_Write_Holding_Regs(%d, 0x%04X, %d), return code = %d, exception code = %d.\n",
handle, ModbusTab[i].addr, 1, rc, exceptionCode);
rc = MX_RTU_Modbus_Tcp_Master_Read_Holding_Regs(handle,
ModbusTab[i].addr, 1, (UINT16*) & (ModbusTab[i].reg), &exceptionCode);
if(rc != MODBUS_MASTER_ERR_OK)
printf("MX_RTU_Modbus_Tcp_Master_Read_Holding_Regs(%d, 0x%04X, %d), return code = %d, exception code = %d.\n",
handle, ModbusTab[i].addr, 1, rc, exceptionCode);
break;
case MODBUS_INPUT_REGISTER:
rc = MX_RTU_Modbus_Tcp_Master_Read_Input_Regs(handle,
ModbusTab[i].addr, 1, (UINT16*) & (ModbusTab[i].reg), &exceptionCode);
if(rc != MODBUS_MASTER_ERR_OK)
printf("MX_RTU_Modbus_Tcp_Master_Read_Input_Regs(%d, 0x%04X, %d), return code = %d, exception code = %d.\n",
handle, ModbusTab[i].addr, 1, rc, exceptionCode);
break;
default:
printf("Error Modbus group: %d\n", ModbusTab[i].group);
continue;
}
if(rc != MODBUS_MASTER_ERR_OK)
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);
if(rc != MODBUS_MASTER_ERR_OK)
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 },
}
MODBUS_HOLDING_REGISTER
#define MODBUS_HOLDING_REGISTER
Definition: libmoxa_rtu.h:4086
MODBUS_INPUT_REGISTER
#define MODBUS_INPUT_REGISTER
Definition: libmoxa_rtu.h:4087