Mosfet Driver

Dependencies:   mbed

main.cpp

Committer:
HMFK03LST1
Date:
2013-05-06
Revision:
2:bdd944abaf86
Parent:
1:19d350e383e6
Child:
3:af6a6f498276

File content as of revision 2:bdd944abaf86:

#include "mbed.h"

LocalFileSystem local("local");                  //init Flashdrive for reading config file
FILE *fp;                                        //Pointer to local Config File

#define USR_POWERDOWN    (0x104)                 //Power Down Mbed Interface (save 50% or 45 mA)

float version = 0.8;                             //Program Version  

bool mosfet1_open  = true ;                      //Mosfet1 geschlossen
bool mosfet1_close = false;                      //Mosfet1 offen

DigitalOut myled  (LED1);
DigitalOut myled1 (LED2);
DigitalOut myled2 (LED3);
DigitalOut myled3 (LED4);

DigitalOut purge  (p33);
DigitalOut pump   (p34);
DigitalOut mosfet1(p35);
DigitalOut mosfet2(p36);
DigitalIn  In1    (p30);
DigitalIn  In2    (p29);
DigitalIn  In3    (p28);
DigitalIn  In4    (p27);
AnalogIn   AI1    (p17);
AnalogIn   cur_in (p18);
AnalogIn   bz_in  (p19);
AnalogIn   cap_in (p20);

Serial pc(USBTX, USBRX);
Ticker PC_OUT_timer;          // Output Monitoring to Serial
Ticker LED_timer;             // Set Status LED´s

Timer t;


// Brennstoffzellen Parameter
float bz_max      =  30.5;    //Brennstoffzelle Spannung Abs. max.
float bz_p_oben   =  10.0;    //Brennstoffzelle Prozent Load bei bz_max
float bz_on       =  29.0;    //Brennstoffzelle Spannung für Ladefreigabe)
float bz_min      =  26.0;    //Brennstoffzelle Spannung min. Laden beenden
float bz_p_unten  = -20.0;    //Brennstoffzelle Prozent Load bei bz_min
float bz_current  =   1.5;    //Brennstoffzellen Strom nominal
float bz_cur_max  =   2.0;    //Brennstoffzellen Strom max

// SuperCap Parameter
float cap_max     =  25.0;    //CAP Spannung max. (Abschaltung)
float cap_min     =  20.0;    //CAP Spannung min. (Zelle an)
float cap_p_min   =   2.0;    //CAP Prozent Load bei 0V
float cap_delta   =   1.5;    //Absenkung der Spannung mit Din

// Pump & Purge Parameter
float purge_start =   3.0;    //s before starting purch
float purge_end   =   3.2;    //s after finishing purch
float boost_time  =   0.2;    //s Pump runup with 100% Duty Cycle
int   pwm_cycle   =    20;    //ms für PWM Period
int   pwm_on      =    12;    //ms für PWM high

// Monitoring Parameter
int   debug       =     1;    //Serial Output on (1)
float sample      =     5;    //Serial Output Samples per Second

