linux下modbus tcp,CentOS5.4 Linux下Modbus TCP IP协议C++的一个小例子

///

/*

ReadCoils函数:

读继电器的状态 , 成功返回ture。

send 数据长度=12

recv 数据长度=10

unsigned short int addr 读继电器的起始地址(继电器编号-1) 。

注意:1~8个继电器,起始地址从0开始

unsigned short int len 读取继电器的个数,最大8.

debug_state 如果为1 打印出调式信息

ubool *paraDO 读出的继电器状态

SOCKET s_bnc,fd_set fds,timeval tv 是辅助的网络接口参数

*/

///

inline bool ReadCoils(unsigned short int addr, byte & coilstate, SOCKET_INT s_bnc)

{

cmd_len = 12;

byte cmd_code = 1; //命令代码:01,读继电器

byte *cmd_string ;

byte *echo_string ;

cmd_string = new byte[cmd_len] ;

echo_string = new byte[cmd_len] ;

cmd_string[ 0] = 0 ; // modbus 协议规定标示

cmd_string[ 1] = 0 ;

cmd_string[ 2] = 0 ;

cmd_string[ 3] = 0 ;

cmd_string[ 4] = 0 ; // length 高位部分 命令的后续字节数量

cmd_string[ 5] = 6 ; // length 低位部分 命令的后续字节数量

cmd_string[ 6] = 0 ; // Unit Identifier :identification of a remote slave connected on a serial line or on other buses.

cmd_string[ 7] = cmd_code ;

cmd_string[ 8] = (unsigned char) (addr >> 8);

cmd_string[ 9] = (unsigned char) addr;

cmd_string[10] = 0; //(unsigned char) (len >> 8);

cmd_string[11] = 8; //(unsigned char) len ;

int iret;

fd_set fds;

struct timeval tv;

tv.tv_sec = SLEEP ; //超时等待时

tv.tv_usec = 0;

FD_ZERO(&fds);

FD_SET(s_bnc, &fds);

/* wait for permission to send(等待是否可写write)*/

iret = select(s_bnc +1, NULL, &fds, NULL, &tv); /*write*/

if (iret=0)

{

if(debug_state) printf("Timer over!n");

close(s_bnc);

return false ;

}

else if (iret<0)

{

if(debug_state) printf("select is err! n");

close(s_bnc);

return false ;

}

/*send 写入数据 */

iret = send(s_bnc, (char *)cmd_string, cmd_len , 0);

if (iret < cmd_len)

{

if(debug_state) printf("failed to send chars:%dn",iret);

close(s_bnc);

return false;

}

/*wait for response(等待是否可读read)*/

FD_SET(s_bnc, &fds);

iret = select(s_bnc +1 , &fds, NULL, NULL, &tv);

if (iret=0)

{

if(debug_state) printf("Timer over!n");

close(s_bnc);

return false ;

}

else if (iret<0)

{

if(debug_state) printf("select is err! n");

close(s_bnc);

return false ;

}

/*读出数据 */

iret = recv(s_bnc, (char *)echo_string, 12 , 0);

if (iret<=0)

{

if(debug_state) printf("接受数据recv语句出错n");

}

if ( echo_string[7] == cmd_code) /*7位置是命令*/

{

/*if(debug_state) printf("n读数据成功了n");*/

}

else if ( echo_string[7] == (0x80 | cmd_code))

{

if(debug_state) printf("设备主动报告:操作出错n");

return false;

}

else

{

if(debug_state) printf("出错n");

return false;

}

//int nDOFlag = echo_string[9] |echo_string[10] << 8); //9位置10位置是继电器的状态

//unsigned char nDOFlag = echo_string[9]; //因为E3018只有8个继电器,故没有10位置

coilstate = echo_string[9];

delete []cmd_string;

delete []echo_string;

return true;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值