Example of how to use an Ada Fruit RGB LCD with the Ada Fruit RGB LCD Shield Library

Dependencies:   AdaFruit_RGBLCDShield MCP23017 mbed RTclock

Dependents:   SX1276_GPS

Fork of MCP_test by Wim Huiskamp

Updated the Adafruit RGB LCD Shield test app with a module system.

It pulls in RTclock which is another library I did for controlling the DS1307 RTC in a sane way (marries stdlib time and the RTC together cleanly). You don't need an RTC to run the example, it'll just use stdlib time instead. This class also maps RTC to system time, so if you loose the RTC the mbed will free run.

Four modules are defined in the modules folder plus the module base class. These examples provide:

  • title menu item
  • time menu item (updates automatically)
  • date menu item
  • fake temp menu item

Press select to switch modes: menu->cursor->change

Menu switches menu items going up/down. Cursor allows you to move around editable fields using the cursor keys / marker. Change allows you to move left/right on a particular line and change values by using up/down on an item with the blink box.

Custom fonts are defined for UI arrows and degree character.

If you want a menu item to update over time then you need to implement the canRefresh() member function in any child module you derive from class Module. Make it return true to receive update requests in your show() member function. Date and time both check when refreshing to see if anything has changed, then update.

main() registers a table of modules with the MenuManager. Others can be added easily by creating children derived from the Module base class..

Depending on what you want to do you may need to adjust the loop wait time in MenuManager::loop(). If you don't balance this based on work you need to do then the key presses may get a little lively. I may adjust the key checking to be fixed to 200ms regardless of loop wait time, however the catch there is that you'll consume more power the more loops you do so the wait is still important.

Happy coding!

