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
- Committer:
- muaiyd
- Date:
- 2014-05-07
- Revision:
- 13:e5b22bfbe67b
- Parent:
- 12:8eb2c1cccee6
File content as of revision 13:e5b22bfbe67b:
/*********************************** * CAR.cpp * ************************************/ #include "CAR.h" //Define semaphores to manage accessing the viriables Semaphore CAR_MAIL_SEM(1); Semaphore INPUT_SEM(1); Semaphore Speed_SEM(1); Semaphore AVR_SPEED_SEM(2); /* Two counter the first is counting the number of element that was sended to the MAIL. The another is to count the number of element that dumped to a file */ uint32_t Element_Counter_W = 0; uint32_t Element_Counter_R = 0; // Initialise a mail with 100 element static Mail<CAR_MAIL, 100> mail_box; // Create the local filesystem under the name "local" LocalFileSystem local("local"); CAR::CAR(){ Port.write_bit(1,BL_BIT); // Open "out.txt" on the local file system for writing FILE *fp = fopen("/local/Car_Values.csv", "w"); fprintf(fp, "Counter,Average_Speed,Accelerometer_Value,Brake_Value\r\n"); fclose(fp); } // This two functions are save and read the ODO value in a register // in order to safe it when the mbed restart void CAR::SAVE_ODO(float value) { LPC_RTC->GPREG0 = *((uint32_t*)&value); } float CAR::GET_ODO() { return *((float*)&(LPC_RTC->GPREG0)); } /* Read the accelerometer and brake value every 100 mSec and calculate the speed. Also save them in variabls.The speed is saved in an array of three element so the past three values of speed is saved. */ void CAR::Car_Simulation(void const *args){ while (true) { INPUT_SEM.wait(); Accelerometer_Value = Accelerometer.read(); Brake_Value = Brake.read(); EngineStat = EngineSwitch; R_LightSide_SW = R_Light_Switch; L_LightSide_SW = L_Light_Switch; R_Indicator_SW = R_Indicator_Switch; L_Indicator_SW = L_Indicator_Switch; INPUT_SEM.release(); Speed_SEM.wait(); Speed[Counter] = Measure_Speed(); Speed_SEM.release(); Counter++; if(Counter > 2) Counter = 0; Thread::wait(100); } } uint8_t CAR::Measure_Speed(){ return (Accelerometer_Value * MaxSpeed * (1 - Brake_Value) * EngineStat) ; } // Average filter the speed every 200 mSec void CAR::Average_Speed_Measure(void const *args) { while (true) { Speed_SEM.wait(); AVR_SPEED_SEM.wait(); Average_Speed = ( Speed[0] + Speed[1] + Speed[2] )/3 ; AVR_SPEED_SEM.release(); Speed_SEM.release(); Thread::wait(200); } } // Update the servo every 1 Sec with the average speed value void CAR::Average_Speed_Show(void const *args){ while(1){ AVR_SPEED_SEM.wait(); SpeedShow_Servo = 1.0 - (float)Average_Speed / (float)MaxSpeed ; AVR_SPEED_SEM.release(); Thread::wait(1000); } } // Check the average speed if it over 70 MPH every 2Sec void CAR::OverSpeed(void const *args){ while(true){ AVR_SPEED_SEM.wait(); if(Average_Speed > 70) IsOverSpeed = 1; else IsOverSpeed = 0; AVR_SPEED_SEM.release(); Thread::wait(2000); } } /* To task in this function becuase boath are repeted every 0.5 Sec 1- Update the ODOmeter 2- Read the indecator swetches */ void CAR::Odo_Show(void const *args){ while(true){ LCD.locate(0,0); AVR_SPEED_SEM.wait(); Odometer_Value = GET_ODO() + Average_Speed / 7200.0 ; SAVE_ODO(Odometer_Value); LCD.printf("Speed %3D MPH",Average_Speed); LCD.locate(1,0); LCD.printf("ODO %4.2f M",GET_ODO()); AVR_SPEED_SEM.release(); Thread::wait(500); } } /* Send the values of the Brake, Accelerometer, and Speed to an mail queue every 5 Sec. */ void CAR::SEND_CAR_VALUES (void const *args) { while (true) { CAR_MAIL *mail = mail_box.alloc(); CAR_MAIL_SEM.wait(); AVR_SPEED_SEM.wait(); mail->Mail_Average_Speed = Average_Speed; AVR_SPEED_SEM.release(); INPUT_SEM.wait(); mail->Mail_Accelerometer_Value = Accelerometer_Value; mail->Mail_Brake_Value = Brake_Value; INPUT_SEM.release(); mail->Counter = Element_Counter_W ; mail_box.put(mail); Element_Counter_W++; CAR_MAIL_SEM.release(); Thread::wait(5000); } } //Saving the memory pool content on the serial port void CAR::DUMP_CAR_VALUES_En (void const *args) { while (true) { CAR_MAIL_SEM.wait(); while (Element_Counter_W > Element_Counter_R) DUMP_CAR_VALUES(); CAR_MAIL_SEM.release(); Thread::wait(20000); } } void CAR::DUMP_CAR_VALUES () { osEvent evt = mail_box.get(10); CAR_MAIL *mail = (CAR_MAIL*)evt.value.p; if (evt.status == osEventMail) { FILE *fp = fopen("/local/Car_Values.csv", "a"); // Open "out.txt" on the local file system for writing fprintf(fp,"%i ," , mail->Counter); fprintf(fp,"%i ,", mail->Mail_Average_Speed); fprintf(fp,"%.3f ," , mail->Mail_Accelerometer_Value); fprintf(fp,"%.3f ", mail->Mail_Brake_Value); fprintf(fp,"\r\n"); fclose(fp); mail_box.free(mail); Element_Counter_R++; } } // Flashing the indecator light void CAR::Side_Light_Flash(void const *args){ while(true){ INPUT_SEM.wait(); // If both side are enabled if((L_Indicator_SW == 1) && (R_Indicator_SW == 1) ){ L_Side_Indicator = L_Side_Indicator ^ 1; R_Side_Indicator = L_Side_Indicator; } //If just one side enabled else if(R_Indicator_SW == 1){ R_Side_Indicator = R_Side_Indicator ^ 1; L_Side_Indicator = 0; } else if(L_Indicator_SW == 1){ L_Side_Indicator = L_Side_Indicator ^ 1; R_Side_Indicator = 0; } //Neither are enabled else{ L_Side_Indicator = 0; R_Side_Indicator = 0 ; } INPUT_SEM.release(); Thread::wait(500); } } // Check the side light swetches and turn on or off the light void CAR::Side_Light(void const *args){ while(true){ INPUT_SEM.wait(); L_Side_Light = L_LightSide_SW; R_Side_Light = R_LightSide_SW; INPUT_SEM.release(); Thread::wait(1000); } }