目的:添加鉴知光谱仪的定标代码

1. zz的is11控制类 PerformAutoExposure没实现;
2. zz的GetExposureTime函数bug:iExposureTimeInMS = qbaRecv[0]*256+ qbaRecv[1]; → iExposureTimeInMS = qbaRecv[0]*256+ static_cast<unsigned char>(qbaRecv[1]);
3. zz代码(IS11_Ctrl_Qt.cpp)需要添加引用:#include <QDebug>,#include <QtEndian>;
This commit is contained in:
tangchao0503
2023-06-06 14:03:54 +08:00
parent 49e9ff6bc3
commit 6088c897b1
6 changed files with 1048 additions and 1 deletions

View File

@ -0,0 +1,130 @@
#pragma once
#include "IrisFiberSpectrometerBase.h"
#include <QtSerialPort/QSerialPort>
#include <QDebug>
#include <QtEndian>
#include "ZZ_Math.h"
#define CRC16_INIT 0xFFFF
#define CRC16_POLYNOMIAL 0xa001
const uint8_t GET_ADDRESS[] = {0x01,0x03,0x00,0x01,0x00,0x01};
const uint8_t GET_BANDRATE[] = {0x01,0x03,0x00,0x02,0x00,0x01};
const uint8_t GET_INTEGRAL_TIME[] = {0x01,0x03,0x00,0x06,0x00,0x01};
const uint8_t GET_AVERAGE_NUMBER[] = {0x01,0x03,0x00,0x07,0x00,0x01};
const uint8_t GET_WAVELENTH_AT_BAND[] = {0x01,0x03,0x00,0x10,0x00,0x02};
const uint8_t GET_VALUE_AT_BAND[] = {0x01,0x03,0x00,0x30,0x00,0x02};
const uint8_t GET_SETTING_OF_LAMP[] = {0x01,0x03,0x00,0x04,0x00,0x01};
const uint8_t GET_WAVELENTH_COEFF[] = {0x01,0x03,0x00,0x20,0x00,0x08};
const uint8_t GET_ALL_DN[] = {0x01,0x03,0x01,0x00,0x10,0x00};
const uint8_t GET_SERIAL_NUMBER[] = {0x01,0x03,0x00,0x40,0x00,0x00};
const uint8_t GET_PRODUCT_NAME[] = {0x01,0x03,0x00,0x50,0x00,0x00};
const uint8_t SET_ADDRESS[] = {0x01,0x06,0x00,0x01};
const uint8_t SET_BandRATE[] = {0x01,0x06,0x00,0x02};
const uint8_t SET_INTEGRAL_TIME[] = {0x01,0x06,0x00,0x06};
const uint8_t SET_AVERAGE_NUMBER[] = {0x01,0x06,0x00,0x07};
const uint8_t SET_WORK_MODE[] = {0x01,0x06,0x00,0x01};
const uint8_t SET_WAVELENTH_COEFF[] = {0x01,0x10,0x00,0x20,0x00,0x08,0x16};
class IS11_Ctrl_Qt :public CIrisFSBase
{
Q_OBJECT
public:
IS11_Ctrl_Qt(QObject* parent = nullptr);
virtual ~IS11_Ctrl_Qt();
public:
//do not call
//int ReInit();
//<2F><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD>
//int SetBaudRate(int iBaud);
//<2F><>ʼ<EFBFBD><CABC><EFBFBD>
int Initialize(bool bIsUSBMode, std::string ucPortNumber, std::string strDeviceName);
//<2F>ر<EFBFBD><D8B1>
void Close();
//<2F><><EFBFBD>β<EFBFBD><CEB2>Բɼ<D4B2> <20><><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//int SingleShot(int& iPixels);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݲɼ<DDB2>
int SingleShot(DataFrame& dfData);
//<2F><><EFBFBD>ΰ<EFBFBD><CEB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD>
//int SingleShotDark(ATPDataFrame &dfData);
//int SingleShotDeducted(ATPDataFrame &dfData);
//<2F><><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD>ʱ<EFBFBD><CAB1>
int SetExposureTime(int iExposureTimeInMS);
//<2F><>ȡ<EFBFBD>ع<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int GetExposureTime(int& iExposureTimeInMS);
//int GetWaveLength(float *pfWaveLength);
//<2F><>ȡ<EFBFBD><EFBFBD><E8B1B8>Ϣ
int GetDeviceInfo(DeviceInfo& Info);
//<2F><>ȡ<EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int GetDeviceAttribute(DeviceAttribute& Attr);
//int GetDeviceListInfo(); //use type name to enum
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int SetDeviceTemperature(float fTemperature);
//<2F><>ȡ<EFBFBD><EFBFBD>
int GetDeviceTemperature(float& fTemperature);
//<2F>Զ<EFBFBD><D4B6>ع<EFBFBD>
int PerformAutoExposure(float fMinScaleFactor, float fMaxScaleFactor, float& fPredictedExposureTime);
#ifdef _DEBUG
public:
#else //
private:
#endif
//port
int m_iBaudRate;
QSerialPort* m_pSerialPort;
//ATP
DeviceInfo m_diDeviceInfo;
DeviceAttribute m_daDeviceAttr;
//Attr
int m_iExposureTime;
#ifdef _DEBUG
public:
#else //
private:
#endif
//unsigned short crc16(const uint8_t *pbdata, size_t sz);
unsigned short CalCRC16(const uint8_t *pbData, size_t szLength);
void Conv_LTB(char * pcData, int iLength);
int Write_IS11(char * pcCMD, size_t szCMDLength);
int Read_IS11(QByteArray &qbaRecv);
int SendData_CMD03(char * pcCMD, size_t szCMDLength);
int RecvData_CMD03(QByteArray &qbaRecv);
int RecvData_CMD03(DataFrame& dfData);
//int RecvData_CMD03(float& fWavelength);
//int RecvData_CMD03(DeviceAttribute& Attr);
int SendData_CMD06(char *pcCMD, size_t szCMDLength, char *pcValue, size_t szValueLenth);
int RecvData_CMD06(QByteArray &qbaRecv);
int SendData_CMD10(char * pcCMD, size_t szCMDLength);
int RecvData_CMD10(QByteArray &qbaRecv);
int ParseHdr(QByteArray &qbaData,char cHdrType);
};

