Mosfet Driver

Dependencies:   mbed

Revision:
5:d814001b8aae
Parent:
4:8c89e422bed7
Child:
6:4af29761b1f0
--- a/main.cpp	Tue May 07 07:11:11 2013 +0000
+++ b/main.cpp	Tue May 14 23:10:35 2013 +0000
@@ -5,28 +5,36 @@
 
 #define USR_POWERDOWN    (0x104)                 //Power Down Mbed Interface (save 50% or 45 mA)
 
-float version = 0.8;                             //Program Version  
+float version = 0.9;                             //Program Version  
 
-bool mosfet1_open  = true ;                      //Mosfet1 geschlossen
-bool mosfet1_close = false;                      //Mosfet1 offen
+bool mosfet_open  = true ;                      //Mosfet1 geschlossen
+bool mosfet_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);
+DigitalOut pump   (p36);
+DigitalOut purge  (p35);
+DigitalOut h2_blow(p34);
+DigitalOut waterp (p33);
+DigitalOut mosfet (p21);
+
+DigitalIn  In1    (p22);                      // Caps Down
+DigitalIn  In2    (p23);                      // Power UP
+DigitalIn  In3    (p24);
+DigitalIn  In4    (p25);
+DigitalIn  In5    (p29);
+DigitalIn  In6    (p30);
+
+AnalogIn   cap_in (p15);                      // AI 1 Faktor /14.8
+AnalogIn   bz_in  (p16);                      // AI 2 Faktor /14.8
+AnalogIn   mos_in (p17);                      // AI 3 Faktor /1.5
+AnalogIn   temp_in(p18);                      // AI 4 Faktor /1.5
+AnalogIn   AI_5   (p19);                      // AI 5 Faktor * 2
+AnalogIn   cur_in (p20);                      // AI 6 Faktor * 2 zum Strommesser
 
 Serial pc(USBTX, USBRX);
 Ticker PC_OUT_timer;          // Output Monitoring to Serial
@@ -34,7 +42,6 @@
 
 Timer t;
 
-
 // Brennstoffzellen Parameter
 float bz_max      =  30.5;    //Brennstoffzelle Spannung Abs. max.
 float bz_p_oben   =  15.0;    //Brennstoffzelle Prozent Load bei bz_max
@@ -45,6 +52,8 @@
 float bz_cur_add  =   2.0;    //Brennstoffzellen Strom max
 float bz_c_i_max  =  20.0;    //Strom Integrale Reglung Max %
 float bz_c_i_min  = -10.0;    //Strom Integrale Reglung Min %
+float bz_temp_max =  55.0;    //Maximale Wassertemperatur °C 
+int   load_fail   =     0;    //Kein Strom trotz Imax
 
 // SuperCap Parameter
 float cap_max     =  25.0;    //CAP Spannung max. (Abschaltung)
@@ -57,40 +66,58 @@
 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
+float pump_red    =  30.0;    //% Pumpen PWM red. zwischen BZ_on und BZ_max linear 
+float pwm_cycle   =  20.0;    //ms für PWM Period
+float pwm_on      =  12.0;    //ms für PWM high
+float pwm_pro     =     0;    //PWM Taktung
 
 // Monitoring Parameter
 int   debug       =     1;    //Serial Output on (1)
 float sample      =     5;    //Serial Output Samples per Second
+char  com_in[8]          ;    //Serial input
+
+
+// Mosfet Parameter
+int   Cel_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 mos_temp    =     0;    //°C Mosfet
 
 // 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   Cel_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
+char  input_c     =     0;    //Serial comand input
+
 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
+float bz_temp     =     0;    //BZ Temperatur
+bool  temp_1_2    = false;    //Auswahl Temperaturkanal
+int   pump_block  =     2;  
+
+unsigned int counter_cycle = 0;      //Counter PWM-Cycles for Pump-Purge
+unsigned int counter_takt  = 0;      //Counter for PWM Pump
 
