#include "modbusoverudp.h" ModbusOverUdp::ModbusOverUdp(QObject *parent) : QObject(parent) {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 - начало контрольной сумимы { 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(); QByteArray recived = datagram.data(); // копируем датаграмку в аррэй для удобной работы int indNachalaCrc = recived[2]+3; uint16_t crcRecived = Crc16(indNachalaCrc, recived); // в функции используют больше или меньше if((recived[indNachalaCrc]&0xFF)==LO(crcRecived)&&(recived[indNachalaCrc+1]&0xFF)==HI(crcRecived)){ //todo внимание костыль //qDebug()<<"CRC Ок "; }else{ qDebug()<<"CRC не катит"; return; } 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() <<"Чувствительность для модбас адреса"<2) return; if((int)recived[6]>5) return; if((int)recived[8]>7) return; if((int)recived[10]>12) return; if((int)recived[22]>3) return; 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.VALUE=(typeVALUE)(recived[22]-0); emit stateRecive(toSend); break; default: qDebug()<bind(QHostAddress::LocalHost,8000,QAbstractSocket::DontShareAddress); targetIp =QHostAddress(oldIp); targetPort=7000; // QUdpSocket *udpSocketForRecive= new QUdpSocket(this); connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); QStringList ip= newIp.split("."); qDebug()<writeDatagram(datagram); udpSocket->waitForBytesWritten(50); } 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"<writeDatagram(datagram); }