![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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
CAR.cpp@12:8eb2c1cccee6, 2014-05-06 (annotated)
- 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?
User | Revision | Line number | New 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 | } |