chad

Dependencies:   MCP23017 WattBob_TextLCD mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
f_legge
Date:
Mon Mar 26 10:42:42 2018 +0000
Parent:
19:1fecb6fa14a2
Commit message:
chad;

Changed in this revision

SDFileSystem.lib Show diff for this revision Revisions of this file
Servo.lib Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
tasks.cpp Show diff for this revision Revisions of this file
diff -r 1fecb6fa14a2 -r aeb7b7044c31 SDFileSystem.lib
--- a/SDFileSystem.lib	Tue Apr 04 13:47:53 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://developer.mbed.org/teams/mbed/code/SDFileSystem/#8db0d3b02cec
diff -r 1fecb6fa14a2 -r aeb7b7044c31 Servo.lib
--- a/Servo.lib	Tue Apr 04 13:47:53 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://developer.mbed.org/users/simon/code/Servo/#36b69a7ced07
diff -r 1fecb6fa14a2 -r aeb7b7044c31 main.cpp
--- a/main.cpp	Tue Apr 04 13:47:53 2017 +0000
+++ b/main.cpp	Mon Mar 26 10:42:42 2018 +0000
@@ -1,16 +1,41 @@
-// Paramater Allocation
+// Frazer Legge - H001262392
+// Embedded Software - Assignment 3
 // 
+// This program operates a simulation of a car control system.
+// THe simulation is completed through the use of external controls,
+// ignition, sidelights switch, idicator switches, accelerator and 
+// brake pedals. 
+// The simulation calculates Average speed and total distance travelled.
+// The simulation outputs are onboard LEDs to show ignition, sidelights,
+// indicators and overspeed indicator. The system shows the distance 
+// traveled and average speed of the car on the LCD. A USB dump is also 
+// done showing the average speed, accelerator and brake positions.
+
 
-#include "main.h"
+#include "mbed.h"
+#include "rtos.h"
+#include "MCP23017.h"
+#include "WattBob_TextLCD.h"
+
 
-// Pointers to LCD Screen
-MCP23017            *par_port;  // pointer to 16-bit parallel I/O chip
-WattBob_TextLCD     *lcd;       // pointer to 2*16 character LCD object
+// LCD Definition
+#define     BACK_LIGHT_ON(INTERFACE)    INTERFACE->write_bit(1,BL_BIT)
+#define     BACK_LIGHT_OFF(INTERFACE)    INTERFACE->write_bit(0,BL_BIT)
+
+// Car Sim Max/Min speed (mph)
+#define MAX_SPEED 100
+#define MIN_SPEED 0
 
 // Serial Connection
-
 Serial pc(USBTX, USBRX,115200);
 
+// ============================================================================
+// MBED Pin Assignments
+// ============================================================================
+//
+
+// System Inputs
+// ----------------------------------------------------------------------------
 // Analogue Input
 AnalogIn Accel(p15);            // Accelerator Pedal Input
 AnalogIn Brake(p16);            // Brake Pedal Input
@@ -21,35 +46,487 @@
 DigitalIn Indi_L(p13);          // Left indicator switch
 DigitalIn Indi_R(p14);          // Right idicator switch
 
-// Analogue Output
-Servo SpeedIndicator(p21);          // Speed Indicator Servo
+// System Outputs
+// ----------------------------------------------------------------------------
+// PWM Output
+PwmOut SpeedIndicator(p21);     // Speed Indicator Servo
+PwmOut Indi_L_LED(LED3);        // Left Indicator LED
+PwmOut Indi_R_LED(LED4);        // Right Indicator LED
 
 // Digital Output
 DigitalOut Ignit_LED(LED1);     // Ignition LED Indicator
 DigitalOut SideL_LED(LED2);     // Side Light Indicator
