Shell Eco Fuelcell controller

Dependencies:   FastPWM mbed

Committer:
HMFK03LST1
Date:
Tue Jan 07 12:02:52 2014 +0000
Revision:
0:adf68d4b873f
work in Progress

Who changed what in which revision?

UserRevisionLine numberNew contents of line
HMFK03LST1 0:adf68d4b873f 1 #include "mbed.h"
HMFK03LST1 0:adf68d4b873f 2 #include "math.h"
HMFK03LST1 0:adf68d4b873f 3 #include <string>
HMFK03LST1 0:adf68d4b873f 4 #include "FastPWM.h"
HMFK03LST1 0:adf68d4b873f 5 #include "components.cpp"
HMFK03LST1 0:adf68d4b873f 6
HMFK03LST1 0:adf68d4b873f 7
HMFK03LST1 0:adf68d4b873f 8 const char I2C_IN = 4;
HMFK03LST1 0:adf68d4b873f 9 const char I2C_OUT = 8;
HMFK03LST1 0:adf68d4b873f 10
HMFK03LST1 0:adf68d4b873f 11 const int PWM_Frequenz = 10000;
HMFK03LST1 0:adf68d4b873f 12
HMFK03LST1 0:adf68d4b873f 13 DigitalOut led_1(LED1);
HMFK03LST1 0:adf68d4b873f 14 DigitalOut led_2(LED2);
HMFK03LST1 0:adf68d4b873f 15 DigitalOut led_3(LED3);
HMFK03LST1 0:adf68d4b873f 16 DigitalOut led_4(LED4);
HMFK03LST1 0:adf68d4b873f 17
HMFK03LST1 0:adf68d4b873f 18 DigitalOut i2c_cs(p29);
HMFK03LST1 0:adf68d4b873f 19 DigitalOut xb_rst(p11);
HMFK03LST1 0:adf68d4b873f 20 DigitalOut mp_A(p15);
HMFK03LST1 0:adf68d4b873f 21 DigitalOut mp_B(p16);
HMFK03LST1 0:adf68d4b873f 22
HMFK03LST1 0:adf68d4b873f 23 AnalogIn current(p19);
HMFK03LST1 0:adf68d4b873f 24 AnalogIn mp1yA(p20);
HMFK03LST1 0:adf68d4b873f 25 AnalogIn mp2yA(p18);
HMFK03LST1 0:adf68d4b873f 26 AnalogIn mp2xA(p17);
HMFK03LST1 0:adf68d4b873f 27 DigitalIn mp2xD(p12);
HMFK03LST1 0:adf68d4b873f 28
HMFK03LST1 0:adf68d4b873f 29 FastPWM pwm_6(p21,-1); //Mosfet
HMFK03LST1 0:adf68d4b873f 30 DigitalOut h2_purge(p22);
HMFK03LST1 0:adf68d4b873f 31 FastPWM pwm_4(p23,-1); //H2O Fan
HMFK03LST1 0:adf68d4b873f 32 FastPWM pwm_3(p24,-1); //H20 Pump
HMFK03LST1 0:adf68d4b873f 33 FastPWM pwm_2(p25,-1); //Air Pump 2
HMFK03LST1 0:adf68d4b873f 34 FastPWM pwm_1(p26,-1); //Air Pump 2
HMFK03LST1 0:adf68d4b873f 35
HMFK03LST1 0:adf68d4b873f 36
HMFK03LST1 0:adf68d4b873f 37 Serial xbee(p9,p10);
HMFK03LST1 0:adf68d4b873f 38 Serial gps(p13,p14);
HMFK03LST1 0:adf68d4b873f 39 Serial pc(USBTX,USBRX);
HMFK03LST1 0:adf68d4b873f 40
HMFK03LST1 0:adf68d4b873f 41 SPI ext_spi(p5, p6, p7);
HMFK03LST1 0:adf68d4b873f 42
HMFK03LST1 0:adf68d4b873f 43 I2C i2c(p28, p27);
HMFK03LST1 0:adf68d4b873f 44
HMFK03LST1 0:adf68d4b873f 45 LocalFileSystem local("local"); //init Flashdrive for reading config file
HMFK03LST1 0:adf68d4b873f 46 FILE *fp;
HMFK03LST1 0:adf68d4b873f 47
HMFK03LST1 0:adf68d4b873f 48 struct_cap cap;
HMFK03LST1 0:adf68d4b873f 49 struct_fuelcell fc;
HMFK03LST1 0:adf68d4b873f 50 struct_h2o h2o;
HMFK03LST1 0:adf68d4b873f 51 struct_mosfet mosfet;
HMFK03LST1 0:adf68d4b873f 52 struct_o2 o2;
HMFK03LST1 0:adf68d4b873f 53 struct_switch switches;
HMFK03LST1 0:adf68d4b873f 54 struct_system sys;
HMFK03LST1 0:adf68d4b873f 55 struct_error error;
HMFK03LST1 0:adf68d4b873f 56
HMFK03LST1 0:adf68d4b873f 57
HMFK03LST1 0:adf68d4b873f 58 //Standard Funktions
HMFK03LST1 0:adf68d4b873f 59 //----------------------------------------------------------------------------------------------
HMFK03LST1 0:adf68d4b873f 60 void read_val(const char* name,const char* value);
HMFK03LST1 0:adf68d4b873f 61
HMFK03LST1 0:adf68d4b873f 62
HMFK03LST1 0:adf68d4b873f 63 double clamp(double value, double val_min, double val_max, bool* has_clamped)
HMFK03LST1 0:adf68d4b873f 64 {
HMFK03LST1 0:adf68d4b873f 65 *has_clamped = true;
HMFK03LST1 0:adf68d4b873f 66 if(value < val_min) return val_min;
HMFK03LST1 0:adf68d4b873f 67 if(value > val_max) return val_max;
HMFK03LST1 0:adf68d4b873f 68 *has_clamped = false;
HMFK03LST1 0:adf68d4b873f 69 return value;
HMFK03LST1 0:adf68d4b873f 70 }
HMFK03LST1 0:adf68d4b873f 71
HMFK03LST1 0:adf68d4b873f 72
HMFK03LST1 0:adf68d4b873f 73
HMFK03LST1 0:adf68d4b873f 74
HMFK03LST1 0:adf68d4b873f 75 void load_cfg()
HMFK03LST1 0:adf68d4b873f 76 {
HMFK03LST1 0:adf68d4b873f 77 char name_val[2][20];
HMFK03LST1 0:adf68d4b873f 78 char i = 0;
HMFK03LST1 0:adf68d4b873f 79 char name = 1;
HMFK03LST1 0:adf68d4b873f 80 int c = 50;
HMFK03LST1 0:adf68d4b873f 81
HMFK03LST1 0:adf68d4b873f 82 fp = fopen("/local/power.cfg", "r");
HMFK03LST1 0:adf68d4b873f 83 if ( fp != NULL )
HMFK03LST1 0:adf68d4b873f 84 {
HMFK03LST1 0:adf68d4b873f 85 while(c != EOF)
HMFK03LST1 0:adf68d4b873f 86 {
HMFK03LST1 0:adf68d4b873f 87
HMFK03LST1 0:adf68d4b873f 88 c = fgetc(fp);
HMFK03LST1 0:adf68d4b873f 89
HMFK03LST1 0:adf68d4b873f 90 if (c == 10){
HMFK03LST1 0:adf68d4b873f 91 name_val[name][i+1] = '\0';
HMFK03LST1 0:adf68d4b873f 92 name = 1;
HMFK03LST1 0:adf68d4b873f 93 i = 0;
HMFK03LST1 0:adf68d4b873f 94 read_val(&name_val[1][0], &name_val[0][0]);
HMFK03LST1 0:adf68d4b873f 95 }
HMFK03LST1 0:adf68d4b873f 96 else
HMFK03LST1 0:adf68d4b873f 97 {
HMFK03LST1 0:adf68d4b873f 98 if (c == '='){
HMFK03LST1 0:adf68d4b873f 99 name_val[name][i+1] = '\0';
HMFK03LST1 0:adf68d4b873f 100 name = 0;
HMFK03LST1 0:adf68d4b873f 101 i = 0;
HMFK03LST1 0:adf68d4b873f 102 }
HMFK03LST1 0:adf68d4b873f 103 else
HMFK03LST1 0:adf68d4b873f 104 {
HMFK03LST1 0:adf68d4b873f 105 name_val[name][i] = c;
HMFK03LST1 0:adf68d4b873f 106 i++;
HMFK03LST1 0:adf68d4b873f 107 }
HMFK03LST1 0:adf68d4b873f 108 }
HMFK03LST1 0:adf68d4b873f 109 }
HMFK03LST1 0:adf68d4b873f 110 fclose(fp);
HMFK03LST1 0:adf68d4b873f 111 }
HMFK03LST1 0:adf68d4b873f 112 }
HMFK03LST1 0:adf68d4b873f 113
HMFK03LST1 0:adf68d4b873f 114
HMFK03LST1 0:adf68d4b873f 115 void read_val(const char* name,const char* value)
HMFK03LST1 0:adf68d4b873f 116 {
HMFK03LST1 0:adf68d4b873f 117 float temp;
HMFK03LST1 0:adf68d4b873f 118
HMFK03LST1 0:adf68d4b873f 119 sscanf(value, "%f", &temp );
HMFK03LST1 0:adf68d4b873f 120 pc.printf("Input : %-18s Value : %6d ", name, int(temp));
HMFK03LST1 0:adf68d4b873f 121
HMFK03LST1 0:adf68d4b873f 122 if (string(&name[0]) == "O2_air_current" ){ o2.air_current = temp; pc.printf("Value read: %6d \n\r", o2.air_current );}
HMFK03LST1 0:adf68d4b873f 123 if (string(&name[0]) == "O2_water_created" ){ o2.water_created = temp; pc.printf("Value read: %6d \n\r", o2.water_created);}
HMFK03LST1 0:adf68d4b873f 124 if (string(&name[0]) == "O2_lambda_max" ) o2.lambda_max = temp;
HMFK03LST1 0:adf68d4b873f 125 if (string(&name[0]) == "O2_lambda_min" ) o2.lambda_min = temp;
HMFK03LST1 0:adf68d4b873f 126 if (string(&name[0]) == "O2_pump_over_load") o2.pump_over_load = temp;
HMFK03LST1 0:adf68d4b873f 127 if (string(&name[0]) == "O2_pump_up" ) o2.pump_up = temp;
HMFK03LST1 0:adf68d4b873f 128 if (string(&name[0]) == "O2_pump_dual_on" ) o2.pump_dual_on = temp;
HMFK03LST1 0:adf68d4b873f 129 if (string(&name[0]) == "O2_pump_dual_off" ) o2.pump_dual_off = temp;
HMFK03LST1 0:adf68d4b873f 130
HMFK03LST1 0:adf68d4b873f 131 if (string(&name[0]) == "CAP_voltage_low" ) cap.voltage_low = temp;
HMFK03LST1 0:adf68d4b873f 132 if (string(&name[0]) == "CAP_voltage_mid" ) cap.voltage_mid = temp;
HMFK03LST1 0:adf68d4b873f 133 if (string(&name[0]) == "CAP_voltage_high" ) cap.voltage_high = temp;
HMFK03LST1 0:adf68d4b873f 134 if (string(&name[0]) == "CAP_voltage_max" ) cap.voltage_max = temp;
HMFK03LST1 0:adf68d4b873f 135 if (string(&name[0]) == "CAP_voltage_down" ) cap.voltage_down = temp;
HMFK03LST1 0:adf68d4b873f 136 if (string(&name[0]) == "CAP_current_low" ) cap.current_low = temp;
HMFK03LST1 0:adf68d4b873f 137 if (string(&name[0]) == "CAP_current_mid" ) cap.current_mid = temp;
HMFK03LST1 0:adf68d4b873f 138 if (string(&name[0]) == "CAP_current_high" ) cap.current_high = temp;
HMFK03LST1 0:adf68d4b873f 139
HMFK03LST1 0:adf68d4b873f 140 if (string(&name[0]) == "FC_temp_max" ) fc.temp_max = temp;
HMFK03LST1 0:adf68d4b873f 141 if (string(&name[0]) == "FC_voltage_max" ) fc.voltage_max = temp;
HMFK03LST1 0:adf68d4b873f 142
HMFK03LST1 0:adf68d4b873f 143 if (string(&name[0]) == "H2O_fan_over_pwm" ) h2o.fan_over_pwm = temp;
HMFK03LST1 0:adf68d4b873f 144 if (string(&name[0]) == "H2O_fan_p" ) h2o.fan_p = temp;
HMFK03LST1 0:adf68d4b873f 145 if (string(&name[0]) == "H2O_fan_i" ) h2o.fan_i = temp;
HMFK03LST1 0:adf68d4b873f 146 if (string(&name[0]) == "H2O_fan_thr" ) h2o.fan_thr = temp;
HMFK03LST1 0:adf68d4b873f 147 if (string(&name[0]) == "H2O_fan_up" ) h2o.fan_up = temp;
HMFK03LST1 0:adf68d4b873f 148 if (string(&name[0]) == "H2O_pump_over_pwm") h2o.pump_over_pwm = temp;
HMFK03LST1 0:adf68d4b873f 149 if (string(&name[0]) == "H2O_pump_p" ) h2o.pump_p = temp;
HMFK03LST1 0:adf68d4b873f 150 if (string(&name[0]) == "H2O_pump_i" ) h2o.pump_i = temp;
HMFK03LST1 0:adf68d4b873f 151 if (string(&name[0]) == "H2O_pump_min" ) h2o.pump_min = temp;
HMFK03LST1 0:adf68d4b873f 152 if (string(&name[0]) == "H2O_pump_up" ) h2o.pump_up = temp;
HMFK03LST1 0:adf68d4b873f 153
HMFK03LST1 0:adf68d4b873f 154 if (string(&name[0]) == "MOSFET_temp_max" ) mosfet.temp_max = temp;
HMFK03LST1 0:adf68d4b873f 155 }
HMFK03LST1 0:adf68d4b873f 156
HMFK03LST1 0:adf68d4b873f 157
HMFK03LST1 0:adf68d4b873f 158 // T - Funktions
HMFK03LST1 0:adf68d4b873f 159 //----------------------------------------------------------------------------------------------
HMFK03LST1 0:adf68d4b873f 160
HMFK03LST1 0:adf68d4b873f 161 void T_1()
HMFK03LST1 0:adf68d4b873f 162 {
HMFK03LST1 0:adf68d4b873f 163 o2.water_in = 13235 * o2.rh_in / (o2.temp_in + 2731) * pow(10.0,(7.5 * o2.temp_in)/((2373 + o2.temp_in))-1);
HMFK03LST1 0:adf68d4b873f 164
HMFK03LST1 0:adf68d4b873f 165 o2.water_in = clamp(o2.water_in,0,4000,&error.t_1);
HMFK03LST1 0:adf68d4b873f 166 }
HMFK03LST1 0:adf68d4b873f 167
HMFK03LST1 0:adf68d4b873f 168 void T_2()
HMFK03LST1 0:adf68d4b873f 169 {
HMFK03LST1 0:adf68d4b873f 170 if (o2.pump_load_act > 0) {
HMFK03LST1 0:adf68d4b873f 171 o2.delta_t = o2.temp_out - h2o.temp_out;
HMFK03LST1 0:adf68d4b873f 172 o2.temp_calc = o2.temp_out;
HMFK03LST1 0:adf68d4b873f 173 }
HMFK03LST1 0:adf68d4b873f 174 else
HMFK03LST1 0:adf68d4b873f 175 {
HMFK03LST1 0:adf68d4b873f 176 o2.temp_calc = o2.delta_t + h2o.temp_out;
HMFK03LST1 0:adf68d4b873f 177 }
HMFK03LST1 0:adf68d4b873f 178
HMFK03LST1 0:adf68d4b873f 179 o2.temp_calc = clamp(o2.temp_calc,0,800,&error.t_2);
HMFK03LST1 0:adf68d4b873f 180 }
HMFK03LST1 0:adf68d4b873f 181
HMFK03LST1 0:adf68d4b873f 182 void T_3()
HMFK03LST1 0:adf68d4b873f 183 {
HMFK03LST1 0:adf68d4b873f 184 o2.water_out = 13235000 / (o2.temp_calc + 2731) * pow(10.0,(7.5 * o2.temp_calc)/((2373 + o2.temp_calc))-1);
HMFK03LST1 0:adf68d4b873f 185
HMFK03LST1 0:adf68d4b873f 186 o2.water_out = clamp(o2.water_out,0,30000,&error.t_3);
HMFK03LST1 0:adf68d4b873f 187 }
HMFK03LST1 0:adf68d4b873f 188
HMFK03LST1 0:adf68d4b873f 189 void T_4()
HMFK03LST1 0:adf68d4b873f 190 {
HMFK03LST1 0:adf68d4b873f 191 o2.water_extracted = o2.water_out - o2.water_in;
HMFK03LST1 0:adf68d4b873f 192 o2.air_needed = o2.water_created * 10000 / o2.water_extracted;
HMFK03LST1 0:adf68d4b873f 193 o2.lambda = o2.air_needed * 100 / o2.air_current;
HMFK03LST1 0:adf68d4b873f 194
HMFK03LST1 0:adf68d4b873f 195 o2.lambda = clamp(o2.lambda,100,500,&error.t_4);
HMFK03LST1 0:adf68d4b873f 196 }
HMFK03LST1 0:adf68d4b873f 197
HMFK03LST1 0:adf68d4b873f 198 void T_5()
HMFK03LST1 0:adf68d4b873f 199 {
HMFK03LST1 0:adf68d4b873f 200 o2.lambda_delta = ((o2.lambda_max + o2.lambda_min) / 2) - o2.lambda;
HMFK03LST1 0:adf68d4b873f 201
HMFK03LST1 0:adf68d4b873f 202 o2.lambda_delta_sum = o2.lambda_delta_sum + (o2.lambda_delta * 0.1);
HMFK03LST1 0:adf68d4b873f 203 o2.lambda_delta_sum = clamp(o2.lambda_delta_sum,-2000,7000,&error.t_5);
HMFK03LST1 0:adf68d4b873f 204
HMFK03LST1 0:adf68d4b873f 205 h2o.fan_pwm = ((h2o.fan_p * o2.lambda_delta) ) + ((h2o.fan_i * o2.lambda_delta_sum / 10) );
HMFK03LST1 0:adf68d4b873f 206 h2o.fan_pwm = clamp( h2o.fan_pwm,0,1000,&error.t_5);
HMFK03LST1 0:adf68d4b873f 207 }
HMFK03LST1 0:adf68d4b873f 208
HMFK03LST1 0:adf68d4b873f 209 void T_6()
HMFK03LST1 0:adf68d4b873f 210 {
HMFK03LST1 0:adf68d4b873f 211 h2o.pump_pwm = ((h2o.pump_p * o2.lambda_delta) ) + ((h2o.pump_i * o2.lambda_delta_sum / 10) + h2o.pump_min );
HMFK03LST1 0:adf68d4b873f 212 h2o.pump_pwm = clamp( h2o.pump_pwm,h2o.pump_min,1000,&error.t_6);
HMFK03LST1 0:adf68d4b873f 213 }
HMFK03LST1 0:adf68d4b873f 214
HMFK03LST1 0:adf68d4b873f 215 void T_7()
HMFK03LST1 0:adf68d4b873f 216 {
HMFK03LST1 0:adf68d4b873f 217 if(h2o.fan_override) {
HMFK03LST1 0:adf68d4b873f 218 h2o.fan_pwm_act = h2o.fan_over_pwm;
HMFK03LST1 0:adf68d4b873f 219 }
HMFK03LST1 0:adf68d4b873f 220 else
HMFK03LST1 0:adf68d4b873f 221 {
HMFK03LST1 0:adf68d4b873f 222 if ((h2o.fan_pwm_act == 0) && (h2o.fan_pwm >= h2o.fan_thr))
HMFK03LST1 0:adf68d4b873f 223 {
HMFK03LST1 0:adf68d4b873f 224 h2o.fan_up_count = h2o.fan_up;
HMFK03LST1 0:adf68d4b873f 225 }
HMFK03LST1 0:adf68d4b873f 226 else
HMFK03LST1 0:adf68d4b873f 227 {
HMFK03LST1 0:adf68d4b873f 228 h2o.fan_pwm_act = h2o.fan_pwm;
HMFK03LST1 0:adf68d4b873f 229 }
HMFK03LST1 0:adf68d4b873f 230 }
HMFK03LST1 0:adf68d4b873f 231
HMFK03LST1 0:adf68d4b873f 232 if (h2o.fan_up_count > 0) {h2o.fan_up_count--; h2o.fan_pwm_act = 1000;}
HMFK03LST1 0:adf68d4b873f 233
HMFK03LST1 0:adf68d4b873f 234 if (!((h2o.fan_pwm_act >= h2o.fan_thr) & sys.run)){h2o.fan_pwm_act = 0;}
HMFK03LST1 0:adf68d4b873f 235
HMFK03LST1 0:adf68d4b873f 236 h2o.fan_pwm_act = clamp( h2o.fan_pwm_act,0,1000,&error.t_7);
HMFK03LST1 0:adf68d4b873f 237
HMFK03LST1 0:adf68d4b873f 238 pwm_4.write(h2o.fan_pwm_act * 0.001);
HMFK03LST1 0:adf68d4b873f 239 }
HMFK03LST1 0:adf68d4b873f 240
HMFK03LST1 0:adf68d4b873f 241
HMFK03LST1 0:adf68d4b873f 242 void T_8()
HMFK03LST1 0:adf68d4b873f 243 {
HMFK03LST1 0:adf68d4b873f 244 if(h2o.pump_override){
HMFK03LST1 0:adf68d4b873f 245 h2o.pump_pwm_act = h2o.pump_over_pwm;
HMFK03LST1 0:adf68d4b873f 246 }
HMFK03LST1 0:adf68d4b873f 247 else
HMFK03LST1 0:adf68d4b873f 248 {
HMFK03LST1 0:adf68d4b873f 249 if ((h2o.pump_pwm_act == 0) && (h2o.pump_pwm > 0))
HMFK03LST1 0:adf68d4b873f 250 {
HMFK03LST1 0:adf68d4b873f 251 h2o.pump_up_count = h2o.pump_up;
HMFK03LST1 0:adf68d4b873f 252 }
HMFK03LST1 0:adf68d4b873f 253 else
HMFK03LST1 0:adf68d4b873f 254 {
HMFK03LST1 0:adf68d4b873f 255 h2o.pump_pwm_act = h2o.pump_pwm;
HMFK03LST1 0:adf68d4b873f 256 }
HMFK03LST1 0:adf68d4b873f 257 }
HMFK03LST1 0:adf68d4b873f 258
HMFK03LST1 0:adf68d4b873f 259 if (h2o.pump_up_count > 0) {h2o.pump_up_count--; h2o.pump_pwm_act = 1000;}
HMFK03LST1 0:adf68d4b873f 260
HMFK03LST1 0:adf68d4b873f 261 if (!(sys.run)){ h2o.pump_pwm_act = 0;}
HMFK03LST1 0:adf68d4b873f 262
HMFK03LST1 0:adf68d4b873f 263 h2o.pump_pwm_act = clamp( h2o.pump_pwm_act,0,1000,&error.t_8);
HMFK03LST1 0:adf68d4b873f 264
HMFK03LST1 0:adf68d4b873f 265 pwm_3.write(h2o.fan_pwm_act * 0.001);
HMFK03LST1 0:adf68d4b873f 266 }
HMFK03LST1 0:adf68d4b873f 267
HMFK03LST1 0:adf68d4b873f 268 void T_ALL(){
HMFK03LST1 0:adf68d4b873f 269 T_1();
HMFK03LST1 0:adf68d4b873f 270 T_2();
HMFK03LST1 0:adf68d4b873f 271 T_3();
HMFK03LST1 0:adf68d4b873f 272 T_4();
HMFK03LST1 0:adf68d4b873f 273 T_5();
HMFK03LST1 0:adf68d4b873f 274 T_6();
HMFK03LST1 0:adf68d4b873f 275 T_7();
HMFK03LST1 0:adf68d4b873f 276 T_8();
HMFK03LST1 0:adf68d4b873f 277 }
HMFK03LST1 0:adf68d4b873f 278
HMFK03LST1 0:adf68d4b873f 279 // O - Funktions
HMFK03LST1 0:adf68d4b873f 280 //----------------------------------------------------------------------------------------------
HMFK03LST1 0:adf68d4b873f 281
HMFK03LST1 0:adf68d4b873f 282
HMFK03LST1 0:adf68d4b873f 283
HMFK03LST1 0:adf68d4b873f 284
HMFK03LST1 0:adf68d4b873f 285 void O_1()
HMFK03LST1 0:adf68d4b873f 286 {
HMFK03LST1 0:adf68d4b873f 287 o2.rh_out_delta = ((o2.rh_out_soll) - o2.rh_out;
HMFK03LST1 0:adf68d4b873f 288 o2.rh_out_delta = clamp( o2.rh_out_delta,-100,100,&error.o_1);
HMFK03LST1 0:adf68d4b873f 289 o2.rh_pump_load = 02.rh_p * o2.rh_out_delta;
HMFK03LST1 0:adf68d4b873f 290 o2.rh_pump_load = clamp( o2.rh_pump_load,o2.rh_pump_min,o2.rh_pump_max,&error.o_2);
HMFK03LST1 0:adf68d4b873f 291 }
HMFK03LST1 0:adf68d4b873f 292
HMFK03LST1 0:adf68d4b873f 293 void O_2()
HMFK03LST1 0:adf68d4b873f 294 {
HMFK03LST1 0:adf68d4b873f 295 if(cap.voltage_act < cap.voltage_mid)
HMFK03LST1 0:adf68d4b873f 296 {
HMFK03LST1 0:adf68d4b873f 297 if(cap.voltage_act < cap.voltage_low) fc.current_load = cap.current_low;
HMFK03LST1 0:adf68d4b873f 298 else fc.current_load = cap.current_mid;
HMFK03LST1 0:adf68d4b873f 299 }
HMFK03LST1 0:adf68d4b873f 300 else fc.current_load = cap.current_high;
HMFK03LST1 0:adf68d4b873f 301 return 0;
HMFK03LST1 0:adf68d4b873f 302 }
HMFK03LST1 0:adf68d4b873f 303
HMFK03LST1 0:adf68d4b873f 304 bool O_3()
HMFK03LST1 0:adf68d4b873f 305 {
HMFK03LST1 0:adf68d4b873f 306 o2.lambda_min = 150;
HMFK03LST1 0:adf68d4b873f 307 fc.air_needed = fc.current_load * o2.lambda_min * 0.007;
HMFK03LST1 0:adf68d4b873f 308 return 0;
HMFK03LST1 0:adf68d4b873f 309 }
HMFK03LST1 0:adf68d4b873f 310
HMFK03LST1 0:adf68d4b873f 311 bool O_4()
HMFK03LST1 0:adf68d4b873f 312 {
HMFK03LST1 0:adf68d4b873f 313 if(o2.pump_on == false) o2.pump_load = 0;
HMFK03LST1 0:adf68d4b873f 314 return 0;
HMFK03LST1 0:adf68d4b873f 315 }
HMFK03LST1 0:adf68d4b873f 316
HMFK03LST1 0:adf68d4b873f 317 bool O_5()
HMFK03LST1 0:adf68d4b873f 318 {
HMFK03LST1 0:adf68d4b873f 319 if(o2.pump_override) o2.pump_load_act = o2.pump_over_load;
HMFK03LST1 0:adf68d4b873f 320 else o2.pump_load_act = o2.pump_load;
HMFK03LST1 0:adf68d4b873f 321 return 0;
HMFK03LST1 0:adf68d4b873f 322 }
HMFK03LST1 0:adf68d4b873f 323
HMFK03LST1 0:adf68d4b873f 324 bool O_6()
HMFK03LST1 0:adf68d4b873f 325 {
HMFK03LST1 0:adf68d4b873f 326 if(o2.pump_load_act < o2.pump_dual_off){o2.pump_dual = false;}
HMFK03LST1 0:adf68d4b873f 327 if(o2.pump_load_act > o2.pump_dual_on ){o2.pump_dual = true;}
HMFK03LST1 0:adf68d4b873f 328
HMFK03LST1 0:adf68d4b873f 329 if (o2.pump_dual)
HMFK03LST1 0:adf68d4b873f 330 {
HMFK03LST1 0:adf68d4b873f 331 o2.pump_pwm_1 = o2.pump_load_act * 0.5;
HMFK03LST1 0:adf68d4b873f 332 o2.pump_pwm_2 = o2.pump_load_act * 0.5;
HMFK03LST1 0:adf68d4b873f 333 }
HMFK03LST1 0:adf68d4b873f 334 else
HMFK03LST1 0:adf68d4b873f 335 {
HMFK03LST1 0:adf68d4b873f 336 o2.pump_pwm_1 = o2.pump_load_act;
HMFK03LST1 0:adf68d4b873f 337 o2.pump_pwm_2 = 0;
HMFK03LST1 0:adf68d4b873f 338 }
HMFK03LST1 0:adf68d4b873f 339 return 0;
HMFK03LST1 0:adf68d4b873f 340 }
HMFK03LST1 0:adf68d4b873f 341
HMFK03LST1 0:adf68d4b873f 342 void O_ALL()
HMFK03LST1 0:adf68d4b873f 343 {
HMFK03LST1 0:adf68d4b873f 344 O_1();
HMFK03LST1 0:adf68d4b873f 345 O_2();
HMFK03LST1 0:adf68d4b873f 346 O_3();
HMFK03LST1 0:adf68d4b873f 347 O_4();
HMFK03LST1 0:adf68d4b873f 348 O_5();
HMFK03LST1 0:adf68d4b873f 349 O_6();
HMFK03LST1 0:adf68d4b873f 350 }
HMFK03LST1 0:adf68d4b873f 351
HMFK03LST1 0:adf68d4b873f 352
HMFK03LST1 0:adf68d4b873f 353 // M - Funktions
HMFK03LST1 0:adf68d4b873f 354 //----------------------------------------------------------------------------------------------
HMFK03LST1 0:adf68d4b873f 355
HMFK03LST1 0:adf68d4b873f 356 bool M_1()
HMFK03LST1 0:adf68d4b873f 357 {
HMFK03LST1 0:adf68d4b873f 358 if(o2.pump_on) mosfet.pwm = 0;
HMFK03LST1 0:adf68d4b873f 359 mosfet.pwm = mosfet.pwm + ( ((fc.current_load - fc.current_act) * mosfet.i) / 100000);
HMFK03LST1 0:adf68d4b873f 360 if(sys.load_act == false) mosfet.pwm = 0;
HMFK03LST1 0:adf68d4b873f 361 return 0;
HMFK03LST1 0:adf68d4b873f 362 }
HMFK03LST1 0:adf68d4b873f 363
HMFK03LST1 0:adf68d4b873f 364 bool M_2()
HMFK03LST1 0:adf68d4b873f 365 {
HMFK03LST1 0:adf68d4b873f 366 sys.mos_overtemp = (mosfet.temp_act < mosfet.temp_max);
HMFK03LST1 0:adf68d4b873f 367 return 0;
HMFK03LST1 0:adf68d4b873f 368 }
HMFK03LST1 0:adf68d4b873f 369
HMFK03LST1 0:adf68d4b873f 370 bool M_3()
HMFK03LST1 0:adf68d4b873f 371 {
HMFK03LST1 0:adf68d4b873f 372 if(sys.mosfet && sys.run) mosfet.pwm_act = mosfet.pwm;
HMFK03LST1 0:adf68d4b873f 373 else mosfet.pwm_act = 0;
HMFK03LST1 0:adf68d4b873f 374 return 0;
HMFK03LST1 0:adf68d4b873f 375 }
HMFK03LST1 0:adf68d4b873f 376
HMFK03LST1 0:adf68d4b873f 377 // S - Funktions
HMFK03LST1 0:adf68d4b873f 378 //----------------------------------------------------------------------------------------------
HMFK03LST1 0:adf68d4b873f 379
HMFK03LST1 0:adf68d4b873f 380 bool S_1()
HMFK03LST1 0:adf68d4b873f 381 {
HMFK03LST1 0:adf68d4b873f 382 sys.run = (switches.master && switches.safety);
HMFK03LST1 0:adf68d4b873f 383 return 0;
HMFK03LST1 0:adf68d4b873f 384 }
HMFK03LST1 0:adf68d4b873f 385
HMFK03LST1 0:adf68d4b873f 386 bool S_2()
HMFK03LST1 0:adf68d4b873f 387 {
HMFK03LST1 0:adf68d4b873f 388 sys.fc_overtemp = (fc.temp_act > fc.temp_max);
HMFK03LST1 0:adf68d4b873f 389 return 0;
HMFK03LST1 0:adf68d4b873f 390 }
HMFK03LST1 0:adf68d4b873f 391
HMFK03LST1 0:adf68d4b873f 392 bool S_3()
HMFK03LST1 0:adf68d4b873f 393 {
HMFK03LST1 0:adf68d4b873f 394 sys.fc_overvoltage = (fc.voltage_act > fc.voltage_max);
HMFK03LST1 0:adf68d4b873f 395 return 0;
HMFK03LST1 0:adf68d4b873f 396 }
HMFK03LST1 0:adf68d4b873f 397
HMFK03LST1 0:adf68d4b873f 398 bool S_4()
HMFK03LST1 0:adf68d4b873f 399 {
HMFK03LST1 0:adf68d4b873f 400 sys.fuelcell = (sys.temp && sys.voltage);
HMFK03LST1 0:adf68d4b873f 401 return 0;
HMFK03LST1 0:adf68d4b873f 402 }
HMFK03LST1 0:adf68d4b873f 403
HMFK03LST1 0:adf68d4b873f 404 // C - Funktions
HMFK03LST1 0:adf68d4b873f 405 //----------------------------------------------------------------------------------------------
HMFK03LST1 0:adf68d4b873f 406
HMFK03LST1 0:adf68d4b873f 407 bool C_1()
HMFK03LST1 0:adf68d4b873f 408 {
HMFK03LST1 0:adf68d4b873f 409 sys.cap_load = (cap.voltage_act < cap.voltage_max);
HMFK03LST1 0:adf68d4b873f 410 return 0;
HMFK03LST1 0:adf68d4b873f 411 }
HMFK03LST1 0:adf68d4b873f 412
HMFK03LST1 0:adf68d4b873f 413 bool C_2()
HMFK03LST1 0:adf68d4b873f 414 {
HMFK03LST1 0:adf68d4b873f 415 sys.cap_down_load = (cap.voltage_act < cap.voltage_down);
HMFK03LST1 0:adf68d4b873f 416 return 0;
HMFK03LST1 0:adf68d4b873f 417 }
HMFK03LST1 0:adf68d4b873f 418
HMFK03LST1 0:adf68d4b873f 419 bool C_3()
HMFK03LST1 0:adf68d4b873f 420 {
HMFK03LST1 0:adf68d4b873f 421 sys.cap_voltage_reset = (cap.voltage_act > cap.voltage_max);
HMFK03LST1 0:adf68d4b873f 422 return 0;
HMFK03LST1 0:adf68d4b873f 423 }
HMFK03LST1 0:adf68d4b873f 424
HMFK03LST1 0:adf68d4b873f 425 bool C_4()
HMFK03LST1 0:adf68d4b873f 426 {
HMFK03LST1 0:adf68d4b873f 427 sys.cap_down_reset = (cap.voltage_act > cap.voltage_down);
HMFK03LST1 0:adf68d4b873f 428 return 0;
HMFK03LST1 0:adf68d4b873f 429 }
HMFK03LST1 0:adf68d4b873f 430
HMFK03LST1 0:adf68d4b873f 431 bool C_5()
HMFK03LST1 0:adf68d4b873f 432 {
HMFK03LST1 0:adf68d4b873f 433 sys.load = ((switches.drive) || (sys.cap_load && (!switches.capdown)) || (switches.capdown && sys.cap_down_load));
HMFK03LST1 0:adf68d4b873f 434 return 0;
HMFK03LST1 0:adf68d4b873f 435 }
HMFK03LST1 0:adf68d4b873f 436
HMFK03LST1 0:adf68d4b873f 437 bool C_6()
HMFK03LST1 0:adf68d4b873f 438 {
HMFK03LST1 0:adf68d4b873f 439 sys.load_reset = (sys.cap_voltage_reset || (sys.cap_down_reset && switches.capdown));
HMFK03LST1 0:adf68d4b873f 440 return 0;
HMFK03LST1 0:adf68d4b873f 441 }
HMFK03LST1 0:adf68d4b873f 442
HMFK03LST1 0:adf68d4b873f 443 bool C_7()
HMFK03LST1 0:adf68d4b873f 444 {
HMFK03LST1 0:adf68d4b873f 445 if(sys.load) sys.load_act = true;
HMFK03LST1 0:adf68d4b873f 446 if(sys.load_reset) sys.load_act = false;
HMFK03LST1 0:adf68d4b873f 447 return 0;
HMFK03LST1 0:adf68d4b873f 448 }
HMFK03LST1 0:adf68d4b873f 449
HMFK03LST1 0:adf68d4b873f 450 bool C_8()
HMFK03LST1 0:adf68d4b873f 451 {
HMFK03LST1 0:adf68d4b873f 452 o2.pump_on = (sys.mosfet && sys.run && sys.fuelcell && sys.load_act);
HMFK03LST1 0:adf68d4b873f 453 return 0;
HMFK03LST1 0:adf68d4b873f 454 }
HMFK03LST1 0:adf68d4b873f 455
HMFK03LST1 0:adf68d4b873f 456
HMFK03LST1 0:adf68d4b873f 457 void read_inputs()
HMFK03LST1 0:adf68d4b873f 458 {
HMFK03LST1 0:adf68d4b873f 459 char channel = sys.count%4;
HMFK03LST1 0:adf68d4b873f 460
HMFK03LST1 0:adf68d4b873f 461 switch (channel)
HMFK03LST1 0:adf68d4b873f 462 {
HMFK03LST1 0:adf68d4b873f 463 case 0 : switches.drive = mp2xD;
HMFK03LST1 0:adf68d4b873f 464 sys.h2_analog = mp2yA.read_u16() /2;
HMFK03LST1 0:adf68d4b873f 465 fc.voltage_act = mp1yA.read_u16() /1.638;
HMFK03LST1 0:adf68d4b873f 466 fc.current_act = current.read_u16()/4;
HMFK03LST1 0:adf68d4b873f 467 break;
HMFK03LST1 0:adf68d4b873f 468
HMFK03LST1 0:adf68d4b873f 469 case 1 : sys.safety_V = mp2xA.read_u16() /4;
HMFK03LST1 0:adf68d4b873f 470 switches.safety = (sys.safety_V > 8000);
HMFK03LST1 0:adf68d4b873f 471 sys.current_out = mp2yA.read_u16() /5;
HMFK03LST1 0:adf68d4b873f 472 cap.voltage_act = mp1yA.read_u16() /1.638;
HMFK03LST1 0:adf68d4b873f 473 fc.current_act = current.read_u16()/4;
HMFK03LST1 0:adf68d4b873f 474 break;
HMFK03LST1 0:adf68d4b873f 475
HMFK03LST1 0:adf68d4b873f 476 case 2 : switches.capdown = !mp2xD;
HMFK03LST1 0:adf68d4b873f 477 mosfet.temp_act = mosfet.temp_act + ((((59000-mp2yA.read_u16())/90) - mosfet.temp_act ) >> 3);
HMFK03LST1 0:adf68d4b873f 478 fc.voltage_act = mp1yA.read_u16() /1.638;
HMFK03LST1 0:adf68d4b873f 479 fc.current_act = current.read_u16()/4;
HMFK03LST1 0:adf68d4b873f 480 break;
HMFK03LST1 0:adf68d4b873f 481
HMFK03LST1 0:adf68d4b873f 482 case 3 : switches.master = mp2xD;
HMFK03LST1 0:adf68d4b873f 483 fc.temp_act = fc.temp_act + ((((61800-mp2yA.read_u16())/90) - fc.temp_act) >> 3);
HMFK03LST1 0:adf68d4b873f 484 h2o.temp_out = fc.temp_act;
HMFK03LST1 0:adf68d4b873f 485 cap.voltage_act = mp1yA.read_u16() /1.638;
HMFK03LST1 0:adf68d4b873f 486 fc.current_act = current.read_u16()/4;
HMFK03LST1 0:adf68d4b873f 487 break;
HMFK03LST1 0:adf68d4b873f 488 }
HMFK03LST1 0:adf68d4b873f 489
HMFK03LST1 0:adf68d4b873f 490 mp_A = ( (channel + 1) & 0x01); // A setzen
HMFK03LST1 0:adf68d4b873f 491 mp_B = (((channel + 1) >> 1) & 0x01); // B setzen
HMFK03LST1 0:adf68d4b873f 492
HMFK03LST1 0:adf68d4b873f 493 }
HMFK03LST1 0:adf68d4b873f 494
HMFK03LST1 0:adf68d4b873f 495 void read_i2c_RHTMP(char ad)
HMFK03LST1 0:adf68d4b873f 496 {
HMFK03LST1 0:adf68d4b873f 497 char input[4];
HMFK03LST1 0:adf68d4b873f 498 short RH = 0;
HMFK03LST1 0:adf68d4b873f 499 short TMP = 0;
HMFK03LST1 0:adf68d4b873f 500
HMFK03LST1 0:adf68d4b873f 501 i2c.write(ad<<1, 0x00 , 1); //wake up
HMFK03LST1 0:adf68d4b873f 502 i2c.read (ad<<1, input , 4); //read out
HMFK03LST1 0:adf68d4b873f 503
HMFK03LST1 0:adf68d4b873f 504 RH = (( 1000 * (((input[0]<<8) | (input[1] )) & 0x3FFF ))>> 14) ; //transform into 0 - 1000 as Integer represents 0.0 - 100.0 %
HMFK03LST1 0:adf68d4b873f 505
HMFK03LST1 0:adf68d4b873f 506 TMP = (( 1650 * (((input[2]<<6) | (input[3]>>2)) & 0x3FFF ))>> 14) -400; //transform into -400 - 1250 as Integer represents -40.0 - 125.0 °C
HMFK03LST1 0:adf68d4b873f 507
HMFK03LST1 0:adf68d4b873f 508 if (TMP > -50 && TMP < 800)
HMFK03LST1 0:adf68d4b873f 509 {
HMFK03LST1 0:adf68d4b873f 510 if (ad == I2C_IN ){o2.temp_in = TMP; o2.rh_in = RH;error.o2_in = false;};
HMFK03LST1 0:adf68d4b873f 511 if (ad == I2C_OUT){o2.temp_out = TMP; o2.rh_out = RH;error.o2_out = false;};
HMFK03LST1 0:adf68d4b873f 512 }
HMFK03LST1 0:adf68d4b873f 513 else
HMFK03LST1 0:adf68d4b873f 514 {
HMFK03LST1 0:adf68d4b873f 515 if (ad == I2C_IN ){error.o2_in = true;};
HMFK03LST1 0:adf68d4b873f 516 if (ad == I2C_OUT){error.o2_out = true;};
HMFK03LST1 0:adf68d4b873f 517 }
HMFK03LST1 0:adf68d4b873f 518 }
HMFK03LST1 0:adf68d4b873f 519
HMFK03LST1 0:adf68d4b873f 520
HMFK03LST1 0:adf68d4b873f 521 void timetable()
HMFK03LST1 0:adf68d4b873f 522 {
HMFK03LST1 0:adf68d4b873f 523 switch (sys.count)
HMFK03LST1 0:adf68d4b873f 524 {
HMFK03LST1 0:adf68d4b873f 525 case 0: read_i2c_RHTMP(I2C_IN) ; break;
HMFK03LST1 0:adf68d4b873f 526 case 125: T_ALL() ; break;
HMFK03LST1 0:adf68d4b873f 527 case 250: read_i2c_RHTMP(I2C_OUT) ; break;
HMFK03LST1 0:adf68d4b873f 528 case 375: O_ALL() ; break;
HMFK03LST1 0:adf68d4b873f 529 case 500: read_i2c_RHTMP(I2C_IN) ; break;
HMFK03LST1 0:adf68d4b873f 530 case 625: T_ALL() ; break;
HMFK03LST1 0:adf68d4b873f 531 case 750: read_i2c_RHTMP(I2C_OUT) ; break;
HMFK03LST1 0:adf68d4b873f 532 case 875: O_ALL() ; break;
HMFK03LST1 0:adf68d4b873f 533 }
HMFK03LST1 0:adf68d4b873f 534
HMFK03LST1 0:adf68d4b873f 535 read_inputs();
HMFK03LST1 0:adf68d4b873f 536
HMFK03LST1 0:adf68d4b873f 537 sys.count ++;
HMFK03LST1 0:adf68d4b873f 538
HMFK03LST1 0:adf68d4b873f 539 if (sys.count >= 1000){sys.count=0; led_1 = !led_1;};
HMFK03LST1 0:adf68d4b873f 540
HMFK03LST1 0:adf68d4b873f 541 }
HMFK03LST1 0:adf68d4b873f 542
HMFK03LST1 0:adf68d4b873f 543
HMFK03LST1 0:adf68d4b873f 544
HMFK03LST1 0:adf68d4b873f 545
HMFK03LST1 0:adf68d4b873f 546 int main()
HMFK03LST1 0:adf68d4b873f 547 {
HMFK03LST1 0:adf68d4b873f 548 pc.baud(115200);
HMFK03LST1 0:adf68d4b873f 549 i2c.frequency(400000);
HMFK03LST1 0:adf68d4b873f 550
HMFK03LST1 0:adf68d4b873f 551 pwm_6.pulsewidth(1.0/PWM_Frequenz); //Mosfet
HMFK03LST1 0:adf68d4b873f 552 //pwm_5.pulsewidth(1.0/PWM_Frequenz); //H2 Purge
HMFK03LST1 0:adf68d4b873f 553 pwm_4.pulsewidth(1.0/PWM_Frequenz); //H2O Fan
HMFK03LST1 0:adf68d4b873f 554 pwm_3.pulsewidth(1.0/PWM_Frequenz); //H20 Pump
HMFK03LST1 0:adf68d4b873f 555 pwm_2.pulsewidth(1.0/PWM_Frequenz); //Air Pump 2
HMFK03LST1 0:adf68d4b873f 556 pwm_1.pulsewidth(1.0/PWM_Frequenz); //Air Pump 2
HMFK03LST1 0:adf68d4b873f 557
HMFK03LST1 0:adf68d4b873f 558
HMFK03LST1 0:adf68d4b873f 559 load_cfg();
HMFK03LST1 0:adf68d4b873f 560
HMFK03LST1 0:adf68d4b873f 561 while(1)
HMFK03LST1 0:adf68d4b873f 562 {
HMFK03LST1 0:adf68d4b873f 563 timetable();
HMFK03LST1 0:adf68d4b873f 564 }
HMFK03LST1 0:adf68d4b873f 565 }