2023-11-28 16:56:30 +03:00
|
|
|
|
#include "modbusoverudp.h"
|
|
|
|
|
|
|
|
|
|
ModbusOverUdp::ModbusOverUdp(QObject *parent) : QObject(parent)
|
2023-11-30 12:58:49 +03:00
|
|
|
|
{timer= new QTimer();
|
|
|
|
|
timer->setInterval(1000);
|
|
|
|
|
connect(timer,SIGNAL(timeout()),this,SLOT(timeout()));
|
|
|
|
|
timer->start();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ModbusOverUdp::timeout()
|
|
|
|
|
{
|
|
|
|
|
if(isConnected){//запросы по всем фронтам
|
|
|
|
|
|
|
|
|
|
for(quint16 i=1; i<=4; i++){
|
|
|
|
|
req(i,SENS);
|
|
|
|
|
req(i,STATE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint16_t ModbusOverUdp::Crc16(uint16_t len, uint16_t iobuf[]) //CRC для сообщения такой то длинны /Len - начало контрольной сумимы
|
|
|
|
|
{
|
|
|
|
|
uint16_t i;
|
|
|
|
|
uint16_t crc = 0xFFFF;
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < len; i++) {
|
|
|
|
|
crc = (crc >> 8) ^ Crc16Table[(crc & 0xFF) ^ (iobuf[i]& 0xFF)];
|
|
|
|
|
}
|
|
|
|
|
return crc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint16_t ModbusOverUdp::Crc16(uint16_t len, QByteArray iobuf) //CRC для сообщения такой то длинны /Len - начало контрольной сумимы
|
2023-11-28 16:56:30 +03:00
|
|
|
|
{
|
2023-11-30 12:58:49 +03:00
|
|
|
|
uint16_t i;
|
|
|
|
|
uint16_t crc = 0xFFFF;
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < len; i++) {
|
|
|
|
|
crc = (crc >> 8) ^ Crc16Table[(crc & 0xFF) ^ (iobuf[i] & 0xFF)]; // ввел маску 0xFF, тк прилетает 0хFFFFFFxx
|
|
|
|
|
}
|
|
|
|
|
return crc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ModbusOverUdp::readPendingDatagrams()
|
|
|
|
|
{
|
|
|
|
|
while (udpSocket->hasPendingDatagrams()) {
|
|
|
|
|
QNetworkDatagram datagram = udpSocket->receiveDatagram();
|
|
|
|
|
processTheDatagram(datagram);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ModbusOverUdp::processTheDatagram(QNetworkDatagram & datagram)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
QByteArray recived = datagram.data(); // копируем датаграмку в аррэй для удобной работы
|
|
|
|
|
|
|
|
|
|
Set toSend; //структура для отправки в другой компонент
|
|
|
|
|
sfloat res; //флоат для сборки из пакета модбас
|
|
|
|
|
toSend.channel=(typeCHANNEL)(recived[0]-1); //Ch1 = 0 - в енаме
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (recived.size()){ // сужу о прибывшем по размеру пакета // ЭТО ПЛОХО!!!
|
|
|
|
|
case 9:
|
|
|
|
|
|
|
|
|
|
res.ch[3]=recived[3]; // Собираю флоат
|
|
|
|
|
res.ch[2]=recived[4];
|
|
|
|
|
res.ch[1]=recived[5];
|
|
|
|
|
res.ch[0]=recived[6];
|
|
|
|
|
//qDebug() <<"Чувствительность для модбас адреса"<<toSend.channel+1 <<res.fl;
|
|
|
|
|
toSend.SENS= res.fl;
|
|
|
|
|
emit sensRecive(toSend);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 25:
|
|
|
|
|
//qDebug() <<"Подвалило состояние для модбас адреса"<<toSend.channel+1;
|
2023-11-28 16:56:30 +03:00
|
|
|
|
|
2023-11-30 12:58:49 +03:00
|
|
|
|
toSend.IIN=(typeIIN)(recived[4]-0);
|
|
|
|
|
toSend.IFV=(typeIFV)(recived[6]-0);
|
|
|
|
|
toSend.IFN=(typeIFN)(recived[8]-0);
|
|
|
|
|
toSend.IKU=(typeIKU)(recived[10]-0);
|
|
|
|
|
//toSend.OUTPUT=(typeOUTPUT)(recived[2]-0);
|
|
|
|
|
toSend.VALUE=(typeVALUE)(recived[22]-0);
|
|
|
|
|
|
|
|
|
|
emit stateRecive(toSend);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
qDebug() <<"ТЫ не понимаешь, это другое";
|
|
|
|
|
qDebug() <<"Это"<<recived<<"размером"<<recived.size();
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
//Разберись с этим
|
|
|
|
|
// "\x01\x10\x13\x89\x00\n\x14\x00\x00\x00\x04\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x05\xB3" размером 29
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ModbusOverUdp::connectTo(QString ipAdress, quint16 port)
|
|
|
|
|
{
|
|
|
|
|
udpSocket = new QUdpSocket(this);
|
|
|
|
|
targetIp =QHostAddress(ipAdress);
|
|
|
|
|
targetPort=port;
|
|
|
|
|
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
|
|
|
|
|
isConnected=1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModbusOverUdp::disconnectFrom()
|
|
|
|
|
{
|
|
|
|
|
isConnected=0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModbusOverUdp::req(quint16 adr, typeREQ TYPEREQ)
|
|
|
|
|
{
|
|
|
|
|
QByteArray data;
|
|
|
|
|
switch (TYPEREQ)
|
|
|
|
|
{
|
|
|
|
|
case SENS:{
|
|
|
|
|
data.resize(8);
|
|
|
|
|
data[0]=adr;
|
|
|
|
|
data[1]=0x3;
|
|
|
|
|
data[2]=0x1b;
|
|
|
|
|
data[3]=0x5c;
|
|
|
|
|
data[4]=0x00;
|
|
|
|
|
data[5]=0x2;
|
|
|
|
|
uint16_t crcToSend= Crc16((uint16_t)6, data);
|
|
|
|
|
data[6]=LO(crcToSend);
|
|
|
|
|
data[7]=HI(crcToSend);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case STATE:{
|
|
|
|
|
data.resize(8);
|
|
|
|
|
data[0]=adr;
|
|
|
|
|
data[1]=0x3;
|
|
|
|
|
data[2]=0x13;
|
|
|
|
|
data[3]=0x89;
|
|
|
|
|
data[4]=0x00;
|
|
|
|
|
data[5]=0xa;
|
|
|
|
|
uint16_t crcToSend= Crc16((uint16_t)6, data);
|
|
|
|
|
data[6]=LO(crcToSend);
|
|
|
|
|
data[7]=HI(crcToSend);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sendPendingDatagrams(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ModbusOverUdp::testReq()
|
|
|
|
|
{
|
|
|
|
|
QByteArray data;
|
|
|
|
|
data.resize(8);
|
|
|
|
|
data[0]=0x1;
|
|
|
|
|
data[1]=0x3;
|
|
|
|
|
data[2]=0x13;
|
|
|
|
|
data[3]=0x89;
|
|
|
|
|
data[4]=0x00;
|
|
|
|
|
data[5]=0x4;
|
|
|
|
|
uint16_t crcToSend= Crc16((uint16_t)6, data);
|
|
|
|
|
data[6]=LO(crcToSend);
|
|
|
|
|
data[7]=HI(crcToSend);
|
|
|
|
|
sendPendingDatagrams(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ModbusOverUdp::sendPendingDatagrams( QByteArray & data )
|
|
|
|
|
{
|
|
|
|
|
QNetworkDatagram datagram;
|
|
|
|
|
|
|
|
|
|
datagram.setDestination(targetIp,targetPort);
|
|
|
|
|
datagram.setData(data);
|
|
|
|
|
// qDebug()<<"sended"<<datagram.data();
|
|
|
|
|
udpSocket->writeDatagram(datagram);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ModbusOverUdp::stateSend(Set setWithState)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModbusOverUdp::sensSend(Set setWithSens)
|
|
|
|
|
{
|
2023-11-28 16:56:30 +03:00
|
|
|
|
}
|