![](/media/cache/profiles/20ef1c5bb97b3a464dc4d8bb4da18bac.50x50_q85.jpg)
Test application for the LCD4884. It uses the LCD 4884 from SainSmart / DFRobot, the on board accelerometer and RGB LED.
Dependencies: LCD4884 MMA8451Q mbed
This is the first version.
- I want to add support for a smaller font (like 5x6).
- Update the 5 way read and de-bounce.
It was my first try with MBED on the FRDM KL25Z board and LCD shield.
!!!!!
The shield needs to be modified to work correctly. It has the 5V routed to the 5 way switch so it is more than the 3V threshold for the ADC.
!!!!!
Diff: main.cpp
- Revision:
- 0:b06425bd412a
diff -r 000000000000 -r b06425bd412a main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Mar 09 21:07:54 2013 +0000 @@ -0,0 +1,475 @@ +#include "mbed.h" +#include "LCD4884.h" +#include "MMA8451Q.h" + +#define MMA8451_I2C_ADDRESS (0x1d<<1) +#define SERIAL_FREQ 10 + +//keypad debounce parameter +#define DEBOUNCE_MAX 10 +//#define DEBOUNCE_ON 10 +//#define DEBOUNCE_OFF 3 + +#define NUM_KEYS 5 + +#define NUM_MENU_ITEM 6 + +// joystick number +#define LEFT_KEY 0 +#define CENTER_KEY 1 +#define DOWN_KEY 2 +#define RIGHT_KEY 3 +#define UP_KEY 4 + +// menu starting points + +#define MENU_X 4 // 0-83 +#define MENU_Y 0 // 0-5 + +/*------------------------------------------------------------------------------ +; DFrobot bitmap - size 48x24 pixels, black/white image +------------------------------------------------------------------------------*/ +unsigned char demo_bmp[]= + +{ +0x00,0x00,0x10,0x20,0x20,0x60,0xE0,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xF0,0xF0,0xF8,0xF8,0xFC,0xFC,0x3E,0x3E,0x32,0x61,0x00,0x00, +0x00,0x00,0x61,0x32,0x3E,0x3E,0xFC,0xFC,0xF8,0xF8,0xF0,0xF0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xC0,0xE0,0x60,0x20,0x20,0x10,0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x08,0x78,0xF3,0xFB,0xF3,0x1B,0x18,0xE8,0xEC,0xC0,0xC4,0xC0,0xF0,0xE0,0x70,0x73,0xE7,0xFE,0xFE,0xF8,0xFE,0xDE,0x0F,0x0F,0xBF,0xFF,0xEB,0x83,0x06,0x06,0x0F,0x0F,0x1C,0x18,0x20,0x00,0x00, +0x00,0x00,0x20,0x18,0x1C,0x0F,0x0F,0x06,0x06,0x83,0xEB,0xFF,0xBF,0x0F,0x0F,0xDE,0xFE,0xF8,0xFE,0xFE,0xE7,0x73,0x70,0xE0,0xF0,0xC0,0xC4,0xC0,0xEC,0xE8,0x18,0x1B,0xF3,0xFB,0xF3,0x78,0x08,0x00,0x00,0x00,0x00,0x00, + +0x00,0x00,0x02,0x03,0x03,0x03,0x03,0x06,0x06,0x0F,0x1F,0x2E,0x68,0xF3,0xE7,0xEF,0xDF,0x9D,0xBC,0xB8,0xB8,0x9C,0xD8,0xE3,0x7F,0x7F,0xFE,0xF0,0xC7,0x87,0x07,0x07,0xFF,0x7E,0x1C,0xFC,0xFC,0xFC,0xFC,0xFE,0xE0,0xF8, +0xF8,0xE0,0xFE,0xFC,0xFC,0xFC,0xFC,0x1C,0x7E,0xFF,0x07,0x07,0x87,0xC7,0xF0,0xFE,0x7F,0x7F,0xE3,0xD8,0x9C,0xB8,0xB8,0xBC,0x9D,0xDF,0xEF,0xE7,0xF3,0x68,0x2E,0x1F,0x0F,0x06,0x06,0x03,0x03,0x03,0x03,0x02,0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x21,0x39,0x1F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0E,0x0E,0x1E,0x1F,0x3F,0x7F,0xFE,0xFC,0xF9,0xF2,0xFE,0xF8,0xE3,0x8F,0xE7,0xCF,0xC7, +0xC7,0xCF,0xE7,0x8F,0xE3,0xF8,0xFE,0xF2,0xF9,0xFC,0xFE,0x7F,0x3F,0x1F,0x1E,0x0E,0x0E,0x0F,0x0F,0x0F,0x0F,0x0F,0x1F,0x39,0x21,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xDF,0x3F,0x01,0x03,0x07,0x0F,0x1F,0x3F,0xFF,0xFF, +0xFF,0xFF,0x3F,0x1F,0x0F,0x07,0x03,0x01,0x3F,0xDF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +/******************************************************************************/ + + +/*------------------------------------------------------------------------------ +; DFrobot chinese - size 12x12 +------------------------------------------------------------------------------*/ +/*unsigned char DFrobot_chinese[]= +{ + 0x84,0x64,0xFF,0x24,0x44,0xFE,0x02,0x02,0xFF,0x02,0x00,0x00,0x01,0x00,0x07,0x04,0x02,0x01,0x00,0x00,0x07,0x04,0x07,0x00, + 0xA0,0xAF,0xA9,0xE9,0xAF,0x30,0xAF,0xA9,0xF9,0xAF,0xA0,0x00,0x00,0x07,0x04,0x04,0x07,0x00,0x07,0x04,0x04,0x07,0x00,0x00, + 0x00,0x00,0x00,0x80,0x60,0x1F,0x60,0x80,0x00,0x00,0x00,0x00,0x04,0x04,0x02,0x01,0x00,0x00,0x00,0x01,0x02,0x04,0x04,0x00, + 0x22,0x12,0x0A,0xBF,0x6A,0x52,0x4A,0x7F,0xCA,0x12,0x22,0x00,0x04,0x05,0x05,0x04,0x05,0x02,0x02,0x01,0x00,0x00,0x00,0x00, + 0x00,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x03,0x02,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x07,0x04,0x04,0x04,0x04,0x04,0x00, + 0x00,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +};*/ + + +LCD4884 lcd; +AnalogIn JStick(PTB0); +Timeout readJStick; +MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS); + +//DigitalOut TestPin1(PTA13); +//DigitalOut TestPin2(PTD5); +PwmOut r (LED_RED); +PwmOut g (LED_GREEN); +PwmOut b (LED_BLUE); + +PwmOut rgb[3] = {PwmOut(LED_RED), PwmOut(LED_GREEN), PwmOut(LED_BLUE)}; + +//LEFT_KEY, CENTER_KEY, DOWN_KEY, RIGHT_KEY, UP_KEY +float adc_key_val[5] ={ + 0.10, 0.20, 0.40, 0.60, 0.90 }; + +float lcdBrightness = 1; +float JStickReadSpeed = 0.015; +float x, y, z; + +// debounce counters +char button_count[NUM_KEYS]; +// button status - pressed/released +char button_status[NUM_KEYS]; + +// menu definition +char menu_items[NUM_MENU_ITEM][14]={ + "BRIGHTNESS", + "RGB", + "CHAR MAP", + "BITMAP", + "ACCELEROMETER", + "ABOUT" +}; + +void brightness(); +void rgb_led_ctrl(); +void charmap(); +void bitmap(); +void accelerometer(); +void about(); +void init_MENU(void); +void update_adc_key(); +void waitfor_OKkey(); + +void (*menu_funcs[NUM_MENU_ITEM])(void) = { + brightness, + rgb_led_ctrl, + charmap, + bitmap, + accelerometer, + about +}; + +char current_menu_item = 0; +char rgb_menu_item = 0; + +void setup() +{ + + /* reset button arrays */ + for(char i=0; i<NUM_KEYS; i++){ + button_count[i]=0; + button_status[i]=0; + } + + lcd.LCD_init(); + lcd.LCD_clear(); + + /*Setup RGB LED*/ + rgb[0].period_us(100); + for(char i=0; i<3; i++){ + rgb[i] = 1; + } + + /*Menu initialization*/ + init_MENU(); + current_menu_item = 0; + + lcd.backlight(ON);//Turn on the backlight + + readJStick.attach(&update_adc_key, JStickReadSpeed); +} + +unsigned long buttonFlasher = 0; + +/* loop */ + +void loop() +{ + for(char i=0; i<NUM_KEYS; i++){ + if(button_status[i] != 0){ + button_status[i] = 0; // reset button flag + + switch(i){ + case UP_KEY: + // current item to normal display + lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL ); + if(current_menu_item == 0) + current_menu_item = NUM_MENU_ITEM -1; + else + current_menu_item -=1; + // next item to highlight display + lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT ); + break; + + case DOWN_KEY: + // current item to normal display + lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL ); + current_menu_item +=1; + if(current_menu_item >(NUM_MENU_ITEM-1)) current_menu_item = 0; + // next item to highlight display + lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT ); + break; + + /*case LEFT_KEY: + case RIGHT_KEY: + init_MENU(); + current_menu_item = 0; + break;*/ + + case CENTER_KEY: + lcd.LCD_clear(); + lcd.LCD_write_string(36, 5, "OK", MENU_HIGHLIGHT ); + (*menu_funcs[current_menu_item])(); + init_MENU(); + break; + } + } + } +} + +/* menu functions */ + +void init_MENU(void) +{ + lcd.LCD_clear(); + + for (char i=0; i<NUM_MENU_ITEM; i++){ + if(i==current_menu_item) + lcd.LCD_write_string(MENU_X, MENU_Y+i, menu_items[i], MENU_HIGHLIGHT); + else + lcd.LCD_write_string(MENU_X, MENU_Y+i, menu_items[i], MENU_NORMAL); + } +} + +// waiting for center key press +void waitfor_OKkey() +{ + char stay = 1; + + while(stay) + { + for(char i=0; i<NUM_KEYS; i++) + { + if(button_status[i] != 0){ + if(CENTER_KEY == i) + { + stay = 0; + button_status[i] = 0; + } + } + } + } +} + +void brightness() +{ + char redraw = 1; + + lcd.LCD_write_string(14, 1, "LCD", MENU_NORMAL); + + while(1) + { + if(redraw) + { + lcd.LCD_set_XY(12,2); + for(char i=0; i<10; i++) + { + if(i < lcdBrightness * 10) + lcd.LCD_write_char(92, MENU_NORMAL); + else + lcd.LCD_write_char(95, MENU_NORMAL); + } + redraw = 0; + } + + if (button_status[RIGHT_KEY]) + { + button_status[RIGHT_KEY] = 0; + redraw = 1; + if(lcdBrightness < 1) + { + lcdBrightness += 0.1; + lcd.backlight(lcdBrightness); + } + } + if (button_status[LEFT_KEY]) + { + button_status[LEFT_KEY] = 0; + redraw = 1; + if(lcdBrightness > 0) + { + lcdBrightness -= 0.1; + lcd.backlight(lcdBrightness); + } + } + + if (button_status[CENTER_KEY]) + { + button_status[CENTER_KEY] = 0; + break; + } + } +} + +void rgb_led_ctrl() +{ + char redraw = 1; + float temp; + + lcd.LCD_write_string(14, 0, "RGB", MENU_NORMAL); + + while(1) + { + if(redraw) + { + lcd.LCD_write_string(5, 2, "R:", (rgb_menu_item == 0)?MENU_HIGHLIGHT:MENU_NORMAL); + lcd.LCD_write_string(5, 3, "G:", (rgb_menu_item == 1)?MENU_HIGHLIGHT:MENU_NORMAL); + lcd.LCD_write_string(5, 4, "B:", (rgb_menu_item == 2)?MENU_HIGHLIGHT:MENU_NORMAL); + + for(char j=0; j<3; j++) + { + lcd.LCD_set_XY(17,2+j); + temp = rgb[j]; + for(char i=0; i<10; i++) + { + if(i < (1-temp)*10) + lcd.LCD_write_char(92, MENU_NORMAL); + else + lcd.LCD_write_char(32, MENU_NORMAL); + } + } + redraw = 0; + } + + if (button_status[RIGHT_KEY]) + { + button_status[RIGHT_KEY] = 0; + redraw = 1; + temp = rgb[rgb_menu_item]; + if(temp > 0){ + rgb[rgb_menu_item] = temp - 0.1; + } + } + if (button_status[LEFT_KEY]) + { + button_status[LEFT_KEY] = 0; + redraw = 1; + temp = rgb[rgb_menu_item]; + if(temp < 1){ + rgb[rgb_menu_item] = temp + 0.1; + } + } + if (button_status[UP_KEY]) + { + button_status[UP_KEY] = 0; + redraw = 1; + if(rgb_menu_item == 0) + rgb_menu_item = 2; + else + rgb_menu_item--; + } + if (button_status[DOWN_KEY]) + { + button_status[DOWN_KEY] = 0; + redraw = 1; + if(rgb_menu_item == 2) + rgb_menu_item = 0; + else + rgb_menu_item++; + } + + if (button_status[CENTER_KEY]) + { + button_status[CENTER_KEY] = 0; + break; + } + } +} + +void charmap(){ + char i,j; + for(i=0; i<5; i++){ + for(j=0; j<14; j++){ + lcd.LCD_set_XY(j*6,i); + lcd.LCD_write_char(i*14+j+32, MENU_NORMAL); + } + } + waitfor_OKkey(); +} + +void bitmap(){ + lcd.LCD_draw_bmp_pixel(0,0, demo_bmp, 84,40); + //lcd.LCD_write_chinese(6,3, DFrobot_chinese,12,6,0,0); + waitfor_OKkey(); +} + +void accelerometer(){ + while(1) + { + x = abs(acc.getAccX()); + y = abs(acc.getAccY()); + z = abs(acc.getAccZ()); + wait(0.1); + lcd.LCD_set_XY(5,2); + lcd.LCD_write_char(48+int(x),MENU_NORMAL); + lcd.LCD_write_char('.',MENU_NORMAL); + lcd.LCD_write_char(48+int((x-int(x))*10),MENU_NORMAL); + lcd.LCD_set_XY(32,2); + lcd.LCD_write_char(48+int(y),MENU_NORMAL); + lcd.LCD_write_char('.',MENU_NORMAL); + lcd.LCD_write_char(48+int((y-int(y))*10),MENU_NORMAL); + lcd.LCD_set_XY(59,2); + lcd.LCD_write_char(48+int(z),MENU_NORMAL); + lcd.LCD_write_char('.',MENU_NORMAL); + lcd.LCD_write_char(48+int((z-int(z))*10),MENU_NORMAL); + if (button_status[CENTER_KEY]) + { + button_status[CENTER_KEY] = 0; + break; + } + } +} +void about(){ + lcd.LCD_write_string( 0, 1, "LCD4884 Shield", MENU_NORMAL); + lcd.LCD_write_string( 0, 3, "sainsmart.com", MENU_NORMAL); + waitfor_OKkey(); +} + +// which includes DEBOUNCE ON/OFF mechanism, and continuous pressing detection +// Convert ADC value to key number + +char get_key(float input) +{ + char k; + + for (k = 0; k < NUM_KEYS; k++) + { + if (input < adc_key_val[k]) + { + return k; + } + } + if (k >= NUM_KEYS) + k = NUM_KEYS; // No valid key pressed + + return k; +} + +//poor attempt at a debounce mechanism. +void update_adc_key(){ + float adc_key_in; + char key_in; + char i; + +//TestPin2 = HIGH; + + adc_key_in = JStick.read(); + + key_in = get_key(adc_key_in); + for(i=0; i<NUM_KEYS; i++) + { + if(key_in == i) //one key is pressed + { + if(button_count[i] < DEBOUNCE_MAX) button_count[i]++; + if(button_count[i] == DEBOUNCE_MAX){ + button_status[i] = 1; + button_count[i] = 1; + JStickReadSpeed = 0.200; + } + } + else // no button pressed + { + if(button_count[i] > 0) button_count[i]--; + if(button_count[i] == 0){ + button_status[i] = 0; + JStickReadSpeed = 0.015; + } + } + } + + readJStick.attach(&update_adc_key, JStickReadSpeed); + +//TestPin2 = LOW; + +} + +int main(void) +{ + lcd = LCD4884(); + setup(); + while(1) { + //TestPin1 = HIGH; + loop(); + //TestPin1 = LOW; + }; +}