| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- #include "serialworker.h"
- #include "QDebug"
- #include <QCoreApplication>
- #include <QDateTime>
- #include <QElapsedTimer>
- #include <QtMath>
- #include <QSerialPortInfo>
- #include <QTimer>
- #include <QRegularExpression>
- #include <QSettings>
- //#define FRAME_LEN 66
- #define CHANNEL_COUNT 24
- #define MAX_STEP 10
- SerialWorker::SerialWorker(QObject *parent) : QObject(parent)
- {
- m_pid.resize(4);
- preTimer = new QTimer(this);
- connect(preTimer,&QTimer::timeout,this,[=](){
- m_portCPLD->write("A55A020405000000000000000004280000009E0C");
- m_portCPLD->flush();
- for(int fan = 0; fan < 24; fan++)
- {
- txFrame[16 + fan] = (uint8_t)100;
- }
- for(int fan = 0; fan < 4; fan++)
- {
- txFrame[40 + fan] = (uint8_t)10;
- }
- sendSnapshot();
- });
- pidTimer = new QTimer(this);
- connect(pidTimer,&QTimer::timeout,this,[=](){
- m_portBMC->write("ipmitool raw 0x36 0x6c 0xdf 0xdd 0x00 0x03\r");
- m_portBMC->flush();
- });
- }
- SerialWorker::~SerialWorker()
- {
- if(m_portBMC && m_portBMC->isOpen())
- {
- m_portBMC->close();
- }
- if(m_portCPLD && m_portCPLD->isOpen())
- {
- m_portCPLD->close();
- }
- }
- void SerialWorker::openBMCSerial(const QString &portname)
- {
- m_portBMC = new QSerialPort(this);
- m_portBMC->setPortName(portname);
- m_portBMC->setBaudRate(115200);
- m_portBMC->setDataBits(QSerialPort::Data8);
- m_portBMC->setParity(QSerialPort::NoParity);
- m_portBMC->setStopBits(QSerialPort::OneStop);
- m_portBMC->setFlowControl(QSerialPort::NoFlowControl);
- if(!m_portBMC->open(QIODevice::ReadWrite))
- {
- qDebug()<<"bmc串口打开失败";
- return;
- }
- else
- {
- connect(m_portBMC,&QSerialPort::readyRead,this,&SerialWorker::onReadyReadBMC);
- qDebug()<<"bmc串口打开成功";
- }
- }
- void SerialWorker::openCPLDSerial(const QString &portname)
- {
- m_portCPLD = new QSerialPort(this);
- m_portCPLD->setPortName(portname);
- m_portCPLD->setBaudRate(921600);
- m_portCPLD->setDataBits(QSerialPort::Data8);
- m_portCPLD->setParity(QSerialPort::NoParity);
- m_portCPLD->setStopBits(QSerialPort::OneStop);
- m_portCPLD->setFlowControl(QSerialPort::NoFlowControl);
- if(!m_portCPLD->open(QIODevice::ReadWrite))
- {
- qDebug()<<"cpld串口打开失败";
- return;
- }
- else
- {
- initFrame();
- connect(m_portCPLD,&QSerialPort::readyRead,this,&SerialWorker::onReadyReadCPLD);
- qDebug()<<"cpld串口打开成功";
- }
- }
- uint16_t SerialWorker::crc16(const uint8_t *data, uint16_t len)
- {
- uint16_t crc = 0xFFFF;
- for(uint16_t i = 0; i < len; i++)
- {
- crc ^= ((uint16_t)data[i] << 8);
- for(uint8_t j = 0; j < 8; j++)
- {
- if(crc & 0x8000)
- {
- crc = (crc << 1) ^ 0x1021;
- }
- else
- {
- crc <<= 1;
- }
- }
- }
- return crc;
- }
- void SerialWorker::initFrame()
- {
- memset(txFrame, 0, sizeof(txFrame));
- txFrame[0] = 0xA5;
- txFrame[1] = 0x5A;
- txFrame[2] = 0x02;
- txFrame[3] = 0x04;
- txFrame[4] = 0x07;
- txFrame[5] = 0x00;
- txFrame[6] = 0x00;
- txFrame[7] = 0x00;
- txFrame[8] = 0x00;
- txFrame[9] = 0x00;
- txFrame[10] = 0x00;
- txFrame[11] = 0x00;
- txFrame[12] = 0x00;
- txFrame[13] = 0x22;
- txFrame[14] = 0x2A;
- txFrame[15] = 0x00;
- txFrame[44] = 0x00;
- txFrame[45] = 0x00;
- txFrame[46] = 0x00;
- txFrame[47] = 0x00;
- }
- void SerialWorker::onStartTest(int index)
- {
- if(!m_portBMC)
- return;
- m_tempIndex = index;
- preTimer->start(500);
- // m_portBMC->write("stty -echo\r");
- // m_portBMC->flush();
- // QTimer::singleShot(200, this, [=]() {
- // pidTimer->start(500);
- // });
- }
- void SerialWorker::onReadyReadBMC()
- {
- m_buffer += m_portBMC->readAll();
- QString text = QString::fromUtf8(m_buffer);
- QRegularExpression re("root@[^#]*#");
- QRegularExpressionMatch match = re.match(text);
- if (!match.hasMatch())
- return;
- // 前面的HEX字符串
- QString hex = text.left(match.capturedStart());
- // 删除已经处理的数据
- m_buffer.remove(0, match.capturedEnd());
- // 去掉所有空白
- hex.remove(QRegularExpression("\\s+"));
- // 转二进制
- QByteArray data = QByteArray::fromHex(hex.toLatin1());
- if(data.size() != 48)
- {
- return;
- }
- parsePIDData(data);
- }
- void SerialWorker::onReadyReadCPLD()
- {
- QByteArray data = m_portCPLD->readAll();
- // 一帧35字节
- if(data.size() < 35)
- return;
- // 帧头
- if((uint8_t)data[0] != 0xA5 ||
- (uint8_t)data[1] != 0x5A)
- {
- return;
- }
- // 固定字段
- if((uint8_t)data[2] != 0x02)
- return;
- if((uint8_t)data[3] != 0x04)
- return;
- if((uint8_t)data[4] != 0x10)
- return;
- if((uint8_t)data[5] != 0x1B)
- return;
- //-------------------------
- // CRC校验
- //-------------------------
- // 小端
- uint16_t recvCrc = ((uint8_t)data[34] << 8) | (uint8_t)data[33];
- // 计算2-32字节
- uint16_t calcCrc = crc16((uint8_t*)data.data()+2,31);
- if(recvCrc != calcCrc)
- {
- qDebug()<<"CRC错误";
- return;
- }
- //-------------------------
- // CRC正确,解析温度
- //-------------------------
- int temp[27];
- for(int i=0;i<27;i++)
- {
- temp[i] = (uint8_t)data[6+i];
- }
- qDebug()<<"第1路温度:" <<temp[0];
- }
- void SerialWorker::parsePIDData(const QByteArray &data)
- {
- QVector<double> temps;
- temps.reserve(CHANNEL_COUNT);
- for(int i = 0; i < CHANNEL_COUNT; ++i)
- {
- quint8 intPart = static_cast<quint8>(data[i * 2]);
- //quint8 decPart = static_cast<quint8>(data[i * 2 + 1]);
- if(intPart == 0xFF /*&& decPart == 0xFF*/)
- {
- temps.append(qQNaN());
- }
- else
- {
- temps.append(intPart/* + decPart / 100.0*/);
- }
- }
- qDebug()<<"temps"<<temps;
- emit signalNewTemps(temps); //发送给数据给主界面绘制
- if(m_tempIndex == 0)
- {
- controlHeat40(temps); //控温核心代码
- }
- else if(m_tempIndex == 1)
- {
- controlHeat(temps); //控温核心代码
- }
- }
- void SerialWorker::controlHeat(const QVector<double> &temps)
- {
- double target = 70.0;
- //double target = 40.0;
- double sumTemp = 0;
- int count = 0;
- for(int i = 0; i < 6; i++)
- {
- double temp = temps[i];
- if(qIsNaN(temp))
- continue;
- sumTemp += temp;
- count++;
- }
- double fanDuty = 0;
- double duty = 0;
- double avgTemp = 0.0;
- if(count > 0)
- {
- avgTemp = sumTemp / count;
- // 第一组计算风扇
- fanDuty = m_pid[0].calculateFanDuty(avgTemp);
- //fanDuty = m_pid[0].calculateFanDuty1(avgTemp);
- // PID计算加热
- duty = m_pid[0].calculate(target, avgTemp);
- }
- if(avgTemp >= 63)
- {
- sendUpCmd();
- }
- else
- {
- sendDownCmd();
- }
- for(int fan = 0; fan < 24; fan++)
- {
- txFrame[16 + fan] = (uint8_t)duty;
- }
- for(int fan = 0; fan < 4; fan++)
- {
- txFrame[40 + fan] = (uint8_t)fanDuty;
- }
- sendSnapshot();
- }
- void SerialWorker::controlHeat40(const QVector<double> &temps)
- {
- double sumTemp = 0;
- int count = 0;
- for(int i = 0; i < 6; i++)
- {
- double temp = temps[i];
- if(qIsNaN(temp))
- continue;
- sumTemp += temp;
- count++;
- }
- double fanDuty = 0;
- double duty = 0;
- double avgTemp = 0.0;
- if(count > 0)
- {
- avgTemp = sumTemp / count;
- // 第一组计算风扇
- fanDuty = m_pid[0].calculateFanDuty1(avgTemp);
- }
- if(avgTemp >= 30)
- {
- sendUpCmd();
- }
- else
- {
- sendDownCmd();
- }
- for(int fan = 0; fan < 24; fan++)
- {
- txFrame[16 + fan] = (uint8_t)duty;
- }
- for(int fan = 0; fan < 4; fan++)
- {
- txFrame[40 + fan] = (uint8_t)fanDuty;
- }
- sendSnapshot();
- }
- void SerialWorker::sendSnapshot()
- {
- uint16_t crc = crc16(txFrame + 2,46);
- txFrame[48] = crc & 0xff;
- txFrame[49] = (crc >> 8)&0xff;
- QByteArray frame((char*)txFrame,50);
- qDebug()<<frame.toHex(' ');
- m_portCPLD->write(frame);
- m_portCPLD->flush();
- }
- void SerialWorker::sendDownCmd()
- {
- if (m_position <= 0)
- return; // 已经到底了
- QByteArray dataX = QByteArray::fromHex(
- "A55A02041100000000000000000835000103C20100001C32"
- );
- QByteArray dataY = QByteArray::fromHex(
- "A55A02041100000000000000000835010103C20100007D8A"
- );
- m_portCPLD->write(dataX);
- m_portCPLD->write(dataY);
- m_portCPLD->flush();
- --m_position;
- }
- void SerialWorker::sendUpCmd()
- {
- if (m_position >= MAX_STEP)
- return; // 已经到顶了
- QByteArray dataX = QByteArray::fromHex(
- "A55A02041100000000000000000835000003C2010000BC77"
- );
- QByteArray dataY = QByteArray::fromHex(
- "A55A02041100000000000000000835010003C2010000DDCF"
- );
- m_portCPLD->write(dataX);
- m_portCPLD->write(dataY);
- m_portCPLD->flush();
- ++m_position;
- }
|