UCSC Embedded Programming Lab 6
Dependencies: C12832_lcd LM75B mbed-rtos mbed
main.cpp@0:e648668434be, 2014-03-07 (annotated)
- 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?
User | Revision | Line number | New 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(<); |
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 |