Copy_Assignment3

Dependencies:   mbed MCP23017 WattBob_TextLCD mbed-rtos

Revision:
0:8940db3353d7
diff -r 000000000000 -r 8940db3353d7 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Mar 28 18:51:55 2018 +0000
@@ -0,0 +1,288 @@
+/*******************************************************************************
+
+  filename  ::  main.cpp
+  ======================
+
+ Description
+    Assignment 3 of the B31DG Embedded Software Course.
+    It consists in writing a simple microcontroller based on the MBED RTOS
+    library for the LPC1768 board. The repetitive tasks have been implemented
+    by using RTOS Timers, 4 to be specific. One for the car simulator, one
+    launching tasks whose frequency is either 5 Hz or 10 Hz, one launching
+    tasks whose frequency is either 2 Hz, 1 Hz or 0.5 Hz and the last one
+    is launching tasks running at a frequency of 0.2 Hz and 0.5Hz.
+
+ Version
+    Antoine    V1.3    February 2018
+
+ History
+    v1.2        Wrote documentation     
+    v1.1        Added timers calling tasks multiple of their execution frequency
+    v1.0        First Complete Version (all tasks done and 11 Timers)
+    ...
+    v0.2        Build main structure of program
+    v0.1        Initial Version
+    ........................................................................
+
+ Detailed Description
+    11 tasks were to be performed:
+        - SIMULATOR - 20 Hz
+            Write a simple car simulator which will compute the car speed based
+            on the values of the accelerator (%), the brake (%) and the state
+            of the engine.
+        - TASK 1    - 10 Hz
+            Read the value of 2 analog inputs which correspond to the values of
+            acceleration and brake.
+        - TASK 2    - 2 Hz
+            Read a digital input switch corresponding to the state of the engine
+        - TASK 3    - 5 Hz
+            Filter the speed with an averaging filter.
+        - TASK 4    - 2 Hz
+            Show the use of a brake with a digital output
+        - TASK 5    - 1 Hz
+            Monitor the speed, and if it goes above a given threshold, switch on
+            a digital output
+        - TASK 6    - 2 Hz
+            Display on the screen travelled distance & the last average speed
+        - TASK 7    - 0.2 Hz
+            Send into a MAIL queue object the values of speed, accelerometer and
+            brake. The queue has a size of 100.
+        - TASK 8    - 0.05 Hz
+            Dump the the content of the queue into the serial port.
+        - TASK 9    - 1 Hz
+            Read a digital switch and set a digital output based on its state
+        - TASK 10   - 0.5 Hz
+            Read two switches and set two LEDs according to their state. They
+            blink at 1 Hz if only one of the switch is on, at 2 Hz is they
+            are both on.
+            
+    .........................................................................
+    
+ Personnal Values           None
+    ..............................
+
+ Method
+    I decided not to use global variables between the different functions called
+    by the RTOS timer as a challenge and because it is not safe to use global
+    variables in most of the case because you lose control on the origin of
+    a modification on them.
+    Hence, I declared a structure which is used by the different tasks and
+    contains pointers to every variables, structures or object needed.
+    To make it work, I had to slightly modify the RTOSTimer library and remove
+    the 'const' keyword protecting the given pointer to function calls.
+ 
+    The functions used by for the different task execution are located in the
+    included files "my_tasks" while "my_tools" contains functions called by the 
+    tasks in order to simplify their code.
+    
+    The header "my_stucture" contains 3 small structures:
+        - engineRAWValues which stores the RAW values of the car
+        - carStatistics which stores values about speed and distance
+        - mailStruct which is the structure required by the mail Queue object    
+
+    ..........................................................................
+
+
+
+*******************************************************************************/
+
+
+#include "mbed.h"
+#include "rtos.h"
+#include "my_tools.h"
+#include "my_structures.h"
+#include "my_tasks.h"
+
+#define     BACK_LIGHT_ON(INTERFACE)    INTERFACE->write_bit(ON,BL_BIT)
+#define     BACK_LIGHT_OFF(INTERFACE)   INTERFACE->write_bit(OFF,BL_BIT)
+
+/*******************************************************************************
+ *                            PIN DECLARATION
+ ******************************************************************************/
+#define     ANALOG_INPUT_1              p20
+#define     ANALOG_INPUT_2              p18
+
+#define     DIGITAL_IN_ENGINE           p15
+#define     DIGITAL_IN_SIDE             p16
+#define     DIGITAL_IN_LEFT             p11
+#define     DIGITAL_IN_RIGHT            p14
+
+#define     DIGITAL_OUT_OVERSPEED       p26
+#define     DIGITAL_OUT_BRAKE           p25
+
+using namespace std;
+
+// ===============
+//  System Inputs 
+// ===============
+AnalogIn    ACCELERATOR(ANALOG_INPUT_1);
+AnalogIn    BRAKE(ANALOG_INPUT_2);
+DigitalIn   ENGINE_SWITCH(DIGITAL_IN_ENGINE);
+DigitalIn   SIDE_LIGHT_SWITCH(DIGITAL_IN_SIDE);
+DigitalIn   LEFT_SWITCH(DIGITAL_IN_LEFT);
+DigitalIn   RIGHT_SWITCH(DIGITAL_IN_RIGHT);
+
+// ================
+//  System Outputs
+// ================
+DigitalOut  SIDE_LIGHT_INDICATOR(LED1);
+PwmOut      LEFT_LIGHT(LED2);
+PwmOut      RIGHT_LIGHT(LED3);
+DigitalOut  ENGINE_LIGHT(LED4);
+DigitalOut  OVERSPEED_LIGHT(DIGITAL_OUT_OVERSPEED);
+DigitalOut  BRAKE_LIGHT(DIGITAL_OUT_BRAKE);
+
+/*******************************************************************************
+ *                          FUNCTION PROTOTYPES
+ ******************************************************************************/
+
+/** Initialize the main structure used in the program
+ *
+ *  @param: Set a arguments used to initalize the structure, all pointers
+ */
+void initializeStructure(carStructure           &car, 
+                         engineRAWValues        *rawValues,
+                         carStatistics          *carStat,
+                         Mail<mailStruct,100>   *mailQueue,
+                         Mutex                  *rawMutex, 
+                         Mutex                  *speedMutex,
+                         Mutex                  *mailMutex,
+                         MCP23017               *par_port,
+                         WattBob_TextLCD        *lcd,
+                         Serial                 *pcSerial
+                        );
+
+/*******************************************************************************
+ *                              MAIN FUNCTION
+ ******************************************************************************/
+int main()
+{
+    /****************************
+     *       MAIN SETUP
+     ****************************/
+    // ---------------------------------------------------------------------- //
+    // Screen Variables
+    MCP23017            *par_port;
+    WattBob_TextLCD     *lcd;
+    par_port = new MCP23017(p9, p10, 0x40);     // initialise 16-bit I/O chip
+    lcd      = new WattBob_TextLCD(par_port);   // initialise 2*26 char display
+    
+    // Turn LCD backlight ON
+    par_port->write_bit(ON,BL_BIT);
+    
+    // Init Message on Screen
+    lcd->cls();
+    lcd->locate(0,0);
+    lcd->printf("Init...");
+    wait(0.5);
+    
+    
+    // ---------------------------------------------------------------------- //
+    // USB Connection to PC
+    Serial PCSerial(USBTX,USBRX);
+    // Increase Baud Rate of Serial Connection
+    PCSerial.baud(115200);
+    
+    /****************************
+     *   DECLARE STRUCTURES
+     ****************************/ 
+    // ---------------------------------------------------------------------- //
+    // ENGINE RAW VALUES   
+    Mutex           rawMutex;
+    engineRAWValues rawValues;
+    initRAWValuesStruct(rawValues);
+    // ---------------------------------------------------------------------- //
+    // CAR STATISTICS VALUES
+    vector<float>   speedVec(SIZE_SPEED_VECTOR);
+    Mutex           speedMutex;
+    carStatistics   carStats;
+    initCarStatisticsStruct(carStats, &speedVec);
+
+    // ---------------------------------------------------------------------- //
+    // MAIL QUEUE STRUCTURE
+    Mail<mailStruct,100> mailQueue;
+    Mutex                mailMutex;
+    
+    // ---------------------------------------------------------------------- //
+    // Declare structure to be used by the different task functions
+    carStructure myCar;
+    initializeStructure(myCar, 
+                        &rawValues, &carStats, 
+                        &mailQueue,
+                        &rawMutex, &speedMutex, &mailMutex,
+                        par_port, lcd,
+                        &PCSerial
+                       );
+
+    // ---------------------------------------------------------------------- //
+    // ---------------------------------------------------------------------- //
+    /****************************
+     *   DECLARE RTOS TIMER
+     ****************************/
+    RtosTimer carSimulator(task0_carSim,    osTimerPeriodic, (void *) &myCar);
+    RtosTimer timer_1(timer1, osTimerPeriodic, (void *) &myCar);
+    RtosTimer timer_2(timer2, osTimerPeriodic, (void *) &myCar);
+    RtosTimer timer_3(timer3, osTimerPeriodic, (void *) &myCar);
+    
+
+    /****************************
+    *     START RTOS TIMER
+    ****************************/
+    carSimulator.start(50); // 20Hz
+    timer_1.start(100);     // 10 Hz
+    timer_2.start(500);     // 2 Hz
+    timer_3.start(5000);    // 0.2 Hz
+    
+    // RtosTimer will run forever
+    Thread::wait(osWaitForever);
+
+    return 0;
+}
+
+
+void initializeStructure(carStructure           &car, 
+                         engineRAWValues        *rawValues,
+                         carStatistics          *carStat,
+                         Mail<mailStruct,100>   *mailQueue,
+                         Mutex                  *rawMutex, 
+                         Mutex                  *speedMutex,
+                         Mutex                  *mailMutex,
+                         MCP23017               *par_port,
+                         WattBob_TextLCD        *lcd,
+                         Serial                 *pcSerial
+                        )
+{
+    //  System Inputs 
+    car.p_accelerator         = &ACCELERATOR ;
+    car.p_brake               = &BRAKE ;
+    car.p_engineSwitch        = &ENGINE_SWITCH ;
+    car.p_sideLightSwitch     = &SIDE_LIGHT_SWITCH ;
+    car.p_leftSwitch          = &LEFT_SWITCH ;
+    car.p_rightSwitch         = &RIGHT_SWITCH ;
+    
+    //  System Outputs
+    car.p_sideLightIndicator  = &SIDE_LIGHT_INDICATOR ;
+    car.p_leftLight           = &LEFT_LIGHT ;
+    car.p_rightLight          = &RIGHT_LIGHT ;
+    car.p_engineLight         = &ENGINE_LIGHT ;
+    car.p_overspeedLight      = &OVERSPEED_LIGHT ;
+    car.p_brakeLight          = &BRAKE_LIGHT ;
+    
+    // Values Structure;
+    car.p_rawValues          = rawValues;
+    car.p_carStats           = carStat;
+    car.p_mailQueue          = mailQueue;
+    car.nbElementInQueue     = 0;
+    
+    // Mutex
+    car.p_rawMutex           = rawMutex;
+    car.p_statMutex          = speedMutex;
+    car.p_mailMutex          = mailMutex;
+    
+    // Serial Connection
+    car.p_PC                 = pcSerial;
+    
+    // Screen variables
+    car.p_par_port           = par_port;
+    car.p_lcd                = lcd;
+}
\ No newline at end of file