chad

Dependencies:   MCP23017 WattBob_TextLCD mbed-rtos mbed

Committer:
f_legge
Date:
Mon Mar 26 10:42:42 2018 +0000
Revision:
20:aeb7b7044c31
Parent:
19:1fecb6fa14a2
chad;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
f_legge 20:aeb7b7044c31 1 // Frazer Legge - H001262392
f_legge 20:aeb7b7044c31 2 // Embedded Software - Assignment 3
f_legge 19:1fecb6fa14a2 3 //
f_legge 20:aeb7b7044c31 4 // This program operates a simulation of a car control system.
f_legge 20:aeb7b7044c31 5 // THe simulation is completed through the use of external controls,
f_legge 20:aeb7b7044c31 6 // ignition, sidelights switch, idicator switches, accelerator and
f_legge 20:aeb7b7044c31 7 // brake pedals.
f_legge 20:aeb7b7044c31 8 // The simulation calculates Average speed and total distance travelled.
f_legge 20:aeb7b7044c31 9 // The simulation outputs are onboard LEDs to show ignition, sidelights,
f_legge 20:aeb7b7044c31 10 // indicators and overspeed indicator. The system shows the distance
f_legge 20:aeb7b7044c31 11 // traveled and average speed of the car on the LCD. A USB dump is also
f_legge 20:aeb7b7044c31 12 // done showing the average speed, accelerator and brake positions.
f_legge 20:aeb7b7044c31 13
f_legge 19:1fecb6fa14a2 14
f_legge 20:aeb7b7044c31 15 #include "mbed.h"
f_legge 20:aeb7b7044c31 16 #include "rtos.h"
f_legge 20:aeb7b7044c31 17 #include "MCP23017.h"
f_legge 20:aeb7b7044c31 18 #include "WattBob_TextLCD.h"
f_legge 20:aeb7b7044c31 19
f_legge 19:1fecb6fa14a2 20
f_legge 20:aeb7b7044c31 21 // LCD Definition
f_legge 20:aeb7b7044c31 22 #define BACK_LIGHT_ON(INTERFACE) INTERFACE->write_bit(1,BL_BIT)
f_legge 20:aeb7b7044c31 23 #define BACK_LIGHT_OFF(INTERFACE) INTERFACE->write_bit(0,BL_BIT)
f_legge 20:aeb7b7044c31 24
f_legge 20:aeb7b7044c31 25 // Car Sim Max/Min speed (mph)
f_legge 20:aeb7b7044c31 26 #define MAX_SPEED 100
f_legge 20:aeb7b7044c31 27 #define MIN_SPEED 0
f_legge 19:1fecb6fa14a2 28
f_legge 19:1fecb6fa14a2 29 // Serial Connection
f_legge 19:1fecb6fa14a2 30 Serial pc(USBTX, USBRX,115200);
f_legge 19:1fecb6fa14a2 31
f_legge 20:aeb7b7044c31 32 // ============================================================================
f_legge 20:aeb7b7044c31 33 // MBED Pin Assignments
f_legge 20:aeb7b7044c31 34 // ============================================================================
f_legge 20:aeb7b7044c31 35 //
f_legge 20:aeb7b7044c31 36
f_legge 20:aeb7b7044c31 37 // System Inputs
f_legge 20:aeb7b7044c31 38 // ----------------------------------------------------------------------------
f_legge 19:1fecb6fa14a2 39 // Analogue Input
f_legge 19:1fecb6fa14a2 40 AnalogIn Accel(p15); // Accelerator Pedal Input
f_legge 19:1fecb6fa14a2 41 AnalogIn Brake(p16); // Brake Pedal Input
f_legge 19:1fecb6fa14a2 42
f_legge 19:1fecb6fa14a2 43 // Digital Input
f_legge 19:1fecb6fa14a2 44 DigitalIn Ignit(p11); // Engine On/Off
f_legge 19:1fecb6fa14a2 45 DigitalIn SideL(p12); // Side Light On/Off
f_legge 19:1fecb6fa14a2 46 DigitalIn Indi_L(p13); // Left indicator switch
f_legge 19:1fecb6fa14a2 47 DigitalIn Indi_R(p14); // Right idicator switch
f_legge 19:1fecb6fa14a2 48
f_legge 20:aeb7b7044c31 49 // System Outputs
f_legge 20:aeb7b7044c31 50 // ----------------------------------------------------------------------------
f_legge 20:aeb7b7044c31 51 // PWM Output
f_legge 20:aeb7b7044c31 52 PwmOut SpeedIndicator(p21); // Speed Indicator Servo
f_legge 20:aeb7b7044c31 53 PwmOut Indi_L_LED(LED3); // Left Indicator LED
f_legge 20:aeb7b7044c31 54 PwmOut Indi_R_LED(LED4); // Right Indicator LED
f_legge 19:1fecb6fa14a2 55
f_legge 19:1fecb6fa14a2 56 // Digital Output
f_legge 19:1fecb6fa14a2 57 DigitalOut Ignit_LED(LED1); // Ignition LED Indicator
f_legge 19:1fecb6fa14a2 58 DigitalOut SideL_LED(LED2); // Side Light Indicator
f_legge 20:aeb7b7044c31 59 DigitalOut OverS_LED(p17); // Overspeed LED (REDBOX)
f_legge 20:aeb7b7044c31 60
f_legge 20:aeb7b7044c31 61 // Pointers to LCD Screen
f_legge 20:aeb7b7044c31 62 MCP23017 *par_port; // pointer to 16-bit parallel I/O chip
f_legge 20:aeb7b7044c31 63 WattBob_TextLCD *lcd; // pointer to 2*16 character LCD object
f_legge 20:aeb7b7044c31 64
f_legge 20:aeb7b7044c31 65 // ============================================================================
f_legge 20:aeb7b7044c31 66 // Data Structure
f_legge 20:aeb7b7044c31 67 // ============================================================================
f_legge 20:aeb7b7044c31 68 //
f_legge 20:aeb7b7044c31 69
f_legge 20:aeb7b7044c31 70 // Raw Data Structure
f_legge 20:aeb7b7044c31 71 // ----------------------------------------------------------------------------
f_legge 20:aeb7b7044c31 72
f_legge 20:aeb7b7044c31 73 // RawData is a global memory section that contains an instance of the raw input
f_legge 20:aeb7b7044c31 74 // data from speedControl.
f_legge 20:aeb7b7044c31 75
f_legge 20:aeb7b7044c31 76 typedef struct
f_legge 20:aeb7b7044c31 77 {
f_legge 20:aeb7b7044c31 78 bool EngineState;
f_legge 20:aeb7b7044c31 79 float RawAccel;
f_legge 20:aeb7b7044c31 80 float RawBrake;
f_legge 20:aeb7b7044c31 81 } RawData;
f_legge 20:aeb7b7044c31 82
f_legge 20:aeb7b7044c31 83 // Create MUTEX to contol access to RawData
f_legge 20:aeb7b7044c31 84 Mutex RawDataMutex;
f_legge 20:aeb7b7044c31 85
f_legge 20:aeb7b7044c31 86 // Create instance of RawData
f_legge 20:aeb7b7044c31 87 RawData rawData;
f_legge 20:aeb7b7044c31 88
f_legge 20:aeb7b7044c31 89 // Speed Data Structure
f_legge 20:aeb7b7044c31 90 // ----------------------------------------------------------------------------
f_legge 20:aeb7b7044c31 91
f_legge 20:aeb7b7044c31 92 // Speed data is a global memory section that contains an instance of the
f_legge 20:aeb7b7044c31 93 // calculated car speed.
f_legge 19:1fecb6fa14a2 94
f_legge 20:aeb7b7044c31 95 typedef struct
f_legge 20:aeb7b7044c31 96 {
f_legge 20:aeb7b7044c31 97 float rawSpeed[3];
f_legge 20:aeb7b7044c31 98 int counter;
f_legge 20:aeb7b7044c31 99 } CarSpeedData;
f_legge 20:aeb7b7044c31 100
f_legge 20:aeb7b7044c31 101 // Create MUTEX to control access to CarSpeedData
f_legge 20:aeb7b7044c31 102
f_legge 20:aeb7b7044c31 103 Mutex SpeedDataMutex;
f_legge 20:aeb7b7044c31 104
f_legge 20:aeb7b7044c31 105 // Create insance of CarSpeedData
f_legge 20:aeb7b7044c31 106 CarSpeedData speedData;
f_legge 19:1fecb6fa14a2 107
f_legge 20:aeb7b7044c31 108 // Filtered Data Structure
f_legge 20:aeb7b7044c31 109 // ----------------------------------------------------------------------------
f_legge 20:aeb7b7044c31 110 typedef struct
f_legge 20:aeb7b7044c31 111 {
f_legge 20:aeb7b7044c31 112 float AvgSpeed;
f_legge 20:aeb7b7044c31 113 float TotalDist;
f_legge 20:aeb7b7044c31 114 } FilteredData;
f_legge 20:aeb7b7044c31 115
f_legge 20:aeb7b7044c31 116 // Create MUTEX to control access to FilterData
f_legge 20:aeb7b7044c31 117 Mutex filteredDataMutex;
f_legge 20:aeb7b7044c31 118
f_legge 20:aeb7b7044c31 119 // Create instance of FilteredData
f_legge 20:aeb7b7044c31 120 FilteredData filteredData;
f_legge 20:aeb7b7044c31 121
f_legge 20:aeb7b7044c31 122 // Mail Queue Structure
f_legge 20:aeb7b7044c31 123 // ----------------------------------------------------------------------------
f_legge 20:aeb7b7044c31 124
f_legge 20:aeb7b7044c31 125 // PCDump is a global memory section that is populated in Mail_queue. The data
f_legge 20:aeb7b7044c31 126 // is coppied from the current state of the control system every 5 seconds.
f_legge 20:aeb7b7044c31 127
f_legge 20:aeb7b7044c31 128 typedef struct
f_legge 20:aeb7b7044c31 129 {
f_legge 19:1fecb6fa14a2 130 float speed;
f_legge 19:1fecb6fa14a2 131 float accelerator;
f_legge 19:1fecb6fa14a2 132 float brake;
f_legge 20:aeb7b7044c31 133 } PCDump;
f_legge 20:aeb7b7044c31 134
f_legge 20:aeb7b7044c31 135 // Create 100 element Mail Queue
f_legge 20:aeb7b7044c31 136 Mail<PCDump, 100> Memory_dump;
f_legge 20:aeb7b7044c31 137
f_legge 20:aeb7b7044c31 138 // Counter to track number of elements in mail
f_legge 20:aeb7b7044c31 139 int MailCounter;
f_legge 20:aeb7b7044c31 140
f_legge 20:aeb7b7044c31 141 // Create MUTEX to control access to MailQueueCounter
f_legge 20:aeb7b7044c31 142 Mutex MailMutex;
f_legge 20:aeb7b7044c31 143
f_legge 20:aeb7b7044c31 144 // ============================================================================
f_legge 20:aeb7b7044c31 145 // Car Simulation
f_legge 20:aeb7b7044c31 146 // ============================================================================
f_legge 20:aeb7b7044c31 147
f_legge 20:aeb7b7044c31 148 // The CarSim task updates the rawSpeed float at freq of 20Hz
f_legge 19:1fecb6fa14a2 149
f_legge 20:aeb7b7044c31 150 void CarSim(void const *arg)
f_legge 20:aeb7b7044c31 151 {
f_legge 20:aeb7b7044c31 152 float NewSpeed;
f_legge 20:aeb7b7044c31 153
f_legge 20:aeb7b7044c31 154 // Deposit global variables to local variables
f_legge 20:aeb7b7044c31 155 RawDataMutex.lock();
f_legge 20:aeb7b7044c31 156 bool currentEngineState = rawData.EngineState;
f_legge 20:aeb7b7044c31 157 float currentAccel = rawData.RawAccel;
f_legge 20:aeb7b7044c31 158 float currentBrake = rawData.RawBrake;
f_legge 20:aeb7b7044c31 159 RawDataMutex.unlock();
f_legge 20:aeb7b7044c31 160
f_legge 20:aeb7b7044c31 161 // Calulate current speed as an fraction of the MAX_SPEED based on the
f_legge 20:aeb7b7044c31 162 // percentage of accelerator and brake.
f_legge 20:aeb7b7044c31 163 // Speed is set to 0 if Engine State is changed to 0;
f_legge 20:aeb7b7044c31 164 NewSpeed = currentAccel*MAX_SPEED*(1-currentBrake)*currentEngineState;
f_legge 20:aeb7b7044c31 165
f_legge 20:aeb7b7044c31 166 // Check Counter. If outside array set to 0
f_legge 20:aeb7b7044c31 167 // Data within shared resource therefore MUTEX is used.
f_legge 20:aeb7b7044c31 168 SpeedDataMutex.lock();
f_legge 20:aeb7b7044c31 169
f_legge 20:aeb7b7044c31 170 if (speedData.counter > 2)
f_legge 20:aeb7b7044c31 171 {
f_legge 20:aeb7b7044c31 172 speedData.counter = 0;
f_legge 20:aeb7b7044c31 173 }
f_legge 20:aeb7b7044c31 174
f_legge 20:aeb7b7044c31 175 // Output rawSpeed value to next index of rawSpeed.
f_legge 20:aeb7b7044c31 176 // Increment counter
f_legge 20:aeb7b7044c31 177 speedData.rawSpeed[speedData.counter] = NewSpeed;
f_legge 20:aeb7b7044c31 178 speedData.counter++;
f_legge 20:aeb7b7044c31 179 SpeedDataMutex.unlock();
f_legge 20:aeb7b7044c31 180 }
f_legge 20:aeb7b7044c31 181
f_legge 20:aeb7b7044c31 182 // ============================================================================
f_legge 20:aeb7b7044c31 183 // Controller Tasks
f_legge 20:aeb7b7044c31 184 // ============================================================================
f_legge 20:aeb7b7044c31 185
f_legge 20:aeb7b7044c31 186 // Speed Control (Task 1) reads external analog inputs and updates rawData.
f_legge 20:aeb7b7044c31 187 // Operating freq of 10Hz
f_legge 20:aeb7b7044c31 188
f_legge 20:aeb7b7044c31 189 void SpeedControl(void const *arg)
f_legge 20:aeb7b7044c31 190 {
f_legge 20:aeb7b7044c31 191 // Deposit global variables to local variables
f_legge 20:aeb7b7044c31 192 RawDataMutex.lock();
f_legge 20:aeb7b7044c31 193 rawData.RawAccel = Accel.read();
f_legge 20:aeb7b7044c31 194 rawData.RawBrake = Brake.read();
f_legge 20:aeb7b7044c31 195 RawDataMutex.unlock();
f_legge 20:aeb7b7044c31 196 }
f_legge 20:aeb7b7044c31 197
f_legge 20:aeb7b7044c31 198 // Ignition(Task 2) reads the state of an "ignition switch".
f_legge 20:aeb7b7044c31 199 // Updates to rawData.
f_legge 20:aeb7b7044c31 200 // Operating freq of 2Hz.
f_legge 20:aeb7b7044c31 201
f_legge 20:aeb7b7044c31 202 void Ignition(void const *arg)
f_legge 20:aeb7b7044c31 203 {
f_legge 20:aeb7b7044c31 204 // Get Switch state and store locally
f_legge 20:aeb7b7044c31 205 bool currentEngineState = Ignit.read();
f_legge 20:aeb7b7044c31 206
f_legge 20:aeb7b7044c31 207 // Deposit Local data to global under locked state
f_legge 20:aeb7b7044c31 208 RawDataMutex.lock();
f_legge 20:aeb7b7044c31 209 rawData.EngineState = currentEngineState;
f_legge 20:aeb7b7044c31 210 RawDataMutex.unlock();
f_legge 20:aeb7b7044c31 211
f_legge 20:aeb7b7044c31 212 // Logic check on Engine state
f_legge 20:aeb7b7044c31 213 if (currentEngineState == 1)
f_legge 20:aeb7b7044c31 214 {
f_legge 20:aeb7b7044c31 215 Ignit_LED = 1;
f_legge 20:aeb7b7044c31 216 }
f_legge 20:aeb7b7044c31 217 else
f_legge 20:aeb7b7044c31 218 {
f_legge 20:aeb7b7044c31 219 Ignit_LED = 0;
f_legge 20:aeb7b7044c31 220 }
f_legge 20:aeb7b7044c31 221 }
f_legge 20:aeb7b7044c31 222
f_legge 20:aeb7b7044c31 223 // Speed_Avg (Task 3) Calculates the average speed of the car over 3 speed
f_legge 20:aeb7b7044c31 224 // samples.
f_legge 20:aeb7b7044c31 225 // Operation freq of 5Hz
f_legge 19:1fecb6fa14a2 226
f_legge 20:aeb7b7044c31 227 void Speed_Avg(void const *arg)
f_legge 20:aeb7b7044c31 228 {
f_legge 20:aeb7b7044c31 229 // Init local float as 0
f_legge 20:aeb7b7044c31 230 float speed_T = 0.0;
f_legge 20:aeb7b7044c31 231
f_legge 20:aeb7b7044c31 232 // Deposit gloabal data to local data under locked state
f_legge 20:aeb7b7044c31 233 SpeedDataMutex.lock();
f_legge 20:aeb7b7044c31 234 for (int i = 0; i < 3; i++)
f_legge 20:aeb7b7044c31 235 {
f_legge 20:aeb7b7044c31 236 speed_T = speed_T + speedData.rawSpeed[i];
f_legge 20:aeb7b7044c31 237 }
f_legge 20:aeb7b7044c31 238 SpeedDataMutex.unlock();
f_legge 20:aeb7b7044c31 239
f_legge 20:aeb7b7044c31 240 // Deposit local data to global data under locked state
f_legge 20:aeb7b7044c31 241 filteredDataMutex.lock();
f_legge 20:aeb7b7044c31 242 filteredData.AvgSpeed = (speed_T/3);
f_legge 20:aeb7b7044c31 243 filteredDataMutex.unlock();
f_legge 20:aeb7b7044c31 244 }
f_legge 20:aeb7b7044c31 245
f_legge 20:aeb7b7044c31 246 // Speed_Indi (Task 4) shows a representation of the car speed through a servo
f_legge 20:aeb7b7044c31 247 // Operation freq of 1Hz
f_legge 20:aeb7b7044c31 248
f_legge 20:aeb7b7044c31 249 void Speed_Indi(void const *arg)
f_legge 20:aeb7b7044c31 250 {
f_legge 20:aeb7b7044c31 251 // Deposit gloabal data to local data under locked state
f_legge 20:aeb7b7044c31 252 filteredDataMutex.lock();
f_legge 20:aeb7b7044c31 253 float currentAvgSpeed = filteredData.AvgSpeed;
f_legge 20:aeb7b7044c31 254 filteredDataMutex.unlock();
f_legge 20:aeb7b7044c31 255
f_legge 20:aeb7b7044c31 256 // Update Servo
f_legge 20:aeb7b7044c31 257 // Operates between 1000us and 2000us pwm
f_legge 20:aeb7b7044c31 258 // ie -> 10 * 50(mph) will give middle positioning
f_legge 20:aeb7b7044c31 259 SpeedIndicator.pulsewidth_us(1000+(10*currentAvgSpeed));
f_legge 20:aeb7b7044c31 260 }
f_legge 19:1fecb6fa14a2 261
f_legge 20:aeb7b7044c31 262 // OverSpeed (Task 5) illuminates an LED indicator to show that the car is above
f_legge 20:aeb7b7044c31 263 // 70mph.
f_legge 20:aeb7b7044c31 264 // Opperation freq of 0.5Hz
f_legge 20:aeb7b7044c31 265
f_legge 20:aeb7b7044c31 266 void OverSpeed(void const *arg)
f_legge 20:aeb7b7044c31 267 {
f_legge 20:aeb7b7044c31 268 // Deposit gloabal data to local data under locked state
f_legge 20:aeb7b7044c31 269 SpeedDataMutex.lock();
f_legge 20:aeb7b7044c31 270 float currentSpeed = speedData.rawSpeed[1];
f_legge 20:aeb7b7044c31 271 SpeedDataMutex.unlock();
f_legge 20:aeb7b7044c31 272
f_legge 20:aeb7b7044c31 273 // Use locally stored current speed to show if car is travelling over 70mph
f_legge 20:aeb7b7044c31 274 if (currentSpeed > 70.0)
f_legge 20:aeb7b7044c31 275 {
f_legge 20:aeb7b7044c31 276 OverS_LED = 1;
f_legge 20:aeb7b7044c31 277 }
f_legge 20:aeb7b7044c31 278 else
f_legge 20:aeb7b7044c31 279 {
f_legge 20:aeb7b7044c31 280 OverS_LED = 0;
f_legge 20:aeb7b7044c31 281 }
f_legge 20:aeb7b7044c31 282 }
f_legge 20:aeb7b7044c31 283
f_legge 20:aeb7b7044c31 284 // Display (Taks 6) shows the total distance traveled and the average speed on
f_legge 20:aeb7b7044c31 285 // the LCD.
f_legge 20:aeb7b7044c31 286 // Operation freq of 2Hz
f_legge 20:aeb7b7044c31 287
f_legge 20:aeb7b7044c31 288 void Display(void const *arg)
f_legge 20:aeb7b7044c31 289 {
f_legge 20:aeb7b7044c31 290 // Local distance variable
f_legge 20:aeb7b7044c31 291 float currentTotalDist;
f_legge 20:aeb7b7044c31 292
f_legge 20:aeb7b7044c31 293 // Deposit gloabal data to local data under locked state
f_legge 20:aeb7b7044c31 294 filteredDataMutex.lock();
f_legge 20:aeb7b7044c31 295 float currentAvgSpeed = filteredData.AvgSpeed;
f_legge 20:aeb7b7044c31 296 float current_TotalDist = filteredData.TotalDist;
f_legge 20:aeb7b7044c31 297 filteredDataMutex.unlock();
f_legge 20:aeb7b7044c31 298
f_legge 20:aeb7b7044c31 299 // Update distance traveled
f_legge 20:aeb7b7044c31 300 // Polling every 0.5 seconds therefore convereted from 0.5s to hours
f_legge 20:aeb7b7044c31 301 // MUTEX not protected as TotalDist is only used for this function
f_legge 20:aeb7b7044c31 302 currentTotalDist = current_TotalDist + (currentAvgSpeed*(0.5/3600));
f_legge 20:aeb7b7044c31 303
f_legge 20:aeb7b7044c31 304 filteredDataMutex.lock();
f_legge 20:aeb7b7044c31 305 filteredData.TotalDist = currentTotalDist;
f_legge 20:aeb7b7044c31 306 filteredDataMutex.unlock();
f_legge 20:aeb7b7044c31 307
f_legge 20:aeb7b7044c31 308 // Output on LCD
f_legge 20:aeb7b7044c31 309 lcd->locate(0,0);
f_legge 20:aeb7b7044c31 310 lcd->printf("D: %f",currentTotalDist);
f_legge 20:aeb7b7044c31 311 lcd->locate(1,0);
f_legge 20:aeb7b7044c31 312 lcd->printf("S: %f",currentAvgSpeed);
f_legge 20:aeb7b7044c31 313 }
f_legge 20:aeb7b7044c31 314
f_legge 20:aeb7b7044c31 315 // Mail_Queue (Task 7) sends gloabal variable to a MAIL structure.
f_legge 20:aeb7b7044c31 316 // A counter is incremented to track the variables.
f_legge 20:aeb7b7044c31 317 // Operation freq of 0.2Hz.
f_legge 20:aeb7b7044c31 318
f_legge 20:aeb7b7044c31 319 void Mail_Queue(void const *arg)
f_legge 20:aeb7b7044c31 320 {
f_legge 20:aeb7b7044c31 321 // Deposit gloabal data to local data under locked state
f_legge 20:aeb7b7044c31 322 RawDataMutex.lock();
f_legge 20:aeb7b7044c31 323 float currentAccel = rawData.RawAccel;
f_legge 20:aeb7b7044c31 324 float currentBrake = rawData.RawBrake;
f_legge 20:aeb7b7044c31 325 RawDataMutex.unlock();
f_legge 20:aeb7b7044c31 326
f_legge 20:aeb7b7044c31 327 filteredDataMutex.lock();
f_legge 20:aeb7b7044c31 328 float currentAvgSpeed = filteredData.AvgSpeed;
f_legge 20:aeb7b7044c31 329 filteredDataMutex.lock();
f_legge 19:1fecb6fa14a2 330
f_legge 20:aeb7b7044c31 331 // Allocate and populate PCDump Struct
f_legge 20:aeb7b7044c31 332 PCDump *currentPCDump = Memory_dump.alloc();
f_legge 20:aeb7b7044c31 333
f_legge 20:aeb7b7044c31 334 currentPCDump->brake = currentBrake;
f_legge 20:aeb7b7044c31 335 currentPCDump->accelerator = currentAccel;
f_legge 20:aeb7b7044c31 336 currentPCDump->speed = currentAvgSpeed;
f_legge 20:aeb7b7044c31 337
f_legge 20:aeb7b7044c31 338 // PCDump struct pushed to mail queue
f_legge 20:aeb7b7044c31 339 Memory_dump.put(currentPCDump);
f_legge 20:aeb7b7044c31 340
f_legge 20:aeb7b7044c31 341 // Lock mail MUTEX and increment counter
f_legge 20:aeb7b7044c31 342 MailMutex.lock();
f_legge 20:aeb7b7044c31 343 MailCounter++;
f_legge 20:aeb7b7044c31 344 MailMutex.unlock();
f_legge 20:aeb7b7044c31 345 }
f_legge 20:aeb7b7044c31 346
f_legge 20:aeb7b7044c31 347 // Mail_Print (Task 8) sends the MAIL queue to a terminal over USB serial.
f_legge 20:aeb7b7044c31 348 // When finished MAIL counter is reset.
f_legge 20:aeb7b7044c31 349 // Operation freq of 0.05Hz.
f_legge 20:aeb7b7044c31 350
f_legge 20:aeb7b7044c31 351 void Mail_Print(void const *arg)
f_legge 20:aeb7b7044c31 352 {
f_legge 20:aeb7b7044c31 353 // Deposit gloabal data to local data under locked state
f_legge 20:aeb7b7044c31 354 MailMutex.lock();
f_legge 20:aeb7b7044c31 355 int currentMCount = MailCounter;
f_legge 20:aeb7b7044c31 356 MailMutex.unlock();
f_legge 20:aeb7b7044c31 357
f_legge 20:aeb7b7044c31 358 // Terminal header notifying dump
f_legge 20:aeb7b7044c31 359 pc.printf("Mail Dump\n\r");
f_legge 20:aeb7b7044c31 360
f_legge 20:aeb7b7044c31 361 // Print each record in MAIL queue. MAIL queue is deposited locally then
f_legge 20:aeb7b7044c31 362 // values are printed and elements freed in MAIL queue.
f_legge 20:aeb7b7044c31 363 for (int i = 0; i < currentMCount; i++)
f_legge 20:aeb7b7044c31 364 {
f_legge 20:aeb7b7044c31 365 osEvent evnt = Memory_dump.get();
f_legge 20:aeb7b7044c31 366 if (evnt.status == osEventMail)
f_legge 20:aeb7b7044c31 367 {
f_legge 20:aeb7b7044c31 368 PCDump *currentPCDump = (PCDump*)evnt.value.p;
f_legge 20:aeb7b7044c31 369
f_legge 20:aeb7b7044c31 370 pc.printf("AvgSpeed: %f\n\rAccel: %f\n\rBrake: %f\n\rCounter: %i\n\n\r",currentPCDump->speed,currentPCDump->accelerator,currentPCDump->brake,i);
f_legge 20:aeb7b7044c31 371
f_legge 20:aeb7b7044c31 372 Memory_dump.free(currentPCDump);
f_legge 20:aeb7b7044c31 373 }
f_legge 20:aeb7b7044c31 374 }
f_legge 20:aeb7b7044c31 375
f_legge 20:aeb7b7044c31 376 // Reset counter under locked state
f_legge 20:aeb7b7044c31 377 MailMutex.lock();
f_legge 20:aeb7b7044c31 378 MailCounter = 0;
f_legge 20:aeb7b7044c31 379 MailMutex.unlock();
f_legge 20:aeb7b7044c31 380 }
f_legge 20:aeb7b7044c31 381
f_legge 20:aeb7b7044c31 382 // Side_Light (Task 9) checks the state of the side light and sets the LED
f_legge 20:aeb7b7044c31 383 // indicator
f_legge 20:aeb7b7044c31 384 // Operation freq of 1Hz
f_legge 20:aeb7b7044c31 385
f_legge 20:aeb7b7044c31 386 void Side_Light(void const *arg)
f_legge 20:aeb7b7044c31 387 {
f_legge 20:aeb7b7044c31 388 if(SideL == 1)
f_legge 20:aeb7b7044c31 389 {
f_legge 20:aeb7b7044c31 390 SideL_LED = 1;
f_legge 20:aeb7b7044c31 391 }
f_legge 20:aeb7b7044c31 392 else
f_legge 20:aeb7b7044c31 393 {
f_legge 20:aeb7b7044c31 394 SideL_LED = 0;
f_legge 20:aeb7b7044c31 395 }
f_legge 20:aeb7b7044c31 396 }
f_legge 20:aeb7b7044c31 397
f_legge 20:aeb7b7044c31 398 // Indicator (Task 10) checks the left and right indicator switches.
f_legge 20:aeb7b7044c31 399 // Illuminates either left or right LED accordingly.
f_legge 20:aeb7b7044c31 400 // If both high then LEDs flash in hazard mode.
f_legge 19:1fecb6fa14a2 401
f_legge 20:aeb7b7044c31 402 void Indicator(void const *arg)
f_legge 20:aeb7b7044c31 403 {
f_legge 20:aeb7b7044c31 404 // If Left switch is high then flash left LED at 1Hz
f_legge 20:aeb7b7044c31 405 if (Indi_L == 1 && Indi_R == 0)
f_legge 20:aeb7b7044c31 406 {
f_legge 20:aeb7b7044c31 407 Indi_L_LED.period(1.0);
f_legge 20:aeb7b7044c31 408 Indi_L_LED.pulsewidth(0.5);
f_legge 20:aeb7b7044c31 409
f_legge 20:aeb7b7044c31 410 Indi_R_LED.period(1.0);
f_legge 20:aeb7b7044c31 411 Indi_R_LED.pulsewidth(0.0);
f_legge 20:aeb7b7044c31 412 }
f_legge 20:aeb7b7044c31 413
f_legge 20:aeb7b7044c31 414 // If Right switch is high then flash right LED at 1Hz
f_legge 20:aeb7b7044c31 415 else if (Indi_L == 0 && Indi_R == 1)
f_legge 20:aeb7b7044c31 416 {
f_legge 20:aeb7b7044c31 417 Indi_L_LED.period(1.0);
f_legge 20:aeb7b7044c31 418 Indi_L_LED.pulsewidth(0.0);
f_legge 20:aeb7b7044c31 419
f_legge 20:aeb7b7044c31 420 Indi_R_LED.period(1.0);
f_legge 20:aeb7b7044c31 421 Indi_R_LED.pulsewidth(0.5);
f_legge 20:aeb7b7044c31 422 }
f_legge 20:aeb7b7044c31 423
f_legge 20:aeb7b7044c31 424 // If Left & Right switch is high then flash both LEDs at 2Hz
f_legge 20:aeb7b7044c31 425 else if (Indi_L == 1 && Indi_R == 1)
f_legge 20:aeb7b7044c31 426 {
f_legge 20:aeb7b7044c31 427 Indi_L_LED.period(0.5);
f_legge 20:aeb7b7044c31 428 Indi_R_LED.period(0.5);
f_legge 20:aeb7b7044c31 429 Indi_L_LED.pulsewidth(0.25);
f_legge 20:aeb7b7044c31 430 Indi_R_LED.pulsewidth(0.25);
f_legge 20:aeb7b7044c31 431 }
f_legge 20:aeb7b7044c31 432
f_legge 20:aeb7b7044c31 433 // If Left & Right switch is low then no flash
f_legge 20:aeb7b7044c31 434 else if (Indi_L == 0 && Indi_R == 0)
f_legge 20:aeb7b7044c31 435 {
f_legge 20:aeb7b7044c31 436 Indi_L_LED.period(1.0);
f_legge 20:aeb7b7044c31 437 Indi_L_LED.pulsewidth(0.0);
f_legge 20:aeb7b7044c31 438
f_legge 20:aeb7b7044c31 439 Indi_R_LED.period(1.0);
f_legge 20:aeb7b7044c31 440 Indi_R_LED.pulsewidth(0.0);
f_legge 20:aeb7b7044c31 441 }
f_legge 20:aeb7b7044c31 442 }
f_legge 20:aeb7b7044c31 443
f_legge 20:aeb7b7044c31 444 void ledFlasher(void const *arg)
f_legge 20:aeb7b7044c31 445 {
f_legge 20:aeb7b7044c31 446 Ignit_LED =! Ignit_LED;
f_legge 20:aeb7b7044c31 447 }
f_legge 20:aeb7b7044c31 448
f_legge 19:1fecb6fa14a2 449
f_legge 20:aeb7b7044c31 450 // ============================================================================
f_legge 20:aeb7b7044c31 451 // Init System
f_legge 20:aeb7b7044c31 452 // ============================================================================
f_legge 20:aeb7b7044c31 453
f_legge 20:aeb7b7044c31 454 void Init()
f_legge 20:aeb7b7044c31 455 {
f_legge 20:aeb7b7044c31 456 // Servo freq set
f_legge 20:aeb7b7044c31 457 SpeedIndicator.period_ms(50);
f_legge 20:aeb7b7044c31 458 // Global Variables zeroed
f_legge 20:aeb7b7044c31 459 rawData.EngineState = 0;
f_legge 20:aeb7b7044c31 460 rawData.RawAccel = 0.0;
f_legge 20:aeb7b7044c31 461 rawData.RawBrake = 0.0;
f_legge 20:aeb7b7044c31 462 speedData.rawSpeed[0] = 0.0;
f_legge 20:aeb7b7044c31 463 speedData.rawSpeed[1] = 0.0;
f_legge 20:aeb7b7044c31 464 speedData.rawSpeed[2] = 0.0;
f_legge 20:aeb7b7044c31 465 speedData.counter = 0;
f_legge 20:aeb7b7044c31 466 filteredData.AvgSpeed = 0.0;
f_legge 20:aeb7b7044c31 467 filteredData.TotalDist = 0.0;
f_legge 20:aeb7b7044c31 468 MailCounter = 0;
f_legge 20:aeb7b7044c31 469 }
f_legge 20:aeb7b7044c31 470
f_legge 20:aeb7b7044c31 471 // ============================================================================
f_legge 20:aeb7b7044c31 472 // Main Thread
f_legge 20:aeb7b7044c31 473 // ============================================================================
f_legge 20:aeb7b7044c31 474
f_legge 20:aeb7b7044c31 475 int main()
f_legge 20:aeb7b7044c31 476 {
f_legge 20:aeb7b7044c31 477 par_port = new MCP23017(p9, p10, 0x40); // initialise 16-bit I/O chip
f_legge 20:aeb7b7044c31 478 par_port->config(0x0F00, 0x0F00, 0x0F00);
f_legge 20:aeb7b7044c31 479
f_legge 20:aeb7b7044c31 480 lcd = new WattBob_TextLCD(par_port); // initialise 2*26 char display
f_legge 20:aeb7b7044c31 481 par_port->write_bit(1,BL_BIT); // turn LCD backlight ON
f_legge 20:aeb7b7044c31 482
f_legge 20:aeb7b7044c31 483 lcd->cls(); // clear display
f_legge 20:aeb7b7044c31 484
f_legge 20:aeb7b7044c31 485 Init(); // Run init void
f_legge 20:aeb7b7044c31 486
f_legge 20:aeb7b7044c31 487 Ignit_LED = 0;
f_legge 20:aeb7b7044c31 488
f_legge 20:aeb7b7044c31 489
f_legge 20:aeb7b7044c31 490 //while(1)
f_legge 20:aeb7b7044c31 491 //{
f_legge 20:aeb7b7044c31 492 // Ignit_LED =! Ignit_LED;
f_legge 20:aeb7b7044c31 493 // wait(1);
f_legge 20:aeb7b7044c31 494 //Ignit_LED = 0;
f_legge 20:aeb7b7044c31 495 //wait(1);
f_legge 20:aeb7b7044c31 496
f_legge 20:aeb7b7044c31 497 //}
f_legge 20:aeb7b7044c31 498
f_legge 20:aeb7b7044c31 499 //SideL_LED = 1;
f_legge 20:aeb7b7044c31 500
f_legge 20:aeb7b7044c31 501 RtosTimer ledFlash(ledFlasher, osTimerPeriodic);
f_legge 20:aeb7b7044c31 502 ledFlash.start(1000);
f_legge 20:aeb7b7044c31 503 // Timer Objects
f_legge 20:aeb7b7044c31 504 //RtosTimer Car_Sim(CarSim,osTimerPeriodic);
f_legge 20:aeb7b7044c31 505 //RtosTimer Task1(SpeedControl,osTimerPeriodic);
f_legge 20:aeb7b7044c31 506 //RtosTimer Task2(Ignition,osTimerPeriodic);
f_legge 20:aeb7b7044c31 507 //RtosTimer Task3(Speed_Avg,osTimerPeriodic);
f_legge 20:aeb7b7044c31 508 //RtosTimer Task4(Speed_Indi,osTimerPeriodic);
f_legge 20:aeb7b7044c31 509 //RtosTimer Task5(OverSpeed,osTimerPeriodic);
f_legge 20:aeb7b7044c31 510 //RtosTimer Task6(Display,osTimerPeriodic);
f_legge 20:aeb7b7044c31 511 //RtosTimer Task7(Mail_Queue,osTimerPeriodic);
f_legge 20:aeb7b7044c31 512 //RtosTimer Task8(Mail_Print,osTimerPeriodic);
f_legge 20:aeb7b7044c31 513 //RtosTimer Task9(Side_Light,osTimerPeriodic);
f_legge 20:aeb7b7044c31 514 //RtosTimer Task10(Indicator,osTimerPeriodic);
f_legge 20:aeb7b7044c31 515
f_legge 20:aeb7b7044c31 516 // Start RTOS Timer objects
f_legge 20:aeb7b7044c31 517
f_legge 20:aeb7b7044c31 518 //Car_Sim.start(50); // 20Hz
f_legge 20:aeb7b7044c31 519 //Task1.start(100); // 10Hz
f_legge 20:aeb7b7044c31 520 //Task2.start(500); // 2Hz
f_legge 20:aeb7b7044c31 521 //Task3.start(200); // 5Hz
f_legge 20:aeb7b7044c31 522 //Task4.start(1000); // 1Hz
f_legge 20:aeb7b7044c31 523 //Task5.start(2000); // 0.5Hz
f_legge 20:aeb7b7044c31 524 //Task6.start(500); // 2Hz
f_legge 20:aeb7b7044c31 525 //Task7.start(5000); // 0.2Hz
f_legge 20:aeb7b7044c31 526 //Task8.start(20000); // 0.05Hz
f_legge 20:aeb7b7044c31 527 //Task9.start(1000); // 1Hz
f_legge 20:aeb7b7044c31 528 //Task10.start(2000); // 2Hz
f_legge 20:aeb7b7044c31 529
f_legge 20:aeb7b7044c31 530 Thread::wait(osWaitForever); // Forever loop
f_legge 20:aeb7b7044c31 531
f_legge 20:aeb7b7044c31 532 }