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:
Fri Oct 10 11:10:56 2014 +0000
Revision:
28:fbcd3bac0cd7
Parent:
27:b6c3dd9a1d8c
Reduced write delay - faster LCD response

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 28:fbcd3bac0cd7 41 Serial cPC(SERIAL_TX, SERIAL_RX);
vtraveller 28:fbcd3bac0cd7 42
vtraveller 25:24654d08a99a 43 const uint8_t k_aMapper[] =
vtraveller 25:24654d08a99a 44 {
vtraveller 25:24654d08a99a 45 PIN_D4,
vtraveller 25:24654d08a99a 46 PIN_D5,
vtraveller 25:24654d08a99a 47 PIN_D6,
vtraveller 25:24654d08a99a 48 PIN_D7,
vtraveller 25:24654d08a99a 49 };
vtraveller 25:24654d08a99a 50
vtraveller 25:24654d08a99a 51 LCD2004::LCD2004(I2C & in_cI2C)
vtraveller 25:24654d08a99a 52 : LCD(in_cI2C)
vtraveller 25:24654d08a99a 53 , m_nDisplayControl(LCD_DISPLAY)
vtraveller 25:24654d08a99a 54 {
vtraveller 25:24654d08a99a 55 ::wait_ms(100);
vtraveller 25:24654d08a99a 56 write_reg(PIN_D5 | PIN_D4);
vtraveller 25:24654d08a99a 57 ::wait_ms(5);
vtraveller 25:24654d08a99a 58 write_reg(PIN_D5 | PIN_D4);
vtraveller 25:24654d08a99a 59 ::wait_us(100);
vtraveller 25:24654d08a99a 60 write_reg(PIN_D5 | PIN_D4);
vtraveller 25:24654d08a99a 61
vtraveller 25:24654d08a99a 62 // IV
vtraveller 25:24654d08a99a 63 write_reg(PIN_D5);
vtraveller 25:24654d08a99a 64 write_reg(PIN_D5);
vtraveller 25:24654d08a99a 65 write_reg(PIN_D7);
vtraveller 25:24654d08a99a 66 write_reg(0);
vtraveller 25:24654d08a99a 67 write_reg(PIN_D7);
vtraveller 25:24654d08a99a 68 write_reg(0);
vtraveller 25:24654d08a99a 69 write_reg(PIN_D4);
vtraveller 25:24654d08a99a 70 write_reg(0);
vtraveller 25:24654d08a99a 71 write_reg(PIN_D7 | PIN_D6 /* | PIN_D5 | PIN_D4 */); // D5 = cursor on D4 = BLINK
vtraveller 25:24654d08a99a 72 }
vtraveller 25:24654d08a99a 73
vtraveller 25:24654d08a99a 74 int LCD2004::_putc(int in_nValue)
vtraveller 25:24654d08a99a 75 {
vtraveller 25:24654d08a99a 76 write_data(PIN_RS, in_nValue);
vtraveller 25:24654d08a99a 77 return 0;
vtraveller 25:24654d08a99a 78 }
vtraveller 25:24654d08a99a 79
vtraveller 25:24654d08a99a 80 void LCD2004::clear()
vtraveller 25:24654d08a99a 81 {
vtraveller 25:24654d08a99a 82 write_data(0, LCD_CLEARDISPLAY);
vtraveller 25:24654d08a99a 83 }
vtraveller 25:24654d08a99a 84
vtraveller 25:24654d08a99a 85 uint8_t LCD2004::columns()
vtraveller 25:24654d08a99a 86 {
vtraveller 25:24654d08a99a 87 return 20;
vtraveller 25:24654d08a99a 88 }
vtraveller 25:24654d08a99a 89
vtraveller 25:24654d08a99a 90 void LCD2004::createChar(uint8_t location, uint8_t charmap[])
vtraveller 25:24654d08a99a 91 {
vtraveller 25:24654d08a99a 92 location &= 0x7; // we only have 8 locations 0-7
vtraveller 25:24654d08a99a 93 write_data(0, LCD_SETCGRAMADDR | (location << 3));
vtraveller 25:24654d08a99a 94
vtraveller 25:24654d08a99a 95 for (int i=0; i<8; i++)
vtraveller 25:24654d08a99a 96 {
vtraveller 25:24654d08a99a 97 _putc(charmap[i]);
vtraveller 25:24654d08a99a 98 }
vtraveller 25:24654d08a99a 99
vtraveller 25:24654d08a99a 100 write_data(0, LCD_SETDDRAMADDR); // unfortunately resets the location to 0,0
vtraveller 25:24654d08a99a 101 }
vtraveller 25:24654d08a99a 102
vtraveller 25:24654d08a99a 103 void LCD2004::home()
vtraveller 25:24654d08a99a 104 {
vtraveller 25:24654d08a99a 105 write_data(0, LCD_RETURNHOME);
vtraveller 25:24654d08a99a 106 }
vtraveller 25:24654d08a99a 107
vtraveller 25:24654d08a99a 108 uint8_t LCD2004::read_reg(void)
vtraveller 25:24654d08a99a 109 {
vtraveller 25:24654d08a99a 110 char nData = PIN_RW | PIN_BL;
vtraveller 25:24654d08a99a 111 m_cI2C.write(ADDR,&nData,1);
vtraveller 28:fbcd3bac0cd7 112
vtraveller 25:24654d08a99a 113 nData = PIN_RW | PIN_BL | PIN_E;
vtraveller 25:24654d08a99a 114 m_cI2C.write(ADDR,&nData,1);
vtraveller 25:24654d08a99a 115
vtraveller 28:fbcd3bac0cd7 116 ::wait_ms(0.05);
vtraveller 28:fbcd3bac0cd7 117
vtraveller 25:24654d08a99a 118 char nValue = 0;
vtraveller 25:24654d08a99a 119 m_cI2C.read(ADDR,&nValue,1);
vtraveller 25:24654d08a99a 120
vtraveller 25:24654d08a99a 121 nData = PIN_RW | PIN_BL;
vtraveller 25:24654d08a99a 122 m_cI2C.write(ADDR,&nData,1);
vtraveller 25:24654d08a99a 123
vtraveller 28:fbcd3bac0cd7 124 ::wait_ms(0.05);
vtraveller 28:fbcd3bac0cd7 125
vtraveller 28:fbcd3bac0cd7 126 return nValue & (PIN_D7 | PIN_D6 | PIN_D5 | PIN_D4);
vtraveller 25:24654d08a99a 127 }
vtraveller 25:24654d08a99a 128
vtraveller 25:24654d08a99a 129 uint8_t LCD2004::remap(uint8_t in_nValue)
vtraveller 25:24654d08a99a 130 {
vtraveller 25:24654d08a99a 131 uint8_t nValue = 0;
vtraveller 25:24654d08a99a 132 for (size_t i = 0; i < 4; i++)
vtraveller 25:24654d08a99a 133 {
vtraveller 25:24654d08a99a 134 if (in_nValue & (1 << i)) nValue |= k_aMapper[i];
vtraveller 25:24654d08a99a 135 }
vtraveller 25:24654d08a99a 136
vtraveller 25:24654d08a99a 137 return nValue;
vtraveller 25:24654d08a99a 138 }
vtraveller 25:24654d08a99a 139
vtraveller 25:24654d08a99a 140 uint8_t LCD2004::rows()
vtraveller 25:24654d08a99a 141 {
vtraveller 25:24654d08a99a 142 return 4;
vtraveller 25:24654d08a99a 143 }
vtraveller 25:24654d08a99a 144
vtraveller 25:24654d08a99a 145 void LCD2004::setCursor(uint8_t in_nX, uint8_t in_nY)
vtraveller 25:24654d08a99a 146 {
vtraveller 25:24654d08a99a 147 int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
vtraveller 25:24654d08a99a 148
vtraveller 25:24654d08a99a 149 // D7 = Set DDRAM address
vtraveller 25:24654d08a99a 150 uint8_t nValue = LCD_SETDDRAMADDR | (in_nX + row_offsets[in_nY]);
vtraveller 25:24654d08a99a 151 write_data(0, nValue);
vtraveller 25:24654d08a99a 152 }
vtraveller 25:24654d08a99a 153
vtraveller 25:24654d08a99a 154 void LCD2004::setDisplayControl(uint8_t in_nReg, bool in_bEnable)
vtraveller 25:24654d08a99a 155 {
vtraveller 27:b6c3dd9a1d8c 156 uint8_t nDisplayControl = m_nDisplayControl;
vtraveller 27:b6c3dd9a1d8c 157
vtraveller 25:24654d08a99a 158 if (in_bEnable)
vtraveller 25:24654d08a99a 159 {
vtraveller 25:24654d08a99a 160 m_nDisplayControl |= in_nReg;
vtraveller 25:24654d08a99a 161 }
vtraveller 25:24654d08a99a 162 else
vtraveller 25:24654d08a99a 163 {
vtraveller 25:24654d08a99a 164 m_nDisplayControl &= ~in_nReg;
vtraveller 25:24654d08a99a 165 }
vtraveller 27:b6c3dd9a1d8c 166
vtraveller 27:b6c3dd9a1d8c 167 if (nDisplayControl != m_nDisplayControl)
vtraveller 27:b6c3dd9a1d8c 168 {
vtraveller 27:b6c3dd9a1d8c 169 write_data(0,LCD_DISPLAYCONTROL | m_nDisplayControl);
vtraveller 27:b6c3dd9a1d8c 170 }
vtraveller 25:24654d08a99a 171 }
vtraveller 25:24654d08a99a 172
vtraveller 25:24654d08a99a 173 void LCD2004::showBlink(bool in_bShow)
vtraveller 25:24654d08a99a 174 {
vtraveller 25:24654d08a99a 175 setDisplayControl(LCD_BLINK,in_bShow);
vtraveller 25:24654d08a99a 176 }
vtraveller 25:24654d08a99a 177
vtraveller 25:24654d08a99a 178 void LCD2004::showCursor(bool in_bShow)
vtraveller 25:24654d08a99a 179 {
vtraveller 25:24654d08a99a 180 setDisplayControl(LCD_CURSOR, in_bShow);
vtraveller 25:24654d08a99a 181 }
vtraveller 25:24654d08a99a 182
vtraveller 25:24654d08a99a 183 void LCD2004::showDisplay(bool in_bShow)
vtraveller 25:24654d08a99a 184 {
vtraveller 25:24654d08a99a 185 setDisplayControl(LCD_DISPLAY,in_bShow);
vtraveller 25:24654d08a99a 186 }
vtraveller 25:24654d08a99a 187
vtraveller 25:24654d08a99a 188 void LCD2004::write_data(uint8_t in_nReg, uint8_t in_nValue)
vtraveller 25:24654d08a99a 189 {
vtraveller 25:24654d08a99a 190 write_reg(in_nReg | remap(in_nValue >> 4));
vtraveller 25:24654d08a99a 191 write_reg(in_nReg | remap(in_nValue & 0x0F));
vtraveller 25:24654d08a99a 192 }
vtraveller 25:24654d08a99a 193
vtraveller 25:24654d08a99a 194 void LCD2004::write_reg(uint8_t in_nValue)
vtraveller 25:24654d08a99a 195 {
vtraveller 25:24654d08a99a 196 char nData = PIN_E | PIN_BL | in_nValue;
vtraveller 25:24654d08a99a 197 m_cI2C.write(ADDR,&nData,1);
vtraveller 28:fbcd3bac0cd7 198
vtraveller 28:fbcd3bac0cd7 199 ::wait_us(1450);
vtraveller 25:24654d08a99a 200
vtraveller 25:24654d08a99a 201 nData = PIN_BL | in_nValue;
vtraveller 25:24654d08a99a 202 m_cI2C.write(ADDR,&nData,1);
vtraveller 25:24654d08a99a 203 }