Code for 'Smart Regulator' featured in 'Model Engineer', November 2020 on. Contains all work to August 2020 including all code described. Top level algorithm development is quite spares, leaving some work for you! Any questions - jon@jons-workshop.com
Dependencies: mbed BufferedSerial Servo2 PCT2075 I2CEeprom FastPWM
Diff: main.cpp
- Revision:
- 5:6ca3e7ffc553
- Parent:
- 4:28cc0cf01570
diff -r 28cc0cf01570 -r 6ca3e7ffc553 main.cpp --- a/main.cpp Fri Aug 07 13:06:03 2020 +0000 +++ b/main.cpp Sat Dec 05 12:40:17 2020 +0000 @@ -1,3 +1,6 @@ +/******************************************************************************* + DON'T FORGET TO REMOVE SOLDER LINKS SB16 AND SB18 ON NUCLEO-L432KC BOARD +*******************************************************************************/ #include "mbed.h" #include "Alternator.h" #include "BufferedSerial.h" @@ -6,6 +9,7 @@ #include "rpm.h" #include "field.h" #include "gps_mod.h" + //#include "baro.h" #ifdef TARGET_NUCLEO_L432KC // 24LC and LM75 work @@ -97,7 +101,7 @@ 10 N.C. 11 N.C. 12 PA_8 D9 InterruptIn pulse_tacho from engine magneto, used to measure rpm -13 PA_11 D10 Speed_Control servo +13 PA_11 D10 Servo 14 PB_5 D11 NEW June 2019 - Output engine tacho cleaned-up, brought out to testpoint 4 NOT REALLY USEFUL 15 PB_4 D12 Scope_probe NOT REALLY USEFUL 16 PB_3 D13 LED Onboard LED @@ -173,6 +177,8 @@ bool auto_test_flag = false; +bool charge_pump_enable = true; + enum {SAFE_NOTHING, POT_SERVO_DIRECT, VARIABLE_VOLTAGE, FIXED_VOLTAGE, ENG_REVS_CTRL, POT_SETS_ENGINE_RPM, CURRENT_FEEDBACK_CTRL, AUTO_TEST} ; /* End of Global variable declarations */ @@ -180,7 +186,8 @@ void ISR_fast_interrupt () { static uint32_t t = 0, u25 = 0; Scope_probe = 1; // To show how much time spent in interrupt handler - CHARGE_PUMP = !CHARGE_PUMP; + if (charge_pump_enable) + CHARGE_PUMP = !CHARGE_PUMP; switch (t) { case 0: // Alternator output voltage flag_link_V_rd = true; @@ -240,7 +247,8 @@ double Read_Field_Volts () { - return field_volt_reading * 42.85; // divisor fiddled to make voltage reading correct ! +// return field_volt_reading * 42.85; // divisor fiddled to make voltage reading correct ! + return field_volt_reading * 40.12; // divisor fiddled to make voltage reading correct ! } double Read_Ammeter () @@ -249,10 +257,27 @@ } -void query_system (struct parameters & a) { +void query_system (parameters & a) { query_toggle = !query_toggle; } +void set_v_out_opamp (double a) { // 0 to 1.0 sets opamp output in range 0 to 5v, charge pump permitting + A_OUT = a; +} +void set_v_out_opamp (parameters & a) { // 0 to 1.0 sets opamp output in range 0 to 5v, charge pump permitting + A_OUT = a.dbl[0] / 100.0; +} + +void charge_pump_override (int a) { // 0 disables, !0 enables charge pump + if (a == 0) + charge_pump_enable = false; + else + charge_pump_enable = true; +} +void charge_pump_override (parameters & a) { // 0 disables, !0 enables charge pump + charge_pump_override ((int)a.dbl[0]); +} + void set_pwm (double d) { // Range 0.0 to 1.0 called from cli Field.set_pwm (d); } @@ -324,7 +349,7 @@ Field.maketable () ; // Here to ensure eeprom has been setup Field.set_for_speed (0); - Engine.Speed_Control (((double)user_settings.rd(WARMUP_SERVO_POS)) / 100.0); + Engine.Set_Speed_Lever (((double)user_settings.rd(WARMUP_SERVO_POS)) / 100.0); startup_delay = user_settings.rd(WARM_UP_DELAY); pc.printf ("Operating Mode is [%s]\r\n", get_mode_text (user_settings.rd(OP_MODE))); @@ -338,22 +363,22 @@ #endif command_line_interpreter () ; // Proceed beyond here once loop_timer ticker ISR has set loop_flag true // A to D converters all read at 100 Hz - if (flag_link_V_rd) { + if (flag_link_V_rd) { // Reads main alternator output and/or traction battery voltage flag_link_V_rd = false; link_volt_reading *= (1.0 - vfilt); // link_volt_reading += vfilt * (double) Ain_Link_Volts.read(); // Volt fiddle factor NOT corrected here } - if (flag_Pot_rd) { + if (flag_Pot_rd) { // Reads Driver's speed control potentiometer flag_Pot_rd = false; driver_pot *= (1.0 - filt); driver_pot += filt * ((double)Driver_Pot.read() * 1.5); // Includes bodge around zener over-clipping input } - if (flag_A_rd) { + if (flag_A_rd) { // Reads ammeter - user wires this to suit their purpose flag_A_rd = false; amp_reading *= (1.0 - ampfilt); - amp_reading += ampfilt * ((double) Ammeter_In.read() - 0.5); // Amp range NOT corrected here + amp_reading += ampfilt * ((double) Ammeter_In.read() - 0.495); // Amp range NOT corrected here BUT OFFSET IS } - if (flag_field_V_rd) { + if (flag_field_V_rd) { // Reads 'Field Positive' supply - from battery via diode, also alternator rectifier out flag_field_V_rd = false; field_volt_reading *= (1.0 - vfilt); // field_volt_reading += vfilt * (double) Field_Supply_V.read(); // Volt fiddle factor NOT corrected here @@ -401,16 +426,19 @@ "6\tControl Engine by Current Load", */ case SAFE_NOTHING: // Safe nothing mode for cli cmd testing - // Use this to test command line commands e.g. Speed_Control, direct field setting etc + // Use this to test command line commands e.g. Set_Speed_Lever, direct field setting etc break; case POT_SERVO_DIRECT: // Driver_pot --> servo direct. Field OFF - Engine.Speed_Control (driver_pot); - Field.set_for_speed (0); // Safe, no output +// Engine.Set_Speed_Lever (driver_pot); + Engine.Set_Speed_Lever (driver_pot); + REF_VAR = driver_pot; +// Field.set_for_speed (0); // Safe, no output + Field.set_for_speed (3000); // Safe, no output break; case VARIABLE_VOLTAGE: // Variable Voltage - Engine.Speed_Control (driver_pot); // Driver_pot --> servo direct. Field ON + Engine.Set_Speed_Lever (driver_pot); // Driver_pot --> servo direct. Field ON if (driver_pot > DRIVER_NEUTRAL) // if pot not close to zero Field.set_for_speed (Engine.RPM_latest()); // according to RPM else @@ -522,7 +550,7 @@ if (startup_delay == 0) { up_and_running = true; pc.printf ("Warmup ended, starting proper ops\r\n"); - Engine.Speed_Control (0.0); + Engine.Set_Speed_Lever (0.0); } else { pc.printf ("In Startup warmup delay %d\r", startup_delay--);