BMS_T2

Dependencies:   INA226

main.cpp

Committer:
takuma1
Date:
13 months ago
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]);
}