#include "work_thread.h" #include #include #include "unistd.h" #include #include #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"); 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"); connect(rs485_Pack,SIGNAL(sendPackDataSignal(PACK_DATA)),this,SLOT(RecvPackData(PACK_DATA))); initValueForParam(); alarmStateText<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;n0)?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=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=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= 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= 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.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.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++; } }