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:
Fri Aug 07 13:06:03 2020 +0000
Parent:
3:43cb067ecd00
Child:
5:6ca3e7ffc553
Commit message:
Ready to test Aug.2020 pcb

Changed in this revision

Alternator.h Show annotated file Show diff for this revision Revisions of this file
gps_mod.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
--- a/Alternator.h	Mon Jul 27 08:44:59 2020 +0000
+++ b/Alternator.h	Fri Aug 07 13:06:03 2020 +0000
@@ -1,5 +1,5 @@
 
-//#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/gps_mod.cpp	Mon Jul 27 08:44:59 2020 +0000
+++ b/gps_mod.cpp	Fri Aug 07 13:06:03 2020 +0000
@@ -1,6 +1,6 @@
 #include "mbed.h"
 
-#ifdef GPS_
+//#ifdef GPS_
 
 #include "mbed.h"
 #include "gps_mod.h"
@@ -236,6 +236,7 @@
                             sprintf (datestr, "%d %s 20%d", date, &month_tab[month], strtol(&destptr[comma_positions[7] + 5], NULL, 10));
                             break;
                         case    5:  //  VTG       ,T   ,             ,M,0.098,N,0.181,K,A*2A course over ground and ground speed
+                        //Adafruit $GPVTG,165.48,T,,M,0.03,N,0.06,K,A*37 
 //$                                   GPVTG 309.62,T   ,             ,M,0.13, N,0.2,  K*6E
                             sprintf (speed_mphourstr, "%.1fmph", km2miles * strtod(destptr + comma_positions[5] + 1, NULL));
                             newdata = true;
@@ -262,4 +263,4 @@
     return 0;
 }   //      end of int gps_mod::update()
 
-#endif
+//#endif
--- a/main.cpp	Mon Jul 27 08:44:59 2020 +0000
+++ b/main.cpp	Fri Aug 07 13:06:03 2020 +0000
@@ -5,7 +5,7 @@
 #include "LM75B.h"              //  New I2C temp sensor code March 2020 (to suit possible next board issue, harmless otherwise)
 #include "rpm.h"
 #include "field.h"
-//#include "gps_mod.h"
+#include "gps_mod.h"
 //#include "baro.h"
 
 #ifdef  TARGET_NUCLEO_L432KC    //  24LC and LM75 work
@@ -73,45 +73,45 @@
 
 //  INPUTS :
 AnalogIn    Ain_Link_Volts  (A6);   //  Sniff of alternator output, not used in control loop as done using analogue MCP1630
-AnalogIn    Ammeter_In      (A1);   //  Output of ASC709LLFTR ammeter chip (pin 20), used to increase engine revs if need be
-//AnalogIn    Ammeter_Ref     (A0);   //  Ref output from ASC709LLFTR used to set ammeter zero (pin 25)
+AnalogIn    Ammeter_In      (A0);   //  Output of ASC709LLFTR ammeter chip (pin 20), used to increase engine revs if need be
 
 //  Nov 2019. Not convinced Ext_Rev_Demand is useful    ** July 2020 - repurposed, voltmeter Field_Supply_V
 //AnalogIn    Ext_Rev_Demand  (D3);   //  Servo determines engine revs, servo out to be higher of Ext_Rev_Demand and internal calc
 AnalogIn    Field_Supply_V  (D3);   //  Servo determines engine revs, servo out to be higher of Ext_Rev_Demand and internal calc
 
