Mosfet Driver

Dependencies:   mbed

main.cpp

Committer:
HMFK03LST1
Date:
2013-07-21
Revision:
6:4af29761b1f0
Parent:
5:d814001b8aae

File content as of revision 6:4af29761b1f0:

#include "mbed.h"

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

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

float version = 1.1;                             //Program Version  

bool mosfet_open  = false;                      //Mosfet1 geschlossen
bool mosfet_close = true;                       //Mosfet1 offen


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

DigitalOut pump   (p36);
DigitalOut purge  (p35);
DigitalOut h2_blow(p34);
DigitalOut out4   (p33);
DigitalOut mosfet (p21);
DigitalOut xbee_rst(p11);

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);
Serial pc(p9, p10);           // XBee
Ticker PC_OUT_timer;          // Output Monitoring to Serial
 
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
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_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 
float bz_faktor   =     0;    //Temp Variable

// SuperCap Parameter
float cap_max     =  35.0;    //CAP Spannung max. (Abschaltung)
float cap_p_max   =  90.0;    //CAP Prozent Load bei 0V
float cap_min     =  30.0;    //CAP Spannung min. (Zelle an)
float cap_p_min   =  15.0;    //CAP Prozent Load bei 0V
float cap_delta   =   1.5;    //Absenkung der Spannung mit Din
float cap_low     =  26.0;    //Grenze zur Volleinkopplung                                  ***
float cap_up      =  29.5;    //Grenze high current                                         ***

// 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
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
float pow_up_on   =  28.5;    //Einschalten Boostpumpe V unter Cap_min                      ***
float pow_up_off  =  29.5;    //Ausschalten Boostpumpe V unter Cap_min                      ***


// Monitoring Parameter
int   debug       =     1;    //Serial Output on (1)
float sample      =     5;    //Serial Output Samples per Second
char  com_in[8]          ;    //Serial input
float mos_t_max   =    85;

// Mosfet Parameter
int   Cel_Level   =     0;    //% Load aus Bz Spannung
int   Cap_Level   =     0;    //% Load aus Cap Spannung
float Cur_Level   =     0;    //% Load aus BZ Strom
float Load_Level  =     0;    //% Load aus Bz und Cap
float mos_temp    =     0;    //°C Mosfet

// Temp Variable
bool  pwm_mode    = false;
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
char  input_c     =     0;    //Serial comand input

float bz          =     0;    //Spannung Brennstoffzelle
float cap         =     0;    //Spannung SuperCap
float current     =     0;    //Strom in den Mosfet
float bz_temp     =     0;    //BZ Temperatur
bool  temp_1_2    = false;    //Auswahl Temperaturkanal
int   pump_block  =     2;  
int   mos_block   =  1000;
int   purge_h2_on =     0;
bool  power_up    =     0; 
int   h2purge     =   100;
int   h2purge_count =   0;   
int   msg_cnt     =     0;
bool  mos_over    = false;
bool  pump_2      = true;

unsigned int counter_cycle = 0;      //Counter PWM-Cycles for Pump-Purge
unsigned int counter_takt  = 0;      //Counter for PWM Pump
unsigned int counter_send  = 0;
unsigned int temp_takt     = 0;
float pwm_cycle_count      = 0;
float zahler               = 0;

float Regler_Hz = 1000.0;  


void load_cfg();
void LED();
void led_beep();
void do_command();
void get_input();
int semihost_powerdown();
int port(int);
void SEND();
void TEMP();
void PUMPE();
void control_block();
bool LOAD_STATE();

void mos_pwm()
{
 int temp = 0;
  temp = int((Load_Level * pwm_cycle_count) / 100.0);                                  
  while(t.read_us() <= temp){ mosfet = mosfet_close;};                           // %Load PWM zu Timer vergleich            {}                                        
  if   (Load_Level < 100.0) { mosfet = mosfet_open ;};         // %Load PWM erreicht Mosfet aus oder dauer an                                                                               
}

