first compiled version

Dependencies:   mbed-rtos mbed C12832_lcd LM75B

main.cpp

Committer:
nleoni
Date:
2014-03-11
Revision:
8:4fcba095bdf0
Parent:
6:45c3ad45a252
Parent:
7:4992146d9872
Child:
9:f40c7c08d1c2

File content as of revision 8:4fcba095bdf0:

//LAB 6: RTOS AND IPC
//WRITTEN BY: ROBERT HARRELL AND NAPOLEON LEONI


//IPC: INTER PROGRAMMER COMMUNICATION....
//Rob I updated the LCD update and read pot thread and they are working
//One key issues was adding timeout for the put and get methods of the queue
//Maybe you can work on the TOD thread and MUTEX (you'll need to add it to the 
//LCD thread and I will finish the scan thread, sounds like Plan?? :-)
//In the end I had to add the memory pool combined with the queue as otherwise
//the queues just keep pointers to data and being that the putting and getting of
//the pot values in the queue is asynchronous you need a buffer to keep the values
//and this is provided by the MemoryPool.

//I also merged your changes with mine.....temproarily commented out the pc.printf meessage for pot read. 3/4/14


#include "mbed.h"
#include "rtos.h"
#include "C12832_lcd.h"
#include "LM75B.h"
#include <string>

//#define _DEBUGMODE  //Uncomment to enter debug mode which prints some diagnostic strings to the terminal
#define BUFFER 17
#define COOKIEQUEUE 30

C12832_LCD lcd;
Serial pc(USBTX, USBRX);   //To differentiate from LCD functions

Mutex lcdMutex;

AnalogIn pot1(p19);
MemoryPool<float, 10> potReadingBuffer;
Queue<float,10> potReadingQueue;

//Temperature Sensor
LM75B      tmp(p28,p27);
Queue<float,10> tempReadingQueue;

MemoryPool<char[BUFFER], COOKIEQUEUE> cookieReadingBuffer;
Queue<char[BUFFER],COOKIEQUEUE> cookieReadingQueue;

DigitalIn   center(p14);    //Initiate RTC clock setup

/******************************************************************
*
*An LCD thread that updates the LCD based on information 
*received from other threads via IPC
*
*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
*
*******************************************************************/
void lcdUpdate(void const*){
while(1){
        osStatus lcdStatus = lcdMutex.lock(1200);
        if(lcdStatus == osOK){
            osEvent evtPot = potReadingQueue.get(1200);
            if (evtPot.status == osEventMessage) {
                float *queuePot = (float*)evtPot.value.p;
                lcd.locate(0,0);
                lcd.printf("Voltage: %.2f V", *queuePot);
                potReadingBuffer.free(queuePot);      
            }
            osEvent evtTemp = tempReadingQueue.get(1200);
            if (evtPot.status == osEventMessage) {
                float *queueTemp = (float*)evtTemp.value.p;
                lcd.locate(0,8);
                lcd.printf("Temp: %.2f F", *queueTemp);      
            }
            osEvent evtCookie = cookieReadingQueue.get(1200);
            if (evtCookie.status == osEventMessage) {
                char (*queueCookie)[BUFFER] = (char (*)[BUFFER])evtCookie.value.p;
                lcd.locate(0,16);
                string str(*queueCookie);
                lcd.printf("F.Cookie: %s", str);    
                cookieReadingBuffer.free(queueCookie);      
            }
        }
        lcdMutex.unlock();
        Thread::wait(1000);
    }
}

/******************************************************************
*
*A POT thread that reads the pot value in a polling loop 
*every 10 seconds and sends value to LCD thread via IPC Queue 
*
*******************************************************************/
void readPOT(void const*){    
while(1){
        float *queue = potReadingBuffer.alloc();
        *queue = pot1; 
        potReadingQueue.put(queue,1200);
        #ifdef _DEBUGMODE
        pc.printf("POT read");
        #endif
        Thread::wait(10000);
    }
    
}

/******************************************************************
*
*A TEMP thread that read the temperature every 60 seconds 
*and sends the value to the LCD task via IPC Queue
*
*******************************************************************/

void readTemp(void const*){
    float temp = 0.0;
    float *temp_ptr;
    
    while(1){
        //pc.printf("TEMP read");
        temp = tmp.read()*9/5+32;
        temp_ptr = &temp;
        tempReadingQueue.put(temp_ptr);
        Thread::wait(5000);
    }
    
}

/******************************************************************
*
*A SCANF thread that reads in a fortune cookie from user 
*and sends it to the LCD task via IPC Memory Pool
*
*******************************************************************/
void readCookie(void const*){
    pc.printf(">Enter your fortune cookie\n>");
    char (*ptrBuffer)[BUFFER] = cookieReadingBuffer.alloc();
    char *ptrChar;
    ptrChar=*ptrBuffer;
    while(1){

        if(pc.readable()){
            *ptrChar=pc.getc();
            pc.putc(*ptrChar);
            if((*ptrChar=='\n') || ((ptrChar-*ptrBuffer)>=(BUFFER-1)) ){
                   if((ptrChar-*ptrBuffer)>=(BUFFER-1)) *++ptrChar='\n';
                   while((ptrChar-*ptrBuffer)<=(BUFFER-1)){
                       *ptrChar++=' ';
                    }
                   *ptrChar='\0';
                   cookieReadingQueue.put(ptrBuffer,500);
                   pc.printf(">Enter your fortune cookie\n>");
                   ptrChar=*ptrBuffer;
            } else {
                ptrChar++;
            }
        }
    Thread::wait(10);
    }  
}


/******************************************************************
*
*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
*
*******************************************************************/
void readTOD(void const*){
    struct tm   dt, *dtp;
    time_t      t;
    char        s[ 30 ];
    dtp = &dt;
    
    while(1){
        osStatus lcdStatus = lcdMutex.lock(1200);
        if(lcdStatus == osOK){
            //pc.printf("TOD updated");
            t       = time( NULL );
            dtp     = localtime( &t );

            strftime( s, 20, "%b %d, %Y", dtp );
            lcd.locate( 70, 0 );
            lcd.printf( "%s", s );
    
            strftime( s, 10, "%H:%M", dtp );
            lcd.locate( 70, 8 );
            lcd.printf( "%s", s );
        }
        lcdMutex.unlock();
        Thread::wait(60000);
    } 
}

//Using a terminal, set the RTC to current date and time
void rtc_setup(void)
{
    // get the current time from the terminal
    struct tm t;
  
    lcd.locate( 0, 0 );
    lcd.printf( "Please set time from serial terminal\n\r" );

    pc.printf("Enter current date and time:\n\r");
    pc.printf("YYYY MM DD HH MM[enter]\n\r");
    pc.scanf("%d %d %d %d %d", &t.tm_year, &t.tm_mon, &t.tm_mday
              , &t.tm_hour, &t.tm_min);

    // adjust for tm structure required values
    t.tm_year = t.tm_year - 1900;
    t.tm_mon = t.tm_mon - 1;

    // set the time
    set_time(mktime(&t));
}

DigitalOut myled(LED1);

int main() {
    //RTC setup if Center Button is held down
    if (center) {  rtc_setup();   }
    lcd.cls();

    Thread threadLCD(lcdUpdate);
    Thread threadPOT(readPOT);
    Thread threadTemp(readTemp);
    Thread threadCookie(readCookie);
    Thread threadTOD(readTOD);

    while(1) {
        Thread::wait(250);       
        
    }
}