-AnalogIn    Driver_Pot      (A3);   //  If whole control system can be made to fit
+AnalogIn    Driver_Pot      (A1);   //  Moved 31/07/2020 from A3 to free up A3 for use as AnalogOut
 
 BufferedSerial  gps_module  (D1, D0, 2048, 4, NULL);   //  For gps - added July 2020
 
 /*
-    MODULE PIN USAGE    
-1   PA_9 D1     LocalCom Tx FUTURE i2c to enable 3rd independent pwm
-2   PA_10 D0    LocalCom Rx FUTURE i2c to enable 3rd independent pwm
+    MODULE PIN USAGE    -   Updated Aug 2020
+1   PA_9 D1     LocalCom Tx
+2   PA_10 D0    LocalCom Rx GPS maybe
 3   NRST        
 4   GND     
-5   PA12_D2     NEW June 2019 - Output engine tacho cleaned-up, brought out to testpoint 4
-6   PB_0 D3     AnalogIn Ext_Rev_Demand
+5   PA12_D2     InterruptIn VEXT PWM controller output folded back for cpu to monitor, useful on test to read what pwm required to do what
+6   PB_0 D3     AnalogIn Field supply voltage
 7   PB_7 D4     SDA i2c to 24LC memory
 8   PB_6 D5     SCL i2c to 24LC memory
-9   PB_12 D6    PwmOut     PWM_OSC_IN Timebase for pwm, also determines max duty ratio
+9   PB_12 D6    DigitalOut  CHARGE_PUMP new Aug 2020
 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
-14  PB_5 D11   //  InterruptIn VEXT PWM controller output folded back for cpu to monitor, useful on test to read what pwm required to do what
-15  PB_4 D12    Scope_probe
-16  PB_3 D13 LED    Onboard LED
+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
 17  3V3         
 18  AREF        
-19  PA_0 A0     AnalogIn Ammeter_Ref
-20  PA_1 A1     AnalogIn Ammeter_In
-21  PA_3 A2     PWM analogue out
-22  PA_4 A3     AnalogIn Driver_Pot
-23  PA_5 A4     n.c. SDA_IN paralleled to i2c pin, necessary because i2c has to be bit banged
-24  PA_6 A5     n.c. SCL_IN paralleled to i2c pin, necessary because i2c has to be bit banged
-25  PA_7 A6     AnalogIn V_Sample system link voltage
-26  PA_2 A7     Not used
+19  PA_0 A0     AnalogIn    Driver Pot
+20  PA_1 A1     AnalogIn    Ammeter_In
+21  PA_3 A2     PwmOut      PWM_OSC_IN Timebase for pwm, also determines max duty ratio
+//22  PA_4 A3     AnalogOut   A_OUT control signal to following traction motor ESC
+22  PA_4 A3     AnalogOut   REF_VAR reference voltage to MCP1630, allows software to set alternator output voltage
+23  PA_5 A4     AnalogOut   A_OUT control signal to following traction motor ESC
+24  PA_6 A5     Spare
+25  PA_7 A6     AnalogIn    V_Sample system link voltage
+26  PA_2 A7     Not useable, taken by uart
 27  5V          
 28  NRST        
 29  GND         
@@ -128,7 +128,8 @@
 //InterruptIn VEXT            (D2);     //  PWM controller output folded back for cpu to monitor, useful on test to read what pwm required to do what
 //                      Note D2 still used but taken to field class object
 //  OUTPUTS :
-
+AnalogOut   REF_VAR (A4);    //  Variable REF to MCP1630 enables software control of output voltage - NEW Aug 2020
+AnalogOut   A_OUT   (A3);    //  Control voltage out to traction motor ESCs
 DigitalOut  Scope_probe     (D12);   //  Handy pin to hang scope probe onto while developing code
 DigitalOut  myled           (LED1);        //  Green LED on board is PB_3 D13
 //PwmOut      PWM_OSC_IN      (A2);   //  Can alter prescaler can not use A5    NOW DONE IN CLASS
@@ -140,11 +141,11 @@
 
 extern  char *  get_mode_text   (uint32_t mode)  ;
 
-
+DigitalOut  CHARGE_PUMP (D6);
 I2CEeprom       eeprom  (SDA_PIN, SCL_PIN, 0xa0, eeprom_page_size, 8192, 100000);
 extern  ee_settings_2020 user_settings  ;
-Engine_Manager  Engine  (D9, D11, D10); //  Pins are magneto in, cleaned magneto out, servo, const debounce time microsecs
-FieldControl    Field   (A2, D2);       //  PWM pin for MCP1630, InterruptIn for signal out of MCP1630
+Engine_Manager  Engine  (D9, D11, D10); //  Pins are magneto in, cleaned magneto out, servo
+FieldControl    Field   (A2, D2);       //  PWM pin for MCP1630 PWM_OSC_IN, InterruptIn for signal out of MCP1630 VEXTFB
 PCT2075         temp_sensor( SDA_PIN, SCL_PIN );    //  or LM75B temp_sensor( p?, p? );  Added March 2020
 
 //class   MPL3115A2   baro    ;
@@ -179,18 +180,18 @@
 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;
     switch  (t) {
-        case    0:
+        case    0:      //  Alternator output voltage
             flag_link_V_rd = true;
             break;
-        case    1:
+        case    1:      //  Ammeter
             flag_A_rd = true;
             break;
-        case    2:
+        case    2:      //  Driver's Pot
             flag_Pot_rd = true;
-//            raw_amp_offset = Ammeter_Ref.read();    //  Feb 2020 Not convinced this is useful
             break;
-        case    3:
+        case    3:      //  Field supply voltage
             flag_field_V_rd = true;
             break;
 //        case    4:
@@ -294,16 +295,20 @@
 //  Programme Entry Point
 int main()
 {
+    const   double PI   = (2.0 * acos(0.0));
     const   double  filt = 0.2;
     const   double  ampfilt = 0.2;
     const   double  vfilt = 0.2;
     //  local variable declarations
     double  driver_pot = 0.0, dtmp;
+//    double  theta = 0.0;
     int32_t temp, startup_delay, print_position = 0;
     int32_t field_pct = 0, auto_test_timer = 0, auto_test_state = AUTO_TEST_INACTIVE, auto_test_step = 0;
     bool    up_and_running = false;
     char    text[64];
-
+    
+    A_OUT = 0.0;
+    REF_VAR = 0.0;
     microsecs.reset()   ;   //  timer = 0
     microsecs.start ()  ;   //  64 bit, counts micro seconds and times out in half million years
 
@@ -328,8 +333,8 @@
     while   (1) {      //  Loop forever, repeats synchroised by waiting for ticker Interrupt Service Routine to set 'loop_flag' true
         while   (!loop_flag)  {         //  Most of the time is spent in this loop, repeatedly re-checking for commands from pc port
 #ifdef  GPS_
-            while   (gps_module.readable())
-                pc.putc (gps_module.getc());
+//            while   (gps_module.readable())
+//                pc.putc (gps_module.getc());
 #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
@@ -360,6 +365,12 @@
 #ifdef GPS_
         gps.update  ();
 #endif
+/*        theta += 0.05;
+        if  (theta > PI)
+            theta -= 2.0 * PI;
+        sinout = 0.5 + sin(theta) / 2.0;
+        cosout = 0.5 + cos(theta) / 2.0;
+*/
 //  END 100Hz stuff
         if  (flag_25Hz)  {
             flag_25Hz = false;