int main() 
{ 
    
    mosfet = mosfet_open;                           //Mosfet auf
    pc.baud(115200);                                //config Serial Port

    load_cfg();                                     //init config File               
    t.start();                                      //Timer für PWM starten     

   while(1) 
    {
     while (t.read_us() <= pwm_cycle_count){};      // Time Sync
     SEND();                                        // Send MSG
     get_input();                                   // Serial Command input
     t.reset();                                     // Timer reset
     
     if (LOAD_STATE() == true) 
      {
       if (Load_Level > 50)      {
                                  mosfet = mosfet_close;                     // Mosfet close
                                  control_block();                           // PID Block
                                  mos_pwm();                                 // Mosfet PWM
                                 }
        else                     {
                                  mos_pwm();                                 // Mosfet PWM
                                  control_block();                           // PID Block 
                                 }; 
       }
      else
       {
        control_block();                                                      // PID Block
       }    
    }
}


void xbee_rs()
 {
  xbee_rst = 0; wait_ms(1); xbee_rst = 1;
 }

void load_cfg()
{
 char read[27][5];

 char  i = 0;
 char  j = 0;
 int   c = 0;
 float  temp;
 
 for (j = 0; j<28; j++)
  {
   for (i = 0; i<6; 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); bz_current  = temp;
       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); 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[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[21][1], "%f", &temp); Regler_Hz   = temp;
       sscanf(&read[22][1], "%f", &temp); debug       = temp;
       sscanf(&read[23][1], "%f", &temp); sample      = temp;
       
       sscanf(&read[24][1], "%f", &temp); mos_t_max   = temp;   
       
       boost           = boost_time * 1000 / pwm_cycle;                 //boost in Pumpen PWM-Cycle
       pump_block      = 5 / purge_end;                                 //5s Pumpen aus
       mos_block       = 2000000.0/Regler_Hz ;                          //2s Mosfet aus
       pwm_cycle_count = 1000000.0/Regler_Hz ;                          //ns pro Mosfet PWM-Cycle
       bz_faktor       = (bz_p_oben - bz_p_unten)/(bz_max - bz_min);    //
       h2purge         = 600 / purge_end;
       xbee_rs();
     }
    
    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] : %5.1f \n\r",bz_max         );
    pc.printf(" BZ max         [%c] : %5.1f \n\r",37,bz_p_oben  );
    pc.printf(" BZ Laden on    [V] : %5.1f \n\r",bz_on          );
    pc.printf(" BZ Laden off   [V] : %5.1f \n\r",bz_min         );
    pc.printf(" BZ Laden off   [%c] : %5.1f \n\r",37,bz_p_unten );
    pc.printf(" BZ Strom norm  [A] : %5.1f \n\r",bz_current     );
    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  );
    pc.printf(" CAP min        [V] : %5.1f \n\r",cap_min        );
    pc.printf(" CAP min        [%c] : %5.1f \n\r",37,cap_p_min  );
    pc.printf(" CAP up  add A  [V] : %5.1f \n\r",cap_up         );
    pc.printf(" CAP low Mos on [V] : %5.1f \n\r",cap_low        );
    pc.printf(" CAP lo on Din  [-V]: %5.1f \n\r",cap_delta      );
    pc.printf("----------Pump & Purge---------- \n\r"           );
    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(" 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(" All Pumps on   [V] : %5.1f \n\r"  ,pow_up_on    );
    pc.printf(" All Pumps off  [V] : %5.1f \n\r"  ,pow_up_off   );
    pc.printf("------------Monitor------------- \n\r"           );
    pc.printf(" Mosfet Temp max[%cC]  :%4.0f \n\r",176,mos_t_max);
    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 (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()
{
 myled = 0; myled1 = 0; myled2 = 0; myled3 = 0;
 wait(0.05);
 myled = 1; 
 wait(0.05);
 myled1 = 1; 
 wait(0.05);
 myled2 = 1;
 wait(0.05);
 myled3 = 1;
 wait(0.05);
}


void do_command()
{
switch(com_in[0])
            {        
                case 'r':  mosfet = mosfet_open;
                           load_cfg();
                           led_beep();
                           break;       
            
                case 'm':  
                           mosfet = mosfet_open;
                           debug = 5;
                           break;
                
                case 'n':  
                           mosfet = mosfet_open;
                           debug = 0;
                           break;
                
                
                
                case 'l':  debug = 6;
                           break;
                           
                case 'u':  pump_on = true;
                           break;
                           
                case '0':  mos_over = false;
                           break;
                
                case '1':  mos_over = true;
                           break;        
                
                case '2':  pump_2 = true;
                           break;
                
                case '3':  pump_2 = false;
                           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() 
{
 uint32_t arg;
 return __semihost(USR_POWERDOWN, &arg); 
}


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 -1;
}

void SEND()
{
 float temp1 = 0;
 float temp2 = 0;
 float temp3 = 0;
 float temp4 = 0;
 float temp5 = 0;
 char  temp6 = 0;



if (counter_send >= int(Regler_Hz / sample)) 
 { 
  LED();
  counter_send = 0;
  
  switch (debug)
   {
    case 1:           
             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 H2purge: %03d\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, h2purge_count);
             break;

    case 2:
             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));      
             break;
 
    case 3:         
             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());
             break;

    case 4:
             pc.printf("Change \n\r");       
             pump    = !pump ;
             purge   = !purge;
             h2_blow = !h2_blow;
             out4    = !out4;
             mosfet  = !mosfet;
             break;   
               


    case 5:   
             mosfet = mosfet_open;
             
             if (msg_cnt > 1000) {xbee_rs(); msg_cnt = 0;} else {msg_cnt++; xbee_rst = 1;};
             
             if (((Cap_Level + Cel_Level) + bz_c_i_min) > 0) {temp1 = ((Cap_Level + Cel_Level) + bz_c_i_min);}
             else temp1 = 0;
             if (temp1 > 100) temp1 = 100;
             if (((Cap_Level + Cel_Level) + bz_c_i_max) > 0) {temp2 = ((Cap_Level + Cel_Level) + bz_c_i_max);}
             else temp2 = 0;
             if (temp2 > 100) temp2 = 100;
             
             if (current > 0) {temp3 = current;}
             else temp3 = 0;
             if (current > 10){temp3 = 10;};
             
             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%c",
                                           255,128,                                                            //0,1
                                           char(int(bz*6)),                                      //0-42   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
                                           char(h2purge_count        ),                          //counter 0 -       11     9 
                                           temp6                                                 //Statusbits        12     10
                      );
             break;
 
    case 6:   
            mosfet = mosfet_open;      
            break;
   }
 }
}


