ioPAC RTU Controllers
C/C++ Sample Code Programming Guide
Macros | Functions
modbus_rtu_master.c File Reference

Modbus RTU Master Sample Application More...

#include <libmoxa_rtu.h>

Macros

#define MAX_SERIAL_PORT   3
 

Functions

int main (int argc, char *argv[])
 

Detailed Description

Modbus RTU Master Sample Application

Date
04-10-2013
Author
Eddy Kao
Version
V1.0
modbus_rtu_master.jpg
Modbus RTU Master
Introduction:
PC sets up a Modbus RTU Slave, using Modbus Slave Version 4.3.1, and builds a modbus address for an AI value.
Then, the controller will then set the DO status to be ON or OFF according to the AI value.
Example:
1. Using default: ./modbus_rtu_master
2. Setting port, Unit ID, and AI Address: ./modbus_rtu_master -p1 -u32 -a8192
Default:
Slot = 0
Port = 0
Unit ID = 0x10 (16)
AI Address = 0x1000 (4096)
DO Slot = 1
DO Channel = 0
Help:
root@Moxa:/tmp#./modbus_rtu_master -h
Modbus RTU Master.

Usage: ./modbus_rtu_master [OPTIONS]

Options:
        -s       slot [0-9]. Default slot = 0
                 (slot 0: Built-in COM Ports, slot 1 ~ 9: Expansion COM Ports)
        -p       port [0-3]. Default port = 0
        -u       Unit ID [0x0-0xffff]. Default Unit ID = 0x10 (16)
        -a       AI Address [0x0-0xffff]. Default AI Address = 0x1000 (4096)
        -S       DO slot [0-9]. Default DO slot = 1
                 (slot 0: Built-in IO, slot 1 ~ 9: IO Module)
        -C       DO channel [0-24]. Default DO channel = 0

Library:
ModbusMaster APIs

Macro Definition Documentation

#define MAX_SERIAL_PORT   3

Function Documentation

