#include "work_thread.h"
|
#include <QDebug>
|
#include <QDateTime>
|
#include "unistd.h"
|
#include <sys/vfs.h>
|
#include <QDir>
|
#include "remote_ctrl.h"
|
#include "DataForm/datalist_page.h"
|
|
|
QStringList alarmStateText;
|
|
Work_Thread::Work_Thread()
|
{
|
memset(&fboData,0x00,sizeof(fboData));
|
memset(&packData,0x00,sizeof(packData));
|
memset(&packData_Origin,0x00,sizeof(packData_Origin));
|
memset(&modTestData,0x00,sizeof(modTestData));
|
memset(&modTestData_Origin,0x00,sizeof(modTestData_Origin));
|
memset(&iconState,0x00,sizeof(iconState));
|
memset(&testStateData,0x00,sizeof(testStateData));
|
memset(&cellMaxMInValue,0x00,sizeof(cellMaxMInValue));
|
memset(&remoteState,0x00,sizeof(remoteState));
|
memset(&adjParamSet,0x00,sizeof(adjParamSet));
|
memset(&volDropParam,0x00,sizeof(volDropParam));
|
memset(&passthroughState,0x00,sizeof(passthroughState));
|
|
cmdExecResult = 0;
|
workThreadCMD = CMD_Null;
|
adjWorkState = ADJ_STATE_STOPPED;
|
|
timer_1s = new QTimer(this);
|
connect(timer_1s,SIGNAL(timeout()),this,SLOT(Timer1sSlot()));
|
timer_1s->start(1000);
|
|
rs485_PowerCtrl = new RS485_PowerCtrl(RS485_PwrCtr_DEV_PORT);
|
rs485_PowerCtrl->start();
|
|
qRegisterMetaType<MOD_TEST_DATA>("MOD_TEST_DATA");
|
connect(rs485_PowerCtrl,SIGNAL(sendModTestDataSignal(MOD_TEST_DATA)),this,SLOT(RecvModTestData(MOD_TEST_DATA)));
|
|
rs485_Pack = new RS485_Pack(RS485_Pack_DEV_PORT);
|
rs485_Pack->start();
|
|
qRegisterMetaType<PACK_DATA>("PACK_DATA");
|
connect(rs485_Pack,SIGNAL(sendPackDataSignal(PACK_DATA)),this,SLOT(RecvPackData(PACK_DATA)));
|
|
initValueForParam();
|
|
alarmStateText<<tr("测试停止!")<<tr("正在放电!")<<tr("正在充电!") \
|
<<tr("放电时间到!")<<tr("放电容量到!")<<tr("放电SOC到!")<<tr("组端下限到!")<<tr("单体下限到!") \
|
<<tr("充电时间到!")<<tr("充电容量到!")<<tr("充电SOC到!")<<tr("组端上限到!")<<tr("单体上限到!") \
|
<<tr("电芯温度过高!")<<tr("电芯压差过大!") \
|
<<tr("内部通信异常!")<<tr("电压异常!")<<tr("电流异常!")<<tr("温度异常!")<<tr("内部停止!") \
|
<<tr("Pack通信异常!")<<tr("Pack故障!")<<tr("未知错误!");
|
|
}
|
|
Work_Thread::~Work_Thread()
|
{
|
|
}
|
|
//=============================================================================================================
|
|
void Work_Thread::initValueForParam()
|
{
|
//---------------- system param ---------------
|
sysParamXml.dev_addr = 1;
|
sysParamXml.save_time_interval = 60;
|
sysParamXml.tcp_type = 1;
|
sysParamXml.server_port = 6666;
|
sysParamXml.server_ip = "192.168.10.199";
|
ClassXML::CreateSysParamXml(sysParamXml);
|
ClassXML::ReadSysParamXml(sysParamXml);
|
|
Remote_Ctrl::setRemoteDevAddr(sysParamXml.dev_addr);
|
|
//---------------- test param -----------------
|
TEST_PARAM defaultTestParam;
|
memset(&defaultTestParam,0x00,sizeof(defaultTestParam));
|
|
//defaultTestParam.batt_pack_type = PACK_TYPE_Halo;
|
//defaultTestParam.batt_pack_addr = 0x06;
|
defaultTestParam.test_type = TestTypeDischarge;
|
defaultTestParam.union_test_EN = 0;
|
|
defaultTestParam.cell_vol_diff = 100;//1mv
|
defaultTestParam.temp_high = 650; //0.1
|
defaultTestParam.constvol_EN = 0;
|
defaultTestParam.curr_end = 50; //0.01A
|
|
defaultTestParam.disParam.dis_time = 180;//minute
|
defaultTestParam.disParam.dis_curr = 1000;//0.01A
|
defaultTestParam.disParam.dis_cap = 3000;//0.01AH
|
defaultTestParam.disParam.sum_vol_low = 3750;//0.01V
|
defaultTestParam.disParam.cell_vol_low = 3200;//0.001V
|
defaultTestParam.disParam.dis_soc = 300;//0.1%
|
|
defaultTestParam.chgParam.chg_time = 180;//minute
|
defaultTestParam.chgParam.chg_curr = 1000;//0.01A
|
defaultTestParam.chgParam.chg_cap = 3000;//0.01AH
|
defaultTestParam.chgParam.sum_vol_high = 4550; //0.01V
|
defaultTestParam.chgParam.cell_vol_high = 4200;//0.001V
|
defaultTestParam.chgParam.chg_soc = 900;//0.1%
|
|
defaultTestParam.crc16 = CRC16::CalModbusCRC16(&defaultTestParam,sizeof(defaultTestParam)-2);
|
|
ClassXML::CreateTestParamFile(defaultTestParam);
|
ClassXML::ReadTestParamFile(testParam);
|
quint16 crc = CRC16::CalModbusCRC16(&testParam,sizeof(testParam)-2);
|
|
if(crc != testParam.crc16){
|
testParam = defaultTestParam;
|
ClassXML::SaveTestParamFile(testParam);
|
}
|
|
//---------------- pack param -----------------
|
PACK_PARAM defaultPackParam;
|
memset(&defaultPackParam,0x00,sizeof(defaultPackParam));
|
|
defaultPackParam.pack_devaddr = 0x06;
|
defaultPackParam.pack_type = PACK_TYPE_Halo;
|
|
defaultPackParam.crc16 = CRC16::CalModbusCRC16(&defaultPackParam,sizeof(defaultPackParam)-2);
|
|
ClassXML::CreatePackParamFile(defaultPackParam);
|
ClassXML::ReadPackParamFile(packParam);
|
crc = CRC16::CalModbusCRC16(&packParam,sizeof(packParam)-2);
|
|
if(crc != packParam.crc16){
|
packParam = defaultPackParam;
|
ClassXML::SavePackParamFile(packParam);
|
}
|
|
rs485_Pack->setPackCommParam(packParam.pack_devaddr, packParam.pack_type);
|
}
|
|
void Work_Thread::setPageIndex(const quint8 pageindex)
|
{
|
pageIndex = pageindex;
|
}
|
|
quint8 Work_Thread::getPageIndex(void)
|
{
|
return pageIndex;
|
}
|
|
void Work_Thread::setPackBarcodeStr(QString code)
|
{
|
packBarcode = code;
|
}
|
|
void Work_Thread::setRemoteState(REMOTE_STATE &st)
|
{
|
remoteState = st;
|
}
|
|
void Work_Thread::setPassthroughState(PASSTHROUGH_ST &st)
|
{
|
passthroughState = st;
|
}
|
|
void Work_Thread::CheckIconState(void)
|
{
|
iconState.usbState = CheckDiskState(usbDir);
|
}
|
|
quint8 Work_Thread::CheckDiskState(const QString &disk)
|
{
|
struct statfs st;
|
statfs(disk.toLocal8Bit().data(), &st);
|
if(19780 == st.f_type)
|
{
|
return 1;
|
}
|
|
return 0;
|
}
|
|
void Work_Thread::saveTestParam(TEST_PARAM &testparam)
|
{
|
testParam = testparam;
|
testParam.crc16 = CRC16::CalModbusCRC16(&testParam,sizeof(testParam)-2);
|
ClassXML::SaveTestParamFile(testParam);
|
|
if(WORK_STATE_STOPPED != testStateData.workState || ADJ_STATE_STOPPED != adjWorkState){
|
setWorkThreadCMD(CMD_SetTestParam);
|
}
|
}
|
|
void Work_Thread::savePackParam(PACK_PARAM &packparam)
|
{
|
packParam = packparam;
|
packParam.crc16 = CRC16::CalModbusCRC16(&packParam,sizeof(packParam)-2);
|
ClassXML::SavePackParamFile(packParam);
|
|
rs485_Pack->setPackCommParam(packParam.pack_devaddr, packParam.pack_type);
|
}
|
|
void Work_Thread::saveSysParam(SYSTEM_PARAM_XML &sysparam)
|
{
|
sysParamXml = sysparam;
|
|
//qDebug("save time interval = %d,dev addr = %d",sysParamXml.save_time_interval,sysParamXml.dev_addr);
|
|
ClassXML::SaveSysParamXml(sysParamXml);
|
|
Remote_Ctrl::setRemoteDevAddr(sysParamXml.dev_addr);
|
}
|
|
//=============================================================================================================
|
void Work_Thread::RecvModTestData(MOD_TEST_DATA testdata)
|
{
|
modTestData_Origin = testdata;
|
MOD_TEST_DATA tmpdata = testdata;
|
tmpdata.ADCVp = tmpdata.ADCVp/10; //2位小数
|
tmpdata.ADCVdc = tmpdata.ADCVdc/10;
|
tmpdata.ADCIdc = tmpdata.ADCIdc/10;
|
|
if(tmpdata.ADCIdc < 0){
|
tmpdata.ADCIdc *= -1;
|
}
|
|
modTestData = tmpdata;
|
|
if(!(rs485_Pack->packComm_OK)){
|
memset(&packData,0x00,sizeof(packData));
|
memset(&packData_Origin,0x00,sizeof(packData_Origin));
|
memset(&cellMaxMInValue,0x00,sizeof(cellMaxMInValue));
|
}
|
}
|
|
void Work_Thread::RecvPackData(PACK_DATA packdata)
|
{
|
packData_Origin = packdata;
|
packData = packdata;
|
|
if(rs485_Pack->packComm_OK){
|
packData.cell_tempe_max = packData.cell_tempe_max-50; //Halo温度换算-50
|
packData.cell_tempe_min = packData.cell_tempe_min-50;
|
for(quint16 n=0;n<packData.temp_count;n++){
|
packData.cell_temp[n] = packData.cell_temp[n]-50;
|
}
|
}
|
|
packData.junheng_on_state = (packData.junheng_on_state & 0x00FF);
|
|
|
cellMaxMInValue.max_vol_value = packData.cell_vol_max;
|
cellMaxMInValue.min_vol_value = packData.cell_vol_min;
|
for(int n=0;n<packData.cell_count;n++){
|
if(packData.cell_vol[n] == cellMaxMInValue.max_vol_value){
|
cellMaxMInValue.max_vol_index = n;
|
}
|
|
if(packData.cell_vol[n] == cellMaxMInValue.min_vol_value){
|
cellMaxMInValue.min_vol_index = n;
|
}
|
}
|
|
// char sv[24] = {'\0'};
|
// memcpy(sv,packData.soft_version,16);
|
// qDebug("soft_version: %s",sv);
|
|
// qDebug("life_data_signal = %d,cell_count = %d,temp_count = %d",packData.life_data_signal, packData.cell_count,packData.temp_count);
|
// qDebug("pre_charge_mos_state = 0x%X,charge_mos_state = 0x%X,dischg_mos_state = 0x%X",packData.pre_charge_mos_state,packData.charge_mos_state,packData.dischg_mos_state);
|
|
}
|
|
void Work_Thread::initFBO_Data(FBO_DATA_HEAD_START &fbo_data_head_start)
|
{
|
memset(&fboData,0x00,sizeof(fboData));
|
if(TestTypeDischarge == testParam.test_type){
|
fboData.m_DataType.TypeTag0 = TestTypeDischarge;
|
fboData.m_DataType.TypeTag1 = TestTypeDischarge;
|
fboData.m_DataType.TypeTag2 = TestTypeDischarge;
|
fboData.m_DataType.TypeTag3 = TestTypeDischarge;
|
}
|
else{
|
fboData.m_DataType.TypeTag0 = TestTypeCharge;
|
fboData.m_DataType.TypeTag1 = TestTypeCharge;
|
fboData.m_DataType.TypeTag2 = TestTypeCharge;
|
fboData.m_DataType.TypeTag3 = TestTypeCharge;
|
}
|
|
testfilename = testDataDir + format_data_name();
|
|
fbo_data_head_start.TestStartTime.year = QDate::currentDate().year()-2000;
|
fbo_data_head_start.TestStartTime.month = QDate::currentDate().month();
|
fbo_data_head_start.TestStartTime.day = QDate::currentDate().day();
|
fbo_data_head_start.TestStartTime.hour = QTime::currentTime().hour();
|
fbo_data_head_start.TestStartTime.minute = QTime::currentTime().minute();
|
fbo_data_head_start.TestStartTime.second = QTime::currentTime().second();
|
fbo_data_head_start.Device = 0x99;
|
|
fbo_data_head_start.DataVersion = 0x00;
|
|
fbo_data_head_start.DataType = testParam.test_type;
|
|
fbo_data_head_start.HourRate = 10;
|
fbo_data_head_start.SaveInterval = sysParamXml.save_time_interval;
|
fbo_data_head_start.STDCap = 100;
|
|
if(TestTypeDischarge == testParam.test_type)
|
fbo_data_head_start.TestCur = testParam.disParam.dis_curr/10; //0.1
|
else
|
fbo_data_head_start.TestCur = testParam.chgParam.chg_curr/10; //0.1
|
|
fbo_data_head_start.MVLLimit = testParam.disParam.cell_vol_low/10; //0.01
|
fbo_data_head_start.SumVLLimit = testParam.disParam.sum_vol_low/10; //0.1
|
fbo_data_head_start.BattSum = (packData.cell_count>0)?packData.cell_count:1;;
|
fbo_data_head_start.BattGroup = 1;
|
fbo_data_head_start.MVLLimitCount = 1;
|
fbo_data_head_start.MonomerVol = 32;
|
|
fboData.BattSum = fbo_data_head_start.BattSum;//2个位置BattSum必须一致
|
}
|
|
void Work_Thread::makeFBO_Data()
|
{
|
fboData.m_TestTime = testStateData.testTime;
|
fboData.BattGroup = 1;
|
//fboData.BattSum = (packData.cell_count>0)?packData.cell_count:1;
|
fboData.OnlineVol = 0;
|
fboData.SumVoltage = modTestData.ADCVdc/10; //0.1
|
fboData.SumCurrent = modTestData.ADCIdc/10; //0.1
|
fboData.AllCap = testStateData.testCap/100; //1
|
for(quint8 n=0;n<4;n++){
|
fboData.SubCurrent[n] = fboData.SumCurrent;
|
fboData.SubCap[n] = fboData.AllCap;
|
}
|
|
if(fboData.BattSum > 1){
|
for(quint8 n=0;n<30;n++){
|
if(n<fboData.BattSum){
|
fboData.SingleVol[n] = packData.cell_vol[n];//0.001
|
}
|
}
|
}
|
else{
|
fboData.SingleVol[0] = modTestData.ADCVdc*10;//0.001
|
}
|
}
|
|
void Work_Thread::SaveFbo_Data(bool force_save){
|
|
if( (true==testStateData.saveDataEn) || (true==force_save) ){
|
|
testStateData.saveDataEn = false;
|
|
makeFBO_Data();
|
ClassXML::SaveFBO_Data(testfilename,fboData);
|
}
|
}
|
|
void Work_Thread::closeTestFbo_Data(const quint8 stoptype)
|
{
|
FBO_DATA_HEAD_STOP fbo_data_head_stop;
|
fbo_data_head_stop.TestTimeLong = fboData.m_TestTime;
|
|
fbo_data_head_stop.StopType = stoptype;
|
|
fbo_data_head_stop.BlockSum = 1;
|
fbo_data_head_stop.StandBy = 0;
|
fbo_data_head_stop.TestCap = fboData.AllCap;
|
for(quint8 g=0;g<4;g++)
|
{
|
fbo_data_head_stop.SMaxIndex[g] = cellMaxMInValue.max_vol_index;
|
fbo_data_head_stop.SMinIndex[g] = cellMaxMInValue.min_vol_index;
|
fbo_data_head_stop.SMaxVol[g] = cellMaxMInValue.max_vol_value;
|
fbo_data_head_stop.SMinVol[g] = cellMaxMInValue.min_vol_value;
|
}
|
|
ClassXML::CloseFBO_Data(testfilename,fbo_data_head_stop);
|
}
|
|
//=============================================================================================================
|
|
QString Work_Thread::format_data_name(void)
|
{
|
QDateTime dtime = QDateTime::currentDateTime();//获取系统现在的时间
|
QString str = "F"+dtime.toString("yyyy-MM-dd hh.mm.ss")+".FBO"; //设置显示格式
|
|
testStartTime.year = QDate::currentDate().year()-2000;
|
testStartTime.month = QDate::currentDate().month();
|
testStartTime.day = QDate::currentDate().day();
|
testStartTime.hour = QTime::currentTime().hour();
|
testStartTime.minute = QTime::currentTime().minute();
|
testStartTime.second = QTime::currentTime().second();
|
|
return str;
|
}
|
|
CT_DATE_TIME Work_Thread::getTestStartTime()
|
{
|
return testStartTime;
|
}
|
|
|
|
//=============================================================================================================
|
void Work_Thread::Timer1sSlot()
|
{
|
if( WORK_STATE_DISCHG == testStateData.workState
|
|| WORK_STATE_CHARGE == testStateData.workState )
|
{
|
if(testStateData.testTime.second<59)
|
{
|
testStateData.testTime.second++;
|
}
|
else
|
{
|
testStateData.testTime.second = 0;
|
if(testStateData.testTime.minute<59)
|
{
|
testStateData.testTime.minute++;
|
}
|
else
|
{
|
testStateData.testTime.minute = 0;
|
if(testStateData.testTime.hour < 99)
|
{
|
testStateData.testTime.hour++;
|
}
|
else
|
{
|
testStateData.testTime.hour = 0;
|
}
|
}
|
}
|
|
testStateData.testCapPS += modTestData.ADCIdc;
|
|
if(testStateData.testCapPS>=3600)
|
{
|
testStateData.testCapPS -= 3600;
|
|
testStateData.testCap++;
|
}
|
/*
|
else if(testStateData.testCapPS<=-3600)
|
{
|
testStateData.testCapPS += 3600;
|
|
testStateData.testCap--;
|
}
|
*/
|
|
quint32 secondsum =3600*testStateData.testTime.hour
|
+ 60*testStateData.testTime.minute
|
+ testStateData.testTime.second;
|
|
//前3分钟5秒,以后按saveInterval秒
|
if(secondsum<=180)
|
{
|
if(secondsum%5 == 0)
|
{
|
testStateData.saveDataEn = true;
|
}
|
}
|
else
|
{
|
if(secondsum%sysParamXml.save_time_interval == 0)
|
{
|
testStateData.saveDataEn = true;
|
}
|
}
|
}
|
|
if(remoteState.heart_ticks < 1000){
|
remoteState.heart_ticks++;
|
|
if(remoteState.heart_ticks > 60){
|
remoteState.conn_type = 0;
|
remoteState.enter_slave = 0;
|
remoteState.heart_ticks = 0;
|
|
passthroughState.passing = 0;
|
|
rs485_Pack->remsumPackComm();
|
}
|
}
|
}
|
|
//=============================================================================================================
|
int Work_Thread::initTestState()
|
{
|
testStateData.testCap = 0;
|
testStateData.testCapPS = 0;
|
|
testStateData.testTime.hour = 0;
|
testStateData.testTime.minute = 0;
|
testStateData.testTime.second = 0;
|
|
testStateData.workState = WORK_STATE_STOPPED;
|
testStateData.alarmState = ALARM_STATE_STOPPED;
|
testStateData.startState = EXE_RES_OK;
|
|
testStateData.saveDataEn = 0;
|
|
stateWorkCount = 0;
|
|
FBO_DATA_HEAD_START fbo_data_head_start;
|
|
initFBO_Data(fbo_data_head_start);
|
|
ClassXML::CreateFBO_Data(testfilename,fbo_data_head_start);
|
|
SaveFbo_Data(true);
|
|
return 0;
|
}
|
|
int Work_Thread::startErrorCheck()
|
{
|
#ifdef _debug_demo_
|
return 0;
|
#endif
|
|
if (modTestData.ADCVdc< VOL_TOO_LOW){
|
return START_VOL_LOW;
|
}
|
|
if (modTestData.ADCVdc>VOL_TOO_HIGH){
|
return START_VOL_HIGH;
|
}
|
|
if(DataList_Page::isMemoryIsFull()){
|
return START_MEM_ERROR;
|
}
|
|
double vol = modTestData.ADCVdc;
|
quint16 volmin = (quint16)(vol * 0.8);
|
quint16 volmax = (quint16)(vol * 1.2);
|
|
if(testParam.test_type == TestTypeDischarge){
|
if( (testParam.disParam.sum_vol_low<volmin)
|
|| (testParam.disParam.sum_vol_low>=modTestData.ADCVdc) ){
|
return START_DISVOL_ERROR;
|
}
|
}
|
else{
|
if( (testParam.chgParam.sum_vol_high>volmax)
|
|| (testParam.chgParam.sum_vol_high<=modTestData.ADCVdc) ){
|
return START_CHGVOL_ERROR;
|
}
|
}
|
|
/*
|
quint32 power1 = modTestData.ADCVdc;
|
quint32 power2 = 0;
|
|
if(testParam.test_type == TestTypeDischarge){
|
power1 *= testParam.disParam.dis_curr;
|
power2 = testParam.disParam.dis_curr * testParam.disParam.sum_vol_low;
|
}
|
else{
|
power1 *= testParam.chgParam.chg_curr;
|
power2 = testParam.chgParam.chg_curr * testParam.chgParam.sum_vol_high;
|
}
|
|
if(power1>POWER_MAX || power2>POWER_MAX){
|
return START_POWER_OVER;
|
}
|
*/
|
|
return START_OK;
|
}
|
|
int Work_Thread::closePrechgMos()
|
{
|
int res = 0;
|
|
#ifdef _debug_demo_
|
return res;
|
#endif
|
|
if(PACK_TYPE_Halo == packParam.pack_type)
|
{
|
if(rs485_Pack->packComm_OK){
|
|
if(0==packData.pre_charge_mos_state && WORK_STATE_STOPPED==testStateData.workState){
|
rs485_Pack->lock_RS485();
|
res = setPreChgMos_Close();
|
msleep(100);
|
rs485_Pack->unlock_RS485();
|
}
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setPreChgMos_Close()
|
{
|
int res = 0;
|
|
if(PACK_TYPE_Halo == packParam.pack_type)
|
{
|
quint16 mos_close = 0x0001;
|
|
for(quint8 t=0;t<3;t++){
|
//预充电MOS管闭合
|
res = rs485_Pack->ModBusMultiWrite(0x06, 0x02B1, &mos_close, 1, 200);
|
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setPreChgMos_Break()
|
{
|
int res = 0;
|
|
if(PACK_TYPE_Halo == packParam.pack_type)
|
{
|
quint16 mos_break = 0x0000;
|
|
for(quint8 t=0;t<3;t++){
|
//预充电MOS管断开
|
res = rs485_Pack->ModBusMultiWrite(0x06, 0x02B1, &mos_break, 1, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setChargeMos_Close()
|
{
|
int res = 0;
|
|
if(PACK_TYPE_Halo == packParam.pack_type)
|
{
|
quint16 mos_close = 0x0001;
|
|
for(quint8 t=0;t<3;t++){
|
//充电MOS管闭合
|
res = rs485_Pack->ModBusMultiWrite(0x06, 0x02B2, &mos_close, 1, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setChargeMos_Break()
|
{
|
int res = 0;
|
|
if(PACK_TYPE_Halo == packParam.pack_type)
|
{
|
quint16 mos_break = 0x0000;
|
|
for(quint8 t=0;t<3;t++){
|
//充电MOS管断开
|
res = rs485_Pack->ModBusMultiWrite(0x06, 0x02B2, &mos_break, 1, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setDischgMos_Close()
|
{
|
int res = 0;
|
|
if(PACK_TYPE_Halo == packParam.pack_type)
|
{
|
quint16 mos_close = 0x0001;
|
|
for(quint8 t=0;t<3;t++){
|
//放电MOS管闭合
|
res = rs485_Pack->ModBusMultiWrite(0x06, 0x02B3, &mos_close, 1, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setDischgMos_Break()
|
{
|
int res = 0;
|
|
if(PACK_TYPE_Halo == packParam.pack_type)
|
{
|
quint16 mos_break = 0x0000;
|
|
for(quint8 t=0;t<3;t++){
|
//放电MOS管断开
|
res = rs485_Pack->ModBusMultiWrite(0x06, 0x02B3, &mos_break, 1, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::getMos_State(quint16 *premos, quint16 *chgmos, quint16 *dismos)
|
{
|
quint16 mos_state[3] = {0};
|
|
int res = rs485_Pack->ModBusRead(0x06, 675, 3, mos_state, 200);
|
|
if(res == Uart_Driver::CommOK){
|
*premos = Swap16(mos_state[0]);
|
*chgmos = Swap16(mos_state[1]);
|
*dismos = Swap16(mos_state[2]);
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setMOS_BeforeDischarge()
|
{
|
int res = 0;
|
|
if(PACK_TYPE_Halo == packParam.pack_type)
|
{
|
res = setPreChgMos_Break();
|
msleep(20);
|
|
if(Uart_Driver::CommOK == res){
|
res = setChargeMos_Break();
|
msleep(20);
|
}
|
|
if(Uart_Driver::CommOK == res){
|
res = setDischgMos_Close();
|
}
|
|
msleep(500);
|
|
if(Uart_Driver::CommOK == res){
|
quint16 premos = 0;
|
quint16 chgmos = 0;
|
quint16 dismos = 0;
|
|
for(quint8 t=0;t<10;t++){
|
msleep(100);
|
res = getMos_State(&premos, &chgmos, &dismos);
|
if(0==res){
|
qDebug("presmos = %d,chgmos = %d,dismos = %d",premos,chgmos,dismos);
|
if(0==premos && 0==chgmos && 1==dismos){
|
break;
|
}
|
else
|
res = RES_Error_MOS_State;
|
}
|
}
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setMOS_AfterDischarge()
|
{
|
int res = 0;
|
|
if(PACK_TYPE_Halo == packParam.pack_type)
|
{
|
rs485_Pack->lock_RS485();
|
|
res = setDischgMos_Break();
|
msleep(20);
|
|
if(Uart_Driver::CommOK == res){
|
res = setPreChgMos_Close();
|
}
|
|
msleep(100);
|
|
rs485_Pack->unlock_RS485();
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setTestParam(const quint8 testtype)
|
{
|
if(TestTypeDischarge == testtype){
|
DISCHG_PARAM_SET disparamset;
|
|
disparamset.Vdis = testParam.disParam.sum_vol_low*10;
|
disparamset.Idis = testParam.disParam.dis_curr*10;
|
disparamset.Tdis = testParam.disParam.dis_time*60+600;
|
|
//qDebug("sum_vol_low = %d,dis_curr = %d",disparamset.Vdis,disparamset.Idis);
|
|
//设置放电参数
|
int res = 0;
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusMultiWrite(0x01, RegAddr_SetModDisParam, (quint16 *)&disparamset,RegCount_SetModDisParam, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
|
return res;
|
}
|
else if(TestTypeCharge == testtype){
|
CHARGE_PARAM_SET chgparamset;
|
|
chgparamset.Vchg = testParam.chgParam.sum_vol_high*10;
|
chgparamset.Ichg = testParam.chgParam.chg_curr*10;
|
chgparamset.Tchg = testParam.chgParam.chg_time*60+600;
|
|
//qDebug("sum_vol_high = %d,chg_curr = %d",chgparamset.Vchg,chgparamset.Ichg);
|
|
//设置充电参数
|
int res = 0;
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusMultiWrite(0x01, RegAddr_SetModChrParam, (quint16 *)&chgparamset,RegCount_SetModChrParam, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
|
return res;
|
}
|
|
return 0;
|
}
|
|
int Work_Thread::setIOBoardState(const quint8 testype, bool is_start)
|
{
|
int res = 0;
|
|
if(TestTypeDischarge == testype){
|
if(is_start){
|
//启动放电
|
quint16 startdis = CMD_BeginWork;
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusMultiWrite(0x01, RegAddr_Discharge, (quint16 *)&startdis,1, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
}
|
else{
|
//关闭放电
|
quint16 stopdis = CMD_EndWork;
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusMultiWrite(0x01, RegAddr_Discharge, (quint16 *)&stopdis,1, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
}
|
}
|
else if(TestTypeCharge == testype){
|
if(is_start){
|
//启动充电
|
quint16 startchg = CMD_BeginWork;
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusMultiWrite(0x01, RegAddr_Charge, (quint16 *)&startchg, 1, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
}
|
else{
|
//关闭充电
|
quint16 stopchg = CMD_EndWork;
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusMultiWrite(0x01, RegAddr_Charge, (quint16 *)&stopchg, 1, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::openDischargePower()
|
{
|
int res = 0;
|
|
#ifdef _debug_demo_
|
return res;
|
#endif
|
|
rs485_Pack->lock_RS485();
|
rs485_PowerCtrl->lock_RS485();
|
|
//start mos
|
res = setMOS_BeforeDischarge();
|
if(Uart_Driver::CommOK != res){
|
if(res < -20){
|
res = EXE_MOS_STATE_ERR;
|
}
|
else
|
res = EXE_MOS_CTRL_FAIL;
|
}
|
|
if(0 == res){
|
res = setTestParam(TestTypeDischarge);
|
|
if(Uart_Driver::CommOK != res){
|
res = EXE_SET_PARAM_FAIL;
|
}
|
}
|
|
if(0 == res){
|
msleep(30);
|
res = setIOBoardState(TestTypeDischarge,true);
|
if(Uart_Driver::CommOK != res){
|
res = EXE_START_FAIL;
|
}
|
}
|
|
msleep(100);
|
|
rs485_Pack->unlock_RS485();
|
rs485_PowerCtrl->unlock_RS485();
|
|
if(packData.comm_certification_state != 2){
|
rs485_Pack->setCertificationPackEn();
|
}
|
else{
|
qDebug("discharge,comm_certification_state = 2.");
|
}
|
|
return res;
|
}
|
|
int Work_Thread::closeDischargePower()
|
{
|
#ifdef _debug_demo_
|
return 0;
|
#endif
|
|
//关闭放电
|
rs485_PowerCtrl->lock_RS485();
|
|
int res = setIOBoardState(TestTypeDischarge,false);
|
if(Uart_Driver::CommOK != res){
|
res = EXE_STOP_FAIL;
|
}
|
|
//opt mos
|
setMOS_AfterDischarge();
|
|
rs485_PowerCtrl->unlock_RS485();
|
|
return res;
|
}
|
|
int Work_Thread::startDischarge()
|
{
|
initTestState();
|
|
int res = openDischargePower();
|
|
testStateData.startState = res;
|
|
if(0 == res){
|
testStateData.workState = WORK_STATE_DISCHG;
|
testStateData.alarmState = ALARM_STATE_DISCHARGING;
|
}
|
|
return res;
|
}
|
|
int Work_Thread::stopDischarge(const quint8 stoptype)
|
{
|
SaveFbo_Data(true);
|
closeTestFbo_Data(stoptype);
|
|
int res = closeDischargePower();
|
|
testStateData.workState = WORK_STATE_STOPPED;
|
testStateData.alarmState = stoptype;
|
|
return res;
|
}
|
|
int Work_Thread::setMOS_BeforeCharge()
|
{
|
int res = 0;
|
|
if(PACK_TYPE_Halo == packParam.pack_type)
|
{
|
res = setDischgMos_Break();
|
msleep(20);
|
|
if(Uart_Driver::CommOK == res){
|
res = setPreChgMos_Close();
|
msleep(20);
|
}
|
|
if(Uart_Driver::CommOK == res){
|
res = setChargeMos_Close();
|
}
|
|
msleep(200);
|
|
if(Uart_Driver::CommOK == res){
|
quint16 premos = 0;
|
quint16 chgmos = 0;
|
quint16 dismos = 0;
|
|
for(quint8 t=0;t<10;t++){
|
msleep(100);
|
res = getMos_State(&premos, &chgmos, &dismos);
|
if(0==res){
|
qDebug("presmos = %d,chgmos = %d,dismos = %d",premos,chgmos,dismos);
|
if(1==premos && 1==chgmos && 0==dismos){
|
break;
|
}
|
else
|
res = RES_Error_MOS_State;
|
}
|
}
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setMOS_AfterCharge()
|
{
|
int res = 0;
|
|
if(PACK_TYPE_Halo == packParam.pack_type)
|
{
|
rs485_Pack->lock_RS485();
|
|
res = setChargeMos_Break();
|
|
msleep(100);
|
|
rs485_Pack->unlock_RS485();
|
}
|
|
return res;
|
}
|
|
int Work_Thread::openChargePower()
|
{
|
int res = 0;
|
|
#ifdef _debug_demo_
|
return res;
|
#endif
|
|
rs485_Pack->lock_RS485();
|
rs485_PowerCtrl->lock_RS485();
|
|
//start mos
|
res = setMOS_BeforeCharge();
|
if(Uart_Driver::CommOK != res){
|
if(res < -20){
|
res = EXE_MOS_STATE_ERR;
|
}
|
else
|
res = EXE_MOS_CTRL_FAIL;
|
}
|
|
if(0 == res){
|
res = setTestParam(TestTypeCharge);
|
|
if(Uart_Driver::CommOK != res){
|
res = EXE_SET_PARAM_FAIL;
|
}
|
}
|
|
if(0 == res){
|
msleep(30);
|
res = setIOBoardState(TestTypeCharge,true);
|
if(Uart_Driver::CommOK != res){
|
res = EXE_START_FAIL;
|
}
|
}
|
|
msleep(100);
|
|
rs485_Pack->unlock_RS485();
|
rs485_PowerCtrl->unlock_RS485();
|
|
return res;
|
}
|
|
int Work_Thread::closeChargePower()
|
{
|
|
#ifdef _debug_demo_
|
return 0;
|
#endif
|
|
rs485_PowerCtrl->lock_RS485();
|
|
int res = setIOBoardState(TestTypeCharge,false);
|
if(Uart_Driver::CommOK != res){
|
res = EXE_STOP_FAIL;
|
}
|
|
//opt mos
|
setMOS_AfterCharge();
|
|
rs485_PowerCtrl->unlock_RS485();
|
|
return res;
|
}
|
|
int Work_Thread::activePackByCharge()
|
{
|
#ifdef _debug_demo_
|
return 0;
|
#endif
|
|
if(modTestData.State > 0){
|
return 0;
|
}
|
|
rs485_PowerCtrl->lock_RS485();
|
|
CHARGE_PARAM_SET chgparamset;
|
|
chgparamset.Vchg = testParam.chgParam.sum_vol_high*10;
|
chgparamset.Ichg = 500;
|
chgparamset.Tchg = 1000; //ms when active
|
|
//设置充电参数
|
int res = 0;
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusMultiWrite(0x01, RegAddr_SetModChrParam, (quint16 *)&chgparamset,RegCount_SetModChrParam, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
|
if(0 == res){
|
msleep(30);
|
quint16 startchg = CMD_ActivePack; //active the pack
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusMultiWrite(0x01, RegAddr_Charge, (quint16 *)&startchg, 1, 200);
|
if(Uart_Driver::CommOK == res){
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
}
|
|
rs485_PowerCtrl->unlock_RS485();
|
|
return res;
|
}
|
|
int Work_Thread::startCharge()
|
{
|
initTestState();
|
|
int res = openChargePower();
|
|
testStateData.startState = res;
|
|
if(0 == res){
|
testStateData.workState = WORK_STATE_CHARGE;
|
testStateData.alarmState = ALARM_STATE_CHARGING;
|
}
|
|
return res;
|
}
|
|
int Work_Thread::stopCharge(const quint8 stoptype)
|
{
|
SaveFbo_Data(true);
|
closeTestFbo_Data(stoptype);
|
|
closeChargePower();
|
|
testStateData.workState = WORK_STATE_STOPPED;
|
testStateData.alarmState = stoptype;
|
|
return 0;
|
}
|
|
quint16 Work_Thread::getCellVolLowCount(const quint16 celllow)
|
{
|
quint16 cnt = 0;
|
|
/*
|
for(quint16 n=0;n<packData.cell_count;n++){
|
if(packData.cell_vol[n] <= celllow){
|
cnt++;
|
}
|
}
|
*/
|
|
if(packData.cell_vol_min<=celllow){
|
return 1;
|
}
|
|
return cnt;
|
}
|
|
quint16 Work_Thread::getCellVolHighCount(const quint16 cellhigh)
|
{
|
quint16 cnt = 0;
|
|
/*
|
for(quint16 n=0;n<packData.cell_count;n++){
|
if(packData.cell_vol[n] >= cellhigh){
|
cnt++;
|
}
|
}
|
*/
|
if(packData.cell_vol_max>=cellhigh){
|
return 1;
|
}
|
|
return cnt;
|
}
|
|
quint16 Work_Thread::getCellTempHighCount(const quint16 cellhigh)
|
{
|
quint16 cnt = 0;
|
|
/*
|
for(quint16 n=0;n<packData.temp_count;n++){
|
if(packData.cell_temp[n] >= cellhigh){
|
cnt++;
|
}
|
}
|
*/
|
|
if(packData.cell_tempe_max*10>=cellhigh){
|
return 1;
|
}
|
|
return cnt;
|
}
|
//=============================================================================================================
|
int Work_Thread::getAdjParamFromIOBoard()
|
{
|
quint16 databuff[8] = {0};
|
|
int res = 0;
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusRead(0x01, 0xB00E, 8, databuff, 300);
|
if(Uart_Driver::CommOK == res){
|
adjParamSet.Islope = Swap16(databuff[0]);
|
adjParamSet.Ioffset = Swap16(databuff[1]);
|
adjParamSet.Tslope = Swap16(databuff[2]);
|
adjParamSet.Toffset = Swap16(databuff[3]);
|
adjParamSet.Vslope = Swap16(databuff[4]);
|
adjParamSet.Voffset = Swap16(databuff[5]);
|
adjParamSet.Pslope = Swap16(databuff[6]);
|
adjParamSet.Poffset = Swap16(databuff[7]);
|
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setAdjParamToIOBoard(void)
|
{
|
int res = 0;
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusMultiWrite(0x01, 0xB00E, (quint16 *)&adjParamSet, 8, 200);
|
if(Uart_Driver::CommOK == res){
|
qDebug("setAdjParamToIOBoard success.");
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
|
return res;
|
}
|
|
void Work_Thread::saveAdjParam(ADJ_PARAM_SET ¶m)
|
{
|
//因采取的是多个校准参数同时下发,所以务必保证所有都正确,以避免将其它校准参数写偏
|
if( (param.Ioffset>-1000&¶m.Ioffset<1000&¶m.Islope>8000&¶m.Islope<12000)
|
&&(param.Toffset>-1000&¶m.Toffset<1000&¶m.Tslope>8000&¶m.Tslope<12000)
|
&&(param.Voffset>-1000&¶m.Voffset<1000&¶m.Vslope>8000&¶m.Vslope<12000)
|
&&(param.Poffset>-1000&¶m.Poffset<1000&¶m.Pslope>8000&¶m.Pslope<12000) ){
|
|
adjParamSet = param;
|
|
setWorkThreadCMD(CMD_SetAdjParamSet);
|
}
|
else{
|
qDebug("Adjust Param Err....");
|
}
|
|
}
|
|
//=============================================================================================================
|
int Work_Thread::getDropVolParamFromIOBoard()
|
{
|
quint16 databuff[1] = {0};
|
|
int res = 0;
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusRead(0x01, 0xB017, 1, databuff, 300);
|
if(Uart_Driver::CommOK == res){
|
volDropParam.dropVol = Swap16(databuff[0]);
|
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
|
return res;
|
}
|
|
int Work_Thread::setDropVolParamToIOBoard(void)
|
{
|
int res = 0;
|
for(quint8 t=0;t<3;t++){
|
res = rs485_PowerCtrl->ModBusMultiWrite(0x01, 0xB017, (quint16 *)&volDropParam, 1, 200);
|
if(Uart_Driver::CommOK == res){
|
qDebug("setDropVolParamToIOBoard success.");
|
break;
|
}
|
else{
|
msleep(100);
|
}
|
}
|
|
return res;
|
}
|
|
void Work_Thread::saveVolDropParam(VOL_DROP_PARAM ¶m)
|
{
|
//因采取的是多个参数同时下发,所以务必保证所有都正确,以避免将其它参数写偏
|
if(param.dropVol>=0 && param.dropVol<=2000 ){
|
|
volDropParam = param;
|
|
setWorkThreadCMD(CMD_SetVolDropParam);
|
}
|
else{
|
qDebug("Vol Drop Param Err....");
|
}
|
|
}
|
|
//=============================================================================================================
|
|
void Work_Thread::CheckIfStop()
|
{
|
//----------------------- 放电 -------------------------
|
if(WORK_STATE_DISCHG == testStateData.workState){
|
quint16 timsum = testStateData.testTime.hour*60 + testStateData.testTime.minute;
|
|
//-----------------------------------------------------------------
|
if(rs485_PowerCtrl->powerCtrlComm_OK == false){
|
stopDischarge(ALARM_STATE_ERR_COMM);
|
}
|
else if((packParam.pack_type!=PACK_TYPE_Other) && (rs485_Pack->packComm_OK==false)){
|
stopDischarge(ALARM_STATE_PACK_COMM_ERR);
|
}
|
//-----------------------------------------------------------------
|
else if(timsum >= testParam.disParam.dis_time)
|
{
|
stopDischarge(ALARM_STATE_DISTIMEOVER);
|
}
|
else if( (0==testParam.constvol_EN && modTestData.ADCVdc<=testParam.disParam.sum_vol_low)
|
|| (1==testParam.constvol_EN && modTestData.ADCVdc<=testParam.disParam.sum_vol_low && modTestData.ADCIdc<testParam.curr_end) )
|
{
|
stopDischarge(ALARM_STATE_SUMVOLLOW);
|
}
|
else if(testStateData.testCap >= testParam.disParam.dis_cap)
|
{
|
stopDischarge(ALARM_STATE_DISCAPOVER);
|
}
|
else if(getCellVolLowCount(testParam.disParam.cell_vol_low)>0 && packParam.pack_type!=PACK_TYPE_Other)
|
{
|
stopDischarge(ALARM_STATE_CELLVOLLOW);
|
}
|
else if(packData.soc <= testParam.disParam.dis_soc && packParam.pack_type!=PACK_TYPE_Other){
|
stopDischarge(ALARM_STATE_DISSOCOVER);
|
}
|
//--------------------------------------------------------------
|
else if(getCellTempHighCount(testParam.temp_high) > 0){
|
stopDischarge(ALARM_STATE_TEMPHIGH);
|
}
|
else if(packData.cell_diff_vol_max>=testParam.cell_vol_diff){
|
stopDischarge(ALARM_STATE_CELLVOLDIFF);
|
}
|
//--------------------------------------------------------------
|
else if(modTestData.ErrorStop & MOD_ERROR_VOL)
|
{
|
stopDischarge(ALARM_STATE_ERR_VOL);
|
}
|
else if(modTestData.ErrorStop & MOD_ERROR_PWRVOL)
|
{
|
stopDischarge(ALARM_STATE_ERR_VOL);
|
}
|
else if(modTestData.ErrorStop & MOD_ERROR_CURR)
|
{
|
stopDischarge(ALARM_STATE_ERR_CURR);
|
}
|
else if(modTestData.ErrorStop & MOD_ERROR_TEMP)
|
{
|
stopDischarge(ALARM_STATE_ERR_TEMP);
|
}
|
else if((~modTestData.State) & MOD_STATE_DIS)
|
{
|
stateWorkCount++;
|
if(stateWorkCount>=10)
|
stopDischarge(ALARM_STATE_ERR_INTSTOP);
|
}
|
//-----------------------------------------------------------
|
else if( (packData.bms_error_state > 0)
|
&& ((packData.error[0]&packParam.pack_errMask1)>0 || (packData.error[1]&packParam.pack_errMask2)>0) )
|
{
|
stopDischarge(ALARM_STATE_PACK_ERR);
|
}
|
//-----------------------------------------------------------
|
|
}
|
//----------------------- 充电 -------------------------
|
else if(WORK_STATE_CHARGE == testStateData.workState){
|
quint16 timsum = testStateData.testTime.hour*60 + testStateData.testTime.minute;
|
//-----------------------------------------------------------------
|
if(rs485_PowerCtrl->powerCtrlComm_OK == false){
|
stopCharge(ALARM_STATE_ERR_COMM);
|
}
|
else if((packParam.pack_type!=PACK_TYPE_Other) && (rs485_Pack->packComm_OK==false)){
|
stopCharge(ALARM_STATE_PACK_COMM_ERR);
|
}
|
//-----------------------------------------------------------------
|
else if(timsum >= testParam.chgParam.chg_time)
|
{
|
stopCharge(ALARM_STATE_CHRTIMEOVER);
|
}
|
else if( (0==testParam.constvol_EN && modTestData.ADCVdc>=testParam.chgParam.sum_vol_high)
|
|| (1==testParam.constvol_EN && modTestData.ADCVdc>=testParam.chgParam.sum_vol_high && modTestData.ADCIdc<testParam.curr_end) )
|
{
|
stopCharge(ALARM_STATE_SUMVOLHIGH);
|
}
|
else if(testStateData.testCap >= testParam.chgParam.chg_cap)
|
{
|
stopCharge(ALARM_STATE_CHRCAPOVER);
|
}
|
else if(getCellVolHighCount(testParam.chgParam.cell_vol_high)>0 && packParam.pack_type!=PACK_TYPE_Other)
|
{
|
stopCharge(ALARM_STATE_CELLVOLHIGH);
|
}
|
else if(packData.soc >= testParam.chgParam.chg_soc && packParam.pack_type!=PACK_TYPE_Other){
|
stopCharge(ALARM_STATE_CHGSOCOVER);
|
}
|
//--------------------------------------------------------------
|
else if(getCellTempHighCount(testParam.temp_high) > 0){
|
stopCharge(ALARM_STATE_TEMPHIGH);
|
}
|
else if(packData.cell_diff_vol_max>=testParam.cell_vol_diff){
|
stopCharge(ALARM_STATE_CELLVOLDIFF);
|
}
|
//--------------------------------------------------------------
|
else if(modTestData.ErrorStop & MOD_ERROR_VOL)
|
{
|
stopCharge(ALARM_STATE_ERR_VOL);
|
}
|
else if(modTestData.ErrorStop & MOD_ERROR_PWRVOL)
|
{
|
stopCharge(ALARM_STATE_ERR_VOL);
|
}
|
else if(modTestData.ErrorStop & MOD_ERROR_CURR)
|
{
|
stopCharge(ALARM_STATE_ERR_CURR);
|
}
|
else if(modTestData.ErrorStop & MOD_ERROR_TEMP)
|
{
|
stopCharge(ALARM_STATE_ERR_TEMP);
|
}
|
else if((~modTestData.State) & MOD_STATE_CHR)
|
{
|
stateWorkCount++;
|
if(stateWorkCount>=10)
|
stopCharge(ALARM_STATE_ERR_INTSTOP);
|
}
|
//-----------------------------------------------------------
|
else if( (packData.bms_error_state > 0)
|
&& ((packData.error[0]&packParam.pack_errMask1)>0 || (packData.error[1]&packParam.pack_errMask2)>0) )
|
{
|
stopCharge(ALARM_STATE_PACK_ERR);
|
}
|
//-----------------------------------------------------------
|
}
|
}
|
|
//=============================================================================================================
|
|
void Work_Thread::setWorkThreadCMD(int cmd)
|
{
|
if(CMD_Null == workThreadCMD){
|
workThreadCMD = cmd;
|
//qDebug("workThreadCMD = %d",workThreadCMD);
|
}
|
}
|
|
void Work_Thread::processWorkThreadCMD()
|
{
|
if(CMD_Null != workThreadCMD){
|
passthroughState.execing = 1;
|
}
|
|
if(CMD_StartTest == workThreadCMD){
|
if(TestTypeDischarge == testParam.test_type){
|
cmdExecResult = startDischarge();
|
if(EXE_RES_OK != cmdExecResult){
|
closeDischargePower();
|
}
|
}
|
else if(TestTypeCharge == testParam.test_type){
|
cmdExecResult = startCharge();
|
if(EXE_RES_OK != cmdExecResult){
|
closeChargePower();
|
}
|
}
|
}
|
else if(CMD_StopTest == workThreadCMD){
|
if(WORK_STATE_DISCHG == testStateData.workState){
|
stopDischarge(ALARM_STATE_STOPPED);
|
}
|
else if(WORK_STATE_CHARGE == testStateData.workState){
|
stopCharge(ALARM_STATE_STOPPED);
|
}
|
}
|
else if(CMD_SetTestParam == workThreadCMD){
|
if(testStateData.workState == WORK_STATE_DISCHG
|
|| adjWorkState == ADJ_STATE_DISCHARGE){
|
rs485_PowerCtrl->lock_RS485();
|
if(setTestParam(TestTypeDischarge) != 0){
|
//cmdExecResult = EXE_SET_PARAM_FAIL;
|
}
|
msleep(100);
|
rs485_PowerCtrl->unlock_RS485();
|
}
|
else if(testStateData.workState == WORK_STATE_CHARGE
|
|| adjWorkState == ADJ_STATE_CHARGE){
|
rs485_PowerCtrl->lock_RS485();
|
if(setTestParam(TestTypeCharge) != 0){
|
//cmdExecResult = EXE_SET_PARAM_FAIL;
|
}
|
msleep(100);
|
rs485_PowerCtrl->unlock_RS485();
|
}
|
}
|
else if(CMD_GetAdjParamSet == workThreadCMD){
|
rs485_PowerCtrl->lock_RS485();
|
if(getAdjParamFromIOBoard() != 0){
|
cmdExecResult = EXE_READ_ADJ_FAIL;
|
}
|
msleep(100);
|
rs485_PowerCtrl->unlock_RS485();
|
}
|
else if(CMD_SetAdjParamSet == workThreadCMD){
|
rs485_PowerCtrl->lock_RS485();
|
if(setAdjParamToIOBoard() != 0){
|
cmdExecResult = EXE_SET_ADJ_FAIL;
|
}
|
msleep(100);
|
rs485_PowerCtrl->unlock_RS485();
|
}
|
else if(CMD_AdjStartChr == workThreadCMD){
|
if(ADJ_STATE_STOPPED == adjWorkState){
|
cmdExecResult = openChargePower();
|
if(EXE_RES_OK != cmdExecResult){
|
closeChargePower();
|
}
|
else{
|
adjWorkState = ADJ_STATE_CHARGE;
|
}
|
}
|
}
|
else if(CMD_AdjStartDis == workThreadCMD){
|
if(ADJ_STATE_STOPPED == adjWorkState){
|
cmdExecResult = openDischargePower();
|
if(EXE_RES_OK != cmdExecResult){
|
closeDischargePower();
|
}
|
else{
|
adjWorkState = ADJ_STATE_DISCHARGE;
|
}
|
}
|
}
|
else if(CMD_AdjStopTest == workThreadCMD){
|
if(ADJ_STATE_DISCHARGE == adjWorkState){
|
closeDischargePower();
|
}
|
else if(ADJ_STATE_CHARGE == adjWorkState){
|
closeChargePower();
|
}
|
|
adjWorkState = ADJ_STATE_STOPPED;
|
}
|
else if(CMD_SetActivePack == workThreadCMD){
|
activePackByCharge();
|
}
|
else if(CMD_GetVolDropParam == workThreadCMD){
|
rs485_PowerCtrl->lock_RS485();
|
if(getDropVolParamFromIOBoard() != 0){
|
|
}
|
msleep(100);
|
rs485_PowerCtrl->unlock_RS485();
|
}
|
else if(CMD_SetVolDropParam == workThreadCMD){
|
rs485_PowerCtrl->lock_RS485();
|
if(setDropVolParamToIOBoard() != 0){
|
|
}
|
msleep(100);
|
rs485_PowerCtrl->unlock_RS485();
|
}
|
|
passthroughState.execing = 0;
|
|
if(CMD_Null != workThreadCMD){
|
qDebug("cmd exe err,errcode = %d",cmdExecResult);
|
emit sendCMD_Result(cmdExecResult);
|
}
|
|
cmdExecResult = 0;
|
workThreadCMD = CMD_Null;
|
}
|
|
//=============================================================================================================
|
|
void Work_Thread::run()
|
{
|
quint16 rate_ctrl = 0;
|
|
while(1){
|
msleep(50);
|
|
processWorkThreadCMD();
|
|
if(0 == (rate_ctrl%6)){
|
CheckIconState();
|
}
|
|
if(0 == (rate_ctrl%15)){
|
closePrechgMos();
|
}
|
|
if(1 == (rate_ctrl%10)){
|
SaveFbo_Data(false);
|
}
|
|
if(0 == (rate_ctrl%10)){
|
if(WORK_STATE_STOPPED != testStateData.workState){
|
quint32 secondsum =3600*testStateData.testTime.hour
|
+ 60*testStateData.testTime.minute
|
+ testStateData.testTime.second;
|
|
if(secondsum > 5){
|
#ifndef _debug_demo_
|
CheckIfStop();
|
#endif
|
}
|
}
|
else{
|
stateWorkCount = 0;
|
}
|
}
|
|
rate_ctrl++;
|
}
|
}
|