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

Committer:
JonFreeman
Date:
Sat Dec 05 12:40:17 2020 +0000
Revision:
5:6ca3e7ffc553
Parent:
4:28cc0cf01570
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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JonFreeman 5:6ca3e7ffc553 1 /*******************************************************************************
JonFreeman 5:6ca3e7ffc553 2 DON'T FORGET TO REMOVE SOLDER LINKS SB16 AND SB18 ON NUCLEO-L432KC BOARD
JonFreeman 5:6ca3e7ffc553 3 *******************************************************************************/
JonFreeman 0:77803b3ee157 4 #include "mbed.h"
JonFreeman 0:77803b3ee157 5 #include "Alternator.h"
JonFreeman 3:43cb067ecd00 6 #include "BufferedSerial.h"
JonFreeman 3:43cb067ecd00 7 #include "I2CEeprom.h"
JonFreeman 3:43cb067ecd00 8 #include "LM75B.h" // New I2C temp sensor code March 2020 (to suit possible next board issue, harmless otherwise)
JonFreeman 3:43cb067ecd00 9 #include "rpm.h"
JonFreeman 3:43cb067ecd00 10 #include "field.h"
JonFreeman 4:28cc0cf01570 11 #include "gps_mod.h"
JonFreeman 5:6ca3e7ffc553 12
JonFreeman 3:43cb067ecd00 13 //#include "baro.h"
JonFreeman 3:43cb067ecd00 14
JonFreeman 3:43cb067ecd00 15 #ifdef TARGET_NUCLEO_L432KC // 24LC and LM75 work
JonFreeman 3:43cb067ecd00 16 // #define SDA_PIN D0 // good
JonFreeman 3:43cb067ecd00 17 // #define SCL_PIN D1
JonFreeman 3:43cb067ecd00 18 #define SDA_PIN D4 // good
JonFreeman 3:43cb067ecd00 19 #define SCL_PIN D5
JonFreeman 3:43cb067ecd00 20 #endif
JonFreeman 3:43cb067ecd00 21
JonFreeman 3:43cb067ecd00 22 /*******************************************************************************
JonFreeman 3:43cb067ecd00 23 DON'T FORGET TO REMOVE SOLDER LINKS SB16 AND SB18 ON L432KC BOARD
JonFreeman 3:43cb067ecd00 24 *******************************************************************************/
JonFreeman 3:43cb067ecd00 25 //During test LED across field has been useful visual aid. Incorporate similar on new board.
JonFreeman 2:8e7b51353f32 26 /*
JonFreeman 2:8e7b51353f32 27 * May 2020 NOTE input circuit to analogue in driver pot zeners input to 3v6, then pot reduces by about 1/3.
JonFreeman 2:8e7b51353f32 28 * This makes input reading only about 0.0 to 0.66
JonFreeman 2:8e7b51353f32 29 * Temp bodge, mult by 1.5
JonFreeman 3:43cb067ecd00 30
JonFreeman 3:43cb067ecd00 31 * Two voltages now measured. Link voltage (alternator output), and field supply (which may come from battery when main output low)
JonFreeman 2:8e7b51353f32 32 */
JonFreeman 0:77803b3ee157 33
JonFreeman 0:77803b3ee157 34 /*
JonFreeman 0:77803b3ee157 35 Alternator Regulator
JonFreeman 0:77803b3ee157 36 Jon Freeman
JonFreeman 3:43cb067ecd00 37 June 2019 - June 2020
JonFreeman 1:450090bdb6f4 38
JonFreeman 3:43cb067ecd00 39 ** Prototype built using Nucleo L432KC. Having solved i2c problem, this looks good for final product
JonFreeman 0:77803b3ee157 40
JonFreeman 1:450090bdb6f4 41 ** main loop frequency upped from 32Hz to 100Hz **
JonFreeman 1:450090bdb6f4 42
JonFreeman 1:450090bdb6f4 43 WHAT THIS PROGRAMME DOES - Controls 4 stroke petrol engine driving vehicle alternator with new custom regulator
JonFreeman 1:450090bdb6f4 44
JonFreeman 3:43cb067ecd00 45 Electronics powered by higher voltage of small 12v backup battery, or alternator output
JonFreeman 1:450090bdb6f4 46 Note only Field+ and MAX5035 supplied thus, all else powered from MAX outputs.
JonFreeman 1:450090bdb6f4 47 Starting engine provides rectified tickle from magneto to enable MAX5035 creating +5 and +3v3 supplies.
JonFreeman 3:43cb067ecd00 48 Alternative, selected by jumper position, is external switch - battery+ to MAX enable circuit. ** Review this **
JonFreeman 3:43cb067ecd00 49 Anytime engine revs measured < TICKOVER_RPM (or some such) RPM, field current OFF (by pwm 0) , see speed related pwm limit table
JonFreeman 0:77803b3ee157 50
JonFreeman 0:77803b3ee157 51 BEGIN
JonFreeman 1:450090bdb6f4 52 Loop forever at 100 Hz {
JonFreeman 1:450090bdb6f4 53 Read engine RPM by monitoring engine tacho signal present on engine On/Off switch line
JonFreeman 1:450090bdb6f4 54 Adjust Alternator field current max limit according to RPM (analogue regulator limits output voltage)
JonFreeman 0:77803b3ee157 55 Measure system voltage (just in case this is ever useful)
JonFreeman 0:77803b3ee157 56 Respond to any commands arriving at serial port (setup and test link to laptop)
JonFreeman 0:77803b3ee157 57 Flash LED at 8 Hz as proof of life
JonFreeman 0:77803b3ee157 58 }
JonFreeman 0:77803b3ee157 59 END
JonFreeman 0:77803b3ee157 60
JonFreeman 0:77803b3ee157 61 INPUTS AnalogIn x 2 - Ammeter chip - current and offset AnalogIns
JonFreeman 0:77803b3ee157 62 INPUT AnalogIn - System voltage for info only.
JonFreeman 0:77803b3ee157 63 INPUT AnalogIn - ExtRevDemand
JonFreeman 0:77803b3ee157 64 INPUT AnalogIn - DriverPot
JonFreeman 0:77803b3ee157 65 INPUT Pulse engine speed indicator, speed checked against EEPROM data to select max pwm duty ratio for this speed
JonFreeman 0:77803b3ee157 66 INPUT Final pwm gate drive wired back to InterruptIn ** MAYBE USEFUL OR NOT ** Could read this back via serial to laptop
JonFreeman 0:77803b3ee157 67 OUTPUT pwm to MCP1630. This is clock to pwm chip. Also limits max duty ratio
JonFreeman 0:77803b3ee157 68 RS232 serial via USB to setup eeprom data
JonFreeman 0:77803b3ee157 69 */
JonFreeman 0:77803b3ee157 70
JonFreeman 0:77803b3ee157 71 /**
JonFreeman 0:77803b3ee157 72 * Jumpers fitted to small mbed Nucleo boards - D5 - A5 and D4 - A4 CHECK - yes
JonFreeman 0:77803b3ee157 73 */
JonFreeman 3:43cb067ecd00 74 //#ifdef TARGET_NUCLEO_L432KC // Has to be, quite settled now on this, having solved i2c problems
JonFreeman 3:43cb067ecd00 75 BufferedSerial pc (USBTX, USBRX, 4096, 4, NULL); // Comms port to pc or terminal using USB lead
JonFreeman 2:8e7b51353f32 76 //BufferedSerial LocalCom (PA_9, PA_10); // New March 2019 - Taken out for i2c test 6/6/2020
JonFreeman 2:8e7b51353f32 77
JonFreeman 0:77803b3ee157 78 // INPUTS :
JonFreeman 3:43cb067ecd00 79 AnalogIn Ain_Link_Volts (A6); // Sniff of alternator output, not used in control loop as done using analogue MCP1630
JonFreeman 4:28cc0cf01570 80 AnalogIn Ammeter_In (A0); // Output of ASC709LLFTR ammeter chip (pin 20), used to increase engine revs if need be
JonFreeman 1:450090bdb6f4 81
JonFreeman 3:43cb067ecd00 82 // Nov 2019. Not convinced Ext_Rev_Demand is useful ** July 2020 - repurposed, voltmeter Field_Supply_V
JonFreeman 2:8e7b51353f32 83 //AnalogIn Ext_Rev_Demand (D3); // Servo determines engine revs, servo out to be higher of Ext_Rev_Demand and internal calc
JonFreeman 3:43cb067ecd00 84 AnalogIn Field_Supply_V (D3); // Servo determines engine revs, servo out to be higher of Ext_Rev_Demand and internal calc
JonFreeman 1:450090bdb6f4 85
JonFreeman 4:28cc0cf01570 86 AnalogIn Driver_Pot (A1); // Moved 31/07/2020 from A3 to free up A3 for use as AnalogOut
JonFreeman 0:77803b3ee157 87
JonFreeman 3:43cb067ecd00 88 BufferedSerial gps_module (D1, D0, 2048, 4, NULL); // For gps - added July 2020
JonFreeman 3:43cb067ecd00 89
JonFreeman 0:77803b3ee157 90 /*
JonFreeman 4:28cc0cf01570 91 MODULE PIN USAGE - Updated Aug 2020
JonFreeman 4:28cc0cf01570 92 1 PA_9 D1 LocalCom Tx
JonFreeman 4:28cc0cf01570 93 2 PA_10 D0 LocalCom Rx GPS maybe
JonFreeman 0:77803b3ee157 94 3 NRST
JonFreeman 0:77803b3ee157 95 4 GND
JonFreeman 4:28cc0cf01570 96 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
JonFreeman 4:28cc0cf01570 97 6 PB_0 D3 AnalogIn Field supply voltage
JonFreeman 0:77803b3ee157 98 7 PB_7 D4 SDA i2c to 24LC memory
JonFreeman 0:77803b3ee157 99 8 PB_6 D5 SCL i2c to 24LC memory
JonFreeman 4:28cc0cf01570 100 9 PB_12 D6 DigitalOut CHARGE_PUMP new Aug 2020
JonFreeman 0:77803b3ee157 101 10 N.C.
JonFreeman 0:77803b3ee157 102 11 N.C.
JonFreeman 1:450090bdb6f4 103 12 PA_8 D9 InterruptIn pulse_tacho from engine magneto, used to measure rpm
JonFreeman 5:6ca3e7ffc553 104 13 PA_11 D10 Servo
JonFreeman 4:28cc0cf01570 105 14 PB_5 D11 NEW June 2019 - Output engine tacho cleaned-up, brought out to testpoint 4 NOT REALLY USEFUL
JonFreeman 4:28cc0cf01570 106 15 PB_4 D12 Scope_probe NOT REALLY USEFUL
JonFreeman 4:28cc0cf01570 107 16 PB_3 D13 LED Onboard LED
JonFreeman 0:77803b3ee157 108 17 3V3
JonFreeman 0:77803b3ee157 109 18 AREF
JonFreeman 4:28cc0cf01570 110 19 PA_0 A0 AnalogIn Driver Pot
JonFreeman 4:28cc0cf01570 111 20 PA_1 A1 AnalogIn Ammeter_In
JonFreeman 4:28cc0cf01570 112 21 PA_3 A2 PwmOut PWM_OSC_IN Timebase for pwm, also determines max duty ratio
JonFreeman 4:28cc0cf01570 113 //22 PA_4 A3 AnalogOut A_OUT control signal to following traction motor ESC
JonFreeman 4:28cc0cf01570 114 22 PA_4 A3 AnalogOut REF_VAR reference voltage to MCP1630, allows software to set alternator output voltage
JonFreeman 4:28cc0cf01570 115 23 PA_5 A4 AnalogOut A_OUT control signal to following traction motor ESC
JonFreeman 4:28cc0cf01570 116 24 PA_6 A5 Spare
JonFreeman 4:28cc0cf01570 117 25 PA_7 A6 AnalogIn V_Sample system link voltage
JonFreeman 4:28cc0cf01570 118 26 PA_2 A7 Not useable, taken by uart
JonFreeman 0:77803b3ee157 119 27 5V
JonFreeman 0:77803b3ee157 120 28 NRST
JonFreeman 0:77803b3ee157 121 29 GND
JonFreeman 0:77803b3ee157 122 30 VIN
JonFreeman 0:77803b3ee157 123 */
JonFreeman 0:77803b3ee157 124
JonFreeman 2:8e7b51353f32 125 // Test 6/6/2020 to get i2c working
JonFreeman 3:43cb067ecd00 126 //I2C i2c (D0, D1); // For 24LC64 eeprom correct
JonFreeman 2:8e7b51353f32 127 //I2C i2c (D1, D0); // For 24LC64 eeprom DEFINITELY WRONG
JonFreeman 2:8e7b51353f32 128 // Test 6/6/2020 to get i2c working
JonFreeman 2:8e7b51353f32 129
JonFreeman 3:43cb067ecd00 130 //InterruptIn pulse_tacho (D9); // Signal from engine magneto (clipped by I limit resistor and 3v3 zener)
JonFreeman 3:43cb067ecd00 131 // Note D9 still used but taken to rpm class object
JonFreeman 3:43cb067ecd00 132 //InterruptIn VEXT (D2); // PWM controller output folded back for cpu to monitor, useful on test to read what pwm required to do what
JonFreeman 3:43cb067ecd00 133 // Note D2 still used but taken to field class object
JonFreeman 0:77803b3ee157 134 // OUTPUTS :
JonFreeman 4:28cc0cf01570 135 AnalogOut REF_VAR (A4); // Variable REF to MCP1630 enables software control of output voltage - NEW Aug 2020
JonFreeman 4:28cc0cf01570 136 AnalogOut A_OUT (A3); // Control voltage out to traction motor ESCs
JonFreeman 1:450090bdb6f4 137 DigitalOut Scope_probe (D12); // Handy pin to hang scope probe onto while developing code
JonFreeman 1:450090bdb6f4 138 DigitalOut myled (LED1); // Green LED on board is PB_3 D13
JonFreeman 3:43cb067ecd00 139 //PwmOut PWM_OSC_IN (A2); // Can alter prescaler can not use A5 NOW DONE IN CLASS
JonFreeman 1:450090bdb6f4 140 //PwmOut A_OUT (A2); // Can alter prescaler can not use A5 PIN STOLEN BY PWM_OSC_IN
JonFreeman 1:450090bdb6f4 141
JonFreeman 3:43cb067ecd00 142 //PwmOut Test_RPM (PA_6);
JonFreeman 2:8e7b51353f32 143 Timer microsecs; // 64 bit counter, rolls over in half million years
JonFreeman 0:77803b3ee157 144 Ticker loop_timer; // Device to cause periodic interrupts, used to sync iterations of main programme loop - slow
JonFreeman 0:77803b3ee157 145
JonFreeman 3:43cb067ecd00 146 extern char * get_mode_text (uint32_t mode) ;
JonFreeman 3:43cb067ecd00 147
JonFreeman 4:28cc0cf01570 148 DigitalOut CHARGE_PUMP (D6);
JonFreeman 3:43cb067ecd00 149 I2CEeprom eeprom (SDA_PIN, SCL_PIN, 0xa0, eeprom_page_size, 8192, 100000);
JonFreeman 3:43cb067ecd00 150 extern ee_settings_2020 user_settings ;
JonFreeman 4:28cc0cf01570 151 Engine_Manager Engine (D9, D11, D10); // Pins are magneto in, cleaned magneto out, servo
JonFreeman 4:28cc0cf01570 152 FieldControl Field (A2, D2); // PWM pin for MCP1630 PWM_OSC_IN, InterruptIn for signal out of MCP1630 VEXTFB
JonFreeman 3:43cb067ecd00 153 PCT2075 temp_sensor( SDA_PIN, SCL_PIN ); // or LM75B temp_sensor( p?, p? ); Added March 2020
JonFreeman 3:43cb067ecd00 154
JonFreeman 3:43cb067ecd00 155 //class MPL3115A2 baro ;
JonFreeman 3:43cb067ecd00 156
JonFreeman 0:77803b3ee157 157 // SYSTEM CONSTANTS
JonFreeman 0:77803b3ee157 158 /* Please Do Not Alter these */
JonFreeman 1:450090bdb6f4 159 const int MAIN_LOOP_REPEAT_TIME_US = 10000; // 10000 us, with TACHO_TAB_SIZE = 100 means tacho_ticks_per_time is tacho_ticks_per_second
JonFreeman 0:77803b3ee157 160 /* End of Please Do Not Alter these */
JonFreeman 0:77803b3ee157 161 /* Global variable declarations */
JonFreeman 3:43cb067ecd00 162 uint32_t sys_timer100Hz = 0; // gets incremented by our Ticker ISR every MAIN_LOOP_REPEAT_TIME_US
JonFreeman 3:43cb067ecd00 163 uint32_t seconds = 0;
JonFreeman 3:43cb067ecd00 164 double link_volt_reading = 0.0; // Global updated by interrupt driven read of Battery Volts at rate of 100 Hz
JonFreeman 3:43cb067ecd00 165 double field_volt_reading = 0.0; // Global updated by interrupt driven read of Battery Volts at rate of 100 Hz
JonFreeman 3:43cb067ecd00 166 double amp_reading = 0.0;
JonFreeman 0:77803b3ee157 167 bool loop_flag = false; // made true in ISR_loop_timer, picked up and made false again in main programme loop
JonFreeman 1:450090bdb6f4 168 bool flag_25Hz = false; // As loop_flag but repeats 25 times per sec
JonFreeman 1:450090bdb6f4 169 bool flag_12Hz5 = false; // As loop_flag but repeats 12.5 times per sec
JonFreeman 1:450090bdb6f4 170 bool flag_1Hz = false; // As loop_flag but repeats 1 times per sec
JonFreeman 1:450090bdb6f4 171 bool query_toggle = false;
JonFreeman 0:77803b3ee157 172
JonFreeman 3:43cb067ecd00 173 bool flag_link_V_rd = false;
JonFreeman 3:43cb067ecd00 174 bool flag_field_V_rd = false;
JonFreeman 3:43cb067ecd00 175 bool flag_A_rd = false;
JonFreeman 2:8e7b51353f32 176 bool flag_Pot_rd = false;
JonFreeman 0:77803b3ee157 177
JonFreeman 3:43cb067ecd00 178 bool auto_test_flag = false;
JonFreeman 3:43cb067ecd00 179
JonFreeman 5:6ca3e7ffc553 180 bool charge_pump_enable = true;
JonFreeman 5:6ca3e7ffc553 181
JonFreeman 3:43cb067ecd00 182 enum {SAFE_NOTHING, POT_SERVO_DIRECT, VARIABLE_VOLTAGE, FIXED_VOLTAGE, ENG_REVS_CTRL, POT_SETS_ENGINE_RPM, CURRENT_FEEDBACK_CTRL, AUTO_TEST} ;
JonFreeman 0:77803b3ee157 183 /* End of Global variable declarations */
JonFreeman 0:77803b3ee157 184
JonFreeman 1:450090bdb6f4 185 //void ISR_fast_interrupt () { // here at 10 times main loop repeat rate (i.e. 1000Hz, 1.0ms)
JonFreeman 1:450090bdb6f4 186 void ISR_fast_interrupt () {
JonFreeman 3:43cb067ecd00 187 static uint32_t t = 0, u25 = 0;
JonFreeman 1:450090bdb6f4 188 Scope_probe = 1; // To show how much time spent in interrupt handler
JonFreeman 5:6ca3e7ffc553 189 if (charge_pump_enable)
JonFreeman 5:6ca3e7ffc553 190 CHARGE_PUMP = !CHARGE_PUMP;
JonFreeman 0:77803b3ee157 191 switch (t) {
JonFreeman 4:28cc0cf01570 192 case 0: // Alternator output voltage
JonFreeman 3:43cb067ecd00 193 flag_link_V_rd = true;
JonFreeman 0:77803b3ee157 194 break;
JonFreeman 4:28cc0cf01570 195 case 1: // Ammeter
JonFreeman 3:43cb067ecd00 196 flag_A_rd = true;
JonFreeman 3:43cb067ecd00 197 break;
JonFreeman 4:28cc0cf01570 198 case 2: // Driver's Pot
JonFreeman 2:8e7b51353f32 199 flag_Pot_rd = true;
JonFreeman 0:77803b3ee157 200 break;
JonFreeman 4:28cc0cf01570 201 case 3: // Field supply voltage
JonFreeman 3:43cb067ecd00 202 flag_field_V_rd = true;
JonFreeman 3:43cb067ecd00 203 break;
JonFreeman 3:43cb067ecd00 204 // case 4:
JonFreeman 2:8e7b51353f32 205 // driver_reading >>= 1; // Result = Result / 2
JonFreeman 2:8e7b51353f32 206 // driver_reading += Driver_Pot.read_u16();
JonFreeman 1:450090bdb6f4 207 // break;
JonFreeman 3:43cb067ecd00 208 case 5:
JonFreeman 0:77803b3ee157 209 loop_flag = true; // set flag to allow main programme loop to proceed
JonFreeman 1:450090bdb6f4 210 sys_timer100Hz++; // Just a handy measure of elapsed time for anything to use
JonFreeman 3:43cb067ecd00 211 if ((sys_timer100Hz & 0x03) == 0) { // is now 12.5Hz, not 8
JonFreeman 1:450090bdb6f4 212 flag_25Hz = true; // flag gets set 25 times per sec. Other code may clear flag and make use of this
JonFreeman 3:43cb067ecd00 213 u25++;
JonFreeman 3:43cb067ecd00 214 if (u25 == 25) {
JonFreeman 3:43cb067ecd00 215 u25 = 0;
JonFreeman 3:43cb067ecd00 216 flag_1Hz = true;
JonFreeman 3:43cb067ecd00 217 seconds++;
JonFreeman 3:43cb067ecd00 218 }
JonFreeman 3:43cb067ecd00 219 }
JonFreeman 1:450090bdb6f4 220 default:
JonFreeman 0:77803b3ee157 221 break;
JonFreeman 0:77803b3ee157 222 }
JonFreeman 0:77803b3ee157 223 t++;
JonFreeman 0:77803b3ee157 224 if (t > 9)
JonFreeman 0:77803b3ee157 225 t = 0;
JonFreeman 1:450090bdb6f4 226 Scope_probe = 0; // To show how much time spent in interrupt handler
JonFreeman 0:77803b3ee157 227 }
JonFreeman 0:77803b3ee157 228
JonFreeman 0:77803b3ee157 229 // **** End of Interrupt Service Routines ****
JonFreeman 0:77803b3ee157 230
JonFreeman 1:450090bdb6f4 231 /*double Read_Ext_Rev_Req ()
JonFreeman 1:450090bdb6f4 232 {
JonFreeman 1:450090bdb6f4 233 double rv = (double) ext_rev_req;
JonFreeman 1:450090bdb6f4 234 return rv / 4096.0;
JonFreeman 1:450090bdb6f4 235 }*/
JonFreeman 3:43cb067ecd00 236 /*
JonFreeman 1:450090bdb6f4 237 double Read_Driver_Pot ()
JonFreeman 1:450090bdb6f4 238 {
JonFreeman 1:450090bdb6f4 239 double rv = (double) driver_reading;
JonFreeman 1:450090bdb6f4 240 return rv / 4096.0;
JonFreeman 3:43cb067ecd00 241 }*/
JonFreeman 0:77803b3ee157 242
JonFreeman 3:43cb067ecd00 243 double Read_Link_Volts ()
JonFreeman 3:43cb067ecd00 244 {
JonFreeman 3:43cb067ecd00 245 return link_volt_reading * 39.9; // divisor fiddled to make voltage reading correct !
JonFreeman 0:77803b3ee157 246 }
JonFreeman 0:77803b3ee157 247
JonFreeman 3:43cb067ecd00 248 double Read_Field_Volts ()
JonFreeman 3:43cb067ecd00 249 {
JonFreeman 5:6ca3e7ffc553 250 // return field_volt_reading * 42.85; // divisor fiddled to make voltage reading correct !
JonFreeman 5:6ca3e7ffc553 251 return field_volt_reading * 40.12; // divisor fiddled to make voltage reading correct !
JonFreeman 0:77803b3ee157 252 }
JonFreeman 0:77803b3ee157 253
JonFreeman 3:43cb067ecd00 254 double Read_Ammeter ()
JonFreeman 3:43cb067ecd00 255 {
JonFreeman 3:43cb067ecd00 256 return amp_reading * 93.28; // Amp range corrected here
JonFreeman 1:450090bdb6f4 257 }
JonFreeman 1:450090bdb6f4 258
JonFreeman 1:450090bdb6f4 259
JonFreeman 5:6ca3e7ffc553 260 void query_system (parameters & a) {
JonFreeman 1:450090bdb6f4 261 query_toggle = !query_toggle;
JonFreeman 3:43cb067ecd00 262 }
JonFreeman 3:43cb067ecd00 263
JonFreeman 5:6ca3e7ffc553 264 void set_v_out_opamp (double a) { // 0 to 1.0 sets opamp output in range 0 to 5v, charge pump permitting
JonFreeman 5:6ca3e7ffc553 265 A_OUT = a;
JonFreeman 5:6ca3e7ffc553 266 }
JonFreeman 5:6ca3e7ffc553 267 void set_v_out_opamp (parameters & a) { // 0 to 1.0 sets opamp output in range 0 to 5v, charge pump permitting
JonFreeman 5:6ca3e7ffc553 268 A_OUT = a.dbl[0] / 100.0;
JonFreeman 5:6ca3e7ffc553 269 }
JonFreeman 5:6ca3e7ffc553 270
JonFreeman 5:6ca3e7ffc553 271 void charge_pump_override (int a) { // 0 disables, !0 enables charge pump
JonFreeman 5:6ca3e7ffc553 272 if (a == 0)
JonFreeman 5:6ca3e7ffc553 273 charge_pump_enable = false;
JonFreeman 5:6ca3e7ffc553 274 else
JonFreeman 5:6ca3e7ffc553 275 charge_pump_enable = true;
JonFreeman 5:6ca3e7ffc553 276 }
JonFreeman 5:6ca3e7ffc553 277 void charge_pump_override (parameters & a) { // 0 disables, !0 enables charge pump
JonFreeman 5:6ca3e7ffc553 278 charge_pump_override ((int)a.dbl[0]);
JonFreeman 5:6ca3e7ffc553 279 }
JonFreeman 5:6ca3e7ffc553 280
JonFreeman 3:43cb067ecd00 281 void set_pwm (double d) { // Range 0.0 to 1.0 called from cli
JonFreeman 3:43cb067ecd00 282 Field.set_pwm (d);
JonFreeman 2:8e7b51353f32 283 }
JonFreeman 2:8e7b51353f32 284
JonFreeman 3:43cb067ecd00 285 double get_temperature () {
JonFreeman 3:43cb067ecd00 286 return (double) temp_sensor;
JonFreeman 3:43cb067ecd00 287 }
JonFreeman 3:43cb067ecd00 288
JonFreeman 3:43cb067ecd00 289 void maketable () {
JonFreeman 3:43cb067ecd00 290 Field.maketable ();
JonFreeman 2:8e7b51353f32 291 }
JonFreeman 2:8e7b51353f32 292
JonFreeman 3:43cb067ecd00 293 int32_t set_engine_RPM_lit (uint32_t RPMrequest) { // Returns actual speed
JonFreeman 3:43cb067ecd00 294 return Engine.set_RPM_literal (RPMrequest);
JonFreeman 3:43cb067ecd00 295 }
JonFreeman 2:8e7b51353f32 296
JonFreeman 3:43cb067ecd00 297 int32_t set_engine_RPM_pct (uint32_t RPMrequest) { // Returns actual speed
JonFreeman 3:43cb067ecd00 298 return Engine.set_RPM_percent (RPMrequest);
JonFreeman 3:43cb067ecd00 299 }
JonFreeman 2:8e7b51353f32 300
JonFreeman 3:43cb067ecd00 301 void auto_test_initiate (int bulb_count) {
JonFreeman 3:43cb067ecd00 302 if (Engine.running()) {
JonFreeman 3:43cb067ecd00 303 auto_test_flag = true;
JonFreeman 3:43cb067ecd00 304 pc.printf ("Requesting Auto-Test for load of %d lamps\r\n", bulb_count);
JonFreeman 3:43cb067ecd00 305 }
JonFreeman 3:43cb067ecd00 306 else {
JonFreeman 3:43cb067ecd00 307 pc.printf ("Engine not running. Can't perform auto test\r\n");
JonFreeman 3:43cb067ecd00 308 auto_test_flag = false;
JonFreeman 2:8e7b51353f32 309 }
JonFreeman 1:450090bdb6f4 310 }
JonFreeman 1:450090bdb6f4 311
JonFreeman 3:43cb067ecd00 312 void is_eng_running () {
JonFreeman 3:43cb067ecd00 313 pc.printf ("Engine%sRunning\r\n", Engine.running() ? " IS " : " NOT ");
JonFreeman 3:43cb067ecd00 314 }
JonFreeman 3:43cb067ecd00 315
JonFreeman 0:77803b3ee157 316 extern void command_line_interpreter () ; // Comms with optional pc or device using serial port through board USB socket
JonFreeman 3:43cb067ecd00 317
JonFreeman 3:43cb067ecd00 318 enum {AUTO_TEST_INACTIVE, AUTO_TEST_BEGIN, AUTO_TEST_ABORT, AUTO_TEST_IN_PROGRESS } ;
JonFreeman 0:77803b3ee157 319
JonFreeman 0:77803b3ee157 320 // Programme Entry Point
JonFreeman 0:77803b3ee157 321 int main()
JonFreeman 0:77803b3ee157 322 {
JonFreeman 4:28cc0cf01570 323 const double PI = (2.0 * acos(0.0));
JonFreeman 2:8e7b51353f32 324 const double filt = 0.2;
JonFreeman 3:43cb067ecd00 325 const double ampfilt = 0.2;
JonFreeman 3:43cb067ecd00 326 const double vfilt = 0.2;
JonFreeman 0:77803b3ee157 327 // local variable declarations
JonFreeman 3:43cb067ecd00 328 double driver_pot = 0.0, dtmp;
JonFreeman 4:28cc0cf01570 329 // double theta = 0.0;
JonFreeman 3:43cb067ecd00 330 int32_t temp, startup_delay, print_position = 0;
JonFreeman 3:43cb067ecd00 331 int32_t field_pct = 0, auto_test_timer = 0, auto_test_state = AUTO_TEST_INACTIVE, auto_test_step = 0;
JonFreeman 3:43cb067ecd00 332 bool up_and_running = false;
JonFreeman 3:43cb067ecd00 333 char text[64];
JonFreeman 4:28cc0cf01570 334
JonFreeman 4:28cc0cf01570 335 A_OUT = 0.0;
JonFreeman 4:28cc0cf01570 336 REF_VAR = 0.0;
JonFreeman 0:77803b3ee157 337 microsecs.reset() ; // timer = 0
JonFreeman 0:77803b3ee157 338 microsecs.start () ; // 64 bit, counts micro seconds and times out in half million years
JonFreeman 1:450090bdb6f4 339
JonFreeman 3:43cb067ecd00 340 #ifdef GPS_
JonFreeman 3:43cb067ecd00 341 gps_mod gps;
JonFreeman 1:450090bdb6f4 342 #endif
JonFreeman 3:43cb067ecd00 343 //- Clear the screen, move to (0,0):
JonFreeman 3:43cb067ecd00 344 // \033[2J
JonFreeman 3:43cb067ecd00 345 pc.printf ("\033[2JAlternator Regulator 2020, Jon Freeman\r\n");
JonFreeman 3:43cb067ecd00 346 user_settings.load () ; // Fetch values from eeprom
JonFreeman 0:77803b3ee157 347 // Setup Complete ! Can now start main control forever loop.
JonFreeman 1:450090bdb6f4 348 loop_timer.attach_us (&ISR_fast_interrupt, MAIN_LOOP_REPEAT_TIME_US / 10); // Start periodic interrupt generator 1000us at Feb 2020
JonFreeman 0:77803b3ee157 349
JonFreeman 3:43cb067ecd00 350 Field.maketable () ; // Here to ensure eeprom has been setup
JonFreeman 3:43cb067ecd00 351 Field.set_for_speed (0);
JonFreeman 5:6ca3e7ffc553 352 Engine.Set_Speed_Lever (((double)user_settings.rd(WARMUP_SERVO_POS)) / 100.0);
JonFreeman 3:43cb067ecd00 353 startup_delay = user_settings.rd(WARM_UP_DELAY);
JonFreeman 3:43cb067ecd00 354 pc.printf ("Operating Mode is [%s]\r\n", get_mode_text (user_settings.rd(OP_MODE)));
JonFreeman 3:43cb067ecd00 355
JonFreeman 2:8e7b51353f32 356
JonFreeman 0:77803b3ee157 357 //***** START OF MAIN LOOP
JonFreeman 0:77803b3ee157 358 while (1) { // Loop forever, repeats synchroised by waiting for ticker Interrupt Service Routine to set 'loop_flag' true
JonFreeman 0:77803b3ee157 359 while (!loop_flag) { // Most of the time is spent in this loop, repeatedly re-checking for commands from pc port
JonFreeman 3:43cb067ecd00 360 #ifdef GPS_
JonFreeman 4:28cc0cf01570 361 // while (gps_module.readable())
JonFreeman 4:28cc0cf01570 362 // pc.putc (gps_module.getc());
JonFreeman 3:43cb067ecd00 363 #endif
JonFreeman 0:77803b3ee157 364 command_line_interpreter () ; // Proceed beyond here once loop_timer ticker ISR has set loop_flag true
JonFreeman 3:43cb067ecd00 365 // A to D converters all read at 100 Hz
JonFreeman 5:6ca3e7ffc553 366 if (flag_link_V_rd) { // Reads main alternator output and/or traction battery voltage
JonFreeman 3:43cb067ecd00 367 flag_link_V_rd = false;
JonFreeman 3:43cb067ecd00 368 link_volt_reading *= (1.0 - vfilt); //
JonFreeman 3:43cb067ecd00 369 link_volt_reading += vfilt * (double) Ain_Link_Volts.read(); // Volt fiddle factor NOT corrected here
JonFreeman 2:8e7b51353f32 370 }
JonFreeman 5:6ca3e7ffc553 371 if (flag_Pot_rd) { // Reads Driver's speed control potentiometer
JonFreeman 2:8e7b51353f32 372 flag_Pot_rd = false;
JonFreeman 3:43cb067ecd00 373 driver_pot *= (1.0 - filt);
JonFreeman 3:43cb067ecd00 374 driver_pot += filt * ((double)Driver_Pot.read() * 1.5); // Includes bodge around zener over-clipping input
JonFreeman 3:43cb067ecd00 375 }
JonFreeman 5:6ca3e7ffc553 376 if (flag_A_rd) { // Reads ammeter - user wires this to suit their purpose
JonFreeman 3:43cb067ecd00 377 flag_A_rd = false;
JonFreeman 3:43cb067ecd00 378 amp_reading *= (1.0 - ampfilt);
JonFreeman 5:6ca3e7ffc553 379 amp_reading += ampfilt * ((double) Ammeter_In.read() - 0.495); // Amp range NOT corrected here BUT OFFSET IS
JonFreeman 3:43cb067ecd00 380 }
JonFreeman 5:6ca3e7ffc553 381 if (flag_field_V_rd) { // Reads 'Field Positive' supply - from battery via diode, also alternator rectifier out
JonFreeman 3:43cb067ecd00 382 flag_field_V_rd = false;
JonFreeman 3:43cb067ecd00 383 field_volt_reading *= (1.0 - vfilt); //
JonFreeman 3:43cb067ecd00 384 field_volt_reading += vfilt * (double) Field_Supply_V.read(); // Volt fiddle factor NOT corrected here
JonFreeman 2:8e7b51353f32 385 }
JonFreeman 1:450090bdb6f4 386 } // Jun 2019 pass here 100 times per sec
JonFreeman 1:450090bdb6f4 387 // BEGIN 100Hz stuff
JonFreeman 3:43cb067ecd00 388 loop_flag = false; // Clear flag set by ticker interrupt handler
JonFreeman 3:43cb067ecd00 389 Engine.manager_core (); // This belongs right here, update regularly, keeps 'filtered()' fresh and keeps engine to set rpm
JonFreeman 3:43cb067ecd00 390 #ifdef GPS_
JonFreeman 3:43cb067ecd00 391 gps.update ();
JonFreeman 3:43cb067ecd00 392 #endif
JonFreeman 4:28cc0cf01570 393 /* theta += 0.05;
JonFreeman 4:28cc0cf01570 394 if (theta > PI)
JonFreeman 4:28cc0cf01570 395 theta -= 2.0 * PI;
JonFreeman 4:28cc0cf01570 396 sinout = 0.5 + sin(theta) / 2.0;
JonFreeman 4:28cc0cf01570 397 cosout = 0.5 + cos(theta) / 2.0;
JonFreeman 4:28cc0cf01570 398 */
JonFreeman 1:450090bdb6f4 399 // END 100Hz stuff
JonFreeman 1:450090bdb6f4 400 if (flag_25Hz) {
JonFreeman 1:450090bdb6f4 401 flag_25Hz = false;
JonFreeman 1:450090bdb6f4 402 // BEGIN 25Hz stuff
JonFreeman 0:77803b3ee157 403
JonFreeman 1:450090bdb6f4 404 // END 25Hz stuff
JonFreeman 1:450090bdb6f4 405 // BEGIN 12.5Hz stuff
JonFreeman 1:450090bdb6f4 406 flag_12Hz5 = !flag_12Hz5;
JonFreeman 1:450090bdb6f4 407 if (flag_12Hz5) { // Do any even stuff to be done 12.5 times per second
JonFreeman 3:43cb067ecd00 408 // if (up_and_running && Engine.running()) {
JonFreeman 3:43cb067ecd00 409 if (up_and_running) {
JonFreeman 3:43cb067ecd00 410 switch (user_settings.rd(OP_MODE)) {
JonFreeman 3:43cb067ecd00 411 /*
JonFreeman 3:43cb067ecd00 412 enum {SAFE_NOTHING, //
JonFreeman 3:43cb067ecd00 413 POT_SERVO_DIRECT, //
JonFreeman 3:43cb067ecd00 414 VARIABLE_VOLTAGE, // Batteryless, controllerless Low Cost Loco - alternator connects direct to DC motors
JonFreeman 3:43cb067ecd00 415 FIXED_VOLTAGE, //
JonFreeman 3:43cb067ecd00 416 ENG_REVS_CTRL, //
JonFreeman 3:43cb067ecd00 417 POT_SETS_ENGINE_RPM, //
JonFreeman 3:43cb067ecd00 418 CURRENT_FEEDBACK_CTRL, //
JonFreeman 3:43cb067ecd00 419 AUTO_TEST }; //
JonFreeman 3:43cb067ecd00 420 "0\tSafe nothing mode for cli cmd testing",
JonFreeman 3:43cb067ecd00 421 "1\tPot to Servo direct, field OFF",
JonFreeman 3:43cb067ecd00 422 "2\tVariable voltage",
JonFreeman 3:43cb067ecd00 423 "3\tFixed voltage",
JonFreeman 3:43cb067ecd00 424 "4\tEngine Revs Control",
JonFreeman 3:43cb067ecd00 425 "5\tSet Engine to Driver's Pot",
JonFreeman 3:43cb067ecd00 426 "6\tControl Engine by Current Load",
JonFreeman 3:43cb067ecd00 427 */
JonFreeman 3:43cb067ecd00 428 case SAFE_NOTHING: // Safe nothing mode for cli cmd testing
JonFreeman 5:6ca3e7ffc553 429 // Use this to test command line commands e.g. Set_Speed_Lever, direct field setting etc
JonFreeman 3:43cb067ecd00 430 break;
JonFreeman 3:43cb067ecd00 431
JonFreeman 3:43cb067ecd00 432 case POT_SERVO_DIRECT: // Driver_pot --> servo direct. Field OFF
JonFreeman 5:6ca3e7ffc553 433 // Engine.Set_Speed_Lever (driver_pot);
JonFreeman 5:6ca3e7ffc553 434 Engine.Set_Speed_Lever (driver_pot);
JonFreeman 5:6ca3e7ffc553 435 REF_VAR = driver_pot;
JonFreeman 5:6ca3e7ffc553 436 // Field.set_for_speed (0); // Safe, no output
JonFreeman 5:6ca3e7ffc553 437 Field.set_for_speed (3000); // Safe, no output
JonFreeman 3:43cb067ecd00 438 break;
JonFreeman 3:43cb067ecd00 439
JonFreeman 3:43cb067ecd00 440 case VARIABLE_VOLTAGE: // Variable Voltage
JonFreeman 5:6ca3e7ffc553 441 Engine.Set_Speed_Lever (driver_pot); // Driver_pot --> servo direct. Field ON
JonFreeman 3:43cb067ecd00 442 if (driver_pot > DRIVER_NEUTRAL) // if pot not close to zero
JonFreeman 3:43cb067ecd00 443 Field.set_for_speed (Engine.RPM_latest()); // according to RPM
JonFreeman 3:43cb067ecd00 444 else
JonFreeman 3:43cb067ecd00 445 Field.set_for_speed (0); // Field OFF
JonFreeman 3:43cb067ecd00 446 break;
JonFreeman 3:43cb067ecd00 447
JonFreeman 3:43cb067ecd00 448 case FIXED_VOLTAGE: // Fixed Voltage
JonFreeman 3:43cb067ecd00 449 Field.set_for_speed (Engine.RPM_latest()); // according to RPM
JonFreeman 3:43cb067ecd00 450 break;
JonFreeman 3:43cb067ecd00 451
JonFreeman 3:43cb067ecd00 452 case ENG_REVS_CTRL: // Engine revs control - Pot to control revs over range tickover to MAX_RPM_LIMIT
JonFreeman 3:43cb067ecd00 453 Field.set_for_speed (Engine.RPM_latest());
JonFreeman 3:43cb067ecd00 454 break;
JonFreeman 3:43cb067ecd00 455
JonFreeman 3:43cb067ecd00 456 case POT_SETS_ENGINE_RPM: // Set engine to driver pot
JonFreeman 3:43cb067ecd00 457 dtmp = driver_pot * (MAX_RPM_LIMIT - TICKOVER_RPM) + TICKOVER_RPM;
JonFreeman 3:43cb067ecd00 458 temp = (int32_t) dtmp;
JonFreeman 3:43cb067ecd00 459 Engine.set_RPM_literal (temp); // this sets engine speed controller
JonFreeman 3:43cb067ecd00 460 Field.set_for_speed (Engine.RPM_latest()); // according to RPM
JonFreeman 3:43cb067ecd00 461 break;
JonFreeman 3:43cb067ecd00 462
JonFreeman 3:43cb067ecd00 463 // case CURRENT_MODE: // Set engine speed determined by current drawn
JonFreeman 3:43cb067ecd00 464 case CURRENT_FEEDBACK_CTRL: // Set engine speed determined by current drawn
JonFreeman 3:43cb067ecd00 465 temp = 0; // an integer. Engine set to tickover when no power demand
JonFreeman 3:43cb067ecd00 466 if (driver_pot > DRIVER_NEUTRAL) // if pot not close to zero
JonFreeman 3:43cb067ecd00 467 temp = 1 + (int32_t)abs(Read_Ammeter() * 8.0); // Sets max amps to 100 / 8.0
JonFreeman 3:43cb067ecd00 468 Engine.set_RPM_percent (temp); // this sets engine speed controller
JonFreeman 3:43cb067ecd00 469 Field.set_for_speed (Engine.RPM_latest()); // according to RPM
JonFreeman 3:43cb067ecd00 470 break;
JonFreeman 3:43cb067ecd00 471
JonFreeman 3:43cb067ecd00 472 case AUTO_TEST: // cli command may initiate test sequence implemented here. Wait for flag to proceed.
JonFreeman 3:43cb067ecd00 473 switch (auto_test_state) {
JonFreeman 3:43cb067ecd00 474 case AUTO_TEST_INACTIVE:
JonFreeman 3:43cb067ecd00 475 if (auto_test_flag) // cli has requested auto test sequence
JonFreeman 3:43cb067ecd00 476 auto_test_state = AUTO_TEST_BEGIN;
JonFreeman 3:43cb067ecd00 477 break;
JonFreeman 3:43cb067ecd00 478
JonFreeman 3:43cb067ecd00 479 case AUTO_TEST_BEGIN: // set engine, field etc, then initiate settling time delay
JonFreeman 3:43cb067ecd00 480 Engine.set_RPM_percent (1); // this sets engine speed controller for min useful revs
JonFreeman 3:43cb067ecd00 481 Field.set_for_speed (0);
JonFreeman 3:43cb067ecd00 482 pc.printf ("Starting auto test sequence, user field limit values :\r\n");
JonFreeman 3:43cb067ecd00 483 for (int i = 0; i < 21; i++)
JonFreeman 3:43cb067ecd00 484 pc.printf ("%d, ", user_settings.rd(i));
JonFreeman 3:43cb067ecd00 485 pc.printf ("\r\n");
JonFreeman 3:43cb067ecd00 486 auto_test_step = 0;
JonFreeman 3:43cb067ecd00 487 auto_test_timer = 0;
JonFreeman 3:43cb067ecd00 488 auto_test_state = AUTO_TEST_IN_PROGRESS;
JonFreeman 3:43cb067ecd00 489 break;
JonFreeman 3:43cb067ecd00 490
JonFreeman 3:43cb067ecd00 491 case AUTO_TEST_IN_PROGRESS: // take sets of readings, then timeout back to INACTIVE
JonFreeman 3:43cb067ecd00 492 field_pct = Field.set_for_speed (Engine.RPM_latest()); // according to RPM
JonFreeman 3:43cb067ecd00 493 switch (auto_test_timer++) { // When active, get here @ 12.5Hz
JonFreeman 3:43cb067ecd00 494 case 30: case 40: case 50: case 60: // take readings at these times
JonFreeman 3:43cb067ecd00 495 case 35: case 45: case 55: case 65:
JonFreeman 3:43cb067ecd00 496 // pc.printf ("\tTaking auto_test readings %d, Volts, Amps, RPM req, RPM got, servo position, measured duty ratio\r\n", auto_test_timer);
JonFreeman 3:43cb067ecd00 497 /*
JonFreeman 3:43cb067ecd00 498 Need to collect here,
JonFreeman 3:43cb067ecd00 499 Volts, Amps, RPM got latest, RPM got filtered, servo position, measured duty ratio, lut pcent
JonFreeman 3:43cb067ecd00 500 */
JonFreeman 3:43cb067ecd00 501 pc.printf ("\t%.2f, %.2f, %.2f, %d, %d, %.2f, %.3f, %d\r\n", Read_Link_Volts(), Read_Field_Volts(),
JonFreeman 3:43cb067ecd00 502 Read_Ammeter(), Engine.RPM_latest(), Engine.RPM_filtered(),
JonFreeman 3:43cb067ecd00 503 Engine.get_servo_position(), Field.get_duty_ratio(), field_pct);
JonFreeman 3:43cb067ecd00 504 break;
JonFreeman 3:43cb067ecd00 505 case 66: // After final set of readings
JonFreeman 3:43cb067ecd00 506 auto_test_step++;
JonFreeman 3:43cb067ecd00 507 if (auto_test_step > 10)
JonFreeman 3:43cb067ecd00 508 auto_test_state = AUTO_TEST_ABORT;
JonFreeman 3:43cb067ecd00 509 else { // set conditions for next set of readings
JonFreeman 3:43cb067ecd00 510 temp = Engine.RPM_percent_to_actual(auto_test_step * 10);
JonFreeman 3:43cb067ecd00 511 Engine.set_RPM_percent (auto_test_step * 10);
JonFreeman 3:43cb067ecd00 512 auto_test_timer = 0;
JonFreeman 3:43cb067ecd00 513 pc.printf ("Setting rig for %d percent, %d RPM\r\n", auto_test_step * 10, temp);
JonFreeman 3:43cb067ecd00 514 }
JonFreeman 3:43cb067ecd00 515 break;
JonFreeman 3:43cb067ecd00 516 default:
JonFreeman 3:43cb067ecd00 517 break;
JonFreeman 3:43cb067ecd00 518 }
JonFreeman 3:43cb067ecd00 519 break;
JonFreeman 3:43cb067ecd00 520
JonFreeman 3:43cb067ecd00 521 case AUTO_TEST_ABORT: // Here at test end or because auto_test_flag made false somewhere somehow
JonFreeman 3:43cb067ecd00 522 Engine.set_RPM_percent (0); // this sets engine speed controller
JonFreeman 3:43cb067ecd00 523 Field.set_for_speed (0);
JonFreeman 3:43cb067ecd00 524 auto_test_state = AUTO_TEST_INACTIVE;
JonFreeman 3:43cb067ecd00 525 auto_test_flag = false;
JonFreeman 3:43cb067ecd00 526 pc.printf ("Ending auto test sequence\r\n");
JonFreeman 3:43cb067ecd00 527 break;
JonFreeman 3:43cb067ecd00 528 default:
JonFreeman 3:43cb067ecd00 529 break;
JonFreeman 3:43cb067ecd00 530 } // END OF SWITCH auto_test_state
JonFreeman 3:43cb067ecd00 531 break;
JonFreeman 3:43cb067ecd00 532 default:
JonFreeman 3:43cb067ecd00 533 user_settings.wr (0, OP_MODE); // set to safe non-mode 0
JonFreeman 3:43cb067ecd00 534 break;
JonFreeman 1:450090bdb6f4 535 }
JonFreeman 1:450090bdb6f4 536 }
JonFreeman 3:43cb067ecd00 537 else { // Engine not running
JonFreeman 3:43cb067ecd00 538 Field.set_for_speed (0); // according to RPM
JonFreeman 3:43cb067ecd00 539 }
JonFreeman 1:450090bdb6f4 540 }
JonFreeman 1:450090bdb6f4 541 else { // Do odd 12.5 times per sec stuff
JonFreeman 1:450090bdb6f4 542 flag_12Hz5 = false;
JonFreeman 1:450090bdb6f4 543 myled = !myled;
JonFreeman 1:450090bdb6f4 544 } // End of if(flag_12Hz5)
JonFreeman 1:450090bdb6f4 545 // END 12.5Hz stuff
JonFreeman 3:43cb067ecd00 546 if (flag_1Hz) {
JonFreeman 1:450090bdb6f4 547 // BEGIN 1Hz stuff
JonFreeman 3:43cb067ecd00 548 flag_1Hz = false;
JonFreeman 3:43cb067ecd00 549 if (!up_and_running) {
JonFreeman 3:43cb067ecd00 550 if (startup_delay == 0) {
JonFreeman 3:43cb067ecd00 551 up_and_running = true;
JonFreeman 3:43cb067ecd00 552 pc.printf ("Warmup ended, starting proper ops\r\n");
JonFreeman 5:6ca3e7ffc553 553 Engine.Set_Speed_Lever (0.0);
JonFreeman 3:43cb067ecd00 554 }
JonFreeman 3:43cb067ecd00 555 else {
JonFreeman 3:43cb067ecd00 556 pc.printf ("In Startup warmup delay %d\r", startup_delay--);
JonFreeman 3:43cb067ecd00 557 }
JonFreeman 3:43cb067ecd00 558 }
JonFreeman 1:450090bdb6f4 559 if (query_toggle) {
JonFreeman 3:43cb067ecd00 560 sprintf (text, "\033[%d;0HI=%.1fA, V=%.2fV, ", 20 + print_position, Read_Ammeter() , Read_Link_Volts());
JonFreeman 3:43cb067ecd00 561 pc.printf ("%sRPM %d, rpm_set %d, pot %.3f, servo %.3f \r\n", text, Engine.RPM_latest(), Engine.get_RPM_requested (), driver_pot, Engine.get_servo_position());
JonFreeman 3:43cb067ecd00 562 print_position++;
JonFreeman 3:43cb067ecd00 563 if (print_position > 10)
JonFreeman 3:43cb067ecd00 564 print_position = 0;
JonFreeman 1:450090bdb6f4 565 }
JonFreeman 3:43cb067ecd00 566 //printf("\033[6;3HHello\n");
JonFreeman 3:43cb067ecd00 567 // pc.printf ("\033[0;1HSecs %d \r\n", seconds);
JonFreeman 3:43cb067ecd00 568 // pc.printf ("Temp = %.1f\r", get_temperature());
JonFreeman 3:43cb067ecd00 569 // gps.update();
JonFreeman 3:43cb067ecd00 570 #ifdef GPS_
JonFreeman 3:43cb067ecd00 571 if (gps.new_data()) {
JonFreeman 3:43cb067ecd00 572 myled = !myled;
JonFreeman 3:43cb067ecd00 573 pc.printf("\033[0;1H%s, %s, %s \r\n", gps.time(), gps.latitude(), gps.longitude());
JonFreeman 3:43cb067ecd00 574 pc.printf("alt ^%s^, sats %s lat mer %f, lon mer %f \r\n", gps.altitude(), gps.sat_count(), gps.lat_merged(), gps.lon_merged());
JonFreeman 3:43cb067ecd00 575 pc.printf("%s, heading %s, mph %s \r\n", gps.date(), gps.heading(), gps.mph());
JonFreeman 3:43cb067ecd00 576 pc.printf("%s\r\n \n .\r\n ", gps.message(1));
JonFreeman 3:43cb067ecd00 577 }
JonFreeman 3:43cb067ecd00 578 #endif
JonFreeman 3:43cb067ecd00 579 // while (gps_module.readable())
JonFreeman 3:43cb067ecd00 580 // pc.putc (gps_module.getc());
JonFreeman 1:450090bdb6f4 581 // END 1Hz stuff
JonFreeman 0:77803b3ee157 582 } // eo once per second stuff
JonFreeman 1:450090bdb6f4 583 } // End of 100Hz stuff
JonFreeman 0:77803b3ee157 584 } // End of main programme loop
JonFreeman 0:77803b3ee157 585 } // End of main function - end of programme
JonFreeman 3:43cb067ecd00 586