View File

@ -0,0 +1,56 @@
//
// Created by 73505 on 2023/5/7.
//
#pragma once
#include <qthread.h>
//#include <QFileDialog>
#include <QDateTime>
#include <iostream>
#include <fstream>
#include "IS11_Ctrl_Qt.h"
#include "FiberSpectrometerOperationBase.h"
class JinspFiberImager :public QObject,public FiberSpectrometerOperationBase
{
Q_OBJECT
public:
JinspFiberImager(bool bIsUSBMode, std::string ucPortNumber, std::string strDeviceName);
~JinspFiberImager();
IS11_Ctrl_Qt * m_FiberSpectrometer;
void connectFiberSpectrometer(QString& sn, QString& pixelCount, QString& wavelengthInfo);
void disconnectFiberSpectrometer();
void getDeviceAttribute(DeviceAttribute& deviceAttribute);
void getDeviceInfo(DeviceInfo& deviceInfo);
void setExposureTime(int iExposureTimeInMS);
void getExposureTime(int &iExposureTimeInMS);//ok
void getDeviceTemperature(float &fTemperature);//ok
void singleShot(DataFrame &dfData);
void getNonlinearityCoeffs(coeffsFrame &coeffs);
ZZ_S32 GetMaxValue(ZZ_S32 * dark, int number);
// DataFrame m_IntegratingSphereData;
// DataFrame m_DarkData;
protected:
private:
std::string mUcPortNumber;
// ZZ_U32 m_MaxValueOfFiberSpectrometer;
public slots:
void recordDark(QString path);
void recordTarget(int recordTimes, QString path);
void autoExpose();
signals:
void sendExposureTimeSignal(int exposureTime);
};

View File