Committer:
vtraveller
Date:
Thu Oct 09 10:21:03 2014 +0000
Revision:
27:b6c3dd9a1d8c
Parent:
25:24654d08a99a
Child:
28:fbcd3bac0cd7
Updated key detection for uneditable modules.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vtraveller 25:24654d08a99a 1 #include "mbed.h"
vtraveller 25:24654d08a99a 2 #include "lcd2004.h"
vtraveller 25:24654d08a99a 3
vtraveller 25:24654d08a99a 4 // commands
vtraveller 25:24654d08a99a 5 #define LCD_CLEARDISPLAY 0x01
vtraveller 25:24654d08a99a 6 #define LCD_RETURNHOME 0x02
vtraveller 25:24654d08a99a 7 #define LCD_ENTRYMODESET 0x04
vtraveller 25:24654d08a99a 8 #define LCD_DISPLAYCONTROL 0x08
vtraveller 25:24654d08a99a 9 #define LCD_CURSORSHIFT 0x10
vtraveller 25:24654d08a99a 10 #define LCD_FUNCTIONSET 0x20
vtraveller 25:24654d08a99a 11 #define LCD_SETCGRAMADDR 0x40
vtraveller 25:24654d08a99a 12 #define LCD_SETDDRAMADDR 0x80
vtraveller 25:24654d08a99a 13
vtraveller 25:24654d08a99a 14 // flags for display entry mode
vtraveller 25:24654d08a99a 15 #define LCD_ENTRYRIGHT 0x00
vtraveller 25:24654d08a99a 16 #define LCD_ENTRYLEFT 0x02
vtraveller 25:24654d08a99a 17 #define LCD_ENTRYSHIFTINCREMENT 0x01
vtraveller 25:24654d08a99a 18 #define LCD_ENTRYSHIFTDECREMENT 0x00
vtraveller 25:24654d08a99a 19
vtraveller 25:24654d08a99a 20 // flags for display on/off control
vtraveller 25:24654d08a99a 21 #define LCD_DISPLAY 0x04
vtraveller 25:24654d08a99a 22 #define LCD_CURSOR 0x02
vtraveller 25:24654d08a99a 23 #define LCD_BLINK 0x01
vtraveller 25:24654d08a99a 24
vtraveller 25:24654d08a99a 25 // flags for display/cursor shift
vtraveller 25:24654d08a99a 26 #define LCD_DISPLAYMOVE 0x08
vtraveller 25:24654d08a99a 27 #define LCD_CURSORMOVE 0x00
vtraveller 25:24654d08a99a 28 #define LCD_MOVERIGHT 0x04
vtraveller 25:24654d08a99a 29 #define LCD_MOVELEFT 0x00
vtraveller 25:24654d08a99a 30
vtraveller 25:24654d08a99a 31 #define ADDR 0x4E
vtraveller 25:24654d08a99a 32 #define PIN_E 1<<2
vtraveller 25:24654d08a99a 33 #define PIN_RW 1<<1
vtraveller 25:24654d08a99a 34 #define PIN_RS 1<<0
vtraveller 25:24654d08a99a 35 #define PIN_D4 1<<4
vtraveller 25:24654d08a99a 36 #define PIN_D5 1<<5
vtraveller 25:24654d08a99a 37 #define PIN_D6 1<<6
vtraveller 25:24654d08a99a 38 #define PIN_D7 1<<7
vtraveller 25:24654d08a99a 39 #define PIN_BL 1<<3
vtraveller 25:24654d08a99a 40
vtraveller 25:24654d08a99a 41 const uint8_t k_aMapper[] =
vtraveller 25:24654d08a99a 42 {
vtraveller 25:24654d08a99a 43 PIN_D4,
vtraveller 25:24654d08a99a 44 PIN_D5,
vtraveller 25:24654d08a99a 45 PIN_D6,
vtraveller 25:24654d08a99a 46 PIN_D7,
vtraveller 25:24654d08a99a 47 };
vtraveller 25:24654d08a99a 48
vtraveller 25:24654d08a99a 49 LCD2004::LCD2004(I2C & in_cI2C)
vtraveller 25:24654d08a99a 50 : LCD(in_cI2C)
vtraveller 25:24654d08a99a 51 , m_nDisplayControl(LCD_DISPLAY)
vtraveller 25:24654d08a99a 52 {
vtraveller 25:24654d08a99a 53 ::wait_ms(100);
vtraveller 25:24654d08a99a 54 write_reg(PIN_D5 | PIN_D4);
vtraveller 25:24654d08a99a 55 ::wait_ms(5);
vtraveller 25:24654d08a99a 56 write_reg(PIN_D5 | PIN_D4);
vtraveller 25:24654d08a99a 57 ::wait_us(100);
vtraveller 25:24654d08a99a 58 write_reg(PIN_D5 | PIN_D4);
vtraveller 25:24654d08a99a 59
vtraveller 25:24654d08a99a 60 // IV
vtraveller 25:24654d08a99a 61 write_reg(PIN_D5);
vtraveller 25:24654d08a99a 62 write_reg(PIN_D5);
vtraveller 25:24654d08a99a 63 write_reg(PIN_D7);
vtraveller 25:24654d08a99a 64 write_reg(0);
vtraveller 25:24654d08a99a 65 write_reg(PIN_D7);
vtraveller 25:24654d08a99a 66 write_reg(0);
vtraveller 25:24654d08a99a 67 write_reg(PIN_D4);
vtraveller 25:24654d08a99a 68 write_reg(0);
vtraveller 25:24654d08a99a 69 write_reg(PIN_D7 | PIN_D6 /* | PIN_D5 | PIN_D4 */); // D5 = cursor on D4 = BLINK
vtraveller 25:24654d08a99a 70 }
vtraveller 25:24654d08a99a 71
vtraveller 25:24654d08a99a 72 int LCD2004::_putc(int in_nValue)
vtraveller 25:24654d08a99a 73 {
vtraveller 25:24654d08a99a 74 write_data(PIN_RS, in_nValue);
vtraveller 25:24654d08a99a 75 return 0;
vtraveller 25:24654d08a99a 76 }
vtraveller 25:24654d08a99a 77
vtraveller 25:24654d08a99a 78 void LCD2004::clear()
vtraveller 25:24654d08a99a 79 {
vtraveller 25:24654d08a99a 80 write_data(0, LCD_CLEARDISPLAY);
vtraveller 25:24654d08a99a 81 }
vtraveller 25:24654d08a99a 82
vtraveller 25:24654d08a99a 83 uint8_t LCD2004::columns()
vtraveller 25:24654d08a99a 84 {
vtraveller 25:24654d08a99a 85 return 20;
vtraveller 25:24654d08a99a 86 }
vtraveller 25:24654d08a99a 87
vtraveller 25:24654d08a99a 88 void LCD2004::createChar(uint8_t location, uint8_t charmap[])
vtraveller 25:24654d08a99a 89 {
vtraveller 25:24654d08a99a 90 location &= 0x7; // we only have 8 locations 0-7
vtraveller 25:24654d08a99a 91 write_data(0, LCD_SETCGRAMADDR | (location << 3));
vtraveller 25:24654d08a99a 92
vtraveller 25:24654d08a99a 93 for (int i=0; i<8; i++)
vtraveller 25:24654d08a99a 94 {
vtraveller 25:24654d08a99a 95 _putc(charmap[i]);
vtraveller 25:24654d08a99a 96 }
vtraveller 25:24654d08a99a 97
vtraveller 25:24654d08a99a 98 write_data(0, LCD_SETDDRAMADDR); // unfortunately resets the location to 0,0
vtraveller 25:24654d08a99a 99 }
vtraveller 25:24654d08a99a 100
vtraveller 25:24654d08a99a 101 void LCD2004::home()
vtraveller 25:24654d08a99a 102 {
vtraveller 25:24654d08a99a 103 write_data(0, LCD_RETURNHOME);
vtraveller 25:24654d08a99a 104 }
vtraveller 25:24654d08a99a 105
vtraveller 25:24654d08a99a 106 uint8_t LCD2004::read_reg(void)
vtraveller 25:24654d08a99a 107 {
vtraveller 25:24654d08a99a 108 char nData = PIN_RW | PIN_BL;
vtraveller 25:24654d08a99a 109 m_cI2C.write(ADDR,&nData,1);
vtraveller 25:24654d08a99a 110
vtraveller 25:24654d08a99a 111 nData = PIN_RW | PIN_BL | PIN_E;
vtraveller 25:24654d08a99a 112 m_cI2C.write(ADDR,&nData,1);
vtraveller 25:24654d08a99a 113
vtraveller 25:24654d08a99a 114 char nValue = 0;
vtraveller 25:24654d08a99a 115 m_cI2C.read(ADDR,&nValue,1);
vtraveller 25:24654d08a99a 116
vtraveller 25:24654d08a99a 117 nData = PIN_RW | PIN_BL;
vtraveller 25:24654d08a99a 118 m_cI2C.write(ADDR,&nData,1);
vtraveller 25:24654d08a99a 119
vtraveller 25:24654d08a99a 120 return nValue;
vtraveller 25:24654d08a99a 121 }
vtraveller 25:24654d08a99a 122
vtraveller 25:24654d08a99a 123 uint8_t LCD2004::remap(uint8_t in_nValue)
vtraveller 25:24654d08a99a 124 {
vtraveller 25:24654d08a99a 125 uint8_t nValue = 0;
vtraveller 25:24654d08a99a 126 for (size_t i = 0; i < 4; i++)
vtraveller 25:24654d08a99a 127 {
vtraveller 25:24654d08a99a 128 if (in_nValue & (1 << i)) nValue |= k_aMapper[i];
vtraveller 25:24654d08a99a 129 }
vtraveller 25:24654d08a99a 130
vtraveller 25:24654d08a99a 131 return nValue;
vtraveller 25:24654d08a99a 132 }
vtraveller 25:24654d08a99a 133
vtraveller 25:24654d08a99a 134 uint8_t LCD2004::rows()
vtraveller 25:24654d08a99a 135 {
vtraveller 25:24654d08a99a 136 return 4;
vtraveller 25:24654d08a99a 137 }
vtraveller 25:24654d08a99a 138
vtraveller 25:24654d08a99a 139 void LCD2004::setCursor(uint8_t in_nX, uint8_t in_nY)
vtraveller 25:24654d08a99a 140 {
vtraveller 25:24654d08a99a 141 int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
vtraveller 25:24654d08a99a 142
vtraveller 25:24654d08a99a 143 // D7 = Set DDRAM address
vtraveller 25:24654d08a99a 144 uint8_t nValue = LCD_SETDDRAMADDR | (in_nX + row_offsets[in_nY]);
vtraveller 25:24654d08a99a 145 write_data(0, nValue);
vtraveller 25:24654d08a99a 146 }
vtraveller 25:24654d08a99a 147
vtraveller 25:24654d08a99a 148 void LCD2004::setDisplayControl(uint8_t in_nReg, bool in_bEnable)
vtraveller 25:24654d08a99a 149 {
vtraveller 27:b6c3dd9a1d8c 150 uint8_t nDisplayControl = m_nDisplayControl;
vtraveller 27:b6c3dd9a1d8c 151
vtraveller 25:24654d08a99a 152 if (in_bEnable)
vtraveller 25:24654d08a99a 153 {
vtraveller 25:24654d08a99a 154 m_nDisplayControl |= in_nReg;
vtraveller 25:24654d08a99a 155 }
vtraveller 25:24654d08a99a 156 else
vtraveller 25:24654d08a99a 157 {
vtraveller 25:24654d08a99a 158 m_nDisplayControl &= ~in_nReg;
vtraveller 25:24654d08a99a 159 }
vtraveller 27:b6c3dd9a1d8c 160
vtraveller 27:b6c3dd9a1d8c 161 if (nDisplayControl != m_nDisplayControl)
vtraveller 27:b6c3dd9a1d8c 162 {
vtraveller 27:b6c3dd9a1d8c 163 write_data(0,LCD_DISPLAYCONTROL | m_nDisplayControl);
vtraveller 27:b6c3dd9a1d8c 164 }
vtraveller 25:24654d08a99a 165 }
vtraveller 25:24654d08a99a 166
vtraveller 25:24654d08a99a 167 void LCD2004::showBlink(bool in_bShow)
vtraveller 25:24654d08a99a 168 {
vtraveller 25:24654d08a99a 169 setDisplayControl(LCD_BLINK,in_bShow);
vtraveller 25:24654d08a99a 170 }
vtraveller 25:24654d08a99a 171
vtraveller 25:24654d08a99a 172 void LCD2004::showCursor(bool in_bShow)
vtraveller 25:24654d08a99a 173 {
vtraveller 25:24654d08a99a 174 setDisplayControl(LCD_CURSOR, in_bShow);
vtraveller 25:24654d08a99a 175 }
vtraveller 25:24654d08a99a 176
vtraveller 25:24654d08a99a 177 void LCD2004::showDisplay(bool in_bShow)
vtraveller 25:24654d08a99a 178 {
vtraveller 25:24654d08a99a 179 setDisplayControl(LCD_DISPLAY,in_bShow);
vtraveller 25:24654d08a99a 180 }
vtraveller 25:24654d08a99a 181
vtraveller 25:24654d08a99a 182 void LCD2004::write_data(uint8_t in_nReg, uint8_t in_nValue)
vtraveller 25:24654d08a99a 183 {
vtraveller 25:24654d08a99a 184 write_reg(in_nReg | remap(in_nValue >> 4));
vtraveller 25:24654d08a99a 185 write_reg(in_nReg | remap(in_nValue & 0x0F));
vtraveller 25:24654d08a99a 186 }
vtraveller 25:24654d08a99a 187
vtraveller 25:24654d08a99a 188 void LCD2004::write_reg(uint8_t in_nValue)
vtraveller 25:24654d08a99a 189 {
vtraveller 25:24654d08a99a 190 char nData = PIN_E | PIN_BL | in_nValue;
vtraveller 25:24654d08a99a 191 m_cI2C.write(ADDR,&nData,1);
vtraveller 25:24654d08a99a 192
vtraveller 25:24654d08a99a 193 ::wait_ms(2);
vtraveller 25:24654d08a99a 194 //while (read_reg() & PIN_D7) ::wait_ms(1);
vtraveller 25:24654d08a99a 195
vtraveller 25:24654d08a99a 196 nData = PIN_BL | in_nValue;
vtraveller 25:24654d08a99a 197 m_cI2C.write(ADDR,&nData,1);
vtraveller 25:24654d08a99a 198 }