Hochschule München
/
PowerDriverforH2m
Mosfet Driver
Diff: main.cpp
- 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(); } }