// Temp Variable
bool  Load        = false;    //Laderegler aktiv
bool  pump_on     = false;    //Pumpenzustand
int   boost       =     0;    //Number of PWM-Cycles for Pump runup boost calc in load_cfg
int   Zelle_Level =     0;    //% Load aus Bz Spannung
int   Cap_Level   =     0;    //% Load aus Cap Spannung
int   Cur_Level   =     0;
int   Load_Level  =     0;    //% Load aus Bz und Cap
float bz          =     0;    //Spannung Brennstoffzelle
float cap         =     0;    //Spannung SuperCap
float current     =     0;    //Strom in den Mosfet
unsigned int counter_cycle = 0; //Counter PWM-Cycles for Pump-Purge
unsigned int counter_ms    = 0; //Counter for PWM Pump

  
void load_cfg()
{
 char read[17][8];

 char  i = 0;
 char  j = 0;
 int   c = 0;
 float  temp;
 
 for (j = 0; j<17; j++)
  {
   for (i = 0; i<8; i++)
    {
     read[j][i] = '\0';
    }
  }
  
  i=0;
  j=0;
  
    fp = fopen("/local/power.cfg", "r");
    if ( fp != NULL )
     {
         while((c != EOF) && (c !=10))
          { 
           c = fgetc(fp);
           if (c == ';'){read[j][0] = i; i = 0; j++;} 
           else {i++; read[j][i] = c;}
          }
       fclose(fp);
      
       
       sscanf(&read[ 0][1], "%f", &temp); bz_max      = temp;
       sscanf(&read[ 1][1], "%f", &temp); bz_p_oben   = temp;
       sscanf(&read[ 2][1], "%f", &temp); bz_on       = temp;
       sscanf(&read[ 3][1], "%f", &temp); bz_min      = temp;
       sscanf(&read[ 4][1], "%f", &temp); bz_p_unten  = temp;
       sscanf(&read[ 5][1], "%f", &temp); cap_max     = temp;
       sscanf(&read[ 6][1], "%f", &temp); cap_min     = temp;
       sscanf(&read[ 7][1], "%f", &temp); cap_p_min   = temp; 
       sscanf(&read[ 8][1], "%f", &temp); cap_delta   = temp;
       sscanf(&read[ 9][1], "%f", &temp); purge_start = temp;
       sscanf(&read[10][1], "%f", &temp); purge_end   = temp;
       sscanf(&read[11][1], "%f", &temp); boost_time  = temp;
       sscanf(&read[12][1], "%f", &temp); pwm_cycle   = temp;
       sscanf(&read[13][1], "%f", &temp); pwm_on      = temp;
       sscanf(&read[14][1], "%f", &temp); debug       = temp;
       sscanf(&read[15][1], "%f", &temp); sample      = temp;   
       
       boost = (boost_time * 1000) / pwm_cycle;     
     }
    
    pc.printf("\n\r"                                           );
    pc.printf("******************************* \n\r"           );
    pc.printf("* Brennstoffzellenregler V%03.1f * \n\r",version);
    pc.printf("******************************* \n\r"           );
    pc.printf("--------------BZ--------------- \n\r"           );
    pc.printf(" BZ max        [V] : %4.1f \n\r",bz_max         );
    pc.printf(" BZ max        [%] : %4.1f \n\r",bz_p_oben      );
    pc.printf(" BZ Laden on   [V] : %4.1f \n\r",bz_on          );
    pc.printf(" BZ Laden off  [V] : %4.1f \n\r",bz_min         );
    pc.printf(" BZ Laden off  [%] : %4.1f \n\r",bz_p_unten     );
    pc.printf(" BZ Strom norm [A] : %4.1f \n\r",bz_current     );
    pc.printf(" BZ Strom max. [A] : %4.1f \n\r",bz_cur_max     );
    pc.printf("-------------CAP--------------- \n\r"           );
    pc.printf(" CAP max       [V] : %4.1f \n\r",cap_max        );
    pc.printf(" CAP min       [V] : %4.1f \n\r",cap_min        );
    pc.printf(" CAP min       [%] : %4.1f \n\r",cap_p_min      );
    pc.printf(" CAP lo on Din[-V] : %4.1f \n\r",cap_delta      );
    pc.printf("----------Pump & Purge--------- \n\r"           );
    pc.printf(" Purge on      [s] : %4.1f \n\r",purge_start    );
    pc.printf(" Purge off     [s] : %4.1f \n\r",purge_end      );
    pc.printf(" Boost         [s] : %4.1f \n\r",boost_time     );    
    pc.printf(" PWM cycle     [ms]: %4d \n\r"  ,pwm_cycle      );
    pc.printf(" PWM on        [ms]: %4d \n\r"  ,pwm_on         );
    pc.printf("------------Monitor------------ \n\r"           );
    pc.printf(" Serial output     : %4d \n\r"  ,debug          );
    pc.printf(" Samplerate    [Hz]: %4.0f \n\r",sample         );
    pc.printf("******************************* \n\r"           );
    pc.printf("\n\r"                                           );
}


int semihost_powerdown() 
{
 uint32_t arg;
 return __semihost(USR_POWERDOWN, &arg); 
}


void SEND()
{
 if (debug == 1) 
 {
  mosfet1 = mosfet1_open;
  pc.printf("BZ: %4.1f/%4.1f-%4.1f+%4.1f  CAP: %4.1f/%4.1f-%4.1f  Purge: %4.1f/%4.1f-%4.1f  Load: %03d Current: %4.2f \n\r"
          ,bz,bz_min,bz_on,bz_max,cap,cap_min,cap_max,float(counter_cycle)/(1000/pwm_cycle),purge_start,purge_end,Load_Level, current);
 }
}


void LED()
{
  if (bz  < bz_min )            myled  = 1; else myled  = 0;                //LED = Spannung an der BZ IO
  if (cap > cap_min)            myled1 = 1; else myled1 = 0;                //LED = Spannung an den Cap´s IO 
  if (mosfet1 == mosfet1_close) myled2 = 1; else myled2 = 0;                //LED = Gate Zustand Mosfet 1
  if (pump == 1)                myled3 = 1; else myled3 = 0;                //LED = Pumpe an
}


