BMS_T1
Dependencies: INA226
main.cpp
- Committer:
- takuma1
- Date:
- 2020-10-13
- Revision:
- 3:61174d4de67d
- Parent:
- 2:3bbbe439ec11
File content as of revision 3:61174d4de67d:
#include "mbed.h" #include "bms.h" #include "LTC681x.h" #include "LTC6811.h" #include "CAN.h" #include "INA226.hpp" #define UI_BUFFER_SIZE 64 #define SERIAL_TERMINATOR '\n' #define ENABLED 1 #define DISABLED 0 #define DATALOG_ENABLED 1 #define DATALOG_DISABLED 0 DigitalOut led1(LED1); Serial pc(USBTX, USBRX); CAN can1(p9,p10); CAN can2(p30,p29); I2C i2c(p28,p27); DigitalOut BAT_MIN_safty(p21); DigitalOut BAT_MAX_safty(p22); INA226 VCmonitor(i2c); void run_command(uint32_t cmd); void measurement_loop(uint8_t datalog_en); //void print_menu(); void print_cells(uint8_t datalog_en); void print_open(); void print_aux(uint8_t datalog_en); void print_stat(); void print_config(); void print_rxconfig(); void print_pec(void); void serial_print_hex(uint8_t data); void check_error(int error); void wakeup(); void cell_read(); void spi_error(); void ic_check(); void spi_check(); void print_CAN(uint8_t datalog_en); void print_math(); void can_sent1(); void can_sent2(); void can_sent3(); void can_sent4(); //void can_set(); void can_wait(); void ic_set(); //char get_char(); //void read_config_data(uint8_t cfg_data[][6], uint8_t nIC); const uint8_t TOTAL_IC = 3;//!<number of ICs in the daisy chain char ui_buffer[UI_BUFFER_SIZE]; //ADC Command Configurations //const uint8_t ADC_OPT = ADC_OPT_DISABLED; // See LTC6811_daisy.h for Options const uint8_t ADC_CONVERSION_MODE = MD_7KHZ_3KHZ;//MD_7KHZ_3KHZ; //MD_26HZ_2KHZ;//MD_7KHZ_3KHZ; // See LTC6811_daisy.h for Options const uint8_t ADC_DCP = DCP_DISABLED; // See LTC6811_daisy.h for Options const uint8_t CELL_CH_TO_CONVERT = CELL_CH_ALL; // See LTC6811_daisy.h for Options const uint8_t AUX_CH_TO_CONVERT = AUX_CH_ALL; // See LTC6811_daisy.h for Options const uint8_t STAT_CH_TO_CONVERT = STAT_CH_ALL; // See LTC6811_daisy.h for Options const uint16_t MEASUREMENT_LOOP_TIME = 100;//milliseconds(mS) //Under Voltage and Over Voltage Thresholds const uint16_t OV_THRESHOLD = 41000; // const uint16_t UV_THRESHOLD = 30000; // //Loop Measurement Setup These Variables are ENABLED or DISABLED Remember ALL CAPS const uint8_t WRITE_CONFIG = DISABLED; // This is ENABLED or DISABLED const uint8_t READ_CONFIG = DISABLED; // This is ENABLED or DISABLED const uint8_t MEASURE_CELL = ENABLED; // This is ENABLED or DISABLED const uint8_t MEASURE_AUX = DISABLED; // This is ENABLED or DISABLED const uint8_t MEASURE_STAT = DISABLED; //This is ENABLED or DISABLED const uint8_t PRINT_PEC = DISABLED; //This is ENABLED or DISABLED short n =0; uint8_t read_data(); float read_float(); int32_t read_int(); int BAT_MIN, BAT_MAX, BAT_AVG; double BAT_Current; long BAT_SUM; unsigned short BAT_CELL[27]; char *read_string(); int8_t read_char(); cell_asic bms_ic[TOTAL_IC]; int main(void) { uint32_t user_command; pc.baud(115200); while(1) { BAT_MIN = 0; BAT_MAX = 0; // 0にする ic_set(); } } void ic_set(){ //__disable_irq(); ic_check(); spi_check(); spi_error(); wakeup(); cell_read(); } void ic_check(){ //1 //__disable_irq(); pc.baud(115200); spi_enable(); LTC681x_init_cfg(TOTAL_IC, bms_ic); LTC6811_reset_crc_count(TOTAL_IC,bms_ic); LTC6811_init_reg_limits(TOTAL_IC,bms_ic); wakeup_sleep(TOTAL_IC); LTC6811_wrcfg(TOTAL_IC,bms_ic); print_config(); //printf("1"); //spi_check(); } void spi_check(){ //2 __disable_irq(); int countup; int8_t error = 0; wakeup_sleep(TOTAL_IC); error = LTC6811_rdcfg(TOTAL_IC,bms_ic); check_error(error); print_rxconfig(); //printf("2"); //spi_error(); } void wakeup(){ //3 __disable_irq(); int countup; int8_t error = 0; uint32_t conv_time = 0; wakeup_sleep(TOTAL_IC); LTC6811_adcv(ADC_CONVERSION_MODE,ADC_DCP,CELL_CH_TO_CONVERT); conv_time = LTC6811_pollAdc(); //printf("3"); //cell_read(); } void spi_error(){ //__disable_irq(); int8_t error = 0; int countup; /* if(error = -1 ){ for(countup = 0; countup <= 2; countup++){ spi_check(); if(error =1){ break; } } } if(error = 1){ wakeup(); } */ //wakeup(); } void cell_read(){ //4 電圧読み取り __disable_irq(); int8_t error = 0; uint32_t conv_time = 0; int8_t readIC=0; wakeup_sleep(TOTAL_IC); error = LTC6811_rdcv(0, TOTAL_IC,bms_ic); check_error(error); //print_cells(DATALOG_DISABLED); print_CAN(DATALOG_DISABLED); //printf("4"); } void print_CAN(uint8_t datalog_en){ __disable_irq(); short n =0; int BAT_SUM = 0; // 0にする int BAT_MIN = 55876; double V,C; int BTA_MAX = 0; float tempC, sum, sum_2, ave, ave_2; int i, j, k, l; //平均化処理に使用 int r = 5; //平均する値の個数 for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) { //if (datalog_en == 0) { //pc.printf("IC%d, ", current_ic+1); //for(n = 0; n <= 12; n++){ for (int i=0; i < bms_ic[0].ic_reg.cell_channels; i++) { //BAT_CELL[n] = bms_ic[current_ic].cells.c_codes[i]; pc.printf("C%d:", i+1); pc.printf("%.4f, ",bms_ic[current_ic].cells.c_codes[i]*0.0001); BAT_SUM = bms_ic[current_ic].cells.c_codes[i] + BAT_SUM; if(bms_ic[current_ic].cells.c_codes[i] > 10000){ if(bms_ic[current_ic].cells.c_codes[i] < BAT_MIN){ BAT_MIN = bms_ic[current_ic].cells.c_codes[i]; } } if( bms_ic[current_ic].cells.c_codes[i] > BAT_MAX){ BAT_MAX = bms_ic[current_ic].cells.c_codes[i]; } /* //平均化処理 sum = 0; ave = 0; i = 0; for( i = 0; i < r; i++) { float temp = max.read_temp(); sum += temp; } ave = sum / r; printf("\n\rT: %f",ave ); max.deselect(); max_2.select_2(); //平均化処理 sum_2 = 0; ave_2 = 0; j = 0; for( j = 0; j < r; j++) { float temp_2 = max_2.read_temp_2(); sum_2 += temp_2; } ave_2 = sum_2 / r; printf("\n\rT: %f",ave_2 ); max.deselect(); max_2.deselect_2(); max.deselect(); max_2.deselect_2(); //BAT_Current = C; */ } } pc.printf("\n"); pc.printf("SUM"); pc.printf("%.4f, ",BAT_SUM*0.0001); BAT_AVG = BAT_SUM / 27; pc.printf("AVG"); pc.printf("%.4f, ",BAT_AVG*0.0001); pc.printf("MIN"); pc.printf("%.4f, ",BAT_MIN*0.0001); pc.printf("MAX"); pc.printf("%.4f, ",BAT_MAX*0.0001); //pc.printf("BAT_Current"); if((VCmonitor.getVoltage(&V) == 0) && (VCmonitor.getCurrent(&C) == 0)){ printf("V,%f,C,%f\n",V,C); BAT_Current = C; } pc.printf("%f, ",BAT_Current); pc.printf("\n"); pc.printf("\n"); printf("\n\rT: %f",ave ); pc.printf("\n"); printf("\n\rT: %f",ave_2 ); pc.printf("\n"); if( BAT_MIN < 25000 ){ BAT_MIN_safty = 1 ; wait(1); BAT_MIN_safty = 0 ; } if( BAT_MAX > 42000){ BAT_MAX_safty = 1; wait(1); BAT_MAX_safty = 0; } } /* void can_sent4(){ if(can1.write(CANMessage(271,&BAT_MAX2))){ pc.printf("10CANMessage:%d\n",BAT_MAX2); } if(can1.write(CANMessage(272,&BAT_MAX3))){ pc.printf("11CANMessage:%d\n",BAT_MAX3); } if(can1.write(CANMessage(273,&BAT_MAX4))){ pc.printf("12CANMessage:%d\n",BAT_MAX4); } }*/ /* void can_set(){ //NVIC_SetPriority(TIMER3_IRQn, 0); //printf("aaaaa"); BAT_SUM1 = 0; BAT_SUM2 = 0; BAT_SUM3 = 0; BAT_SUM4 = 0; BAT_MIN1 = 0; BAT_MIN2 = 0; BAT_MIN3 = 0; BAT_MIN4 = 0; BAT_MAX1 = 0; BAT_MAX2 = 0; BAT_MAX3 = 0; BAT_MAX4 = 0; BAT_Current1 = 0; BAT_Current2 = 0; int data1 = 0; //BAT_SUM int data2 = 0; int data3 = 0; //BAT_MAX int data4 = 0; //BAT_Current BAT_SUM = data1; data2 = BAT_MIN; data3 = BAT_MAX; data4 = BAT_Current; BAT_SUM1 = data1 / 1000; //114 BAT_SUM2 = data1 % 1000; //755 BAT_SUM3 = BAT_SUM2 / 10; //75 BAT_SUM4 = BAT_SUM2 % 10; // 5 BAT_MIN1 = data2 / 1000; BAT_MIN2 = data2 % 1000; BAT_MIN3 = BAT_MIN2 / 10; BAT_MIN4 = BAT_MIN2 % 10; BAT_MAX = data3 / 1000; BAT_MAX2 = data3 % 1000; BAT_MAX3 = BAT_MAX2 / 10; BAT_MAX4 = BAT_MAX2 % 10; BAT_Current1 = data4 / 100; BAT_Current2 = data4 % 100; printf("can_set\n"); printf("aaaa%f",BAT_SUM); } */ void measurement_loop(uint8_t datalog_en) { int8_t error = 0; if (WRITE_CONFIG == ENABLED) { wakeup_sleep(TOTAL_IC); LTC6811_wrcfg(TOTAL_IC,bms_ic); print_config(); } if (READ_CONFIG == ENABLED) { wakeup_sleep(TOTAL_IC); error = LTC6811_rdcfg(TOTAL_IC,bms_ic); check_error(error); print_rxconfig(); } if (MEASURE_CELL == ENABLED) { wakeup_idle(TOTAL_IC); LTC6811_adcv(ADC_CONVERSION_MODE,ADC_DCP,CELL_CH_TO_CONVERT); LTC6811_pollAdc(); wakeup_idle(TOTAL_IC); error = LTC6811_rdcv(0, TOTAL_IC,bms_ic); check_error(error); print_cells(datalog_en); } if (MEASURE_AUX == ENABLED) { wakeup_idle(TOTAL_IC); LTC6811_adax(ADC_CONVERSION_MODE , AUX_CH_ALL); LTC6811_pollAdc(); wakeup_idle(TOTAL_IC); error = LTC6811_rdaux(0,TOTAL_IC,bms_ic); // Set to read back all aux registers check_error(error); print_aux(datalog_en); } if (MEASURE_STAT == ENABLED) { wakeup_idle(TOTAL_IC); LTC6811_adstat(ADC_CONVERSION_MODE, STAT_CH_ALL); LTC6811_pollAdc(); wakeup_idle(TOTAL_IC); error = LTC6811_rdstat(0,TOTAL_IC,bms_ic); // Set to read back all aux registers check_error(error); print_stat(); } if (PRINT_PEC == ENABLED) { print_pec(); } } void print_cells(uint8_t datalog_en) { for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) { if (datalog_en == 0) { pc.printf("IC%d, ", current_ic+1); for (int i=0; i < bms_ic[0].ic_reg.cell_channels; i++) { pc.printf("C%d:", i+1); pc.printf("%.4f, ", bms_ic[current_ic].cells.c_codes[i]*0.0001); } pc.printf("\n"); } else { pc.printf("Cells, "); for (int i=0; i<bms_ic[0].ic_reg.cell_channels; i++) { pc.printf("%.4f, ",bms_ic[current_ic].cells.c_codes[i]*0.0001); } } } pc.printf("\n"); } void print_open() { for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++) { if (bms_ic[current_ic].system_open_wire == 0) { pc.printf("No Opens Detected on IC%d\n", current_ic+1); } else { for (int cell=0; cell<bms_ic[0].ic_reg.cell_channels+1; cell++) { if ((bms_ic[current_ic].system_open_wire &(1<<cell))>0) { pc.printf("There is an open wire on IC%d Channel: %d\n", current_ic + 1, cell); } } } } } void print_aux(uint8_t datalog_en) { for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++) { if (datalog_en == 0) { pc.printf(" IC%d", current_ic+1); for (int i=0; i < 5; i++) { pc.printf(" GPIO-%d:%.4f,", i+1, bms_ic[current_ic].aux.a_codes[i]*0.0001); } pc.printf("Vref2:%.4f\n", bms_ic[current_ic].aux.a_codes[5]*0.0001); } else { pc.printf("AUX, "); for (int i=0; i < 6; i++) { pc.printf("%.4f,", bms_ic[current_ic].aux.a_codes[i]*0.0001); } } } pc.printf("\n"); } void print_stat() { for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++) { pc.printf("IC%d", current_ic+1); pc.printf(" SOC:%.4f,", bms_ic[current_ic].stat.stat_codes[0]*0.0001*20); pc.printf(" Itemp:%.4f,", bms_ic[current_ic].stat.stat_codes[1]*0.0001); pc.printf(" VregA:%.4f,", bms_ic[current_ic].stat.stat_codes[2]*0.0001); pc.printf(" VregD:%.4f\n", bms_ic[current_ic].stat.stat_codes[3]*0.0001); } pc.printf("\n"); } void print_config() { int cfg_pec; //pc.printf("Written Configuration: \n"); for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++) { //pc.printf(" IC "); //pc.printf("%d", current_ic+1); // pc.printf(": "); //pc.printf("0x"); serial_print_hex(bms_ic[current_ic].config.tx_data[0]); // pc.printf(", 0x"); serial_print_hex(bms_ic[current_ic].config.tx_data[1]); //pc.printf(", 0x"); serial_print_hex(bms_ic[current_ic].config.tx_data[2]); //pc.printf(", 0x"); serial_print_hex(bms_ic[current_ic].config.tx_data[3]); // pc.printf(", 0x"); serial_print_hex(bms_ic[current_ic].config.tx_data[4]); // pc.printf(", 0x"); serial_print_hex(bms_ic[current_ic].config.tx_data[5]); //pc.printf(", Calculated PEC: 0x"); cfg_pec = pec15_calc(6,&bms_ic[current_ic].config.tx_data[0]); serial_print_hex((uint8_t)(cfg_pec>>8)); //pc.printf(", 0x"); serial_print_hex((uint8_t)(cfg_pec)); // pc.printf("\n"); } // pc.printf("\n"); } void print_rxconfig() { //pc.printf("Received Configuration "); for (int current_ic=0; current_ic<TOTAL_IC; current_ic++) { // pc.printf(" IC "); // pc.printf("%d", current_ic+1); //pc.printf(": 0x"); serial_print_hex(bms_ic[current_ic].config.rx_data[0]); //pc.printf(", 0x"); serial_print_hex(bms_ic[current_ic].config.rx_data[1]); //pc.printf(", 0x"); serial_print_hex(bms_ic[current_ic].config.rx_data[2]); //pc.printf(", 0x"); serial_print_hex(bms_ic[current_ic].config.rx_data[3]); //pc.printf(", 0x"); serial_print_hex(bms_ic[current_ic].config.rx_data[4]); // pc.printf(", 0x"); serial_print_hex(bms_ic[current_ic].config.rx_data[5]); //pc.printf(", Received PEC: 0x"); serial_print_hex(bms_ic[current_ic].config.rx_data[6]); //pc.printf(", 0x"); serial_print_hex(bms_ic[current_ic].config.rx_data[7]); // pc.printf("\n"); } pc.printf("\n"); } void print_pec() { for (int current_ic=0; current_ic<TOTAL_IC; current_ic++) { pc.printf("\n%d", bms_ic[current_ic].crc_count.pec_count); pc.printf(" : PEC Errors Detected on IC"); pc.printf("%d\n", current_ic+1); } } void serial_print_hex(uint8_t data) { /* if (data < 16) { //pc.printf("0x0%X", data); } else pc.printf("0x%X", data); */ } //Function to check error flag and print PEC error message void check_error(int error) { if (error == -1) { pc.printf("A PEC error was detected in the received data"); } } char hex_digits[16]= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; char hex_to_byte_buffer[5]= { '0', 'x', '0', '0', '\0' }; // buffer for ASCII hex to byte conversion char byte_to_hex_buffer[3]= { '\0','\0','\0' }; // シリアル インターフェイスから ui_バッファへのデータの読み取り uint8_t read_data() { uint8_t index = 0; // 内の現在の場所を保持するインデックス int c; // 着信キーストロークの格納に使用される単一の文字 //pc.printf("check 1\n"); while (index < UI_BUFFER_SIZE-1) { //pc.printf("check 2\n"); c = pc.getc(); //return c; //pc.printf("check 3\n"); if (((char) c == '\r') || ((char) c == '\n')) break; if ( ((char) c == '\x7F') || ((char) c == '\x08') ) { if (index > 0) index--; } else if (c >= 0) { ui_buffer[index++]=(char) c; } //pc.printf("check 4\n"); } ui_buffer[index]='\0'; if ((char) c == '\r') { wait_ms(1); //pc.printf("check 5\n"); if (pc.readable()==1) { //pc.printf("check 6\n"); pc.getc(); } } return index; } float read_float() { float data; read_data(); data = atof(ui_buffer); return(data); } int32_t read_int() { int32_t data; read_data(); if (ui_buffer[0] == 'm') return('m'); if ((ui_buffer[0] == 'B') || (ui_buffer[0] == 'b')) { data = strtol(ui_buffer+1, NULL, 2); } else data = strtol(ui_buffer, NULL, 0); return(data); } char *read_string() { read_data(); return(ui_buffer); } int8_t read_char() { read_data(); return(ui_buffer[0]); }