UCSC Embedded Programming Lab 6

Dependencies:   C12832_lcd LM75B mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //****************************************************************************
00002 //*******************************  prologue  *********************************
00003 //
00004 //               University of California Extension, Santa Cruz
00005 //                    Introduction to Embedded Programming
00006 //
00007 // Author: E. Lujan, ...
00008 // Assignment Number:  6
00009 // Topic: Queues and Message Pools
00010 // Project Name: Lab_6
00011 // Date: March 6, 2014
00012 //
00013 // Objectives:
00014 // a.   A LCD thread that updates the LCD based on information 
00015 //      received from other threads via IPC
00016 // b.   Thread POT that reads the pot value in a polling loop every 
00017 //      10 seconds and sends value to LCD thread via IPC Queue
00018 // c.   Thread TEMP that read the temperature every 60 seconds and 
00019 //      sends the value to the LCD task via IPC Queue
00020 // d.   A SCANF thread that reads in a fortune cookie from user and 
00021 //      sends it to the LCD task via IPC Memory Pool
00022 // e.   The LCD thread uses the top 3 lines of the LCD to reflect the 
00023 //      pot, the temperature, and the cookie. This task must use IPC 
00024 //      (with timeout) methods to get data from each of the previous 
00025 //      threads
00026 // f.   A TOD thread that updates the 4th line of the LCD with time 
00027 //      of day once a minute. It shares the LCD with the LCD thread 
00028 //      using mutual exclusion. Note: This is modified to update the 
00029 //      third line of the LCD as there is no fourth line.
00030 //
00031 //****************************************************************************
00032 // PROGRAM ELEMENTS
00033 // preprocessor directives
00034 // function prototypes
00035 // global definitions
00036 // comments above the functions
00037 // comments above each major block of code
00038 //
00039 //****************************************************************************
00040 #include "mbed.h"
00041 #include "rtos.h"
00042 #include "C12832_lcd.h"
00043 #include "LM75B.h"
00044 
00045 #define POT 1
00046 #define TEMP 2
00047 #define COOKIE 3
00048 
00049 // Function prototypes
00050 void lcd_thread (void const *args);
00051 void pot_thread (void const *args);
00052 void temp_thread (void const *args);
00053 void cookie_thread (void const *args);
00054 void tod_thread (void const *args);
00055 
00056 // Message structure
00057 typedef struct {
00058     float   pot;   
00059     float   temperature;  
00060     char    cookie[8]; 
00061     // Message ID
00062     int     index;  
00063 } message_t;
00064 
00065 // Global definitions
00066 MemoryPool<message_t, 16> mpool;
00067 Queue<message_t, 16> queue;
00068 AnalogIn pot(p19);
00069 C12832_LCD lcd;
00070 LM75B tmp(p28,p27);
00071 Mutex lcd_mutex;
00072 
00073 // Start threads
00074 int main (void) {
00075     // Clear LCD
00076     lcd.cls();
00077     // Start threads
00078     Thread thread_1(lcd_thread);
00079     Thread thread_2(pot_thread);
00080     Thread thread_3(temp_thread);
00081     Thread thread_4(cookie_thread);
00082     Thread thread_5(tod_thread);
00083     // Keep running
00084     while (true) {
00085             Thread::wait(1000);
00086     }
00087 }
00088 
00089 // A LCD thread that updates the LCD based on information 
00090 // received from other threads via IPC
00091 void lcd_thread (void const *args) {
00092     // Local declerations
00093     float pot = 0.0;
00094     float tmp = 0.0;
00095     char *cookie = "";
00096     while (true) {
00097         // Get message from queue
00098         osEvent evt = queue.get();
00099         if (evt.status == osEventMessage) {
00100             message_t *message = (message_t*)evt.value.p;
00101             // Determine which item of the message is received
00102             // and only update that item
00103             if (message->index == POT) 
00104                 pot = message->pot;
00105             else if (message->index == TEMP)
00106                 tmp = message->temperature;                
00107             else if (message->index == COOKIE)
00108                 cookie = message->cookie;    
00109             // else 
00110             //     do not update any values        
00111             
00112             // Update LCD and use Mutex to protect
00113             // access
00114             lcd_mutex.lock();
00115             lcd.locate(0,3);
00116             lcd.printf("Pot: %.2fV Tmp: %.2fF\n\r", pot, tmp);
00117             lcd.printf("Cookie: %7s\n\r", cookie);
00118             lcd_mutex.unlock();
00119             // Free message memory
00120             mpool.free(message);
00121         }
00122     }
00123 }
00124 
00125 // Thread POT that reads the pot value in a polling loop every 
00126 // 10 seconds and sends value to LCD thread via IPC Queue
00127 void pot_thread (void const *args) {
00128     while (true) {
00129         // Get message memory from pool
00130         message_t *message = mpool.alloc();
00131         // Read potentiometer
00132         message->pot = pot; 
00133         // Set message ID
00134         message->index = POT;
00135         // Put message in the queue
00136         queue.put(message);
00137         // Wait ten seconds
00138         Thread::wait(10000);
00139     }
00140 }
00141 
00142 // Thread TEMP that read the temperature every 60 seconds and 
00143 // sends the value to the LCD task via IPC Queue
00144 void temp_thread (void const *args) {
00145     while (true) {
00146         // Get message memory from pool
00147         message_t *message = mpool.alloc();
00148         // Read and convert temperature
00149         message->temperature = (9/5) * tmp.read() + 32.0;
00150         // Set message ID
00151         message->index = TEMP;
00152         // Put message in the queue
00153         queue.put(message);
00154         // Wait one minute
00155         Thread::wait(60000);
00156     }
00157 }
00158 
00159 // A SCANF thread that reads in a fortune cookie from user and 
00160 // sends it to the LCD task via IPC Memory Pool
00161 void cookie_thread (void const *args) {
00162     while (true) {
00163         // Get message memory from pool
00164         message_t *message = mpool.alloc();
00165         // Use scanf to get fortune cookie message
00166         scanf ("%7s",message->cookie); 
00167         message->index = COOKIE;
00168         // Put message in the queue
00169         queue.put(message);
00170         // Wait 100 msec
00171         Thread::wait(100);
00172     }
00173 }
00174 
00175 // A TOD thread that updates the 3rd line of the LCD with time 
00176 // of day once a minute. It shares the LCD with the LCD thread 
00177 // using mutual exclusion 
00178 void tod_thread (void const *args) {
00179     // Declerations
00180     char time_str[80];
00181     struct tm *time_ptr;
00182     time_t lt;
00183     
00184     // Initialize time and day
00185     set_time(1392000000);
00186 
00187     while (true) {
00188         // Get time and day
00189         lt = time(NULL);
00190         time_ptr = localtime(&lt);    
00191         strftime(time_str, 100, "%D %R%p", time_ptr);
00192         // Update third line of LCD         
00193         lcd_mutex.lock();
00194         lcd.locate(0,21);  
00195         lcd.printf("%s\n", time_str); 
00196         lcd_mutex.unlock();
00197         // Wait one minute
00198         Thread::wait(60000);
00199     }
00200 }
00201