-  
+
+float Regler_Hz = 1000.0;  
+
+
+
+
 void load_cfg()
 {
- char read[24][5];
+ char read[25][5];
 
  char  i = 0;
  char  j = 0;
  int   c = 0;
  float  temp;
  
- for (j = 0; j<24; j++)
+ for (j = 0; j<26; j++)
   {
-   for (i = 0; i<8; i++)
+   for (i = 0; i<6; i++)
     {
      read[j][i] = '\0';
     }
@@ -108,7 +135,7 @@
            if (c == ';'){read[j][0] = i; i = 0; j++;} 
            else {i++; read[j][i] = c;}
           }
-       fclose(fp);
+     fclose(fp);
       
        
        sscanf(&read[ 0][1], "%f", &temp); bz_max      = temp;
@@ -120,26 +147,30 @@
        sscanf(&read[ 6][1], "%f", &temp); bz_cur_add  = temp;
        sscanf(&read[ 7][1], "%f", &temp); bz_c_i_max  = temp;
        sscanf(&read[ 8][1], "%f", &temp); bz_c_i_min  = temp;      
-      
-       sscanf(&read[ 9][1], "%f", &temp); cap_max     = temp; 
-       sscanf(&read[10][1], "%f", &temp); cap_p_max   = temp;
-       sscanf(&read[11][1], "%f", &temp); cap_min     = temp;
-       sscanf(&read[12][1], "%f", &temp); cap_p_min   = temp; 
-       sscanf(&read[13][1], "%f", &temp); cap_delta   = temp;
+       sscanf(&read[ 9][1], "%f", &temp); bz_temp_max = temp;
+       
+       sscanf(&read[10][1], "%f", &temp); cap_max     = temp; 
+       sscanf(&read[11][1], "%f", &temp); cap_p_max   = temp;
+       sscanf(&read[12][1], "%f", &temp); cap_min     = temp;
+       sscanf(&read[13][1], "%f", &temp); cap_p_min   = temp; 
+       sscanf(&read[14][1], "%f", &temp); cap_delta   = temp;
        
-       sscanf(&read[14][1], "%f", &temp); purge_start = temp;
-       sscanf(&read[15][1], "%f", &temp); purge_end   = temp;
-       sscanf(&read[16][1], "%f", &temp); boost_time  = temp;
-       sscanf(&read[17][1], "%f", &temp); pwm_cycle   = temp;
-       sscanf(&read[18][1], "%f", &temp); pwm_on      = temp;
+       sscanf(&read[15][1], "%f", &temp); purge_start = temp;
+       sscanf(&read[16][1], "%f", &temp); purge_end   = temp;
+       sscanf(&read[17][1], "%f", &temp); boost_time  = temp;
+       sscanf(&read[18][1], "%f", &temp); pump_red    = temp;
+       sscanf(&read[19][1], "%f", &temp); pwm_cycle   = temp;
+       sscanf(&read[20][1], "%f", &temp); pwm_on      = temp;
        
-       sscanf(&read[19][1], "%f", &temp); debug       = temp;
-       sscanf(&read[20][1], "%f", &temp); sample      = temp;   
+       sscanf(&read[21][1], "%f", &temp); Regler_Hz   = temp;
+       sscanf(&read[22][1], "%f", &temp); debug       = temp;
+       sscanf(&read[23][1], "%f", &temp); sample      = temp;   
        
-       boost = (boost_time * 1000) / pwm_cycle;     
+       boost = boost_time * 1000 / pwm_cycle;
+       pump_block = 5 / purge_end;      
      }
     
-    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"           );
@@ -153,6 +184,7 @@
     pc.printf(" BZ Strom max.  [A] : %5.1f \n\r",bz_cur_add     );
     pc.printf(" BZ Strom I max.[%c] : %5.1f \n\r",37,bz_c_i_max );
     pc.printf(" BZ Strom I min.[%c] : %5.1f \n\r",37,bz_c_i_min ); 
+    pc.printf(" BZ Temp max.   [%cC]: %5.1f \n\r",176,bz_temp_max); 
     pc.printf("-------------CAP---------------- \n\r"           );
     pc.printf(" CAP max        [V] : %5.1f \n\r",cap_max        );
     pc.printf(" CAP max        [%c] : %5.1f \n\r",37,cap_p_max  );
@@ -163,15 +195,78 @@
     pc.printf(" Purge on       [s] : %5.1f \n\r",purge_start    );
     pc.printf(" Purge off      [s] : %5.1f \n\r",purge_end      );
     pc.printf(" Boost          [s] : %5.1f \n\r",boost_time     );    
-    pc.printf(" PWM cycle      [ms]: %5d \n\r"  ,pwm_cycle      );
-    pc.printf(" PWM on         [ms]: %5d \n\r"  ,pwm_on         );
+    pc.printf(" Pumpe abregeln [%c] : %5.1f \n\r",37,pump_red   );
+    pc.printf(" PWM cycle      [ms]: %5.0f \n\r"  ,pwm_cycle    );
+    pc.printf(" PWM on         [ms]: %5.0f \n\r"  ,pwm_on       );
     pc.printf("------------Monitor------------- \n\r"           );