-DigitalOut Indi_L_LED(LED3);    // Left Indicator LED
-DigitalOut Indi_R_LED(LED4);    // Right Indicator LED
+DigitalOut OverS_LED(p17);        // Overspeed LED (REDBOX)
+
+// Pointers to LCD Screen
+MCP23017            *par_port;  // pointer to 16-bit parallel I/O chip
+WattBob_TextLCD     *lcd;       // pointer to 2*16 character LCD object
+
+// ============================================================================
+// Data Structure 
+// ============================================================================
+//
+
+// Raw Data Structure
+// ----------------------------------------------------------------------------
+
+// RawData is a global memory section that contains an instance of the raw input
+// data from speedControl.
+
+typedef struct
+{
+    bool EngineState;
+    float RawAccel;
+    float RawBrake;
+} RawData;
+
+// Create MUTEX to contol access to RawData 
+Mutex RawDataMutex;
+
+// Create instance of RawData
+RawData rawData;
+
+// Speed Data Structure
+// ----------------------------------------------------------------------------
+
+// Speed data is a global memory section that contains an instance of the 
+// calculated car speed.  
 
-DigitalOut O_S_LED(p18);        // Overspeed LED (REDBOX)
+typedef struct
+{
+    float rawSpeed[3];
+    int counter;
+} CarSpeedData;
+
+// Create MUTEX to control access to CarSpeedData
+
+Mutex SpeedDataMutex;
+
+// Create insance of CarSpeedData
+CarSpeedData speedData;
 
-/*typedef struct {
+// Filtered Data Structure
+// ----------------------------------------------------------------------------
+typedef struct
+{
+    float AvgSpeed; 
+    float TotalDist;
+} FilteredData;
+
+// Create MUTEX to control access to FilterData
+Mutex filteredDataMutex;
+
+// Create instance of FilteredData
+FilteredData filteredData;
+
+// Mail Queue Structure
+// ----------------------------------------------------------------------------
+
+// PCDump is a global memory section that is populated in Mail_queue. The data 
+// is coppied from the current state of the control system every 5 seconds.
+
+typedef struct 
+{
     float   speed;
     float   accelerator;
     float   brake;
-} mail_t;
+} PCDump;
+
+// Create 100 element Mail Queue
+Mail<PCDump, 100> Memory_dump;
+
+// Counter to track number of elements in mail
+int MailCounter;
+
+// Create MUTEX to control access to MailQueueCounter
+Mutex MailMutex;
+ 
+// ============================================================================
+// Car Simulation
+// ============================================================================ 
+ 
+// The CarSim task updates the rawSpeed float at freq of 20Hz
 
-Mail<mail_t, 100> mail_box;*/
+void CarSim(void const *arg) 
+{ 
+    float NewSpeed;
+    
+    // Deposit global variables to local variables
+    RawDataMutex.lock();
+    bool currentEngineState = rawData.EngineState;
+    float currentAccel = rawData.RawAccel;
+    float currentBrake = rawData.RawBrake;
+    RawDataMutex.unlock();
+    
+    // Calulate current speed as an fraction of the MAX_SPEED based on the 
+    // percentage of accelerator and brake. 
+    // Speed is set to 0 if Engine State is changed to 0;
+    NewSpeed = currentAccel*MAX_SPEED*(1-currentBrake)*currentEngineState;
+    
+    // Check Counter. If outside array set to 0
+    // Data within shared resource therefore MUTEX is used.
+    SpeedDataMutex.lock();
+    
+    if (speedData.counter > 2)
+    {
+        speedData.counter = 0; 
+    }
+    
+    // Output rawSpeed value to next index of rawSpeed. 
+    // Increment counter
+    speedData.rawSpeed[speedData.counter] = NewSpeed;
+    speedData.counter++;
+    SpeedDataMutex.unlock();
+}
+    
+// ============================================================================
+// Controller Tasks
+// ============================================================================    
+
+// Speed Control (Task 1) reads external analog inputs and updates rawData.
+// Operating freq of 10Hz
+
+void SpeedControl(void const *arg) 
+{ 
+    // Deposit global variables to local variables
+    RawDataMutex.lock();
+    rawData.RawAccel = Accel.read();
+    rawData.RawBrake = Brake.read();
+    RawDataMutex.unlock();
+}
+
+// Ignition(Task 2) reads the state of an "ignition switch". 
+// Updates to rawData.
+// Operating freq of 2Hz.
+
+void Ignition(void const *arg) 
+{
+    // Get Switch state and store locally
+    bool currentEngineState = Ignit.read();
+    
+    // Deposit Local data to global under locked state
+    RawDataMutex.lock();
+    rawData.EngineState = currentEngineState;
+    RawDataMutex.unlock();
+    
+    // Logic check on Engine state
+    if (currentEngineState == 1)
+    { 
+        Ignit_LED = 1;
+    }
+    else
+    { 
+        Ignit_LED = 0;
+    }
+}
+
+// Speed_Avg (Task 3) Calculates the average speed of the car over 3 speed 
+// samples.
+// Operation freq of 5Hz
 
