Files
airborne_CO2/Source/IrisSensor_Gas_P0.cpp
xin e7cd1e93a6 优化气体传感器数据解析和消息传递
- 使用union解析CO2/H2O数据,解决大小端问题
- 添加LINECOMMEND/LINEDATASHOW消息类型区分
- 添加WorkingState/SavingDate原子变量
- 修正气体传感器部分逻辑
2026-03-04 10:22:51 +08:00

364 lines
8.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "pch.h"
#include "IrisSensor_Gas_P0.h"
IrisSensor_Gas_P0::IrisSensor_Gas_P0()
{
m_pSerialPort = new QSerialPort;
m_iBaudRate = 115200;
}
IrisSensor_Gas_P0::~IrisSensor_Gas_P0()
{
delete m_pSerialPort;
}
int IrisSensor_Gas_P0::SendData_Chk(std::string sSend)
{
QByteArray qbaSend(sSend.c_str(), (int)sSend.length());
qint64 qi64Write = m_pSerialPort->write(qbaSend);
m_pSerialPort->waitForBytesWritten(200);
if (qi64Write != qbaSend.size())
{
qDebug() << "Err:Sensor_Gas write Failed.Exit Code:1" << qi64Write;
return qi64Write;
}
return 0;
}
int IrisSensor_Gas_P0::RecvData_Chk(/*std::string sRecv*/)
{
QByteArray qbData;
qbData.clear();
qbData = m_pSerialPort->readAll();
int iCounter = 0;
while (qbData.size() < 3)
{
m_pSerialPort->waitForReadyRead(100);
QByteArray qbTemp = m_pSerialPort->readAll();
qbData.append(qbTemp);
if (iCounter > 3)
{
qDebug() << "Err:Sensor_Gas RecvData Failed,Not Enough Data.Exit Code:1" << qbData.size();
return 1;
}
iCounter++;
}
iCounter = 0;
if (qbData[0]==(char)0x06)
{
int iLength = qbData[2] + 3 + 1;
while (qbData.size()< iLength)
{
m_pSerialPort->waitForReadyRead(100);
qbData.append(m_pSerialPort->readAll());
iCounter++;
if (iCounter > 3)
{
qDebug() << "Err:Sensor_Gas RecvData Failed,Incomplete Data.Exit Code:2" << qbData.size();
return 3;
}
//return 0;
}
}
else
{
qDebug() << "Err:Sensor_Gas RecvData wrong header.Exit Code:2" << qbData.size();
}
m_sRecv.clear();
m_sRecv.resize(qbData.size());
for (int i=0;i< qbData.size();i++)
{
m_sRecv[i] = (unsigned char)qbData[i];
}
//QString qstrTest = m_sRecv.c_str();
//QString qstrTemp;
// qstrTemp.resize((int)m_sRecv.size());
// for (int i = 0; i < m_sRecv.size(); i++)
// {
// qstrTemp[i] = m_sRecv[i];
// }
return 0;
}
union Union16 {
short s16; // 有符号短整型 (处理正负)
unsigned short u16; // 无符号短整型
unsigned char b[2]; // 字节数组
};
// 用于处理4字节32位数据
union Union32 {
int s32; // 有符号长整型
unsigned int u32; // 无符号长整型
unsigned char b[4]; // 字节数组
};
int IrisSensor_Gas_P0::ParseMeasuredData_Chk()
{
// 如果长度不匹配0x1f + 4 = 35
if (m_sRecv.size() != 35)
{
qDebug() << "Err:Sensor_Gas ParseData Failed, Incorrect Data Length. Exit Code:1";
return 1;
}
Union16 u16;
Union32 u32;
// 1. 解析温度 (Index 32, 33) - 假设是 short (16-bit)
// 大端转小端:高位 index[32] 放在 b[1],低位 index[33] 放在 b[0]
u16.b[1] = static_cast<unsigned char>(m_sRecv[32]);
u16.b[0] = static_cast<unsigned char>(m_sRecv[33]);
m_fTPTemperature = u16.s16 / 100.0f; // 直接使用 s16 即可自动处理正负
// 2. 解析 PB (Index 30, 31)
u16.b[1] = static_cast<unsigned char>(m_sRecv[30]);
u16.b[0] = static_cast<unsigned char>(m_sRecv[31]);
// 注意:你原代码里这里和下面都赋值给了 m_fPB是否其中一个是别的变量
float fPB_1 = u16.s16 / 10.0f;
// 3. 解析 PB (Index 28, 29)
u16.b[1] = static_cast<unsigned char>(m_sRecv[28]);
u16.b[0] = static_cast<unsigned char>(m_sRecv[29]);
m_fPB = u16.s16 / 10.0f;
// 4. 解析 CO2 (Index 16-19) - 32位
u32.b[3] = static_cast<unsigned char>(m_sRecv[16]);
u32.b[2] = static_cast<unsigned char>(m_sRecv[17]);
u32.b[1] = static_cast<unsigned char>(m_sRecv[18]);
u32.b[0] = static_cast<unsigned char>(m_sRecv[19]);
m_ulCO2 = u32.s32; // 如果 CO2 是正数s32 和 u32 一样如果有负数s32 会正确解释补码
// 5. 解析 H2O (Index 12-15) - 32位
u32.b[3] = static_cast<unsigned char>(m_sRecv[12]);
u32.b[2] = static_cast<unsigned char>(m_sRecv[13]);
u32.b[1] = static_cast<unsigned char>(m_sRecv[14]);
u32.b[0] = static_cast<unsigned char>(m_sRecv[15]);
m_ulH2O = u32.s32;
return 0;
}
// int IrisSensor_Gas_P0::ParseMeasuredData_Chk()
// {
// if (m_sRecv.size()!=0x1f+4)
// {
// qDebug() << "Err:Sensor_Gas ParseData Failed,Incorrect Data Length.Exit Code:1";
// return 1;
// }
// else
// {
// unsigned char uc12, uc13, uc14, uc15, uc16,uc17,uc18,uc19,uc28,uc29,uc30,uc31,uc32, uc33;
// char aaaa[34];
// memcpy(aaaa,m_sRecv.c_str(),m_sRecv.size());
//
// uc32 = m_sRecv[32];
// uc33 = m_sRecv[33];
// m_fTPTemperature = (uc32 * 256 + uc33) / 100;
//
// uc30 = m_sRecv[30];
// uc31 = m_sRecv[31];
// m_fPB = (uc30 * 256 + uc31) / 10;
//
// uc28 = m_sRecv[28];
// uc29 = m_sRecv[29];
// m_fPB = (uc28 * 256 + uc29) / 10;
//
// uc16 = m_sRecv[16];
// uc17 = m_sRecv[17];
// uc18 = m_sRecv[18];
// uc19 = m_sRecv[19];
// m_ulCO2 = uc16*256*256*256 + uc17*256*256 + uc18*256 + uc19;
//
// uc12 = m_sRecv[12];
// uc13 = m_sRecv[13];
// uc14 = m_sRecv[14];
// uc15 = m_sRecv[15];
// m_ulH2O = uc12 * 256 * 256 * 256 + uc13 * 256 * 256 + uc14 * 256 + uc15;
//
//
// return 0;
// }
//
// return 0;
// }
int IrisSensor_Gas_P0::Initialize(std::string ucPortNumber)
{
QString qstrPortName = QString::fromStdString(ucPortNumber);
m_pSerialPort->setPortName(qstrPortName);
m_pSerialPort->setReadBufferSize(512);
bool bRes = m_pSerialPort->setBaudRate(m_iBaudRate);
if (!bRes)
{
qDebug() << "Err:setBaudRate Failed.Exit Code:1";
return 1;
}
bRes = m_pSerialPort->open(QIODevice::ReadWrite);
if (!bRes)
{
qDebug() << "Err:open Failed.Exit Code:2";
return 2;
}
return 0;
}
int IrisSensor_Gas_P0::GetVersion()
{
QByteArray qbSend;
qbSend.append(0x02);
qbSend.append(0x01);
qbSend.append(0x09);
qbSend.append((unsigned char)0xf4);
SendData_Chk(qbSend.toStdString());
return 0;
}// 02 01 09 F4
int IrisSensor_Gas_P0::GetMeasuredData( double &ulCO2, double &ulH2O, float &fTPTemperature, float &fPP, float &fPB)
{
QByteArray qbSend;
qbSend.append(0x02);
qbSend.append(0x04);
qbSend.append(0x01);
qbSend.append(0x01);
qbSend.append(0x05);
qbSend.append((const char) 0x00);
qbSend.append((unsigned char)0xf3); //chksum
SendData_Chk(qbSend.toStdString());
RecvData_Chk();
ParseMeasuredData_Chk();
ulCO2 = m_ulCO2*1.0/10;
ulH2O = m_ulH2O*1.0/10;
fTPTemperature = m_fTPTemperature;
fPP = m_fPP;
fPB = m_fPB;
ulCO2=ulCO2<0?0:ulCO2;
ulH2O=ulH2O<0?0:ulH2O;
return 0;
}
int IrisSensor_Gas_P0::ZeroCalibration_N2()
{
QByteArray qbSend;
qbSend.append(0x02);
qbSend.append(0x02);
qbSend.append(0x02);
qbSend.append((const char) 0x00);
qbSend.append((unsigned char)0xfa); //chksum
SendData_Chk(qbSend.toStdString());
qDebug()<<"finish zero calirbation n2";
return 0;
}
int IrisSensor_Gas_P0::ZeroCalibration_Air()
{
QByteArray qbSend;
qbSend.append(0x02);
qbSend.append(0x02);
qbSend.append(0x02);
qbSend.append((const char) 0x01);
qbSend.append((unsigned char)0xf9); //chksum
SendData_Chk(qbSend.toStdString());
qDebug()<<"finish zero calirbation air";
return 0;
}
int IrisSensor_Gas_P0::SpanCalibration(char cChannel,unsigned int uiPPM)
{
qDebug()<<"start span calirbation"<< uiPPM<<" on channel "<<(int)cChannel;
unsigned char ucChksum=0x0;
QByteArray qbSend;
qbSend.append(0x02);
qbSend.append(0x06);
qbSend.append(0x03);
qbSend.append(cChannel);
unsigned char *pResult = new unsigned char[4];
pResult[0] = (unsigned char)((uiPPM >> 24) & 0xFF);
pResult[1] = (unsigned char)((uiPPM >> 16) & 0xFF);
pResult[2] = (unsigned char)((uiPPM >> 8) & 0xFF);
pResult[3] = (unsigned char)(uiPPM & 0xFF);
for (int i=0;i<4;i++)
{
qbSend.append(pResult[i]);
}
for (int i=0;i<qbSend.size();i++)
{
ucChksum += qbSend[i];
}
ucChksum = ~ucChksum + 1;
qbSend.append(ucChksum); //chksum
SendData_Chk(qbSend.toStdString());
delete[] pResult;
return 0;
}
int IrisSensor_Gas_P0::ResetCalibration(char cChannel)
{
unsigned char ucChksum = 0x0;
QByteArray qbSend;
qbSend.append(0x02);
qbSend.append(0x02);
qbSend.append(0x04);
qbSend.append(cChannel);
for (int i = 0; i < qbSend.size(); i++)
{
ucChksum += qbSend[i];
}
ucChksum = ~ucChksum + 1;
qbSend.append(ucChksum);
SendData_Chk(qbSend.toStdString());
return 0;
}
int IrisSensor_Gas_P0::StopAutoSending()
{
QByteArray qbSend;
qbSend.append(0x02);
qbSend.append(0x04);
qbSend.append(0x01);
qbSend.append((const char)0x00);
qbSend.append(0x05);
qbSend.append((const char)0x00);
qbSend.append((unsigned char)0xf4); //chksum
int iRes = SendData_Chk(qbSend.toStdString());
return 0;
}