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:
- 4:28cc0cf01570
- Parent:
- 3:43cb067ecd00
- Child:
- 5:6ca3e7ffc553
diff -r 43cb067ecd00 -r 28cc0cf01570 main.cpp --- 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;