-    pc.printf(" Serial output  [bool]: %5d \n\r"  ,debug        );
-    pc.printf(" Samplerate     [Hz]  : %5.0f \n\r",sample       );
+    pc.printf(" Regler Frequenz[Hz]  :%4.0f \n\r"  ,Regler_Hz   );
+    pc.printf(" Serial output  [bool]: %3d \n\r"  ,debug        );
+    pc.printf(" Samplerate     [Hz]  : %3.0f \n\r",sample       );
     pc.printf("******************************** \n\r"           );
     pc.printf("\n\r"                                            );
 }
 
+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 ((mosfet == mosfet_close)
+     &&(Load == true))          myled2 = 1; else myled2 = 0;                //LED = Gate Zustand Mosfet 1
+  if (pump_on == 1)             myled3 = 1; else myled3 = 0;                //LED = Pumpe an
+}
+
+void led_beep()
+{
+ LED_timer.detach();
+ mosfet = mosfet_open;
+ myled = 0; myled1 = 0; myled2 = 0; myled3 = 0;
+ wait(0.1);
+ myled = 1; 
+ wait(0.1);
+ myled1 = 1; 
+ wait(0.1);
+ myled2 = 1;
+ wait(0.1);
+ myled3 = 1;
+ wait(0.1);
+ LED_timer.attach   (&LED   , 0.200);
+ myled3 = 1; 
+}
+
+
+void do_command()
+{
+switch(com_in[0])
+            {        
+                case 'r':  load_cfg();
+                           led_beep();
+                           break;       
+            }
+}
+
+
+void get_input()
+{
+ char wert;
+
+    while (pc.readable() == true)     
+    { 
+          wert = pc.getc();                                       //Char lesen
+          if ((wert == 'c') && ((input_c == 0))) {input_c = 1;}       //Command Char 1 prüfen
+          if ( wert == 10) {input_c = 0; do_command(); com_in[0] =' ';}   //Command End prüfen
+          
+          if (input_c == 2)
+             {                
+              com_in[0] = wert;
+             }
+          
+          if ((input_c == 1) && (wert == '_')){input_c = 2;}         //Command Char 2 prüfen                        
+    }   
+}
+
+
+
+
 
 int semihost_powerdown() 
 {
@@ -180,149 +275,277 @@
 }
 
 