+void Speed_Avg(void const *arg) 
+{ 
+    // Init local float as 0
+    float speed_T = 0.0;
+    
+    // Deposit gloabal data to local data under locked state
+    SpeedDataMutex.lock();
+    for (int i = 0; i < 3; i++)
+    { 
+        speed_T = speed_T + speedData.rawSpeed[i];
+    } 
+    SpeedDataMutex.unlock();
+    
+    // Deposit local data to global data under locked state
+    filteredDataMutex.lock();
+    filteredData.AvgSpeed = (speed_T/3);
+    filteredDataMutex.unlock();
+}
+
+// Speed_Indi (Task 4) shows a representation of the car speed through a servo
+// Operation freq of 1Hz
+
+void Speed_Indi(void const *arg) 
+{
+    // Deposit gloabal data to local data under locked state
+    filteredDataMutex.lock();
+    float currentAvgSpeed = filteredData.AvgSpeed;
+    filteredDataMutex.unlock();
+    
+    // Update Servo
+    // Operates between 1000us and 2000us pwm
+    // ie -> 10 * 50(mph) will give middle positioning
+    SpeedIndicator.pulsewidth_us(1000+(10*currentAvgSpeed));
+}
  
-float Accel_Reg;
-float Brake_Reg;
+// OverSpeed (Task 5) illuminates an LED indicator to show that the car is above
+// 70mph.
+// Opperation freq of 0.5Hz
+
+void OverSpeed(void const *arg) 
+{ 
+    // Deposit gloabal data to local data under locked state
+    SpeedDataMutex.lock();
+    float currentSpeed = speedData.rawSpeed[1];
+    SpeedDataMutex.unlock();
+    
+    // Use locally stored current speed to show if car is travelling over 70mph
+    if (currentSpeed > 70.0)
+    {
+        OverS_LED = 1;
+    }
+    else
+    { 
+        OverS_LED = 0;
+    }
+} 
+
+// Display (Taks 6) shows the total distance traveled and the average speed on 
+// the LCD.
+// Operation freq of 2Hz
+
+void Display(void const *arg) 
+{ 
+    // Local distance variable
+    float currentTotalDist;
+    
+    // Deposit gloabal data to local data under locked state
+    filteredDataMutex.lock();
+    float currentAvgSpeed = filteredData.AvgSpeed;
+    float current_TotalDist = filteredData.TotalDist;
+    filteredDataMutex.unlock();
+    
+    // Update distance traveled
+    // Polling every 0.5 seconds therefore convereted from 0.5s to hours
+    // MUTEX not protected as TotalDist is only used for this function 
+    currentTotalDist = current_TotalDist + (currentAvgSpeed*(0.5/3600)); 
+    
+    filteredDataMutex.lock();
+    filteredData.TotalDist = currentTotalDist;
+    filteredDataMutex.unlock();
+    
+    // Output on LCD
+    lcd->locate(0,0);
+    lcd->printf("D: %f",currentTotalDist);
+    lcd->locate(1,0); 
+    lcd->printf("S: %f",currentAvgSpeed);
+}
+
+// Mail_Queue (Task 7) sends gloabal variable to a MAIL structure. 
+// A counter is incremented to track the variables. 
+// Operation freq of 0.2Hz.
+
+void Mail_Queue(void const *arg) 
+{ 
+    // Deposit gloabal data to local data under locked state
+    RawDataMutex.lock();
+    float currentAccel = rawData.RawAccel;
+    float currentBrake = rawData.RawBrake;
+    RawDataMutex.unlock();
+    
+    filteredDataMutex.lock();
+    float currentAvgSpeed = filteredData.AvgSpeed;
+    filteredDataMutex.lock();
 
-float p;
+    // Allocate and populate PCDump Struct
+    PCDump *currentPCDump = Memory_dump.alloc();
+    
+    currentPCDump->brake = currentBrake;
+    currentPCDump->accelerator = currentAccel;
+    currentPCDump->speed = currentAvgSpeed; 
+    
+    // PCDump struct pushed to mail queue
+    Memory_dump.put(currentPCDump);
+    
+    // Lock mail MUTEX and increment counter
+    MailMutex.lock();
+    MailCounter++;
+    MailMutex.unlock();
+} 
+
+// Mail_Print (Task 8) sends the MAIL queue to a terminal over USB serial. 
+// When finished MAIL counter is reset.
+// Operation freq of 0.05Hz.
+
+void Mail_Print(void const *arg) 
+{ 
+    // Deposit gloabal data to local data under locked state
+    MailMutex.lock();
+    int currentMCount = MailCounter;
+    MailMutex.unlock();
+    
+    // Terminal header notifying dump
+    pc.printf("Mail Dump\n\r"); 
+    
+    // Print each record in MAIL queue. MAIL queue is deposited locally then 
+    // values are printed and elements freed in MAIL queue. 
+    for (int i = 0; i < currentMCount; i++)
+    {
+        osEvent evnt = Memory_dump.get();
+        if (evnt.status == osEventMail)
+        {
+            PCDump *currentPCDump = (PCDump*)evnt.value.p;
+            
+            pc.printf("AvgSpeed: %f\n\rAccel: %f\n\rBrake: %f\n\rCounter: %i\n\n\r",currentPCDump->speed,currentPCDump->accelerator,currentPCDump->brake,i);
+            
+            Memory_dump.free(currentPCDump);
+        }
+    }
+    
+    // Reset counter under locked state
+    MailMutex.lock();
+    MailCounter = 0;
+    MailMutex.unlock();
+}
+
+// Side_Light (Task 9) checks the state of the side light and sets the LED
+// indicator
+// Operation freq of 1Hz
+
+void Side_Light(void const *arg) 
+{ 
+    if(SideL == 1)
+    { 
+        SideL_LED = 1;
+    } 
+    else 
+    {
+        SideL_LED = 0;
+    } 
+} 
+
+// Indicator (Task 10) checks the left and right indicator switches.
+// Illuminates either left or right LED accordingly.
+// If both high then LEDs flash in hazard mode.
 
