Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed BufferedSerial Servo2 PCT2075 I2CEeprom FastPWM
main.cpp
00001 /******************************************************************************* 00002 DON'T FORGET TO REMOVE SOLDER LINKS SB16 AND SB18 ON NUCLEO-L432KC BOARD 00003 *******************************************************************************/ 00004 #include "mbed.h" 00005 #include "Alternator.h" 00006 #include "BufferedSerial.h" 00007 #include "I2CEeprom.h" 00008 #include "LM75B.h" // New I2C temp sensor code March 2020 (to suit possible next board issue, harmless otherwise) 00009 #include "rpm.h" 00010 #include "field.h" 00011 #include "gps_mod.h" 00012 00013 //#include "baro.h" 00014 00015 #ifdef TARGET_NUCLEO_L432KC // 24LC and LM75 work 00016 // #define SDA_PIN D0 // good 00017 // #define SCL_PIN D1 00018 #define SDA_PIN D4 // good 00019 #define SCL_PIN D5 00020 #endif 00021 00022 /******************************************************************************* 00023 DON'T FORGET TO REMOVE SOLDER LINKS SB16 AND SB18 ON L432KC BOARD 00024 *******************************************************************************/ 00025 //During test LED across field has been useful visual aid. Incorporate similar on new board. 00026 /* 00027 * May 2020 NOTE input circuit to analogue in driver pot zeners input to 3v6, then pot reduces by about 1/3. 00028 * This makes input reading only about 0.0 to 0.66 00029 * Temp bodge, mult by 1.5 00030 00031 * Two voltages now measured. Link voltage (alternator output), and field supply (which may come from battery when main output low) 00032 */ 00033 00034 /* 00035 Alternator Regulator 00036 Jon Freeman 00037 June 2019 - June 2020 00038 00039 ** Prototype built using Nucleo L432KC. Having solved i2c problem, this looks good for final product 00040 00041 ** main loop frequency upped from 32Hz to 100Hz ** 00042 00043 WHAT THIS PROGRAMME DOES - Controls 4 stroke petrol engine driving vehicle alternator with new custom regulator 00044 00045 Electronics powered by higher voltage of small 12v backup battery, or alternator output 00046 Note only Field+ and MAX5035 supplied thus, all else powered from MAX outputs. 00047 Starting engine provides rectified tickle from magneto to enable MAX5035 creating +5 and +3v3 supplies. 00048 Alternative, selected by jumper position, is external switch - battery+ to MAX enable circuit. ** Review this ** 00049 Anytime engine revs measured < TICKOVER_RPM (or some such) RPM, field current OFF (by pwm 0) , see speed related pwm limit table 00050 00051 BEGIN 00052 Loop forever at 100 Hz { 00053 Read engine RPM by monitoring engine tacho signal present on engine On/Off switch line 00054 Adjust Alternator field current max limit according to RPM (analogue regulator limits output voltage) 00055 Measure system voltage (just in case this is ever useful) 00056 Respond to any commands arriving at serial port (setup and test link to laptop) 00057 Flash LED at 8 Hz as proof of life 00058 } 00059 END 00060 00061 INPUTS AnalogIn x 2 - Ammeter chip - current and offset AnalogIns 00062 INPUT AnalogIn - System voltage for info only. 00063 INPUT AnalogIn - ExtRevDemand 00064 INPUT AnalogIn - DriverPot 00065 INPUT Pulse engine speed indicator, speed checked against EEPROM data to select max pwm duty ratio for this speed 00066 INPUT Final pwm gate drive wired back to InterruptIn ** MAYBE USEFUL OR NOT ** Could read this back via serial to laptop 00067 OUTPUT pwm to MCP1630. This is clock to pwm chip. Also limits max duty ratio 00068 RS232 serial via USB to setup eeprom data 00069 */ 00070 00071 /** 00072 * Jumpers fitted to small mbed Nucleo boards - D5 - A5 and D4 - A4 CHECK - yes 00073 */ 00074 //#ifdef TARGET_NUCLEO_L432KC // Has to be, quite settled now on this, having solved i2c problems 00075 BufferedSerial pc (USBTX, USBRX, 4096, 4, NULL); // Comms port to pc or terminal using USB lead 00076 //BufferedSerial LocalCom (PA_9, PA_10); // New March 2019 - Taken out for i2c test 6/6/2020 00077 00078 // INPUTS : 00079 AnalogIn Ain_Link_Volts (A6); // Sniff of alternator output, not used in control loop as done using analogue MCP1630 00080 AnalogIn Ammeter_In (A0); // Output of ASC709LLFTR ammeter chip (pin 20), used to increase engine revs if need be 00081 00082 // Nov 2019. Not convinced Ext_Rev_Demand is useful ** July 2020 - repurposed, voltmeter Field_Supply_V 00083 //AnalogIn Ext_Rev_Demand (D3); // Servo determines engine revs, servo out to be higher of Ext_Rev_Demand and internal calc 00084 AnalogIn Field_Supply_V (D3); // Servo determines engine revs, servo out to be higher of Ext_Rev_Demand and internal calc 00085 00086 AnalogIn Driver_Pot (A1); // Moved 31/07/2020 from A3 to free up A3 for use as AnalogOut 00087 00088 BufferedSerial gps_module (D1, D0, 2048, 4, NULL); // For gps - added July 2020 00089 00090 /* 00091 MODULE PIN USAGE - Updated Aug 2020 00092 1 PA_9 D1 LocalCom Tx 00093 2 PA_10 D0 LocalCom Rx GPS maybe 00094 3 NRST 00095 4 GND 00096 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 00097 6 PB_0 D3 AnalogIn Field supply voltage 00098 7 PB_7 D4 SDA i2c to 24LC memory 00099 8 PB_6 D5 SCL i2c to 24LC memory 00100 9 PB_12 D6 DigitalOut CHARGE_PUMP new Aug 2020 00101 10 N.C. 00102 11 N.C. 00103 12 PA_8 D9 InterruptIn pulse_tacho from engine magneto, used to measure rpm 00104 13 PA_11 D10 Servo 00105 14 PB_5 D11 NEW June 2019 - Output engine tacho cleaned-up, brought out to testpoint 4 NOT REALLY USEFUL 00106 15 PB_4 D12 Scope_probe NOT REALLY USEFUL 00107 16 PB_3 D13 LED Onboard LED 00108 17 3V3 00109 18 AREF 00110 19 PA_0 A0 AnalogIn Driver Pot 00111 20 PA_1 A1 AnalogIn Ammeter_In 00112 21 PA_3 A2 PwmOut PWM_OSC_IN Timebase for pwm, also determines max duty ratio 00113 //22 PA_4 A3 AnalogOut A_OUT control signal to following traction motor ESC 00114 22 PA_4 A3 AnalogOut REF_VAR reference voltage to MCP1630, allows software to set alternator output voltage 00115 23 PA_5 A4 AnalogOut A_OUT control signal to following traction motor ESC 00116 24 PA_6 A5 Spare 00117 25 PA_7 A6 AnalogIn V_Sample system link voltage 00118 26 PA_2 A7 Not useable, taken by uart 00119 27 5V 00120 28 NRST 00121 29 GND 00122 30 VIN 00123 */ 00124 00125 // Test 6/6/2020 to get i2c working 00126 //I2C i2c (D0, D1); // For 24LC64 eeprom correct 00127 //I2C i2c (D1, D0); // For 24LC64 eeprom DEFINITELY WRONG 00128 // Test 6/6/2020 to get i2c working 00129 00130 //InterruptIn pulse_tacho (D9); // Signal from engine magneto (clipped by I limit resistor and 3v3 zener) 00131 // Note D9 still used but taken to rpm class object 00132 //InterruptIn VEXT (D2); // PWM controller output folded back for cpu to monitor, useful on test to read what pwm required to do what 00133 // Note D2 still used but taken to field class object 00134 // OUTPUTS : 00135 AnalogOut REF_VAR (A4); // Variable REF to MCP1630 enables software control of output voltage - NEW Aug 2020 00136 AnalogOut A_OUT (A3); // Control voltage out to traction motor ESCs 00137 DigitalOut Scope_probe (D12); // Handy pin to hang scope probe onto while developing code 00138 DigitalOut myled (LED1); // Green LED on board is PB_3 D13 00139 //PwmOut PWM_OSC_IN (A2); // Can alter prescaler can not use A5 NOW DONE IN CLASS 00140 //PwmOut A_OUT (A2); // Can alter prescaler can not use A5 PIN STOLEN BY PWM_OSC_IN 00141 00142 //PwmOut Test_RPM (PA_6); 00143 Timer microsecs; // 64 bit counter, rolls over in half million years 00144 Ticker loop_timer; // Device to cause periodic interrupts, used to sync iterations of main programme loop - slow 00145 00146 extern char * get_mode_text (uint32_t mode) ; 00147 00148 DigitalOut CHARGE_PUMP (D6); 00149 I2CEeprom eeprom (SDA_PIN, SCL_PIN, 0xa0, eeprom_page_size, 8192, 100000); 00150 extern ee_settings_2020 user_settings ; 00151 Engine_Manager Engine (D9, D11, D10); // Pins are magneto in, cleaned magneto out, servo 00152 FieldControl Field (A2, D2); // PWM pin for MCP1630 PWM_OSC_IN, InterruptIn for signal out of MCP1630 VEXTFB 00153 PCT2075 temp_sensor( SDA_PIN, SCL_PIN ); // or LM75B temp_sensor( p?, p? ); Added March 2020 00154 00155 //class MPL3115A2 baro ; 00156 00157 // SYSTEM CONSTANTS 00158 /* Please Do Not Alter these */ 00159 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 00160 /* End of Please Do Not Alter these */ 00161 /* Global variable declarations */ 00162 uint32_t sys_timer100Hz = 0; // gets incremented by our Ticker ISR every MAIN_LOOP_REPEAT_TIME_US 00163 uint32_t seconds = 0; 00164 double link_volt_reading = 0.0; // Global updated by interrupt driven read of Battery Volts at rate of 100 Hz 00165 double field_volt_reading = 0.0; // Global updated by interrupt driven read of Battery Volts at rate of 100 Hz 00166 double amp_reading = 0.0; 00167 bool loop_flag = false; // made true in ISR_loop_timer, picked up and made false again in main programme loop 00168 bool flag_25Hz = false; // As loop_flag but repeats 25 times per sec 00169 bool flag_12Hz5 = false; // As loop_flag but repeats 12.5 times per sec 00170 bool flag_1Hz = false; // As loop_flag but repeats 1 times per sec 00171 bool query_toggle = false; 00172 00173 bool flag_link_V_rd = false; 00174 bool flag_field_V_rd = false; 00175 bool flag_A_rd = false; 00176 bool flag_Pot_rd = false; 00177 00178 bool auto_test_flag = false; 00179 00180 bool charge_pump_enable = true; 00181 00182 enum {SAFE_NOTHING, POT_SERVO_DIRECT, VARIABLE_VOLTAGE, FIXED_VOLTAGE, ENG_REVS_CTRL, POT_SETS_ENGINE_RPM, CURRENT_FEEDBACK_CTRL, AUTO_TEST} ; 00183 /* End of Global variable declarations */ 00184 00185 //void ISR_fast_interrupt () { // here at 10 times main loop repeat rate (i.e. 1000Hz, 1.0ms) 00186 void ISR_fast_interrupt () { 00187 static uint32_t t = 0, u25 = 0; 00188 Scope_probe = 1; // To show how much time spent in interrupt handler 00189 if (charge_pump_enable) 00190 CHARGE_PUMP = !CHARGE_PUMP; 00191 switch (t) { 00192 case 0: // Alternator output voltage 00193 flag_link_V_rd = true; 00194 break; 00195 case 1: // Ammeter 00196 flag_A_rd = true; 00197 break; 00198 case 2: // Driver's Pot 00199 flag_Pot_rd = true; 00200 break; 00201 case 3: // Field supply voltage 00202 flag_field_V_rd = true; 00203 break; 00204 // case 4: 00205 // driver_reading >>= 1; // Result = Result / 2 00206 // driver_reading += Driver_Pot.read_u16(); 00207 // break; 00208 case 5: 00209 loop_flag = true; // set flag to allow main programme loop to proceed 00210 sys_timer100Hz++; // Just a handy measure of elapsed time for anything to use 00211 if ((sys_timer100Hz & 0x03) == 0) { // is now 12.5Hz, not 8 00212 flag_25Hz = true; // flag gets set 25 times per sec. Other code may clear flag and make use of this 00213 u25++; 00214 if (u25 == 25) { 00215 u25 = 0; 00216 flag_1Hz = true; 00217 seconds++; 00218 } 00219 } 00220 default: 00221 break; 00222 } 00223 t++; 00224 if (t > 9) 00225 t = 0; 00226 Scope_probe = 0; // To show how much time spent in interrupt handler 00227 } 00228 00229 // **** End of Interrupt Service Routines **** 00230 00231 /*double Read_Ext_Rev_Req () 00232 { 00233 double rv = (double) ext_rev_req; 00234 return rv / 4096.0; 00235 }*/ 00236 /* 00237 double Read_Driver_Pot () 00238 { 00239 double rv = (double) driver_reading; 00240 return rv / 4096.0; 00241 }*/ 00242 00243 double Read_Link_Volts () 00244 { 00245 return link_volt_reading * 39.9; // divisor fiddled to make voltage reading correct ! 00246 } 00247 00248 double Read_Field_Volts () 00249 { 00250 // return field_volt_reading * 42.85; // divisor fiddled to make voltage reading correct ! 00251 return field_volt_reading * 40.12; // divisor fiddled to make voltage reading correct ! 00252 } 00253 00254 double Read_Ammeter () 00255 { 00256 return amp_reading * 93.28; // Amp range corrected here 00257 } 00258 00259 00260 void query_system (parameters & a) { 00261 query_toggle = !query_toggle; 00262 } 00263 00264 void set_v_out_opamp (double a) { // 0 to 1.0 sets opamp output in range 0 to 5v, charge pump permitting 00265 A_OUT = a; 00266 } 00267 void set_v_out_opamp (parameters & a) { // 0 to 1.0 sets opamp output in range 0 to 5v, charge pump permitting 00268 A_OUT = a.dbl[0] / 100.0; 00269 } 00270 00271 void charge_pump_override (int a) { // 0 disables, !0 enables charge pump 00272 if (a == 0) 00273 charge_pump_enable = false; 00274 else 00275 charge_pump_enable = true; 00276 } 00277 void charge_pump_override (parameters & a) { // 0 disables, !0 enables charge pump 00278 charge_pump_override ((int)a.dbl[0]); 00279 } 00280 00281 void set_pwm (double d) { // Range 0.0 to 1.0 called from cli 00282 Field.set_pwm (d); 00283 } 00284 00285 double get_temperature () { 00286 return (double) temp_sensor; 00287 } 00288 00289 void maketable () { 00290 Field.maketable (); 00291 } 00292 00293 int32_t set_engine_RPM_lit (uint32_t RPMrequest) { // Returns actual speed 00294 return Engine.set_RPM_literal (RPMrequest); 00295 } 00296 00297 int32_t set_engine_RPM_pct (uint32_t RPMrequest) { // Returns actual speed 00298 return Engine.set_RPM_percent (RPMrequest); 00299 } 00300 00301 void auto_test_initiate (int bulb_count) { 00302 if (Engine.running()) { 00303 auto_test_flag = true; 00304 pc.printf ("Requesting Auto-Test for load of %d lamps\r\n", bulb_count); 00305 } 00306 else { 00307 pc.printf ("Engine not running. Can't perform auto test\r\n"); 00308 auto_test_flag = false; 00309 } 00310 } 00311 00312 void is_eng_running () { 00313 pc.printf ("Engine%sRunning\r\n", Engine.running() ? " IS " : " NOT "); 00314 } 00315 00316 extern void command_line_interpreter () ; // Comms with optional pc or device using serial port through board USB socket 00317 00318 enum {AUTO_TEST_INACTIVE, AUTO_TEST_BEGIN, AUTO_TEST_ABORT, AUTO_TEST_IN_PROGRESS } ; 00319 00320 // Programme Entry Point 00321 int main() 00322 { 00323 const double PI = (2.0 * acos(0.0)); 00324 const double filt = 0.2; 00325 const double ampfilt = 0.2; 00326 const double vfilt = 0.2; 00327 // local variable declarations 00328 double driver_pot = 0.0, dtmp; 00329 // double theta = 0.0; 00330 int32_t temp, startup_delay, print_position = 0; 00331 int32_t field_pct = 0, auto_test_timer = 0, auto_test_state = AUTO_TEST_INACTIVE, auto_test_step = 0; 00332 bool up_and_running = false; 00333 char text[64]; 00334 00335 A_OUT = 0.0; 00336 REF_VAR = 0.0; 00337 microsecs.reset() ; // timer = 0 00338 microsecs.start () ; // 64 bit, counts micro seconds and times out in half million years 00339 00340 #ifdef GPS_ 00341 gps_mod gps; 00342 #endif 00343 //- Clear the screen, move to (0,0): 00344 // \033[2J 00345 pc.printf ("\033[2JAlternator Regulator 2020, Jon Freeman\r\n"); 00346 user_settings.load () ; // Fetch values from eeprom 00347 // Setup Complete ! Can now start main control forever loop. 00348 loop_timer.attach_us (&ISR_fast_interrupt, MAIN_LOOP_REPEAT_TIME_US / 10); // Start periodic interrupt generator 1000us at Feb 2020 00349 00350 Field.maketable () ; // Here to ensure eeprom has been setup 00351 Field.set_for_speed (0); 00352 Engine.Set_Speed_Lever (((double)user_settings.rd(WARMUP_SERVO_POS)) / 100.0); 00353 startup_delay = user_settings.rd(WARM_UP_DELAY); 00354 pc.printf ("Operating Mode is [%s]\r\n", get_mode_text (user_settings.rd(OP_MODE))); 00355 00356 00357 //***** START OF MAIN LOOP 00358 while (1) { // Loop forever, repeats synchroised by waiting for ticker Interrupt Service Routine to set 'loop_flag' true 00359 while (!loop_flag) { // Most of the time is spent in this loop, repeatedly re-checking for commands from pc port 00360 #ifdef GPS_ 00361 // while (gps_module.readable()) 00362 // pc.putc (gps_module.getc()); 00363 #endif 00364 command_line_interpreter () ; // Proceed beyond here once loop_timer ticker ISR has set loop_flag true 00365 // A to D converters all read at 100 Hz 00366 if (flag_link_V_rd) { // Reads main alternator output and/or traction battery voltage 00367 flag_link_V_rd = false; 00368 link_volt_reading *= (1.0 - vfilt); // 00369 link_volt_reading += vfilt * (double) Ain_Link_Volts.read(); // Volt fiddle factor NOT corrected here 00370 } 00371 if (flag_Pot_rd) { // Reads Driver's speed control potentiometer 00372 flag_Pot_rd = false; 00373 driver_pot *= (1.0 - filt); 00374 driver_pot += filt * ((double)Driver_Pot.read() * 1.5); // Includes bodge around zener over-clipping input 00375 } 00376 if (flag_A_rd) { // Reads ammeter - user wires this to suit their purpose 00377 flag_A_rd = false; 00378 amp_reading *= (1.0 - ampfilt); 00379 amp_reading += ampfilt * ((double) Ammeter_In.read() - 0.495); // Amp range NOT corrected here BUT OFFSET IS 00380 } 00381 if (flag_field_V_rd) { // Reads 'Field Positive' supply - from battery via diode, also alternator rectifier out 00382 flag_field_V_rd = false; 00383 field_volt_reading *= (1.0 - vfilt); // 00384 field_volt_reading += vfilt * (double) Field_Supply_V.read(); // Volt fiddle factor NOT corrected here 00385 } 00386 } // Jun 2019 pass here 100 times per sec 00387 // BEGIN 100Hz stuff 00388 loop_flag = false; // Clear flag set by ticker interrupt handler 00389 Engine.manager_core (); // This belongs right here, update regularly, keeps 'filtered()' fresh and keeps engine to set rpm 00390 #ifdef GPS_ 00391 gps.update (); 00392 #endif 00393 /* theta += 0.05; 00394 if (theta > PI) 00395 theta -= 2.0 * PI; 00396 sinout = 0.5 + sin(theta) / 2.0; 00397 cosout = 0.5 + cos(theta) / 2.0; 00398 */ 00399 // END 100Hz stuff 00400 if (flag_25Hz) { 00401 flag_25Hz = false; 00402 // BEGIN 25Hz stuff 00403 00404 // END 25Hz stuff 00405 // BEGIN 12.5Hz stuff 00406 flag_12Hz5 = !flag_12Hz5; 00407 if (flag_12Hz5) { // Do any even stuff to be done 12.5 times per second 00408 // if (up_and_running && Engine.running()) { 00409 if (up_and_running) { 00410 switch (user_settings.rd(OP_MODE)) { 00411 /* 00412 enum {SAFE_NOTHING, // 00413 POT_SERVO_DIRECT, // 00414 VARIABLE_VOLTAGE, // Batteryless, controllerless Low Cost Loco - alternator connects direct to DC motors 00415 FIXED_VOLTAGE, // 00416 ENG_REVS_CTRL, // 00417 POT_SETS_ENGINE_RPM, // 00418 CURRENT_FEEDBACK_CTRL, // 00419 AUTO_TEST }; // 00420 "0\tSafe nothing mode for cli cmd testing", 00421 "1\tPot to Servo direct, field OFF", 00422 "2\tVariable voltage", 00423 "3\tFixed voltage", 00424 "4\tEngine Revs Control", 00425 "5\tSet Engine to Driver's Pot", 00426 "6\tControl Engine by Current Load", 00427 */ 00428 case SAFE_NOTHING: // Safe nothing mode for cli cmd testing 00429 // Use this to test command line commands e.g. Set_Speed_Lever, direct field setting etc 00430 break; 00431 00432 case POT_SERVO_DIRECT: // Driver_pot --> servo direct. Field OFF 00433 // Engine.Set_Speed_Lever (driver_pot); 00434 Engine.Set_Speed_Lever (driver_pot); 00435 REF_VAR = driver_pot; 00436 // Field.set_for_speed (0); // Safe, no output 00437 Field.set_for_speed (3000); // Safe, no output 00438 break; 00439 00440 case VARIABLE_VOLTAGE: // Variable Voltage 00441 Engine.Set_Speed_Lever (driver_pot); // Driver_pot --> servo direct. Field ON 00442 if (driver_pot > DRIVER_NEUTRAL) // if pot not close to zero 00443 Field.set_for_speed (Engine.RPM_latest()); // according to RPM 00444 else 00445 Field.set_for_speed (0); // Field OFF 00446 break; 00447 00448 case FIXED_VOLTAGE: // Fixed Voltage 00449 Field.set_for_speed (Engine.RPM_latest()); // according to RPM 00450 break; 00451 00452 case ENG_REVS_CTRL: // Engine revs control - Pot to control revs over range tickover to MAX_RPM_LIMIT 00453 Field.set_for_speed (Engine.RPM_latest()); 00454 break; 00455 00456 case POT_SETS_ENGINE_RPM: // Set engine to driver pot 00457 dtmp = driver_pot * (MAX_RPM_LIMIT - TICKOVER_RPM) + TICKOVER_RPM; 00458 temp = (int32_t) dtmp; 00459 Engine.set_RPM_literal (temp); // this sets engine speed controller 00460 Field.set_for_speed (Engine.RPM_latest()); // according to RPM 00461 break; 00462 00463 // case CURRENT_MODE: // Set engine speed determined by current drawn 00464 case CURRENT_FEEDBACK_CTRL: // Set engine speed determined by current drawn 00465 temp = 0; // an integer. Engine set to tickover when no power demand 00466 if (driver_pot > DRIVER_NEUTRAL) // if pot not close to zero 00467 temp = 1 + (int32_t)abs(Read_Ammeter() * 8.0); // Sets max amps to 100 / 8.0 00468 Engine.set_RPM_percent (temp); // this sets engine speed controller 00469 Field.set_for_speed (Engine.RPM_latest()); // according to RPM 00470 break; 00471 00472 case AUTO_TEST: // cli command may initiate test sequence implemented here. Wait for flag to proceed. 00473 switch (auto_test_state) { 00474 case AUTO_TEST_INACTIVE: 00475 if (auto_test_flag) // cli has requested auto test sequence 00476 auto_test_state = AUTO_TEST_BEGIN; 00477 break; 00478 00479 case AUTO_TEST_BEGIN: // set engine, field etc, then initiate settling time delay 00480 Engine.set_RPM_percent (1); // this sets engine speed controller for min useful revs 00481 Field.set_for_speed (0); 00482 pc.printf ("Starting auto test sequence, user field limit values :\r\n"); 00483 for (int i = 0; i < 21; i++) 00484 pc.printf ("%d, ", user_settings.rd(i)); 00485 pc.printf ("\r\n"); 00486 auto_test_step = 0; 00487 auto_test_timer = 0; 00488 auto_test_state = AUTO_TEST_IN_PROGRESS; 00489 break; 00490 00491 case AUTO_TEST_IN_PROGRESS: // take sets of readings, then timeout back to INACTIVE 00492 field_pct = Field.set_for_speed (Engine.RPM_latest()); // according to RPM 00493 switch (auto_test_timer++) { // When active, get here @ 12.5Hz 00494 case 30: case 40: case 50: case 60: // take readings at these times 00495 case 35: case 45: case 55: case 65: 00496 // pc.printf ("\tTaking auto_test readings %d, Volts, Amps, RPM req, RPM got, servo position, measured duty ratio\r\n", auto_test_timer); 00497 /* 00498 Need to collect here, 00499 Volts, Amps, RPM got latest, RPM got filtered, servo position, measured duty ratio, lut pcent 00500 */ 00501 pc.printf ("\t%.2f, %.2f, %.2f, %d, %d, %.2f, %.3f, %d\r\n", Read_Link_Volts(), Read_Field_Volts(), 00502 Read_Ammeter(), Engine.RPM_latest(), Engine.RPM_filtered(), 00503 Engine.get_servo_position(), Field.get_duty_ratio(), field_pct); 00504 break; 00505 case 66: // After final set of readings 00506 auto_test_step++; 00507 if (auto_test_step > 10) 00508 auto_test_state = AUTO_TEST_ABORT; 00509 else { // set conditions for next set of readings 00510 temp = Engine.RPM_percent_to_actual(auto_test_step * 10); 00511 Engine.set_RPM_percent (auto_test_step * 10); 00512 auto_test_timer = 0; 00513 pc.printf ("Setting rig for %d percent, %d RPM\r\n", auto_test_step * 10, temp); 00514 } 00515 break; 00516 default: 00517 break; 00518 } 00519 break; 00520 00521 case AUTO_TEST_ABORT: // Here at test end or because auto_test_flag made false somewhere somehow 00522 Engine.set_RPM_percent (0); // this sets engine speed controller 00523 Field.set_for_speed (0); 00524 auto_test_state = AUTO_TEST_INACTIVE; 00525 auto_test_flag = false; 00526 pc.printf ("Ending auto test sequence\r\n"); 00527 break; 00528 default: 00529 break; 00530 } // END OF SWITCH auto_test_state 00531 break; 00532 default: 00533 user_settings.wr (0, OP_MODE); // set to safe non-mode 0 00534 break; 00535 } 00536 } 00537 else { // Engine not running 00538 Field.set_for_speed (0); // according to RPM 00539 } 00540 } 00541 else { // Do odd 12.5 times per sec stuff 00542 flag_12Hz5 = false; 00543 myled = !myled; 00544 } // End of if(flag_12Hz5) 00545 // END 12.5Hz stuff 00546 if (flag_1Hz) { 00547 // BEGIN 1Hz stuff 00548 flag_1Hz = false; 00549 if (!up_and_running) { 00550 if (startup_delay == 0) { 00551 up_and_running = true; 00552 pc.printf ("Warmup ended, starting proper ops\r\n"); 00553 Engine.Set_Speed_Lever (0.0); 00554 } 00555 else { 00556 pc.printf ("In Startup warmup delay %d\r", startup_delay--); 00557 } 00558 } 00559 if (query_toggle) { 00560 sprintf (text, "\033[%d;0HI=%.1fA, V=%.2fV, ", 20 + print_position, Read_Ammeter() , Read_Link_Volts()); 00561 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()); 00562 print_position++; 00563 if (print_position > 10) 00564 print_position = 0; 00565 } 00566 //printf("\033[6;3HHello\n"); 00567 // pc.printf ("\033[0;1HSecs %d \r\n", seconds); 00568 // pc.printf ("Temp = %.1f\r", get_temperature()); 00569 // gps.update(); 00570 #ifdef GPS_ 00571 if (gps.new_data()) { 00572 myled = !myled; 00573 pc.printf("\033[0;1H%s, %s, %s \r\n", gps.time(), gps.latitude(), gps.longitude()); 00574 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()); 00575 pc.printf("%s, heading %s, mph %s \r\n", gps.date(), gps.heading(), gps.mph()); 00576 pc.printf("%s\r\n \n .\r\n ", gps.message(1)); 00577 } 00578 #endif 00579 // while (gps_module.readable()) 00580 // pc.putc (gps_module.getc()); 00581 // END 1Hz stuff 00582 } // eo once per second stuff 00583 } // End of 100Hz stuff 00584 } // End of main programme loop 00585 } // End of main function - end of programme 00586
Generated on Fri Jul 22 2022 15:22:19 by
1.7.2