void PUMPE()
{
 counter_ms++;
 if (((cap <= cap_min) || (pump_on == true)) && (bz < bz_max) && (cap < (cap_max - (In1 * cap_delta)))) //Pumpe Einschaltbedingung
  {  
   pump_on = true;
   if (counter_ms > (pwm_cycle - pwm_on))  pump = 1 ;                               //Set PWM from low to high 
                                        
   if (counter_ms >= pwm_cycle)                                                   //End PWM cycle
    {
     counter_cycle++;
     counter_ms = 0;
              
     if (boost > 0) boost--;
     
     if ((counter_cycle < (1000 / pwm_cycle) * purge_start) || (boost <= 0) || (In1 == 0))  
      {   
       pump  = 0;                                                                 //PWM Betrieb
       purge = 0;                                     
      }
     else
      {
       if (pump == 1) purge   = 1;                                                //Purge Betrieb
      }
             
     if (counter_cycle > (1000 / pwm_cycle) * purge_end)                          //Purge Ende 
      {
       counter_cycle = 0; 
       purge = 0; 
       pump = 0;
      }    
    }      
  }
 else
  {
   pump_on = 0; pump = 0; purge = 0;                                       //Pumpe aus
   boost = (boost_time * 1000) / pwm_cycle;                                // Boost für nächsten Start setzen
  }

}

int main() 
{ 
    pc.baud(115200);                                                     //config Serial Port
    load_cfg();                                                          //init config File
    semihost_powerdown();                                                //Mbed Interface powerdown
    PC_OUT_timer.attach(&SEND  , (1/sample));                            //Serial output Timer
    LED_timer.attach   (&LED   , 0.200     );                            //LED Status    Timer
    t.start();                                                           //Timer für PWM starten
    float bz_faktor;                                                     //Temp Variable

    bz_faktor = ((bz_p_oben - bz_p_unten)/(bz_max - bz_min));            //Prozent Umrechnung BZ


    
    while(1) 
    {
     bz  = ((bz_in  * 92.0) + bz )/3;                                    //BZ  RAW in Spannung umrechnen (2*neu zu 1*alt Glättung)
     cap = ((cap_in * 92.0) + cap)/3;                                    //CAP RAW in Spannung umrechnen (2*neu zu 1*alt Glättung)
     current = (cur_in * 23.82) - 4.00; 

     PUMPE();                                                            //Pumpen PWM aufrufen         
     
     Zelle_Level = (bz_faktor * (bz - bz_min) + bz_p_unten) * 10;        //%Load aus Zellenspannung berechnen
     Cap_Level   = ((cap / cap_max) + cap_p_min) * 10;                   //%Load aus Cap Level
     Cur_Level   = (current/bz_current)*100; 
     Load_Level  = Zelle_Level + Cap_Level - Cur_Level;                              //%Load Summe Cap + Bz

     if (Load == true)                                                   // Laden aktiv
      {
                                                            // Timer für 1 kHz starten 
       if (bz > bz_min)                                                  // Zelle über min. Spannung
        { 
         while (t.read_us() <= 1000)                                     // während der PWM (1khz Periode)
          {
           if (t.read_us() < Load_Level)                                 // %Load PWM zu Timer vergleich
            {mosfet1 = mosfet1_close;}                                   // %Load PWM nicht erreicht Mosfet an
           else
            {mosfet1 = mosfet1_open;}                                    // %Load PWM erreicht Mosfet aus
          }
        }
       else
        {
          mosfet1 = mosfet1_open ;                                      // Mosfet wegen Unterspannung BZ auskoppeln 
          Load = false;                                                 // Laden beenden bis BZ > BZ on (Sicherungsschaltung)
        }       
      }
     else
      {
       if (bz >= cap){mosfet1 = mosfet1_open ;}                         // Mosfet im nicht Ladebetrieb auskoppeln 
       else          {mosfet1 = mosfet1_close;}                         // Mosfet im nicht Ladebetrieb einkoppeln (Treiber stromfrei = Stromsparen) 
       while (t.read_us() <= 1000){};
      }  
       
     
     if (((cap < cap_min) && (bz > bz_on))||(bz > bz_max)) Load = true ;// Cap unter Minimum oder BZ über Maximum = Laden beginnen
     if (  cap >= cap_max                                ) Load = false;//  
     t.reset(); 
    }

}