int main ( int  argc,
char *  argv[] 
)
/*******************************************************************************
* Copyright Moxa Inc.
*
* Modbus RTU Master
*
* Date Author Comment
* 04-10-2013 Eddy Kao Created.
******************************************************************************/
#include <libmoxa_rtu.h>
#define MAX_SERIAL_PORT 3
int main(int argc, char *argv[])
{
int retval = 0;
UINT32 rc = 0;
UINT8 slot = 0;
UINT8 port = PORT1;
UINT8 unitID = 0x10;
UINT16 aiAddress = 0x1000;
UINT32 timeoutMs = 5 * 1000; //5 seconds
float aiValue = 0;
UINT8 doSlot = 1;
UINT8 doChannel = 0;
UINT32 doValue = 0;
TTY_PARAM param;
UINT8 exceptionCode = 0;
while((retval = getopt(argc, argv, "hs:p:u:a:S:C:")) != -1)
{
switch(retval)
{
case 's':
slot = atoi(optarg);
if(slot > MAX_SLOT)
{
printf("Error serial slot = %d\r\n", slot);
exit(1);
}
break;
case 'p':
port = atoi(optarg);
if(port > MAX_SERIAL_PORT)
{
printf("Error serial port = %d\r\n", port);
exit(1);
}
break;
case 'u':
unitID = atoi(optarg);
break;
case 'a':
aiAddress = atoi(optarg);
break;
case 'S':
doSlot = atoi(optarg);
if(doSlot > MAX_SLOT)
{
printf("Error DO slot = %d\r\n", doSlot);
exit(1);
}
break;
case 'C':
doChannel = atoi(optarg);
if(doChannel > MAX_CHANNEL)
{
printf("Error DO channel = %d\r\n", doChannel);
exit(1);
}
break;
case '?':
case 'h':
default:
printf("Modbus RTU Master.\n\n");
printf("Usage: ./modbus_rtu_master [OPTIONS]\n\n");
printf("Options:\n");
printf("\t%-8s slot [%d-%d]. Default slot = %d\n", "-s", 0, MAX_SLOT, slot);
printf("\t%-8s (slot 0: Built-in COM Ports, slot 1 ~ 9: Expansion COM Ports)\n", "");
printf("\t%-8s port [%d-%d]. Default port = %d\n", "-p", 0, MAX_SERIAL_PORT, port);
printf("\t%-8s Unit ID [0x%x-0x%x]. Default Unit ID = 0x%x (%d)\n", "-u", 0x0, 0xFFFF, unitID, unitID);
printf("\t%-8s AI Address [0x%x-0x%x]. Default AI Address = 0x%x (%d)\n", "-a", 0x0, 0xFFFF, aiAddress, aiAddress);
printf("\t%-8s DO slot [%d-%d]. Default DO slot = %d\n", "-S", 0, MAX_SLOT, doSlot);
printf("\t%-8s (slot 0: Built-in IO, slot 1 ~ 9: IO Module)\n", "");
printf("\t%-8s DO channel [%d-%d]. Default DO channel = %d\n", "-C", 0, MAX_CHANNEL, doChannel);
printf("\n");
return 0;
}
}
{
printf("MX_RTU_Modbus_Master_Init(), return code = %d\r\n", rc);
exit(1);
}
memset(&param, 0, sizeof(param));
param.mode = RS232_MODE;
printf("Slot = %d, Port = %d, UnitID = 0x%x, AI Address = 0x%x, DO Slot = %d, DO Channel = %d\r\n", slot, port, unitID, aiAddress, doSlot, doChannel);
rc = MX_RTU_Modbus_Rtu_Master_Open(slot, port, &param);
{
printf("MX_RTU_Modbus_Rtu_Master_Open(%d, %d, &param), return code = %d\r\n", slot, port, rc);
exit(1);
}
while(1)
{
//AI Value: Low Word + HIGH Word
rc = MX_RTU_Modbus_Rtu_Master_Read_Input_Regs(slot, port, unitID, aiAddress, 2, (UINT16 *)&aiValue, timeoutMs, &exceptionCode);
{
printf("MX_RTU_Modbus_Rtu_Master_Read_Input_Regs(%d, %d, 0x%x, 0x%x, %d, &aiValue, %d), return code = %d, exception code = %d\r\n", slot, port, unitID, aiAddress, 2, timeoutMs, rc, exceptionCode);
exit(1);
}
if(aiValue >= 5.0)
{
rc = MX_RTU_Module_DO_Value_Get(doSlot, &doValue);
if(rc != MODULE_RW_ERR_OK)
{
printf("MX_RTU_Module_DO_Value_Get(%d, &doValue), return code = %d\r\n", doSlot, rc);
exit(1);
}
doValue |= (1 << doChannel);
rc = MX_RTU_Module_DO_Value_Set(doSlot, doValue);
if(rc != MODULE_RW_ERR_OK)
{
printf("MX_RTU_Module_DO_Value_Set(%d, %x), return code = %d\r\n", doSlot, doValue, rc);
exit(1);
}
}
else
{
rc = MX_RTU_Module_DO_Value_Get(doSlot, &doValue);
if(rc != MODULE_RW_ERR_OK)
{
printf("MX_RTU_Module_DO_Value_Get(%d, &doValue), return code = %d\r\n", doSlot, rc);
exit(1);
}
doValue &= ~(1 << doChannel);
rc = MX_RTU_Module_DO_Value_Set(doSlot, doValue);
if(rc != MODULE_RW_ERR_OK)
{
printf("MX_RTU_Module_DO_Value_Set(%d, %x), return code = %d\r\n", doSlot, doValue, rc);
exit(1);
}
}
if(aiValue > 8.0) break;
sleep(1);
}
{
printf("MX_RTU_Modbus_Rtu_Master_Close(%d, %d), return code = %d\r\n", slot, port, rc);
exit(1);
}
return 0;
}