Copy_Assignment3

Dependencies:   mbed MCP23017 WattBob_TextLCD mbed-rtos

Committer:
aoc2
Date:
Wed Mar 28 18:53:05 2018 +0000
Revision:
1:d980a57e422a
Parent:
0:8940db3353d7
Publish

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aoc2 0:8940db3353d7 1 /*******************************************************************************
aoc2 0:8940db3353d7 2
aoc2 0:8940db3353d7 3 filename :: main.cpp
aoc2 0:8940db3353d7 4 ======================
aoc2 0:8940db3353d7 5
aoc2 0:8940db3353d7 6 Description
aoc2 0:8940db3353d7 7 Assignment 3 of the B31DG Embedded Software Course.
aoc2 0:8940db3353d7 8 It consists in writing a simple microcontroller based on the MBED RTOS
aoc2 0:8940db3353d7 9 library for the LPC1768 board. The repetitive tasks have been implemented
aoc2 0:8940db3353d7 10 by using RTOS Timers, 4 to be specific. One for the car simulator, one
aoc2 0:8940db3353d7 11 launching tasks whose frequency is either 5 Hz or 10 Hz, one launching
aoc2 0:8940db3353d7 12 tasks whose frequency is either 2 Hz, 1 Hz or 0.5 Hz and the last one
aoc2 0:8940db3353d7 13 is launching tasks running at a frequency of 0.2 Hz and 0.5Hz.
aoc2 0:8940db3353d7 14
aoc2 0:8940db3353d7 15 Version
aoc2 0:8940db3353d7 16 Antoine V1.3 February 2018
aoc2 0:8940db3353d7 17
aoc2 0:8940db3353d7 18 History
aoc2 0:8940db3353d7 19 v1.2 Wrote documentation
aoc2 0:8940db3353d7 20 v1.1 Added timers calling tasks multiple of their execution frequency
aoc2 0:8940db3353d7 21 v1.0 First Complete Version (all tasks done and 11 Timers)
aoc2 0:8940db3353d7 22 ...
aoc2 0:8940db3353d7 23 v0.2 Build main structure of program
aoc2 0:8940db3353d7 24 v0.1 Initial Version
aoc2 0:8940db3353d7 25 ........................................................................
aoc2 0:8940db3353d7 26
aoc2 0:8940db3353d7 27 Detailed Description
aoc2 0:8940db3353d7 28 11 tasks were to be performed:
aoc2 0:8940db3353d7 29 - SIMULATOR - 20 Hz
aoc2 0:8940db3353d7 30 Write a simple car simulator which will compute the car speed based
aoc2 0:8940db3353d7 31 on the values of the accelerator (%), the brake (%) and the state
aoc2 0:8940db3353d7 32 of the engine.
aoc2 0:8940db3353d7 33 - TASK 1 - 10 Hz
aoc2 0:8940db3353d7 34 Read the value of 2 analog inputs which correspond to the values of
aoc2 0:8940db3353d7 35 acceleration and brake.
aoc2 0:8940db3353d7 36 - TASK 2 - 2 Hz
aoc2 0:8940db3353d7 37 Read a digital input switch corresponding to the state of the engine
aoc2 0:8940db3353d7 38 - TASK 3 - 5 Hz
aoc2 0:8940db3353d7 39 Filter the speed with an averaging filter.
aoc2 0:8940db3353d7 40 - TASK 4 - 2 Hz
aoc2 0:8940db3353d7 41 Show the use of a brake with a digital output
aoc2 0:8940db3353d7 42 - TASK 5 - 1 Hz
aoc2 0:8940db3353d7 43 Monitor the speed, and if it goes above a given threshold, switch on
aoc2 0:8940db3353d7 44 a digital output
aoc2 0:8940db3353d7 45 - TASK 6 - 2 Hz
aoc2 0:8940db3353d7 46 Display on the screen travelled distance & the last average speed
aoc2 0:8940db3353d7 47 - TASK 7 - 0.2 Hz
aoc2 0:8940db3353d7 48 Send into a MAIL queue object the values of speed, accelerometer and
aoc2 0:8940db3353d7 49 brake. The queue has a size of 100.
aoc2 0:8940db3353d7 50 - TASK 8 - 0.05 Hz
aoc2 0:8940db3353d7 51 Dump the the content of the queue into the serial port.
aoc2 0:8940db3353d7 52 - TASK 9 - 1 Hz
aoc2 0:8940db3353d7 53 Read a digital switch and set a digital output based on its state
aoc2 0:8940db3353d7 54 - TASK 10 - 0.5 Hz
aoc2 0:8940db3353d7 55 Read two switches and set two LEDs according to their state. They
aoc2 0:8940db3353d7 56 blink at 1 Hz if only one of the switch is on, at 2 Hz is they
aoc2 0:8940db3353d7 57 are both on.
aoc2 0:8940db3353d7 58
aoc2 0:8940db3353d7 59 .........................................................................
aoc2 0:8940db3353d7 60
aoc2 0:8940db3353d7 61 Personnal Values None
aoc2 0:8940db3353d7 62 ..............................
aoc2 0:8940db3353d7 63
aoc2 0:8940db3353d7 64 Method
aoc2 0:8940db3353d7 65 I decided not to use global variables between the different functions called
aoc2 0:8940db3353d7 66 by the RTOS timer as a challenge and because it is not safe to use global
aoc2 0:8940db3353d7 67 variables in most of the case because you lose control on the origin of
aoc2 0:8940db3353d7 68 a modification on them.
aoc2 0:8940db3353d7 69 Hence, I declared a structure which is used by the different tasks and
aoc2 0:8940db3353d7 70 contains pointers to every variables, structures or object needed.
aoc2 0:8940db3353d7 71 To make it work, I had to slightly modify the RTOSTimer library and remove
aoc2 0:8940db3353d7 72 the 'const' keyword protecting the given pointer to function calls.
aoc2 0:8940db3353d7 73
aoc2 0:8940db3353d7 74 The functions used by for the different task execution are located in the
aoc2 0:8940db3353d7 75 included files "my_tasks" while "my_tools" contains functions called by the
aoc2 0:8940db3353d7 76 tasks in order to simplify their code.
aoc2 0:8940db3353d7 77
aoc2 0:8940db3353d7 78 The header "my_stucture" contains 3 small structures:
aoc2 0:8940db3353d7 79 - engineRAWValues which stores the RAW values of the car
aoc2 0:8940db3353d7 80 - carStatistics which stores values about speed and distance
aoc2 0:8940db3353d7 81 - mailStruct which is the structure required by the mail Queue object
aoc2 0:8940db3353d7 82
aoc2 0:8940db3353d7 83 ..........................................................................
aoc2 0:8940db3353d7 84
aoc2 0:8940db3353d7 85
aoc2 0:8940db3353d7 86
aoc2 0:8940db3353d7 87 *******************************************************************************/
aoc2 0:8940db3353d7 88
aoc2 0:8940db3353d7 89
aoc2 0:8940db3353d7 90 #include "mbed.h"
aoc2 0:8940db3353d7 91 #include "rtos.h"
aoc2 0:8940db3353d7 92 #include "my_tools.h"
aoc2 0:8940db3353d7 93 #include "my_structures.h"
aoc2 0:8940db3353d7 94 #include "my_tasks.h"
aoc2 0:8940db3353d7 95
aoc2 0:8940db3353d7 96 #define BACK_LIGHT_ON(INTERFACE) INTERFACE->write_bit(ON,BL_BIT)
aoc2 0:8940db3353d7 97 #define BACK_LIGHT_OFF(INTERFACE) INTERFACE->write_bit(OFF,BL_BIT)
aoc2 0:8940db3353d7 98
aoc2 0:8940db3353d7 99 /*******************************************************************************
aoc2 0:8940db3353d7 100 * PIN DECLARATION
aoc2 0:8940db3353d7 101 ******************************************************************************/
aoc2 0:8940db3353d7 102 #define ANALOG_INPUT_1 p20
aoc2 0:8940db3353d7 103 #define ANALOG_INPUT_2 p18
aoc2 0:8940db3353d7 104
aoc2 0:8940db3353d7 105 #define DIGITAL_IN_ENGINE p15
aoc2 0:8940db3353d7 106 #define DIGITAL_IN_SIDE p16
aoc2 0:8940db3353d7 107 #define DIGITAL_IN_LEFT p11
aoc2 0:8940db3353d7 108 #define DIGITAL_IN_RIGHT p14
aoc2 0:8940db3353d7 109
aoc2 0:8940db3353d7 110 #define DIGITAL_OUT_OVERSPEED p26
aoc2 0:8940db3353d7 111 #define DIGITAL_OUT_BRAKE p25
aoc2 0:8940db3353d7 112
aoc2 0:8940db3353d7 113 using namespace std;
aoc2 0:8940db3353d7 114
aoc2 0:8940db3353d7 115 // ===============
aoc2 0:8940db3353d7 116 // System Inputs
aoc2 0:8940db3353d7 117 // ===============
aoc2 0:8940db3353d7 118 AnalogIn ACCELERATOR(ANALOG_INPUT_1);
aoc2 0:8940db3353d7 119 AnalogIn BRAKE(ANALOG_INPUT_2);
aoc2 0:8940db3353d7 120 DigitalIn ENGINE_SWITCH(DIGITAL_IN_ENGINE);
aoc2 0:8940db3353d7 121 DigitalIn SIDE_LIGHT_SWITCH(DIGITAL_IN_SIDE);
aoc2 0:8940db3353d7 122 DigitalIn LEFT_SWITCH(DIGITAL_IN_LEFT);
aoc2 0:8940db3353d7 123 DigitalIn RIGHT_SWITCH(DIGITAL_IN_RIGHT);
aoc2 0:8940db3353d7 124
aoc2 0:8940db3353d7 125 // ================
aoc2 0:8940db3353d7 126 // System Outputs
aoc2 0:8940db3353d7 127 // ================
aoc2 0:8940db3353d7 128 DigitalOut SIDE_LIGHT_INDICATOR(LED1);
aoc2 0:8940db3353d7 129 PwmOut LEFT_LIGHT(LED2);
aoc2 0:8940db3353d7 130 PwmOut RIGHT_LIGHT(LED3);
aoc2 0:8940db3353d7 131 DigitalOut ENGINE_LIGHT(LED4);
aoc2 0:8940db3353d7 132 DigitalOut OVERSPEED_LIGHT(DIGITAL_OUT_OVERSPEED);
aoc2 0:8940db3353d7 133 DigitalOut BRAKE_LIGHT(DIGITAL_OUT_BRAKE);
aoc2 0:8940db3353d7 134
aoc2 0:8940db3353d7 135 /*******************************************************************************
aoc2 0:8940db3353d7 136 * FUNCTION PROTOTYPES
aoc2 0:8940db3353d7 137 ******************************************************************************/
aoc2 0:8940db3353d7 138
aoc2 0:8940db3353d7 139 /** Initialize the main structure used in the program
aoc2 0:8940db3353d7 140 *
aoc2 0:8940db3353d7 141 * @param: Set a arguments used to initalize the structure, all pointers
aoc2 0:8940db3353d7 142 */
aoc2 0:8940db3353d7 143 void initializeStructure(carStructure &car,
aoc2 0:8940db3353d7 144 engineRAWValues *rawValues,
aoc2 0:8940db3353d7 145 carStatistics *carStat,
aoc2 0:8940db3353d7 146 Mail<mailStruct,100> *mailQueue,
aoc2 0:8940db3353d7 147 Mutex *rawMutex,
aoc2 0:8940db3353d7 148 Mutex *speedMutex,
aoc2 0:8940db3353d7 149 Mutex *mailMutex,
aoc2 0:8940db3353d7 150 MCP23017 *par_port,
aoc2 0:8940db3353d7 151 WattBob_TextLCD *lcd,
aoc2 0:8940db3353d7 152 Serial *pcSerial
aoc2 0:8940db3353d7 153 );
aoc2 0:8940db3353d7 154
aoc2 0:8940db3353d7 155 /*******************************************************************************
aoc2 0:8940db3353d7 156 * MAIN FUNCTION
aoc2 0:8940db3353d7 157 ******************************************************************************/
aoc2 0:8940db3353d7 158 int main()
aoc2 0:8940db3353d7 159 {
aoc2 0:8940db3353d7 160 /****************************
aoc2 0:8940db3353d7 161 * MAIN SETUP
aoc2 0:8940db3353d7 162 ****************************/
aoc2 0:8940db3353d7 163 // ---------------------------------------------------------------------- //
aoc2 0:8940db3353d7 164 // Screen Variables
aoc2 0:8940db3353d7 165 MCP23017 *par_port;
aoc2 0:8940db3353d7 166 WattBob_TextLCD *lcd;
aoc2 0:8940db3353d7 167 par_port = new MCP23017(p9, p10, 0x40); // initialise 16-bit I/O chip
aoc2 0:8940db3353d7 168 lcd = new WattBob_TextLCD(par_port); // initialise 2*26 char display
aoc2 0:8940db3353d7 169
aoc2 0:8940db3353d7 170 // Turn LCD backlight ON
aoc2 0:8940db3353d7 171 par_port->write_bit(ON,BL_BIT);
aoc2 0:8940db3353d7 172
aoc2 0:8940db3353d7 173 // Init Message on Screen
aoc2 0:8940db3353d7 174 lcd->cls();
aoc2 0:8940db3353d7 175 lcd->locate(0,0);
aoc2 0:8940db3353d7 176 lcd->printf("Init...");
aoc2 0:8940db3353d7 177 wait(0.5);
aoc2 0:8940db3353d7 178
aoc2 0:8940db3353d7 179
aoc2 0:8940db3353d7 180 // ---------------------------------------------------------------------- //
aoc2 0:8940db3353d7 181 // USB Connection to PC
aoc2 0:8940db3353d7 182 Serial PCSerial(USBTX,USBRX);
aoc2 0:8940db3353d7 183 // Increase Baud Rate of Serial Connection
aoc2 0:8940db3353d7 184 PCSerial.baud(115200);
aoc2 0:8940db3353d7 185
aoc2 0:8940db3353d7 186 /****************************
aoc2 0:8940db3353d7 187 * DECLARE STRUCTURES
aoc2 0:8940db3353d7 188 ****************************/
aoc2 0:8940db3353d7 189 // ---------------------------------------------------------------------- //
aoc2 0:8940db3353d7 190 // ENGINE RAW VALUES
aoc2 0:8940db3353d7 191 Mutex rawMutex;
aoc2 0:8940db3353d7 192 engineRAWValues rawValues;
aoc2 0:8940db3353d7 193 initRAWValuesStruct(rawValues);
aoc2 0:8940db3353d7 194 // ---------------------------------------------------------------------- //
aoc2 0:8940db3353d7 195 // CAR STATISTICS VALUES
aoc2 0:8940db3353d7 196 vector<float> speedVec(SIZE_SPEED_VECTOR);
aoc2 0:8940db3353d7 197 Mutex speedMutex;
aoc2 0:8940db3353d7 198 carStatistics carStats;
aoc2 0:8940db3353d7 199 initCarStatisticsStruct(carStats, &speedVec);
aoc2 0:8940db3353d7 200
aoc2 0:8940db3353d7 201 // ---------------------------------------------------------------------- //
aoc2 0:8940db3353d7 202 // MAIL QUEUE STRUCTURE
aoc2 0:8940db3353d7 203 Mail<mailStruct,100> mailQueue;
aoc2 0:8940db3353d7 204 Mutex mailMutex;
aoc2 0:8940db3353d7 205
aoc2 0:8940db3353d7 206 // ---------------------------------------------------------------------- //
aoc2 0:8940db3353d7 207 // Declare structure to be used by the different task functions
aoc2 0:8940db3353d7 208 carStructure myCar;
aoc2 0:8940db3353d7 209 initializeStructure(myCar,
aoc2 0:8940db3353d7 210 &rawValues, &carStats,
aoc2 0:8940db3353d7 211 &mailQueue,
aoc2 0:8940db3353d7 212 &rawMutex, &speedMutex, &mailMutex,
aoc2 0:8940db3353d7 213 par_port, lcd,
aoc2 0:8940db3353d7 214 &PCSerial
aoc2 0:8940db3353d7 215 );
aoc2 0:8940db3353d7 216
aoc2 0:8940db3353d7 217 // ---------------------------------------------------------------------- //
aoc2 0:8940db3353d7 218 // ---------------------------------------------------------------------- //
aoc2 0:8940db3353d7 219 /****************************
aoc2 0:8940db3353d7 220 * DECLARE RTOS TIMER
aoc2 0:8940db3353d7 221 ****************************/
aoc2 0:8940db3353d7 222 RtosTimer carSimulator(task0_carSim, osTimerPeriodic, (void *) &myCar);
aoc2 0:8940db3353d7 223 RtosTimer timer_1(timer1, osTimerPeriodic, (void *) &myCar);
aoc2 0:8940db3353d7 224 RtosTimer timer_2(timer2, osTimerPeriodic, (void *) &myCar);
aoc2 0:8940db3353d7 225 RtosTimer timer_3(timer3, osTimerPeriodic, (void *) &myCar);
aoc2 0:8940db3353d7 226
aoc2 0:8940db3353d7 227
aoc2 0:8940db3353d7 228 /****************************
aoc2 0:8940db3353d7 229 * START RTOS TIMER
aoc2 0:8940db3353d7 230 ****************************/
aoc2 0:8940db3353d7 231 carSimulator.start(50); // 20Hz
aoc2 0:8940db3353d7 232 timer_1.start(100); // 10 Hz
aoc2 0:8940db3353d7 233 timer_2.start(500); // 2 Hz
aoc2 0:8940db3353d7 234 timer_3.start(5000); // 0.2 Hz
aoc2 0:8940db3353d7 235
aoc2 0:8940db3353d7 236 // RtosTimer will run forever
aoc2 0:8940db3353d7 237 Thread::wait(osWaitForever);
aoc2 0:8940db3353d7 238
aoc2 0:8940db3353d7 239 return 0;
aoc2 0:8940db3353d7 240 }
aoc2 0:8940db3353d7 241
aoc2 0:8940db3353d7 242
aoc2 0:8940db3353d7 243 void initializeStructure(carStructure &car,
aoc2 0:8940db3353d7 244 engineRAWValues *rawValues,
aoc2 0:8940db3353d7 245 carStatistics *carStat,
aoc2 0:8940db3353d7 246 Mail<mailStruct,100> *mailQueue,
aoc2 0:8940db3353d7 247 Mutex *rawMutex,
aoc2 0:8940db3353d7 248 Mutex *speedMutex,
aoc2 0:8940db3353d7 249 Mutex *mailMutex,
aoc2 0:8940db3353d7 250 MCP23017 *par_port,
aoc2 0:8940db3353d7 251 WattBob_TextLCD *lcd,
aoc2 0:8940db3353d7 252 Serial *pcSerial
aoc2 0:8940db3353d7 253 )
aoc2 0:8940db3353d7 254 {
aoc2 0:8940db3353d7 255 // System Inputs
aoc2 0:8940db3353d7 256 car.p_accelerator = &ACCELERATOR ;
aoc2 0:8940db3353d7 257 car.p_brake = &BRAKE ;
aoc2 0:8940db3353d7 258 car.p_engineSwitch = &ENGINE_SWITCH ;
aoc2 0:8940db3353d7 259 car.p_sideLightSwitch = &SIDE_LIGHT_SWITCH ;
aoc2 0:8940db3353d7 260 car.p_leftSwitch = &LEFT_SWITCH ;
aoc2 0:8940db3353d7 261 car.p_rightSwitch = &RIGHT_SWITCH ;
aoc2 0:8940db3353d7 262
aoc2 0:8940db3353d7 263 // System Outputs
aoc2 0:8940db3353d7 264 car.p_sideLightIndicator = &SIDE_LIGHT_INDICATOR ;
aoc2 0:8940db3353d7 265 car.p_leftLight = &LEFT_LIGHT ;
aoc2 0:8940db3353d7 266 car.p_rightLight = &RIGHT_LIGHT ;
aoc2 0:8940db3353d7 267 car.p_engineLight = &ENGINE_LIGHT ;
aoc2 0:8940db3353d7 268 car.p_overspeedLight = &OVERSPEED_LIGHT ;
aoc2 0:8940db3353d7 269 car.p_brakeLight = &BRAKE_LIGHT ;
aoc2 0:8940db3353d7 270
aoc2 0:8940db3353d7 271 // Values Structure;
aoc2 0:8940db3353d7 272 car.p_rawValues = rawValues;
aoc2 0:8940db3353d7 273 car.p_carStats = carStat;
aoc2 0:8940db3353d7 274 car.p_mailQueue = mailQueue;
aoc2 0:8940db3353d7 275 car.nbElementInQueue = 0;
aoc2 0:8940db3353d7 276
aoc2 0:8940db3353d7 277 // Mutex
aoc2 0:8940db3353d7 278 car.p_rawMutex = rawMutex;
aoc2 0:8940db3353d7 279 car.p_statMutex = speedMutex;
aoc2 0:8940db3353d7 280 car.p_mailMutex = mailMutex;
aoc2 0:8940db3353d7 281
aoc2 0:8940db3353d7 282 // Serial Connection
aoc2 0:8940db3353d7 283 car.p_PC = pcSerial;
aoc2 0:8940db3353d7 284
aoc2 0:8940db3353d7 285 // Screen variables
aoc2 0:8940db3353d7 286 car.p_par_port = par_port;
aoc2 0:8940db3353d7 287 car.p_lcd = lcd;
aoc2 0:8940db3353d7 288 }