-float Avg_Speed;
-float Speed_In;
-float Speed_0;
-float Speed_1;
-float Speed_2;
+void Indicator(void const *arg) 
+{ 
+    // If Left switch is high then flash left LED at 1Hz
+    if (Indi_L == 1 && Indi_R == 0)
+    { 
+        Indi_L_LED.period(1.0);
+        Indi_L_LED.pulsewidth(0.5);
+        
+        Indi_R_LED.period(1.0);
+        Indi_R_LED.pulsewidth(0.0);
+    }
+    
+    // If Right switch is high then flash right LED at 1Hz
+    else if (Indi_L == 0 && Indi_R == 1)
+    { 
+        Indi_L_LED.period(1.0);
+        Indi_L_LED.pulsewidth(0.0);
+        
+        Indi_R_LED.period(1.0);
+        Indi_R_LED.pulsewidth(0.5);
+    }
+    
+    // If Left & Right switch is high then flash both LEDs at 2Hz
+    else if (Indi_L == 1 && Indi_R == 1)
+    { 
+        Indi_L_LED.period(0.5);
+        Indi_R_LED.period(0.5);
+        Indi_L_LED.pulsewidth(0.25);
+        Indi_R_LED.pulsewidth(0.25);
+    }
+    
+    // If Left & Right switch is low then no flash
+    else if (Indi_L == 0 && Indi_R == 0)
+    { 
+        Indi_L_LED.period(1.0);
+        Indi_L_LED.pulsewidth(0.0);
+        
+        Indi_R_LED.period(1.0);
+        Indi_R_LED.pulsewidth(0.0);
+    }
+}
+
+void ledFlasher(void const *arg)
+{
+    Ignit_LED =! Ignit_LED;
+}
+
 
