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

Revision:
5:6ca3e7ffc553
Parent:
4:28cc0cf01570
--- 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--);