Code to run on the charger board (used to charge the car from the mains).

Dependencies:   mbed CUER_CAN

charger.cpp

Committer:
drajan
Date:
2017-05-06
Revision:
0:6d930d0d13a1
Child:
1:0c77e20b4d4c

File content as of revision 0:6d930d0d13a1:

#include "charger.h"


void get_charger_data(void) {
    //Updates charger data
    
    //for now, before the CAN communication is set up, arbitrary values are set.
    voltage_error = 0.1; //received function is in mV. Must be divided by 1000 so that this value is in V.
    temp_margin = 5; //multiply received temp_margin by 10 to get answer in Celcius.
    discharge_error = 0.1; //divide received value by 1000 to get value in V
    chrg_status_recv_time = chargerboard_timer.read_ms();
    charger_current; 
    charger_voltage;
    
    }
    
void get_voltage_data(void){
    
    //Updates Voltage Data
    min_cell_voltage = 1; //divide received value by 1000 to get value in V
    max_cell_voltage = 5;//divide received value by 1000 to get value in V
    
    bms_minmax_cell_volts_recv_time = chargerboard_timer.read_ms();
    
    }
    
void get_bms_data(void){
    //Updates BMS data
    rising_voltage_threshold; //(V)
    falling_voltage_threshold; //(V)
    bms_status;
    
    bms_pack_status_recv_time = chargerboard_timer.read_ms();
    
    }

void calculate_current(float voltage_error, float temp_margin, float *current, float *voltage){
        
        float Idot, I;
        static bool balancing = false;
         I = *current;
         if (I < 0.8 && voltage_error < 0.1 || balancing) {
                balancing = true;
                printf("balancing\r\n");
                Idot = voltage_error*KI_BALANCE;
            } else {
                    Idot = voltage_error*KI_CHARGE;
                }
    I += Idot*TIME_STEP/1000.0;

    if(I > MAX_CURRENT) {
        I = MAX_CURRENT;
    }
    if(I < 0) {
        I = 0;
    }

    //Reduce current if temperature is too high
    if (temp_margin > TEMP_RAMP_START) {
        I = 1 - ((temp_margin - TEMP_RAMP_START) / (TEMP_RAMP_FINISH - TEMP_RAMP_START));
    }
    if (temp_margin > TEMP_RAMP_FINISH) {
        I *= 0;
    }

    *current = I;
    *voltage = MAX_VOLTAGE;
}


int main() {
    
    chargerboard_timer.start();
    
    while(1) {
        
        get_voltage_data();
        get_charger_data();
        get_bms_data();
        
        int current_time = chargerboard_timer.read_ms();
        
        bool timeout = false;
        bool failure = false;


//check for timeouts
        if (current_time < CHARGER_MSG_TIMEOUT + BMS_MSG_TIMEOUT) {
                printf("Waiting for messages\r\n");
                timeout = false;
            
            }

        if (current_time - chrg_status_recv_time         > BMS_MSG_TIMEOUT ||
            current_time - bms_minmax_cell_volts_recv_time > BMS_MSG_TIMEOUT ||
            current_time - bms_pack_status_recv_time       > BMS_MSG_TIMEOUT) {
            
                printf("BMS timeout\r\n");
                timeout = true;
                bms_timeout = true;
                
            }

        if (current_time - chrg_status_recv_time > CHARGER_MSG_TIMEOUT) {
        
                printf("charger timeout\r\n");
                timeout = true;
                charger_timeout = true;
            }
            
        if (charger_timeout) {
                printf("charger has timed out\r\n");
            }
    

//Check for Failure: Values set according to ELON-CAN-specification.pdf STATUS register
        if(bms_status bitand 1 == 1) {
            
            printf("Hardware Failure\r\n");
            failure = true;
            
            }
        
        if(bms_status bitand 2 == 2) {
            
            printf("Error: Over Temperature\r\n");
            failure = true;
            
            }
        
        if(bms_status bitand 4 == 4) {
            
            printf("Input Voltage Wrong\r\n");
            failure = true;
            
           }
            



//Update LEDs
        if (failure == true) {
            desired_current = 0;    
            red_led = 1;
        
            } else if (timeout == true) {
                desired_current = 0;
                yellow_led = 1;
                } else if (charge_finished == false) {
                    green_led = 1;
                    } else {
                        red_led = 0;
                        yellow_led = 0;
                        green_led = 0;
                        }
            
            
    
        if (min_cell_voltage > rising_voltage_threshold) { 
            charge_finished = true;
            printf("Charge Finished\r\n");
            //set charger control bit to finished charging
        } else {
            calculate_current(voltage_error, temp_margin, &desired_current, &desired_voltage);
            charge_finished = false;
            
            }

//voltage error, temp margin, desired voltage, desired current, voltage, current, min cell voltage, max cell voltage.

printf("Voltage Error = %f\n", voltage_error);
printf("Temperature Margin = %f\n", temp_margin);
printf("Desired Voltage = %f\n", desired_voltage);
printf("Desired Current = %f\n", desired_current);
printf("Voltage = %f\n", charger_voltage);
printf("Current = %f\n", charger_current);
printf("Min cell voltage = %f\n", min_cell_voltage);
printf("Max cell voltage = %f\n", max_cell_voltage);

//send CAN data
//send charger control max voltage MAX_VOLTAGE
//send charger control max current desired_current
//send charge_finished value to control bit.
    
    

    }
}