| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- #include "serialworker.h"
- #include "QDebug"
- #include <QCoreApplication>
- #include <QDateTime>
- #include <QElapsedTimer>
- #include <QtMath>
- #include <QSerialPortInfo>
- #include <QTimer>
- #include <QRegularExpression>
- #include <QSettings>
- #include <QThread>
- #define CHANNEL_COUNT 24
- #define MAX_STEP 10
- SerialWorker::SerialWorker(QObject *parent) : QObject(parent)
- {
- }
- SerialWorker::~SerialWorker()
- {
- if(m_portBMC && m_portBMC->isOpen())
- {
- m_portBMC->close();
- }
- if(m_portCPLD && m_portCPLD->isOpen())
- {
- m_portCPLD->close();
- }
- }
- void SerialWorker::initFrame()
- {
- memset(txFrame, 0, sizeof(txFrame));
- txFrame[0] = 0xA5;
- txFrame[1] = 0x5A;
- txFrame[2] = 0x01;
- txFrame[3] = 0x0B;
- txFrame[5] = 0x00;
- txFrame[6] = 0x00;
- txFrame[7] = 0x00;
- txFrame[9] = 0x00;
- txFrame[10] = 0x00;
- txFrame[11] = 0x00;
- }
- void SerialWorker::start()
- {
- m_pid.resize(4);
- initFrame();
- preTimer = new QTimer(this);
- static int stime = 0;
- connect(preTimer,&QTimer::timeout,this,[=](){
- stime++;
- qDebug()<<"stime = "<<stime;
- QByteArray data = QByteArray::fromHex(
- "A55A02006D7B"
- );
- m_portCPLD->write(data);
- m_portCPLD->flush();
- });
- pidTimer = new QTimer(this);
- connect(pidTimer,&QTimer::timeout,this,[=](){
- m_portBMC->write("ipmitool raw 0x36 0x6c 0xdf 0xdd 0x00 0x03\r");
- m_portBMC->flush();
- });
- }
- 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
- {
- m_portBMC->write("stty -echo\r");
- m_portBMC->flush();
- qDebug()<<"bmc串口打开成功";
- }
- }
- void SerialWorker::openCPLDSerial(const QString &portname)
- {
- m_portCPLD = new QSerialPort(this);
- m_portCPLD->setPortName(portname);
- m_portCPLD->setBaudRate(115200);
- 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
- {
- 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::onStartTest(int index)
- {
- m_tempIndex = index;
- preTimer->start(1000);
- }
- 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;
- }
- parseFrame(data);
- }
- void SerialWorker::onReadyReadCPLD()
- {
- m_cpldBuffer.append(m_portCPLD->readAll());
- while(m_cpldBuffer.size() >= 6)
- {
- // 查找帧头
- int index = m_cpldBuffer.indexOf(QByteArray::fromHex("A55A"));
- if(index < 0)
- {
- m_cpldBuffer.clear();
- return;
- }
- // 删除前面的垃圾数据
- if(index > 0)
- m_cpldBuffer.remove(0,index);
- // 至少需要 Header + Type + Length
- if(m_cpldBuffer.size() < 4)
- return;
- // 判断类型
- uint8_t type = (uint8_t)m_cpldBuffer[2];
- uint8_t len = (uint8_t)m_cpldBuffer[3];
- // 只处理温度帧
- if(type != 0x82)
- {
- m_cpldBuffer.remove(0,2);
- continue;
- }
- // 长度检查
- if(len != 0x1B)
- {
- qDebug()<<"长度错误";
- m_cpldBuffer.remove(0,2);
- continue;
- }
- // 完整帧长度
- int frameLen = 33;
- if(m_cpldBuffer.size() < frameLen)
- return;
- QByteArray data = m_cpldBuffer.left(frameLen);
- m_cpldBuffer.remove(0,frameLen);
- qDebug()<<"温度帧:" <<data.toHex(' ');
- //--------------------
- // CRC
- //--------------------
- // 小端
- uint16_t recvCrc = (uint8_t)data[31] | ((uint8_t)data[32]<<8);
- // CRC计算范围
- // Type + Length + Payload
- // 偏移2开始,共31字节
- uint16_t calcCrc = crc16( (uint8_t*)data.data()+2, 29);
- if(recvCrc != calcCrc)
- {
- qDebug()<<"CRC错误";
- continue;
- }
- int temp=(uint8_t)data[23];
- qDebug()<<"sensor温度:" <<temp;
- if(temp <= 50)
- {
- txFrame[8] = (uint8_t)40;
- }
- else
- {
- txFrame[8] = (uint8_t)20;
- }
- sendDownCmd();
- txFrame[4] = (uint8_t)100;
- sendSnapshot();
- if(temp >=40 && m_tempIndex==0)
- {
- preTimer->stop();
- QTimer::singleShot(200,this,[=](){
- connect(m_portBMC,&QSerialPort::readyRead,this,&SerialWorker::onReadyReadBMC);
- qDebug()<<"40°预加热结束";
- pidTimer->start(500);
- });
- }
- else if(temp>=70 && m_tempIndex==1)
- {
- preTimer->stop();
- QTimer::singleShot(200,this,[=](){
- connect(m_portBMC,&QSerialPort::readyRead,this,&SerialWorker::onReadyReadBMC);
- qDebug()<<"70°预加热结束";
- pidTimer->start(500);
- });
- }
- }
- }
- void SerialWorker::parseFrame(const QByteArray &frame)
- {
- QVector<double> temps;
- temps.reserve(CHANNEL_COUNT);
- for(int i = 0; i < CHANNEL_COUNT; ++i)
- {
- quint8 intPart = static_cast<quint8>(frame[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 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);
- // PID计算加热
- duty = m_pid[0].calculate(target, avgTemp);
- txFrame[4] = (uint8_t)duty;
- txFrame[8] = (uint8_t)fanDuty;
- qDebug()<<"avgTemp = "<<avgTemp<<"duty = "<<duty<<"fanDuty = "<<fanDuty;
- }
- if(avgTemp >= 70)
- {
- sendUpCmd();
- }
- else
- {
- sendDownCmd();
- }
- 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);
- txFrame[4] = (uint8_t)duty;
- txFrame[8] = (uint8_t)fanDuty;
- qDebug()<<"duty = "<<duty<<"fanDuty = "<<fanDuty;
- }
- if(avgTemp >= 30)
- {
- sendUpCmd();
- }
- else
- {
- sendDownCmd();
- }
- sendSnapshot();
- }
- void SerialWorker::sendSnapshot()
- {
- uint16_t crc = crc16(txFrame + 2, 13);
- // CRC小端
- txFrame[15] = crc & 0xff;
- txFrame[16] = (crc >> 8)&0xff;
- QByteArray frame((char*)txFrame,17);
- qDebug()<<frame.toHex(' ');
- m_portCPLD->write(frame);
- m_portCPLD->flush();
- }
- void SerialWorker::sendDownCmd()
- {
- if (m_position <= 0)
- {
- txFrame[12] = 0x00;
- txFrame[13] = 0x00;
- txFrame[14] = 0x00;
- return; // 已经到底了
- }
- txFrame[12] = 0x02;
- txFrame[13] = 0x02;
- txFrame[14] = 0x02;
- --m_position;
- }
- void SerialWorker::sendUpCmd()
- {
- if (m_position >= MAX_STEP)
- {
- txFrame[12] = 0x00;
- txFrame[13] = 0x00;
- txFrame[14] = 0x00;
- return; // 已经到顶了
- }
- txFrame[12] = 0x01;
- txFrame[13] = 0x01;
- txFrame[14] = 0x01;
- ++m_position;
- }
|