@ -0,0 +1,578 @@
#include "Header_Files/IS11_Ctrl_Qt.h"
IS11_Ctrl_Qt::IS11_Ctrl_Qt(QObject* parent /*= nullptr*/)
{
m_pSerialPort = new QSerialPort;
m_iBaudRate = 921600;
}
IS11_Ctrl_Qt::~IS11_Ctrl_Qt()
{
delete m_pSerialPort;
}
int IS11_Ctrl_Qt::Initialize(bool bIsUSBMode, std::string ucPortNumber, std::string strDeviceName)
{
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";
//std::cout << "Err.setBaudRate Failed" << std::endl;
printf("Err:setBaudRate Failed.Exit Code:1");
return 1;
}
bRes = m_pSerialPort->open(QIODevice::ReadWrite);
if (!bRes)
{
//qDebug() << "Err:open Failed.Exit Code:2";
//std::cout << "Err.open Failed" << std::endl;
printf("Err:open Failed.Exit Code:2");
return 2;
}
// int testi;
// GetDeviceAttribute(m_daDeviceAttr);
// GetExposureTime(testi);
// SetExposureTime(10000);
// DataFrame test;
// SingleShot(test);
GetDeviceInfo(m_diDeviceInfo);
//GetExposureTime_Init();
std::string::size_type szPostion = m_diDeviceInfo.strSN.find(strDeviceName);
if (szPostion == std::string::npos)
{
printf("Err:FS serial number not match.Exit Code:3");
//qDebug() << "Err:FS serial number not match.Exit Code:3";
//return 3;
}
else
{
return 0;
}
return 0;
}
void IS11_Ctrl_Qt::Close()
{
}
int IS11_Ctrl_Qt::SingleShot(DataFrame& dfData)
{
SendData_CMD03((char*)GET_ALL_DN, sizeof(GET_ALL_DN));
RecvData_CMD03(dfData);
GetExposureTime(m_iExposureTime);
dfData.usExposureTimeInMS = (unsigned short)m_iExposureTime;
return 0;
}
int IS11_Ctrl_Qt::SetExposureTime(int iExposureTimeInMS)
{
QByteArray qbaRecv;
qbaRecv.clear();
unsigned char pucExposureTime[2];
pucExposureTime[0] = iExposureTimeInMS / 256;
pucExposureTime[1] = iExposureTimeInMS % 256;
SendData_CMD06((char *)SET_INTEGRAL_TIME, sizeof(SET_INTEGRAL_TIME), (char*)pucExposureTime, 2);
//SendData_CMD03((char *)GET_INTEGRAL_TIME, sizeof(GET_INTEGRAL_TIME));
int iRes = RecvData_CMD06(qbaRecv);
return iRes;
}
int IS11_Ctrl_Qt::GetExposureTime(int & iExposureTimeInMS)
{
QByteArray qbaRecv;
qbaRecv.clear();
SendData_CMD03((char *)GET_INTEGRAL_TIME, sizeof(GET_INTEGRAL_TIME));
int iRes = RecvData_CMD03(qbaRecv);
iExposureTimeInMS = qbaRecv[0]*256+ static_cast<unsigned char>(qbaRecv[1]);
return iRes;
}
int IS11_Ctrl_Qt::GetDeviceInfo(DeviceInfo & Info)
{
Info.strPN = "IS11";
Info.strSN = "NULL";
return 0;
}
int IS11_Ctrl_Qt::GetDeviceAttribute(DeviceAttribute & Attr)
{
QByteArray qbaRecv;
qbaRecv.clear();
float fCoef[4];
unsigned short usTempCoef[8];
Attr.iPixels = 2048;
Attr.iMinIntegrationTimeInMS = 1;
Attr.iMaxIntegrationTimeInMS = 60000;
SendData_CMD03((char *)GET_WAVELENTH_COEFF, sizeof(GET_WAVELENTH_COEFF));
RecvData_CMD03(qbaRecv);
//memcpy(fTempCoef,qbaRecv,16);
memcpy(usTempCoef, qbaRecv, 16);
for (int i=0;i<8;i++)
{
usTempCoef[i] = qToBigEndian(usTempCoef[i]);
}
//float *pfTemp = (float*)usTempCoef;
memcpy(fCoef, usTempCoef,16);
//Conv_LTB((char*)fTempCoef,16);
for (int i = 1; i <= 2048; i++)
{
Attr.fWaveLengthInNM[i - 1] = fCoef[0] * i*i*i + fCoef[1] * i*i + fCoef[2] * i + fCoef[3];
//setem.WavelenthStr = setem.WavelenthStr + String(setem.wavelenthlist[i - 1]).c_str() + ",";
}
return 0;
}
int IS11_Ctrl_Qt::SetDeviceTemperature(float fTemperature)
{
return 0;
}
int IS11_Ctrl_Qt::GetDeviceTemperature(float & fTemperature)
{
fTemperature = -1000;
return 0;
}
int IS11_Ctrl_Qt::PerformAutoExposure(float fMinScaleFactor, float fMaxScaleFactor, float & fPredictedExposureTime)
{
return 0;
}
// unsigned short IS11_Ctrl_Qt::crc16(const uint8_t *pbdata, size_t sz)
// {
// uint16_t i, j, tmp, CRC16;
//
// CRC16 = 0xFFFF; // CRC<52>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ʼֵ
// for (i = 0; i < sz; i++)
// {
// CRC16 ^= pbdata[i];
// for (j = 0; j < 8; j++)
// {
// tmp = (uint16_t)(CRC16 & 0x0001);
// CRC16 >>= 1;
// if (tmp == 1)
// {
// CRC16 ^= 0xa001; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
// }
// }
// }
// return CRC16;
// }
unsigned short IS11_Ctrl_Qt::CalCRC16(const uint8_t *pbData, size_t szLength)
{
uint16_t usCRC16 = CRC16_INIT;
for (size_t i = 0; i < szLength; i++)
{
usCRC16 ^= pbData[i];
for (size_t j = 0; j < 8; j++)
{
if ((usCRC16 & 0x0001) != 0)
{
usCRC16 = (usCRC16 >> 1) ^ CRC16_POLYNOMIAL;
}
else
{
usCRC16 = usCRC16 >> 1;
}
}
}
return usCRC16;
}
void IS11_Ctrl_Qt::Conv_LTB(char * pcData, int iLength)
{
char *TempData = new char[iLength];
memcpy(TempData, pcData, iLength);
for (int i = 0; i < iLength / 2; i++)
{
pcData[2 * i] = TempData[2 * i + 1];
pcData[2 * i + 1] = TempData[2 * i];
/* code */
}
delete[] TempData;
}
int IS11_Ctrl_Qt::SendData_CMD03(char * pcCMD, size_t szCMDLength)
{
QString qstrSend,qstrCRC16;
QByteArray qbaSend;
qbaSend.clear();
//char *pctest=new char[szCMDLength+2];
//memcpy(pctest, pcCMD, szCMDLength);
//ushort ustest = crc16((unsigned char*)pcCMD,szCMDLength);
//qstrCRC16= QString::fromLatin1((const char*)usCRC16, (int)sizeof(uint16_t));
//memcpy(pctest+ szCMDLength,&usCRC16, 2);
//int iReturn = m_pSerialPort->write(pctest,szCMDLength+2);
//delete[] pctest;
uint16_t usCRC16 = CalCRC16((unsigned char*)pcCMD, szCMDLength);
qstrSend = QString::fromLatin1((const char*)pcCMD, (int)szCMDLength);
const char * pucSend = (char *)&usCRC16;
qbaSend.append(qstrSend);
qbaSend.append(pucSend, (int)sizeof(uint16_t));
int iReturn = m_pSerialPort->write(qbaSend);
return iReturn;
}
int IS11_Ctrl_Qt::RecvData_CMD03(QByteArray &qbaRecv)
{
int iRetryCount = 0;
QByteArray qbaOriRecv,qbaTemp;
qbaOriRecv.clear();
qbaTemp.clear();
///read all once
Read_IS11(qbaTemp);
qbaOriRecv.append(qbaTemp);
while (qbaOriRecv.size() < 2 || ParseHdr(qbaOriRecv, 3) == 1)
{
m_pSerialPort->waitForReadyRead(1000);
Read_IS11(qbaTemp);
qbaOriRecv.append(qbaTemp);
iRetryCount++;
if (iRetryCount>100)
{
qDebug() << "Recv Hdr Err.out of retry time.RecvData_CMD03";
return 1;
}
}
iRetryCount = 0;
while (qbaOriRecv.size()< qbaOriRecv[2]+5)
{
m_pSerialPort->waitForReadyRead(1000);
Read_IS11(qbaTemp);
qbaOriRecv.append(qbaTemp);
iRetryCount++;
if (iRetryCount > 66)
{
qDebug() << "Recv Data Err.out of retry time";
return 2;
}
}
if (qbaOriRecv.size()!= qbaOriRecv[2] + 5)
{
/// can be handled but dont want to
qDebug() << "Wrong Recv data size.RecvData_CMD03_QBA";
return 3;
}
unsigned short usCRCC=CalCRC16((unsigned char *)qbaOriRecv.data(), qbaOriRecv.size()-2);
char *pc = (char *)&usCRCC;
if ((pc[0]== qbaOriRecv[qbaOriRecv.size()-1]&& pc[1]== qbaOriRecv[qbaOriRecv.size()-2])||
(pc[0] == qbaOriRecv[qbaOriRecv.size()-2] && pc[1] == qbaOriRecv[qbaOriRecv.size()-1]))
{
qbaRecv = qbaOriRecv.mid(3, qbaOriRecv.length() - 5);
}
else
{
///error crc
qDebug() << "Recv data crc16 Err."<<pc[1]<< pc[0];
return 4;
}
/*while (ParseHdr(qbaOriRecv, 3)==1)
{
m_pSerialPort->waitForReadyRead(100);
Read_IS11(qbaTemp);
qbaOriRecv.append(qbaTemp);
}*/
return 0;
}
int IS11_Ctrl_Qt::RecvData_CMD03(DataFrame& dfData)
{
int iRecvDataLength = 0;
int iRetryCount = 0;
QByteArray qbaOriRecv, qbaTemp;
qbaOriRecv.clear();
qbaTemp.clear();
///read all once
Read_IS11(qbaTemp);
qbaOriRecv.append(qbaTemp);
while (qbaOriRecv.size() < 4 || ParseHdr(qbaOriRecv, 3) == 1)
{
m_pSerialPort->waitForReadyRead(1000);
Read_IS11(qbaTemp);
qbaOriRecv.append(qbaTemp);
iRetryCount++;
if (iRetryCount > 66)
{
qDebug() << "Recv Hdr Err.out of retry time";
return 1;
}
}
int length = qbaOriRecv[2] * 256 + qbaOriRecv[3];
iRetryCount = 0;
while (qbaOriRecv.size() < length + 4)
{
m_pSerialPort->waitForReadyRead(1000);
Read_IS11(qbaTemp);
qbaOriRecv.append(qbaTemp);
iRetryCount++;
if (iRetryCount > 66)
{
qDebug() << "Recv Data Err.out of retry time";
return 2;
}
}
if (qbaOriRecv.size() != length + 4)
{
/// can be handled but dont want to
qDebug() << "Wrong Recv data size.RecvData_CMD03_DF";
return 3;
}
QByteArray qbaData;
qbaData = qbaOriRecv.right(length - 4);
int iDataSizeInPixel = qbaData.size() / 2;
unsigned short *pusData = new unsigned short[iDataSizeInPixel];
memcpy(pusData, qbaData, iDataSizeInPixel * 2);
for (size_t i = 0; i < iDataSizeInPixel; i++)
{
dfData.lData[i] = qToBigEndian(pusData[i]);
//qDebug() << dfData.lData[i];
}
///it seems the manufacture not enable crc16 check for this function
// unsigned short usCRCC = CalCRC16((unsigned char *)qbaOriRecv.data(), qbaOriRecv.size() - 2);
// char *pc = (char *)&usCRCC;
// if ((pc[0] == qbaOriRecv[qbaOriRecv.size() - 1] && pc[1] == qbaOriRecv[qbaOriRecv.size() - 2]) ||
// (pc[0] == qbaOriRecv[qbaOriRecv.size() - 2] && pc[1] == qbaOriRecv[qbaOriRecv.size() - 1]))
// {
// //qbaRecv = qbaOriRecv.mid(3, qbaOriRecv.length() - 5);
// //dataframe process here
//
// }
// else
// {
// ///error crc
// qDebug() << "Recv data crc16 Err." << pc[1] << pc[0];
// return 4;
// }
return 0;
}
//int IS11_Ctrl_Qt::RecvData_CMD03(float& fWavelength)
//{
// int iRetryCount = 0;
// QByteArray qbaOriRecv, qbaTemp,qbaRecv;
// qbaOriRecv.clear();
// qbaTemp.clear();
// qbaRecv.clear();
//
// ///read all once
// Read_IS11(qbaTemp);
// qbaOriRecv.append(qbaTemp);
// while (qbaOriRecv.size() < 2 || ParseHdr(qbaOriRecv, 3) == 1)
// {
// m_pSerialPort->waitForReadyRead(100);
// Read_IS11(qbaTemp);
// qbaOriRecv.append(qbaTemp);
// iRetryCount++;
// if (iRetryCount > 20)
// {
// qDebug() << "Recv Hdr Err.out of retry time";
// return 1;
// }
// }
//
// iRetryCount = 0;
// while (qbaOriRecv.size() < qbaOriRecv[2] + 5)
// {
// m_pSerialPort->waitForReadyRead(100);
// Read_IS11(qbaTemp);
// qbaOriRecv.append(qbaTemp);
// iRetryCount++;
// if (iRetryCount > 20)
// {
// qDebug() << "Recv Data Err.out of retry time";
// return 2;
// }
// }
//
// if (qbaOriRecv.size() != qbaOriRecv[2] + 5)
// {
// /// can be handled but dont want to
// qDebug() << "Wrong Recv data size.";
// return 3;
// }
//
// unsigned short usCRCC = CalCRC16((unsigned char *)qbaOriRecv.data(), qbaOriRecv.size() - 2);
// char *pc = (char *)&usCRCC;
// if ((pc[0] == qbaOriRecv[qbaOriRecv.size() - 1] && pc[1] == qbaOriRecv[qbaOriRecv.size() - 2]) ||
// (pc[0] == qbaOriRecv[qbaOriRecv.size() - 2] && pc[1] == qbaOriRecv[qbaOriRecv.size() - 1]))
// {
// qbaRecv = qbaOriRecv.mid(3, qbaOriRecv.length() - 5);
// }
// else
// {
// ///error crc
// qDebug() << "Recv data crc16 Err." << pc[1] << pc[0];
// return 4;
// }
//
// fWavelength = qbaRecv.toFloat();
// return 0;
//}
int IS11_Ctrl_Qt::SendData_CMD06(char *pcCMD, size_t szCMDLength, char *pcValue, size_t szValueLenth)
{
// QString qstrSend, qstrSend1, qstrCRC16;///QByteArray append<6E><64><EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD>ֽ<EFBFBD>
// QByteArray qbaSend;
// qbaSend.clear();
//
// qstrSend = QString::fromLatin1(pcCMD, (int)szCMDLength);
// qbaSend.append(qstrSend);
//
// qstrSend1.clear();
// qstrSend1 = QString::fromLatin1(pcValue,(int)szValueLenth);
// qbaSend.append(qstrSend1);
QByteArray qbaSend;
qbaSend.append(pcCMD, szCMDLength);
qbaSend.append(pcValue, szValueLenth);
unsigned short usCRC16 = CalCRC16((unsigned char*)qbaSend.data(), qbaSend.size());
const char * pucSend = (char *)&usCRC16;
qbaSend.append(pucSend, (int)sizeof(unsigned short));
int iReturn = m_pSerialPort->write(qbaSend);
return 0;
}
int IS11_Ctrl_Qt::RecvData_CMD06(QByteArray &qbaRecv)
{
int iRetryCount = 0;
QByteArray qbaOriRecv, qbaTemp;
qbaOriRecv.clear();
qbaTemp.clear();
Read_IS11(qbaTemp);
qbaOriRecv.append(qbaTemp);
while (qbaOriRecv.size() < 2 || ParseHdr(qbaOriRecv, 6) == 1)
{
m_pSerialPort->waitForReadyRead(1000);
Read_IS11(qbaTemp);
qbaOriRecv.append(qbaTemp);
iRetryCount++;
if (iRetryCount > 100)
{
qDebug() << "Recv Hdr Err.out of retry time.RecvData_CMD06";
return 1;
}
}
iRetryCount = 0;
while (qbaOriRecv.size() < 8)
{
m_pSerialPort->waitForReadyRead(1000);
Read_IS11(qbaTemp);
qbaOriRecv.append(qbaTemp);
iRetryCount++;
if (iRetryCount > 66)
{
qDebug() << "Recv Data Err.out of retry time";
return 2;
}
}
if (qbaOriRecv.size() != 8)
{
/// can be handled but dont want to
qDebug() << "Wrong Recv data size.RecvData_CMD06";
return 3;
}
unsigned short usCRCC = CalCRC16((unsigned char *)qbaOriRecv.data(), qbaOriRecv.size() - 2);
char *pc = (char *)&usCRCC;
if ((pc[0] == qbaOriRecv[qbaOriRecv.size() - 1] && pc[1] == qbaOriRecv[qbaOriRecv.size() - 2]) ||
(pc[0] == qbaOriRecv[qbaOriRecv.size() - 2] && pc[1] == qbaOriRecv[qbaOriRecv.size() - 1]))
{
qbaRecv = qbaOriRecv.mid(2, 4);
}
else
{
///error crc
qDebug() << "Recv data crc16 Err." << pc[1] << pc[0];
return 4;
}
return 0;
}
int IS11_Ctrl_Qt::ParseHdr(QByteArray &qbaData, char cHdrType)
{
QByteArray qbaTemp(qbaData);
while ((qbaTemp[0] != (char)0x01) &&(qbaTemp[1] != cHdrType))
{
qbaTemp.remove(0, 1);
if (qbaTemp.size()<=2)
{
return 1;
}
}
if (qbaTemp!= qbaData)
{
///warning some communication error may happened.
qbaData = qbaTemp;
return 1000;
}
return 0;
}
int IS11_Ctrl_Qt::Write_IS11(char * pcCMD, size_t szCMDLength)
{
QString qstrSend;
QByteArray qbaSend;
qbaSend.clear();
qstrSend = QString::fromLatin1((const char*)pcCMD, (int)szCMDLength);
return (int)m_pSerialPort->write(qbaSend);
}
int IS11_Ctrl_Qt::Read_IS11(QByteArray &qbaRecv)
{
//m_pSerialPort->waitForReadyRead(100);
qbaRecv = m_pSerialPort->readAll();
return qbaRecv.size();
}

