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

Dependencies:   mbed CUER_CAN

charger.cpp

Committer:
DasSidG
Date:
2017-09-12
Revision:
12:77d493b3320b
Parent:
11:f578a372be42

File content as of revision 12:77d493b3320b:

#include "charger.h"
#include "mbed.h"
#include "CAN_Data.h"
#include "CAN_IDs.h"
#include "Data_types.h"
#include "CANParserCharger.h"

void init();

float calculate_desired_current(float charger_current, float min_cell_voltage);
void check_timeouts();
void update_LEDS();

DigitalOut green_led(p21); //charging LED
DigitalOut yellow_led(p22); //timeout LED
DigitalOut red_led(p23); //error LED
DigitalIn charge_switch(p8); //switch to enable charging

uint8_t charger_status; //status packet given by charger, see Elcon CAN Specification in google drive
bool precharge_status;
bool comms_timeout;
bool charger_failure;
bool charge_finished;
bool bms_error;
bool charging;
bool bms_timeout = false;
bool charger_timeout = false;

float min_cell_voltage = 3600; //mV
float max_cell_voltage = 3600;//mV

float charger_current; //mA
float charger_voltage; //mV

float desired_current = 0; //mA
float desired_voltage = MAX_PACK_VOLTAGE; //mV

//float voltage_error = 1000; //mV //This = RISING_BALANCE_THRESHOLD - max_cell_voltage

uint8_t charger_control = STOP_CHARGING;

timeouts_t timeouts;

int main() {
    
    init();
    
    while(1) {
                
        //get the various data from the CAN packets
        get_CAN_data();

        check_timeouts();
        update_LEDS();
        
        charger_control = STOP_CHARGING;
        
        //if (min_cell_voltage > RISING_BALANCE_THRESHOLD || charge_finished) {  //Note: if balancing is implemented, use this version instead
        if ((max_cell_voltage > CHARGING_FINISHED_THRESHOLD_VOLTAGE && charger_current < CHARGING_FINISHED_THRESHOLD_CURRENT) 
                || charge_finished 
                || max_cell_voltage > MAX_CELL_VOLTAGE) {
            charge_finished = true;
            charging = false;
            if (DEBUG) printf("Charge Finished\r\n");
            car_can.write(generate_charging_finished_msg());
            charger_control = STOP_CHARGING; //set charger control bit to stop charging
        } 
        else if (precharge_status && !bms_error && !comms_timeout && !charger_failure && charge_switch.read()) { 
            charging = true;
            desired_current = calculate_desired_current(charger_current, min_cell_voltage);
            desired_voltage = MAX_PACK_VOLTAGE;
            charge_finished = false;
            charger_control = START_CHARGING; //set charger control bit to start charging
        }
        
        //send CAN data
        
        Timer t;
        t.start();
        charger_CAN_data_sent = false;
        charger_can.write(generate_charger_control_msg(desired_voltage, desired_current, charger_control)); //control message to charger
        while(!charger_CAN_data_sent && t.read_ms() < CAN_TIMEOUT_MS);
        
        t.reset();
        car_CAN_data_sent = false;
        car_can.write(generate_charger_info_msg(charger_voltage, charger_current, charger_status, charger_timeout, bms_timeout)); //charger info message for rest of car
        while(!car_CAN_data_sent && t.read_ms() < CAN_TIMEOUT_MS);
        
        if (DEBUG) {
            printf("Desired Voltage = %f \r\n", desired_voltage);
            printf("Desired Current = %f \r\n", desired_current);
            printf("Charger voltage = %f \r\n", charger_voltage);
            printf("Charger current = %f \r\n", charger_current);
            printf("Min cell voltage = %f \r\n", min_cell_voltage);
            printf("Max cell voltage = %f \r\n", max_cell_voltage);
            printf("Precharge status is %d \r\n", precharge_status);
            printf("\r\n");
        }
        
        wait_ms(500);
        
    }
}

float calculate_desired_current(float _charger_current, float _min_cell_voltage){
    float _desired_current;
    _desired_current += 500; //gradually ramp up current when charging starts
    
    if (_min_cell_voltage < DEEP_DISCHARGE_THRESHOLD_VOLTAGE) {
        if(_desired_current > DEEP_DISCHARGE_MAX_CURRENT) {
            _desired_current = DEEP_DISCHARGE_MAX_CURRENT;
        }
    }

    else if(_desired_current > MAX_CURRENT) {
        _desired_current = MAX_CURRENT;
    }
    if(_desired_current < 0) {
        _desired_current = 0;
    }
    
    return _desired_current;
}

void init()
{    
    CAN_Init();
    //Start comms timeout timers
    timeouts.BMS_timeout.start();
    timeouts.charger_timeout.start();
    precharge_status = false;
    //Reset error indicators
    comms_timeout = false;
    charger_failure = false;
    bms_error = false;
    charging = false;
}

void check_timeouts() //Check if it's been too long since any of the other devices in the car have communicated
{
    
    if (timeouts.BMS_timeout.read_ms() > BMS_MSG_TIMEOUT_MS) 
    {
        if (DEBUG) printf("Error: BMS comms timeout \r\n");
        comms_timeout = true;
        bms_timeout = true;
    }
    
    if (timeouts.charger_timeout.read_ms() > CHARGER_MSG_TIMEOUT_MS) 
    {
        if (DEBUG) printf("Error: Charger comms timeout \r\n");
        comms_timeout = true;
        charger_timeout = true;
    }
}

void update_LEDS() {
    if (charger_failure || bms_error) {
        desired_current = 0;    
        red_led = 1;
    } 
        
    else if (comms_timeout) {
        desired_current = 0;
        yellow_led = 1;
    } 
    
    else if (!charge_finished) {
        green_led = 1;
    } 
    
    else {
        red_led = 0;
        yellow_led = 0;
        green_led = 0;
    }  

}