Test session
Dependencies: FatFileSystem MCP23017 WattBob_TextLCD mbed
Fork of Assignment_2_herpe by
main.cpp@0:aaddc17011a9, 2012-03-08 (annotated)
- Committer:
- xherpe
- Date:
- Thu Mar 08 16:32:35 2012 +0000
- Revision:
- 0:aaddc17011a9
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
xherpe | 0:aaddc17011a9 | 1 | // XAVIER HERPE Assignment 2 |
xherpe | 0:aaddc17011a9 | 2 | // 5th year Robotics & Cybertronics |
xherpe | 0:aaddc17011a9 | 3 | // Heriot-Watt University |
xherpe | 0:aaddc17011a9 | 4 | |
xherpe | 0:aaddc17011a9 | 5 | #include "mbed.h" |
xherpe | 0:aaddc17011a9 | 6 | #include "MCP23017.h" |
xherpe | 0:aaddc17011a9 | 7 | #include "WattBob_TextLCD.h" |
xherpe | 0:aaddc17011a9 | 8 | #include "SDFileSystem.h" |
xherpe | 0:aaddc17011a9 | 9 | #include "FATFileSystem.h" |
xherpe | 0:aaddc17011a9 | 10 | |
xherpe | 0:aaddc17011a9 | 11 | #define BACK_LIGHT_ON(INTERFACE) INTERFACE->write_bit(1,BL_BIT) |
xherpe | 0:aaddc17011a9 | 12 | #define BACK_LIGHT_OFF(INTERFACE) INTERFACE->write_bit(0,BL_BIT) |
xherpe | 0:aaddc17011a9 | 13 | |
xherpe | 0:aaddc17011a9 | 14 | // Pointers to LCD screen and SD card |
xherpe | 0:aaddc17011a9 | 15 | MCP23017 *par_port; // pointer to 16-bit parallel I/O chip |
xherpe | 0:aaddc17011a9 | 16 | WattBob_TextLCD *lcd; // pointer to 2*16 character LCD object |
xherpe | 0:aaddc17011a9 | 17 | FILE *fp; // Pointer to SD card object |
xherpe | 0:aaddc17011a9 | 18 | |
xherpe | 0:aaddc17011a9 | 19 | |
xherpe | 0:aaddc17011a9 | 20 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 21 | // I/O ports allocation |
xherpe | 0:aaddc17011a9 | 22 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 23 | DigitalIn TTL(p17); // TTL input for frequency measurement |
xherpe | 0:aaddc17011a9 | 24 | DigitalIn switch_1(p18); // Switch 1 input |
xherpe | 0:aaddc17011a9 | 25 | DigitalIn switch_2(p19); // Switch 2 input |
xherpe | 0:aaddc17011a9 | 26 | DigitalIn switch_off(p11); // Switch used to close SD file and stop cyclic executive |
xherpe | 0:aaddc17011a9 | 27 | AnalogIn analogue_in_1(p15); // POT value |
xherpe | 0:aaddc17011a9 | 28 | AnalogIn analogue_in_2(p16); // LDR value |
xherpe | 0:aaddc17011a9 | 29 | PwmOut servo(p21); // Servo output |
xherpe | 0:aaddc17011a9 | 30 | DigitalOut TestPin(p20); // Pin only used to test program and measure time |
xherpe | 0:aaddc17011a9 | 31 | SDFileSystem sd(p5, p6, p7, p8, "sd"); // The pinout on the mbed Cool Components workshop board |
xherpe | 0:aaddc17011a9 | 32 | |
xherpe | 0:aaddc17011a9 | 33 | |
xherpe | 0:aaddc17011a9 | 34 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 35 | // Internal objects declaration |
xherpe | 0:aaddc17011a9 | 36 | // ==================================================================================== |
xherpe | 0:aaddc17011a9 | 37 | BusOut LEDs(LED4, LED3, LED2, LED1); // Address the four LEDs to a single bus |
xherpe | 0:aaddc17011a9 | 38 | Timer timer; // Timer used to measure frequency in task 1 |
xherpe | 0:aaddc17011a9 | 39 | Timer DoNothing; // Timer used to measure how long the program does nothing |
xherpe | 0:aaddc17011a9 | 40 | Ticker ticker; // Ticker used as clock for cyclic executive program |
xherpe | 0:aaddc17011a9 | 41 | |
xherpe | 0:aaddc17011a9 | 42 | |
xherpe | 0:aaddc17011a9 | 43 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 44 | // Constants declaration |
xherpe | 0:aaddc17011a9 | 45 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 46 | const int SampFreq = 100; // Sampling frequency is 10kHz (100us) |
xherpe | 0:aaddc17011a9 | 47 | |
xherpe | 0:aaddc17011a9 | 48 | |
xherpe | 0:aaddc17011a9 | 49 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 50 | // Variables declaration |
xherpe | 0:aaddc17011a9 | 51 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 52 | |
xherpe | 0:aaddc17011a9 | 53 | // Variables for cyclic executive program |
xherpe | 0:aaddc17011a9 | 54 | long int ticks = 0; // Used to define what task to call in the cyclic executive program |
xherpe | 0:aaddc17011a9 | 55 | int NoTask = 0; // Used to return how long the program does nothing in ms |
xherpe | 0:aaddc17011a9 | 56 | int NoTaskCount = 0; // Variable incremented until one total cycle of 10 seconds is reached |
xherpe | 0:aaddc17011a9 | 57 | |
xherpe | 0:aaddc17011a9 | 58 | // Variables for tasks 1 and 2 |
xherpe | 0:aaddc17011a9 | 59 | int period = 0; // Returned period of the TTL input signal |
xherpe | 0:aaddc17011a9 | 60 | int frequency = 0; // Returned frequency of the TTL signal |
xherpe | 0:aaddc17011a9 | 61 | |
xherpe | 0:aaddc17011a9 | 62 | // Varibles for task 4 |
xherpe | 0:aaddc17011a9 | 63 | int switch_1_val = 0; // Used to return how many times the switch is high |
xherpe | 0:aaddc17011a9 | 64 | int switch_2_val = 0; |
xherpe | 0:aaddc17011a9 | 65 | bool switch_1_state = 0; // Used to define whether the debounced switch is ON or OFF |
xherpe | 0:aaddc17011a9 | 66 | bool switch_2_state = 0; |
xherpe | 0:aaddc17011a9 | 67 | |
xherpe | 0:aaddc17011a9 | 68 | // Variables for task 5 |
xherpe | 0:aaddc17011a9 | 69 | float analogue_1_val = 0; // Used to return the filtered analogue input |
xherpe | 0:aaddc17011a9 | 70 | float analogue_2_val = 0; |
xherpe | 0:aaddc17011a9 | 71 | |
xherpe | 0:aaddc17011a9 | 72 | int analogue_1_int = 0; // Used to convert float to int (results in quicker display on LCD in task 6) |
xherpe | 0:aaddc17011a9 | 73 | int analogue_2_int = 0; |
xherpe | 0:aaddc17011a9 | 74 | |
xherpe | 0:aaddc17011a9 | 75 | // Variable for task 7 |
xherpe | 0:aaddc17011a9 | 76 | int LogCount = 0; // Used to define logging number |
xherpe | 0:aaddc17011a9 | 77 | |
xherpe | 0:aaddc17011a9 | 78 | // Variable used for task 8 |
xherpe | 0:aaddc17011a9 | 79 | int BinCount = 0; // Used to increment a binary display on LEDs. Goes from 0 to 15 and then is reset |
xherpe | 0:aaddc17011a9 | 80 | bool BinEnable = 0; // Used to tell task 5 to display binary pattern on LEDs every 1.5s |
xherpe | 0:aaddc17011a9 | 81 | int IncCheck = 0; // Check increment to see if 6 cycles have elapsed to light LEDs ( 6 * 250us = 1.5s) |
xherpe | 0:aaddc17011a9 | 82 | |
xherpe | 0:aaddc17011a9 | 83 | |
xherpe | 0:aaddc17011a9 | 84 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 85 | // Task declaration |
xherpe | 0:aaddc17011a9 | 86 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 87 | |
xherpe | 0:aaddc17011a9 | 88 | void CyclEx(); |
xherpe | 0:aaddc17011a9 | 89 | |
xherpe | 0:aaddc17011a9 | 90 | void Task1(); // Measure TTL input frequency |
xherpe | 0:aaddc17011a9 | 91 | void Task2(); // Show frequency on LCD screen |
xherpe | 0:aaddc17011a9 | 92 | void Task3(); // Show speed on servo dial |
xherpe | 0:aaddc17011a9 | 93 | void Task4(); // Read and debounce two digital inputs |
xherpe | 0:aaddc17011a9 | 94 | void Task5(); // Read and filter two analogue inputs |
xherpe | 0:aaddc17011a9 | 95 | void Task6(); // Display digital and analogue inputs on LCD screen |
xherpe | 0:aaddc17011a9 | 96 | void Task7(); // Log speed, analogue and digital inputs on SD card |
xherpe | 0:aaddc17011a9 | 97 | void Task8(); // Display error message on LCD screen and display binary pattern on LEDs |
xherpe | 0:aaddc17011a9 | 98 | |
xherpe | 0:aaddc17011a9 | 99 | void WaitRisEdge(); // Subroutine to detect rising edge |
xherpe | 0:aaddc17011a9 | 100 | void WaitFalEdge(); // Subroutine to detect falling edge |
xherpe | 0:aaddc17011a9 | 101 | |
xherpe | 0:aaddc17011a9 | 102 | void Stop(); // Close log file and stop cyclic executive |
xherpe | 0:aaddc17011a9 | 103 | |
xherpe | 0:aaddc17011a9 | 104 | |
xherpe | 0:aaddc17011a9 | 105 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 106 | // Main program |
xherpe | 0:aaddc17011a9 | 107 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 108 | |
xherpe | 0:aaddc17011a9 | 109 | int main() |
xherpe | 0:aaddc17011a9 | 110 | { |
xherpe | 0:aaddc17011a9 | 111 | |
xherpe | 0:aaddc17011a9 | 112 | // LCD Screen Initialisation |
xherpe | 0:aaddc17011a9 | 113 | par_port = new MCP23017(p9, p10, 0x40); // initialise 16-bit I/O chip |
xherpe | 0:aaddc17011a9 | 114 | lcd = new WattBob_TextLCD(par_port); // initialise 2*26 char display |
xherpe | 0:aaddc17011a9 | 115 | par_port->write_bit(1,BL_BIT); // turn LCD backlight ON |
xherpe | 0:aaddc17011a9 | 116 | lcd->cls(); // clear display |
xherpe | 0:aaddc17011a9 | 117 | |
xherpe | 0:aaddc17011a9 | 118 | // EXEL log file initialisation |
xherpe | 0:aaddc17011a9 | 119 | fp = fopen("/sd/log.xls", "w"); // pointer to log in text file called "log". (Use "a" to not delete file) |
xherpe | 0:aaddc17011a9 | 120 | fprintf(fp, "This file is the property of Xavier Herpe, the French\n\n"); |
xherpe | 0:aaddc17011a9 | 121 | |
xherpe | 0:aaddc17011a9 | 122 | // DoNothing timer reset |
xherpe | 0:aaddc17011a9 | 123 | DoNothing.reset(); |
xherpe | 0:aaddc17011a9 | 124 | |
xherpe | 0:aaddc17011a9 | 125 | // Internal ticker set to 25ms. Every 25ms, the scheduler is called and selects the task to run |
xherpe | 0:aaddc17011a9 | 126 | ticker.attach(&CyclEx, 0.025); // Period set to 25ms |
xherpe | 0:aaddc17011a9 | 127 | while(1)// Run until system shuts down |
xherpe | 0:aaddc17011a9 | 128 | { |
xherpe | 0:aaddc17011a9 | 129 | |
xherpe | 0:aaddc17011a9 | 130 | } |
xherpe | 0:aaddc17011a9 | 131 | } |
xherpe | 0:aaddc17011a9 | 132 | |
xherpe | 0:aaddc17011a9 | 133 | // Where tasks are scheduled based on an EXEL sheet |
xherpe | 0:aaddc17011a9 | 134 | void CyclEx() |
xherpe | 0:aaddc17011a9 | 135 | { |
xherpe | 0:aaddc17011a9 | 136 | // Stop timer when a new task starts |
xherpe | 0:aaddc17011a9 | 137 | DoNothing.stop(); |
xherpe | 0:aaddc17011a9 | 138 | |
xherpe | 0:aaddc17011a9 | 139 | if(ticks % 80 == 4) // Occures every 80 clock cycles (2 seconds). Starts with an offset of 4 clock cycles |
xherpe | 0:aaddc17011a9 | 140 | { |
xherpe | 0:aaddc17011a9 | 141 | Task1(); |
xherpe | 0:aaddc17011a9 | 142 | } |
xherpe | 0:aaddc17011a9 | 143 | |
xherpe | 0:aaddc17011a9 | 144 | else if(ticks % 200 == 8) // Occures every 200 clock cycles (5 seconds). Starts with an offset of 8 clock cycles |
xherpe | 0:aaddc17011a9 | 145 | { |
xherpe | 0:aaddc17011a9 | 146 | Task2(); |
xherpe | 0:aaddc17011a9 | 147 | } |
xherpe | 0:aaddc17011a9 | 148 | else if(ticks % 240 == 7) // Occures every 240 clock cycles (6 seconds). Starts with an offset of 7 clock cycles |
xherpe | 0:aaddc17011a9 | 149 | { |
xherpe | 0:aaddc17011a9 | 150 | Task3(); |
xherpe | 0:aaddc17011a9 | 151 | } |
xherpe | 0:aaddc17011a9 | 152 | else if(ticks % 4 == 0) // Occures every 4 clock cycles (0.1 seconds). Starts with an offset of 0 clock cycles |
xherpe | 0:aaddc17011a9 | 153 | { |
xherpe | 0:aaddc17011a9 | 154 | Task4(); |
xherpe | 0:aaddc17011a9 | 155 | } |
xherpe | 0:aaddc17011a9 | 156 | else if(ticks % 10 == 1) // Occures every 10 clock cycles (0.25 seconds). Starts with an offset of 1 clock cycles |
xherpe | 0:aaddc17011a9 | 157 | { |
xherpe | 0:aaddc17011a9 | 158 | Task5(); |
xherpe | 0:aaddc17011a9 | 159 | } |
xherpe | 0:aaddc17011a9 | 160 | else if(ticks % 40 == 3) // Occures every 40 clock cycles (1 seconds). Starts with an offset of 3 clock cycles |
xherpe | 0:aaddc17011a9 | 161 | { |
xherpe | 0:aaddc17011a9 | 162 | Task6(); |
xherpe | 0:aaddc17011a9 | 163 | } |
xherpe | 0:aaddc17011a9 | 164 | else if(ticks % 400 == 10) // Occures every 400 clock cycles (10 seconds). Starts with an offset of 10 clock cycles |
xherpe | 0:aaddc17011a9 | 165 | { |
xherpe | 0:aaddc17011a9 | 166 | Task7(); |
xherpe | 0:aaddc17011a9 | 167 | } |
xherpe | 0:aaddc17011a9 | 168 | else if(ticks % 160 == 6) // Occures every 160 clock cycles (4 seconds). Starts with an offset of 6 clock cycles |
xherpe | 0:aaddc17011a9 | 169 | { |
xherpe | 0:aaddc17011a9 | 170 | Task8(); |
xherpe | 0:aaddc17011a9 | 171 | } |
xherpe | 0:aaddc17011a9 | 172 | |
xherpe | 0:aaddc17011a9 | 173 | if (switch_off == 1) // Pin used to log data on SD card and stop Cyclic executive program |
xherpe | 0:aaddc17011a9 | 174 | { |
xherpe | 0:aaddc17011a9 | 175 | Stop(); |
xherpe | 0:aaddc17011a9 | 176 | } |
xherpe | 0:aaddc17011a9 | 177 | ticks++; |
xherpe | 0:aaddc17011a9 | 178 | |
xherpe | 0:aaddc17011a9 | 179 | // Start timer when one task is ended |
xherpe | 0:aaddc17011a9 | 180 | DoNothing.start(); |
xherpe | 0:aaddc17011a9 | 181 | NoTaskCount++; |
xherpe | 0:aaddc17011a9 | 182 | |
xherpe | 0:aaddc17011a9 | 183 | // When one full cycle of 10 seconds is finished, return how long the program was doing nothing (lazy program) |
xherpe | 0:aaddc17011a9 | 184 | if (NoTaskCount == 400) |
xherpe | 0:aaddc17011a9 | 185 | { |
xherpe | 0:aaddc17011a9 | 186 | NoTask = DoNothing.read_ms(); |
xherpe | 0:aaddc17011a9 | 187 | NoTaskCount = 0; |
xherpe | 0:aaddc17011a9 | 188 | DoNothing.reset(); |
xherpe | 0:aaddc17011a9 | 189 | } |
xherpe | 0:aaddc17011a9 | 190 | } |
xherpe | 0:aaddc17011a9 | 191 | |
xherpe | 0:aaddc17011a9 | 192 | |
xherpe | 0:aaddc17011a9 | 193 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 194 | // Tasks |
xherpe | 0:aaddc17011a9 | 195 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 196 | |
xherpe | 0:aaddc17011a9 | 197 | // Task 1: Measure TTL input frequency |
xherpe | 0:aaddc17011a9 | 198 | void Task1() |
xherpe | 0:aaddc17011a9 | 199 | { |
xherpe | 0:aaddc17011a9 | 200 | timer.reset(); |
xherpe | 0:aaddc17011a9 | 201 | |
xherpe | 0:aaddc17011a9 | 202 | // If the input signal is low, wait for a rising edge to start counting |
xherpe | 0:aaddc17011a9 | 203 | if (TTL == 0) |
xherpe | 0:aaddc17011a9 | 204 | { |
xherpe | 0:aaddc17011a9 | 205 | WaitRisEdge(); // Call subroutine to wait for rising edge |
xherpe | 0:aaddc17011a9 | 206 | timer.start(); // Start timer |
xherpe | 0:aaddc17011a9 | 207 | while(TTL == 1) // Keep counting as long as signal is high |
xherpe | 0:aaddc17011a9 | 208 | { |
xherpe | 0:aaddc17011a9 | 209 | wait_us(SampFreq); |
xherpe | 0:aaddc17011a9 | 210 | } |
xherpe | 0:aaddc17011a9 | 211 | } |
xherpe | 0:aaddc17011a9 | 212 | |
xherpe | 0:aaddc17011a9 | 213 | // If the input signal is high, wait for a falling edge to start counting |
xherpe | 0:aaddc17011a9 | 214 | else if (TTL == 1) |
xherpe | 0:aaddc17011a9 | 215 | { |
xherpe | 0:aaddc17011a9 | 216 | WaitFalEdge(); // Call subroutine to wait for falling edge |
xherpe | 0:aaddc17011a9 | 217 | timer.start(); // Start timer |
xherpe | 0:aaddc17011a9 | 218 | while(TTL == 0) // Keep counting as long as signal is high |
xherpe | 0:aaddc17011a9 | 219 | { |
xherpe | 0:aaddc17011a9 | 220 | wait_us(SampFreq); |
xherpe | 0:aaddc17011a9 | 221 | } |
xherpe | 0:aaddc17011a9 | 222 | } |
xherpe | 0:aaddc17011a9 | 223 | |
xherpe | 0:aaddc17011a9 | 224 | timer.stop(); // Stop counting when signal changes |
xherpe | 0:aaddc17011a9 | 225 | period = timer.read_us()*2; // Convert the time into a period |
xherpe | 0:aaddc17011a9 | 226 | frequency = 1000000/period; // Convert the period into a frequency |
xherpe | 0:aaddc17011a9 | 227 | } |
xherpe | 0:aaddc17011a9 | 228 | |
xherpe | 0:aaddc17011a9 | 229 | |
xherpe | 0:aaddc17011a9 | 230 | |
xherpe | 0:aaddc17011a9 | 231 | // Task 2: display the measured frequency on LCD screen |
xherpe | 0:aaddc17011a9 | 232 | void Task2() |
xherpe | 0:aaddc17011a9 | 233 | { |
xherpe | 0:aaddc17011a9 | 234 | lcd->cls(); // clear display |
xherpe | 0:aaddc17011a9 | 235 | lcd->locate(0,0); // set cursor to location (0,0) - top left corner |
xherpe | 0:aaddc17011a9 | 236 | lcd->printf("%d Hz",frequency); // print the frequency calculated in task 1 |
xherpe | 0:aaddc17011a9 | 237 | } |
xherpe | 0:aaddc17011a9 | 238 | |
xherpe | 0:aaddc17011a9 | 239 | |
xherpe | 0:aaddc17011a9 | 240 | |
xherpe | 0:aaddc17011a9 | 241 | // Task 3: show speed on servo output dial |
xherpe | 0:aaddc17011a9 | 242 | void Task3() |
xherpe | 0:aaddc17011a9 | 243 | { |
xherpe | 0:aaddc17011a9 | 244 | servo.period(0.02); // servo requires a 20ms period |
xherpe | 0:aaddc17011a9 | 245 | // To rotate the servo from -90 to +90 degrees, the pulse width must varies between 600us to 2300us |
xherpe | 0:aaddc17011a9 | 246 | // The pulse width is calculated from the speed measured in task one |
xherpe | 0:aaddc17011a9 | 247 | // 50Hz is equivalent to -90 degrees and 100Hz is equivalent to 90 degrees |
xherpe | 0:aaddc17011a9 | 248 | // 1Hz change is equal to 34us pulse width change, so pulse width = ((frequency - 50)*34) + 600 |
xherpe | 0:aaddc17011a9 | 249 | servo.pulsewidth_us(2300-((frequency - 50)*34)); |
xherpe | 0:aaddc17011a9 | 250 | wait_ms(1); // Leave the servo some time to reach its position |
xherpe | 0:aaddc17011a9 | 251 | } |
xherpe | 0:aaddc17011a9 | 252 | |
xherpe | 0:aaddc17011a9 | 253 | |
xherpe | 0:aaddc17011a9 | 254 | |
xherpe | 0:aaddc17011a9 | 255 | // Task 4: Read two digital inputs (debounced) |
xherpe | 0:aaddc17011a9 | 256 | void Task4() |
xherpe | 0:aaddc17011a9 | 257 | { |
xherpe | 0:aaddc17011a9 | 258 | switch_1_val = 0; |
xherpe | 0:aaddc17011a9 | 259 | switch_2_val = 0; |
xherpe | 0:aaddc17011a9 | 260 | |
xherpe | 0:aaddc17011a9 | 261 | // Read each switch three consecutive times with 100us between readings |
xherpe | 0:aaddc17011a9 | 262 | for(int i=0; i<3; i++) |
xherpe | 0:aaddc17011a9 | 263 | { |
xherpe | 0:aaddc17011a9 | 264 | if (switch_1 == 1) // Increment variable if switch 1 is pressed |
xherpe | 0:aaddc17011a9 | 265 | { |
xherpe | 0:aaddc17011a9 | 266 | switch_1_val++; |
xherpe | 0:aaddc17011a9 | 267 | } |
xherpe | 0:aaddc17011a9 | 268 | |
xherpe | 0:aaddc17011a9 | 269 | if (switch_2 == 1) // Increment variable if switch 2 is pressed |
xherpe | 0:aaddc17011a9 | 270 | { |
xherpe | 0:aaddc17011a9 | 271 | switch_2_val++; |
xherpe | 0:aaddc17011a9 | 272 | } |
xherpe | 0:aaddc17011a9 | 273 | |
xherpe | 0:aaddc17011a9 | 274 | wait_us(SampFreq); |
xherpe | 0:aaddc17011a9 | 275 | } |
xherpe | 0:aaddc17011a9 | 276 | // Check how many times switch 1 has been high |
xherpe | 0:aaddc17011a9 | 277 | // if it has been high more than twice, then switch 1 state = 1 |
xherpe | 0:aaddc17011a9 | 278 | if (switch_1_val > 1) |
xherpe | 0:aaddc17011a9 | 279 | { |
xherpe | 0:aaddc17011a9 | 280 | switch_1_state = 1; |
xherpe | 0:aaddc17011a9 | 281 | } |
xherpe | 0:aaddc17011a9 | 282 | else |
xherpe | 0:aaddc17011a9 | 283 | { |
xherpe | 0:aaddc17011a9 | 284 | switch_1_state = 0; |
xherpe | 0:aaddc17011a9 | 285 | } |
xherpe | 0:aaddc17011a9 | 286 | |
xherpe | 0:aaddc17011a9 | 287 | // Check how many times switch 1 has been high |
xherpe | 0:aaddc17011a9 | 288 | // if it has been high more than twice, then switch 2 state = 1 |
xherpe | 0:aaddc17011a9 | 289 | if (switch_2_val > 1) |
xherpe | 0:aaddc17011a9 | 290 | { |
xherpe | 0:aaddc17011a9 | 291 | switch_2_state = 1; |
xherpe | 0:aaddc17011a9 | 292 | } |
xherpe | 0:aaddc17011a9 | 293 | |
xherpe | 0:aaddc17011a9 | 294 | else |
xherpe | 0:aaddc17011a9 | 295 | { |
xherpe | 0:aaddc17011a9 | 296 | switch_2_state = 0; |
xherpe | 0:aaddc17011a9 | 297 | } |
xherpe | 0:aaddc17011a9 | 298 | } |
xherpe | 0:aaddc17011a9 | 299 | |
xherpe | 0:aaddc17011a9 | 300 | |
xherpe | 0:aaddc17011a9 | 301 | |
xherpe | 0:aaddc17011a9 | 302 | // Task 5: Read two analogue inputs (filtered) |
xherpe | 0:aaddc17011a9 | 303 | void Task5() |
xherpe | 0:aaddc17011a9 | 304 | { |
xherpe | 0:aaddc17011a9 | 305 | analogue_1_val = 0; // Reset variables |
xherpe | 0:aaddc17011a9 | 306 | analogue_2_val = 0; |
xherpe | 0:aaddc17011a9 | 307 | |
xherpe | 0:aaddc17011a9 | 308 | // Takes four readings of each analogue input. Readings occure every 0.1ms |
xherpe | 0:aaddc17011a9 | 309 | // Because the analogue.read() function returns a value from 0 to 1, |
xherpe | 0:aaddc17011a9 | 310 | // we need to multiply the readings by 3.3 to cover 0V to 3.3V |
xherpe | 0:aaddc17011a9 | 311 | for(int i=0; i<4;i++) |
xherpe | 0:aaddc17011a9 | 312 | { |
xherpe | 0:aaddc17011a9 | 313 | analogue_1_val = analogue_1_val + (analogue_in_1*3.3); |
xherpe | 0:aaddc17011a9 | 314 | analogue_2_val = analogue_2_val + (analogue_in_2*3.3); |
xherpe | 0:aaddc17011a9 | 315 | wait_us(SampFreq); |
xherpe | 0:aaddc17011a9 | 316 | } |
xherpe | 0:aaddc17011a9 | 317 | |
xherpe | 0:aaddc17011a9 | 318 | analogue_1_val = (analogue_1_val / 4); |
xherpe | 0:aaddc17011a9 | 319 | analogue_2_val = (analogue_2_val / 4); |
xherpe | 0:aaddc17011a9 | 320 | |
xherpe | 0:aaddc17011a9 | 321 | analogue_1_int = analogue_1_val * 10; // Convert floating point into an integer to reduce display delay |
xherpe | 0:aaddc17011a9 | 322 | analogue_2_int = analogue_2_val * 10; |
xherpe | 0:aaddc17011a9 | 323 | |
xherpe | 0:aaddc17011a9 | 324 | // This section of task 5 is used to take over part of task 8. |
xherpe | 0:aaddc17011a9 | 325 | // Since the LEDs pattern has to be incremented every 1.5s, the pattern is |
xherpe | 0:aaddc17011a9 | 326 | // incremented every 6 cycles, which correspond to 1.5s. |
xherpe | 0:aaddc17011a9 | 327 | if(BinEnable == 1) |
xherpe | 0:aaddc17011a9 | 328 | { |
xherpe | 0:aaddc17011a9 | 329 | IncCheck++; |
xherpe | 0:aaddc17011a9 | 330 | |
xherpe | 0:aaddc17011a9 | 331 | if(IncCheck == 6) // Corresponds to 1.5s. Increment binary pattern |
xherpe | 0:aaddc17011a9 | 332 | { |
xherpe | 0:aaddc17011a9 | 333 | LEDs = BinCount; |
xherpe | 0:aaddc17011a9 | 334 | BinCount++; |
xherpe | 0:aaddc17011a9 | 335 | IncCheck = 0; |
xherpe | 0:aaddc17011a9 | 336 | |
xherpe | 0:aaddc17011a9 | 337 | if (BinCount > 15) // Used to reset variable once maximum 4-bit binary value is reached |
xherpe | 0:aaddc17011a9 | 338 | { |
xherpe | 0:aaddc17011a9 | 339 | BinCount = 0; |
xherpe | 0:aaddc17011a9 | 340 | } |
xherpe | 0:aaddc17011a9 | 341 | } |
xherpe | 0:aaddc17011a9 | 342 | } |
xherpe | 0:aaddc17011a9 | 343 | } |
xherpe | 0:aaddc17011a9 | 344 | |
xherpe | 0:aaddc17011a9 | 345 | |
xherpe | 0:aaddc17011a9 | 346 | |
xherpe | 0:aaddc17011a9 | 347 | // Task 6: Display analogue and digital values on LCD screen |
xherpe | 0:aaddc17011a9 | 348 | void Task6() |
xherpe | 0:aaddc17011a9 | 349 | { |
xherpe | 0:aaddc17011a9 | 350 | // lcd->cls(); // clear display (takes too long) |
xherpe | 0:aaddc17011a9 | 351 | lcd->locate(0,0); // set cursor to location (0,0) - top left corner |
xherpe | 0:aaddc17011a9 | 352 | lcd->printf("%d %d%d%d",analogue_1_int,analogue_2_int,switch_1_state,switch_2_state); |
xherpe | 0:aaddc17011a9 | 353 | } |
xherpe | 0:aaddc17011a9 | 354 | |
xherpe | 0:aaddc17011a9 | 355 | |
xherpe | 0:aaddc17011a9 | 356 | |
xherpe | 0:aaddc17011a9 | 357 | // Task 7: Log values on SD card |
xherpe | 0:aaddc17011a9 | 358 | void Task7() |
xherpe | 0:aaddc17011a9 | 359 | { |
xherpe | 0:aaddc17011a9 | 360 | LogCount++; //Used to print the logging number in file. Starts from 1 |
xherpe | 0:aaddc17011a9 | 361 | fprintf(fp, "Log: %d, Speed: %dHz, Switch_1: %d, Switch_2: %d, POT: %.2fVolts, LDR: %.2fVolts\n",LogCount,frequency,switch_1_state,switch_2_state,analogue_1_val,analogue_2_val); |
xherpe | 0:aaddc17011a9 | 362 | } |
xherpe | 0:aaddc17011a9 | 363 | |
xherpe | 0:aaddc17011a9 | 364 | |
xherpe | 0:aaddc17011a9 | 365 | |
xherpe | 0:aaddc17011a9 | 366 | // Task 8: Show error message and light LEDs |
xherpe | 0:aaddc17011a9 | 367 | void Task8() |
xherpe | 0:aaddc17011a9 | 368 | { |
xherpe | 0:aaddc17011a9 | 369 | // If switch_1 = 1 and POT value > 3V, display error message |
xherpe | 0:aaddc17011a9 | 370 | if(switch_1_state == 1 && analogue_1_val > 3) |
xherpe | 0:aaddc17011a9 | 371 | { |
xherpe | 0:aaddc17011a9 | 372 | //lcd->cls(); // clear display |
xherpe | 0:aaddc17011a9 | 373 | lcd->locate(0,0); // set cursor to location (0,0) - top left corner |
xherpe | 0:aaddc17011a9 | 374 | lcd->printf(".ERREUR"); |
xherpe | 0:aaddc17011a9 | 375 | } |
xherpe | 0:aaddc17011a9 | 376 | |
xherpe | 0:aaddc17011a9 | 377 | // If switch 2 is high, return a command to task 5 to do the incrementing pattern every 1.5 seconds |
xherpe | 0:aaddc17011a9 | 378 | if(switch_2_state == 1) |
xherpe | 0:aaddc17011a9 | 379 | { |
xherpe | 0:aaddc17011a9 | 380 | BinEnable = 1; |
xherpe | 0:aaddc17011a9 | 381 | } |
xherpe | 0:aaddc17011a9 | 382 | |
xherpe | 0:aaddc17011a9 | 383 | // If switch 2 is low, stop sending a command to task 5 and light off LEDs |
xherpe | 0:aaddc17011a9 | 384 | else |
xherpe | 0:aaddc17011a9 | 385 | { |
xherpe | 0:aaddc17011a9 | 386 | LEDs = 0; |
xherpe | 0:aaddc17011a9 | 387 | BinEnable = 0; |
xherpe | 0:aaddc17011a9 | 388 | BinCount = 0; |
xherpe | 0:aaddc17011a9 | 389 | } |
xherpe | 0:aaddc17011a9 | 390 | } |
xherpe | 0:aaddc17011a9 | 391 | |
xherpe | 0:aaddc17011a9 | 392 | |
xherpe | 0:aaddc17011a9 | 393 | |
xherpe | 0:aaddc17011a9 | 394 | // Stop function to stop cyclic executive and close log file |
xherpe | 0:aaddc17011a9 | 395 | void Stop() |
xherpe | 0:aaddc17011a9 | 396 | { |
xherpe | 0:aaddc17011a9 | 397 | ticker.detach(); |
xherpe | 0:aaddc17011a9 | 398 | fprintf(fp, "\n The program did nothing for %d ms, which corresponds to %d percent of the time \n",NoTask, NoTask/100); |
xherpe | 0:aaddc17011a9 | 399 | fprintf(fp, "\n PROGRAM STOPPED"); |
xherpe | 0:aaddc17011a9 | 400 | fclose(fp); |
xherpe | 0:aaddc17011a9 | 401 | |
xherpe | 0:aaddc17011a9 | 402 | } |
xherpe | 0:aaddc17011a9 | 403 | |
xherpe | 0:aaddc17011a9 | 404 | |
xherpe | 0:aaddc17011a9 | 405 | |
xherpe | 0:aaddc17011a9 | 406 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 407 | // Subroutines |
xherpe | 0:aaddc17011a9 | 408 | //===================================================================================== |
xherpe | 0:aaddc17011a9 | 409 | |
xherpe | 0:aaddc17011a9 | 410 | // Wait for rising edge |
xherpe | 0:aaddc17011a9 | 411 | void WaitRisEdge() |
xherpe | 0:aaddc17011a9 | 412 | { |
xherpe | 0:aaddc17011a9 | 413 | // As soon as it gets high, the subroutine will end and the timer will start |
xherpe | 0:aaddc17011a9 | 414 | while(TTL == 0) |
xherpe | 0:aaddc17011a9 | 415 | { |
xherpe | 0:aaddc17011a9 | 416 | wait_us(SampFreq); |
xherpe | 0:aaddc17011a9 | 417 | } |
xherpe | 0:aaddc17011a9 | 418 | } |
xherpe | 0:aaddc17011a9 | 419 | |
xherpe | 0:aaddc17011a9 | 420 | |
xherpe | 0:aaddc17011a9 | 421 | // Wait for falling edge |
xherpe | 0:aaddc17011a9 | 422 | void WaitFalEdge() |
xherpe | 0:aaddc17011a9 | 423 | { |
xherpe | 0:aaddc17011a9 | 424 | // As soon as it gets low, the subroutine will end and the timer will start |
xherpe | 0:aaddc17011a9 | 425 | while(TTL == 1) |
xherpe | 0:aaddc17011a9 | 426 | { |
xherpe | 0:aaddc17011a9 | 427 | wait_us(SampFreq); |
xherpe | 0:aaddc17011a9 | 428 | } |
xherpe | 0:aaddc17011a9 | 429 | } |