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

Files at this revision

API Documentation at this revision

Comitter:
JonFreeman
Date:
Sat Dec 05 12:40:17 2020 +0000
Parent:
4:28cc0cf01570
Commit message:
Code for 'Smart Regulator' to August 2020, published as is. Basic low-level functions all thoroughly tested and debugged, top level algorithms have scope for further development - over to you! For help contact jon @ jons-workshop[.com

Changed in this revision

Alternator.h Show annotated file Show diff for this revision Revisions of this file
Servo.lib Show annotated file Show diff for this revision Revisions of this file
cli.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
rpm.cpp Show annotated file Show diff for this revision Revisions of this file
rpm.h Show annotated file Show diff for this revision Revisions of this file
--- a/Alternator.h	Fri Aug 07 13:06:03 2020 +0000
+++ b/Alternator.h	Sat Dec 05 12:40:17 2020 +0000
@@ -1,5 +1,8 @@
+/*******************************************************************************
+        DON'T FORGET TO REMOVE SOLDER LINKS SB16 AND SB18 ON L432KC BOARD
+*******************************************************************************/
 
-#define GPS_  //  Not the crap one I tried!
+//#define GPS_  //  Not the crap one I tried!
 
 const   double      ALTERNATOR_DESIGN_VOLTAGE = 14.0;   //  Used to scale down max field pwm when available voltage higher than this
 const   double      DRIVER_NEUTRAL      = 0.18;  //  Proportion of driver's pot travel deemed to be zero power request
--- a/Servo.lib	Fri Aug 07 13:06:03 2020 +0000
+++ b/Servo.lib	Sat Dec 05 12:40:17 2020 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/users/simon/code/Servo/#94980819591d
+https://os.mbed.com/users/JonFreeman/code/Servo2/#94980819591d
--- a/cli.cpp	Fri Aug 07 13:06:03 2020 +0000
+++ b/cli.cpp	Sat Dec 05 12:40:17 2020 +0000
@@ -20,6 +20,8 @@
 extern  double  Read_Link_Volts   ()  ;
 extern  double  Read_Field_Volts   ()  ;
 extern  double  Read_Ammeter        ()  ;
+extern  void    charge_pump_override    (parameters & a) ;   //  0 disables, !0 enables charge pump
+extern  void    set_v_out_opamp    (parameters & a) ;   //  0 to 1.0 sets opamp output in range 0 to 5v, charge pump permitting
 
 //bool    ee_settings_2020::wr   (char c, uint32_t i)  {           //  Write one setup char value to private buffer 'settings'
 /*
@@ -264,6 +266,8 @@
 
 struct  kb_command const command_list[] = {
     {"?", "Lists available commands, same as ls", menucmd},
+    {"cp", "Charge pump disable (0), enable (!0)", charge_pump_override},
+    {"vo", "Set out volts to ESC 0 - 100 pct", set_v_out_opamp},
     {"ft", "Test Field.set_for_speed fn", test_Fsfs_cmd},
     {"at", "Initiate Auto Test sequence", auto_test_kickoff_cmd},
     {"svod", "Set servo sense 0 or 1", servodir_cmd},
--- 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--);
--- a/rpm.cpp	Fri Aug 07 13:06:03 2020 +0000
+++ b/rpm.cpp	Sat Dec 05 12:40:17 2020 +0000
@@ -18,7 +18,7 @@
 //    microsecs.reset  ()  ;   //  timer = 0
 //    microsecs.start  ()  ;   //  64 bit, counts micro seconds and times out in half million years
     servo_position = MIN_WORKING_THROTTLE;
-    Speed_Control    (MIN_WORKING_THROTTLE);
+    Set_Speed_Lever    (MIN_WORKING_THROTTLE);
 };
 
 void        Engine_Manager::magneto_timeoutC    ()
@@ -75,7 +75,7 @@
     return  (uint32_t)filtered_measured_RPM;
 }
 
-void        Engine_Manager::Speed_Control  (double th)       //  Make this private once all throttle refs local
+void        Engine_Manager::Set_Speed_Lever  (double th)       //  Make this private once all throttle refs local
 {
     if  (user_settings.rd(SERVO_DIR) == 0)
         Speed_ControlServo   = th;
@@ -91,13 +91,13 @@
         if  (!rpm_in_run_range) {   //  Transition from idle to working revs
             rpm_in_run_range = true;
             servo_position  = MIN_WORKING_THROTTLE; //  set throttle to probably somewhere near low useful revs
-            Speed_Control    (MIN_WORKING_THROTTLE);
+            Set_Speed_Lever    (MIN_WORKING_THROTTLE);
         }   //  Endof transition from idle to working revs
     }       //  Endof Runnable or make runnable
     else    {   //  requested rpm are below useful, so kill engine
         if  (rpm_in_run_range)  {   //  detect transition from useful work to idle
             servo_position = 0.0;
-            Speed_Control    (0.0);
+            Set_Speed_Lever    (0.0);
             rpm_in_run_range = false;
         }
     }
@@ -148,7 +148,7 @@
                     servo_position = MIN_WORKING_THROTTLE;
                 if  (servo_position > MAX_WORKING_THROTTLE)
                     servo_position = MAX_WORKING_THROTTLE;
-                Speed_Control    (servo_position);   //  Update signal to engine throttle control servo
+                Set_Speed_Lever    (servo_position);   //  Update signal to engine throttle control servo
             }
             break;
         default:
--- a/rpm.h	Fri Aug 07 13:06:03 2020 +0000
+++ b/rpm.h	Sat Dec 05 12:40:17 2020 +0000
@@ -35,7 +35,7 @@
 //    Timer       microseconds;
   public:
     Engine_Manager    (PinName magneto_signal, PinName cleaned_output, PinName for_servo)  ;   //  
-    void        Speed_Control    (double);
+    void        Set_Speed_Lever    (double);
     bool        running ();
     void        manager_core();
     double      get_servo_position  ();