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