+int port(int number)
+{
+ if (number == 1) {if (In1 == 1) return 1; else return 0;}
+ if (number == 2) {if (In2 == 1) return 1; else return 0;}
+ if (number == 3) {if (In3 == 1) return 1; else return 0;}
+ if (number == 4) {if (In4 == 1) return 1; else return 0;}
+ if (number == 5) {if (In5 == 1) return 1; else return 0;}
+ if (number == 6) {if (In6 == 1) return 1; else return 0;}
+return 2;
+}
+
 void SEND()
 {
+ float temp1 = 0;
+ float temp2 = 0;
+ float temp3 = 0;
+ float temp4 = 0;
+ float temp5 = 0;
+ char  temp6 = 0;
+ 
  bool status= false;
- if (debug == 1)
- {
-  if (mosfet1 == mosfet1_close) status = true;
-  if (Load == true) 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);
-  if (status == true) mosfet1 = mosfet1_close; 
+
+switch (debug)
+{
+ case 1:     
+             if (mosfet == mosfet_close) status = true;
+             if (Load == true) mosfet = mosfet_open;
+             pc.printf("BZ: %4.1f/%4.1f-%4.1f+%4.1f  CAP: %4.1f/%4.1f-%4.1f  Pump : %2d Purge: %3.1f/%3.1f-%3.1f  Load: %02d/%02d-%02d Current: %4.2f Temp BZ: %3.1f Temp Mos: %3.1f\n\r"
+             ,bz,bz_min,bz_on,bz_max,cap,cap_min,cap_max,int(pwm_pro*100),float(counter_cycle*pwm_cycle/1000),
+             purge_start,purge_end,int(Load_Level),int((Cap_Level + Cel_Level) + bz_c_i_min), 
+             int((Cap_Level + Cel_Level) + bz_c_i_max), current, bz_temp, mos_temp);
+             if (status == true) mosfet = mosfet_close; 
+             break;
+
+ case 2:
+             if (mosfet == mosfet_close) status = true;
+             if (Load == true) mosfet = mosfet_open;
+             pc.printf("In1: %2d In2: %2d In3: %2d In4: %2d In5: %2d In6: %2d \n\r",port(1),port(2),port(3),port(4),port(5),port(6));      
+             if (status == true) mosfet = mosfet_close; 
+             break;
+ 
+ case 3:
+             if (mosfet == mosfet_close) status = true;
+             if (Load == true) mosfet = mosfet_open;
+             pc.printf("AI1: %3.2f AI2: %3.2f AI3: %3.2f AI4: %3.2f AI5: %3.2f AI6: %3.2f \n\r",cap_in.read(),bz_in.read(),mos_in.read(),temp_in.read(),AI_5.read(),cur_in.read());       
+             if (status == true) mosfet = mosfet_close; 
+             break;
+
+ case 4:
+             pc.printf("Change \n\r");       
+             pump    = !pump ;
+             purge   = !purge;
+             h2_blow = !h2_blow;
+             waterp  = !waterp;
+             mosfet  = !mosfet;
+             break;   
+               
+
+
+ case 5:   
+             
+             if (((Cap_Level + Cel_Level) + bz_c_i_min) > 0) {temp1 = ((Cap_Level + Cel_Level) + bz_c_i_min);}
+             else temp1 = 0;
+             
+             if (((Cap_Level + Cel_Level) + bz_c_i_max) > 0) {temp2 = ((Cap_Level + Cel_Level) + bz_c_i_max);}
+             else temp2 = 0;
+             
+             if (current > 0) {temp3 = current;}
+             else temp3 = 0;
+             
+             if (bz_temp > 0) {temp4 = bz_temp;}
+             else temp4 = 0;
+             
+             if (mos_temp > 0) {temp5 = mos_temp;}
+             else temp5 = 0;
+             
+             temp6 = (purge<<7)+(pump_on<<6)+(In1<<5) + (In2<<4) + (In3<<3) + (In4<<2) + (In5<<1) + In6;
+             
+             pc.printf("%c%c%c%c%c%c%c%c%c%c%c%c",255,128,                                                            //0,1
+                                           char(int(bz*6)),                                      //0-35   zu 0-250    2     0
+                                           char(int(cap*7)),                                     //0-38   zu 0-250    3     1
+                                           char(int(Load_Level * 2.5)),                          //0-100  zu 0-250    4     2
+                                           char(int(temp1      * 2.5)),                          //0-100  zu 0-250    5     3
+                                           char(int(temp2      * 2.5)),                          //0-100  zu 0-250    6     4
+                                           char(int(temp3      * 25 )),                          //0-10   zu 0-250    7     5
+                                           char(int(temp4      * 2.5)),                          //0-100  zu 0-250    8     6
+                                           char(int(temp5      * 2.5)),                          //0-100  zu 0-250    9     7
+                                           char(int(pwm_pro    * 250)),                          //0-100  zu 0-250   10     8
+                                           temp6                                                 //Statusbits Din/Pump/Purge
+                      );
+             break;
  }
+
 }
 
 
-void LED()
+
+
+
+
+void TEMP() 
 {
-  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)
-     &&(Load == true))          myled2 = 1; else myled2 = 0;                //LED = Gate Zustand Mosfet 1
-  if (pump_on == 1)             myled3 = 1; else myled3 = 0;                //LED = Pumpe an
+if (temp_1_2 == true) bz_temp  = (temp_in.read()/0.00407)- 48.3;
+else                  mos_temp = ( mos_in.read()/0.00407)- 50.3;
+temp_1_2 = !temp_1_2;
 }
 
 
