
Engine Variable Advance Timing successfull code implementation
main.cpp@3:c89c3fa9395f, 2021-01-15 (annotated)
- Committer:
- kwstasfane1
- Date:
- Fri Jan 15 11:28:10 2021 +0000
- Revision:
- 3:c89c3fa9395f
- Parent:
- 2:9ff654aaf923
Last (to be submitted)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kwstasfane1 | 2:9ff654aaf923 | 1 | /* Konstantinos Fane |
kwstasfane1 | 2:9ff654aaf923 | 2 | * kf289@kent.ac.uk |
kwstasfane1 | 2:9ff654aaf923 | 3 | * ID: 20901830 |
kwstasfane1 | 2:9ff654aaf923 | 4 | */ |
kwstasfane1 | 0:1fe3a53ac109 | 5 | |
kwstasfane1 | 0:1fe3a53ac109 | 6 | /* timing.cpp api verion 1.01 */ |
kwstasfane1 | 0:1fe3a53ac109 | 7 | /* wajw 21/03/18 */ |
kwstasfane1 | 0:1fe3a53ac109 | 8 | //V 1.02 mod to just do period measurement edh 24/03/18 |
kwstasfane1 | 0:1fe3a53ac109 | 9 | /* Prog to measure period of rotation of flywheel */ |
kwstasfane1 | 0:1fe3a53ac109 | 10 | |
kwstasfane1 | 0:1fe3a53ac109 | 11 | /* Software uses Pin 9 as an interrupt to determine rotation period */ |
kwstasfane1 | 0:1fe3a53ac109 | 12 | /* A ticker is used to give a count of elapsed time */ |
kwstasfane1 | 0:1fe3a53ac109 | 13 | |
kwstasfane1 | 0:1fe3a53ac109 | 14 | /* Interrupt occurs on +ve edge of TDC Pulse on pin10 */ |
kwstasfane1 | 0:1fe3a53ac109 | 15 | /* ISR Stores ticker count value as 'period', resets 'count' and sets flag */ |
kwstasfane1 | 0:1fe3a53ac109 | 16 | |
kwstasfane1 | 0:1fe3a53ac109 | 17 | #include "mbed.h" |
kwstasfane1 | 0:1fe3a53ac109 | 18 | #include "C12832_lcd.h" |
kwstasfane1 | 0:1fe3a53ac109 | 19 | #define counts_per_min 600000 // .1ms clock = 600k pulses minute |
kwstasfane1 | 0:1fe3a53ac109 | 20 | |
kwstasfane1 | 2:9ff654aaf923 | 21 | // Advance degree and RPM data arrays: |
kwstasfane1 | 0:1fe3a53ac109 | 22 | |
kwstasfane1 | 2:9ff654aaf923 | 23 | // advance angles in degrees BTDC |
kwstasfane1 | 2:9ff654aaf923 | 24 | static int map[] = {5,5,6,10,15,15,21,25,27,34,38}; |
kwstasfane1 | 2:9ff654aaf923 | 25 | // rpm range for which the advance angle should change |
kwstasfane1 | 2:9ff654aaf923 | 26 | static int rpm_range[] = {500,600,700,800,900,1000,1100,1200,1300,1400,1500}; |
kwstasfane1 | 0:1fe3a53ac109 | 27 | |
kwstasfane1 | 2:9ff654aaf923 | 28 | // Global Variables: |
kwstasfane1 | 0:1fe3a53ac109 | 29 | |
kwstasfane1 | 2:9ff654aaf923 | 30 | volatile int period = 0, count1 = 0; |
kwstasfane1 | 0:1fe3a53ac109 | 31 | volatile int pflag = 0, rpm = 0; |
kwstasfane1 | 0:1fe3a53ac109 | 32 | |
kwstasfane1 | 2:9ff654aaf923 | 33 | // Student added global variables: |
kwstasfane1 | 2:9ff654aaf923 | 34 | |
kwstasfane1 | 2:9ff654aaf923 | 35 | int lag; // to be used to calculate the ignition lag |
kwstasfane1 | 2:9ff654aaf923 | 36 | int spark_advance; // to be used for the advance degree input |
kwstasfane1 | 0:1fe3a53ac109 | 37 | |
kwstasfane1 | 0:1fe3a53ac109 | 38 | C12832_LCD lcd; |
kwstasfane1 | 0:1fe3a53ac109 | 39 | |
kwstasfane1 | 0:1fe3a53ac109 | 40 | // Function Prototypes: |
kwstasfane1 | 0:1fe3a53ac109 | 41 | |
kwstasfane1 | 2:9ff654aaf923 | 42 | void Tick1_isr (void); // ISR for Ticker interrupt |
kwstasfane1 | 2:9ff654aaf923 | 43 | void TDC_isr (void); // ISR for rising edge of TDC interrupt |
kwstasfane1 | 2:9ff654aaf923 | 44 | void Spark_on (void); // set the output Spark (p10) high |
kwstasfane1 | 2:9ff654aaf923 | 45 | void Spark_off (void); // set it low |
kwstasfane1 | 2:9ff654aaf923 | 46 | void Ignition(int); |
kwstasfane1 | 0:1fe3a53ac109 | 47 | |
kwstasfane1 | 2:9ff654aaf923 | 48 | // Custom function prototypes: |
kwstasfane1 | 2:9ff654aaf923 | 49 | |
kwstasfane1 | 0:1fe3a53ac109 | 50 | void advance_calculator(int); |
kwstasfane1 | 0:1fe3a53ac109 | 51 | |
kwstasfane1 | 0:1fe3a53ac109 | 52 | |
kwstasfane1 | 0:1fe3a53ac109 | 53 | // Hardware Definitions: |
kwstasfane1 | 0:1fe3a53ac109 | 54 | |
kwstasfane1 | 2:9ff654aaf923 | 55 | Ticker Tick; // Tick produces a periodic interrupt |
kwstasfane1 | 2:9ff654aaf923 | 56 | DigitalOut Spark(p10); // Spark Output to Flywheel Board |
kwstasfane1 | 2:9ff654aaf923 | 57 | InterruptIn tdc(p9); // Pulse from TDC Sensor on Flywheel Board |
kwstasfane1 | 0:1fe3a53ac109 | 58 | |
kwstasfane1 | 2:9ff654aaf923 | 59 | Timeout StartSpark; // one-off interrupt to set spark o/p high |
kwstasfane1 | 2:9ff654aaf923 | 60 | Timeout EndSpark; // and this one sets spark low |
kwstasfane1 | 0:1fe3a53ac109 | 61 | |
kwstasfane1 | 2:9ff654aaf923 | 62 | // Function Declarations: |
kwstasfane1 | 2:9ff654aaf923 | 63 | |
kwstasfane1 | 2:9ff654aaf923 | 64 | // triggers ignition spark based on the current advance angle provided |
kwstasfane1 | 0:1fe3a53ac109 | 65 | void Ignition(int lag) |
kwstasfane1 | 0:1fe3a53ac109 | 66 | { |
kwstasfane1 | 2:9ff654aaf923 | 67 | StartSpark.attach_us(&Spark_on, lag) ; // set time of Spark |
kwstasfane1 | 2:9ff654aaf923 | 68 | EndSpark.attach_us(&Spark_off, lag + 200); // set spark duration at 200usec |
kwstasfane1 | 0:1fe3a53ac109 | 69 | } |
kwstasfane1 | 0:1fe3a53ac109 | 70 | |
kwstasfane1 | 0:1fe3a53ac109 | 71 | void Spark_on() |
kwstasfane1 | 0:1fe3a53ac109 | 72 | { |
kwstasfane1 | 0:1fe3a53ac109 | 73 | Spark = 1; |
kwstasfane1 | 0:1fe3a53ac109 | 74 | } |
kwstasfane1 | 0:1fe3a53ac109 | 75 | |
kwstasfane1 | 0:1fe3a53ac109 | 76 | void Spark_off() |
kwstasfane1 | 0:1fe3a53ac109 | 77 | { |
kwstasfane1 | 0:1fe3a53ac109 | 78 | Spark = 0; |
kwstasfane1 | 0:1fe3a53ac109 | 79 | } |
kwstasfane1 | 0:1fe3a53ac109 | 80 | |
kwstasfane1 | 2:9ff654aaf923 | 81 | /* Interrupt cause by Ticker |
kwstasfane1 | 2:9ff654aaf923 | 82 | * Increments count every 100usec |
kwstasfane1 | 2:9ff654aaf923 | 83 | */ |
kwstasfane1 | 0:1fe3a53ac109 | 84 | void Tick1_isr() |
kwstasfane1 | 0:1fe3a53ac109 | 85 | { |
kwstasfane1 | 0:1fe3a53ac109 | 86 | count1++; |
kwstasfane1 | 0:1fe3a53ac109 | 87 | } |
kwstasfane1 | 0:1fe3a53ac109 | 88 | |
kwstasfane1 | 2:9ff654aaf923 | 89 | /* Interrupt caused by +ve edge on TDC |
kwstasfane1 | 2:9ff654aaf923 | 90 | * Captured value = period |
kwstasfane1 | 2:9ff654aaf923 | 91 | */ |
kwstasfane1 | 0:1fe3a53ac109 | 92 | void TDC_isr() |
kwstasfane1 | 0:1fe3a53ac109 | 93 | { |
kwstasfane1 | 2:9ff654aaf923 | 94 | period = count1; // Capture time since last TDC |
kwstasfane1 | 0:1fe3a53ac109 | 95 | count1 = 0; |
kwstasfane1 | 2:9ff654aaf923 | 96 | pflag = 1; // New value of period available |
kwstasfane1 | 0:1fe3a53ac109 | 97 | } |
kwstasfane1 | 0:1fe3a53ac109 | 98 | |
kwstasfane1 | 2:9ff654aaf923 | 99 | //Custom functions declaration: |
kwstasfane1 | 2:9ff654aaf923 | 100 | |
kwstasfane1 | 2:9ff654aaf923 | 101 | /* calculates the advance angle */ |
kwstasfane1 | 0:1fe3a53ac109 | 102 | void advance_calculator(int rpm) |
kwstasfane1 | 0:1fe3a53ac109 | 103 | { |
kwstasfane1 | 0:1fe3a53ac109 | 104 | if(rpm < rpm_range[0]) |
kwstasfane1 | 0:1fe3a53ac109 | 105 | { |
kwstasfane1 | 2:9ff654aaf923 | 106 | // advance angle for any speeds lower than 500 RPM |
kwstasfane1 | 0:1fe3a53ac109 | 107 | spark_advance = 360 - map[0]; |
kwstasfane1 | 0:1fe3a53ac109 | 108 | } |
kwstasfane1 | 0:1fe3a53ac109 | 109 | else if(rpm >= rpm_range[0] && rpm < rpm_range[1]) |
kwstasfane1 | 0:1fe3a53ac109 | 110 | { |
kwstasfane1 | 0:1fe3a53ac109 | 111 | spark_advance = 360 - map[0]; |
kwstasfane1 | 0:1fe3a53ac109 | 112 | } |
kwstasfane1 | 0:1fe3a53ac109 | 113 | else if(rpm >= rpm_range[1] && rpm < rpm_range[2]) |
kwstasfane1 | 0:1fe3a53ac109 | 114 | { |
kwstasfane1 | 0:1fe3a53ac109 | 115 | spark_advance = 360 - map[1]; |
kwstasfane1 | 0:1fe3a53ac109 | 116 | } |
kwstasfane1 | 0:1fe3a53ac109 | 117 | else if(rpm >= rpm_range[2] && rpm < rpm_range[3]) |
kwstasfane1 | 0:1fe3a53ac109 | 118 | { |
kwstasfane1 | 0:1fe3a53ac109 | 119 | spark_advance = 360 - map[2]; |
kwstasfane1 | 0:1fe3a53ac109 | 120 | } |
kwstasfane1 | 0:1fe3a53ac109 | 121 | else if(rpm >= rpm_range[3] && rpm < rpm_range[4]) |
kwstasfane1 | 0:1fe3a53ac109 | 122 | { |
kwstasfane1 | 0:1fe3a53ac109 | 123 | spark_advance = 360 - map[3]; |
kwstasfane1 | 0:1fe3a53ac109 | 124 | } |
kwstasfane1 | 0:1fe3a53ac109 | 125 | else if(rpm >= rpm_range[4] && rpm < rpm_range[5]) |
kwstasfane1 | 0:1fe3a53ac109 | 126 | { |
kwstasfane1 | 0:1fe3a53ac109 | 127 | spark_advance = 360 - map[4]; |
kwstasfane1 | 0:1fe3a53ac109 | 128 | } |
kwstasfane1 | 0:1fe3a53ac109 | 129 | else if(rpm >= rpm_range[5] && rpm < rpm_range[6]) |
kwstasfane1 | 0:1fe3a53ac109 | 130 | { |
kwstasfane1 | 0:1fe3a53ac109 | 131 | spark_advance = 360 - map[5]; |
kwstasfane1 | 0:1fe3a53ac109 | 132 | } |
kwstasfane1 | 0:1fe3a53ac109 | 133 | else if(rpm >= rpm_range[6] && rpm < rpm_range[7]) |
kwstasfane1 | 0:1fe3a53ac109 | 134 | { |
kwstasfane1 | 0:1fe3a53ac109 | 135 | spark_advance = 360 - map[6]; |
kwstasfane1 | 0:1fe3a53ac109 | 136 | } |
kwstasfane1 | 0:1fe3a53ac109 | 137 | else if(rpm >= rpm_range[7] && rpm < rpm_range[8]) |
kwstasfane1 | 0:1fe3a53ac109 | 138 | { |
kwstasfane1 | 0:1fe3a53ac109 | 139 | spark_advance = 360 - map[7]; |
kwstasfane1 | 0:1fe3a53ac109 | 140 | } |
kwstasfane1 | 0:1fe3a53ac109 | 141 | else if(rpm >= rpm_range[8] && rpm < rpm_range[9]) |
kwstasfane1 | 0:1fe3a53ac109 | 142 | { |
kwstasfane1 | 0:1fe3a53ac109 | 143 | spark_advance = 360 - map[8]; |
kwstasfane1 | 0:1fe3a53ac109 | 144 | } |
kwstasfane1 | 0:1fe3a53ac109 | 145 | else if(rpm >= rpm_range[9] && rpm < rpm_range[10]) |
kwstasfane1 | 0:1fe3a53ac109 | 146 | { |
kwstasfane1 | 0:1fe3a53ac109 | 147 | spark_advance = 360 - map[9]; |
kwstasfane1 | 0:1fe3a53ac109 | 148 | } |
kwstasfane1 | 2:9ff654aaf923 | 149 | else |
kwstasfane1 | 0:1fe3a53ac109 | 150 | { |
kwstasfane1 | 2:9ff654aaf923 | 151 | // advance angle for speeds higher than 1500RPM(same angle as 1500RPM) |
kwstasfane1 | 0:1fe3a53ac109 | 152 | spark_advance = 360 - map[10]; |
kwstasfane1 | 0:1fe3a53ac109 | 153 | } |
kwstasfane1 | 0:1fe3a53ac109 | 154 | } |
kwstasfane1 | 0:1fe3a53ac109 | 155 | |
kwstasfane1 | 0:1fe3a53ac109 | 156 | |
kwstasfane1 | 0:1fe3a53ac109 | 157 | int main() |
kwstasfane1 | 0:1fe3a53ac109 | 158 | { |
kwstasfane1 | 0:1fe3a53ac109 | 159 | |
kwstasfane1 | 2:9ff654aaf923 | 160 | /* Produce regular clock tick for timing period: |
kwstasfane1 | 2:9ff654aaf923 | 161 | * initializes the ticker with period of 100usec |
kwstasfane1 | 2:9ff654aaf923 | 162 | * and attaches it to Tick1 ISR |
kwstasfane1 | 2:9ff654aaf923 | 163 | */ |
kwstasfane1 | 2:9ff654aaf923 | 164 | Tick.attach_us(&Tick1_isr, 100); |
kwstasfane1 | 0:1fe3a53ac109 | 165 | |
kwstasfane1 | 2:9ff654aaf923 | 166 | tdc.rise(&TDC_isr); // Generate Interrupt on each TDC pulse |
kwstasfane1 | 2:9ff654aaf923 | 167 | |
kwstasfane1 | 2:9ff654aaf923 | 168 | while(1) |
kwstasfane1 | 2:9ff654aaf923 | 169 | { |
kwstasfane1 | 0:1fe3a53ac109 | 170 | |
kwstasfane1 | 2:9ff654aaf923 | 171 | // spark advance calculation = TDC point(360) - desired advance angle |
kwstasfane1 | 2:9ff654aaf923 | 172 | //spark_advance = 360 - 15; |
kwstasfane1 | 2:9ff654aaf923 | 173 | |
kwstasfane1 | 2:9ff654aaf923 | 174 | // function to calculate the spark advance for variating RPM speeds |
kwstasfane1 | 3:c89c3fa9395f | 175 | // on every itteration |
kwstasfane1 | 0:1fe3a53ac109 | 176 | advance_calculator(rpm); |
kwstasfane1 | 0:1fe3a53ac109 | 177 | |
kwstasfane1 | 2:9ff654aaf923 | 178 | // checks if new timing data is available |
kwstasfane1 | 2:9ff654aaf923 | 179 | if (pflag == 1) |
kwstasfane1 | 2:9ff654aaf923 | 180 | { |
kwstasfane1 | 2:9ff654aaf923 | 181 | //lag = (period*100)*180/360; // Period in units of 100usec |
kwstasfane1 | 2:9ff654aaf923 | 182 | lag = (period*100)*spark_advance/360; // Period in units of 100usec |
kwstasfane1 | 2:9ff654aaf923 | 183 | Ignition(lag); //triggers ignition spark for given advance angle |
kwstasfane1 | 0:1fe3a53ac109 | 184 | |
kwstasfane1 | 2:9ff654aaf923 | 185 | /* RPM calculation command |
kwstasfane1 | 2:9ff654aaf923 | 186 | * RPM = f(Hz) * 60 = (1/T() * 60 |
kwstasfane1 | 2:9ff654aaf923 | 187 | * 1 period = 1*100us(period counter incrments every 100us, |
kwstasfane1 | 2:9ff654aaf923 | 188 | * this conversion is needed to get the Hz frequency |
kwstasfane1 | 2:9ff654aaf923 | 189 | */ |
kwstasfane1 | 2:9ff654aaf923 | 190 | rpm = (1/(period*100e-6))*60; |
kwstasfane1 | 0:1fe3a53ac109 | 191 | |
kwstasfane1 | 2:9ff654aaf923 | 192 | /* "lcd.cls();" was moved inside the while() |
kwstasfane1 | 2:9ff654aaf923 | 193 | * to fix a bug in the display, by refreshing |
kwstasfane1 | 2:9ff654aaf923 | 194 | * the screen at every itteration |
kwstasfane1 | 2:9ff654aaf923 | 195 | */ |
kwstasfane1 | 2:9ff654aaf923 | 196 | lcd.cls(); |
kwstasfane1 | 2:9ff654aaf923 | 197 | |
kwstasfane1 | 2:9ff654aaf923 | 198 | // divided by 10 to display captured period same as the osciloscope |
kwstasfane1 | 0:1fe3a53ac109 | 199 | lcd.locate(0,0); |
kwstasfane1 | 2:9ff654aaf923 | 200 | lcd.printf("Period(T): %4.2d ms", period/10); |
kwstasfane1 | 2:9ff654aaf923 | 201 | |
kwstasfane1 | 2:9ff654aaf923 | 202 | // display the captured RPM |
kwstasfane1 | 0:1fe3a53ac109 | 203 | lcd.locate(0,11); |
kwstasfane1 | 2:9ff654aaf923 | 204 | lcd.printf("Speed(RPM): %4.2d ", rpm); |
kwstasfane1 | 0:1fe3a53ac109 | 205 | |
kwstasfane1 | 2:9ff654aaf923 | 206 | // display the advance angle for troubleshooting purposes |
kwstasfane1 | 2:9ff654aaf923 | 207 | // 360 - spark advance = advance angle in BTDC (reverse operation) |
kwstasfane1 | 0:1fe3a53ac109 | 208 | lcd.locate(0,22); |
kwstasfane1 | 2:9ff654aaf923 | 209 | lcd.printf("Advance(deg): %4.2d ", 360-spark_advance); |
kwstasfane1 | 0:1fe3a53ac109 | 210 | pflag = 0; //reset flag |
kwstasfane1 | 0:1fe3a53ac109 | 211 | } |
kwstasfane1 | 2:9ff654aaf923 | 212 | |
kwstasfane1 | 0:1fe3a53ac109 | 213 | } |
kwstasfane1 | 0:1fe3a53ac109 | 214 | } |
kwstasfane1 | 0:1fe3a53ac109 | 215 |