-float dist;
+// ============================================================================
+// Init System
+// ============================================================================ 
+    
+void Init()
+{
+    // Servo freq set
+    SpeedIndicator.period_ms(50);
+    // Global Variables zeroed
+    rawData.EngineState = 0;
+    rawData.RawAccel = 0.0;
+    rawData.RawBrake = 0.0;
+    speedData.rawSpeed[0] = 0.0;
+    speedData.rawSpeed[1] = 0.0;
+    speedData.rawSpeed[2] = 0.0;
+    speedData.counter = 0;
+    filteredData.AvgSpeed = 0.0;
+    filteredData.TotalDist = 0.0;
+    MailCounter = 0;
+}
+
+// ============================================================================
+// Main Thread
+// ============================================================================
+
+int main()
+{ 
+    par_port = new MCP23017(p9, p10, 0x40); // initialise 16-bit I/O chip
+    par_port->config(0x0F00, 0x0F00, 0x0F00);
+
+    lcd = new WattBob_TextLCD(par_port);    // initialise 2*26 char display
+    par_port->write_bit(1,BL_BIT);          // turn LCD backlight ON
+
+    lcd->cls();                             // clear display
+     
+    Init();                                 // Run init void
+    
+    Ignit_LED = 0; 
+    
+    
+    //while(1)
+    //{
+    //    Ignit_LED =! Ignit_LED;
+    //    wait(1);
+        //Ignit_LED = 0;
+        //wait(1);
+        
+    //}
+    
+    //SideL_LED = 1;
+    
+    RtosTimer ledFlash(ledFlasher, osTimerPeriodic);
+    ledFlash.start(1000);
+    // Timer Objects
+    //RtosTimer Car_Sim(CarSim,osTimerPeriodic);
+    //RtosTimer Task1(SpeedControl,osTimerPeriodic);
+    //RtosTimer Task2(Ignition,osTimerPeriodic);
+    //RtosTimer Task3(Speed_Avg,osTimerPeriodic);
+    //RtosTimer Task4(Speed_Indi,osTimerPeriodic);
+    //RtosTimer Task5(OverSpeed,osTimerPeriodic);
+    //RtosTimer Task6(Display,osTimerPeriodic);
+    //RtosTimer Task7(Mail_Queue,osTimerPeriodic);
+    //RtosTimer Task8(Mail_Print,osTimerPeriodic);
+    //RtosTimer Task9(Side_Light,osTimerPeriodic);
+    //RtosTimer Task10(Indicator,osTimerPeriodic);
+    
+    // Start RTOS Timer objects
+
+    //Car_Sim.start(50);                      // 20Hz
+    //Task1.start(100);                       // 10Hz
+    //Task2.start(500);                       // 2Hz
+    //Task3.start(200);                       // 5Hz
+    //Task4.start(1000);                      // 1Hz
+    //Task5.start(2000);                      // 0.5Hz
+    //Task6.start(500);                       // 2Hz
+    //Task7.start(5000);                      // 0.2Hz
+    //Task8.start(20000);                     // 0.05Hz
+    //Task9.start(1000);                      // 1Hz
+    //Task10.start(2000);                     // 2Hz
+
+    Thread::wait(osWaitForever);            // Forever loop
+       
+}
\ No newline at end of file
diff -r 1fecb6fa14a2 -r aeb7b7044c31 main.h
--- a/main.h	Tue Apr 04 13:47:53 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-#include "mbed.h"
-#include "MCP23017.h"
-#include "WattBob_TextLCD.h"
-#include "rtos.h"
-#include "Servo.h"
-
-#define     BACK_LIGHT_ON(INTERFACE)    INTERFACE->write_bit(1,BL_BIT)
-#define     BACK_LIGHT_OFF(INTERFACE)    INTERFACE->write_bit(0,BL_BIT)
-
-extern  MCP23017            *par_port;  // pointer to 16-bit parallel I/O chip
-extern  WattBob_TextLCD     *lcd;       // pointer to 2*16 character LCD object
-
-extern Serial pc;
-
-// Analogue Input
-extern AnalogIn Accel;            // Accelerator Pedal Input
-extern AnalogIn Brake;            // Brake Pedal Input
-
-// Digital Input
-extern DigitalIn Ignit;           // Engine On/Off
-extern DigitalIn SideL;           // Side Light On/Off
-extern DigitalIn Indi_L;          // Left indicator switch
-extern DigitalIn Indi_R;          // Right idicator switch
-
-// Analogue Output
-extern Servo SpeedIndicator;          // Speed Indicator Servo
-
-// Digital Output
-extern DigitalOut Ignit_LED;     // Ignition LED Indicator
-extern DigitalOut SideL_LED;     // Side Light Indicator
-extern DigitalOut Indi_L_LED;    // Left Indicator LED
-extern DigitalOut Indi_R_LED;    // Right Indicator LED
-
-extern DigitalOut O_S_LED;        // Overspeed LED (REDBOX)
-
-extern float Accel_Reg;
-extern float Brake_Reg;
-
-extern float p;
-
-extern float Avg_Speed;
-extern float Speed_In;
-extern float Speed_0;
-extern float Speed_1;
-extern float Speed_2;
-
-extern float Dist;
-
-
-
diff -r 1fecb6fa14a2 -r aeb7b7044c31 mbed-rtos.lib
--- a/mbed-rtos.lib	Tue Apr 04 13:47:53 2017 +0000
+++ b/mbed-rtos.lib	Mon Mar 26 10:42:42 2018 +0000
@@ -1,1 +1,1 @@
-https://mbed.org/users/mbed_official/code/mbed-rtos/#58563e6cba1e
+https://os.mbed.com/users/f_legge/code/mbed-rtos/#b63b65f13991
diff -r 1fecb6fa14a2 -r aeb7b7044c31 tasks.cpp
--- a/tasks.cpp	Tue Apr 04 13:47:53 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-#include "main.h"
-
-void speedControl(void)
-{
-    Accel_Reg = (Accel * 100);
-    Brake_Reg = (Brake * 100);
-}
-
-
-void ignition(void)
-{
-    Ignit_LED = Ignit;
-}
-
-void Speed_avg(void)
-{
-    Speed_2 = Speed_1;
-    Speed_1 = Speed_0;
-    Speed_0 = Speed_In;
-    
-    Avg_Speed = ((Speed_2 + Speed_1 + Speed_0)/3);
-}
-
-void Speed_Indi(void)
-{
-    p = (Avg_Speed/100);
-    SpeedIndicator = p;
-}
-
-void OverSpeed(void)
-{
-    if (Avg_Speed >= 70)
-        O_S_LED = 1;
-    else
-        O_S_LED = 0;
-}
-
-void Display(void)
-{
-    lcd->locate(0,0);
-    lcd->printf(".2%fmi, .2%fmph", Dist, Avg_Speed);
-}
-
-void Mail_queue(void)
-{
-    mail_t *mail = mail_box.alloc()
-    mail->speed = Avg_Speed;
-    mail->accelerator = Accel_Reg;
-    mail->brake = Brake_Reg;
-}
-
-void Mail_print(void)
-{
-    pc.printf("Speed: %f\r",mail->speed);
-    pc.printf("Accelerator: %f\r",mail->accelerator);
-    pc.printf("Brake: %f\r",mail->brake);
-    mail_box.free(mail);
-}
-
-void side_light(void)
-{
-    SideL_LED = SideL;
-}
-
-void indicator(void)
-{
-    if (Indi_L == 1 && Indi_R == 1)
-    {
-        Indi_L_LED = 1;
-        Indi_R_LED = 1;
-        wait(0.25);
-        Indi_L_LED = 0;
-        Indi_R_LED = 0;
-        wait(0.25); 
-    }
-    else if (Indi_L == 1)
-    {
-        Indi_L_LED != Indi_L_LED; 
-        wait(0.5);
-    }
-    else if (Indi_R == 1)
-    {
-        Indi_R_LED != Indi_R_LED;
-        wait(0.5);
-    }
-}
-
-void car_sim(void)
-{ 
-    Speed_In = Speed_In + ((Accel_Reg - Brake_Reg)*?);
-}
-
-
-
-