UCSC Embedded Programming Lab 6

Dependencies:   C12832_lcd LM75B mbed-rtos mbed

main.cpp

Committer:
subtask
Date:
2014-03-07
Revision:
0:e648668434be

File content as of revision 0:e648668434be:

//****************************************************************************
//*******************************  prologue  *********************************
//
//               University of California Extension, Santa Cruz
//                    Introduction to Embedded Programming
//
// Author: E. Lujan, ...
// Assignment Number:  6
// Topic: Queues and Message Pools
// Project Name: Lab_6
// Date: March 6, 2014
//
// Objectives:
// a.   A LCD thread that updates the LCD based on information 
//      received from other threads via IPC
// b.   Thread POT that reads the pot value in a polling loop every 
//      10 seconds and sends value to LCD thread via IPC Queue
// c.   Thread TEMP that read the temperature every 60 seconds and 
//      sends the value to the LCD task via IPC Queue
// d.   A SCANF thread that reads in a fortune cookie from user and 
//      sends it to the LCD task via IPC Memory Pool
// e.   The LCD thread 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
// f.   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. Note: This is modified to update the 
//      third line of the LCD as there is no fourth line.
//
//****************************************************************************
// PROGRAM ELEMENTS
// preprocessor directives
// function prototypes
// global definitions
// comments above the functions
// comments above each major block of code
//
//****************************************************************************
#include "mbed.h"
#include "rtos.h"
#include "C12832_lcd.h"
#include "LM75B.h"

#define POT 1
#define TEMP 2
#define COOKIE 3

// Function prototypes
void lcd_thread (void const *args);
void pot_thread (void const *args);
void temp_thread (void const *args);
void cookie_thread (void const *args);
void tod_thread (void const *args);

// Message structure
typedef struct {
    float   pot;   
    float   temperature;  
    char    cookie[8]; 
    // Message ID
    int     index;  
} message_t;

// Global definitions
MemoryPool<message_t, 16> mpool;
Queue<message_t, 16> queue;
AnalogIn pot(p19);
C12832_LCD lcd;
LM75B tmp(p28,p27);
Mutex lcd_mutex;

// Start threads
int main (void) {
    // Clear LCD
    lcd.cls();
    // Start threads
    Thread thread_1(lcd_thread);
    Thread thread_2(pot_thread);
    Thread thread_3(temp_thread);
    Thread thread_4(cookie_thread);
    Thread thread_5(tod_thread);
    // Keep running
    while (true) {
            Thread::wait(1000);
    }
}

// A LCD thread that updates the LCD based on information 
// received from other threads via IPC
void lcd_thread (void const *args) {
    // Local declerations
    float pot = 0.0;
    float tmp = 0.0;
    char *cookie = "";
    while (true) {
        // Get message from queue
        osEvent evt = queue.get();
        if (evt.status == osEventMessage) {
            message_t *message = (message_t*)evt.value.p;
            // Determine which item of the message is received
            // and only update that item
            if (message->index == POT) 
                pot = message->pot;
            else if (message->index == TEMP)
                tmp = message->temperature;                
            else if (message->index == COOKIE)
                cookie = message->cookie;    
            // else 
            //     do not update any values        
            
            // Update LCD and use Mutex to protect
            // access
            lcd_mutex.lock();
            lcd.locate(0,3);
            lcd.printf("Pot: %.2fV Tmp: %.2fF\n\r", pot, tmp);
            lcd.printf("Cookie: %7s\n\r", cookie);
            lcd_mutex.unlock();
            // Free message memory
            mpool.free(message);
        }
    }
}

// Thread POT that reads the pot value in a polling loop every 
// 10 seconds and sends value to LCD thread via IPC Queue
void pot_thread (void const *args) {
    while (true) {
        // Get message memory from pool
        message_t *message = mpool.alloc();
        // Read potentiometer
        message->pot = pot; 
        // Set message ID
        message->index = POT;
        // Put message in the queue
        queue.put(message);
        // Wait ten seconds
        Thread::wait(10000);
    }
}

// Thread TEMP that read the temperature every 60 seconds and 
// sends the value to the LCD task via IPC Queue
void temp_thread (void const *args) {
    while (true) {
        // Get message memory from pool
        message_t *message = mpool.alloc();
        // Read and convert temperature
        message->temperature = (9/5) * tmp.read() + 32.0;
        // Set message ID
        message->index = TEMP;
        // Put message in the queue
        queue.put(message);
        // Wait one minute
        Thread::wait(60000);
    }
}

// A SCANF thread that reads in a fortune cookie from user and 
// sends it to the LCD task via IPC Memory Pool
void cookie_thread (void const *args) {
    while (true) {
        // Get message memory from pool
        message_t *message = mpool.alloc();
        // Use scanf to get fortune cookie message
        scanf ("%7s",message->cookie); 
        message->index = COOKIE;
        // Put message in the queue
        queue.put(message);
        // Wait 100 msec
        Thread::wait(100);
    }
}

// A TOD thread that updates the 3rd line of the LCD with time 
// of day once a minute. It shares the LCD with the LCD thread 
// using mutual exclusion 
void tod_thread (void const *args) {
    // Declerations
    char time_str[80];
    struct tm *time_ptr;
    time_t lt;
    
    // Initialize time and day
    set_time(1392000000);

    while (true) {
        // Get time and day
        lt = time(NULL);
        time_ptr = localtime(&lt);    
        strftime(time_str, 100, "%D %R%p", time_ptr);
        // Update third line of LCD         
        lcd_mutex.lock();
        lcd.locate(0,21);  
        lcd.printf("%s\n", time_str); 
        lcd_mutex.unlock();
        // Wait one minute
        Thread::wait(60000);
    }
}