new file: app.ico
modified: comWorks.cpp modified: comWorks.h modified: customlabel.cpp modified: customlabel.h modified: enums.h modified: mainwindow.h modified: mainwindow.ui new file: modbushandler.cpp new file: modbushandler.h new file: secondwindows.cpp new file: secondwindows.h new file: secondwindows.ui modified: setpribor.cpp modified: setpribor.h modified: setpribor.uimain
parent
fc8393ac29
commit
38869813ad
|
@ -1,4 +1,5 @@
|
|||
QT += core gui
|
||||
QT += core gui serialport serialbus
|
||||
# Дописываем serialport что бы qt понял что к чему
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
|
@ -16,15 +17,29 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
comWorks.cpp \
|
||||
customlabel.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
mainwindow.cpp \
|
||||
modbushandler.cpp \
|
||||
secondwindows.cpp \
|
||||
setpribor.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h
|
||||
comWorks.h \
|
||||
customlabel.h \
|
||||
enums.h \
|
||||
mainwindow.h \
|
||||
modbushandler.h \
|
||||
secondwindows.h \
|
||||
setpribor.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
mainwindow.ui \
|
||||
secondwindows.ui \
|
||||
setpribor.ui
|
||||
|
||||
win32:RC_FILE = ico.rc
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
559
comWorks.cpp
559
comWorks.cpp
|
@ -0,0 +1,559 @@
|
|||
#include "comWorks.h"
|
||||
#include "mainwindow.h"
|
||||
#include <QtSerialPort/QSerialPort>
|
||||
#include <QtSerialPort/QSerialPortInfo>
|
||||
#include "QThread"
|
||||
|
||||
|
||||
//bool connectToCom();
|
||||
|
||||
#define PACKET_STATE_SIZE 26
|
||||
#define PACKET_SENS_SIZE 10
|
||||
|
||||
#define READY_FOR_READ_INT 200
|
||||
|
||||
extern QSerialPort *serial;
|
||||
|
||||
static const uint16_t Crc16Table[256] =
|
||||
{
|
||||
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
|
||||
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
|
||||
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
|
||||
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
|
||||
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
|
||||
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
|
||||
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
|
||||
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
|
||||
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
|
||||
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
|
||||
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
|
||||
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
|
||||
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
|
||||
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
|
||||
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
|
||||
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
|
||||
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
|
||||
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
|
||||
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
|
||||
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
|
||||
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
|
||||
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
|
||||
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
|
||||
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
|
||||
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
|
||||
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
|
||||
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
|
||||
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
|
||||
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
|
||||
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
|
||||
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
|
||||
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
|
||||
};
|
||||
|
||||
uint16_t 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 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;
|
||||
}
|
||||
|
||||
|
||||
stateStruct readSet(QSerialPort *serial, uint16_t adr){
|
||||
|
||||
|
||||
// qDebug()<<"чтение состояния";
|
||||
stateStruct readed;
|
||||
uint16_t recived[PACKET_STATE_SIZE]; /// поменял
|
||||
uint16_t toSend[8];
|
||||
toSend[0]=adr;
|
||||
toSend[1]=0x3; // comand
|
||||
toSend[2]=0x13;//hi addr 5001
|
||||
toSend[3]=0x89; //low addr
|
||||
toSend[4]=0x00; //hi regs
|
||||
toSend[5]=0xb;//low regs //11 регистров
|
||||
|
||||
uint16_t crcToSend;
|
||||
crcToSend= Crc16((uint16_t)6, toSend);
|
||||
toSend[6]=LO(crcToSend);//lo CRC
|
||||
toSend[7]=HI(crcToSend);//hi CRC
|
||||
|
||||
QByteArray readCom;
|
||||
readCom.resize(8);
|
||||
readCom[0]=toSend[0];
|
||||
readCom[1]=toSend[1];
|
||||
readCom[2]=toSend[2]; //hi addr 5001
|
||||
readCom[3]=toSend[3]; //low addr
|
||||
readCom[4]=toSend[4]; //hi regs
|
||||
readCom[5]=toSend[5]; //low regs
|
||||
readCom[6]=toSend[6]; //lo CRC
|
||||
readCom[7]=toSend[7]; //hi CRC
|
||||
|
||||
|
||||
QByteArray rec;
|
||||
rec.resize(PACKET_STATE_SIZE);
|
||||
|
||||
serial->open(QIODevice::ReadWrite);
|
||||
serial->write(readCom);
|
||||
serial->waitForReadyRead(READY_FOR_READ_INT); //todo: блочное устройство, иногда читаю не все байты нужна функция приема
|
||||
rec = serial->readAll();
|
||||
serial->close();
|
||||
|
||||
|
||||
for(int i=0; i<=PACKET_STATE_SIZE;i++){
|
||||
recived[i]=rec.constData()[i];
|
||||
}
|
||||
|
||||
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 Ок ";
|
||||
readed.crcOk = true;
|
||||
}else{
|
||||
qDebug()<<"чтение состояния CRC не катит";
|
||||
readed.crcOk = false;
|
||||
}
|
||||
|
||||
|
||||
readed.fn=(typeIFN)recived[8];
|
||||
readed.fv=(typeIFV)recived[6];
|
||||
readed.in=(typeIIN)recived[2]; //!!!шляпа он точно не второй
|
||||
readed.ku=(typeIKU)recived[10];
|
||||
readed.unit=(typeUnit)recived[22];
|
||||
readed.overload=(typeOverload)recived[24];
|
||||
readed.pz=(typePlavGround)recived[18];
|
||||
|
||||
return readed;
|
||||
};
|
||||
|
||||
sensStruct readSens(QSerialPort *serial,uint16_t adr){ //todo: неплохо если ты посчитаешь контрольные суммы, Дима.
|
||||
|
||||
// qDebug()<<"Сработало чтение чувствительности";
|
||||
sensStruct result;
|
||||
usfloat res;
|
||||
res.ch[0] =0;
|
||||
res.ch[1] =0;
|
||||
res.ch[2] =0;
|
||||
res.ch[3] =0;
|
||||
//структура на отправку
|
||||
uint16_t toSend[8]={0,};
|
||||
uint16_t recived[25]={0,};
|
||||
toSend[0]=adr;
|
||||
toSend[1]=0x3; // comand
|
||||
|
||||
toSend[2]=0x1b;//hi addr 7004
|
||||
toSend[3]=0x5c; //low addr 7004
|
||||
|
||||
toSend[4]=0x00; //hi regs
|
||||
toSend[5]=0x02;//low regs
|
||||
uint16_t crc = Crc16(6, toSend);
|
||||
toSend[6]=LO(crc);//lo CRC
|
||||
toSend[7]=HI(crc);//hi CRC
|
||||
|
||||
QByteArray readCom;
|
||||
readCom.resize(8);
|
||||
|
||||
readCom[0]=toSend[0];
|
||||
readCom[1]=toSend[1];
|
||||
readCom[2]=toSend[2]; //hi addr 5001
|
||||
readCom[3]=toSend[3]; //low addr
|
||||
readCom[4]=toSend[4]; //hi regs
|
||||
readCom[5]=toSend[5]; //low regs
|
||||
readCom[6]=toSend[6]; //lo CRC
|
||||
readCom[7]=toSend[7]; //hi CRC
|
||||
|
||||
QByteArray rec;
|
||||
rec.resize(PACKET_SENS_SIZE);
|
||||
serial->open(QIODevice::ReadWrite); // открыли порт на запись и чтение
|
||||
serial->write(readCom);
|
||||
serial->waitForReadyRead(READY_FOR_READ_INT);
|
||||
rec = serial->readAll();
|
||||
serial->close();
|
||||
|
||||
|
||||
|
||||
for(int i=0; i<PACKET_SENS_SIZE;i++){
|
||||
recived[i]=rec.constData()[i];
|
||||
}
|
||||
|
||||
int indNachalaCrc = recived[2]+3; //todo: проверить
|
||||
uint16_t crcRecived = Crc16(indNachalaCrc, recived); // в функции используют больше или меньше
|
||||
|
||||
|
||||
|
||||
if((recived[indNachalaCrc]&0xFF)==LO(crcRecived)&&(recived[indNachalaCrc+1]&0xFF)==HI(crcRecived)){ //todo внимание костыль
|
||||
result.crcOk =true;
|
||||
}else{
|
||||
result.crcOk =false;
|
||||
}
|
||||
|
||||
res.ch[3]=recived[3]; // Собираю флоат
|
||||
res.ch[2]=recived[4];
|
||||
res.ch[1]=recived[5];
|
||||
res.ch[0]=recived[6];
|
||||
|
||||
qDebug()<<(float)res.fl;
|
||||
result.sens =res.fl;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool writePalam(QSerialPort *serial, uint16_t adr, typeParam typeparam, uint16_t value)
|
||||
{
|
||||
QByteArray writeCom;
|
||||
writeCom.resize(11);
|
||||
writeCom[0]=adr;
|
||||
writeCom[1]=0x10; // comand
|
||||
|
||||
switch (typeparam) {
|
||||
|
||||
case in:
|
||||
writeCom[2]=0x13;//hi addr 5001
|
||||
writeCom[3]=0x89; //low addr5001
|
||||
break;
|
||||
|
||||
case ku:
|
||||
writeCom[2]=0x13;//hi addr 5004
|
||||
writeCom[3]=0x8c; //low addr5004
|
||||
break;
|
||||
|
||||
case fv:
|
||||
writeCom[2]=0x13;//hi addr 5002
|
||||
writeCom[3]=0x8a; //low addr5002
|
||||
break;
|
||||
|
||||
case fn:
|
||||
writeCom[2]=0x13;//hi addr 5003
|
||||
writeCom[3]=0x8b; //low addr5003
|
||||
break;
|
||||
|
||||
case unit:
|
||||
writeCom[2]=0x13;//hi addr 5010
|
||||
writeCom[3]=0x92; //low addr5010
|
||||
break;
|
||||
|
||||
|
||||
case overload:
|
||||
writeCom[2]=0x13;//hi addr 5011
|
||||
writeCom[3]=0x93; //low addr5011
|
||||
break;
|
||||
|
||||
case pz:
|
||||
writeCom[2]=0x13;//hi addr 5008
|
||||
writeCom[3]=0x90; //low addr5008
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug() << "передано неверное значение типа параметра";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
//пишем по одномк регистру
|
||||
writeCom[4]=0x00; //hi regs
|
||||
writeCom[5]=0x1;//low regs
|
||||
writeCom[6]=0x2;// байт на отправку
|
||||
writeCom[7]=0;
|
||||
writeCom[8]=value; //значение на отправку
|
||||
|
||||
uint16_t crcToSend;
|
||||
crcToSend= Crc16((uint16_t)9, writeCom); //длинна захардкожена //Возможно будет неправильно считать
|
||||
writeCom[9]=LO(crcToSend);//lo CRC
|
||||
writeCom[10]=HI(crcToSend);//hi CRC
|
||||
|
||||
|
||||
qDebug()<<QByteArray::number(writeCom[0], 16)<< "adr";
|
||||
qDebug()<<QByteArray::number(writeCom[1], 16)<< "comand";
|
||||
qDebug()<<QByteArray::number(writeCom[2], 16)<< "adr reg HI";
|
||||
qDebug()<<QByteArray::number(writeCom[3], 16)<< "adr reg LO";
|
||||
qDebug()<<QByteArray::number(writeCom[4], 16)<< "num reg HI";
|
||||
qDebug()<<QByteArray::number(writeCom[5], 16)<< "num reg Lo";
|
||||
qDebug()<<QByteArray::number(writeCom[6], 16)<< "num reg bytes";
|
||||
qDebug()<<QByteArray::number(writeCom[7], 16)<< "num reg HI data";
|
||||
qDebug()<<QByteArray::number(writeCom[8], 16)<< "num reg LO data";
|
||||
qDebug()<<QByteArray::number(writeCom[9], 16)<< " LO CRC ";
|
||||
qDebug()<<QByteArray::number(writeCom[10], 16)<< "CRC HI";
|
||||
|
||||
serial->open(QIODevice::ReadWrite);
|
||||
serial->write(writeCom);
|
||||
serial->waitForReadyRead(READY_FOR_READ_INT);
|
||||
|
||||
|
||||
QByteArray rec;
|
||||
rec = serial->readAll();
|
||||
|
||||
qDebug()<<rec.toHex();
|
||||
|
||||
serial->close();
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool writeSens(QSerialPort *serial, uint16_t adr, float value)
|
||||
{
|
||||
QByteArray writeCom;
|
||||
writeCom.resize(11);
|
||||
writeCom[0]=adr;
|
||||
writeCom[1]=0x10; // comand
|
||||
writeCom[2]=0x1b;//hi addr 7004
|
||||
writeCom[3]=0x5c; //low addr 7004
|
||||
writeCom[4]=0x00; //hi regs
|
||||
writeCom[5]=0x2;//low regs
|
||||
writeCom[6]=0x4;// байт на отправку //а не 2=)
|
||||
|
||||
usfloat res;
|
||||
res.fl=value;
|
||||
|
||||
writeCom[7]=res.ch[3]&0xFF; // Собираю флоат
|
||||
writeCom[8]=res.ch[2]&0xFF;
|
||||
writeCom[9]=res.ch[1]&0xFF;
|
||||
writeCom[10]=res.ch[0]&0xFF;
|
||||
|
||||
uint16_t crcToSend;
|
||||
crcToSend= Crc16((uint16_t)11, writeCom); //длинна захардкожена //Возможно будет неправильно считать
|
||||
writeCom[11]=(LO(crcToSend)&0xFF);//lo CRC
|
||||
writeCom[12]=(HI(crcToSend)&0xFF);//hi CRC
|
||||
|
||||
qDebug()<<writeCom.toHex(); // с этой шляпой всё работает
|
||||
|
||||
qDebug()<<QByteArray::number(writeCom[0], 16)<< "adr";
|
||||
qDebug()<<QByteArray::number(writeCom[1], 16)<< "comand";
|
||||
qDebug()<<QByteArray::number(writeCom[2], 16)<< "reg HI";
|
||||
qDebug()<<QByteArray::number(writeCom[3], 16)<< "adr reg LO";
|
||||
qDebug()<<QByteArray::number(writeCom[4], 16)<< "num reg HI";
|
||||
qDebug()<<QByteArray::number(writeCom[5], 16)<< "num reg Lo";
|
||||
qDebug()<<QByteArray::number(writeCom[6], 16)<< "num reg bytes";
|
||||
qDebug()<<QByteArray::number(writeCom[7], 16)<< "HI data";
|
||||
qDebug()<<QByteArray::number(writeCom[8], 16)<< "LO data";
|
||||
qDebug()<<QByteArray::number(writeCom[9], 16)<< "HI data";
|
||||
qDebug()<<QByteArray::number(writeCom[10], 16)<< "LO data";
|
||||
qDebug()<<QByteArray::number(writeCom[11], 16)<< " LO CRC ";
|
||||
qDebug()<<QByteArray::number(writeCom[12], 16)<< "CRC HI";
|
||||
|
||||
|
||||
|
||||
serial->open(QIODevice::ReadWrite);
|
||||
serial->write(writeCom);
|
||||
serial->waitForReadyRead(READY_FOR_READ_INT);
|
||||
|
||||
QByteArray rec;
|
||||
rec = serial->readAll();
|
||||
|
||||
|
||||
|
||||
qDebug()<<rec.toHex();
|
||||
|
||||
serial->close();
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool writeConSet(QSerialPort *serial, uint16_t adrCurrent,
|
||||
uint16_t adrNew, uint32_t new_speed, Parity parity)
|
||||
{
|
||||
QByteArray writeCom;
|
||||
writeCom.resize(11);
|
||||
writeCom[0]=adrCurrent;
|
||||
writeCom[1]=0x10; // comand
|
||||
writeCom[2]=0xf;//hi addr 4001
|
||||
writeCom[3]=0xa1; //low addr 4001
|
||||
writeCom[4]=0x00; //hi regs
|
||||
writeCom[5]=0x3;//low regs
|
||||
writeCom[6]=0x6;// байт на отправку
|
||||
|
||||
writeCom[7]=0x0;
|
||||
writeCom[8]=adrNew; //новый адрес
|
||||
|
||||
writeCom[9]=0x0;
|
||||
|
||||
switch (new_speed) {
|
||||
case 4800:
|
||||
writeCom[10]=0x0; //скорость
|
||||
break;
|
||||
case 7200:
|
||||
writeCom[10]=0x1; //скорость
|
||||
break;
|
||||
case 9600:
|
||||
writeCom[10]=0x2; //скорость
|
||||
break;
|
||||
case 14400:
|
||||
writeCom[10]=0x3; //скорость
|
||||
break;
|
||||
case 19200:
|
||||
writeCom[10]=0x4; //скорость
|
||||
break;
|
||||
case 38400:
|
||||
writeCom[10]=0x5; //скорость
|
||||
break;
|
||||
case 57600:
|
||||
writeCom[10]=0x6; //скорость
|
||||
break;
|
||||
case 115200:
|
||||
writeCom[10]=0x7; //скорость
|
||||
break;
|
||||
case 128000:
|
||||
writeCom[10]=0x8; //скорость
|
||||
break;
|
||||
case 230400:
|
||||
writeCom[10]=0x9; //скорость
|
||||
break;
|
||||
default:
|
||||
qDebug()<<"Со скоростью беда";
|
||||
break;
|
||||
}
|
||||
writeCom[11]=0x0;
|
||||
switch (parity) {
|
||||
case UART_PARITY_NONE:
|
||||
writeCom[12]=0x0;
|
||||
break;
|
||||
case UART_PARITY_ODD:
|
||||
writeCom[12]=0x1;
|
||||
break;
|
||||
case UART_PARITY_EVEN:
|
||||
writeCom[12]=0x2;
|
||||
break;
|
||||
}
|
||||
//бит четности
|
||||
|
||||
|
||||
uint16_t crcToSend;
|
||||
crcToSend= Crc16((uint16_t)13, writeCom); //длинна захардкожена //Возможно будет неправильно считать
|
||||
writeCom[13]=(LO(crcToSend)&0xFF);//lo CRC
|
||||
writeCom[14]=(HI(crcToSend)&0xFF);//hi CRC
|
||||
|
||||
|
||||
qDebug()<<writeCom.toHex(); // с этой шляпой всё работает
|
||||
|
||||
qDebug()<<QByteArray::number(writeCom[0], 16)<< "adr";
|
||||
qDebug()<<QByteArray::number(writeCom[1], 16)<< "comand";
|
||||
qDebug()<<QByteArray::number(writeCom[2], 16)<< "reg HI";
|
||||
qDebug()<<QByteArray::number(writeCom[3], 16)<< "adr reg LO";
|
||||
qDebug()<<QByteArray::number(writeCom[4], 16)<< "num reg HI";
|
||||
qDebug()<<QByteArray::number(writeCom[5], 16)<< "num reg Lo";
|
||||
qDebug()<<QByteArray::number(writeCom[6], 16)<< "num reg bytes";
|
||||
qDebug()<<QByteArray::number(writeCom[7], 16)<< "HI data";
|
||||
qDebug()<<QByteArray::number(writeCom[8], 16)<< "LO data";
|
||||
qDebug()<<QByteArray::number(writeCom[9], 16)<< "HI data";
|
||||
qDebug()<<QByteArray::number(writeCom[10], 16)<< "LO data";
|
||||
qDebug()<<QByteArray::number(writeCom[11], 16)<< "HI data";
|
||||
qDebug()<<QByteArray::number(writeCom[12], 16)<< "LO data";
|
||||
qDebug()<<QByteArray::number(writeCom[13], 16)<< " LO CRC ";
|
||||
qDebug()<<QByteArray::number(writeCom[14], 16)<< "CRC HI";
|
||||
|
||||
|
||||
serial->open(QIODevice::ReadWrite);
|
||||
serial->write(writeCom);
|
||||
serial->waitForReadyRead(READY_FOR_READ_INT);
|
||||
QByteArray rec;
|
||||
rec = serial->readAll();
|
||||
|
||||
qDebug()<<rec.toHex();
|
||||
|
||||
serial->close();
|
||||
if(((rec[0]&0xFF)==adrCurrent) && ((rec[1]&0xFF)==0x10)) return NO_ERROR;
|
||||
else return ERROR;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sensStruct readSensTest(QSerialPort *serial, uint16_t adr)
|
||||
{
|
||||
|
||||
|
||||
sensStruct result;
|
||||
usfloat res;
|
||||
res.ch[0] =0;
|
||||
res.ch[1] =0;
|
||||
res.ch[2] =0;
|
||||
res.ch[3] =0;
|
||||
//структура на отправку
|
||||
uint16_t toSend[8]={0,};
|
||||
uint16_t recived[25]={0,};
|
||||
toSend[0]=adr;
|
||||
toSend[1]=0x3; // comand
|
||||
|
||||
//Если мы хотим читать 7502 - то нужно увеличить размер
|
||||
//toSend[2]=0x1d;//hi addr 7502
|
||||
//toSend[3]=0x4e; //low addr 7502
|
||||
|
||||
toSend[2]=0x1b;//hi addr 7004
|
||||
toSend[3]=0x5c; //low addr 7004
|
||||
|
||||
toSend[4]=0x00; //hi regs
|
||||
toSend[5]=0x02;//low regs
|
||||
uint16_t crc = Crc16(6, toSend);
|
||||
toSend[6]=LO(crc);//lo CRC
|
||||
toSend[7]=HI(crc);//hi CRC
|
||||
|
||||
QByteArray readCom;
|
||||
readCom.resize(8);
|
||||
// uint16_t crc = Crc16(5);
|
||||
readCom[0]=toSend[0];
|
||||
readCom[1]=toSend[1];
|
||||
readCom[2]=toSend[2]; //hi addr 5001
|
||||
readCom[3]=toSend[3]; //low addr
|
||||
readCom[4]=toSend[4]; //hi regs
|
||||
readCom[5]=toSend[5]; //low regs
|
||||
readCom[6]=toSend[6]; //lo CRC
|
||||
readCom[7]=toSend[7]; //hi CRC
|
||||
|
||||
serial->open(QIODevice::ReadWrite); // открыли порт на запись и чтение
|
||||
serial->write(readCom);
|
||||
serial->waitForReadyRead(READY_FOR_READ_INT);
|
||||
|
||||
QByteArray rec;
|
||||
rec.resize(PACKET_SENS_SIZE);
|
||||
rec = serial->readAll();
|
||||
serial->close();
|
||||
|
||||
|
||||
|
||||
for(int i=0; i<PACKET_SENS_SIZE;i++){
|
||||
recived[i]=rec.constData()[i];
|
||||
}
|
||||
|
||||
int indNachalaCrc = recived[2]+3; //todo: проверить
|
||||
uint16_t crcRecived = Crc16(indNachalaCrc, recived); // в функции используют больше или меньше
|
||||
// qDebug()<<QString("Начало CRC в пакете %1").arg(indNachalaCrc);
|
||||
// qDebug()<<QString("ожидаемая CRC %1%2").arg(LO(crcRecived), 0, 16).arg(HI(crcRecived), 0, 16);
|
||||
// qDebug()<<QString("Прибывшая CRC %1%2").arg(recived[indNachalaCrc], 0, 16).arg(recived[indNachalaCrc+1], 0, 16);
|
||||
|
||||
//если CRC Норм ставим зеленый
|
||||
if((recived[indNachalaCrc]&0xFF)==LO(crcRecived)&&(recived[indNachalaCrc+1]&0xFF)==HI(crcRecived)){ //todo внимание костыль
|
||||
result.crcOk =true;
|
||||
qDebug()<<"Чтение чувуствительности CRC Ок";
|
||||
}else{
|
||||
qDebug()<<"Чтение чувуствительности CRC не катит";
|
||||
result.crcOk =false;
|
||||
}
|
||||
|
||||
|
||||
res.ch[3]=recived[3]; // Собираю флоат
|
||||
res.ch[2]=recived[4];
|
||||
res.ch[1]=recived[5];
|
||||
res.ch[0]=recived[6];
|
||||
|
||||
qDebug()<<(float)res.fl;
|
||||
result.sens =res.fl;
|
||||
return result;
|
||||
}
|
31
comWorks.h
31
comWorks.h
|
@ -1,4 +1,35 @@
|
|||
#ifndef COMWORKS_H
|
||||
#define COMWORKS_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "enums.h"
|
||||
#include "mainwindow.h"
|
||||
#include "QDebug"
|
||||
|
||||
|
||||
//extern QSerialPort *serial;
|
||||
//bool connectToCom();
|
||||
|
||||
|
||||
#define LO(x) ((uint8_t) ((x) & 0xff))
|
||||
#define HI(x) ((uint8_t) (((x) >> 8) & 0xff))
|
||||
|
||||
|
||||
stateStruct readSet(QSerialPort *serial, uint16_t adr);
|
||||
sensStruct readSens(QSerialPort *serial, uint16_t adr);
|
||||
sensStruct readSensTest(QSerialPort *serial, uint16_t adr);
|
||||
|
||||
bool writePalam(QSerialPort *serial, uint16_t adr, typeParam typeparam, uint16_t value);
|
||||
|
||||
bool writeConSet(QSerialPort *serial, uint16_t adrCurrent,
|
||||
uint16_t adrNew, uint32_t new_speed, Parity parity);
|
||||
|
||||
bool writeSens(QSerialPort *serial, uint16_t adr,float value);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // COMWORKS_H
|
||||
|
|
|
@ -1,6 +1,33 @@
|
|||
#include "customlabel.h"
|
||||
|
||||
CustomLabel::CustomLabel(QWidget *parent) : QWidget(parent)
|
||||
CustomLabel::CustomLabel(QWidget *parent) : QLabel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CustomLabel::wheelEvent(QWheelEvent * event)
|
||||
{
|
||||
if (event->delta() > 0) {
|
||||
emit wheelUp();
|
||||
}else{
|
||||
emit wheelDown();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CustomLabel::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
emit clicked();
|
||||
}
|
||||
|
||||
void CustomLabel::enterEvent(QEvent * event)
|
||||
{
|
||||
this->setStyleSheet("QLabel { background-color : #00bbff; color : black; }");
|
||||
emit focused();
|
||||
}
|
||||
|
||||
void CustomLabel::leaveEvent(QEvent * event)
|
||||
{
|
||||
this->setStyleSheet("QLabel { background-color : black; color : #00bbff; }");
|
||||
emit unfocused();
|
||||
}
|
||||
|
|
|
@ -1,17 +1,35 @@
|
|||
#ifndef CUSTOMLABEL_H
|
||||
#define CUSTOMLABEL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QMouseEvent>
|
||||
#include <QWheelEvent>
|
||||
#include <QDebug>
|
||||
|
||||
class CustomLabel : public QWidget
|
||||
class CustomLabel : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CustomLabel(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
protected:
|
||||
void wheelEvent(QWheelEvent * event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void enterEvent(QEvent * event) override;
|
||||
void leaveEvent(QEvent * event) override;
|
||||
|
||||
|
||||
//void mouseRe(QMouseEvent *event) override;
|
||||
|
||||
|
||||
|
||||
|
||||
signals:
|
||||
void wheelUp();
|
||||
void wheelDown();
|
||||
void clicked();
|
||||
void focused();
|
||||
void unfocused();
|
||||
};
|
||||
|
||||
#endif // CUSTOMLABEL_H
|
||||
|
|
107
enums.h
107
enums.h
|
@ -1,4 +1,111 @@
|
|||
#ifndef ENUMS_H
|
||||
#define ENUMS_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include <QObject>
|
||||
|
||||
typedef enum { NO_ERROR =0, ERROR } typeError;
|
||||
|
||||
typedef enum { CHARGE = 0} typeIIN;
|
||||
typedef enum { Ku0_1 = 0, Ku0_2, Ku0_5, Ku1, Ku2, Ku5, Ku10, Ku20, Ku50, Ku100, Ku200, Ku500, Ku1000 } typeIKU;
|
||||
typedef enum { Hp0_2 = 0, Hp1, Hp2, Hp10 } typeIFV;
|
||||
typedef enum { Lp100 = 0, Lp300, Lp1000, Lp3000, Lp10000, Lp30000, Lp100000 } typeIFN;
|
||||
typedef enum{MS2=0, PA, H } typeUnit;
|
||||
typedef enum{Oz=0, Pz } typePlavGround;
|
||||
typedef enum{Norm=0, Overload } typeOverload;
|
||||
|
||||
typedef enum{in=0, ku, fv,fn,unit,overload,pz } typeParam;
|
||||
|
||||
typedef enum {UART_PARITY_NONE=0, UART_PARITY_ODD, UART_PARITY_EVEN} Parity;
|
||||
|
||||
static const uint32_t BAUDRATE[] = {4800, 7200, 9600, 14400, 19200, 38400, 57600, 115200, 128000, 230400};
|
||||
|
||||
typedef enum {s4800, s7200, s9600, s14400, s19200, s38400, s57600, s115200, s128000, s230400} Baudrate;
|
||||
|
||||
typedef enum {}setConnectionParameterNotyfy;
|
||||
|
||||
typedef struct{uint adress;
|
||||
typeIIN in;
|
||||
typeIKU ku;
|
||||
typeIFV fv;
|
||||
typeIFN fn;
|
||||
typeUnit unit;
|
||||
typeOverload overload;
|
||||
typePlavGround pz;
|
||||
bool crcOk;
|
||||
}stateStruct;
|
||||
|
||||
typedef struct{uint adress;
|
||||
float sens;
|
||||
bool crcOk;
|
||||
}sensStruct;
|
||||
|
||||
|
||||
typedef struct{//адрес скорость четность
|
||||
}conSet;
|
||||
|
||||
|
||||
typedef enum{OWN = 4001,
|
||||
BAUD = 4002,
|
||||
INFB=4003,
|
||||
IIN=5001,
|
||||
IFV=5002,
|
||||
IFN=5003,
|
||||
IKU=5004,
|
||||
IKE=5005,
|
||||
IKD=5006,
|
||||
IKS=5007,
|
||||
IPZ=5008,
|
||||
OPZ=5009,
|
||||
UNIT=5010,
|
||||
OVERLOAD=5011,
|
||||
IK0=5012,
|
||||
IK1=5013,
|
||||
IK2=5014,
|
||||
IK3=5015,
|
||||
IK4=5016,
|
||||
IK5=5017,
|
||||
KCOND=7501,
|
||||
SENS=7002,
|
||||
SENS2=7502,
|
||||
ACCEL=7503,
|
||||
|
||||
}regEnum;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct{ QString port;
|
||||
uint16_t adress;//адрес
|
||||
uint32_t speed; //скорость
|
||||
Parity parity; //четность
|
||||
}PrborConnectonAtr;
|
||||
|
||||
|
||||
typedef struct{ uint16_t adress;
|
||||
float sens;
|
||||
typeIIN in;
|
||||
typeIKU ku;
|
||||
typeIFV fv;
|
||||
typeIFN fn;
|
||||
typeUnit unit;
|
||||
typeOverload overload;
|
||||
typePlavGround pz; //четность
|
||||
}DataStruct;
|
||||
|
||||
|
||||
typedef enum{ ALL_RIGHT=0,
|
||||
IS_BUSY,
|
||||
MODEBUS_ERROR //четность
|
||||
}ErrorCode;
|
||||
|
||||
|
||||
|
||||
typedef union{
|
||||
uint8_t ch[4];
|
||||
uint16_t sh[2];
|
||||
float fl;
|
||||
} usfloat;
|
||||
|
||||
#endif // ENUMS_H
|
||||
|
|
4
main.cpp
4
main.cpp
|
@ -4,6 +4,10 @@
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
//шляпка для конфигов
|
||||
QCoreApplication::setOrganizationName("org");
|
||||
QCoreApplication::setApplicationName("app");
|
||||
//она неявно определяет их местоположение
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
|
468
mainwindow.cpp
468
mainwindow.cpp
|
@ -1,15 +1,473 @@
|
|||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
//подключаем последующие окна
|
||||
#include "setpribor.h"
|
||||
#include "enums.h"
|
||||
#include "QDebug"
|
||||
#include "comWorks.h"
|
||||
#include "qvalidator.h"
|
||||
#include "cstring"
|
||||
#include "QThread"
|
||||
#include "QInputDialog"
|
||||
#include <vector>
|
||||
#include <QSettings>
|
||||
#include "secondwindows.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::MainWindow)
|
||||
const char *STRINGS_OUTUNITS[] = {"0.0001мВ/",
|
||||
"0.0002мВ/",
|
||||
"0.0005мВ/",
|
||||
"0.001мВ/", //3
|
||||
"0.002мВ/",
|
||||
"0.005мВ/",
|
||||
"0.01мВ/",//6
|
||||
"0.02мВ/",
|
||||
"0.05мВ/",
|
||||
"0.1мВ/",//9
|
||||
"0.2мВ/",
|
||||
"0.5мВ/",
|
||||
"1мВ/",//12
|
||||
"2мВ/",
|
||||
"5мВ/",
|
||||
"10мВ/",//15
|
||||
"20мВ/",
|
||||
"50мВ/",
|
||||
"100мВ/",//18
|
||||
"200мВ/",
|
||||
"500мВ/",
|
||||
"1В/",//21
|
||||
"2В/",
|
||||
"5В/",
|
||||
"10В/",//24
|
||||
"20В/",
|
||||
"50В/",
|
||||
"100В/",//27
|
||||
"200В/",
|
||||
"500В/",
|
||||
"1000В/", //30
|
||||
};
|
||||
|
||||
const char *STRINGS_UNITS[]={"мс2","Па","Н"}; // массив с единицами измерений
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
conf = new QSettings();
|
||||
ui->setupUi(this);
|
||||
|
||||
|
||||
//Перенос хэндлера в друглй поток- перечтают работать сигналы
|
||||
|
||||
// modeBusThread = new QThread(this);
|
||||
modebus = new ModBusHandler();
|
||||
// modebus ->moveToThread(modeBusThread);
|
||||
// modeBusThread->start();
|
||||
|
||||
|
||||
|
||||
|
||||
connect(modebus, SIGNAL(dataRecivedNotify(DataStruct)),this, SLOT(dataSetter(DataStruct)));
|
||||
//по получению данных проверяем адрес раскидываем их по переменным
|
||||
//и обновляем экран
|
||||
|
||||
|
||||
|
||||
QWidget::setWindowTitle("А1210");
|
||||
QWidget::setFixedSize( 314, 372 );
|
||||
OffsetKuDisplay=0;
|
||||
isConnected = false;
|
||||
|
||||
|
||||
|
||||
// Перечислим порты в консоль
|
||||
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){ //для каждого доступного порта
|
||||
QSerialPort port; //
|
||||
port.setPort(info); //
|
||||
if(port.open(QIODevice::ReadWrite)){// если порт доступен
|
||||
ui->comboBoxPort->addItem(info.portName()); // Добавляем в список доступных
|
||||
comList.push_back(info.portName());
|
||||
}
|
||||
}//конец foreach
|
||||
|
||||
|
||||
//формирую комбобокс для установки скорости
|
||||
extern const uint32_t BAUDRATE[];
|
||||
for(uint i = 0; i<10; i++){ui->comboBoxSpeed->addItem(QString::number(BAUDRATE[i]));
|
||||
}
|
||||
|
||||
//формирую данные для комбобокса бита четности
|
||||
ui->comboBoxBit->addItem("Нет"); // Добавляем в список доступных
|
||||
ui->comboBoxBit->addItem("Четности"); // Добавляем в список доступных
|
||||
ui->comboBoxBit->addItem("Нечетности"); // Добавляем в список доступных
|
||||
|
||||
// значения для полей из сохраненных значений
|
||||
ui->comboBoxPort->setCurrentIndex(conf->value("section1/keyCurrentPort").toInt());
|
||||
ui->comboBoxSpeed->setCurrentIndex(conf->value("section1/keyCurrentSpeed").toInt());
|
||||
ui->comboBoxBit->setCurrentIndex(conf->value("section1/keyCurrentBit").toInt());
|
||||
ui->lineEditAddr->setText(conf->value("section1/keyAdress").toString());
|
||||
|
||||
//передаем текущие значения полей в глобальные переменные
|
||||
adrValue=ui->lineEditAddr->text();
|
||||
bitComboboxIndex=ui->comboBoxBit->currentIndex();
|
||||
portComboboxIndex=ui->comboBoxPort->currentIndex();
|
||||
speedComboboxIndex=ui->comboBoxSpeed->currentIndex();
|
||||
|
||||
|
||||
|
||||
|
||||
}//конец конструктора главного окна
|
||||
|
||||
|
||||
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
qDebug()<<"сработал деструктор первого окна";
|
||||
//сохранение значения полей
|
||||
conf->setValue("section1/keyCurrentPort", ui->comboBoxPort->currentIndex());
|
||||
conf->setValue("section1/keyCurrentSpeed", ui->comboBoxSpeed->currentIndex());
|
||||
conf->setValue("section1/keyCurrentBit", ui->comboBoxBit->currentIndex());
|
||||
conf->setValue("section1/keyAdress", ui->lineEditAddr->text());
|
||||
// modeBusThread->quit();
|
||||
// modeBusThread->wait(1000);
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::dataSetter(DataStruct data)
|
||||
{
|
||||
if(adrPri==data.adress){
|
||||
state=data;
|
||||
refreshDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//todo: заблокировать элементы управления без подключения
|
||||
void MainWindow::on_pushButtonConnect_clicked()
|
||||
{
|
||||
|
||||
adrPri=ui->lineEditAddr->text().toInt(); //todo:добавить валидатор для адреса
|
||||
if(isConnected==false){
|
||||
|
||||
|
||||
PrborConnectonAtr thisPribor;
|
||||
thisPribor.port=ui->comboBoxPort->currentText();
|
||||
thisPribor.adress=ui->lineEditAddr->text().toInt();
|
||||
thisPribor.speed=(ui->comboBoxSpeed->currentText().toInt());
|
||||
thisPribor.parity=(Parity)ui->comboBoxBit->currentIndex();
|
||||
|
||||
modebus->addToReqList(thisPribor); //добавляем прибор в список опрашиваемых
|
||||
|
||||
|
||||
ui->pushButtonConnect->setText("Отключение");
|
||||
//блокируем элементы
|
||||
ui->lineEditAddr->setDisabled(true);
|
||||
ui->pushButtonSetPri->setDisabled(true);
|
||||
ui->comboBoxPort->setDisabled(true);
|
||||
ui->comboBoxBit->setDisabled(true);
|
||||
ui->comboBoxSpeed->setDisabled(true);
|
||||
isConnected=true;
|
||||
}
|
||||
else if(isConnected==true){
|
||||
modebus->removeFromReqList(adrPri);
|
||||
|
||||
//удаляем прибор с данным адресом из списка
|
||||
|
||||
//опустошаем форму
|
||||
ui->labelKu->setText("XXXXX");
|
||||
ui->labelNch->setText("XX");
|
||||
ui->labelVch->setText("XX");
|
||||
ui->labelSens->setText("XXXXX");
|
||||
ui->labelPlavGround->setText("XX");
|
||||
ui->labelUnitSens->setText("XXXXXX");
|
||||
|
||||
//разблокируем элементы
|
||||
ui->lineEditAddr->setDisabled(false);
|
||||
ui->comboBoxPort->setDisabled(false);
|
||||
ui->pushButtonSetPri->setDisabled(false);
|
||||
ui->comboBoxBit->setDisabled(false);
|
||||
ui->comboBoxSpeed->setDisabled(false);
|
||||
ui->pushButtonConnect->setText("Подключение");
|
||||
|
||||
isConnected=false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_pushButtonAddPri_clicked()
|
||||
{
|
||||
SecondWindows *w2 = new SecondWindows(this);
|
||||
w2->show();
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_pushButtonSetPri_clicked()
|
||||
{
|
||||
SetPribor *w2 = new SetPribor(this); //передаем в новый обьект указатель на существующий для доступа к нему
|
||||
w2->exec();
|
||||
|
||||
/*
|
||||
SetPribor setpribor;
|
||||
setpribor.setModal(true);
|
||||
setpribor.exec();
|
||||
*/
|
||||
}
|
||||
|
||||
void MainWindow::getSens(){
|
||||
// sens=readSens(serial, adrPri);
|
||||
|
||||
};
|
||||
|
||||
|
||||
void MainWindow::getState(){
|
||||
// state = readSet(serial, adrPri);
|
||||
|
||||
|
||||
};
|
||||
|
||||
void MainWindow::setState(){
|
||||
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::refreshDisplay(){
|
||||
|
||||
//делаем дополнение до 6 знаков
|
||||
if(state.sens==1000) { ui->labelSens->setText(QString::number(state.sens,'f', 1));}
|
||||
else if(state.sens<1000&&state.sens>=100) {ui->labelSens->setText(QString::number(state.sens,'f', 2));}
|
||||
else if(state.sens<100&&state.sens>=10){ui->labelSens->setText(QString::number(state.sens,'f', 3));}
|
||||
else {ui->labelSens->setText(QString::number(state.sens,'f', 4));}
|
||||
|
||||
//с автоподгонкой всё начинает прыгать. Я думаю всё прокатит если её применять поьлко по изменеию содержимого
|
||||
//ui->labelSens->adjustSize(); //подгоняем размер по содержимому
|
||||
|
||||
|
||||
|
||||
switch (state.fn) {
|
||||
case Lp100:
|
||||
ui->labelNch->setText("0.1");
|
||||
break;
|
||||
case Lp300:
|
||||
ui->labelNch->setText("0.3");
|
||||
break;
|
||||
case Lp1000:
|
||||
ui->labelNch->setText("1");
|
||||
break;
|
||||
case Lp3000:
|
||||
ui->labelNch->setText("3");
|
||||
break;
|
||||
case Lp10000:
|
||||
ui->labelNch->setText("10");
|
||||
break;
|
||||
case Lp30000:
|
||||
ui->labelNch->setText("30");
|
||||
break;
|
||||
case Lp100000:
|
||||
ui->labelNch->setText("100");
|
||||
break;
|
||||
default:
|
||||
ui->labelNch->setText("#####");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch (state.fv) {
|
||||
case Hp0_2 :
|
||||
ui->labelVch->setText("0.2");
|
||||
break;
|
||||
case Hp1:
|
||||
ui->labelVch->setText("1");
|
||||
break;
|
||||
case Hp2:
|
||||
ui->labelVch->setText("2");
|
||||
break;
|
||||
case Hp10:
|
||||
ui->labelVch->setText("10");
|
||||
break;
|
||||
default:
|
||||
ui->labelVch->setText("#####");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////
|
||||
///// вывод юнитов и нормирование///
|
||||
////////////////////////////////////
|
||||
|
||||
////Аналогично прибору считаем смещение по массиву значений
|
||||
///
|
||||
if (state.sens>=0.0001&&state.sens<0.001) {OffsetKuDisplay=0;} // такие значения не допустимы
|
||||
else if (state.sens>=0.001&&state.sens<0.01){OffsetKuDisplay=0;}
|
||||
else if (state.sens>=0.01&&state.sens<0.1){OffsetKuDisplay=3; }
|
||||
else if (state.sens>=0.1&&state.sens<1){OffsetKuDisplay=6;}
|
||||
else if (state.sens>=1&&state.sens<10){OffsetKuDisplay=9;}
|
||||
else if (state.sens>=10&&state.sens<100){OffsetKuDisplay=12;}
|
||||
else if (state.sens>=100&&state.sens<1000){OffsetKuDisplay=15;}
|
||||
else if (state.sens<=1000){OffsetKuDisplay=18;}
|
||||
|
||||
char * result = (char *)malloc(strlen(STRINGS_OUTUNITS[state.ku+OffsetKuDisplay]) + strlen(STRINGS_UNITS[state.unit]) + 1); // +1 for the null-terminator
|
||||
strcpy(result, STRINGS_OUTUNITS[state.ku+OffsetKuDisplay]);
|
||||
strcat(result, STRINGS_UNITS[state.unit]);
|
||||
|
||||
ui->labelKu->setText(result);
|
||||
ui->labelKu->adjustSize();
|
||||
free(result); /// освободил память
|
||||
|
||||
|
||||
|
||||
|
||||
switch (state.pz) { //todo тут нужно нормирование
|
||||
case 0 :
|
||||
ui->labelPlavGround->setText("ОЗ");
|
||||
break;
|
||||
case 1:
|
||||
ui->labelPlavGround->setText("ПЗ");
|
||||
break;
|
||||
default:
|
||||
ui->labelPlavGround->setText("#####");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
switch (state.unit) { //todo тут нужно нормирование
|
||||
case H :
|
||||
ui->labelUnitSens->setText("пКл/Н");
|
||||
// ui->labelUnitKu->setText("xВ/Н"); // Заменил на нормирование с прибора
|
||||
break;
|
||||
case PA:
|
||||
ui->labelUnitSens->setText("пКл/Па");
|
||||
// ui->labelUnitKu->setText("xВ/Па");
|
||||
break;
|
||||
case MS2:
|
||||
ui->labelUnitSens->setText("пКл/мс2");
|
||||
// ui->labelUnitKu->setText("xВ/мс2");
|
||||
break;
|
||||
default:
|
||||
ui->labelUnitSens->setText("#####");
|
||||
break;
|
||||
}
|
||||
//ui->labelUnitSens->adjustSize();
|
||||
|
||||
|
||||
switch (state.overload) { //todo тут нужно нормирование
|
||||
case Norm :
|
||||
ui->labelOverload->setText("");
|
||||
break;
|
||||
case Overload:
|
||||
ui->labelOverload->setText("ПЕРЕГРУЗКА");
|
||||
break;
|
||||
default:
|
||||
ui->labelOverload->setText("#####");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
void MainWindow::on_labelKu_wheelDown()
|
||||
{ //смотрим на текущее состояние дел
|
||||
|
||||
state.ku=typeIKU((uint16_t)state.ku-1);
|
||||
modebus->writeDataToPribor(state);
|
||||
//writePalam(serial, adrPri, ku, newVal); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
|
||||
qDebug()<<"WheelDown";
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_labelKu_wheelUp()
|
||||
{
|
||||
state.ku=typeIKU((uint16_t)state.ku+1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
qDebug()<<"WheelUp";
|
||||
}
|
||||
|
||||
void MainWindow::on_labelVch_wheelDown()
|
||||
{
|
||||
|
||||
state.fv=typeIFV((uint16_t)state.fv-1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
qDebug()<<"WheelUp";
|
||||
}
|
||||
|
||||
void MainWindow::on_labelVch_wheelUp()
|
||||
{
|
||||
state.fv=typeIFV((uint16_t)state.fv+1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
qDebug()<<"WheelUp";
|
||||
}
|
||||
|
||||
void MainWindow::on_labelNch_wheelDown()
|
||||
{
|
||||
|
||||
state.fn=typeIFN((uint16_t)state.fn-1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
void MainWindow::on_labelNch_wheelUp()
|
||||
{
|
||||
state.fn=typeIFN((uint16_t)state.fn+1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_labelPlavGround_wheelDown()
|
||||
{
|
||||
state.pz=typePlavGround((uint16_t)state.pz-1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
void MainWindow::on_labelPlavGround_wheelUp()
|
||||
{
|
||||
state.pz=typePlavGround((uint16_t)state.pz+1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
void MainWindow::on_labelUnitSens_wheelDown()
|
||||
{
|
||||
|
||||
state.unit=typeUnit((uint16_t)state.unit-1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
void MainWindow::on_labelUnitSens_wheelUp()
|
||||
{
|
||||
state.unit=typeUnit((uint16_t)state.unit+1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MainWindow::on_labelSens_clicked()
|
||||
{
|
||||
bool ok;
|
||||
state.sens = QInputDialog::getDouble(this, tr("Введите значение"),
|
||||
tr("Введите значение чувствительности датчика"), state.sens, 0.001, 1000, 4, &ok,
|
||||
Qt::WindowFlags(), 1);
|
||||
|
||||
if (ok){modebus->writeDataToPribor(state);}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_comboBoxPort_currentIndexChanged(int )
|
||||
{
|
||||
portComboboxIndex=ui->comboBoxPort->currentIndex();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_comboBoxSpeed_currentIndexChanged(int )
|
||||
{
|
||||
speedComboboxIndex=ui->comboBoxSpeed->currentIndex();
|
||||
}
|
||||
|
||||
void MainWindow::on_comboBoxBit_currentIndexChanged(int )
|
||||
{
|
||||
bitComboboxIndex=ui->comboBoxBit->currentIndex();
|
||||
}
|
||||
|
||||
void MainWindow::on_lineEditAddr_textEdited(const QString &)
|
||||
{
|
||||
adrValue=ui->lineEditAddr->text();
|
||||
}
|
||||
|
|
91
mainwindow.h
91
mainwindow.h
|
@ -2,20 +2,109 @@
|
|||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "secondwindows.h"
|
||||
#include "QDebug"
|
||||
#include <enums.h>
|
||||
#include <QSettings>
|
||||
|
||||
|
||||
#include <modbushandler.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class MainWindow; }
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#define LO(x) ((uint8_t) ((x) & 0xff))
|
||||
#define HI(x) ((uint8_t) (((x) >> 8) & 0xff))
|
||||
|
||||
|
||||
|
||||
#define REFRESH_TIME_MS 5
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
|
||||
~MainWindow();
|
||||
|
||||
private:
|
||||
ModBusHandler *modebus;
|
||||
QThread *modeBusThread;
|
||||
|
||||
|
||||
Ui::MainWindow *ui;
|
||||
QSerialPort *serial;
|
||||
QVector <QString> comList;
|
||||
|
||||
|
||||
int portComboboxIndex;
|
||||
int speedComboboxIndex;
|
||||
int bitComboboxIndex;
|
||||
QString adrValue;
|
||||
QSettings *conf;
|
||||
|
||||
public slots:
|
||||
void dataSetter(DataStruct data);
|
||||
|
||||
|
||||
|
||||
private slots:
|
||||
|
||||
void on_pushButtonConnect_clicked();
|
||||
|
||||
void on_pushButtonAddPri_clicked();
|
||||
|
||||
void on_pushButtonSetPri_clicked();
|
||||
|
||||
void on_labelKu_wheelDown();
|
||||
|
||||
void on_labelKu_wheelUp();
|
||||
|
||||
void on_labelVch_wheelDown();
|
||||
|
||||
void on_labelVch_wheelUp();
|
||||
|
||||
void on_labelNch_wheelDown();
|
||||
|
||||
void on_labelNch_wheelUp();
|
||||
|
||||
void on_labelPlavGround_wheelDown();
|
||||
|
||||
void on_labelPlavGround_wheelUp();
|
||||
|
||||
void on_labelUnitSens_wheelDown();
|
||||
|
||||
void on_labelUnitSens_wheelUp();
|
||||
|
||||
void on_labelSens_clicked();
|
||||
|
||||
void on_comboBoxPort_currentIndexChanged(int index);
|
||||
|
||||
void on_comboBoxSpeed_currentIndexChanged(int index);
|
||||
|
||||
void on_comboBoxBit_currentIndexChanged(int index);
|
||||
|
||||
void on_lineEditAddr_textEdited(const QString &arg1);
|
||||
|
||||
private:
|
||||
|
||||
uint16_t adrPri;
|
||||
QByteArray ba;
|
||||
bool isConnected;
|
||||
QTimer *tmr;
|
||||
static const uint16_t Crc16Table[256];
|
||||
DataStruct state;
|
||||
|
||||
int OffsetKuDisplay;
|
||||
|
||||
void getSens();
|
||||
void getState();
|
||||
void setState();
|
||||
void refreshDisplay();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
8046
mainwindow.ui
8046
mainwindow.ui
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,475 @@
|
|||
#include "modbushandler.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define REQ_PERIOD 50 //прериод опроса
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ModBusHandler::ModBusHandler(QObject *parent) : QObject(parent)
|
||||
{
|
||||
modbusDevice = new QModbusRtuSerialMaster;
|
||||
//заводим таймер
|
||||
|
||||
|
||||
|
||||
tmr = new QTimer();
|
||||
tmr->start(REQ_PERIOD);
|
||||
connect(tmr, SIGNAL(timeout()), this, SLOT(requestPriborFromList()));
|
||||
|
||||
|
||||
|
||||
// 2. Если вы находитесь в состоянии соединения, отключите соединение
|
||||
if (modbusDevice->state() == QModbusDevice::ConnectedState)
|
||||
{
|
||||
// отключимся если вдруг подключено
|
||||
modbusDevice->disconnectDevice();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ModBusHandler::~ModBusHandler()
|
||||
{
|
||||
if (modbusDevice)
|
||||
{
|
||||
modbusDevice->disconnectDevice();
|
||||
}
|
||||
|
||||
delete modbusDevice;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ModBusHandler::requestPriborFromList() //слот для истекшего таймера
|
||||
{
|
||||
//пробегаемся по листу и опрашиваем выкидываая сигналы
|
||||
|
||||
static uint numForReqest;
|
||||
|
||||
qDebug()<<"Приборов в списке "<<PriborMap.size();
|
||||
|
||||
|
||||
for(PrborConnectonAtr atr:PriborMap){
|
||||
getDataFromPribor(atr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/////это всё тлен и плюсы
|
||||
//делаем итератор где то наверху
|
||||
//обновляем количество элементов
|
||||
//проверяем, если элемент последний, то в начало
|
||||
//если нет то ++
|
||||
//делаем запрос. - он у нас раз в 300 мс, типа успеет отработать. Ну должен успеть
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ModBusHandler::addToReqList(PrborConnectonAtr pribor)
|
||||
{
|
||||
PriborMap.insert(pribor.adress, pribor);
|
||||
}
|
||||
|
||||
void ModBusHandler::removeFromReqList(uint adress)
|
||||
{
|
||||
PriborMap.remove(adress);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ModBusHandler::getDataFromPribor(PrborConnectonAtr atr) //слот для истекшего таймера
|
||||
{
|
||||
{
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, QVariant(atr.port));
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
|
||||
modbusDevice->setTimeout(100); //1 таймаута
|
||||
modbusDevice->setNumberOfRetries(1);// попытки достучатся
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, atr.speed);
|
||||
switch (atr.parity) {//выставляем парити
|
||||
case UART_PARITY_NONE:
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::NoParity);
|
||||
break;
|
||||
|
||||
case UART_PARITY_ODD:
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::OddParity);
|
||||
break;
|
||||
|
||||
case UART_PARITY_EVEN:
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::EvenParity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
modbusDevice->connectDevice(); //подключаемся!!!
|
||||
isConnected = true;
|
||||
|
||||
readCoils(atr.adress, 5001, 11);
|
||||
|
||||
readCoils(atr.adress, 7004, 2);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ModBusHandler::onReadReady()
|
||||
{
|
||||
auto reply = qobject_cast<QModbusReply*>(sender());
|
||||
if (nullptr == reply)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// определить, есть ли ошибка
|
||||
if (reply->error() == QModbusDevice::NoError)
|
||||
{
|
||||
// Читать данные ответа
|
||||
//qDebug() << "адрес ответа"<<reply->serverAddress();
|
||||
const QModbusDataUnit responseData = reply->result();
|
||||
// qDebug() << responseData.values(); //отсюда летит ответ
|
||||
dataCollector(reply->serverAddress(),responseData.values());
|
||||
}
|
||||
else if (reply->error() == QModbusDevice::ProtocolError)
|
||||
{
|
||||
qDebug() << "Read response Protocol error: " << reply->errorString();
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Read response Error: " << reply->errorString();
|
||||
}
|
||||
// Удалить перенастремленность
|
||||
isWaitingResponse=false;
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ModBusHandler::readCoils(uint16_t adress, uint16_t startCoil, uint16_t numCoil)
|
||||
{
|
||||
if(isWaitingResponse){
|
||||
}
|
||||
QModbusDataUnit data(QModbusDataUnit::HoldingRegisters, startCoil, numCoil);
|
||||
QModbusReply* reply = modbusDevice->sendReadRequest(data, adress); //указатель куда складывать// адрес клиента
|
||||
if (nullptr == reply)
|
||||
{
|
||||
qDebug() << "Отправка данных запроса не удалась:" << modbusDevice->errorString();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!reply->isFinished()) //если сразу не получилось
|
||||
{// то создадим коннект
|
||||
if(isWaitingResponse){
|
||||
|
||||
}
|
||||
isWaitingResponse=1;
|
||||
|
||||
connect(reply, &QModbusReply::finished, this, &ModBusHandler::onReadReady);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reply->error() == QModbusDevice::NoError) //если без ошибок
|
||||
{
|
||||
// Читать данные ответа
|
||||
qDebug() << "адрес ответа"<<reply->serverAddress();
|
||||
const QModbusDataUnit responseData = reply->result();
|
||||
dataCollector(reply->serverAddress(), responseData.values());
|
||||
qDebug() << responseData.values();
|
||||
|
||||
|
||||
}
|
||||
else if (reply->error() == QModbusDevice::ProtocolError)
|
||||
{
|
||||
qDebug() << "Read response Protocol error: " << reply->errorString();
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Read response Error: " << reply->errorString();
|
||||
}
|
||||
|
||||
//Парсим ответ по структуре или пока выведем в дебаг
|
||||
isWaitingResponse=false;
|
||||
delete reply;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ModBusHandler::dataCollector(quint16 adress, QVector<quint16>recivedData)
|
||||
{
|
||||
static bool sensIsRecived;
|
||||
static bool stateIsRecived;
|
||||
static DataStruct data;
|
||||
data.adress=adress;
|
||||
if (recivedData.size()==2){
|
||||
usfloat result;
|
||||
|
||||
result.sh[0]=recivedData[1];
|
||||
result.sh[1]=recivedData[0];
|
||||
|
||||
data.sens= result.fl;
|
||||
sensIsRecived=1;
|
||||
};
|
||||
|
||||
if (recivedData.size()==11){
|
||||
data.in=(typeIIN)recivedData[0];
|
||||
data.fv=(typeIFV)recivedData[1];
|
||||
data.fn=(typeIFN)recivedData[2];
|
||||
data.ku=(typeIKU)recivedData[3];
|
||||
data.unit=(typeUnit)recivedData[9];
|
||||
data.overload=(typeOverload)recivedData[10];
|
||||
data.pz=(typePlavGround)recivedData[7];
|
||||
stateIsRecived=1;
|
||||
};
|
||||
if(stateIsRecived&&stateIsRecived){
|
||||
|
||||
//connect(this,SIGNAL(dataRecivedNotify(DataStruct)),parent(),SLOT(dataSetter(DataStruct)));
|
||||
emit dataRecivedNotify(data);
|
||||
// qDebug()<<"Должен проити эмит";
|
||||
stateIsRecived=0;
|
||||
stateIsRecived=0;
|
||||
}
|
||||
}
|
||||
|
||||
// Входные параметры: startAddress - адрес первого элемента, count - количество элементов (1 или более).
|
||||
QModbusDataUnit ModBusHandler::writeRequest(int startAddress, int count) const {
|
||||
return QModbusDataUnit(QModbusDataUnit::HoldingRegisters, startAddress, count);
|
||||
}
|
||||
|
||||
|
||||
// Входные параметры: startAddress - адрес первого элемента, count - количество элементов (1 или более).
|
||||
void ModBusHandler::prepareWrite(uint16_t adress, int startAddress, int count, QVector<uint16_t> values) {
|
||||
if(!modbusDevice) return;
|
||||
QModbusDataUnit writeUnit = writeRequest(startAddress, count);
|
||||
writeUnit.setValues(values);
|
||||
if(auto *lastRequest = modbusDevice->sendWriteRequest(writeUnit, adress)) {
|
||||
if(!lastRequest->isFinished()) {
|
||||
connect(lastRequest, &QModbusReply::finished, this, [this, lastRequest]() {
|
||||
if(lastRequest->error() == QModbusDevice::ProtocolError) {
|
||||
qDebug() << "ошибка протокола";
|
||||
} else if(lastRequest->error() == QModbusDevice::TimeoutError) {
|
||||
qDebug() << "таймаут";
|
||||
} else if (lastRequest->error() != QModbusDevice::NoError) {
|
||||
qDebug() << "уууууууу";
|
||||
} else if(lastRequest->error() == QModbusDevice::NoError) {
|
||||
qDebug() << "успех)";
|
||||
}
|
||||
emit writeResult(lastRequest->error()); // сигналим о завершении операции
|
||||
lastRequest->deleteLater();
|
||||
qDebug() << "первый deleteLater";
|
||||
});
|
||||
} else {
|
||||
lastRequest->deleteLater();
|
||||
qDebug() << "второй deleteLater";
|
||||
}
|
||||
|
||||
} else {
|
||||
qDebug()<<"Ошибка записи: " + modbusDevice->errorString();
|
||||
}
|
||||
}
|
||||
|
||||
void ModBusHandler::scanAdressSignalChain(uint16_t adrToScan)
|
||||
{
|
||||
if(adrToScan<=247){// делаем запрос
|
||||
{
|
||||
|
||||
isConnected = true;
|
||||
|
||||
QModbusDataUnit data(QModbusDataUnit::HoldingRegisters, 5001, 11); // формируем пакет на отправку
|
||||
QModbusReply* reply = modbusDevice->sendReadRequest(data, adrToScan);
|
||||
if (nullptr == reply)
|
||||
{
|
||||
qDebug() << "Отправка данных запроса не удалась:";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!reply->isFinished()) //
|
||||
{
|
||||
connect(reply, &QModbusReply::finished, this, &ModBusHandler::ScanPortOnReadReady);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
scanPort();//переделать на сигнал иначе стэк может охуеть с такого фокуса
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ModBusHandler::scanPort(QString port){
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, QVariant(port));
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
|
||||
modbusDevice->setTimeout(30); //1 таймаута
|
||||
modbusDevice->setNumberOfRetries(0);// попытки достучатся
|
||||
|
||||
scanPort();
|
||||
}
|
||||
|
||||
void ModBusHandler::scanPort() //принимает сигнал о завершенных адресах
|
||||
{
|
||||
|
||||
// static uint s;//статик скорость // перенес в глобальные
|
||||
// static uint b;//статик бит // перенес в глобальные
|
||||
|
||||
if(isScanning==0){s=0; b=0; isScanning=1;}//если новое новое сканирование обнуляем переменные
|
||||
|
||||
qDebug()<<"Скорость"<<BAUDRATE[s];
|
||||
qDebug()<<"Бит"<<b;
|
||||
|
||||
if(b>=3){ //если инкрементится некуда
|
||||
emit priborNotFounded();
|
||||
s=0;
|
||||
b=0;
|
||||
isScanning=0;
|
||||
return;}
|
||||
|
||||
|
||||
modbusDevice->disconnectDevice();//отключавемся
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, BAUDRATE[s]);
|
||||
switch (b) {//выставляем парити
|
||||
case UART_PARITY_NONE:
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::NoParity);
|
||||
break;
|
||||
|
||||
case UART_PARITY_ODD:
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::OddParity);
|
||||
break;
|
||||
|
||||
case UART_PARITY_EVEN:
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::EvenParity);
|
||||
break;
|
||||
}
|
||||
modbusDevice->connectDevice(); //подключаемся
|
||||
|
||||
//фор меняем на отдельную функцию-слот работающую по сигналам
|
||||
//меняем на отдельную функцию вопрошающиую всех по сигналам.
|
||||
// если вернулся сигнал со значением 247 она вызывает снова сканпорт
|
||||
|
||||
scanAdressSignalChain(1);
|
||||
|
||||
//инкрементим скорость и/или бит
|
||||
if(s<9) s++; //если s меньше крайнего значения индекса массива скоростей
|
||||
else{s=0; b++;}
|
||||
|
||||
|
||||
|
||||
}//конец функции сканпорт
|
||||
|
||||
|
||||
|
||||
|
||||
void ModBusHandler::ScanPortOnReadReady()
|
||||
{
|
||||
auto reply = qobject_cast<QModbusReply*>(sender());
|
||||
if (nullptr == reply)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// определить, есть ли ошибка
|
||||
if (reply->error() == QModbusDevice::NoError)
|
||||
{
|
||||
|
||||
//когда нашел прибор
|
||||
const QModbusDataUnit responseData = reply->result();
|
||||
qDebug() <<reply->serverAddress()<<"прибор грит"<< responseData.values(); //отсюда летит ответ
|
||||
disconnect(this, SIGNAL(scanPlease(uint16_t)), this,SLOT(scanAdressSignalChain(uint16_t))); //рвем коннект цепочки ответ-запрос на всякий
|
||||
isScanning =0;
|
||||
emit priborFounded(reply->serverAddress(),s,b); // передаем сигнал с настройками прибора в окно
|
||||
modbusDevice->disconnectDevice();
|
||||
//не забудь закрыть соединение
|
||||
}
|
||||
|
||||
else{
|
||||
//Когда не нашел прибор но пытаешься еще
|
||||
connect(this, SIGNAL(scanPlease(uint16_t)),SLOT(scanAdressSignalChain(uint16_t)));
|
||||
emit scanPlease((reply->serverAddress()+1)); //
|
||||
emit progressUpToStatusBar(1);
|
||||
disconnect(this, SIGNAL(scanPlease(uint16_t)), this,SLOT(scanAdressSignalChain(uint16_t)));
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ModBusHandler::writeConnectionAttr(PrborConnectonAtr oldAtr,PrborConnectonAtr newAtr){
|
||||
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, QVariant(oldAtr.port));
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
|
||||
modbusDevice->setTimeout(100); //1 таймаута
|
||||
modbusDevice->setNumberOfRetries(1);// попытки достучатся
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, oldAtr.speed);
|
||||
switch (oldAtr.parity) {//выставляем парити
|
||||
case UART_PARITY_NONE:
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::NoParity);
|
||||
break;
|
||||
|
||||
case UART_PARITY_ODD:
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::OddParity);
|
||||
break;
|
||||
|
||||
case UART_PARITY_EVEN:
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::EvenParity);
|
||||
break;
|
||||
}
|
||||
|
||||
modbusDevice->connectDevice(); //подключаемся!!!
|
||||
|
||||
QVector <uint16_t> dataValues(3);
|
||||
dataValues={
|
||||
dataValues[0]=newAtr.adress,
|
||||
dataValues[2]=newAtr.parity,
|
||||
};
|
||||
|
||||
for (int i=0; i<10; i++){ //todo: выкинуть палки-шишки - скорость в структуре как значениеб а передавать нужно индекс массива. Будь умничкой и сделай всё хорошо.
|
||||
if(BAUDRATE[i]==newAtr.speed) dataValues[1]=i; //dataValues[один]
|
||||
|
||||
};
|
||||
prepareWrite(oldAtr.adress, 4001, 3, dataValues);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ModBusHandler::writeDataToPribor(DataStruct datastruct)
|
||||
{
|
||||
|
||||
usfloat floated;
|
||||
floated.fl = datastruct.sens;
|
||||
QVector <uint16_t> floatedQVector(2);
|
||||
floatedQVector[0]=floated.sh[1];
|
||||
floatedQVector[1]=floated.sh[0];
|
||||
prepareWrite(datastruct.adress, 7004, 2, floatedQVector);//7004*
|
||||
|
||||
QVector <uint16_t> dataValues(10);
|
||||
dataValues={
|
||||
dataValues[0]=datastruct.in,
|
||||
dataValues[1]=datastruct.fv,
|
||||
dataValues[2]=datastruct.fn,
|
||||
dataValues[3]=datastruct.ku,
|
||||
dataValues[4]=0,
|
||||
dataValues[5]=0,
|
||||
dataValues[6]=0,
|
||||
dataValues[7]=datastruct.pz,
|
||||
dataValues[8]=0,
|
||||
dataValues[9]=datastruct.unit,
|
||||
// dataValues[10]=datastruct.overload,
|
||||
};
|
||||
prepareWrite(datastruct.adress, 5001, 10, dataValues);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
#ifndef MODBUSHANDLER_H
|
||||
#define MODBUSHANDLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMainWindow>
|
||||
#include <QModbusServer>
|
||||
|
||||
#include <QModbusRtuSerialMaster>
|
||||
|
||||
#include <QModbusDataUnit>
|
||||
#include <QModbusReply>
|
||||
#include <QVariant>
|
||||
#include <QSerialPort>
|
||||
#include <enums.h>
|
||||
#include <qDebug>
|
||||
#include <QTimer>
|
||||
#include <QTime>
|
||||
#include <QThread>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QModbusClient;
|
||||
class QModbusReply;
|
||||
|
||||
|
||||
class ModBusHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ModBusHandler(QObject *parent = nullptr);
|
||||
~ModBusHandler();
|
||||
QModbusClient *modbusDevice = nullptr;
|
||||
bool piborIsReqesting = false;
|
||||
bool isConnected = false;
|
||||
// QList <PrborConnectonAtr> PriborList;
|
||||
QMap<uint,PrborConnectonAtr>PriborMap;
|
||||
bool isWaitingResponse=false;
|
||||
QTimer *tmr;
|
||||
|
||||
//переменные для поиска прибора
|
||||
uint s;uint b;
|
||||
|
||||
signals:
|
||||
void dataRecivedNotify(DataStruct datastruct);
|
||||
void errorNotify(ErrorCode error);
|
||||
|
||||
void scanPlease(uint16_t);
|
||||
void priborFounded(uint a, uint s,uint b); //прибор найден
|
||||
void progressUpToStatusBar(uint);
|
||||
void priborNotFounded();
|
||||
void writeResult(QModbusDevice::Error);
|
||||
|
||||
public slots:
|
||||
|
||||
void requestPriborFromList(); //
|
||||
|
||||
void addToReqList(PrborConnectonAtr pribor);
|
||||
void removeFromReqList(uint adress);
|
||||
|
||||
void scanPort(QString port);
|
||||
void scanPort();
|
||||
|
||||
void writeDataToPribor(DataStruct datastruct); //обработчик в лямде!!!!!
|
||||
void prepareWrite(uint16_t adress, int startAddress, int count, QVector<uint16_t> values);
|
||||
|
||||
void getDataFromPribor(PrborConnectonAtr atr);
|
||||
void readCoils(uint16_t adress, uint16_t startCoil, uint16_t numCoil);
|
||||
|
||||
void onReadReady(); //обработчик чтения
|
||||
void ScanPortOnReadReady(); //обработчик чтения при сканировании
|
||||
|
||||
QModbusDataUnit writeRequest(int startAddress, int count) const;
|
||||
|
||||
void writeConnectionAttr(PrborConnectonAtr oldAtr,PrborConnectonAtr newAtr);
|
||||
|
||||
|
||||
private slots:
|
||||
void scanAdressSignalChain(uint16_t adrToScan);
|
||||
|
||||
private:
|
||||
void dataCollector(quint16 adress, QVector<quint16>recivedData); //сборщик данных для одновременой отправки сенса и данных
|
||||
bool isScanning=0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // MODBUSHANDLER_H
|
|
@ -0,0 +1,358 @@
|
|||
#include "secondwindows.h"
|
||||
#include "ui_secondwindows.h"
|
||||
#include "setpribor.h"
|
||||
#include "enums.h"
|
||||
#include "QDebug"
|
||||
#include "comWorks.h"
|
||||
#include "qvalidator.h"
|
||||
#include "cstring"
|
||||
#include "QThread"
|
||||
#include "QInputDialog"
|
||||
#include <vector>
|
||||
#include <QSettings>
|
||||
#include <modbushandler.h>
|
||||
|
||||
extern const char *STRINGS_OUTUNITS[];
|
||||
extern const char *STRINGS_UNITS[]; // массив с единицами измерений
|
||||
|
||||
|
||||
|
||||
SecondWindows::SecondWindows(MainWindow *parent) ://конструктор
|
||||
QMainWindow(parent), //наследует qt класс
|
||||
ui(new Ui::SecondWindows) //наследует уи
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->setAttribute(Qt::WA_DeleteOnClose, true); //что бы сработал деструктор при закрытии
|
||||
modebus =parent->modebus; //забираем модбас папочки
|
||||
conf = parent->conf;
|
||||
|
||||
connect(modebus, SIGNAL(dataRecivedNotify(DataStruct)),this, SLOT(dataSetter(DataStruct)));
|
||||
//по получению данных проверяем адрес раскидываем их по переменным
|
||||
//и обновляем экран
|
||||
|
||||
QWidget::setWindowTitle("А1210");
|
||||
QWidget::setFixedSize( 315, 358 );
|
||||
OffsetKuDisplay=0;
|
||||
isConnected = false;
|
||||
|
||||
extern const uint32_t BAUDRATE[];
|
||||
for(uint i = 0; i<10; i++){ui->comboBoxSpeed->addItem(QString::number(BAUDRATE[i]));
|
||||
}
|
||||
|
||||
// Возьмем порты у папочки
|
||||
foreach(const auto com, parent->comList){ //для каждого доступного порта
|
||||
ui->comboBoxPort->addItem(com); // Добавляем в список доступных
|
||||
}//
|
||||
|
||||
//формирую данные для комбобокса бита четности
|
||||
ui->comboBoxBit->addItem("Нет"); // Добавляем в список доступных
|
||||
ui->comboBoxBit->addItem("Четности"); // Добавляем в список доступных
|
||||
ui->comboBoxBit->addItem("Нечетности"); // Добавляем в список доступных
|
||||
|
||||
// значения для полей из сохраненных значений
|
||||
ui->comboBoxPort->setCurrentIndex(parent->portComboboxIndex);
|
||||
ui->comboBoxPort->setDisabled(1);
|
||||
ui->comboBoxSpeed->setCurrentIndex(conf->value("section2/keyCurrentSpeed").toInt());
|
||||
ui->comboBoxBit->setCurrentIndex(conf->value("section2/keyCurrentBit").toInt());
|
||||
ui->lineEditAddr->setText(conf->value("section2/keyAdress").toString());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
SecondWindows::~SecondWindows()
|
||||
{ qDebug()<<"сработал деструктор второго окна";
|
||||
|
||||
conf->setValue("section2/keyCurrentSpeed", ui->comboBoxSpeed->currentIndex());
|
||||
conf->setValue("section2/keyCurrentBit", ui->comboBoxBit->currentIndex());
|
||||
conf->setValue("section2/keyAdress", ui->lineEditAddr->text());
|
||||
modebus->removeFromReqList(adrPri);
|
||||
delete ui;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SecondWindows::dataSetter(DataStruct data)
|
||||
{
|
||||
if(adrPri==data.adress){
|
||||
state=data;
|
||||
refreshDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//todo: заблокировать элементы управления без подключения
|
||||
void SecondWindows::on_pushButtonConnect_clicked()
|
||||
{
|
||||
|
||||
adrPri=ui->lineEditAddr->text().toInt(); //todo:добавить валидатор для адреса
|
||||
if(isConnected==false){
|
||||
|
||||
|
||||
PrborConnectonAtr thisPribor;
|
||||
thisPribor.port=ui->comboBoxPort->currentText();
|
||||
thisPribor.adress=ui->lineEditAddr->text().toInt();
|
||||
thisPribor.speed=(ui->comboBoxSpeed->currentText().toInt());
|
||||
thisPribor.parity=(Parity)ui->comboBoxBit->currentIndex();
|
||||
|
||||
modebus->addToReqList(thisPribor); //добавляем прибор в список опрашиваемых
|
||||
|
||||
|
||||
ui->pushButtonConnect->setText("Отключение");
|
||||
//блокируем элементы
|
||||
ui->lineEditAddr->setDisabled(true);
|
||||
ui->comboBoxPort->setDisabled(true);
|
||||
ui->comboBoxBit->setDisabled(true);
|
||||
ui->comboBoxSpeed->setDisabled(true);
|
||||
isConnected=true;
|
||||
}
|
||||
else if(isConnected==true){
|
||||
modebus->removeFromReqList(adrPri);
|
||||
|
||||
//удаляем прибор с данным адресом из списка
|
||||
|
||||
//опустошаем форму
|
||||
ui->labelKu->setText("XXXXX");
|
||||
ui->labelNch->setText("XX");
|
||||
ui->labelVch->setText("XX");
|
||||
ui->labelSens->setText("XXXXX");
|
||||
ui->labelPlavGround->setText("XX");
|
||||
ui->labelUnitSens->setText("XXXXXX");
|
||||
|
||||
//разблокируем элементы
|
||||
ui->lineEditAddr->setDisabled(false);
|
||||
ui->comboBoxPort->setDisabled(false);
|
||||
ui->comboBoxBit->setDisabled(false);
|
||||
ui->comboBoxSpeed->setDisabled(false);
|
||||
ui->pushButtonConnect->setText("Подключение");
|
||||
|
||||
isConnected=false;
|
||||
}
|
||||
}
|
||||
|
||||
void SecondWindows::refreshDisplay(){
|
||||
|
||||
//делаем дополнение до 6 знаков
|
||||
if(state.sens==1000) { ui->labelSens->setText(QString::number(state.sens,'f', 1));}
|
||||
else if(state.sens<1000&&state.sens>=100) {ui->labelSens->setText(QString::number(state.sens,'f', 2));}
|
||||
else if(state.sens<100&&state.sens>=10){ui->labelSens->setText(QString::number(state.sens,'f', 3));}
|
||||
else {ui->labelSens->setText(QString::number(state.sens,'f', 4));}
|
||||
|
||||
//с автоподгонкой всё начинает прыгать. Я думаю всё прокатит если её применять поьлко по изменеию содержимого
|
||||
//ui->labelSens->adjustSize(); //подгоняем размер по содержимому
|
||||
|
||||
|
||||
|
||||
switch (state.fn) {
|
||||
case Lp100:
|
||||
ui->labelNch->setText("0.1");
|
||||
break;
|
||||
case Lp300:
|
||||
ui->labelNch->setText("0.3");
|
||||
break;
|
||||
case Lp1000:
|
||||
ui->labelNch->setText("1");
|
||||
break;
|
||||
case Lp3000:
|
||||
ui->labelNch->setText("3");
|
||||
break;
|
||||
case Lp10000:
|
||||
ui->labelNch->setText("10");
|
||||
break;
|
||||
case Lp30000:
|
||||
ui->labelNch->setText("30");
|
||||
break;
|
||||
case Lp100000:
|
||||
ui->labelNch->setText("100");
|
||||
break;
|
||||
default:
|
||||
ui->labelNch->setText("#####");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch (state.fv) {
|
||||
case Hp0_2 :
|
||||
ui->labelVch->setText("0.2");
|
||||
break;
|
||||
case Hp1:
|
||||
ui->labelVch->setText("1");
|
||||
break;
|
||||
case Hp2:
|
||||
ui->labelVch->setText("2");
|
||||
break;
|
||||
case Hp10:
|
||||
ui->labelVch->setText("10");
|
||||
break;
|
||||
default:
|
||||
ui->labelVch->setText("#####");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////
|
||||
///// вывод юнитов и нормирование///
|
||||
////////////////////////////////////
|
||||
|
||||
////Аналогично прибору считаем смещение по массиву значений
|
||||
///
|
||||
if (state.sens>=0.0001&&state.sens<0.001) {OffsetKuDisplay=0;} // такие значения не допустимы
|
||||
else if (state.sens>=0.001&&state.sens<0.01){OffsetKuDisplay=0;}
|
||||
else if (state.sens>=0.01&&state.sens<0.1){OffsetKuDisplay=3; }
|
||||
else if (state.sens>=0.1&&state.sens<1){OffsetKuDisplay=6;}
|
||||
else if (state.sens>=1&&state.sens<10){OffsetKuDisplay=9;}
|
||||
else if (state.sens>=10&&state.sens<100){OffsetKuDisplay=12;}
|
||||
else if (state.sens>=100&&state.sens<1000){OffsetKuDisplay=15;}
|
||||
else if (state.sens<=1000){OffsetKuDisplay=18;}
|
||||
|
||||
char * result = (char *)malloc(strlen(STRINGS_OUTUNITS[state.ku+OffsetKuDisplay]) + strlen(STRINGS_UNITS[state.unit]) + 1); // +1 for the null-terminator
|
||||
strcpy(result, STRINGS_OUTUNITS[state.ku+OffsetKuDisplay]);
|
||||
strcat(result, STRINGS_UNITS[state.unit]);
|
||||
|
||||
ui->labelKu->setText(result);
|
||||
ui->labelKu->adjustSize();
|
||||
free(result); /// освободил память
|
||||
|
||||
|
||||
|
||||
|
||||
switch (state.pz) { //todo тут нужно нормирование
|
||||
case 0 :
|
||||
ui->labelPlavGround->setText("ОЗ");
|
||||
break;
|
||||
case 1:
|
||||
ui->labelPlavGround->setText("ПЗ");
|
||||
break;
|
||||
default:
|
||||
ui->labelPlavGround->setText("#####");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
switch (state.unit) { //todo тут нужно нормирование
|
||||
case H :
|
||||
ui->labelUnitSens->setText("пКл/Н");
|
||||
// ui->labelUnitKu->setText("xВ/Н"); // Заменил на нормирование с прибора
|
||||
break;
|
||||
case PA:
|
||||
ui->labelUnitSens->setText("пКл/Па");
|
||||
// ui->labelUnitKu->setText("xВ/Па");
|
||||
break;
|
||||
case MS2:
|
||||
ui->labelUnitSens->setText("пКл/мс2");
|
||||
// ui->labelUnitKu->setText("xВ/мс2");
|
||||
break;
|
||||
default:
|
||||
ui->labelUnitSens->setText("#####");
|
||||
break;
|
||||
}
|
||||
//ui->labelUnitSens->adjustSize();
|
||||
|
||||
|
||||
switch (state.overload) { //todo тут нужно нормирование
|
||||
case Norm :
|
||||
ui->labelOverload->setText("");
|
||||
break;
|
||||
case Overload:
|
||||
ui->labelOverload->setText("ПЕРЕГРУЗКА");
|
||||
break;
|
||||
default:
|
||||
ui->labelOverload->setText("#####");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
void SecondWindows::on_labelKu_wheelDown()
|
||||
{ //смотрим на текущее состояние дел
|
||||
|
||||
state.ku=typeIKU((uint16_t)state.ku-1);
|
||||
modebus->writeDataToPribor(state);
|
||||
//writePalam(serial, adrPri, ku, newVal); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
|
||||
qDebug()<<"WheelDown";
|
||||
|
||||
}
|
||||
|
||||
void SecondWindows::on_labelKu_wheelUp()
|
||||
{
|
||||
state.ku=typeIKU((uint16_t)state.ku+1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
qDebug()<<"WheelUp";
|
||||
}
|
||||
|
||||
void SecondWindows::on_labelVch_wheelDown()
|
||||
{
|
||||
|
||||
state.fv=typeIFV((uint16_t)state.fv-1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
qDebug()<<"WheelUp";
|
||||
}
|
||||
|
||||
void SecondWindows::on_labelVch_wheelUp()
|
||||
{
|
||||
state.fv=typeIFV((uint16_t)state.fv+1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
qDebug()<<"WheelUp";
|
||||
}
|
||||
|
||||
void SecondWindows::on_labelNch_wheelDown()
|
||||
{
|
||||
|
||||
state.fn=typeIFN((uint16_t)state.fn-1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
void SecondWindows::on_labelNch_wheelUp()
|
||||
{
|
||||
state.fn=typeIFN((uint16_t)state.fn+1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
|
||||
void SecondWindows::on_labelPlavGround_wheelDown()
|
||||
{
|
||||
state.pz=typePlavGround((uint16_t)state.pz-1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
void SecondWindows::on_labelPlavGround_wheelUp()
|
||||
{
|
||||
state.pz=typePlavGround((uint16_t)state.pz+1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
void SecondWindows::on_labelUnitSens_wheelDown()
|
||||
{
|
||||
|
||||
state.unit=typeUnit((uint16_t)state.unit-1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
void SecondWindows::on_labelUnitSens_wheelUp()
|
||||
{
|
||||
state.unit=typeUnit((uint16_t)state.unit+1);
|
||||
modebus->writeDataToPribor(state); // и тут ему говорим - отправь на запись такое то значение КУ
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SecondWindows::on_labelSens_clicked()
|
||||
{
|
||||
bool ok;
|
||||
state.sens = QInputDialog::getDouble(this, tr("Введите значение"),
|
||||
tr("Введите значение чувствительности датчика"), state.sens, 0.001, 1000, 4, &ok,
|
||||
Qt::WindowFlags(), 1);
|
||||
|
||||
if (ok){modebus->writeDataToPribor(state);}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef SECONDWINDOWS_H
|
||||
#define SECONDWINDOWS_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <mainwindow.h>
|
||||
#include <modbushandler.h>
|
||||
#include <QSettings>
|
||||
|
||||
namespace Ui {
|
||||
class SecondWindows;
|
||||
}
|
||||
|
||||
|
||||
class ModBusHandler;
|
||||
class MainWindow; // бля обязательно надо обявить классы
|
||||
|
||||
class SecondWindows : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SecondWindows(MainWindow *parent = nullptr);
|
||||
~SecondWindows();
|
||||
|
||||
QSettings *conf;
|
||||
|
||||
public slots:
|
||||
void on_pushButtonConnect_clicked();
|
||||
|
||||
void dataSetter(DataStruct data);
|
||||
private slots:
|
||||
void on_labelKu_wheelDown();
|
||||
void on_labelKu_wheelUp();
|
||||
void on_labelVch_wheelDown();
|
||||
void on_labelVch_wheelUp();
|
||||
void on_labelNch_wheelDown();
|
||||
void on_labelNch_wheelUp();
|
||||
void on_labelPlavGround_wheelDown();
|
||||
void on_labelPlavGround_wheelUp();
|
||||
void on_labelUnitSens_wheelDown();
|
||||
void on_labelUnitSens_wheelUp();
|
||||
void on_labelSens_clicked();
|
||||
private:
|
||||
Ui::SecondWindows *ui;
|
||||
ModBusHandler *modebus;
|
||||
bool isConnected;
|
||||
int OffsetKuDisplay;
|
||||
DataStruct state;
|
||||
|
||||
uint16_t adrPri;
|
||||
|
||||
void refreshDisplay();
|
||||
};
|
||||
|
||||
#endif // SECONDWINDOWS_H
|
File diff suppressed because it is too large
Load Diff
123
setpribor.cpp
123
setpribor.cpp
|
@ -1,14 +1,133 @@
|
|||
#include "setpribor.h"
|
||||
#include "ui_setpribor.h"
|
||||
|
||||
setPribor::setPribor(QWidget *parent) :
|
||||
SetPribor::SetPribor(MainWindow *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::setPribor)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
parentUi=parent->ui;
|
||||
QWidget::setWindowTitle("Поиск и настройка");
|
||||
|
||||
qDebug()<<parent->comList;
|
||||
this->parent = parent;
|
||||
|
||||
|
||||
|
||||
// Перечислим порты в консоль
|
||||
foreach(const auto com, parent->comList){ //для каждого доступного порта
|
||||
ui->comboBoxPort->addItem(com); // Добавляем в список доступных
|
||||
}//конец foreach
|
||||
|
||||
extern const uint32_t BAUDRATE[];
|
||||
for(uint i = 0; i<10; i++){ui->comboBoxCurrentSpeed->addItem(QString::number(BAUDRATE[i]));
|
||||
ui->comboBoxNewSpeed->addItem(QString::number(BAUDRATE[i]));
|
||||
}
|
||||
|
||||
|
||||
//формирую данные для комбобокса бита четности
|
||||
ui->comboBoxCurrentBit->addItem("Нет"); // Добавляем в список доступных
|
||||
ui->comboBoxCurrentBit->addItem("Четности"); // Добавляем в список доступных
|
||||
ui->comboBoxCurrentBit->addItem("Нечетности"); // Добавляем в список доступных
|
||||
ui->comboBoxNewBit->addItem("Нет"); // Добавляем в список доступных
|
||||
ui->comboBoxNewBit->addItem("Четности"); // Добавляем в список доступных
|
||||
ui->comboBoxNewBit->addItem("Нечетности"); // Добавляем в список доступных
|
||||
|
||||
|
||||
ui->progressBar->setValue(0);
|
||||
ui->progressBar->setRange(0, 7410);
|
||||
|
||||
ui->comboBoxPort->setCurrentIndex(parent->portComboboxIndex);
|
||||
|
||||
ui->lineEditNewAdr->setText(parent->adrValue);
|
||||
ui->lineEditCurrentAdr->setText(parent->adrValue);
|
||||
|
||||
ui->comboBoxCurrentSpeed->setCurrentIndex(parent->speedComboboxIndex);
|
||||
ui->comboBoxNewSpeed->setCurrentIndex(parent->speedComboboxIndex);
|
||||
ui->comboBoxCurrentBit->setCurrentIndex(parent->bitComboboxIndex);
|
||||
ui->comboBoxNewBit->setCurrentIndex(parent->bitComboboxIndex);
|
||||
|
||||
|
||||
}
|
||||
|
||||
setPribor::~setPribor()
|
||||
SetPribor::~SetPribor()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void SetPribor::on_pushButtonSetParam_clicked()
|
||||
{
|
||||
PrborConnectonAtr oldAtr;
|
||||
oldAtr.port=ui->comboBoxPort->currentText();
|
||||
oldAtr.speed=ui->comboBoxCurrentSpeed->currentText().toInt();
|
||||
oldAtr.adress=ui->lineEditCurrentAdr->text().toInt();
|
||||
oldAtr.parity=(Parity)ui->comboBoxCurrentBit->currentIndex();
|
||||
|
||||
PrborConnectonAtr newAtr;
|
||||
newAtr.speed= ui->comboBoxNewSpeed->currentText().toInt();
|
||||
newAtr.adress=ui->lineEditNewAdr->text().toInt();
|
||||
newAtr.parity=(Parity)ui->comboBoxNewBit->currentIndex();
|
||||
connect(parent->modebus, SIGNAL(writeResult(QModbusDevice::Error)), this, SLOT(priborIsSetConnAtr(QModbusDevice::Error)));
|
||||
|
||||
parent->modebus->writeConnectionAttr(oldAtr,newAtr);
|
||||
|
||||
}
|
||||
|
||||
void SetPribor::on_pushButtonDetectAuto_clicked()
|
||||
{
|
||||
|
||||
ui->progressBar->setValue(0);
|
||||
ui->labelFound->setText("Поиск..."); //выводим надпись
|
||||
|
||||
|
||||
// делаем коннект к сигналу найденого
|
||||
//делаем коннект к сигналу не найденого
|
||||
parent->modebus->scanPort(ui->comboBoxPort->currentText());
|
||||
connect(parent->modebus, SIGNAL(priborFounded(uint,uint,uint)),
|
||||
this, SLOT(getFoundedPribor(uint, uint,uint)));//коннект для найденого прибора
|
||||
|
||||
connect(parent->modebus, SIGNAL(priborNotFounded()),
|
||||
this, SLOT(priborNotFounded()));//коннект для не найденого прибора
|
||||
|
||||
|
||||
connect(parent->modebus, SIGNAL(progressUpToStatusBar(uint)), //todo: дисконнекту быть
|
||||
this, SLOT(getProgressBar(uint))); //сделать коннект для полосы
|
||||
|
||||
}
|
||||
|
||||
void SetPribor::getFoundedPribor(uint a, uint s, uint b)
|
||||
{
|
||||
ui->lineEditCurrentAdr->setText(QString::number(a)); //если верная то заполняем поля
|
||||
ui->comboBoxCurrentSpeed->setCurrentIndex(s-1);//из за особенности поиска
|
||||
ui->comboBoxCurrentBit->setCurrentIndex(b);
|
||||
ui->labelFound->setText("Найден!!"); //выводим радость
|
||||
ui->progressBar->setValue(7410);
|
||||
QApplication::beep();
|
||||
}
|
||||
|
||||
void SetPribor::priborNotFounded()
|
||||
{
|
||||
ui->labelFound->setText("Не найден!!");
|
||||
QApplication::beep();
|
||||
}
|
||||
|
||||
void SetPribor::priborIsSetConnAtr(QModbusDevice::Error modbusMessage)
|
||||
{
|
||||
if(modbusMessage== QModbusDevice::ProtocolError) {
|
||||
ui->labelResult->setText("Ошибка протокола"); //выводим радость
|
||||
} else if(modbusMessage == QModbusDevice::TimeoutError) {
|
||||
ui->labelResult->setText("Таймаут"); //
|
||||
} else if (modbusMessage != QModbusDevice::NoError) {
|
||||
ui->labelResult->setText("Ошибочка"); //
|
||||
} else if(modbusMessage == QModbusDevice::NoError) {
|
||||
ui->labelResult->setText("Успшно настроен"); //
|
||||
}
|
||||
|
||||
QApplication::beep();
|
||||
}
|
||||
|
||||
void SetPribor::getProgressBar(uint a)
|
||||
{
|
||||
ui->progressBar->setValue(ui->progressBar->value()+a);
|
||||
|
||||
}
|
||||
|
|
27
setpribor.h
27
setpribor.h
|
@ -2,21 +2,42 @@
|
|||
#define SETPRIBOR_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QtSerialPort/QSerialPort>
|
||||
#include <QtSerialPort/QSerialPortInfo>
|
||||
#include "QDebug"
|
||||
#include "mainwindow.h"
|
||||
#include "comWorks.h"
|
||||
#include <QModbusRtuSerialMaster> // чтоб знал ошибки модбаса
|
||||
|
||||
namespace Ui {
|
||||
class setPribor;
|
||||
}
|
||||
|
||||
class setPribor : public QDialog
|
||||
class SetPribor : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit setPribor(QWidget *parent = nullptr);
|
||||
~setPribor();
|
||||
explicit SetPribor(MainWindow *parent = nullptr);
|
||||
~SetPribor();
|
||||
|
||||
private slots:
|
||||
void on_pushButtonSetParam_clicked();
|
||||
|
||||
void on_pushButtonDetectAuto_clicked();
|
||||
|
||||
public slots:
|
||||
void getFoundedPribor(uint a, uint s,uint b);
|
||||
void priborNotFounded();
|
||||
void priborIsSetConnAtr(QModbusDevice::Error); // прибор принял новые атрибуты соединения???
|
||||
void getProgressBar(uint a);
|
||||
|
||||
private:
|
||||
|
||||
MainWindow *parent;
|
||||
Ui::MainWindow *parentUi;
|
||||
Ui::setPribor *ui;
|
||||
|
||||
};
|
||||
|
||||
#endif // SETPRIBOR_H
|
||||
|
|
309
setpribor.ui
309
setpribor.ui
|
@ -1,7 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<author/>
|
||||
<comment/>
|
||||
<exportmacro/>
|
||||
<class>setPribor</class>
|
||||
<widget class="QDialog" name="setPribor">
|
||||
<property name="geometry">
|
||||
|
@ -9,63 +7,282 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
<height>375</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>290</x>
|
||||
<y>20</y>
|
||||
<width>81</width>
|
||||
<height>241</height>
|
||||
<x>20</x>
|
||||
<y>10</y>
|
||||
<width>361</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Данный режим предназначен для начальной инициализации прибора. </string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>30</y>
|
||||
<width>361</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Убедитесь что к шине подключен только один прибор</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="comboBoxCurrentSpeed">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>180</y>
|
||||
<width>69</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="comboBoxCurrentBit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>220</y>
|
||||
<width>69</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="lineEditCurrentAdr">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>140</y>
|
||||
<width>51</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="comboBoxNewSpeed">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>240</x>
|
||||
<y>180</y>
|
||||
<width>69</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="comboBoxNewBit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>240</x>
|
||||
<y>220</y>
|
||||
<width>69</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="lineEditNewAdr">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>240</x>
|
||||
<y>140</y>
|
||||
<width>51</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButtonSetParam">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>240</x>
|
||||
<y>260</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Присвоить</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>143</y>
|
||||
<width>47</width>
|
||||
<height>13</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Адрес</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>185</y>
|
||||
<width>47</width>
|
||||
<height>13</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Скорость</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>6</x>
|
||||
<y>220</y>
|
||||
<width>71</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Бит четности</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>80</x>
|
||||
<y>120</y>
|
||||
<width>111</width>
|
||||
<height>231</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Текущий</string>
|
||||
</property>
|
||||
<widget class="QPushButton" name="pushButtonDetectAuto">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>130</y>
|
||||
<width>91</width>
|
||||
<height>51</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Определить
|
||||
автоматически</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="labelFound">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>6</x>
|
||||
<y>190</y>
|
||||
<width>101</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>230</x>
|
||||
<y>120</y>
|
||||
<width>111</width>
|
||||
<height>231</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Новый</string>
|
||||
</property>
|
||||
<widget class="QLabel" name="labelResult">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>170</y>
|
||||
<width>91</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>362</x>
|
||||
<y>75</y>
|
||||
<width>20</width>
|
||||
<height>251</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="comboBoxPort">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>70</y>
|
||||
<width>69</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>70</y>
|
||||
<width>47</width>
|
||||
<height>13</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Порт</string>
|
||||
</property>
|
||||
</widget>
|
||||
<zorder>groupBox_2</zorder>
|
||||
<zorder>groupBox</zorder>
|
||||
<zorder>label</zorder>
|
||||
<zorder>label_2</zorder>
|
||||
<zorder>comboBoxCurrentSpeed</zorder>
|
||||
<zorder>comboBoxCurrentBit</zorder>
|
||||
<zorder>lineEditCurrentAdr</zorder>
|
||||
<zorder>comboBoxNewSpeed</zorder>
|
||||
<zorder>comboBoxNewBit</zorder>
|
||||
<zorder>lineEditNewAdr</zorder>
|
||||
<zorder>pushButtonSetParam</zorder>
|
||||
<zorder>label_3</zorder>
|
||||
<zorder>label_4</zorder>
|
||||
<zorder>label_5</zorder>
|
||||
<zorder>progressBar</zorder>
|
||||
<zorder>comboBoxPort</zorder>
|
||||
<zorder>label_6</zorder>
|
||||
</widget>
|
||||
<pixmapfunction/>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>setPribor</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>setPribor</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
Loading…
Reference in New Issue