Mosfet Driver

Dependencies:   mbed

Revision:
2:bdd944abaf86
Parent:
1:19d350e383e6
Child:
3:af6a6f498276
--- a/main.cpp	Sun May 05 17:59:15 2013 +0000
+++ b/main.cpp	Mon May 06 18:47:34 2013 +0000
@@ -1,12 +1,14 @@
 #include "mbed.h"
 
-LocalFileSystem local("local");                  //Flashdrive for config file
-FILE *fp;                                        //Local Config File
+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)
 
-bool mosfet1_open  = true ;
-bool mosfet1_close = false;
+float version = 0.8;                             //Program Version  
+
+bool mosfet1_open  = true ;                      //Mosfet1 geschlossen
+bool mosfet1_close = false;                      //Mosfet1 offen
 
 DigitalOut myled  (LED1);
 DigitalOut myled1 (LED2);
@@ -22,52 +24,70 @@
 DigitalIn  In3    (p28);
 DigitalIn  In4    (p27);
 AnalogIn   AI1    (p17);
-AnalogIn   AI2    (p18);
+AnalogIn   cur_in (p18);
 AnalogIn   bz_in  (p19);
 AnalogIn   cap_in (p20);
 
-
 Serial pc(USBTX, USBRX);
-Ticker PC_OUT_timer;
-Ticker LED_timer;
-Ticker PUMPE_timer;
+Ticker PC_OUT_timer;          // Output Monitoring to Serial
+Ticker LED_timer;             // Set Status LED´s
 
 Timer t;
 
-float bz_off     =  16.0;    //Brennstoffzellen Spannung min. Laden beenden
-float bz_on      =  17.0;    //Brennstoffzellen Spannung für Ladefreigabe)
-float bz_max     =  18.0;    //Brennstoffzellen Spannung Abs. max.
-float cap_max    =  13.0;    //CAP Spannung max. (Abschaltung)
-float cap_min    =   9.0;    //CAP Spannung min. (Zelle an)
-int  pwm_cycle   =    60;    //ms für PWM Period
-int  pwm_lo      =    40;    //ms für PWM high
-float purge_start=  60.0;    //s before starting purch
-float purge_end  =  60.2;    //s after finishing purch
-float boost_time =   0.2;    //s Pump runup with 100% Duty Cycle
-int  boost       =    25;    //Number of PWM-Cycles for Pump runup boost
-int  debug       =     1;    //Serial Output on (1)
-float gate_on    =   3.5;    //Mosfet opt. Gate Drain [V]
-float gate_off   =   2.8;    //Mosfet min. Gate Drain [V]
-float sample     =     5;    //Serial Output Samples per Second
-bool pump_on     = false;    //Pumpenzustand
+
+// 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
 
-float bz;
-float cap;
-unsigned int counter;
+// 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[16][16];
+ char read[17][8];
 
  char  i = 0;
  char  j = 0;
  int   c = 0;
  float  temp;
  
- for (j = 0; j<16; j++)
+ for (j = 0; j<17; j++)
   {
-   for (i = 0; i<16; i++)
+   for (i = 0; i<8; i++)
     {
      read[j][i] = '\0';
     }
@@ -88,65 +108,78 @@
        fclose(fp);
       
        
-       sscanf(&read[ 0][1], "%f", &temp); bz_on       = temp;
-       sscanf(&read[ 1][1], "%f", &temp); bz_off      = temp;
-       sscanf(&read[ 2][1], "%f", &temp); bz_max      = temp;
-       sscanf(&read[ 3][1], "%f", &temp); cap_min     = temp;
-       sscanf(&read[ 4][1], "%f", &temp); cap_max     = temp;
-       sscanf(&read[ 5][1], "%f", &temp); gate_on     = temp;
-       sscanf(&read[ 6][1], "%f", &temp); gate_off    = temp;
-       sscanf(&read[ 7][1], "%f", &temp); purge_start = temp;
-       sscanf(&read[ 8][1], "%f", &temp); purge_end   = temp;
-       sscanf(&read[ 9][1], "%f", &temp); boost_time  = temp;
-       sscanf(&read[10][1], "%f", &temp); pwm_cycle   = temp;
-       sscanf(&read[11][1], "%f", &temp); pwm_lo      = temp;
-       sscanf(&read[12][1], "%f", &temp); debug       = temp;
-       sscanf(&read[13][1], "%f", &temp); sample      = temp;
+       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;
-       
-    }
+       boost = (boost_time * 1000) / pwm_cycle;     
+     }
     
