first compiled version
Dependencies: mbed-rtos mbed C12832_lcd LM75B
main.cpp@8:4fcba095bdf0, 2014-03-11 (annotated)
- Committer:
- nleoni
- Date:
- Tue Mar 11 05:40:23 2014 +0000
- Revision:
- 8:4fcba095bdf0
- Parent:
- 6:45c3ad45a252
- Parent:
- 7:4992146d9872
- Child:
- 9:f40c7c08d1c2
Added _DEBUGMODE precompiler definition to easily turn on/off diagnostic strings printed to terminal
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nleoni | 7:4992146d9872 | 1 | //LAB 6: RTOS AND IPC |
nleoni | 7:4992146d9872 | 2 | //WRITTEN BY: ROBERT HARRELL AND NAPOLEON LEONI |
nleoni | 7:4992146d9872 | 3 | |
nleoni | 7:4992146d9872 | 4 | |
nleoni | 7:4992146d9872 | 5 | //IPC: INTER PROGRAMMER COMMUNICATION.... |
nleoni | 3:0945093f48ec | 6 | //Rob I updated the LCD update and read pot thread and they are working |
nleoni | 3:0945093f48ec | 7 | //One key issues was adding timeout for the put and get methods of the queue |
nleoni | 3:0945093f48ec | 8 | //Maybe you can work on the TOD thread and MUTEX (you'll need to add it to the |
nleoni | 3:0945093f48ec | 9 | //LCD thread and I will finish the scan thread, sounds like Plan?? :-) |
nleoni | 3:0945093f48ec | 10 | //In the end I had to add the memory pool combined with the queue as otherwise |
nleoni | 3:0945093f48ec | 11 | //the queues just keep pointers to data and being that the putting and getting of |
nleoni | 3:0945093f48ec | 12 | //the pot values in the queue is asynchronous you need a buffer to keep the values |
nleoni | 3:0945093f48ec | 13 | //and this is provided by the MemoryPool. |
nleoni | 3:0945093f48ec | 14 | |
nleoni | 7:4992146d9872 | 15 | //I also merged your changes with mine.....temproarily commented out the pc.printf meessage for pot read. 3/4/14 |
nleoni | 5:d40a563e2c3b | 16 | |
robertwharrell | 1:83bc9f91d154 | 17 | |
nleoni | 0:7ae4f23f84a3 | 18 | #include "mbed.h" |
nleoni | 0:7ae4f23f84a3 | 19 | #include "rtos.h" |
nleoni | 3:0945093f48ec | 20 | #include "C12832_lcd.h" |
robertwharrell | 6:45c3ad45a252 | 21 | #include "LM75B.h" |
nleoni | 3:0945093f48ec | 22 | #include <string> |
nleoni | 3:0945093f48ec | 23 | |
nleoni | 8:4fcba095bdf0 | 24 | //#define _DEBUGMODE //Uncomment to enter debug mode which prints some diagnostic strings to the terminal |
nleoni | 3:0945093f48ec | 25 | #define BUFFER 17 |
nleoni | 3:0945093f48ec | 26 | #define COOKIEQUEUE 30 |
nleoni | 3:0945093f48ec | 27 | |
nleoni | 3:0945093f48ec | 28 | C12832_LCD lcd; |
nleoni | 5:d40a563e2c3b | 29 | Serial pc(USBTX, USBRX); //To differentiate from LCD functions |
robertwharrell | 2:43cd60e0e32f | 30 | |
robertwharrell | 6:45c3ad45a252 | 31 | Mutex lcdMutex; |
robertwharrell | 6:45c3ad45a252 | 32 | |
nleoni | 0:7ae4f23f84a3 | 33 | AnalogIn pot1(p19); |
nleoni | 3:0945093f48ec | 34 | MemoryPool<float, 10> potReadingBuffer; |
nleoni | 0:7ae4f23f84a3 | 35 | Queue<float,10> potReadingQueue; |
nleoni | 0:7ae4f23f84a3 | 36 | |
robertwharrell | 6:45c3ad45a252 | 37 | //Temperature Sensor |
robertwharrell | 6:45c3ad45a252 | 38 | LM75B tmp(p28,p27); |
robertwharrell | 6:45c3ad45a252 | 39 | Queue<float,10> tempReadingQueue; |
nleoni | 5:d40a563e2c3b | 40 | |
nleoni | 3:0945093f48ec | 41 | MemoryPool<char[BUFFER], COOKIEQUEUE> cookieReadingBuffer; |
nleoni | 3:0945093f48ec | 42 | Queue<char[BUFFER],COOKIEQUEUE> cookieReadingQueue; |
robertwharrell | 2:43cd60e0e32f | 43 | |
robertwharrell | 6:45c3ad45a252 | 44 | DigitalIn center(p14); //Initiate RTC clock setup |
robertwharrell | 6:45c3ad45a252 | 45 | |
robertwharrell | 2:43cd60e0e32f | 46 | /****************************************************************** |
robertwharrell | 2:43cd60e0e32f | 47 | * |
robertwharrell | 2:43cd60e0e32f | 48 | *An LCD thread that updates the LCD based on information |
robertwharrell | 2:43cd60e0e32f | 49 | *received from other threads via IPC |
robertwharrell | 2:43cd60e0e32f | 50 | * |
robertwharrell | 2:43cd60e0e32f | 51 | *Uses the top 3 lines of the LCD to reflect the pot, the |
robertwharrell | 2:43cd60e0e32f | 52 | *temperature, and the cookie. This task must use IPC (with |
robertwharrell | 2:43cd60e0e32f | 53 | *timeout) methods to get data from each of the previous threads |
robertwharrell | 2:43cd60e0e32f | 54 | * |
robertwharrell | 2:43cd60e0e32f | 55 | *******************************************************************/ |
nleoni | 0:7ae4f23f84a3 | 56 | void lcdUpdate(void const*){ |
nleoni | 0:7ae4f23f84a3 | 57 | while(1){ |
robertwharrell | 6:45c3ad45a252 | 58 | osStatus lcdStatus = lcdMutex.lock(1200); |
robertwharrell | 6:45c3ad45a252 | 59 | if(lcdStatus == osOK){ |
robertwharrell | 6:45c3ad45a252 | 60 | osEvent evtPot = potReadingQueue.get(1200); |
robertwharrell | 6:45c3ad45a252 | 61 | if (evtPot.status == osEventMessage) { |
robertwharrell | 6:45c3ad45a252 | 62 | float *queuePot = (float*)evtPot.value.p; |
robertwharrell | 6:45c3ad45a252 | 63 | lcd.locate(0,0); |
robertwharrell | 6:45c3ad45a252 | 64 | lcd.printf("Voltage: %.2f V", *queuePot); |
robertwharrell | 6:45c3ad45a252 | 65 | potReadingBuffer.free(queuePot); |
robertwharrell | 6:45c3ad45a252 | 66 | } |
robertwharrell | 6:45c3ad45a252 | 67 | osEvent evtTemp = tempReadingQueue.get(1200); |
robertwharrell | 6:45c3ad45a252 | 68 | if (evtPot.status == osEventMessage) { |
robertwharrell | 6:45c3ad45a252 | 69 | float *queueTemp = (float*)evtTemp.value.p; |
robertwharrell | 6:45c3ad45a252 | 70 | lcd.locate(0,8); |
robertwharrell | 6:45c3ad45a252 | 71 | lcd.printf("Temp: %.2f F", *queueTemp); |
robertwharrell | 6:45c3ad45a252 | 72 | } |
robertwharrell | 6:45c3ad45a252 | 73 | osEvent evtCookie = cookieReadingQueue.get(1200); |
robertwharrell | 6:45c3ad45a252 | 74 | if (evtCookie.status == osEventMessage) { |
robertwharrell | 6:45c3ad45a252 | 75 | char (*queueCookie)[BUFFER] = (char (*)[BUFFER])evtCookie.value.p; |
robertwharrell | 6:45c3ad45a252 | 76 | lcd.locate(0,16); |
robertwharrell | 6:45c3ad45a252 | 77 | string str(*queueCookie); |
robertwharrell | 6:45c3ad45a252 | 78 | lcd.printf("F.Cookie: %s", str); |
robertwharrell | 6:45c3ad45a252 | 79 | cookieReadingBuffer.free(queueCookie); |
robertwharrell | 6:45c3ad45a252 | 80 | } |
nleoni | 0:7ae4f23f84a3 | 81 | } |
robertwharrell | 6:45c3ad45a252 | 82 | lcdMutex.unlock(); |
nleoni | 3:0945093f48ec | 83 | Thread::wait(1000); |
nleoni | 0:7ae4f23f84a3 | 84 | } |
nleoni | 0:7ae4f23f84a3 | 85 | } |
nleoni | 0:7ae4f23f84a3 | 86 | |
robertwharrell | 2:43cd60e0e32f | 87 | /****************************************************************** |
robertwharrell | 2:43cd60e0e32f | 88 | * |
robertwharrell | 2:43cd60e0e32f | 89 | *A POT thread that reads the pot value in a polling loop |
robertwharrell | 2:43cd60e0e32f | 90 | *every 10 seconds and sends value to LCD thread via IPC Queue |
robertwharrell | 2:43cd60e0e32f | 91 | * |
robertwharrell | 2:43cd60e0e32f | 92 | *******************************************************************/ |
nleoni | 0:7ae4f23f84a3 | 93 | void readPOT(void const*){ |
nleoni | 0:7ae4f23f84a3 | 94 | while(1){ |
nleoni | 3:0945093f48ec | 95 | float *queue = potReadingBuffer.alloc(); |
nleoni | 0:7ae4f23f84a3 | 96 | *queue = pot1; |
nleoni | 3:0945093f48ec | 97 | potReadingQueue.put(queue,1200); |
nleoni | 8:4fcba095bdf0 | 98 | #ifdef _DEBUGMODE |
robertwharrell | 2:43cd60e0e32f | 99 | pc.printf("POT read"); |
nleoni | 8:4fcba095bdf0 | 100 | #endif |
robertwharrell | 2:43cd60e0e32f | 101 | Thread::wait(10000); |
robertwharrell | 2:43cd60e0e32f | 102 | } |
robertwharrell | 2:43cd60e0e32f | 103 | |
robertwharrell | 2:43cd60e0e32f | 104 | } |
robertwharrell | 2:43cd60e0e32f | 105 | |
robertwharrell | 2:43cd60e0e32f | 106 | /****************************************************************** |
robertwharrell | 2:43cd60e0e32f | 107 | * |
robertwharrell | 2:43cd60e0e32f | 108 | *A TEMP thread that read the temperature every 60 seconds |
robertwharrell | 2:43cd60e0e32f | 109 | *and sends the value to the LCD task via IPC Queue |
robertwharrell | 2:43cd60e0e32f | 110 | * |
robertwharrell | 2:43cd60e0e32f | 111 | *******************************************************************/ |
nleoni | 5:d40a563e2c3b | 112 | |
robertwharrell | 2:43cd60e0e32f | 113 | void readTemp(void const*){ |
robertwharrell | 6:45c3ad45a252 | 114 | float temp = 0.0; |
robertwharrell | 6:45c3ad45a252 | 115 | float *temp_ptr; |
robertwharrell | 6:45c3ad45a252 | 116 | |
robertwharrell | 2:43cd60e0e32f | 117 | while(1){ |
nleoni | 5:d40a563e2c3b | 118 | //pc.printf("TEMP read"); |
robertwharrell | 6:45c3ad45a252 | 119 | temp = tmp.read()*9/5+32; |
robertwharrell | 6:45c3ad45a252 | 120 | temp_ptr = &temp; |
robertwharrell | 6:45c3ad45a252 | 121 | tempReadingQueue.put(temp_ptr); |
robertwharrell | 6:45c3ad45a252 | 122 | Thread::wait(5000); |
nleoni | 0:7ae4f23f84a3 | 123 | } |
nleoni | 0:7ae4f23f84a3 | 124 | |
nleoni | 0:7ae4f23f84a3 | 125 | } |
nleoni | 0:7ae4f23f84a3 | 126 | |
robertwharrell | 2:43cd60e0e32f | 127 | /****************************************************************** |
robertwharrell | 2:43cd60e0e32f | 128 | * |
robertwharrell | 2:43cd60e0e32f | 129 | *A SCANF thread that reads in a fortune cookie from user |
robertwharrell | 2:43cd60e0e32f | 130 | *and sends it to the LCD task via IPC Memory Pool |
robertwharrell | 2:43cd60e0e32f | 131 | * |
robertwharrell | 2:43cd60e0e32f | 132 | *******************************************************************/ |
nleoni | 5:d40a563e2c3b | 133 | void readCookie(void const*){ |
nleoni | 5:d40a563e2c3b | 134 | pc.printf(">Enter your fortune cookie\n>"); |
nleoni | 5:d40a563e2c3b | 135 | char (*ptrBuffer)[BUFFER] = cookieReadingBuffer.alloc(); |
nleoni | 5:d40a563e2c3b | 136 | char *ptrChar; |
nleoni | 5:d40a563e2c3b | 137 | ptrChar=*ptrBuffer; |
robertwharrell | 2:43cd60e0e32f | 138 | while(1){ |
nleoni | 5:d40a563e2c3b | 139 | |
nleoni | 3:0945093f48ec | 140 | if(pc.readable()){ |
nleoni | 3:0945093f48ec | 141 | *ptrChar=pc.getc(); |
nleoni | 3:0945093f48ec | 142 | pc.putc(*ptrChar); |
nleoni | 3:0945093f48ec | 143 | if((*ptrChar=='\n') || ((ptrChar-*ptrBuffer)>=(BUFFER-1)) ){ |
nleoni | 3:0945093f48ec | 144 | if((ptrChar-*ptrBuffer)>=(BUFFER-1)) *++ptrChar='\n'; |
nleoni | 3:0945093f48ec | 145 | while((ptrChar-*ptrBuffer)<=(BUFFER-1)){ |
nleoni | 3:0945093f48ec | 146 | *ptrChar++=' '; |
nleoni | 3:0945093f48ec | 147 | } |
nleoni | 3:0945093f48ec | 148 | *ptrChar='\0'; |
nleoni | 3:0945093f48ec | 149 | cookieReadingQueue.put(ptrBuffer,500); |
nleoni | 3:0945093f48ec | 150 | pc.printf(">Enter your fortune cookie\n>"); |
nleoni | 3:0945093f48ec | 151 | ptrChar=*ptrBuffer; |
nleoni | 3:0945093f48ec | 152 | } else { |
nleoni | 3:0945093f48ec | 153 | ptrChar++; |
nleoni | 3:0945093f48ec | 154 | } |
nleoni | 3:0945093f48ec | 155 | } |
nleoni | 3:0945093f48ec | 156 | Thread::wait(10); |
robertwharrell | 2:43cd60e0e32f | 157 | } |
nleoni | 0:7ae4f23f84a3 | 158 | } |
nleoni | 0:7ae4f23f84a3 | 159 | |
robertwharrell | 2:43cd60e0e32f | 160 | |
robertwharrell | 2:43cd60e0e32f | 161 | /****************************************************************** |
robertwharrell | 2:43cd60e0e32f | 162 | * |
robertwharrell | 2:43cd60e0e32f | 163 | *A TOD thread that updates the 4th line of the LCD with time |
robertwharrell | 2:43cd60e0e32f | 164 | *of day once a minute. It shares the LCD with the LCD thread |
robertwharrell | 2:43cd60e0e32f | 165 | *using mutual exclusion |
robertwharrell | 2:43cd60e0e32f | 166 | * |
robertwharrell | 2:43cd60e0e32f | 167 | *******************************************************************/ |
robertwharrell | 6:45c3ad45a252 | 168 | void readTOD(void const*){ |
robertwharrell | 6:45c3ad45a252 | 169 | struct tm dt, *dtp; |
robertwharrell | 6:45c3ad45a252 | 170 | time_t t; |
robertwharrell | 6:45c3ad45a252 | 171 | char s[ 30 ]; |
robertwharrell | 6:45c3ad45a252 | 172 | dtp = &dt; |
robertwharrell | 6:45c3ad45a252 | 173 | |
robertwharrell | 6:45c3ad45a252 | 174 | while(1){ |
robertwharrell | 6:45c3ad45a252 | 175 | osStatus lcdStatus = lcdMutex.lock(1200); |
robertwharrell | 6:45c3ad45a252 | 176 | if(lcdStatus == osOK){ |
robertwharrell | 6:45c3ad45a252 | 177 | //pc.printf("TOD updated"); |
robertwharrell | 6:45c3ad45a252 | 178 | t = time( NULL ); |
robertwharrell | 6:45c3ad45a252 | 179 | dtp = localtime( &t ); |
robertwharrell | 6:45c3ad45a252 | 180 | |
robertwharrell | 6:45c3ad45a252 | 181 | strftime( s, 20, "%b %d, %Y", dtp ); |
robertwharrell | 6:45c3ad45a252 | 182 | lcd.locate( 70, 0 ); |
robertwharrell | 6:45c3ad45a252 | 183 | lcd.printf( "%s", s ); |
robertwharrell | 6:45c3ad45a252 | 184 | |
robertwharrell | 6:45c3ad45a252 | 185 | strftime( s, 10, "%H:%M", dtp ); |
robertwharrell | 6:45c3ad45a252 | 186 | lcd.locate( 70, 8 ); |
robertwharrell | 6:45c3ad45a252 | 187 | lcd.printf( "%s", s ); |
robertwharrell | 6:45c3ad45a252 | 188 | } |
robertwharrell | 6:45c3ad45a252 | 189 | lcdMutex.unlock(); |
robertwharrell | 6:45c3ad45a252 | 190 | Thread::wait(60000); |
robertwharrell | 2:43cd60e0e32f | 191 | } |
nleoni | 0:7ae4f23f84a3 | 192 | } |
nleoni | 0:7ae4f23f84a3 | 193 | |
robertwharrell | 6:45c3ad45a252 | 194 | //Using a terminal, set the RTC to current date and time |
robertwharrell | 6:45c3ad45a252 | 195 | void rtc_setup(void) |
robertwharrell | 6:45c3ad45a252 | 196 | { |
robertwharrell | 6:45c3ad45a252 | 197 | // get the current time from the terminal |
robertwharrell | 6:45c3ad45a252 | 198 | struct tm t; |
robertwharrell | 6:45c3ad45a252 | 199 | |
robertwharrell | 6:45c3ad45a252 | 200 | lcd.locate( 0, 0 ); |
robertwharrell | 6:45c3ad45a252 | 201 | lcd.printf( "Please set time from serial terminal\n\r" ); |
robertwharrell | 6:45c3ad45a252 | 202 | |
robertwharrell | 6:45c3ad45a252 | 203 | pc.printf("Enter current date and time:\n\r"); |
robertwharrell | 6:45c3ad45a252 | 204 | pc.printf("YYYY MM DD HH MM[enter]\n\r"); |
robertwharrell | 6:45c3ad45a252 | 205 | pc.scanf("%d %d %d %d %d", &t.tm_year, &t.tm_mon, &t.tm_mday |
robertwharrell | 6:45c3ad45a252 | 206 | , &t.tm_hour, &t.tm_min); |
robertwharrell | 6:45c3ad45a252 | 207 | |
robertwharrell | 6:45c3ad45a252 | 208 | // adjust for tm structure required values |
robertwharrell | 6:45c3ad45a252 | 209 | t.tm_year = t.tm_year - 1900; |
robertwharrell | 6:45c3ad45a252 | 210 | t.tm_mon = t.tm_mon - 1; |
robertwharrell | 6:45c3ad45a252 | 211 | |
robertwharrell | 6:45c3ad45a252 | 212 | // set the time |
robertwharrell | 6:45c3ad45a252 | 213 | set_time(mktime(&t)); |
robertwharrell | 6:45c3ad45a252 | 214 | } |
robertwharrell | 6:45c3ad45a252 | 215 | |
nleoni | 0:7ae4f23f84a3 | 216 | DigitalOut myled(LED1); |
nleoni | 0:7ae4f23f84a3 | 217 | |
nleoni | 0:7ae4f23f84a3 | 218 | int main() { |
robertwharrell | 6:45c3ad45a252 | 219 | //RTC setup if Center Button is held down |
robertwharrell | 6:45c3ad45a252 | 220 | if (center) { rtc_setup(); } |
robertwharrell | 6:45c3ad45a252 | 221 | lcd.cls(); |
nleoni | 3:0945093f48ec | 222 | |
robertwharrell | 6:45c3ad45a252 | 223 | Thread threadLCD(lcdUpdate); |
robertwharrell | 6:45c3ad45a252 | 224 | Thread threadPOT(readPOT); |
robertwharrell | 6:45c3ad45a252 | 225 | Thread threadTemp(readTemp); |
robertwharrell | 6:45c3ad45a252 | 226 | Thread threadCookie(readCookie); |
robertwharrell | 6:45c3ad45a252 | 227 | Thread threadTOD(readTOD); |
nleoni | 0:7ae4f23f84a3 | 228 | |
nleoni | 0:7ae4f23f84a3 | 229 | while(1) { |
nleoni | 3:0945093f48ec | 230 | Thread::wait(250); |
nleoni | 3:0945093f48ec | 231 | |
nleoni | 0:7ae4f23f84a3 | 232 | } |
nleoni | 0:7ae4f23f84a3 | 233 | } |