System Management code

Dependencies:   CANBuffer mbed SystemManagement mbed-rtos

Dependents:   SystemManagement

System Management code for Penn Electric Racing

Functions:

Controls Fans and Pumps via instruction from CAN Messages, ramps them up over time to prevent damage

Turns on/off DC-DC converter via instruction from CAN Messages

FanPump/FanPump.cpp

Committer:
martydd3
Date:
2014-10-10
Revision:
6:6a04210a3f4f
Child:
7:5f6e31faa08e

File content as of revision 6:6a04210a3f4f:

#include "mbed.h"
#include "FanPump.h"

PwmOut pwmPins[PIN_NUM] = { 
    (P2_0),         // pump
    (P2_1),         // fan 1
    (P2_2),         // fan 2
    (P2_3),         // fan 3
};

PinStatus pin_status[PIN_NUM];
CANBuffer *txBuffer;

FanPump::FanPump(CANBuffer *can){
    for(int i = 0; i < PIN_NUM; i++){
        pin_status[i].cur_duty = 0;
        pin_status[i].new_duty = 0;
        
        pin_status[i].pin = &pwmPins[i];
        pin_status[i].pin->period_ms(10);
        pin_status[i].pin->write(0.0);
        
        pin_threads[i] = NULL;
    }  

    txBuffer = can;
}

// this is not a member function. For some reason, thread does weird things
// with functions in classes. Apparently pointers get messed up when pointing to
// a function in a class
void ramp_fan(void const *arg)
{
    PinStatus *pin_stat = (PinStatus *)arg;
    unsigned char *cur_duty = &(pin_stat->cur_duty);
    unsigned char *new_duty = &(pin_stat->new_duty);
    
    while(*cur_duty != *new_duty)
    {
        if(*new_duty > *cur_duty){
            *cur_duty += 1;
            
            if(*cur_duty > *new_duty)
                *cur_duty = *new_duty;   
        } else if(*new_duty < *cur_duty){
            *cur_duty -= 1;
            
            if(*cur_duty < *new_duty)
                *cur_duty = *new_duty;   
        }
        
        pin_stat->pin->write((*cur_duty)*0.01);
        
        Thread::wait(5);    //1% duty cycle per 0.005 s
    }
}

void FanPump::set_fan(FanSelect fan, unsigned char duty){
    if((int)fan >= PIN_NUM || duty > 100)
        return;
    
    free_pin(fan);

    pin_status[fan].new_duty = duty;
    pin_threads[fan] = new Thread(ramp_fan, &pin_status[fan]);
}

void FanPump::shutdown(FanSelect fan){
    free_pin(fan);
    
    pin_status[fan].cur_duty = 0;
    pin_status[fan].new_duty = 0;
    pin_status[fan].pin->write(0);
}

void FanPump::shutdown_all(){
    for(int i = 0; i < PIN_NUM; i++)
        FanPump::shutdown((FanSelect)i);    
}

void FanPump::free_pin(FanSelect fan){
    if(pin_threads[fan] != NULL){
        pin_threads[fan]->terminate();
        free(pin_threads[fan]);    
    }    
}

void update_fans(void const *arg){
    char data[4] = {0};
    while(1){
        for(int i = 0; i < PIN_NUM; i++)
        {
            data[i] = pin_status[i].cur_duty;
        }
        
        CANMessage txMessage(TX_FAN_ID, data, 4);
        txBuffer->txWrite(txMessage);
        
        Thread::wait(100);  // 10 Hz update    
    }    
}

void FanPump::start_update()
{
    Thread update_thread(update_fans);
}