View File

@ -0,0 +1,263 @@
//
// Created by 73505 on 2023/5/7.
//
#include "Header_Files/JinspFiberImager.h"
JinspFiberImager::JinspFiberImager(bool bIsUSBMode, std::string ucPortNumber, std::string strDeviceName)
{
m_FiberSpectrometer = NULL;
mUcPortNumber=ucPortNumber;
}
JinspFiberImager::~JinspFiberImager()
{
}
void JinspFiberImager::connectFiberSpectrometer(QString& SN, QString& pixelCount, QString& wavelengthInfo)
{
using namespace std;
m_FiberSpectrometer = new IS11_Ctrl_Qt();
m_FiberSpectrometer->Initialize(false, mUcPortNumber, "OPTOSKY");
DeviceInfo deviceInfo;//
DeviceAttribute deviceAttribute;
m_FiberSpectrometer->GetDeviceInfo(deviceInfo);
m_FiberSpectrometer->GetDeviceAttribute(deviceAttribute);//
SN = QString::fromStdString(deviceInfo.strSN);
pixelCount = QString::number(deviceAttribute.iPixels);
wavelengthInfo = QString::number(deviceAttribute.fWaveLengthInNM[0]) + "--" + QString::number(deviceAttribute.fWaveLengthInNM[deviceAttribute.iPixels - 1]);
m_FiberSpectrometer->SetDeviceTemperature(-10);
//设置dn值的最大值和位深相关
string qepro = "QEP";//?????????????????????????????????????????????????????????????????????????????????????????
string flame = "FLMS";//?????????????????????????????????????????????????????????????????????????????????????????
if (deviceInfo.strSN.find(qepro) != string::npos)
{
m_MaxValueOfFiberSpectrometer = 200000;
}
else if (deviceInfo.strSN.find(flame) != string::npos)
{
m_MaxValueOfFiberSpectrometer = 65535;
}
else//没有找到匹配的仪器来设置 dn值的最大值
{
m_MaxValueOfFiberSpectrometer = 65535;
}
}
void JinspFiberImager::disconnectFiberSpectrometer()
{
m_FiberSpectrometer->Close();
}
void JinspFiberImager::getDeviceAttribute(DeviceAttribute& deviceAttribute)
{
m_FiberSpectrometer->GetDeviceAttribute(deviceAttribute);
}
void JinspFiberImager::getDeviceInfo(DeviceInfo& deviceInfo)
{
m_FiberSpectrometer->GetDeviceInfo(deviceInfo);
}
void JinspFiberImager::setExposureTime(int iExposureTimeInMS)
{
m_FiberSpectrometer->SetExposureTime(iExposureTimeInMS);
}
void JinspFiberImager::getExposureTime(int &iExposureTimeInMS)
{
m_FiberSpectrometer->GetExposureTime(iExposureTimeInMS);
}
void JinspFiberImager::getDeviceTemperature(float &fTemperature)
{
m_FiberSpectrometer->GetDeviceTemperature(fTemperature);
}
void JinspFiberImager::singleShot(DataFrame &dfData)
{
m_FiberSpectrometer->SingleShot(dfData);
}
void JinspFiberImager::getNonlinearityCoeffs(coeffsFrame &coeffs)
{
printf("This is JinspFiberImager.\n");
}
void JinspFiberImager::recordDark(QString path)
{
//获取设备信息
DeviceAttribute attribute;
DeviceInfo deviceInfo;
getDeviceAttribute(attribute);
getDeviceInfo(deviceInfo);
//采集暗帧
singleShot(m_DarkData);
//输出到csv
QDateTime curDateTime = QDateTime::currentDateTime();
QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss");
QString fileName = path + "/" + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + "_darkSpectral_dn.csv";
std::ofstream outfile(fileName.toStdString().c_str());
for (int i = 0; i < attribute.iPixels; i++)
{
if (i==0)
{
outfile << m_DarkData.usExposureTimeInMS << std::endl;
}
outfile << attribute.fWaveLengthInNM[i] << "," << m_DarkData.lData[i] << std::endl;
}
outfile.close();
}
void JinspFiberImager::recordTarget(int recordTimes, QString path)
{
//获取设备信息
DeviceAttribute attribute;
DeviceInfo deviceInfo;
getDeviceAttribute(attribute);
getDeviceInfo(deviceInfo);
DataFrame integratingSphereData_tmp;
for (int i = 0; i < recordTimes; i++)
{
singleShot(integratingSphereData_tmp);
if (i == 0)//将integratingSphereData_tmp中的曝光时间、温度等信息传给m_IntegratingSphereData
{
m_IntegratingSphereData = integratingSphereData_tmp;
}
else
{
for (int i = 0; i < attribute.iPixels; i++)
{
m_IntegratingSphereData.lData[i] += integratingSphereData_tmp.lData[i];
}
}
}
for (int i = 0; i < attribute.iPixels; i++)
{
m_IntegratingSphereData.lData[i] = m_IntegratingSphereData.lData[i] / recordTimes;
}
//输出到csv
QDateTime curDateTime = QDateTime::currentDateTime();
QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss");
QString fileName = path + "/" + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + "_integratingSphereSpectral_dn.csv";
std::ofstream outfile(fileName.toStdString().c_str());
for (int i = 0; i < attribute.iPixels; i++)
{
if (i==0)
{
outfile << m_IntegratingSphereData.usExposureTimeInMS << std::endl;
}
outfile << attribute.fWaveLengthInNM[i] << "," << m_IntegratingSphereData.lData[i] << std::endl;
}
outfile.close();
}
void JinspFiberImager::autoExpose()
{
// float fPredictedExposureTime;
// m_FiberSpectrometer->PerformAutoExposure(0.6,0.9,fPredictedExposureTime);
//tc
DeviceAttribute attribute;
getDeviceAttribute(attribute);
int iterations = 0;//记录自动曝光已经迭代的次数
int maxIterations = 10;//允许最大的迭代次数
ZZ_U32 thresholdValue = m_MaxValueOfFiberSpectrometer * 0.8;//最佳线性区间为80%
ZZ_U16 range = 10000;
//设置初始曝光时间
int exposureTimeInMS = 200;
setExposureTime(exposureTimeInMS);
// int exposureTime;
// m_FiberSpectrometer->GetExposureTime(exposureTime);
emit sendExposureTimeSignal(exposureTimeInMS);
DataFrame integratingSphereData_tmp;
ZZ_S32 maxValue;
while (true)
{
if (iterations > maxIterations)//是否超过允许的最大迭代次数
{
break;
}
singleShot(integratingSphereData_tmp);
maxValue = GetMaxValue(integratingSphereData_tmp.lData, attribute.iPixels);
if (maxValue < thresholdValue && maxValue < (thresholdValue - range))//曝光时间过小
{
double scale = 1 + ((double)(thresholdValue - maxValue) / (double)thresholdValue);
int exposureTime;
m_FiberSpectrometer->GetExposureTime(exposureTime);
m_FiberSpectrometer->SetExposureTime(exposureTime * scale);
emit sendExposureTimeSignal(exposureTime);
std::cout << "自动曝光-----------" << "最大值为" << maxValue << std::endl;
}
else if (maxValue > thresholdValue)//曝光时间过大
{
double scale = 1 - ((double)(maxValue - thresholdValue) / (double)thresholdValue);
int exposureTime;
m_FiberSpectrometer->GetExposureTime(exposureTime);
m_FiberSpectrometer->SetExposureTime(exposureTime * scale);
emit sendExposureTimeSignal(exposureTime);
std::cout << "自动曝光-----------" << "最大值为" << maxValue << std::endl;
}
else//找到最佳曝光时间跳出while循环
{
break;
}
iterations++;
}
int a = 2;
}
ZZ_S32 JinspFiberImager::GetMaxValue(ZZ_S32 * dark, int number)
{
ZZ_S32 max = 0;
for (size_t i = 0; i < number; i++)
{
if (dark[i] > max)
{
max = dark[i];
}
}
//std::cout << "本帧最大值为" << max << std::endl;
return max;
}