void TEMP() 
{
 if (temp_1_2 == true) bz_temp  = (temp_in.read()/0.00407)- 53.6;
 else                  mos_temp = ( mos_in.read()/0.00407)- 54.1;
 
 temp_1_2 = !temp_1_2;
 
 if (  (mos_temp >  mos_t_max  )   
     ||(bz_temp  >  bz_temp_max)){power_up = 0; pump_block = (10 / purge_end);}                 ;
}


void PUMPE()
{                                                     
 temp_takt++;                                        //Aufrufzähler
  if (temp_takt >= 500){TEMP();temp_takt = 0;}       //alle 500ms
 
//*** Autopurge

 if (    (h2purge    == 0)                            // Purge Sperre aus
      && (Cur_Level  == bz_c_i_max)                   // Current Integral auf maximum     
      && (pump_on    == 1)                            // Pumpe an
      && (cap < (0.95 * cap_low))                     // Capspannung niedrig  
      
      ) {mosfet = mosfet_open; h2_blow = 1; wait_ms(40); h2_blow = 0; h2purge = 495 * Regler_Hz/pwm_cycle; h2purge_count++;} else {h2_blow = 0;}
 
 
//*** Abschalten
 if (  (cap >= (cap_max - (In1 * cap_delta)))         // Abschalten wenn CAP max erreicht
     ||(bz  >  (bz_max))                              // Abschalten wenn BZ max überrschritten 
    )                                                     
  {
   pump_on = false;
   pwm_pro = 0;
  }

//*** Einschalten
 if ( 
      ((cap <= (cap_min - (In1 * cap_delta)))           // Einschalten wenn Cap min erreicht
     ||(pump_on == true))                               // Einschalten wenn Pumpe in Betrieb - Abschaltbedingung nicht erreicht
     && (In2 == false)                                  // Serviceschalter nicht betätigt
    )                                                   
  {
   pump_on = true;
   pwm_pro = ((float(pwm_on)) / pwm_cycle );                                                // PWM Prozent für Monitoring              
    
   if ((pump_block == 0) && (counter_takt > (pwm_cycle - pwm_on))) {pump = 1 ;}             //Set PWM from low to high 
                                     
   if (counter_takt > pwm_cycle)                                                            //End PWM cycle    40ms * 7500/1000=7.5/ms
    {                 
     counter_takt  = 0;
     counter_cycle++;
              
     if (h2purge > 0){h2purge--;};
     
     if ((boost > 0) && (pump_block == 0)) {boost--; pump = 1;} else {pump = 0;}            //PWM Betrieb
     
     if (
          (   (counter_cycle == int((purge_start - boost_time) * (1000 / pwm_cycle)))       //Vorgezogener Anlauf Purgepumpe
          || (power_up == 1))
        )   
      {                                                                     
       if (pump_2 == true) purge = 1; else purge = 0;                                     
      } 
       
     if (counter_cycle == int((purge_start) * (1000 / pwm_cycle)))                          //Purge Start
      {                                                                                                                                  
      }
             
     if (counter_cycle >= int(purge_end * (1000 / pwm_cycle )))          //Purge Ende   counter_cycle = 1 pro Mosfet (PWM 1000/Regler_Hz in [ms])
      {
       counter_cycle = 0; 
       if ((power_up == 0))purge = 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
  }
}



void control_block()
{    
 float cur_t;
 float bz_t;
 float cap_t;
 float bz_cur_t;
 
     counter_takt++;
     counter_send++;        
    
     
     if (counter_takt%(int(Regler_Hz/1000)) == 0) PUMPE();                                   //Pumpen PWM aufrufen
     cur_t = (cur_in - 0.270);                         
     current = ( (cur_t * cur_t * 24.975) + (cur_t * 4.701) + (current) ) / 2;               //Current RAW in Spannung umrechnen (immer) -0.28
     if (current > 10.1) current = 10.1;
     if (counter_takt%2 == 0){cap_t = cap_in; cap = (((24.54 * cap_t * cap_t)+(31.812 * cap_t) + 0.04) + cap * 2)/3;}   //CAP RAW in Spannung umrechnen (1*neu zu 2*alt Glättung) (jedes 2.mal)
     else                    {bz_t  = bz_in ; bz  = (((24.54 * bz_t  * bz_t )+(31.812 * bz_t ) + 0.04) + bz  * 2)/3;}   //BZ  RAW in Spannung umrechnen (1*neu zu 2*alt Glättung)(jedes 2.mal)                                                                      
     
//***Regulate Cell Level***     
     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);                //%Load aus Cap Level

//***Regulate Current Level***     
      if ((cap <  pow_up_on ) && (cap > 10)) {power_up = 1;};
      if ((cap >  pow_up_off)              ) {power_up = 0;}; 
      
      if ( (cap > cap_up) || (cap < 14)    ) {bz_cur_t = bz_current;} else {bz_cur_t = bz_current + bz_cur_add;};
      if ( (current - bz_cur_t) > 0        )
       {if ((Cur_Level > bz_c_i_min))                  {Cur_Level = Cur_Level - 0.2;}}                  //to much Amp-Load
      else
       {if ((Cur_Level < bz_c_i_max) && (bz > bz_min)) {Cur_Level = Cur_Level + 0.2;}}                  //less Amp-Load  
          
//*** Sum and limit all Regulators     
 
     Load_Level  = Cur_Level + Cap_Level + Cel_Level;   
     
     if (  (Load_Level > 100)
         ||(mos_over == true)
        )                       Load_Level = 100.1;
           
     if (  (cap > (bz_max - 3.5))
         ||(cap <  cap_low)
        )                       Load_Level = 100.1;

     if (Load_Level <   0)      Load_Level =   0;  
}




bool LOAD_STATE()
{
 if (
        ( bz   >  bz_on )                //  BZ über Einschaltspannung 
     && ( Load == false )                //  Laden noch nicht ausgelöst
    )
       {
        Load = true;              
        Cur_Level = bz_c_i_min;        // mit I min einkoppeln
       }
       
 if (
        (  Load      == true     )       // Laden aktiv
      &&( (bz - cap) >  0.0      )                     
      &&(  bz        >  bz_min   ) 
    ) 
    {return true;}
  else 
    {Load = false; mosfet = mosfet_open; return false;};
}