mBed + timer + keyboard + keypad

Dependencies:   TextLCD keypad mbed

main.cpp

Committer:
jatinsha
Date:
2014-09-28
Revision:
2:0d5060721258
Parent:
1:9b8e060faeab

File content as of revision 2:0d5060721258:

/*
CIS 541 - Embedded Systems for Life Critical Applications
Assignment3
Timer using mBed 1768 + 4x4 keypad

Developers - Jatin Sharma and Samarth Shah

References
1. Timer                    : http://mbed.org/handbook/Timer
2. String format modifiers  : http://www.cdf.toronto.edu/~ajr/209/notes/printf.html
3. Keyboard Input           : http://mbed.org/handbook/SerialPC
4. Interrupt attach         : http://mbed.org/handbook/Serial
5. Enum tutorial            : http://stackoverflow.com/questions/1102542/how-to-define-an-enumerated-type-enum-in-c
6. Keypad interfacing       : http://mbed.org/users/yoonghm/code/keypad/docs/tip/

*/


#include "mbed.h"
#include "TextLCD.h"
#include "Keypad.h"

// RS, E, D4 - D7 for 4 bit mode
#define RS p15
#define E p16
#define D4 p17
#define D5 p18
#define D6 p19
#define D7 p20
#define interval 10

TextLCD lcd(RS, E, D4, D5, D6, D7, TextLCD::LCD16x2);
Timer timerDisplay, timerReference;
Serial pc(USBTX, USBRX); // tx, rx


int miliSeconds, centiSeconds, seconds, minutes;
int currentReferenceTime, previousReferenceTime;
int calculatedTimeInterval, referenceTimeInterval, runningError;
char keyboardInput;
int32_t Index = -1; // keypad state

typedef enum {Running, Paused, Reset} state_t;
state_t timerState = Reset;

// Define your own keypad values
// Define your own keypad values
 char Keytable[] = { '1', '2', '3', 'A',   // r0
                      '4', '5', '6', 'B',   // r1
                      '7', '8', '9', 'C',   // r2
                      '*', '0', '#', 'D'    // r3
                    };
                   // c0   c1   c2   c3
 
 
uint32_t cbAfterInput(uint32_t _index)
{
    Index = _index;
    
    if (Index > -1) 
    {
        //lcd.locate(0,1);
        //lcd.printf("Key:%c", Keytable[Index]);
        
        
        if(Keytable[Index] == '*') 
        {
                if(timerState == Reset)
                {
                    timerReference.start();
                    timerDisplay.start();
                    timerState = Running;
                }
                else if(timerState == Paused)
                {
                    timerReference.start();
                    timerDisplay.start();
                    timerState = Running;
                }
        }
        if(Keytable[Index] == '0') 
        {
            if(timerState == Running)
            {
                timerReference.stop();
                timerDisplay.stop();
                timerState = Paused;
            }
            
        } 
        if(Keytable[Index] == '#') 
        
        {  
            if(timerState == Paused)
            {
                // Reset timer
                timerReference.reset();
                timerDisplay.reset();
                timerState = Reset;
                
                // Reset variables
                miliSeconds = seconds = minutes = 0;
                currentReferenceTime = previousReferenceTime = 0;
                calculatedTimeInterval = referenceTimeInterval = runningError = 0;
                lcd.locate(0,0);
                lcd.printf("00:00:00");
                //lcd.locate(0,1);
                //lcd.printf("000000");
            }
        }
         
        Index = -1;
    }
    
    return 0;
}
 
void callback() 
{
    // Keyboard input : you need to actually read from the serial to clear the RX interrupt
    if(keyboardInput = pc.getc())
    {
        if((keyboardInput == 's' || keyboardInput == 'S')) 
        {
            if(timerState == Reset)
            {
                timerReference.start();
                timerDisplay.start();
                timerState = Running;
            }
            else if(timerState == Paused)
            {
                timerReference.start();
                timerDisplay.start();
                timerState = Running;
            }
        }
        if((keyboardInput == 'p' || keyboardInput == 'P')) 
        {
            if(timerState == Running)
            {
                timerReference.stop();
                timerDisplay.stop();
                timerState = Paused;
            }
            
        } 
        if((keyboardInput == 'r' || keyboardInput == 'R')) 
        {  
            if(timerState == Paused)
            {
                // Reset timer
                timerReference.reset();
                timerDisplay.reset();
                timerState = Reset;
                
                // Reset variables
                miliSeconds = seconds = minutes = 0;
                currentReferenceTime = previousReferenceTime = 0;
                calculatedTimeInterval = referenceTimeInterval = runningError = 0;
                lcd.locate(0,0);
                lcd.printf("00:00:00");
                //lcd.locate(0,1);
                //lcd.printf("000000");
            }
        } 
    }
} 
 
int main() 
{
    // interrupt service routine
    pc.attach(&callback);
               // r0   r1   r2   r3   c0   c1   c2   c3
    Keypad keypad(p21, p22, p23, p24, p25, p26, p27, p28);
    keypad.attach(&cbAfterInput);
    keypad.start();  // energize the columns c0-c3 of the keypad
    
    // local variable
    miliSeconds = seconds = minutes = 0;
    currentReferenceTime = previousReferenceTime = 0;
    calculatedTimeInterval = referenceTimeInterval = runningError = 0;
    //timerReference.start();
    //timerDisplay.start();
    
    // Initial display work
    lcd.locate(0,0);
    lcd.printf("00:00:00");
    
    while(1)
    {
        if( timerDisplay.read_ms() >= interval)
        {
            timerDisplay.reset();
            
            // Calculate display variables
            miliSeconds += interval;
    
            centiSeconds += (miliSeconds / 10);
            miliSeconds %= 10;
    
            seconds += (centiSeconds / 100);
            centiSeconds %= 100;
    
            minutes += (seconds / 60);
            seconds %= 60;
            
            // Error correction using referenceClock
            currentReferenceTime = timerReference.read_us();
            referenceTimeInterval = currentReferenceTime - previousReferenceTime;
            runningError += (referenceTimeInterval - interval*1000);

            //miliSeconds += runningError;
            previousReferenceTime = currentReferenceTime;
                
            
            // Display time on LCD
            lcd.locate(0,0);
            lcd.printf("%02d:%02d:%02d",minutes, seconds, centiSeconds);
            
            //lcd.locate(0,1);
            //lcd.printf("%06d", runningError);
            }
            
            
            
        

    }
    
}