View File

@ -7,6 +7,7 @@
#include "Header_Files/oceanOpticsFiberImager.h"
#include "Header_Files/atpFiberImager.h"
#include "Header_Files/JinspFiberImager.h"
#include "Header_Files/calibration.h"
enum CommandLineParseResult
@ -21,6 +22,7 @@ enum DeviceType
{
OPTOSKY,
OceanOptics,
JINSP,
UnknownDevice
};
@ -106,6 +108,11 @@ int main(int argc, char *argv[])
isOcean = true;
break;
}
case JINSP:
{
m_FiberSpectrometer = new JinspFiberImager(false,query.serialPort.toStdString(),"JINSP");
break;
}
case UnknownDevice:
parser.showHelp();
Q_UNREACHABLE();
@ -120,6 +127,10 @@ int main(int argc, char *argv[])
logout("<br><b style=\"color:red\">Connectting the fiber spectrometer!</b>");
m_FiberSpectrometer->connectFiberSpectrometer(SN, pixelCount, wavelengthInfo);
qDebug() << SN;
qDebug() << pixelCount;
qDebug() << wavelengthInfo;
//<2F>Զ<EFBFBD><D4B6>ع<EFBFBD>
@ -216,7 +227,7 @@ CommandLineParseResult parseCommandLine2(QCommandLineParser &parser, TcQuery *qu
{
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
QCommandLineOption deviceType("deviceType", "Device type. Options are OPTOSKY and OceanOptics", "deviceType");
QCommandLineOption deviceType("deviceType", "Device type. Options are OPTOSKY, OceanOptics and JINSP", "deviceType");
parser.addOption(deviceType);
QCommandLineOption serialPort("serialPort", "Serial port.", "serialPort");
@ -317,6 +328,10 @@ CommandLineParseResult parseCommandLine2(QCommandLineParser &parser, TcQuery *qu
{
query->deviceType = OceanOptics;
}
else if(deviceTypeTmp=="JINSP")
{
query->deviceType = JINSP;
}
else
{
*errorMessage = "DeviceType set error.";

View File

@ -0,0 +1,5 @@
--deviceType OPTOSKY --serialPort ttyS1 -t 30 -slfs RadLamp.txt --cfon FSNISIF4.data --position 4 --integratingSphereDetectorValue 2500
--deviceType JINSP --serialPort ttyUSB0 -t 30 -slfs RadLamp.txt --cfon FSNISIF4.data --position 4 --integratingSphereDetectorValue 2500
--deviceType OceanOptics -t 30 -slfs RadLamp.txt --cfon FSNISIF4.data --position 4 --integratingSphereDetectorValue 2500