Penn Electric Racing / Mbed 2 deprecated SystemManagement

Dependencies:   mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP

Fork of SystemManagement by Martin Deng

FanPump/FanPump.cpp

Committer:
martydd3
Date:
2014-10-21
Revision:
12:e0adb697fcdb
Parent:
7:5f6e31faa08e
Child:
13:fbd9b3f5a07c

File content as of revision 12:e0adb697fcdb:

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

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

PinStatus pin_status[PIN_NUM];
CANBuffer *tx_Fan_Buffer;

FanPump::FanPump(CANBuffer *can){
    for(int i = 0; i < PIN_NUM; i++){
        pin_status[i].cur_duty = 0.0;
        pin_status[i].new_duty = 0.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;
    }  

    tx_Fan_Buffer = 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_pin(void const *arg)
{
    PinStatus *pin_stat = (PinStatus *)arg;
    float *cur_duty = &(pin_stat->cur_duty);
    float *new_duty = &(pin_stat->new_duty);
    
    while(*cur_duty != *new_duty)
    {
        if(*new_duty > *cur_duty){
            *cur_duty += 1.0;
            
            if(*cur_duty > *new_duty)
                *cur_duty = *new_duty;   
        } else if(*new_duty < *cur_duty){
            *cur_duty -= 1.0;
            
            if(*cur_duty < *new_duty)
                *cur_duty = *new_duty;   
        }
        
        pin_stat->pin->write((*cur_duty));
        
        Thread::wait(5);    //1% duty cycle per 0.005 s
    }
}

void FanPump::set_fan_pump(FanPumpSelect fan_pump, float duty){
    if((int)fan_pump >= PIN_NUM || duty > 100.0)
        return;
    
    free_pin(fan_pump);

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

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

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

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

void update_fans_pumps(void const *arg){
    char data[8] = {0};
    while(1){
        memcpy(&pin_status[0].cur_duty, data, sizeof(float));
        memcpy(&pin_status[1].cur_duty, data+4, sizeof(float));
        
        CANMessage txPumpMessage(TX_PUMP_ID, data, 8);
        tx_Fan_Buffer->txWrite(txPumpMessage);
        
        memcpy(&pin_status[2].cur_duty, data, sizeof(float));
        memcpy(&pin_status[3].cur_duty, data+4, sizeof(float));
        
        CANMessage txFanMessage(TX_FAN_ID, data, 8);
        tx_Fan_Buffer->txWrite(txFanMessage);
        
        Thread::wait(100);  // 10 Hz update    
    }    
}

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