![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
all bms comunicating with nucleo board and balancing
Dependencies: CANnucleo LTC68041 mbed
Fork of BMS_2 by
main.cpp
- Committer:
- Crazyaboutmachines
- Date:
- 2016-12-07
- Revision:
- 49:94a58ef0edc4
- Parent:
- 48:ddb7570eb4d7
- Child:
- 50:3cc0ad385612
File content as of revision 49:94a58ef0edc4:
#include "CANnucleo.h" #include "mbed.h" #include "LTC68041.h" uint8_t const TOTAL_IC = 1;//!<number of ICs in the daisy chain uint8_t rx_cfg[TOTAL_IC][8]; uint8_t tx_cfg[TOTAL_IC][6]; uint16_t aux_codes[TOTAL_IC][6]; uint16_t cell_codes[TOTAL_IC][12]; //uint16_t temp_codes[32]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}; float temp_codes[32]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}; volatile bool msgAvailable = false; volatile bool to_send = false; CANnucleo::CAN can(PA_11, PA_12); // CAN Rx pin name, CAN Tx pin name CANnucleo::CANMessage rxMsg; CANnucleo::CANMessage txMsg; DigitalOut led(PA_5); /*!*********************************** \brief Initializes the configuration array **************************************/ void init_cfg() { for (int i = 0; i<TOTAL_IC; i++) { tx_cfg[i][0] = 0xFE; tx_cfg[i][1] = 0x00 ; tx_cfg[i][2] = 0x00 ; tx_cfg[i][3] = 0x00 ; tx_cfg[i][4] = 0x00 ; tx_cfg[i][5] = 0x00 ; } } void serial_print_hex(uint8_t data) { if (data< 16) { printf("0"); printf("%x",(uint8_t)data); } else printf("%x",(uint8_t)data); } void print_config() { int cfg_pec; printf("Written Configuration:\n\r "); for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++) { printf(" IC "); printf("%d", current_ic+1); printf(": "); printf("0x"); serial_print_hex(tx_cfg[current_ic][0]); printf(", 0x"); serial_print_hex(tx_cfg[current_ic][1]); printf(", 0x"); serial_print_hex(tx_cfg[current_ic][2]); printf(", 0x"); serial_print_hex(tx_cfg[current_ic][3]); printf(", 0x"); serial_print_hex(tx_cfg[current_ic][4]); printf(", 0x"); serial_print_hex(tx_cfg[current_ic][5]); printf(", Calculated PEC: 0x"); cfg_pec = pec15_calc(6,&tx_cfg[current_ic][0]); serial_print_hex((uint8_t)(cfg_pec>>8)); printf(", 0x"); serial_print_hex((uint8_t)(cfg_pec)); } printf("\n\r"); } void print_rxconfig() { printf("Received Configuration "); for (int current_ic=0; current_ic<TOTAL_IC; current_ic++) { printf(" IC "); printf("%d " ,current_ic+1); printf(": 0x"); serial_print_hex(rx_cfg[current_ic][0]); printf(", 0x"); serial_print_hex(rx_cfg[current_ic][1]); printf(", 0x"); serial_print_hex(rx_cfg[current_ic][2]); printf(", 0x"); serial_print_hex(rx_cfg[current_ic][3]); printf(", 0x"); serial_print_hex(rx_cfg[current_ic][4]); printf(", 0x"); serial_print_hex(rx_cfg[current_ic][5]); printf(", Received PEC: 0x"); serial_print_hex(rx_cfg[current_ic][6]); printf(", 0x"); serial_print_hex(rx_cfg[current_ic][7]); } } int err; void print_cells2() { for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) { for (int i=0; i<12; i++) { printf(" C"); printf("%d",i+1); printf(":"); printf("%f", cell_codes[current_ic][i]*0.0001); printf(","); } } } void pec_error() { for(int i = 0; i<5; i++) { led = 1; wait(0.2); led=0; wait(0.2); } } char cells_left=0; char temps_left=0; Ticker ticker; Ticker sender; typedef union can_union { int i[2]; char bytes[8]; float f[2]; } data; /* void message_trigger() { if(cells_left < 1) { sender.detach(); } else { to_send = 1; } } */ void message_trigger() { if((cells_left < 1)&&(temps_left < 1)) { sender.detach(); } else { to_send = 1; } } void check_charging_voltage() { wakeup_idle(); LTC6804_adcv(); wait_ms(10); wakeup_idle(); err = LTC6804_rdcv(0, TOTAL_IC,cell_codes); if (err == -1) { pec_error(); } cells_left = 12; for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) { for (int i=0; i<12; i++) { if(cell_codes[current_ic][i]*0.0001 > 4.07) { //liga balanceamento switch (i) { case 0: //cell 1 tx_cfg[0][4] = tx_cfg[0][4] | 0x01 ; // 00000001 case 1: //cell 2 tx_cfg[0][4] = tx_cfg[0][4] | 0x02 ; // 00000010 case 2: //cell 3 tx_cfg[0][4] = tx_cfg[0][4] | 0x04 ; // 00000100 case 3: //cell 4 tx_cfg[0][4] = tx_cfg[0][4] | 0x08 ; // 00001000 case 4: //cell 5 tx_cfg[0][4] = tx_cfg[0][4] | 0x10 ; // 00010000 case 6: //cell 7 tx_cfg[0][4] = tx_cfg[0][4] | 0x40 ; // 01000000 case 7: //cell 8 tx_cfg[0][4] = tx_cfg[0][4] | 0x80 ; // 10000000 case 8: //cell 9 tx_cfg[0][5] = tx_cfg[0][5] | 0x01; // 00000001 case 9: //cell 10 tx_cfg[0][5] = tx_cfg[0][5] | 0x02; // 00000010 } } else { switch (i) { case 0: //cell 1 tx_cfg[0][4] = tx_cfg[0][4] & 0xFE ; // 11111110 case 1: //cell 2 tx_cfg[0][4] = tx_cfg[0][4] & 0xFD ; // 11111101 case 2: //cell 3 tx_cfg[0][4] = tx_cfg[0][4] & 0xFB ; // 11111011 case 3: //cell 4 tx_cfg[0][4] = tx_cfg[0][4] & 0xF7 ; // 11110111 case 4: //cell 5 tx_cfg[0][4] = tx_cfg[0][4] & 0xEF ; // 11101111 case 6: //cell 7 tx_cfg[0][4] = tx_cfg[0][4] & 0xBF ; // 10111111 case 7: //cell 8 tx_cfg[0][4] = tx_cfg[0][4] & 0x7F ; // 01111111 case 8: //cell 9 tx_cfg[0][5] = tx_cfg[0][5] & 0xFE; // 11111110 case 9: //cell 10 tx_cfg[0][5] = tx_cfg[0][5] & 0xFD; // 11111101 } } } } //print_cells2(); LTC6804_wrcfg(TOTAL_IC,tx_cfg); } void check_discharging_voltage() { wakeup_idle(); LTC6804_adcv(); wait_ms(10); wakeup_idle(); err = LTC6804_rdcv(0, TOTAL_IC,cell_codes); if (err == -1) { pec_error(); }/* for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) { for (int i=0; i<11; i++) { //printf("%f\t", cell_codes[current_ic][i]*0.0001); if(cell_codes[current_ic][i]*0.0001 < 2.7) { txMsg.clear(); txMsg.id = 1; printf("%f\t", cell_codes[current_ic][i]*0.0001); txMsg << cell_codes[current_ic][i]*0.0001; can.write(txMsg); wait(0.1); } } }*/ //print_cells2(); cells_left = 12; tx_cfg[0][4] = tx_cfg[0][4] & 0b00000000; //para desactivar balanceamento durante a descarga tx_cfg[0][5] = tx_cfg[0][5] & 0b11110000; //print_cells2(); LTC6804_wrcfg(TOTAL_IC,tx_cfg); } AnalogIn MUXA_Read(PC_1); DigitalOut MUXA_0(PB_10); DigitalOut MUXA_1(PB_2); DigitalOut MUXA_2(PB_0); DigitalOut MUXA_3(PB_1); AnalogIn MUXB_Read(PC_2); DigitalOut MUXB_0(PC_7); DigitalOut MUXB_1(PC_6); DigitalOut MUXB_2(PB_14); DigitalOut MUXB_3(PB_15); /* void check_temperatures() { int i=14; MUXA_3=0; MUXA_2=0; MUXA_1=0; MUXA_0=1; //(escolha do NTC on board) temp_codes[i]= MUXA_Read.read()*3300; temps_left = 32; } */ void alarm(char alarm_code){ txMsg.clear(); txMsg.id = 8; //BMS1=>ID:11; BMS2=>ID:12; BMS3=>ID:13. txMsg.len = 1; txMsg.data[0] = alarm_code; //alarm_code if(!(can.write(txMsg))) { //se nao conseguiu transmitir continua a tentar transmitir a tensão dessa celula pec_error(); } } float temp; void check_temperatures() { for (int i=0; i<32; i++){ switch (i) { case 0: //ntc 1 //from MUXA MUXA_3=0; MUXA_2=0; MUXA_1=0; MUXA_0=0; break; case 1: //ntc 2 MUXA_3=0; MUXA_2=0; MUXA_1=0; MUXA_0=1; break; case 2: //ntc 3 MUXA_3=0; MUXA_2=0; MUXA_1=1; MUXA_0=0; break; case 3: //ntc 4 MUXA_3=0; MUXA_2=0; MUXA_1=1; MUXA_0=1; break; case 4: //ntc 5 MUXA_3=0; MUXA_2=1; MUXA_1=0; MUXA_0=0; break; case 5: //ntc 6 MUXA_3=0; MUXA_2=1; MUXA_1=0; MUXA_0=1; break; case 6: //ntc 7 MUXA_3=0; MUXA_2=1; MUXA_1=1; MUXA_0=0; break; case 7: //ntc 8 MUXA_3=0; MUXA_2=1; MUXA_1=1; MUXA_0=1; break; case 8: //ntc 9 MUXA_3=1; MUXA_2=0; MUXA_1=0; MUXA_0=0; break; case 9: //ntc 10 MUXA_3=1; MUXA_2=0; MUXA_1=0; MUXA_0=1; break; case 10: //ntc 11 MUXA_3=1; MUXA_2=0; MUXA_1=1; MUXA_0=0; break; case 11: //ntc 12 MUXA_3=1; MUXA_2=0; MUXA_1=1; MUXA_0=1; break; case 12: //ntc 13 MUXA_3=1; MUXA_2=1; MUXA_1=0; MUXA_0=0; break; case 13: //ntc 14 MUXA_3=1; MUXA_2=1; MUXA_1=0; MUXA_0=1; break; case 14: //ntc 15 MUXA_3=1; MUXA_2=1; MUXA_1=1; MUXA_0=0; break; case 15: //ntc 16 MUXA_3=1; MUXA_2=1; MUXA_1=1; MUXA_0=1; break; case 16: //ntc 17 //from MUXB MUXB_3=0; MUXB_2=0; MUXB_1=0; MUXB_0=0; break; case 17: //ntc 18 MUXB_3=0; MUXB_2=0; MUXB_1=0; MUXB_0=1; break; case 18: //ntc 19 MUXB_3=0; MUXB_2=0; MUXB_1=1; MUXB_0=0; break; case 19: //ntc 20 MUXB_3=0; MUXB_2=0; MUXB_1=1; MUXB_0=1; break; case 20: //ntc 21 MUXB_3=0; MUXB_2=1; MUXB_1=0; MUXB_0=0; break; case 21: //ntc 22 MUXB_3=0; MUXB_2=1; MUXB_1=0; MUXB_0=1; break; case 22: //ntc 23 MUXB_3=0; MUXB_2=1; MUXB_1=1; MUXB_0=0; break; case 23: //ntc 24 MUXB_3=0; MUXB_2=1; MUXB_1=1; MUXB_0=1; break; case 24: //ntc 25 MUXB_3=1; MUXB_2=0; MUXB_1=0; MUXB_0=0; break; case 25: //ntc 26 MUXB_3=1; MUXB_2=0; MUXB_1=0; MUXB_0=1; break; case 26: //ntc 27 MUXB_3=1; MUXB_2=0; MUXB_1=1; MUXB_0=0; break; case 27: //ntc 28 MUXB_3=1; MUXB_2=0; MUXB_1=1; MUXB_0=1; break; case 28: //ntc 29 MUXB_3=1; MUXB_2=1; MUXB_1=0; MUXB_0=0; break; case 29: //ntc 30 MUXB_3=1; MUXB_2=1; MUXB_1=0; MUXB_0=1; break; case 30: //ntc 31 MUXB_3=1; MUXB_2=1; MUXB_1=1; MUXB_0=0; break; case 31: //ntc 32 MUXB_3=1; MUXB_2=1; MUXB_1=1; MUXB_0=1; break; } wait_ms(100); //tempo para a tensao á saida do mux estabilisar if(i<16){ // Converts and read the analog input value (value from 0.0 to 1.0) temp_codes[i] = MUXA_Read.read()*3300; }else{ temp_codes[i] = MUXB_Read.read()*3300; } temp=temp_codes[i]/1000; temp=(temp*10000)/(3.3-temp); temp = 3380/log(temp/0.119228); temp_codes[i] = temp-273.15; // //-------------------------- // if(i==0||i==1||i==2||i==3||i==4||i==5||i==6||i==7||i==8||i==9||i==10||i==11||i==14||i==30){ // if(temp_codes[i]>23){ // // if(temp_codes[i]>30||temp_codes[i]<-20){ // //disable interrupts // alarm();//temperature alarm // //enable interrupts // } // } // //-------------------------- } temps_left = 32; } void onMsgReceived() { msgAvailable = true; } bool to_charge_or_not_to_charge=false; // false = discharge bool charging = false; bool discharging = false; void monitor() { led = !led; if(to_charge_or_not_to_charge) { charging = 1; discharging = 0; } else { discharging = 1; charging = 0; } } uint8_t motostate=0; int main() { data data; //printf("starting\n\r"); led =1; wait(1); pec_error(); to_charge_or_not_to_charge=0; charging = 0; discharging = 1; ticker.attach(&monitor, 3); LTC6804_initialize(); init_cfg(); //write configuration wakeup_sleep(); __disable_irq(); // Disable Interrupts LTC6804_wrcfg(TOTAL_IC,tx_cfg); __enable_irq(); wait(1); //read configuration: may differ from written config wakeup_sleep(); __disable_irq(); err = LTC6804_rdcfg(TOTAL_IC,rx_cfg); __enable_irq(); if (err == -1) { pec_error(); } wait(0.5); wakeup_idle(); __disable_irq(); LTC6804_adcv(); __enable_irq(); wait_ms(10); wakeup_idle(); __disable_irq(); err = LTC6804_rdcv(0, TOTAL_IC,cell_codes); __enable_irq(); if (err == -1) { pec_error(); } can.frequency(1000000); // set bit rate to 1Mbps can.attach(&onMsgReceived); //print_cells2(); while(1) { if(charging) { charging = 0; check_charging_voltage(); check_temperatures(); sender.attach(&message_trigger,0.1); } if(discharging) { discharging = 0; check_discharging_voltage(); check_temperatures(); sender.attach(&message_trigger,0.1); } if(to_send) { to_send=0; //-----------------1º send cell voltages //------------------------------ if(cells_left>0){ if(cells_left==1||cells_left==2||cells_left==3||cells_left==4||cells_left==5||cells_left==7||cells_left==8||cells_left==9||cells_left==10){ if(cell_codes[0][cells_left-1]<30000||cell_codes[0][cells_left-1]>42000){ // if(cell_codes[0][cells_left-1]<0||cell_codes[0][cells_left-1]>70000){ //for debug __disable_irq(); // Disable Interrupts alarm('v'); __enable_irq(); } } //------------------------------ txMsg.clear(); txMsg.id = 13; //BMS1=>ID:11; BMS2=>ID:12; BMS3=>ID:13. txMsg.len = 5; data.f[0] = cell_codes[0][cells_left-1]*0.0001; txMsg.data[0] = data.bytes[0]; txMsg.data[1] = data.bytes[1]; txMsg.data[2] = data.bytes[2]; txMsg.data[3] = data.bytes[3]; txMsg.data[4] = cells_left; cells_left--; if(!(can.write(txMsg))) { //se nao conseguiu transmitir continua a tentar transmitir a tensão dessa celula pec_error(); cells_left++; //to_send=1; } } //-----------------2º send cell temperatures // wait_ms(200); falha se houver aqui um delay deste tamanho if(temps_left>0){ //------------------------------ if(temps_left==1||temps_left==2||temps_left==3||temps_left==4||temps_left==5|| temps_left==6||temps_left==7||temps_left==8||temps_left==9||temps_left==10|| temps_left==11||temps_left==12||temps_left==15||temps_left==31){ if(temp_codes[temps_left-1]>65||temp_codes[temps_left-1]<-20){ //4-49(ambiente) //if(temp_codes[temps_left-1]>25||temp_codes[temps_left-1]<-300){ //for debug // if(temp_codes[i]>30||temp_codes[i]<-20){ __disable_irq(); // Disable Interrupts alarm('t'); //temperature alarm __enable_irq(); } } //------------------------------ txMsg.clear(); txMsg.id = 23; //BMS1=>ID:21; BMS2=>ID:22; BMS3=>ID:23. txMsg.len = 5; data.f[0] = temp_codes[temps_left-1]; // data.f[0] = temp_codes[14]; txMsg.data[0] = data.bytes[0]; txMsg.data[1] = data.bytes[1]; txMsg.data[2] = data.bytes[2]; txMsg.data[3] = data.bytes[3]; txMsg.data[4] = temps_left; temps_left--; if(!(can.write(txMsg))) { //se nao conseguiu transmitir continua a tentar transmitir a tensão dessa celula pec_error(); temps_left++; //to_send=1; } } } if(msgAvailable) { int len = can.read(rxMsg); if(rxMsg.id==9){ motostate = rxMsg.data[0]; //motostate: (0|0|0|0|0|0|to_charge_or_not_to_charge|key_switch) to_charge_or_not_to_charge=((motostate & 0b00000010)>>1); msgAvailable = false; } } } }