UCSC Embedded Programming Lab 6

Dependencies:   C12832_lcd LM75B mbed-rtos mbed

Committer:
subtask
Date:
Fri Mar 07 21:31:52 2014 +0000
Revision:
0:e648668434be
UCSC Embedded Programming Lab 6

Who changed what in which revision?

UserRevisionLine numberNew contents of line
subtask 0:e648668434be 1 //****************************************************************************
subtask 0:e648668434be 2 //******************************* prologue *********************************
subtask 0:e648668434be 3 //
subtask 0:e648668434be 4 // University of California Extension, Santa Cruz
subtask 0:e648668434be 5 // Introduction to Embedded Programming
subtask 0:e648668434be 6 //
subtask 0:e648668434be 7 // Author: E. Lujan, ...
subtask 0:e648668434be 8 // Assignment Number: 6
subtask 0:e648668434be 9 // Topic: Queues and Message Pools
subtask 0:e648668434be 10 // Project Name: Lab_6
subtask 0:e648668434be 11 // Date: March 6, 2014
subtask 0:e648668434be 12 //
subtask 0:e648668434be 13 // Objectives:
subtask 0:e648668434be 14 // a. A LCD thread that updates the LCD based on information
subtask 0:e648668434be 15 // received from other threads via IPC
subtask 0:e648668434be 16 // b. Thread POT that reads the pot value in a polling loop every
subtask 0:e648668434be 17 // 10 seconds and sends value to LCD thread via IPC Queue
subtask 0:e648668434be 18 // c. Thread TEMP that read the temperature every 60 seconds and
subtask 0:e648668434be 19 // sends the value to the LCD task via IPC Queue
subtask 0:e648668434be 20 // d. A SCANF thread that reads in a fortune cookie from user and
subtask 0:e648668434be 21 // sends it to the LCD task via IPC Memory Pool
subtask 0:e648668434be 22 // e. The LCD thread uses the top 3 lines of the LCD to reflect the
subtask 0:e648668434be 23 // pot, the temperature, and the cookie. This task must use IPC
subtask 0:e648668434be 24 // (with timeout) methods to get data from each of the previous
subtask 0:e648668434be 25 // threads
subtask 0:e648668434be 26 // f. A TOD thread that updates the 4th line of the LCD with time
subtask 0:e648668434be 27 // of day once a minute. It shares the LCD with the LCD thread
subtask 0:e648668434be 28 // using mutual exclusion. Note: This is modified to update the
subtask 0:e648668434be 29 // third line of the LCD as there is no fourth line.
subtask 0:e648668434be 30 //
subtask 0:e648668434be 31 //****************************************************************************
subtask 0:e648668434be 32 // PROGRAM ELEMENTS
subtask 0:e648668434be 33 // preprocessor directives
subtask 0:e648668434be 34 // function prototypes
subtask 0:e648668434be 35 // global definitions
subtask 0:e648668434be 36 // comments above the functions
subtask 0:e648668434be 37 // comments above each major block of code
subtask 0:e648668434be 38 //
subtask 0:e648668434be 39 //****************************************************************************
subtask 0:e648668434be 40 #include "mbed.h"
subtask 0:e648668434be 41 #include "rtos.h"
subtask 0:e648668434be 42 #include "C12832_lcd.h"
subtask 0:e648668434be 43 #include "LM75B.h"
subtask 0:e648668434be 44
subtask 0:e648668434be 45 #define POT 1
subtask 0:e648668434be 46 #define TEMP 2
subtask 0:e648668434be 47 #define COOKIE 3
subtask 0:e648668434be 48
subtask 0:e648668434be 49 // Function prototypes
subtask 0:e648668434be 50 void lcd_thread (void const *args);
subtask 0:e648668434be 51 void pot_thread (void const *args);
subtask 0:e648668434be 52 void temp_thread (void const *args);
subtask 0:e648668434be 53 void cookie_thread (void const *args);
subtask 0:e648668434be 54 void tod_thread (void const *args);
subtask 0:e648668434be 55
subtask 0:e648668434be 56 // Message structure
subtask 0:e648668434be 57 typedef struct {
subtask 0:e648668434be 58 float pot;
subtask 0:e648668434be 59 float temperature;
subtask 0:e648668434be 60 char cookie[8];
subtask 0:e648668434be 61 // Message ID
subtask 0:e648668434be 62 int index;
subtask 0:e648668434be 63 } message_t;
subtask 0:e648668434be 64
subtask 0:e648668434be 65 // Global definitions
subtask 0:e648668434be 66 MemoryPool<message_t, 16> mpool;
subtask 0:e648668434be 67 Queue<message_t, 16> queue;
subtask 0:e648668434be 68 AnalogIn pot(p19);
subtask 0:e648668434be 69 C12832_LCD lcd;
subtask 0:e648668434be 70 LM75B tmp(p28,p27);
subtask 0:e648668434be 71 Mutex lcd_mutex;
subtask 0:e648668434be 72
subtask 0:e648668434be 73 // Start threads
subtask 0:e648668434be 74 int main (void) {
subtask 0:e648668434be 75 // Clear LCD
subtask 0:e648668434be 76 lcd.cls();
subtask 0:e648668434be 77 // Start threads
subtask 0:e648668434be 78 Thread thread_1(lcd_thread);
subtask 0:e648668434be 79 Thread thread_2(pot_thread);
subtask 0:e648668434be 80 Thread thread_3(temp_thread);
subtask 0:e648668434be 81 Thread thread_4(cookie_thread);
subtask 0:e648668434be 82 Thread thread_5(tod_thread);
subtask 0:e648668434be 83 // Keep running
subtask 0:e648668434be 84 while (true) {
subtask 0:e648668434be 85 Thread::wait(1000);
subtask 0:e648668434be 86 }
subtask 0:e648668434be 87 }
subtask 0:e648668434be 88
subtask 0:e648668434be 89 // A LCD thread that updates the LCD based on information
subtask 0:e648668434be 90 // received from other threads via IPC
subtask 0:e648668434be 91 void lcd_thread (void const *args) {
subtask 0:e648668434be 92 // Local declerations
subtask 0:e648668434be 93 float pot = 0.0;
subtask 0:e648668434be 94 float tmp = 0.0;
subtask 0:e648668434be 95 char *cookie = "";
subtask 0:e648668434be 96 while (true) {
subtask 0:e648668434be 97 // Get message from queue
subtask 0:e648668434be 98 osEvent evt = queue.get();
subtask 0:e648668434be 99 if (evt.status == osEventMessage) {
subtask 0:e648668434be 100 message_t *message = (message_t*)evt.value.p;
subtask 0:e648668434be 101 // Determine which item of the message is received
subtask 0:e648668434be 102 // and only update that item
subtask 0:e648668434be 103 if (message->index == POT)
subtask 0:e648668434be 104 pot = message->pot;
subtask 0:e648668434be 105 else if (message->index == TEMP)
subtask 0:e648668434be 106 tmp = message->temperature;
subtask 0:e648668434be 107 else if (message->index == COOKIE)
subtask 0:e648668434be 108 cookie = message->cookie;
subtask 0:e648668434be 109 // else
subtask 0:e648668434be 110 // do not update any values
subtask 0:e648668434be 111
subtask 0:e648668434be 112 // Update LCD and use Mutex to protect
subtask 0:e648668434be 113 // access
subtask 0:e648668434be 114 lcd_mutex.lock();
subtask 0:e648668434be 115 lcd.locate(0,3);
subtask 0:e648668434be 116 lcd.printf("Pot: %.2fV Tmp: %.2fF\n\r", pot, tmp);
subtask 0:e648668434be 117 lcd.printf("Cookie: %7s\n\r", cookie);
subtask 0:e648668434be 118 lcd_mutex.unlock();
subtask 0:e648668434be 119 // Free message memory
subtask 0:e648668434be 120 mpool.free(message);
subtask 0:e648668434be 121 }
subtask 0:e648668434be 122 }
subtask 0:e648668434be 123 }
subtask 0:e648668434be 124
subtask 0:e648668434be 125 // Thread POT that reads the pot value in a polling loop every
subtask 0:e648668434be 126 // 10 seconds and sends value to LCD thread via IPC Queue
subtask 0:e648668434be 127 void pot_thread (void const *args) {
subtask 0:e648668434be 128 while (true) {
subtask 0:e648668434be 129 // Get message memory from pool
subtask 0:e648668434be 130 message_t *message = mpool.alloc();
subtask 0:e648668434be 131 // Read potentiometer
subtask 0:e648668434be 132 message->pot = pot;
subtask 0:e648668434be 133 // Set message ID
subtask 0:e648668434be 134 message->index = POT;
subtask 0:e648668434be 135 // Put message in the queue
subtask 0:e648668434be 136 queue.put(message);
subtask 0:e648668434be 137 // Wait ten seconds
subtask 0:e648668434be 138 Thread::wait(10000);
subtask 0:e648668434be 139 }
subtask 0:e648668434be 140 }
subtask 0:e648668434be 141
subtask 0:e648668434be 142 // Thread TEMP that read the temperature every 60 seconds and
subtask 0:e648668434be 143 // sends the value to the LCD task via IPC Queue
subtask 0:e648668434be 144 void temp_thread (void const *args) {
subtask 0:e648668434be 145 while (true) {
subtask 0:e648668434be 146 // Get message memory from pool
subtask 0:e648668434be 147 message_t *message = mpool.alloc();
subtask 0:e648668434be 148 // Read and convert temperature
subtask 0:e648668434be 149 message->temperature = (9/5) * tmp.read() + 32.0;
subtask 0:e648668434be 150 // Set message ID
subtask 0:e648668434be 151 message->index = TEMP;
subtask 0:e648668434be 152 // Put message in the queue
subtask 0:e648668434be 153 queue.put(message);
subtask 0:e648668434be 154 // Wait one minute
subtask 0:e648668434be 155 Thread::wait(60000);
subtask 0:e648668434be 156 }
subtask 0:e648668434be 157 }
subtask 0:e648668434be 158
subtask 0:e648668434be 159 // A SCANF thread that reads in a fortune cookie from user and
subtask 0:e648668434be 160 // sends it to the LCD task via IPC Memory Pool
subtask 0:e648668434be 161 void cookie_thread (void const *args) {
subtask 0:e648668434be 162 while (true) {
subtask 0:e648668434be 163 // Get message memory from pool
subtask 0:e648668434be 164 message_t *message = mpool.alloc();
subtask 0:e648668434be 165 // Use scanf to get fortune cookie message
subtask 0:e648668434be 166 scanf ("%7s",message->cookie);
subtask 0:e648668434be 167 message->index = COOKIE;
subtask 0:e648668434be 168 // Put message in the queue
subtask 0:e648668434be 169 queue.put(message);
subtask 0:e648668434be 170 // Wait 100 msec
subtask 0:e648668434be 171 Thread::wait(100);
subtask 0:e648668434be 172 }
subtask 0:e648668434be 173 }
subtask 0:e648668434be 174
subtask 0:e648668434be 175 // A TOD thread that updates the 3rd line of the LCD with time
subtask 0:e648668434be 176 // of day once a minute. It shares the LCD with the LCD thread
subtask 0:e648668434be 177 // using mutual exclusion
subtask 0:e648668434be 178 void tod_thread (void const *args) {
subtask 0:e648668434be 179 // Declerations
subtask 0:e648668434be 180 char time_str[80];
subtask 0:e648668434be 181 struct tm *time_ptr;
subtask 0:e648668434be 182 time_t lt;
subtask 0:e648668434be 183
subtask 0:e648668434be 184 // Initialize time and day
subtask 0:e648668434be 185 set_time(1392000000);
subtask 0:e648668434be 186
subtask 0:e648668434be 187 while (true) {
subtask 0:e648668434be 188 // Get time and day
subtask 0:e648668434be 189 lt = time(NULL);
subtask 0:e648668434be 190 time_ptr = localtime(&lt);
subtask 0:e648668434be 191 strftime(time_str, 100, "%D %R%p", time_ptr);
subtask 0:e648668434be 192 // Update third line of LCD
subtask 0:e648668434be 193 lcd_mutex.lock();
subtask 0:e648668434be 194 lcd.locate(0,21);
subtask 0:e648668434be 195 lcd.printf("%s\n", time_str);
subtask 0:e648668434be 196 lcd_mutex.unlock();
subtask 0:e648668434be 197 // Wait one minute
subtask 0:e648668434be 198 Thread::wait(60000);
subtask 0:e648668434be 199 }
subtask 0:e648668434be 200 }
subtask 0:e648668434be 201