///
/*
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;
}