-    pc.printf("\n\r");
-    pc.printf("Brennstoffzellenregler V0.5 \n\r");
-    pc.printf("___________________________ \n\r" );
-    pc.printf("BZ  max   [V] : %4.1f \n\r",bz_max);
-    pc.printf("BZ  on    [V] : %4.1f \n\r",bz_on);
-    pc.printf("BZ  off   [V] : %4.1f \n\r",bz_off);
-    pc.printf("CAP min   [V] : %4.1f \n\r",cap_min);
-    pc.printf("CAP max   [V] : %4.1f \n\r",cap_max);
-    pc.printf("Gate On   [V] : %4.1f \n\r",gate_on);
-    pc.printf("Gate Off  [V] : %4.1f \n\r",gate_off);
-    pc.printf("Purch on  [s] : %4.1f \n\r",purge_start);
-    pc.printf("Purch 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 lo    [ms]: %4d \n\r"  ,pwm_lo);
-    pc.printf("Serial        : %4d \n\r"  ,debug);
-    pc.printf("Sample    [Hz]: %4.0f \n\r",sample);
-    pc.printf("___________________________ \n\r" );
-    pc.printf("\n\r");
+    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()
 {
- mosfet1 = mosfet1_open;
- if (debug == 1) 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\n\r"
-          ,bz,bz_off,bz_on,bz_max,cap,cap_min,cap_max,float(counter)/(1000/pwm_cycle),purge_start,purge_end);
+ 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_off )            myled  = 1; else myled  = 0;                //LED = Spannung an der BZ IO
+  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
@@ -155,31 +188,32 @@
 
 void PUMPE()
 {
- if (((cap <= cap_min) || (pump_on == true)) 
-     && (bz < bz_max) && (cap < cap_max))                                   //Pumpe Einschaltbedingung
-  {
+ counter_ms++;
+ if (((cap <= cap_min) || (pump_on == true)) && (bz < bz_max) && (cap < (cap_max - (In1 * cap_delta)))) //Pumpe Einschaltbedingung
+  {  
    pump_on = true;
-   if (t.read_ms() > pwm_lo)  pump = 1 ;                                    //Set PWM from low to high 
+   if (counter_ms > (pwm_cycle - pwm_on))  pump = 1 ;                               //Set PWM from low to high 
                                         
-   if (t.read_ms() >= pwm_cycle)                                            //End PWM cycle
+   if (counter_ms >= pwm_cycle)                                                   //End PWM cycle
     {
-     counter++;
-     t.reset();         
+     counter_cycle++;
+     counter_ms = 0;
+              
      if (boost > 0) boost--;
      
-     if ((counter < (1000 / pwm_cycle) * purge_start) || (boost <= 0) || (In1 == 0))  
+     if ((counter_cycle < (1000 / pwm_cycle) * purge_start) || (boost <= 0) || (In1 == 0))  
       {   
-       pump  = 0;                                                           //PWM Betrieb
+       pump  = 0;                                                                 //PWM Betrieb
        purge = 0;                                     
       }
      else
       {
-       if (pump == 1) purge   = 1;                                          //Purge Betrieb
+       if (pump == 1) purge   = 1;                                                //Purge Betrieb
       }
              
-     if (counter > (1000 / pwm_cycle) * purge_end)                          //Purge Ende 
+     if (counter_cycle > (1000 / pwm_cycle) * purge_end)                          //Purge Ende 
       {
-       counter = 0; 
+       counter_cycle = 0; 
        purge = 0; 
        pump = 0;
       }    
@@ -194,36 +228,62 @@
 }
 
 int main() 
-{
-    
-    int gate_pwm = 0;     
+{ 
     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
-    PUMPE_timer.attach (&PUMPE , 0.001     );                            //Pumpen PWM    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
-     //cap = ((cap_in * 92.0) + cap)/3;                                             //CAP RAW in Spannung umrechnen
-               
-     if (((bz-cap) >= gate_on) && (bz > bz_on) && (In2 == 0))                     //Überspannung (> gate_on) oder Ladespannung der BZ in die Caps laden ***(cap > 13)
-      {     
-      // if (gate_pwm%2==0) mosfet1 = mosfet1_close;                                //Spule einkoppeln (mit PWM anteil für StepDown)
-      //  else mosfet1 = mosfet1_close;                                             //Spule auskoppeln                                      
-      mosfet1 = !mosfet1;
+     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 ((bz < bz_off) || ((bz-cap) < gate_off))                                  //Ladereglung Unterspannung Zelle / Gate-Mosfet
-      {
-       //mosfet1 = mosfet1_open;                                                    //Zelle trennen
-       mosfet1 = !mosfet1;
-      }
-     
-     if (gate_pwm > 99) gate_pwm = 0; else gate_pwm++; 
+     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(); 
     }
 
 }