+
 void PUMPE()
 {
- counter_ms++;
+ float regler = 1;
+ 
+ counter_takt++;                                        //Aufrufzähler 
  
- if ((bz > bz_max) && (cap > (cap_max - (In1 * cap_delta))))
+ 
+ 
+ if (cap > (cap_max - (!In1 * cap_delta)))
  {
   pump_on = false;
+  pwm_pro = 0;
  }
  
  
  if ((cap <= cap_min) || (pump_on == true)) //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
+
+   if (bz > bz_on) {1 - ((pump_red / ((bz_max-(!In1 * cap_delta)) - bz_on) * (bz - bz_on)) / 1000);}               //Luftreduzierung wenn Spannung über BZ_on (lineare Reduzierung bis BZ_max um pump_red(%))
+                 
+   pwm_pro = ((float(pwm_on) * regler) / pwm_cycle );                                                               //PWM Prozent für Monitoring
+  
+   
+   if ((pump_block == 0) && (counter_takt > (pwm_cycle - pwm_on) * Regler_Hz / 1000.0)) {pump = 1 ;}     //Set PWM from low to high 
+   
+                                     
+   if (counter_takt > (pwm_cycle * Regler_Hz / 1000))                             //End PWM cycle
     {
+     if (counter_cycle == (50)) TEMP();                                           //Temperatur messen
+     counter_takt  = 0;
      counter_cycle++;
-     counter_ms = 0;
               
-     if (boost > 0) boost--;
+     if ((boost > 0) && (pump_block == 0)) {boost--;}
      
-     if ((counter_cycle < (1000 / pwm_cycle) * purge_start) || (boost <= 0) || (In1 == 0))  
-      {   
-       pump  = 0;                                                                 //PWM Betrieb
+     if (counter_cycle >= ((purge_start - boost_time) * 1000 / pwm_cycle))         //Vorgezogener Anlauf Purgepumpe
+      {                                                                     
+       if (pump = 1) purge = 1;                                     
+      }
+     
+     if (counter_cycle < ((purge_start - boost_time) * 1000 / pwm_cycle))  
+      {           
+       if (boost == 0) pump = 0;                                                  //PWM Betrieb
        purge = 0;                                     
       }
      else
       {
-       if (pump == 1) purge   = 1;                                                //Purge Betrieb
+       pump = 0;
       }
              
-     if (counter_cycle > (1000 / pwm_cycle) * purge_end)                          //Purge Ende 
+     if (counter_cycle >= (purge_end * (1000 / pwm_cycle )))                           //Purge Ende   counter_cycle = 1 pro Mosfet (PWM 1000/Regler_Hz in [ms])
       {
        counter_cycle = 0; 
        purge = 0; 
        pump = 0;
+       if (pump_block > 0) pump_block--;
       }    
     }      
   }
  else
   {
    pump_on = 0; pump = 0; purge = 0;                                       //Pumpe aus
-   boost = (boost_time * 1000) / pwm_cycle;                                // Boost für nächsten Start setzen
+   boost = (boost_time * 1000 / pwm_cycle);                                // Boost für nächsten Start setzen
   }
 
 }
 
 int main() 
 { 
+    mosfet = mosfet_open;                                                //Mosfet schließen
     pc.baud(115200);                                                     //config Serial Port
     load_cfg();                                                          //init config File
-    semihost_powerdown();                                                //Mbed Interface powerdown
+    //semihost_powerdown();                                                //Mbed Interface powerdown
     PC_OUT_timer.attach(&SEND  , (1/sample));                            //Serial output Timer
-    LED_timer.attach   (&LED   , 0.200     );                            //LED Status    Timer
+    LED_timer.attach   (&LED   , 0.200     );                            //LED Status    Timer                      
+    
     t.start();                                                           //Timer für PWM starten
     float bz_faktor;                                                     //Temp Variable
-
+    unsigned int pwm_cycle_count;
+    bool  power_up = 0;      
+    
+    pwm_cycle_count = ((1000000/Regler_Hz)); 
     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.75) - 4.12; 
-     t.reset();                                                          // Timer für 1 kHz starten 
-     PUMPE();                                                            //Pumpen PWM aufrufen         
-
+     while (t.read_us() <= pwm_cycle_count){};
+     
+     get_input();                                                        //µs Timer für Mosfet PWM starten
+     PUMPE();                                                            //Pumpen PWM aufrufen
+                                                                                      
+     bz  = (((24.54 * bz_in * bz_in)+(31.812 * bz_in)+0.04)*2 + bz )/3;                                    //BZ  RAW in Spannung umrechnen (2*neu zu 1*alt Glättung) (immer)
+     if (counter_takt%2 == 0){cap = (((24.54 * cap_in * cap_in)+(31.812 * cap_in + 0.04))*2 + cap_in )/3;}          //CAP RAW in Spannung umrechnen (2*neu zu 1*alt Glättung) (jedes 2.mal)
+     else                    {current = (cur_in - 0.32) * 12.568;}           //Current RAW in Spannung umrechnen (ohne Glättung)       (jedes 2.mal)
+     
+                                                                        
+     
 //***Regulate Cell Level***     
