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:
Tue May 06 09:49:08 2014 +0000
Revision:
12:8eb2c1cccee6
Parent:
11:7f2414ecb7ee
Child:
13:e5b22bfbe67b
Make all input in the Simulation Task

Who changed what in which revision?

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