Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- takuma1
- Date:
- 2021-04-08
- Revision:
- 5:f07de56debf3
- Parent:
- 4:e57b023e41f3
File content as of revision 5:f07de56debf3:
#include "mbed.h" #include "bms.h" #include "LTC681x.h" #include "LTC6811.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 canSlave(p30,p29); I2C i2c(p28,p27); DigitalOut led2(LED2); DigitalOut BAT_MIN_safty(p21); DigitalOut BAT_MAX_safty(p22); //Timer timer; //書き込み時間を計測するタイマ // CAN関係 short int forSend = 0; //データ送信時に一時的に使用する変数 bool CANsendOK = 0; //CAN送信完了時,セットする(mainでのprintfのため) CANMessage msgSlave1; //CAN送信用 short int canSlaveID = 0x20; //canSlaveのIDをに設定 void Handler_canSend(); bool flag_can = 1; //測定関係の関数(変更の際触る必要がない) void run_command(uint32_t cmd); //測定コマンド送信関数 void measurement_loop(uint8_t datalog_en); 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();//ICの起動関数、消費電力削減関数 void cell_read();//セルの電圧の読み込みコマンド void spi_error();//SPIエラー処理関数 void ic_check();//ICが測定可能状態か診断して次のコマンドに持ち込むための関数 void spi_check();//SPIエラーの確認関数 void print_CAN(uint8_t datalog_en);//セルの電圧の表示コマンドと過充電過放電検出 void BAT_safty(); void print_math(); void can_sent1(); void can_sent2(); void can_sent3(); void can_sent4(); //void can_set(); void can_wait(); void ic_set(); const uint8_t TOTAL_IC = 3; //IC数 char ui_buffer[UI_BUFFER_SIZE]; const uint8_t ADC_CONVERSION_MODE = MD_7KHZ_3KHZ; const uint8_t ADC_DCP = DCP_DISABLED; const uint8_t CELL_CH_TO_CONVERT = CELL_CH_ALL; const uint8_t AUX_CH_TO_CONVERT = AUX_CH_ALL; const uint8_t STAT_CH_TO_CONVERT = STAT_CH_ALL; const uint16_t MEASUREMENT_LOOP_TIME = 10;//milliseconds(mS) const uint16_t OV_THRESHOLD = 41000; // const uint16_t UV_THRESHOLD = 30000; // const uint8_t WRITE_CONFIG = DISABLED; const uint8_t READ_CONFIG = DISABLED; const uint8_t MEASURE_CELL = ENABLED; const uint8_t MEASURE_AUX = DISABLED; const uint8_t MEASURE_STAT = DISABLED; const uint8_t PRINT_PEC = DISABLED; short n =0; uint8_t read_data(); float read_float(); INA226 VCmonitor(i2c); // INA226 int32_t read_int(); float BAT_MIN ; float BAT_MAX ; float BAT_AVG ; double BAT_C; float BAT_SUM; unsigned short BAT_CELL[23]; char *read_string(); /* int Replace1; int Replace2; int Replace3; int Replace4; */ int8_t read_char(); cell_asic bms_ic[TOTAL_IC]; void Handler_canSend() { int Replace1 = 0; int Replace2 = 0; int Replace3 = 0; short int Replace4 = 0; short n =0; int BAT_SUM = 0; // 0にする int BAT_MIN = 55876; double C; //unsigned short BTA_MAX = 0; for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) { for (int i=0; i < bms_ic[0].ic_reg.cell_channels; i++) { //pc.printf("C%d:", i+1); 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]; } } if(VCmonitor.getCurrent(&C) == 0){ // INA226 BAT_C = C; printf("C,%f\n",C); } } // BMA_SUM Replace1 = (int)(BAT_SUM / 100); msgSlave1.data[0] = Replace1 / 100; msgSlave1.data[1] = Replace1 % 100; //BAT_MIN Replace2 = (int)(BAT_MIN / 10); msgSlave1.data[2] = Replace2 / 100; msgSlave1.data[3] = Replace2 % 100; //BAT_MAX Replace3 = (int)(BAT_MAX /10); msgSlave1.data[4] = Replace3 / 100; msgSlave1.data[5] = Replace3 % 100; //BAT_C //short BAT_C = -233; if(BAT_C < 1000){ BAT_C = BAT_C + 9002; } if(BAT_C < 0){ //正電流か負電流を判定する BAT_C = BAT_C + 9001; //負だと正の電流に変更する。さらにモニタ側でマイナスに戻すための定数を9001とする //最大放電電流は50000mA 充電電流は-40000mAであるため9001とした。 } Replace4 = (short int)(BAT_C / 1); msgSlave1.data[6] = Replace4 / 100; msgSlave1.data[7] = Replace4 % 100; pc.printf("BAT_C %d\n",Replace4 ); printf("Data in msgSlave1.data[6] : %d\n\r", msgSlave1.data[6]); if(canSlave.write(msgSlave1)){ //格納したデータを送信する led1 = !led1; CANsendOK = 1; } ic_check(); } void Handler_canRecieve(){ //canMasterから送信要求が来たとき,データ送信するための関数 if( flag_can ){ if( canSlave.read( msgSlave1 ) ){ //msgに送られたデータが入る led2 = !led2; if( msgSlave1.id == canSlaveID ){ //IDがcanSlaveIDであれば処理する Handler_canSend(); } } } } int main(void) { uint32_t user_command; //short int BAT_C = 2322; pc.baud(115200); //printf("main()\n\r"); canSlave.attach(&Handler_canRecieve, CAN::RxIrq); //CAN受信割り込みの設定 msgSlave1.id = canSlaveID; //CAN送信側(slave)のIDを決定 msgSlave1.len = 8; //CAN送信側で送るデータのバイト数 while(1) { BAT_MIN = 0; BAT_MAX = 0; // 0にする /* if ( fp == NULL ) { pc.printf("USB fileopen!\r\n"); exit(1); } FILE *fp = fopen( "/usb/test.csv", "w"); //ファイルを開く "W"は新規作成して書き込みっていう命令? */ ic_check(); //timer.start(); //書き込み時間測定開始 //timer.stop(); //書き込み時間測定終了 //fclose(fp); //ファイルを閉じる if( CANsendOK ) { CANsendOK = 0; printf("Data in msgSlave1.data[0] : %d\n\r", msgSlave1.data[0]); //CANで送信したデータをそのまま表示 printf("Data in msgSlave1.data[1] : %d\n\r", msgSlave1.data[1]); //上に同じ printf("Data in msgSlave1.data[2] : %d\n\r", msgSlave1.data[2]); //上に同じ printf("Data in msgSlave1.data[3] : %d\n\r", msgSlave1.data[3]); printf("Data in msgSlave1.data[4] : %d\n\r", msgSlave1.data[4]); printf("Data in msgSlave1.data[5] : %d\n\r", msgSlave1.data[5]); printf("Data in msgSlave1.data[6] : %d\n\r", msgSlave1.data[6]); printf("Data in msgSlave1.data[7] : %d\n\r", msgSlave1.data[7]); //上に同じ printf("\n\r"); } BAT_safty(); } } /* void ic_set(){ // __disable_irq(); // flag_can = 0; ic_check(); spi_check(); spi_error(); wakeup(); cell_read(); } */ void ic_check(){ //1 //__disable_irq(); 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(); 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(); 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(); 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); } void print_CAN(uint8_t datalog_en){ /* __disable_irq(); short n =0; int BAT_SUM = 0; // 0にする int BAT_MIN = 55876; double C; //unsigned short BTA_MAX = 0; for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) { 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); 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]; } if(VCmonitor.getCurrent(&C) == 0){ // INA226 BAT_C = C; //printf("C,%f\n",C); } } } /* 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= bms_ic[current_ic].cells.c_codes[i]; //fprintf(fp,"C%d:", i+1); //fprintf(fp,"%.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]; } } //unsigned short BTA_MAX = 0; if( bms_ic[current_ic].cells.c_codes[i] > BAT_MAX){ BAT_MAX = bms_ic[current_ic].cells.c_codes[i]; } if(VCmonitor.getCurrent(&C) == 0){ // INA226 BAT_C = C; } } } fprintf(fp,"SUM"); fprintf(fp,"%0.4f, ",BAT_SUM*0.0001); BAT_AVG = BAT_SUM / 20; fprintf(fp,"AVG"); fprintf(fp,"%.4f, ",BAT_AVG*0.0001); fprintf(fp,"MIN"); fprintf(fp,"%.4f, ",BAT_MIN*0.0001); fprintf(fp,"MAX"); fprintf(fp,"%.4f, ",BAT_MAX*0.0001); fprintf(fp,"BAT_Current,%f\n",BAT_Current); */ } void BAT_safty(){ 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; } if(BAT_C > 60000){ BAT_MIN_safty = 1 ; wait(1); BAT_MIN_safty = 0 ; } } 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]); }