832 lines
24 KiB
C++
832 lines
24 KiB
C++
#include "modbustcp.h"
|
||
|
||
#include "deviceproxy.h"
|
||
|
||
|
||
ModbusTCP* ModbusTCP::uniqueInstance = nullptr;
|
||
ModbusTCP* ModbusTCP::instance()
|
||
{
|
||
if (!uniqueInstance) {
|
||
uniqueInstance = new ModbusTCP();
|
||
}
|
||
return uniqueInstance;
|
||
}
|
||
ModbusTCP::ModbusTCP()
|
||
{
|
||
sockfd = INVALID_SOCKET;
|
||
sockfd_fl = INVALID_SOCKET;
|
||
sockfd_record = INVALID_SOCKET;
|
||
port = 502;
|
||
ipAddr = "";
|
||
ipAddr_fl = "";
|
||
ipAddr_record = "";
|
||
ipAddr_electric_resistance = "";
|
||
_seq_modbus = 0;
|
||
_seq_modbus_fl = 0;
|
||
stopFlag = false;
|
||
memset(RFID,0,50);
|
||
PLCSts[0] = -1;
|
||
PLCSts[1] = -1;
|
||
TransferPLCCmd.cmdAddr = 0;
|
||
TransferPLCCmd.cmdDelay = 0;
|
||
TransferPLCCmd.cmdWriteFlag = false;
|
||
SeparatePLCCmd.cmdAddr = 0;
|
||
SeparatePLCCmd.cmdDelay = 0;
|
||
SeparatePLCCmd.cmdWriteFlag = false;
|
||
WORD sockVersion = MAKEWORD(2, 2);
|
||
WSADATA data;
|
||
WSAStartup(sockVersion, &data);
|
||
|
||
InitializeCriticalSection(&mCsRead);
|
||
InitializeCriticalSection(&mCsRead_fl);
|
||
}
|
||
|
||
ModbusTCP::~ModbusTCP(void)
|
||
{
|
||
if (sockfd != INVALID_SOCKET)
|
||
{
|
||
CloseConn();
|
||
}
|
||
if (sockfd_fl != INVALID_SOCKET)
|
||
{
|
||
CloseConn_fl();
|
||
}
|
||
if (sockfd_record != INVALID_SOCKET)
|
||
{
|
||
CloseConn_record();
|
||
}
|
||
|
||
sockfd = INVALID_SOCKET;
|
||
sockfd_fl = INVALID_SOCKET;
|
||
sockfd_record = INVALID_SOCKET;
|
||
WSACleanup();
|
||
}
|
||
|
||
bool ModbusTCP::ConnPLC()
|
||
{
|
||
struct sockaddr_in server_addr;
|
||
char* ip;
|
||
QByteArray ba = ipAddr.toLatin1(); // must
|
||
ip=ba.data();
|
||
|
||
|
||
|
||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||
if (sockfd == INVALID_SOCKET) {
|
||
//printf("Failed to create socket: %s\n", strerror(errno));
|
||
return false;
|
||
}
|
||
server_addr.sin_family = AF_INET;
|
||
server_addr.sin_port = htons(port);
|
||
//inet_pton(AF_INET, "server_ip", &server_addr.sin_addr.s_addr);
|
||
server_addr.sin_addr.s_addr = inet_addr(ip);
|
||
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
|
||
//printf("Failed to connect to server: %s\n", strerror(errno));
|
||
closesocket(sockfd);
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool ModbusTCP::ConnPLC_fl()
|
||
{
|
||
struct sockaddr_in server_addr;
|
||
char* ip;
|
||
QByteArray ba = ipAddr_fl.toLatin1(); // must
|
||
ip=ba.data();
|
||
|
||
|
||
sockfd_fl = socket(AF_INET, SOCK_STREAM, 0);
|
||
if (sockfd_fl == INVALID_SOCKET) {
|
||
//printf("Failed to create socket: %s\n", strerror(errno));
|
||
return false;
|
||
}
|
||
server_addr.sin_family = AF_INET;
|
||
server_addr.sin_port = htons(port);
|
||
//inet_pton(AF_INET, "server_ip", &server_addr.sin_addr.s_addr);
|
||
server_addr.sin_addr.s_addr = inet_addr(ip);
|
||
if (connect(sockfd_fl, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
|
||
//printf("Failed to connect to server: %s\n", strerror(errno));
|
||
closesocket(sockfd_fl);
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
bool ModbusTCP::ConnPLC_force()
|
||
{
|
||
struct sockaddr_in server_addr;
|
||
char* ip;
|
||
QByteArray ba = ipAddr_record.toLatin1(); // must
|
||
ip=ba.data();
|
||
|
||
sockfd_record = socket(AF_INET, SOCK_STREAM, 0);
|
||
if (sockfd_record == INVALID_SOCKET) {
|
||
//printf("Failed to create socket: %s\n", strerror(errno));
|
||
return false;
|
||
}
|
||
server_addr.sin_family = AF_INET;
|
||
server_addr.sin_port = htons(6000);
|
||
//inet_pton(AF_INET, "server_ip", &server_addr.sin_addr.s_addr);
|
||
server_addr.sin_addr.s_addr = inet_addr(ip);
|
||
if (connect(sockfd_record, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
|
||
//printf("Failed to connect to server: %s\n", strerror(errno));
|
||
closesocket(sockfd_record);
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
bool ModbusTCP::ConnPLC_electric_resistance()
|
||
{
|
||
struct sockaddr_in server_addr;
|
||
char* ip;
|
||
//ipAddr_electric_resistance = "192.168.30.6";
|
||
QByteArray ba = ipAddr_electric_resistance.toLatin1(); // must AF_LOCAL
|
||
ip=ba.data();
|
||
|
||
sockfd_electric_resistance = socket(AF_INET, SOCK_STREAM, 0);
|
||
if (sockfd_electric_resistance == INVALID_SOCKET) {
|
||
//printf("Failed to create socket: %s\n", strerror(errno));
|
||
return false;
|
||
}
|
||
server_addr.sin_family = AF_INET;
|
||
server_addr.sin_port = htons(6677);
|
||
//inet_pton(AF_INET, "server_ip", &server_addr.sin_addr.s_addr);
|
||
server_addr.sin_addr.s_addr = inet_addr(ip);
|
||
if (connect(sockfd_electric_resistance, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
|
||
//printf("Failed to connect to server: %s\n", strerror(errno));
|
||
closesocket(sockfd_electric_resistance);
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
bool ModbusTCP::CloseConn()
|
||
{
|
||
bool ret = true;
|
||
if (sockfd != INVALID_SOCKET)
|
||
closesocket(sockfd);
|
||
sockfd = INVALID_SOCKET;
|
||
|
||
|
||
return ret;
|
||
}
|
||
bool ModbusTCP::CloseConn_fl()
|
||
{
|
||
bool ret = true;
|
||
if (sockfd_fl != INVALID_SOCKET)
|
||
closesocket(sockfd_fl);
|
||
sockfd_fl = INVALID_SOCKET;
|
||
|
||
return ret;
|
||
}
|
||
bool ModbusTCP::CloseConn_record()
|
||
{
|
||
bool ret = true;
|
||
if (sockfd_record != INVALID_SOCKET)
|
||
closesocket(sockfd_record);
|
||
sockfd_record = INVALID_SOCKET;
|
||
|
||
return ret;
|
||
}
|
||
bool ModbusTCP::CloseConn_electric_resistance()
|
||
{
|
||
bool ret = true;
|
||
if (sockfd_electric_resistance != INVALID_SOCKET)
|
||
closesocket(sockfd_electric_resistance);
|
||
sockfd_electric_resistance = INVALID_SOCKET;
|
||
|
||
return ret;
|
||
}
|
||
int ModbusTCP::SendCmdRead(unsigned int sockfd,char *data, unsigned short data_len)
|
||
{
|
||
//可能存在问题。
|
||
//1、接收按照数据长度接收,然后校验接收长度是否正确
|
||
//2、返回的数据,是否正确,是否要进行判断?
|
||
char rev_buf[4096];
|
||
int RevDataLen = 0;
|
||
|
||
//发送modbus请求
|
||
if (send(sockfd, data, data_len, 0) == -1) {
|
||
closesocket(sockfd);
|
||
return -1;
|
||
|
||
}
|
||
//printf("Sent request successfully.\n");
|
||
//接收modbus请求
|
||
RevDataLen = recv(sockfd, rev_buf, 4096, 0);
|
||
if (RevDataLen == -1) {
|
||
//printf("Failed to receive response: %s\n", strerror(errno));
|
||
closesocket(sockfd);
|
||
return -1;
|
||
}
|
||
int ret = DataDecode(rev_buf, RevDataLen);
|
||
return ret;
|
||
}
|
||
int ModbusTCP::SendCmdWrite(unsigned int sockfd,char *data, unsigned short data_len)
|
||
{
|
||
//可能存在问题。
|
||
//1、接收按照数据长度接收,然后校验接收长度是否正确
|
||
//2、返回的数据,是否正确,是否要进行判断?
|
||
|
||
char rev_buf[4096];
|
||
int RevDataLen = 0;
|
||
|
||
//发送modbus请求
|
||
if (send(sockfd, data, data_len, 0) == -1) {
|
||
closesocket(sockfd);
|
||
return -1;
|
||
}
|
||
//printf("Sent request successfully.\n");
|
||
//接收modbus请求
|
||
RevDataLen = recv(sockfd, rev_buf, 4096, 0);
|
||
if (RevDataLen == -1) {
|
||
//printf("Failed to receive response: %s\n", strerror(errno));
|
||
closesocket(sockfd);
|
||
return -1;
|
||
}
|
||
//int ret = Com_decode(rev_buf, RevDataLen);
|
||
return 0;
|
||
}
|
||
int ModbusTCP::SendCmdRead_fl(unsigned int sockfd,char *data, unsigned short data_len)
|
||
{
|
||
//可能存在问题。
|
||
//1、接收按照数据长度接收,然后校验接收长度是否正确
|
||
//2、返回的数据,是否正确,是否要进行判断?
|
||
char rev_buf[4096];
|
||
int RevDataLen = 0;
|
||
|
||
//发送modbus请求
|
||
if (send(sockfd, data, data_len, 0) == -1) {
|
||
closesocket(sockfd);
|
||
return -1;
|
||
|
||
}
|
||
//printf("Sent request successfully.\n");
|
||
//接收modbus请求
|
||
RevDataLen = recv(sockfd, rev_buf, 4096, 0);
|
||
if (RevDataLen == -1) {
|
||
//printf("Failed to receive response: %s\n", strerror(errno));
|
||
closesocket(sockfd);
|
||
return -1;
|
||
}
|
||
int ret = DataDecode(rev_buf, RevDataLen);
|
||
return ret;
|
||
}
|
||
int ModbusTCP::SendCmdWrite_fl(unsigned int sockfd,char *data, unsigned short data_len)
|
||
{
|
||
//可能存在问题。
|
||
//1、接收按照数据长度接收,然后校验接收长度是否正确
|
||
//2、返回的数据,是否正确,是否要进行判断?
|
||
|
||
char rev_buf[4096];
|
||
int RevDataLen = 0;
|
||
|
||
//发送modbus请求
|
||
if (send(sockfd, data, data_len, 0) == -1) {
|
||
closesocket(sockfd);
|
||
return -1;
|
||
}
|
||
//printf("Sent request successfully.\n");
|
||
//接收modbus请求
|
||
RevDataLen = recv(sockfd, rev_buf, 4096, 0);
|
||
if (RevDataLen == -1) {
|
||
//printf("Failed to receive response: %s\n", strerror(errno));
|
||
closesocket(sockfd);
|
||
return -1;
|
||
}
|
||
//int ret = Com_decode(rev_buf, RevDataLen);
|
||
return 0;
|
||
}
|
||
int ModbusTCP::DataDecode(char *data, int len)
|
||
{
|
||
if ((len >= 10) && (len <= 11))
|
||
{
|
||
return data[len-1];
|
||
}
|
||
else if (len > 11)
|
||
{
|
||
memset(MODBUSTCP->RFID,0,50);
|
||
memcpy(RFID,&data[9],len-9);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int ModbusTCP::ModbusWrite(unsigned char cmd,unsigned short addr, unsigned short data)
|
||
{
|
||
int ret;
|
||
|
||
|
||
unsigned char sendBuf[50];//发送缓存
|
||
unsigned short temps = _seq_modbus++;//类似于TCP的seq序列号,让其自增即可
|
||
unsigned char* temp = reinterpret_cast<unsigned char*>(&temps);
|
||
//协议头
|
||
sendBuf[0] = *(temp + 1);//前两位为事务处理标识,2个字节的序列号
|
||
sendBuf[1] = *(temp);
|
||
|
||
sendBuf[2] = 0;//协议标识,两个字节,0000即为Modbus TCP协议
|
||
sendBuf[3] = 0;
|
||
|
||
sendBuf[4] = 0;//长度字段(前半部分字节)
|
||
sendBuf[5] = 6;//随后字节数
|
||
|
||
sendBuf[6] = 1;//单元标志,定义连接目的节点的其他设备(这个设备是1号,所以是0x01)
|
||
//以上是Modbus协议头部分
|
||
//协议体
|
||
sendBuf[7] = cmd;//Modbus功能码 ,这里是 写多个保持寄存器 操作
|
||
temps = addr;
|
||
sendBuf[8] = *(temp + 1); //写寄存器起始地址高字节
|
||
sendBuf[9] = *(temp); //写寄存器起始地址低字节(所以这里是往0x0100地址写寄存器)
|
||
|
||
//sendBuf[10] = 0x00; //写寄存器数量高字节
|
||
//sendBuf[11] = 0x01; //写寄存器数量低字节
|
||
|
||
//sendBuf[12] = 0x01; //数据长度
|
||
|
||
//写1个值到报文中
|
||
temps = data;
|
||
//sendBuf[10] = data;
|
||
sendBuf[10] = *(temp + 1);
|
||
sendBuf[11] = *(temp);
|
||
|
||
|
||
bool ret_conn = true;
|
||
::EnterCriticalSection(&mCsRead);
|
||
ret_conn = ConnPLC();
|
||
if (ret_conn)
|
||
ret = SendCmdWrite(sockfd,reinterpret_cast<char*>(sendBuf), 12);
|
||
else
|
||
{
|
||
CloseConn();
|
||
::LeaveCriticalSection(&mCsRead);
|
||
return -1;
|
||
}
|
||
CloseConn();
|
||
::LeaveCriticalSection(&mCsRead);
|
||
return ret;
|
||
|
||
}
|
||
|
||
int ModbusTCP::ModbusWrite_fl(unsigned char cmd,unsigned short addr, unsigned short data)
|
||
{
|
||
int ret;
|
||
|
||
|
||
unsigned char sendBuf[50];//发送缓存
|
||
unsigned short temps = _seq_modbus_fl++;//类似于TCP的seq序列号,让其自增即可
|
||
unsigned char* temp = reinterpret_cast<unsigned char*>(&temps);
|
||
//协议头
|
||
sendBuf[0] = *(temp + 1);//前两位为事务处理标识,2个字节的序列号
|
||
sendBuf[1] = *(temp);
|
||
|
||
sendBuf[2] = 0;//协议标识,两个字节,0000即为Modbus TCP协议
|
||
sendBuf[3] = 0;
|
||
|
||
sendBuf[4] = 0;//长度字段(前半部分字节)
|
||
sendBuf[5] = 6;//随后字节数
|
||
|
||
sendBuf[6] = 1;//单元标志,定义连接目的节点的其他设备(这个设备是1号,所以是0x01)
|
||
//以上是Modbus协议头部分
|
||
//协议体
|
||
sendBuf[7] = cmd;//Modbus功能码 ,这里是 写多个保持寄存器 操作
|
||
temps = addr;
|
||
sendBuf[8] = *(temp + 1); //写寄存器起始地址高字节
|
||
sendBuf[9] = *(temp); //写寄存器起始地址低字节(所以这里是往0x0100地址写寄存器)
|
||
|
||
//sendBuf[10] = 0x00; //写寄存器数量高字节
|
||
//sendBuf[11] = 0x01; //写寄存器数量低字节
|
||
|
||
//sendBuf[12] = 0x01; //数据长度
|
||
|
||
//写1个值到报文中
|
||
temps = data;
|
||
//sendBuf[10] = data;
|
||
sendBuf[10] = *(temp + 1);
|
||
sendBuf[11] = *(temp);
|
||
|
||
|
||
bool ret_conn = true;
|
||
::EnterCriticalSection(&mCsRead_fl);
|
||
ret_conn = ConnPLC_fl();
|
||
if (ret_conn)
|
||
ret = SendCmdWrite_fl(sockfd_fl,reinterpret_cast<char*>(sendBuf), 12);
|
||
else
|
||
{
|
||
CloseConn_fl();
|
||
::LeaveCriticalSection(&mCsRead_fl);
|
||
return -1;
|
||
}
|
||
CloseConn_fl();
|
||
::LeaveCriticalSection(&mCsRead_fl);
|
||
return ret;
|
||
|
||
}
|
||
|
||
int ModbusTCP::ModbusWrite_force(char * data, int len)
|
||
{
|
||
|
||
bool ret_conn = true;
|
||
//::EnterCriticalSection(&mCsRead_fl);
|
||
ret_conn = ConnPLC_force();
|
||
if (ret_conn)
|
||
{
|
||
if (send(sockfd_record, data, len, 0) == -1)
|
||
{
|
||
CloseConn_record();
|
||
qDebug()<< "result1: "<<data;
|
||
//::LeaveCriticalSection(&mCsRead_fl);
|
||
return -1;
|
||
}
|
||
else
|
||
{
|
||
qDebug()<< "result: "<<data;
|
||
CloseConn_record();
|
||
//::LeaveCriticalSection(&mCsRead_fl);
|
||
return 0;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
CloseConn_record();
|
||
qDebug()<< "result2: "<<data;
|
||
//::LeaveCriticalSection(&mCsRead_fl);
|
||
return -1;
|
||
}
|
||
|
||
|
||
}
|
||
int ModbusTCP::ModbusWrite_electric_resistance(char * data, int len, char * rev_buf)
|
||
{
|
||
|
||
int RevDataLen = 0;
|
||
bool ret_conn = true;
|
||
|
||
// if (data[0] == 'G')
|
||
// {
|
||
// memset(array_pos,0,sizeof(array_pos));
|
||
// }
|
||
|
||
// ret_conn = ConnPLC_electric_resistance();
|
||
// if (ret_conn)
|
||
{
|
||
if (send(sockfd_electric_resistance, data, len, 0) == -1)
|
||
{
|
||
CloseConn_electric_resistance();
|
||
return -1;
|
||
}
|
||
else
|
||
{
|
||
if(strcmp(data,"***") == 0)
|
||
return 0;
|
||
RevDataLen = recv(sockfd_electric_resistance, rev_buf, 4096, 0);
|
||
if (RevDataLen == -1) {
|
||
closesocket(sockfd_electric_resistance);
|
||
return -1;
|
||
}
|
||
return RevDataLen;
|
||
}
|
||
|
||
}
|
||
// else
|
||
// {
|
||
// CloseConn_electric_resistance();
|
||
// qDebug()<< "result2: "<<data;
|
||
// //::LeaveCriticalSection(&mCsRead_fl);
|
||
// return -1;
|
||
// }
|
||
|
||
}
|
||
|
||
|
||
int ModbusTCP::ModbusRead(unsigned short addr,int dataLen)
|
||
{
|
||
|
||
int ret;
|
||
|
||
|
||
unsigned char sendBuf[50];//发送缓存
|
||
unsigned short temps = _seq_modbus++;//类似于TCP的seq序列号,让其自增即可
|
||
unsigned char* temp = reinterpret_cast<unsigned char*>(&temps);
|
||
//协议头
|
||
sendBuf[0] = *(temp + 1);//前两位为事务处理标识,2个字节的序列号
|
||
sendBuf[1] = *(temp);
|
||
|
||
sendBuf[2] = 0;//协议标识,两个字节,0000即为Modbus TCP协议
|
||
sendBuf[3] = 0;
|
||
|
||
sendBuf[4] = 0;//长度字段(前半部分字节)
|
||
sendBuf[5] = 6;//随后字节数
|
||
|
||
sendBuf[6] = 0x01;//单元标志,定义连接目的节点的其他设备(这个设备是1号,所以是0x01)
|
||
//以上是Modbus协议头部分
|
||
//协议体
|
||
sendBuf[7] = 0x03;//Modbus功能码 ,这里是读
|
||
temps = addr;
|
||
sendBuf[8] = *(temp + 1); //写寄存器起始地址高字节
|
||
sendBuf[9] = *(temp); //写寄存器起始地址低字节(所以这里是往0x0100地址写寄存器)
|
||
sendBuf[10] = 0x00; //长度
|
||
sendBuf[11] = dataLen; //写寄存器数量低字节
|
||
|
||
bool ret_conn = true;
|
||
::EnterCriticalSection(&mCsRead);
|
||
ret_conn = ConnPLC();
|
||
if (ret_conn)
|
||
ret = SendCmdRead(sockfd,reinterpret_cast<char*>(sendBuf), 12);
|
||
else
|
||
{
|
||
CloseConn();
|
||
::LeaveCriticalSection(&mCsRead);
|
||
return -1;
|
||
}
|
||
CloseConn();
|
||
::LeaveCriticalSection(&mCsRead);
|
||
return ret;
|
||
|
||
}
|
||
|
||
int ModbusTCP::ModbusRead_fl(unsigned short addr,int dataLen)
|
||
{
|
||
|
||
int ret;
|
||
|
||
|
||
unsigned char sendBuf[50];//发送缓存
|
||
unsigned short temps = _seq_modbus_fl++;//类似于TCP的seq序列号,让其自增即可
|
||
unsigned char* temp = reinterpret_cast<unsigned char*>(&temps);
|
||
//协议头
|
||
sendBuf[0] = *(temp + 1);//前两位为事务处理标识,2个字节的序列号
|
||
sendBuf[1] = *(temp);
|
||
|
||
sendBuf[2] = 0;//协议标识,两个字节,0000即为Modbus TCP协议
|
||
sendBuf[3] = 0;
|
||
|
||
sendBuf[4] = 0;//长度字段(前半部分字节)
|
||
sendBuf[5] = 6;//随后字节数
|
||
|
||
sendBuf[6] = 0x01;//单元标志,定义连接目的节点的其他设备(这个设备是1号,所以是0x01)
|
||
//以上是Modbus协议头部分
|
||
//协议体
|
||
sendBuf[7] = 0x03;//Modbus功能码 ,这里是读
|
||
temps = addr;
|
||
sendBuf[8] = *(temp + 1); //写寄存器起始地址高字节
|
||
sendBuf[9] = *(temp); //写寄存器起始地址低字节(所以这里是往0x0100地址写寄存器)
|
||
sendBuf[10] = 0x00; //长度
|
||
sendBuf[11] = dataLen; //写寄存器数量低字节
|
||
|
||
bool ret_conn = true;
|
||
::EnterCriticalSection(&mCsRead_fl);
|
||
ret_conn = ConnPLC_fl();
|
||
if (ret_conn)
|
||
ret = SendCmdRead_fl(sockfd_fl,reinterpret_cast<char*>(sendBuf), 12);
|
||
else
|
||
{
|
||
CloseConn_fl();
|
||
::LeaveCriticalSection(&mCsRead_fl);
|
||
return -1;
|
||
}
|
||
CloseConn_fl();
|
||
::LeaveCriticalSection(&mCsRead_fl);
|
||
return ret;
|
||
|
||
}
|
||
|
||
int ModbusTCP::TransferPLCRun(unsigned short addr,int delay)
|
||
{
|
||
if ((addr == 0) || (delay <= 0))
|
||
return -1;
|
||
if (TransferPLCCmd.cmdAddr != 0)
|
||
{
|
||
return -1;
|
||
}
|
||
else
|
||
{
|
||
TransferPLCCmd.cmdAddr = addr;
|
||
TransferPLCCmd.cmdDelay = delay;
|
||
TransferPLCCmd.cmdWriteFlag = false;
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
int ModbusTCP::SeparatePLCRun(unsigned short addr,int delay)
|
||
{
|
||
if ((addr == 0) || (delay <= 0))
|
||
return -1;
|
||
if (SeparatePLCCmd.cmdAddr != 0)
|
||
{
|
||
return -1;
|
||
}
|
||
else
|
||
{
|
||
SeparatePLCCmd.cmdAddr = addr;
|
||
SeparatePLCCmd.cmdDelay = delay;
|
||
SeparatePLCCmd.cmdWriteFlag = false;
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
int ModbusTCP::getModbusPara(QString DevName)
|
||
{
|
||
QSettings *settings;//申明一个QSetting类函数
|
||
settings = new QSettings ("SerialDevSet.ini", QSettings::IniFormat);//构建函数
|
||
|
||
QString strKey;
|
||
strKey = "/"+DevName+"/ipAddr";
|
||
ipAddr = settings->value(strKey).toString();
|
||
strKey = "/"+DevName+"/ipAddr_fl";
|
||
ipAddr_fl = settings->value(strKey).toString();
|
||
|
||
strKey = "/"+DevName+"/ipAddr_record";
|
||
ipAddr_record = settings->value(strKey).toString();
|
||
|
||
strKey = "/"+DevName+"/ipAddr_electric_resistance";
|
||
ipAddr_electric_resistance = settings->value(strKey).toString();
|
||
|
||
strKey = "/"+DevName+"/shangReadAddr";
|
||
shangReadAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
strKey = "/"+DevName+"/shangWriteAddr";
|
||
shangWriteAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
|
||
strKey = "/"+DevName+"/shangReadRFIDAddr";
|
||
shangReadRFIDAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
|
||
strKey = "/"+DevName+"/shangReadVacuumAddr";
|
||
shangReadVacuumAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
strKey = "/"+DevName+"/shangWriteHeartbeatAddr";
|
||
shangWriteHeartbeatAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
|
||
strKey = "/"+DevName+"/shangWriteVacuumAddr";
|
||
shangWriteVacuumAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
|
||
strKey = "/"+DevName+"/xiaReadAddr";
|
||
xiaReadAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
strKey = "/"+DevName+"/xiaWriteAddr";
|
||
xiaWriteAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
|
||
strKey = "/"+DevName+"/xiaReadStsAddr";
|
||
xiaReadStsAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
strKey = "/"+DevName+"/ReadTransferPLCStsAddr";
|
||
ReadTransferPLCStsAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
|
||
strKey = "/"+DevName+"/xiaWriteVacuumAddr";
|
||
xiaWriteVacuumAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
|
||
strKey = "/"+DevName+"/InitAddr";
|
||
InitAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
strKey = "/"+DevName+"/RunAddr";
|
||
RunAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
strKey = "/"+DevName+"/StopAddr";
|
||
StopAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
strKey = "/"+DevName+"/ClearAlarmAddr";
|
||
ClearAlarmAddr = static_cast<unsigned short>(settings->value(strKey).toInt());
|
||
|
||
|
||
return 0;
|
||
}
|
||
|
||
int ModbusTCP::Heartbeat(void)
|
||
{
|
||
int internal_read = 0;
|
||
int internal_write = 0;
|
||
int internal_sts = 0;
|
||
int ret_modbus;
|
||
int count = 0;
|
||
bool readFlag = false;
|
||
int fail_count[2] = {0};
|
||
int internal_TransferPLCCmd_sts = 0;
|
||
while (1)
|
||
{
|
||
internal_read++;
|
||
internal_write++;
|
||
internal_sts++;
|
||
if ((internal_read >= 240) && (readFlag))
|
||
{
|
||
ret_modbus = MODBUSTCP->ModbusRead(MODBUSTCP->shangWriteHeartbeatAddr, 1);
|
||
if (ret_modbus != 0)
|
||
{
|
||
count++;
|
||
}
|
||
else
|
||
{
|
||
count = 0;
|
||
MODBUSTCP->connFlag = true;
|
||
}
|
||
if (count >= 3)
|
||
{
|
||
MODBUSTCP->connFlag = false;
|
||
}
|
||
readFlag = false;
|
||
internal_write = 0;
|
||
}
|
||
if ((internal_write >= 20) && (!readFlag))
|
||
{
|
||
ret_modbus = MODBUSTCP->ModbusWrite(0x06,MODBUSTCP->shangWriteHeartbeatAddr, 1);
|
||
internal_read = 0;
|
||
readFlag = true;
|
||
}
|
||
|
||
if (internal_sts >= 20)
|
||
{
|
||
ret_modbus = MODBUSTCP->ModbusRead(MODBUSTCP->xiaReadStsAddr, 1);
|
||
if (ret_modbus == -1)
|
||
{
|
||
fail_count[0]++;
|
||
if (fail_count[0] >= 3)
|
||
{
|
||
PLCSts[0] = -1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
fail_count[0] = 0;
|
||
PLCSts[0] = ret_modbus;
|
||
}
|
||
ret_modbus = MODBUSTCP->ModbusRead(MODBUSTCP->ReadTransferPLCStsAddr, 1);
|
||
TransferPLCSts = ret_modbus;
|
||
emit DEV->TransferPLCSGL(PLCSts[0]);
|
||
internal_sts = 0;
|
||
|
||
}
|
||
|
||
if (TransferPLCCmd.cmdAddr != 0)
|
||
{
|
||
if (TransferPLCCmd.cmdWriteFlag == false)
|
||
{
|
||
//发送写命令
|
||
ret_modbus = MODBUSTCP->ModbusWrite(0x05,TransferPLCCmd.cmdAddr, 0xff00);
|
||
TransferPLCCmd.cmdWriteFlag = true;
|
||
}
|
||
internal_TransferPLCCmd_sts++;
|
||
if ((internal_TransferPLCCmd_sts * 5) >= TransferPLCCmd.cmdDelay)
|
||
{
|
||
//发送清除命令
|
||
ret_modbus = MODBUSTCP->ModbusWrite(0x05,TransferPLCCmd.cmdAddr, 0);
|
||
TransferPLCCmd.cmdWriteFlag = false;
|
||
TransferPLCCmd.cmdAddr = 0;
|
||
TransferPLCCmd.cmdDelay = 0;
|
||
internal_TransferPLCCmd_sts = 0;
|
||
}
|
||
}
|
||
|
||
Sleep(5);
|
||
}
|
||
}
|
||
|
||
int ModbusTCP::Heartbeat_fl(void)
|
||
{
|
||
int internal_sts = 0;
|
||
int ret_modbus;
|
||
int fail_count[2] = {0};
|
||
int internal_SeparatePLCCmd_sts = 0;
|
||
while (1)
|
||
{
|
||
|
||
internal_sts++;
|
||
|
||
if (internal_sts >= 20)
|
||
{
|
||
ret_modbus = MODBUSTCP->ModbusRead_fl(MODBUSTCP->xiaReadStsAddr, 1);
|
||
if (ret_modbus == -1)
|
||
{
|
||
fail_count[1]++;
|
||
if (fail_count[1] >= 3)
|
||
{
|
||
PLCSts[1] = -1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
fail_count[1] = 0;
|
||
PLCSts[1] = ret_modbus;
|
||
}
|
||
emit DEV->SeparatePLCSGL(PLCSts[1]);
|
||
internal_sts = 0;
|
||
|
||
}
|
||
|
||
if (SeparatePLCCmd.cmdAddr != 0)
|
||
{
|
||
if (SeparatePLCCmd.cmdWriteFlag == false)
|
||
{
|
||
ret_modbus = MODBUSTCP->ModbusWrite_fl(0x05,SeparatePLCCmd.cmdAddr, 0xff00);
|
||
SeparatePLCCmd.cmdWriteFlag = true;
|
||
}
|
||
internal_SeparatePLCCmd_sts++;
|
||
if ((internal_SeparatePLCCmd_sts * 5) >= SeparatePLCCmd.cmdDelay)
|
||
{
|
||
//发送清除命令
|
||
ret_modbus = MODBUSTCP->ModbusWrite_fl(0x05,SeparatePLCCmd.cmdAddr, 0);
|
||
SeparatePLCCmd.cmdWriteFlag = false;
|
||
SeparatePLCCmd.cmdAddr = 0;
|
||
SeparatePLCCmd.cmdDelay = 0;
|
||
internal_SeparatePLCCmd_sts = 0;
|
||
}
|
||
}
|
||
|
||
Sleep(5);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* 1、正常自动加工时,在工作线程跑上下料
|
||
* 2、在测试界面,使用线程(CreateThread),有运行标记
|
||
*/
|