UCSC Embedded Programming Lab 6

Dependencies:   C12832_lcd LM75B mbed-rtos mbed

Revision:
0:e648668434be
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Mar 07 21:31:52 2014 +0000
@@ -0,0 +1,201 @@
+//****************************************************************************
+//*******************************  prologue  *********************************
+//
+//               University of California Extension, Santa Cruz
+//                    Introduction to Embedded Programming
+//
+// Author: E. Lujan, ...
+// Assignment Number:  6
+// Topic: Queues and Message Pools
+// Project Name: Lab_6
+// Date: March 6, 2014
+//
+// Objectives:
+// a.   A LCD thread that updates the LCD based on information 
+//      received from other threads via IPC
+// b.   Thread POT that reads the pot value in a polling loop every 
+//      10 seconds and sends value to LCD thread via IPC Queue
+// c.   Thread TEMP that read the temperature every 60 seconds and 
+//      sends the value to the LCD task via IPC Queue
+// d.   A SCANF thread that reads in a fortune cookie from user and 
+//      sends it to the LCD task via IPC Memory Pool
+// e.   The LCD thread uses the top 3 lines of the LCD to reflect the 
+//      pot, the temperature, and the cookie. This task must use IPC 
+//      (with timeout) methods to get data from each of the previous 
+//      threads
+// f.   A TOD thread that updates the 4th line of the LCD with time 
+//      of day once a minute. It shares the LCD with the LCD thread 
+//      using mutual exclusion. Note: This is modified to update the 
+//      third line of the LCD as there is no fourth line.
+//
+//****************************************************************************
+// PROGRAM ELEMENTS
+// preprocessor directives
+// function prototypes
+// global definitions
+// comments above the functions
+// comments above each major block of code
+//
+//****************************************************************************
+#include "mbed.h"
+#include "rtos.h"
+#include "C12832_lcd.h"
+#include "LM75B.h"
+
+#define POT 1
+#define TEMP 2
+#define COOKIE 3
+
+// Function prototypes
+void lcd_thread (void const *args);
+void pot_thread (void const *args);
+void temp_thread (void const *args);
+void cookie_thread (void const *args);
+void tod_thread (void const *args);
+
+// Message structure
+typedef struct {
+    float   pot;   
+    float   temperature;  
+    char    cookie[8]; 
+    // Message ID
+    int     index;  
+} message_t;
+
+// Global definitions
+MemoryPool<message_t, 16> mpool;
+Queue<message_t, 16> queue;
+AnalogIn pot(p19);
+C12832_LCD lcd;
+LM75B tmp(p28,p27);
+Mutex lcd_mutex;
+
+// Start threads
+int main (void) {
+    // Clear LCD
+    lcd.cls();
+    // Start threads
+    Thread thread_1(lcd_thread);
+    Thread thread_2(pot_thread);
+    Thread thread_3(temp_thread);
+    Thread thread_4(cookie_thread);
+    Thread thread_5(tod_thread);
+    // Keep running
+    while (true) {
+            Thread::wait(1000);
+    }
+}
+
+// A LCD thread that updates the LCD based on information 
+// received from other threads via IPC
+void lcd_thread (void const *args) {
+    // Local declerations
+    float pot = 0.0;
+    float tmp = 0.0;
+    char *cookie = "";
+    while (true) {
+        // Get message from queue
+        osEvent evt = queue.get();
+        if (evt.status == osEventMessage) {
+            message_t *message = (message_t*)evt.value.p;
+            // Determine which item of the message is received
+            // and only update that item
+            if (message->index == POT) 
+                pot = message->pot;
+            else if (message->index == TEMP)
+                tmp = message->temperature;                
+            else if (message->index == COOKIE)
+                cookie = message->cookie;    
+            // else 
+            //     do not update any values        
+            
+            // Update LCD and use Mutex to protect
+            // access
+            lcd_mutex.lock();
+            lcd.locate(0,3);
+            lcd.printf("Pot: %.2fV Tmp: %.2fF\n\r", pot, tmp);
+            lcd.printf("Cookie: %7s\n\r", cookie);
+            lcd_mutex.unlock();
+            // Free message memory
+            mpool.free(message);
+        }
+    }
+}
+
+// Thread POT that reads the pot value in a polling loop every 
+// 10 seconds and sends value to LCD thread via IPC Queue
+void pot_thread (void const *args) {
+    while (true) {
+        // Get message memory from pool
+        message_t *message = mpool.alloc();
+        // Read potentiometer
+        message->pot = pot; 
+        // Set message ID
+        message->index = POT;
+        // Put message in the queue
+        queue.put(message);
+        // Wait ten seconds
+        Thread::wait(10000);
+    }
+}
+
+// Thread TEMP that read the temperature every 60 seconds and 
+// sends the value to the LCD task via IPC Queue
+void temp_thread (void const *args) {
+    while (true) {
+        // Get message memory from pool
+        message_t *message = mpool.alloc();
+        // Read and convert temperature
+        message->temperature = (9/5) * tmp.read() + 32.0;
+        // Set message ID
+        message->index = TEMP;
+        // Put message in the queue
+        queue.put(message);
+        // Wait one minute
+        Thread::wait(60000);
+    }
+}
+
+// A SCANF thread that reads in a fortune cookie from user and 
+// sends it to the LCD task via IPC Memory Pool
+void cookie_thread (void const *args) {
+    while (true) {
+        // Get message memory from pool
+        message_t *message = mpool.alloc();
+        // Use scanf to get fortune cookie message
+        scanf ("%7s",message->cookie); 
+        message->index = COOKIE;
+        // Put message in the queue
+        queue.put(message);
+        // Wait 100 msec
+        Thread::wait(100);
+    }
+}
+
+// A TOD thread that updates the 3rd line of the LCD with time 
+// of day once a minute. It shares the LCD with the LCD thread 
+// using mutual exclusion 
+void tod_thread (void const *args) {
+    // Declerations
+    char time_str[80];
+    struct tm *time_ptr;
+    time_t lt;
+    
+    // Initialize time and day
+    set_time(1392000000);
+
+    while (true) {
+        // Get time and day
+        lt = time(NULL);
+        time_ptr = localtime(&lt);    
+        strftime(time_str, 100, "%D %R%p", time_ptr);
+        // Update third line of LCD         
+        lcd_mutex.lock();
+        lcd.locate(0,21);  
+        lcd.printf("%s\n", time_str); 
+        lcd_mutex.unlock();
+        // Wait one minute
+        Thread::wait(60000);
+    }
+}
+