Display librairy manage 3 LED and a TextLCD (on, off, flash) (print message, clear)

Display.cpp

Committer:
us191
Date:
2013-05-06
Revision:
4:424dd7f7b12c

File content as of revision 4:424dd7f7b12c:

#include "Display.h"


/* Create a Display interface (default : 16X2 screen)
* 
* @param pinGreenLED    greenLED broche
* @param pinRedLED      redLED broche
* @param pinOrangeLED   orangeLED broche
* @param pinLCDrs       LCD Instruction/data control line
* @param pinLCDe        LCD Enable line (clock)
* @param pinLCDd0-d3    LCD Data lines     
*/
Display::Display(PinName pinGreenLED, PinName pinRedLED, PinName pinOrangeLED, PinName pinLCDrs, PinName pinLCDe,
        PinName pinLCDd0, PinName pinLCDd1, PinName pinLCDd2, PinName pinLCDd3) : _greenLED(pinGreenLED), _redLED(pinRedLED), 
        _orangeLED(pinOrangeLED), _lcd(pinLCDrs, pinLCDe, pinLCDd0, pinLCDd1, pinLCDd2, pinLCDd3)
{
    this->clear();
}

/* Create a Display interface
* 
* @param pinGreenLED    greenLED broche
* @param pinRedLED      redLED broche
* @param pinOrangeLED   orangeLED broche
* @param pinLCDrs       LCD Instruction/data control line
* @param pinLCDe        LCD Enable line (clock)
* @param pinLCDd0-d3    LCD Data lines
* @param typeScreen     LCD Sets the panel size/addressing mode (default = LCD16x2)
*/
Display::Display(PinName pinGreenLED, PinName pinRedLED, PinName pinOrangeLED, PinName pinLCDrs, PinName pinLCDe,
        PinName pinLCDd0, PinName pinLCDd1, PinName pinLCDd2, PinName pinLCDd3, TextLCD::LCDType typeScreen) : 
            _greenLED(pinGreenLED), _redLED(pinRedLED), _orangeLED(pinOrangeLED), 
            _lcd(pinLCDrs, pinLCDe, pinLCDd0, pinLCDd1, pinLCDd2, pinLCDd3, typeScreen)
{
    this->clear();
}

/* Destructor
*/
Display::~Display()
{
}

/* print message on LCD screen and change status of green, red and orange LED
* all line except the last line, have to finish by '\n'. Warning : '\n' count like a character
* don't end message by '\n'
*
* @param message            message will be display on screen
* @param statusGreenLED     new status of greenLED (on, off, flash)
* @param statusRedLED       new status of redLED (on, off, flash)
* @param statusOrangeLED    new status of orangeLED (on, off, flash)
*/
void Display::printMessage(string message, choiceStatusLED statusGreenLED, choiceStatusLED statusRedLED, choiceStatusLED statusOrangeLED) {
    // clear LCD screen and shutdown 3 LED
    this->clear();
    
    // change green LED status to statusGreenLED
    this->changeStatusLED(Display::green, statusGreenLED);
    // ...
    this->changeStatusLED(Display::red, statusRedLED);
    this->changeStatusLED(Display::orange, statusOrangeLED);
    
    if (this->checkMessage(message))    
        // print message on LCD screen
        this->_lcd.printf("%s\n", message.c_str());
    else
        this->_lcd.printf("this message can't show rigthly");
}


/* put off 3 LED and clear LCD screen
*/
void Display::clear(void) {
    this->shutdownLED();
    this->cls();
}



/* change led status to statusLED
* use by printMessage()
*
* @param led        the led (green, red, orange)
* @param statusLED  new status (on, off, flash)
*/
void Display::changeStatusLED(choiceLED led, choiceStatusLED statusLED) {
    Led *ptr_led;
    
    // select LED 
    switch (led) {
    case green : ptr_led = &_greenLED;
                break;
    case red : ptr_led = &_redLED;
                break;
    default : ptr_led = &_orangeLED;
                break;
    }
    
    // change this status
    switch (statusLED) {
    case on : ptr_led->on();
                break;
    case flash : ptr_led->flash();
                break;
    default : ptr_led->off();
                break;
    }
}

/* put off 3 LED
* use by clear()
*/
void Display::shutdownLED(void) {
    _greenLED.off(); _redLED.off(); _orangeLED.off();
}

/* clear LCD screen
* use by clear()
*/
void Display::cls(void) {
    _lcd.cls();
}

/* check if this message can be display correctly on LCD screen 
* use by printMessage()
*
* @param message    the message to be verified
* @return 
*        true if message is ok
*        flase else
*/
bool Display::checkMessage(string message) {
    // check message length (don't exceed screen capacity)
    unsigned int screenSize = _lcd.columns() * _lcd.rows();
    if (message.length() > screenSize)
        return false;
    
    // check number of '\n'
    // TextLCD is circular, so if we are on last line, a '\n' we come back on first line
    int nbCRLF = this->calculNbCRLF(message);
    if (nbCRLF >= _lcd.rows())
        return false;
    
    // check all line length (don't exceed column capacity)
    std::vector<std::string> allLine = this->subAllLine(message);
    int lineLength;
    for (unsigned int i = 0; i < allLine.size(); i++) {
        lineLength = allLine[i].length();
        if (lineLength > _lcd.columns())
            return false;
    }
    
    
    return true;
}

/* calcul number of '\n'
* use by checkMessage()
*
* @param message    the message to be analyse
* @return number of '\n'
*/ 
int Display::calculNbCRLF(string message) {
    unsigned int index = 0, nbCRLF = 0;
    
    while ((index = message.find('\n', index)) != std::string::npos) {      // npos is a static member constant of string,
        nbCRLF++;                                                           // defined with a value of -1
        index++;
    }
    
    return nbCRLF;
}

/* return vector of all line message
* use by checkMessage()
*
* @param message    the message to be cut
* @return   a vector which contains a line of the message by entry
*/
vector<string> Display::subAllLine(string message) {
    std::vector<std::string> allLine;
    unsigned int index = 0, indexNext = 0; 
    
    // get next '\n' from last position
    while ((indexNext = message.find('\n', index)) != std::string::npos) {
        // sub new line (with '\n')
        allLine.push_back(message.substr(index, indexNext-index+1));
        // go to next line
        index = indexNext + 1;
    }
    
    // get last line
    allLine.push_back(message.substr(index));
        
    return allLine;
}