This is car control simulation by using Mbed controller and real time operating system.

Dependencies:   MCP23017 Servo WattBob_TextLCD mbed-rtos mbed

Fork of Ass3 by Muaiyd Al-Zandi

Committer:
muaiyd
Date:
Wed May 07 10:25:50 2014 +0000
Revision:
13:e5b22bfbe67b
Parent:
12:8eb2c1cccee6
Final Version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
muaiyd 13:e5b22bfbe67b 1 /***********************************
muaiyd 13:e5b22bfbe67b 2 * CAR.cpp *
muaiyd 13:e5b22bfbe67b 3 ************************************/
muaiyd 0:68ce46607848 4 #include "CAR.h"
muaiyd 11:7f2414ecb7ee 5
muaiyd 11:7f2414ecb7ee 6 //Define semaphores to manage accessing the viriables
muaiyd 1:b409ad65466a 7 Semaphore CAR_MAIL_SEM(1);
muaiyd 12:8eb2c1cccee6 8 Semaphore INPUT_SEM(1);
muaiyd 12:8eb2c1cccee6 9 Semaphore Speed_SEM(1);
muaiyd 13:e5b22bfbe67b 10
muaiyd 11:7f2414ecb7ee 11 Semaphore AVR_SPEED_SEM(2);
muaiyd 11:7f2414ecb7ee 12 /* Two counter the first is counting the number of element that
muaiyd 11:7f2414ecb7ee 13 was sended to the MAIL. The another is to count the number of
muaiyd 11:7f2414ecb7ee 14 element that dumped to a file */
muaiyd 1:b409ad65466a 15 uint32_t Element_Counter_W = 0;
muaiyd 1:b409ad65466a 16 uint32_t Element_Counter_R = 0;
muaiyd 11:7f2414ecb7ee 17 // Initialise a mail with 100 element
muaiyd 11:7f2414ecb7ee 18 static Mail<CAR_MAIL, 100> mail_box;
muaiyd 9:d86a6b8cdfa4 19
muaiyd 9:d86a6b8cdfa4 20 // Create the local filesystem under the name "local"
muaiyd 9:d86a6b8cdfa4 21 LocalFileSystem local("local");
muaiyd 9:d86a6b8cdfa4 22
muaiyd 1:b409ad65466a 23 CAR::CAR(){
muaiyd 1:b409ad65466a 24 Port.write_bit(1,BL_BIT);
muaiyd 11:7f2414ecb7ee 25 // Open "out.txt" on the local file system for writing
muaiyd 11:7f2414ecb7ee 26 FILE *fp = fopen("/local/Car_Values.csv", "w");
muaiyd 9:d86a6b8cdfa4 27 fprintf(fp, "Counter,Average_Speed,Accelerometer_Value,Brake_Value\r\n");
muaiyd 9:d86a6b8cdfa4 28 fclose(fp);
muaiyd 1:b409ad65466a 29 }
muaiyd 11:7f2414ecb7ee 30 // This two functions are save and read the ODO value in a register
muaiyd 11:7f2414ecb7ee 31 // in order to safe it when the mbed restart
muaiyd 1:b409ad65466a 32 void CAR::SAVE_ODO(float value) {
muaiyd 1:b409ad65466a 33 LPC_RTC->GPREG0 = *((uint32_t*)&value);
muaiyd 1:b409ad65466a 34 }
muaiyd 1:b409ad65466a 35 float CAR::GET_ODO() {
muaiyd 1:b409ad65466a 36 return *((float*)&(LPC_RTC->GPREG0));
muaiyd 1:b409ad65466a 37 }
muaiyd 11:7f2414ecb7ee 38
muaiyd 11:7f2414ecb7ee 39 /* Read the accelerometer and brake value every 100 mSec and calculate the speed.
muaiyd 11:7f2414ecb7ee 40 Also save them in variabls.The speed is saved in an array of three element
muaiyd 11:7f2414ecb7ee 41 so the past three values of speed is saved. */
muaiyd 12:8eb2c1cccee6 42 void CAR::Car_Simulation(void const *args){
muaiyd 0:68ce46607848 43 while (true) {
muaiyd 7:a92da438d06c 44 INPUT_SEM.wait();
muaiyd 1:b409ad65466a 45 Accelerometer_Value = Accelerometer.read();
muaiyd 1:b409ad65466a 46 Brake_Value = Brake.read();
muaiyd 1:b409ad65466a 47 EngineStat = EngineSwitch;
muaiyd 13:e5b22bfbe67b 48 R_LightSide_SW = R_Light_Switch;
muaiyd 13:e5b22bfbe67b 49 L_LightSide_SW = L_Light_Switch;
muaiyd 13:e5b22bfbe67b 50 R_Indicator_SW = R_Indicator_Switch;
muaiyd 13:e5b22bfbe67b 51 L_Indicator_SW = L_Indicator_Switch;
muaiyd 13:e5b22bfbe67b 52 INPUT_SEM.release();
muaiyd 12:8eb2c1cccee6 53 Speed_SEM.wait();
muaiyd 13:e5b22bfbe67b 54 Speed[Counter] = Measure_Speed();
muaiyd 12:8eb2c1cccee6 55 Speed_SEM.release();
muaiyd 1:b409ad65466a 56 Counter++;
muaiyd 1:b409ad65466a 57 if(Counter > 2) Counter = 0;
muaiyd 1:b409ad65466a 58 Thread::wait(100);
muaiyd 1:b409ad65466a 59 }
muaiyd 1:b409ad65466a 60 }
muaiyd 13:e5b22bfbe67b 61 uint8_t CAR::Measure_Speed(){
muaiyd 12:8eb2c1cccee6 62 return (Accelerometer_Value * MaxSpeed * (1 - Brake_Value) * EngineStat) ;
muaiyd 12:8eb2c1cccee6 63 }
muaiyd 1:b409ad65466a 64
muaiyd 11:7f2414ecb7ee 65 // Average filter the speed every 200 mSec
muaiyd 1:b409ad65466a 66 void CAR::Average_Speed_Measure(void const *args) {
muaiyd 1:b409ad65466a 67 while (true) {
muaiyd 12:8eb2c1cccee6 68 Speed_SEM.wait();
muaiyd 11:7f2414ecb7ee 69 AVR_SPEED_SEM.wait();
muaiyd 1:b409ad65466a 70 Average_Speed = ( Speed[0] + Speed[1] + Speed[2] )/3 ;
muaiyd 11:7f2414ecb7ee 71 AVR_SPEED_SEM.release();
muaiyd 12:8eb2c1cccee6 72 Speed_SEM.release();
muaiyd 1:b409ad65466a 73 Thread::wait(200);
muaiyd 1:b409ad65466a 74 }
muaiyd 1:b409ad65466a 75 }
muaiyd 1:b409ad65466a 76
muaiyd 11:7f2414ecb7ee 77 // Update the servo every 1 Sec with the average speed value
muaiyd 1:b409ad65466a 78 void CAR::Average_Speed_Show(void const *args){
muaiyd 1:b409ad65466a 79 while(1){
muaiyd 11:7f2414ecb7ee 80 AVR_SPEED_SEM.wait();
muaiyd 7:a92da438d06c 81 SpeedShow_Servo = 1.0 - (float)Average_Speed / (float)MaxSpeed ;
muaiyd 11:7f2414ecb7ee 82 AVR_SPEED_SEM.release();
muaiyd 0:68ce46607848 83 Thread::wait(1000);
muaiyd 0:68ce46607848 84 }
muaiyd 1:b409ad65466a 85 }
muaiyd 11:7f2414ecb7ee 86
muaiyd 11:7f2414ecb7ee 87 // Check the average speed if it over 70 MPH every 2Sec
muaiyd 1:b409ad65466a 88 void CAR::OverSpeed(void const *args){
muaiyd 1:b409ad65466a 89 while(true){
muaiyd 11:7f2414ecb7ee 90 AVR_SPEED_SEM.wait();
muaiyd 1:b409ad65466a 91 if(Average_Speed > 70)
muaiyd 1:b409ad65466a 92 IsOverSpeed = 1;
muaiyd 1:b409ad65466a 93
muaiyd 1:b409ad65466a 94 else
muaiyd 1:b409ad65466a 95 IsOverSpeed = 0;
muaiyd 11:7f2414ecb7ee 96 AVR_SPEED_SEM.release();
muaiyd 7:a92da438d06c 97 Thread::wait(2000);
muaiyd 1:b409ad65466a 98 }
muaiyd 1:b409ad65466a 99 }
muaiyd 11:7f2414ecb7ee 100 /* To task in this function becuase boath are repeted every 0.5 Sec
muaiyd 11:7f2414ecb7ee 101 1- Update the ODOmeter
muaiyd 11:7f2414ecb7ee 102 2- Read the indecator swetches */
muaiyd 13:e5b22bfbe67b 103 void CAR::Odo_Show(void const *args){
muaiyd 1:b409ad65466a 104 while(true){
muaiyd 1:b409ad65466a 105 LCD.locate(0,0);
muaiyd 11:7f2414ecb7ee 106 AVR_SPEED_SEM.wait();
muaiyd 7:a92da438d06c 107 Odometer_Value = GET_ODO() + Average_Speed / 7200.0 ;
muaiyd 7:a92da438d06c 108 SAVE_ODO(Odometer_Value);
muaiyd 11:7f2414ecb7ee 109 LCD.printf("Speed %3D MPH",Average_Speed);
muaiyd 1:b409ad65466a 110 LCD.locate(1,0);
muaiyd 11:7f2414ecb7ee 111 LCD.printf("ODO %4.2f M",GET_ODO());
muaiyd 11:7f2414ecb7ee 112 AVR_SPEED_SEM.release();
muaiyd 11:7f2414ecb7ee 113
muaiyd 1:b409ad65466a 114 Thread::wait(500);
muaiyd 1:b409ad65466a 115 }
muaiyd 1:b409ad65466a 116 }
muaiyd 11:7f2414ecb7ee 117
muaiyd 11:7f2414ecb7ee 118 /* Send the values of the Brake, Accelerometer, and Speed to
muaiyd 11:7f2414ecb7ee 119 an mail queue every 5 Sec. */
muaiyd 9:d86a6b8cdfa4 120 void CAR::SEND_CAR_VALUES (void const *args) {
muaiyd 1:b409ad65466a 121 while (true) {
muaiyd 1:b409ad65466a 122 CAR_MAIL *mail = mail_box.alloc();
muaiyd 1:b409ad65466a 123 CAR_MAIL_SEM.wait();
muaiyd 11:7f2414ecb7ee 124
muaiyd 11:7f2414ecb7ee 125 AVR_SPEED_SEM.wait();
muaiyd 11:7f2414ecb7ee 126 mail->Mail_Average_Speed = Average_Speed;
muaiyd 11:7f2414ecb7ee 127 AVR_SPEED_SEM.release();
muaiyd 11:7f2414ecb7ee 128
muaiyd 9:d86a6b8cdfa4 129 INPUT_SEM.wait();
muaiyd 1:b409ad65466a 130 mail->Mail_Accelerometer_Value = Accelerometer_Value;
muaiyd 1:b409ad65466a 131 mail->Mail_Brake_Value = Brake_Value;
muaiyd 13:e5b22bfbe67b 132 INPUT_SEM.release();
muaiyd 13:e5b22bfbe67b 133
muaiyd 1:b409ad65466a 134 mail->Counter = Element_Counter_W ;
muaiyd 1:b409ad65466a 135 mail_box.put(mail);
muaiyd 1:b409ad65466a 136 Element_Counter_W++;
muaiyd 13:e5b22bfbe67b 137
muaiyd 7:a92da438d06c 138 CAR_MAIL_SEM.release();
muaiyd 11:7f2414ecb7ee 139
muaiyd 7:a92da438d06c 140 Thread::wait(5000);
muaiyd 1:b409ad65466a 141 }
muaiyd 1:b409ad65466a 142 }
muaiyd 11:7f2414ecb7ee 143
muaiyd 11:7f2414ecb7ee 144 //Saving the memory pool content on the serial port
muaiyd 1:b409ad65466a 145 void CAR::DUMP_CAR_VALUES_En (void const *args) {
muaiyd 1:b409ad65466a 146 while (true) {
muaiyd 1:b409ad65466a 147 CAR_MAIL_SEM.wait();
muaiyd 1:b409ad65466a 148 while (Element_Counter_W > Element_Counter_R)
muaiyd 11:7f2414ecb7ee 149 DUMP_CAR_VALUES();
muaiyd 11:7f2414ecb7ee 150
muaiyd 1:b409ad65466a 151 CAR_MAIL_SEM.release();
muaiyd 6:5037779f6a55 152 Thread::wait(20000);
muaiyd 1:b409ad65466a 153 }
muaiyd 1:b409ad65466a 154 }
muaiyd 1:b409ad65466a 155 void CAR::DUMP_CAR_VALUES () {
muaiyd 1:b409ad65466a 156 osEvent evt = mail_box.get(10);
muaiyd 1:b409ad65466a 157 CAR_MAIL *mail = (CAR_MAIL*)evt.value.p;
muaiyd 9:d86a6b8cdfa4 158 if (evt.status == osEventMail) {
muaiyd 9:d86a6b8cdfa4 159 FILE *fp = fopen("/local/Car_Values.csv", "a"); // Open "out.txt" on the local file system for writing
muaiyd 9:d86a6b8cdfa4 160 fprintf(fp,"%i ," , mail->Counter);
muaiyd 9:d86a6b8cdfa4 161 fprintf(fp,"%i ,", mail->Mail_Average_Speed);
muaiyd 9:d86a6b8cdfa4 162 fprintf(fp,"%.3f ," , mail->Mail_Accelerometer_Value);
muaiyd 9:d86a6b8cdfa4 163 fprintf(fp,"%.3f ", mail->Mail_Brake_Value);
muaiyd 9:d86a6b8cdfa4 164 fprintf(fp,"\r\n");
muaiyd 9:d86a6b8cdfa4 165 fclose(fp);
muaiyd 1:b409ad65466a 166 mail_box.free(mail);
muaiyd 1:b409ad65466a 167 Element_Counter_R++;
muaiyd 1:b409ad65466a 168 }
muaiyd 7:a92da438d06c 169 }
muaiyd 11:7f2414ecb7ee 170
muaiyd 11:7f2414ecb7ee 171 // Flashing the indecator light
muaiyd 7:a92da438d06c 172 void CAR::Side_Light_Flash(void const *args){
muaiyd 7:a92da438d06c 173 while(true){
muaiyd 13:e5b22bfbe67b 174 INPUT_SEM.wait();
muaiyd 11:7f2414ecb7ee 175 // If both side are enabled
muaiyd 13:e5b22bfbe67b 176 if((L_Indicator_SW == 1) && (R_Indicator_SW == 1) ){
muaiyd 8:6e55db96c11c 177 L_Side_Indicator = L_Side_Indicator ^ 1;
muaiyd 8:6e55db96c11c 178 R_Side_Indicator = L_Side_Indicator;
muaiyd 8:6e55db96c11c 179 }
muaiyd 11:7f2414ecb7ee 180 //If just one side enabled
muaiyd 13:e5b22bfbe67b 181 else if(R_Indicator_SW == 1){
muaiyd 8:6e55db96c11c 182 R_Side_Indicator = R_Side_Indicator ^ 1;
muaiyd 8:6e55db96c11c 183 L_Side_Indicator = 0;
muaiyd 8:6e55db96c11c 184 }
muaiyd 13:e5b22bfbe67b 185 else if(L_Indicator_SW == 1){
muaiyd 8:6e55db96c11c 186 L_Side_Indicator = L_Side_Indicator ^ 1;
muaiyd 8:6e55db96c11c 187 R_Side_Indicator = 0;
muaiyd 8:6e55db96c11c 188 }
muaiyd 11:7f2414ecb7ee 189 //Neither are enabled
muaiyd 8:6e55db96c11c 190 else{
muaiyd 8:6e55db96c11c 191 L_Side_Indicator = 0;
muaiyd 8:6e55db96c11c 192 R_Side_Indicator = 0 ;
muaiyd 8:6e55db96c11c 193 }
muaiyd 13:e5b22bfbe67b 194 INPUT_SEM.release();
muaiyd 13:e5b22bfbe67b 195 Thread::wait(500);
muaiyd 8:6e55db96c11c 196 }
muaiyd 8:6e55db96c11c 197 }
muaiyd 11:7f2414ecb7ee 198 // Check the side light swetches and turn on or off the light
muaiyd 8:6e55db96c11c 199 void CAR::Side_Light(void const *args){
muaiyd 8:6e55db96c11c 200 while(true){
muaiyd 13:e5b22bfbe67b 201 INPUT_SEM.wait();
muaiyd 13:e5b22bfbe67b 202 L_Side_Light = L_LightSide_SW;
muaiyd 13:e5b22bfbe67b 203 R_Side_Light = R_LightSide_SW;
muaiyd 13:e5b22bfbe67b 204 INPUT_SEM.release();
muaiyd 7:a92da438d06c 205 Thread::wait(1000);
muaiyd 7:a92da438d06c 206 }
muaiyd 0:68ce46607848 207 }