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