-     Cel_Level = (bz_faktor * (bz - bz_min) + bz_p_unten) * 10;                  //%Load aus Zellenspannung berechnen
+     Cel_Level = (bz_faktor * (bz - bz_min) + bz_p_unten);          //%Load aus Zellenspannung berechnen
 
 //***Regulate Cap´s Level*** 
-     Cap_Level   = (((cap / cap_max) * (cap_p_max - cap_p_min)) + cap_p_min) * 10;  //%Load aus Cap Level
+     Cap_Level   = (((cap / cap_max) * (cap_p_max - cap_p_min)) + cap_p_min);  //%Load aus Cap Level
 
 //***Regulate Current Level***     
-     if ((current-(bz_current + (In2 * bz_cur_add))) > 0)
-      {if (Cur_Level > (bz_c_i_min*10)) Cur_Level--;}                     //to much Load
+     if (cap < cap_min) {power_up = 1;};
+     if (cap > 0.9*cap_max){power_up = 0;}; 
+     if ((current-(bz_current + (power_up * bz_cur_add))) > 0)
+      {if (Cur_Level > (bz_c_i_min)) Cur_Level--;}                     //to much Load
      else
-      {if (Cur_Level < (bz_c_i_max*10)) Cur_Level++;}                     //less Load  
+      {if (Cur_Level < (bz_c_i_max)) Cur_Level++;}                     //less Load  
            
 //*** Sum all Regulators     
  
      Load_Level  = Cur_Level;   
      Load_Level  = Load_Level + Cap_Level;
      Load_Level  = Load_Level + Cel_Level;
-
+     if (Load_Level > 100) Load_Level = 100;
+     if (Load_Level <   0) Load_Level =   0;
 
-     if (Load == true)                                                   // Laden aktiv
+ t.reset();  
+
+     if (Load == true)                                                 // Laden aktiv
       {
                                                                        
-       if (bz > bz_min || bz > bz_max)                                   // Zelle über min. Spannung oder über max Spannung zum Entladen
+       if (bz > bz_min || bz > bz_max)                                 // Zelle über min. Spannung oder über max Spannung zum Entladen
         { 
-         while (t.read_us() <= 920)                                      // während der PWM (1khz Periode)
+         while (t.read_us() <= pwm_cycle_count)                        // 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
+           if (t.read_us() < Load_Level * 10000 / Regler_Hz)            // %Load PWM zu Timer vergleich
+            {mosfet = mosfet_close;}                                   // %Load PWM nicht erreicht Mosfet an
            else
-            {mosfet1 = mosfet1_open;}                                    // %Load PWM erreicht Mosfet aus
+            {mosfet = mosfet_open;}                                    // %Load PWM erreicht Mosfet aus
           }
         }
        else
         {
-          mosfet1 = mosfet1_open ;                                      // Mosfet wegen Unterspannung BZ auskoppeln 
-          Load = false;                                                 // Laden beenden bis BZ > BZ on (Sicherungsschaltung)
+          mosfet = mosfet_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() <= 920){};
+       if (bz > cap + 0.5){mosfet = mosfet_open ;}                      // Mosfet im nicht Ladebetrieb auskoppeln 
+       else               {mosfet = mosfet_close;}                      // Mosfet im nicht Ladebetrieb einkoppeln (Treiber stromfrei = Stromsparen) 
       }  
-       
+    
+    
      
-     if (( cap < cap_min) && (bz > bz_on)) Load = true;   // Cap unter Minimum oder BZ über Maximum = Laden beginnen
-     if (  cap >= cap_max                ) Load = false;  //  
-     if (  bz  > bz_max                  ) Load = true;   // Überladung abführen
+     if ((current < 0.2) && (Cur_Level > (0.9 * bz_c_i_max)) && (Load == true)){Load = false; load_fail = 100;}
+    
+     if (( cap < cap_min) && (bz > bz_on) && (Load == false)) 
+       {
+        Load = true; 
+        if (bz_c_i_min < 0) {Cur_Level = 2 * bz_c_i_min;}else {Cur_Level = -100;}   // Cap unter Minimum oder BZ über Maximum = Laden beginnen / PWM vom Minimum Starten
+       }
+       
+     if (  bz  > bz_max && load_fail == 0) Load = true;   // Überladung abführen
+     
+     if (load_fail > 0){load_fail--;pump_on = false;}
+   
     }
-
+ 
 }