Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: AdaFruit_RGBLCDShield MCP23017 mbed RTclock
Fork of MCP_test by
Revision 25:24654d08a99a, committed 2014-10-09
- Comitter:
- vtraveller
- Date:
- Thu Oct 09 08:03:20 2014 +0000
- Parent:
- 24:e67c825ec6d8
- Child:
- 26:0cfd95d8f270
- Commit message:
- Updated with new LCD and Key abstraction (to support different LCDs and Keyboard input).
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/KeyReaderNull/keyreadernull.cpp Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,12 @@
+#include "mbed.h"
+#include "keyreadernull.h"
+
+KeyReaderNull::KeyReaderNull(I2C & in_cI2C)
+ : Keys(in_cI2C)
+{
+}
+
+uint8_t KeyReaderNull::readButtons()
+{
+ return eButtonNone;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/KeyReaderNull/keyreadernull.h Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,15 @@
+#ifndef __KEYREADERNULL_H__
+#define __KEYREADERNULL_H__
+
+#include "keys.h"
+
+class KeyReaderNull
+ : public Keys
+{
+public:
+ KeyReaderNull(I2C & in_cI2C);
+
+ virtual uint8_t readButtons();
+};
+
+#endif // __KEYREADERNULL_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LCD2004/lcd2004.cpp Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,193 @@
+#include "mbed.h"
+#include "lcd2004.h"
+
+// commands
+#define LCD_CLEARDISPLAY 0x01
+#define LCD_RETURNHOME 0x02
+#define LCD_ENTRYMODESET 0x04
+#define LCD_DISPLAYCONTROL 0x08
+#define LCD_CURSORSHIFT 0x10
+#define LCD_FUNCTIONSET 0x20
+#define LCD_SETCGRAMADDR 0x40
+#define LCD_SETDDRAMADDR 0x80
+
+// flags for display entry mode
+#define LCD_ENTRYRIGHT 0x00
+#define LCD_ENTRYLEFT 0x02
+#define LCD_ENTRYSHIFTINCREMENT 0x01
+#define LCD_ENTRYSHIFTDECREMENT 0x00
+
+// flags for display on/off control
+#define LCD_DISPLAY 0x04
+#define LCD_CURSOR 0x02
+#define LCD_BLINK 0x01
+
+// flags for display/cursor shift
+#define LCD_DISPLAYMOVE 0x08
+#define LCD_CURSORMOVE 0x00
+#define LCD_MOVERIGHT 0x04
+#define LCD_MOVELEFT 0x00
+
+#define ADDR 0x4E
+#define PIN_E 1<<2
+#define PIN_RW 1<<1
+#define PIN_RS 1<<0
+#define PIN_D4 1<<4
+#define PIN_D5 1<<5
+#define PIN_D6 1<<6
+#define PIN_D7 1<<7
+#define PIN_BL 1<<3
+
+const uint8_t k_aMapper[] =
+{
+ PIN_D4,
+ PIN_D5,
+ PIN_D6,
+ PIN_D7,
+};
+
+LCD2004::LCD2004(I2C & in_cI2C)
+ : LCD(in_cI2C)
+ , m_nDisplayControl(LCD_DISPLAY)
+{
+ ::wait_ms(100);
+ write_reg(PIN_D5 | PIN_D4);
+ ::wait_ms(5);
+ write_reg(PIN_D5 | PIN_D4);
+ ::wait_us(100);
+ write_reg(PIN_D5 | PIN_D4);
+
+ // IV
+ write_reg(PIN_D5);
+ write_reg(PIN_D5);
+ write_reg(PIN_D7);
+ write_reg(0);
+ write_reg(PIN_D7);
+ write_reg(0);
+ write_reg(PIN_D4);
+ write_reg(0);
+ write_reg(PIN_D7 | PIN_D6 /* | PIN_D5 | PIN_D4 */); // D5 = cursor on D4 = BLINK
+}
+
+int LCD2004::_putc(int in_nValue)
+{
+ write_data(PIN_RS, in_nValue);
+ return 0;
+}
+
+void LCD2004::clear()
+{
+ write_data(0, LCD_CLEARDISPLAY);
+}
+
+uint8_t LCD2004::columns()
+{
+ return 20;
+}
+
+void LCD2004::createChar(uint8_t location, uint8_t charmap[])
+{
+ location &= 0x7; // we only have 8 locations 0-7
+ write_data(0, LCD_SETCGRAMADDR | (location << 3));
+
+ for (int i=0; i<8; i++)
+ {
+ _putc(charmap[i]);
+ }
+
+ write_data(0, LCD_SETDDRAMADDR); // unfortunately resets the location to 0,0
+}
+
+void LCD2004::home()
+{
+ write_data(0, LCD_RETURNHOME);
+}
+
+uint8_t LCD2004::read_reg(void)
+{
+ char nData = PIN_RW | PIN_BL;
+ m_cI2C.write(ADDR,&nData,1);
+
+ nData = PIN_RW | PIN_BL | PIN_E;
+ m_cI2C.write(ADDR,&nData,1);
+
+ char nValue = 0;
+ m_cI2C.read(ADDR,&nValue,1);
+
+ nData = PIN_RW | PIN_BL;
+ m_cI2C.write(ADDR,&nData,1);
+
+ return nValue;
+}
+
+uint8_t LCD2004::remap(uint8_t in_nValue)
+{
+ uint8_t nValue = 0;
+ for (size_t i = 0; i < 4; i++)
+ {
+ if (in_nValue & (1 << i)) nValue |= k_aMapper[i];
+ }
+
+ return nValue;
+}
+
+uint8_t LCD2004::rows()
+{
+ return 4;
+}
+
+void LCD2004::setCursor(uint8_t in_nX, uint8_t in_nY)
+{
+ int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
+
+ // D7 = Set DDRAM address
+ uint8_t nValue = LCD_SETDDRAMADDR | (in_nX + row_offsets[in_nY]);
+ write_data(0, nValue);
+}
+
+void LCD2004::setDisplayControl(uint8_t in_nReg, bool in_bEnable)
+{
+ if (in_bEnable)
+ {
+ m_nDisplayControl |= in_nReg;
+ }
+ else
+ {
+ m_nDisplayControl &= ~in_nReg;
+ }
+
+ write_data(0,LCD_DISPLAYCONTROL | m_nDisplayControl);
+}
+
+void LCD2004::showBlink(bool in_bShow)
+{
+ setDisplayControl(LCD_BLINK,in_bShow);
+}
+
+void LCD2004::showCursor(bool in_bShow)
+{
+ setDisplayControl(LCD_CURSOR, in_bShow);
+}
+
+void LCD2004::showDisplay(bool in_bShow)
+{
+ setDisplayControl(LCD_DISPLAY,in_bShow);
+}
+
+void LCD2004::write_data(uint8_t in_nReg, uint8_t in_nValue)
+{
+ write_reg(in_nReg | remap(in_nValue >> 4));
+ write_reg(in_nReg | remap(in_nValue & 0x0F));
+}
+
+void LCD2004::write_reg(uint8_t in_nValue)
+{
+ char nData = PIN_E | PIN_BL | in_nValue;
+ m_cI2C.write(ADDR,&nData,1);
+
+ ::wait_ms(2);
+ //while (read_reg() & PIN_D7) ::wait_ms(1);
+
+ nData = PIN_BL | in_nValue;
+ m_cI2C.write(ADDR,&nData,1);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LCD2004/lcd2004.h Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,34 @@
+#ifndef __LCD2004_H__
+#define __LCD2004_H__
+
+#include "lcd.h"
+
+class LCD2004
+ : public LCD
+{
+public:
+ LCD2004(I2C & in_cI2C);
+ virtual int _putc(int c);
+
+ virtual uint8_t columns();
+ virtual void clear();
+ virtual void createChar(uint8_t location, uint8_t charmap[]);
+ virtual void home();
+ virtual uint8_t rows();
+ virtual void setCursor(uint8_t in_nX, uint8_t in_nY);
+ virtual void showBlink(bool in_bShow);
+ virtual void showCursor(bool in_bShow);
+ virtual void showDisplay(bool in_bShow);
+
+protected:
+ uint8_t read_reg(void);
+ uint8_t remap(uint8_t in_nValue);
+ void setDisplayControl(uint8_t in_nReg, bool in_bEnable);
+ void write_data(uint8_t in_nReg, uint8_t in_nValue);
+ void write_reg(uint8_t in_nValue);
+
+protected:
+ uint8_t m_nDisplayControl;
+};
+
+#endif // __LCD2004_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LCDadafruit/lcdadafruit.cpp Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,60 @@
+#include "mbed.h"
+#include "lcdadafruit.h"
+
+LCDadafruit::LCDadafruit(I2C & in_cI2C)
+ : LCD(in_cI2C)
+ , m_cMCP(in_cI2C, 0x20 << 1)
+ , m_cLCD(m_cMCP)
+{
+ m_cLCD.begin(16,2);
+}
+
+int LCDadafruit::_putc(int in_nValue)
+{
+ return m_cLCD._putc(in_nValue);
+}
+
+void LCDadafruit::clear()
+{
+ m_cLCD.clear();
+}
+
+uint8_t LCDadafruit::columns()
+{
+ return 16;
+}
+
+void LCDadafruit::createChar(uint8_t location, uint8_t charmap[])
+{
+ m_cLCD.createChar(location,charmap);
+}
+
+void LCDadafruit::home()
+{
+ m_cLCD.home();
+}
+
+uint8_t LCDadafruit::rows()
+{
+ return 2;
+}
+
+void LCDadafruit::setCursor(uint8_t in_nX, uint8_t in_nY)
+{
+ m_cLCD.setCursor(in_nX,in_nY);
+}
+
+void LCDadafruit::showBlink(bool in_bShow)
+{
+ if (in_bShow) m_cLCD.blink(); else m_cLCD.noBlink();
+}
+
+void LCDadafruit::showCursor(bool in_bShow)
+{
+ if (in_bShow) m_cLCD.cursor(); else m_cLCD.noCursor();
+}
+
+void LCDadafruit::showDisplay(bool in_bShow)
+{
+ if (in_bShow) m_cLCD.display(); else m_cLCD.noDisplay();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LCDadafruit/lcdadafruit.h Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,31 @@
+#ifndef __LCDADAFRUIT_H__
+#define __LCDADAFRUIT_H__
+
+#include "lcd.h"
+#include "Adafruit_RGBLCDShield.h"
+#include "MCP23017.h"
+
+class LCDadafruit
+ : public LCD
+{
+public:
+ LCDadafruit(I2C & in_cI2C);
+ virtual int _putc(int c);
+
+ virtual uint8_t columns();
+ virtual void clear();
+ virtual void createChar(uint8_t location, uint8_t charmap[]);
+ virtual void home();
+ virtual uint8_t rows();
+ virtual void setCursor(uint8_t in_nX, uint8_t in_nY);
+ virtual void showBlink(bool in_bBlink);
+ virtual void showCursor(bool in_bShow);
+ virtual void showDisplay(bool in_bBlink);
+
+protected:
+ MCP23017 m_cMCP;
+ Adafruit_RGBLCDShield m_cLCD;
+ uint8_t m_nDisplayControl;
+};
+
+#endif // __LCDADAFRUIT_H__
--- a/MenuManager.cpp Wed Oct 08 16:42:17 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-#include "mbed.h"
-#include "module.h"
-#include "extra_chars.h"
-#include "Adafruit_RGBLCDShield.h"
-
-#include "MenuManager.h"
-
-MenuManager::MenuManager
-(
- Module ** in_pModules,
- size_t in_nModules,
- Adafruit_RGBLCDShield & in_cLCD,
- int in_nColumns,
- int in_nRows
-)
- : m_pModules(in_pModules)
- , m_nModules(in_nModules)
- , m_cLCD(in_cLCD)
- , m_eMode(Module::eModeLast)
- , m_nMenuPos(0)
- , m_nIndex(0)
- , m_nCursorX(0)
- , m_nCursorY(0)
- , m_nColumns(in_nColumns)
- , m_nRows(in_nRows)
-{
-}
-
-void MenuManager::changeModule(bool in_bUp)
-{
- size_t nModule = (m_nMenuPos + m_nCursorY) % m_nModules;
- m_pModules[nModule]->change(m_nIndex,in_bUp);
-}
-
-void MenuManager::createChars()
-{
- //uint8_t k_aUp[] = { 0x4,0xe,0x1f,0x15,0x4,0x4,0x4,0x4 };
- //uint8_t k_aDown[] = { 0x4,0x4,0x4,0x4,0x15,0x1f,0xe,0x4 };
-
- uint8_t k_aUp[] = { 0x0,0x0,0x4,0xe,0x1f,0x0,0x0 };
- uint8_t k_aDown[] = { 0x0,0x0,0x1f,0xe,0x4,0x0,0x0 };
- uint8_t k_aRight[] = { 0x0,0x8,0xc,0xe,0xc,0x8,0x0 };
- uint8_t k_aLeft[] = { 0x0,0x2,0x6,0xe,0x6,0x2,0x0 };
- uint8_t k_aDegree[] = { 0xc,0x12,0x12,0xc,0x0,0x0,0x0,0x0 };
-
- m_cLCD.createChar(eUp,k_aUp);
- m_cLCD.createChar(eDown,k_aDown);
- m_cLCD.createChar(eRight,k_aRight);
- m_cLCD.createChar(eLeft,k_aLeft);
- m_cLCD.createChar(eDegree,k_aDegree);
-}
-
-void MenuManager::initialise()
-{
- // Initialise LCD
- m_cLCD.begin(m_nColumns,m_nRows);
- createChars();
-
- m_cLCD.setCursor(0,0);
- m_cLCD._putc(eUp);
-
- m_cLCD.setCursor(0,1);
- m_cLCD._putc(eDown);
-
- m_nCursorX = 2;
- m_nCursorY = 0;
-}
-
-void MenuManager::loop()
-{
- setMode(Module::eModeMenu);
-
- m_nMenuPos = 0;
- m_nIndex = 0;
-
- initialise();
-
- showModules();
-
- while (true)
- {
- uint8_t nKeys = m_cLCD.readButtons();
- if (nKeys)
- {
- processKeys(nKeys);
- }
- else
- {
- switch (m_eMode)
- {
- case Module::eModeMenu:
- showModules(true);
-
- int nOffsetX = m_pModules[m_nMenuPos]->getCursorOffset(m_nIndex);
- m_cLCD.setCursor(m_nCursorY + nOffsetX,m_nCursorY);
- break;
- }
- }
-
- wait(0.2);
- }
-}
-
-void MenuManager::processKeys(uint8_t in_nKeys)
-{
- // Change mode based on select
- if (in_nKeys & BUTTON_SELECT)
- {
- Module::EModes eMode = (Module::EModes)((m_eMode + 1) % Module::eModeLast);
- setMode(eMode);
-
- // Start at top corner
- if (Module::eModeSelect == m_eMode)
- {
- m_nIndex = 0;
- m_nCursorY = 0;
- }
- }
-
- switch (m_eMode)
- {
- case Module::eModeMenu:
- setCursor(false,false);
- showTracking(false);
-
- if (in_nKeys & BUTTON_UP) m_nMenuPos--;
- if (in_nKeys & BUTTON_DOWN) m_nMenuPos++;
-
- m_nMenuPos = m_nMenuPos % m_nModules;
- break;
-
- case Module::eModeSelect:
- setCursor(true,false);
- showTracking(true);
-
- if (m_nCursorY > 0 && (in_nKeys & BUTTON_UP)) m_nCursorY--;
- if ((m_nCursorY < m_cLCD.lines() - 1) && (in_nKeys & BUTTON_DOWN)) m_nCursorY++;
-
- if (in_nKeys & BUTTON_LEFT) m_nIndex--;
- if (in_nKeys & BUTTON_RIGHT) m_nIndex++;
- break;
-
- case Module::eModeChange:
- setCursor(false,true);
- showTracking(true);
-
- if (in_nKeys & (BUTTON_UP | BUTTON_DOWN))
- {
- bool bUp = (in_nKeys & BUTTON_UP) ? true : false;
- changeModule(bUp);
- }
-
- if (in_nKeys & BUTTON_LEFT) m_nIndex--;
- if (in_nKeys & BUTTON_RIGHT) m_nIndex++;
- break;
- }
-
- updateDisplay();
-}
-
-void MenuManager::setCursor(bool in_bCursor,bool in_bBlink)
-{
- if (in_bCursor) m_cLCD.cursor(); else m_cLCD.noCursor();
- if (in_bBlink) m_cLCD.blink(); else m_cLCD.noBlink();
-}
-
-void MenuManager::setMode(Module::EModes in_eMode)
-{
- m_eMode = in_eMode;
-
- for (size_t i = 0; i < m_nModules; i++)
- {
- m_pModules[i]->onModeChange(m_eMode);
- }
-}
-
-void MenuManager::showModules(bool in_bRefresh)
-{
- m_cLCD.setCursor(2,0);
-
- if (m_pModules[m_nMenuPos]->canRefresh() || !in_bRefresh) m_pModules[m_nMenuPos]->show(in_bRefresh);
-
- size_t nPos = (m_nMenuPos + 1) % m_nModules;
- m_cLCD.setCursor(2,1);
-
- if (m_pModules[nPos]->canRefresh() || !in_bRefresh) m_pModules[nPos]->show(in_bRefresh);
-}
-
-void MenuManager::showTracking(bool in_bShow)
-{
- if (in_bShow)
- {
- m_cLCD.setCursor(1,0);
- m_cLCD._putc(eLeft);
-
- m_cLCD.setCursor(1,1);
- m_cLCD._putc(eRight);
- }
- else
- {
- m_cLCD.setCursor(1,0);
- m_cLCD._putc(' ');
-
- m_cLCD.setCursor(1,1);
- m_cLCD._putc(' ');
- }
-}
-
-void MenuManager::updateDisplay()
-{
- showModules();
-
- size_t nCurrent = (m_nMenuPos + m_nCursorY) % m_nModules;
-
- int nOffsetX = m_pModules[nCurrent]->getCursorOffset(m_nIndex);
-
- // If we didn't have anything, move the line
- if (-1 == nOffsetX)
- {
- m_nCursorY = (m_nCursorY + 1) % m_cLCD.lines();
-
- nCurrent = (m_nMenuPos + m_nCursorY) % m_nModules;
-
- m_nIndex = 0;
- nOffsetX = m_pModules[nCurrent]->getCursorOffset(m_nIndex);
- }
-
- if ((size_t)-1 != m_nIndex)
- {
- // Move cursor to new position
- m_cLCD.setCursor(m_nCursorX + nOffsetX,m_nCursorY);
- }
- else
- {
- // If nothing to show - hide everything
- setCursor(false,false);
- }
-}
--- a/MenuManager.h Wed Oct 08 16:42:17 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-#ifndef __MENUMANAGER_H__
-#define __MENUMANAGER_H__
-
-class MenuManager
-{
-public:
- MenuManager
- (
- Module ** in_pModules,
- size_t in_nModules,
- Adafruit_RGBLCDShield & in_cLCD,
- int in_nCols,
- int in_nRows
- );
- void loop();
-
-protected:
- void changeModule(bool in_bUp);
- void createChars();
- void initialise();
- void processKeys(uint8_t in_nKeys);
- void setCursor
- (
- bool in_bCursor,
- bool in_bBlink
- );
- void setMode(Module::EModes in_eMode);
- void showModules(bool in_bRefresh = false);
- void showTracking(bool in_bShow);
- void updateDisplay();
-
-protected:
- Module ** m_pModules;
- size_t m_nModules;
- Adafruit_RGBLCDShield & m_cLCD;
- Module::EModes m_eMode;
- size_t m_nMenuPos;
- size_t m_nIndex;
- int m_nCursorX, m_nCursorY;
- int m_nColumns, m_nRows;
-};
-
-#endif /* __MENUMANAGER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MenuManager/MenuManager.cpp Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,232 @@
+#include "mbed.h"
+#include "module.h"
+#include "extra_chars.h"
+
+#include "MenuManager.h"
+
+MenuManager::MenuManager
+(
+ Module ** in_pModules,
+ size_t in_nModules,
+ LCD & in_cLCD,
+ Keys & in_cKeys
+)
+ : m_pModules(in_pModules)
+ , m_nModules(in_nModules)
+ , m_cLCD(in_cLCD)
+ , m_cKeys(in_cKeys)
+ , m_eMode(Module::eModeLast)
+ , m_nMenuPos(0)
+ , m_nIndex(0)
+ , m_nCursorX(0)
+ , m_nCursorY(0)
+{
+}
+
+void MenuManager::changeModule(bool in_bUp)
+{
+ size_t nModule = (m_nMenuPos + m_nCursorY) % m_nModules;
+ m_pModules[nModule]->change(m_nIndex,in_bUp);
+}
+
+void MenuManager::createChars()
+{
+ //uint8_t k_aUp[] = { 0x4,0xe,0x1f,0x15,0x4,0x4,0x4,0x4 };
+ //uint8_t k_aDown[] = { 0x4,0x4,0x4,0x4,0x15,0x1f,0xe,0x4 };
+
+ uint8_t k_aUp[] = { 0x0,0x0,0x4,0xe,0x1f,0x0,0x0 };
+ uint8_t k_aDown[] = { 0x0,0x0,0x1f,0xe,0x4,0x0,0x0 };
+ uint8_t k_aRight[] = { 0x0,0x8,0xc,0xe,0xc,0x8,0x0 };
+ uint8_t k_aLeft[] = { 0x0,0x2,0x6,0xe,0x6,0x2,0x0 };
+ uint8_t k_aDegree[] = { 0xc,0x12,0x12,0xc,0x0,0x0,0x0,0x0 };
+
+ m_cLCD.createChar(eUp,k_aUp);
+ m_cLCD.createChar(eDown,k_aDown);
+ m_cLCD.createChar(eRight,k_aRight);
+ m_cLCD.createChar(eLeft,k_aLeft);
+ m_cLCD.createChar(eDegree,k_aDegree);
+}
+
+void MenuManager::initialise()
+{
+ createChars();
+
+ m_cLCD.setCursor(0,0);
+ m_cLCD._putc(eUp);
+
+ m_cLCD.setCursor(0,m_cLCD.rows() - 1);
+ m_cLCD._putc(eDown);
+
+ m_nCursorX = 2;
+ m_nCursorY = 0;
+}
+
+void MenuManager::loop()
+{
+ setMode(Module::eModeMenu);
+
+ m_nMenuPos = 0;
+ m_nIndex = 0;
+
+ initialise();
+
+ showModules();
+
+ while (true)
+ {
+ uint8_t nKeys = m_cKeys.readButtons();
+ if (Keys::eButtonNone != nKeys)
+ {
+ processKeys(nKeys);
+ }
+ else
+ {
+ switch (m_eMode)
+ {
+ case Module::eModeMenu:
+ showModules(true);
+
+ int nOffsetX = m_pModules[m_nMenuPos]->getCursorOffset(m_nIndex);
+ m_cLCD.setCursor(m_nCursorY + nOffsetX,m_nCursorY);
+ break;
+ }
+ }
+
+ wait(0.2);
+ }
+}
+
+void MenuManager::processKeys(uint8_t in_nKeys)
+{
+ // Change mode based on select
+ if (in_nKeys & Keys::eButtonSelect)
+ {
+ Module::EModes eMode = (Module::EModes)((m_eMode + 1) % Module::eModeLast);
+ setMode(eMode);
+
+ // Start at top corner
+ if (Module::eModeSelect == m_eMode)
+ {
+ m_nIndex = 0;
+ m_nCursorY = 0;
+ }
+ }
+
+ switch (m_eMode)
+ {
+ case Module::eModeMenu:
+ setCursor(false,false);
+ showTracking(false);
+
+ if (in_nKeys & Keys::eButtonUp) m_nMenuPos--;
+ if (in_nKeys & Keys::eButtonDown) m_nMenuPos++;
+
+ m_nMenuPos = m_nMenuPos % m_nModules;
+ break;
+
+ case Module::eModeSelect:
+ setCursor(true,false);
+ showTracking(true);
+
+ if (m_nCursorY > 0 && (in_nKeys & Keys::eButtonUp)) m_nCursorY--;
+ if ((m_nCursorY < m_cLCD.rows() - 1) && (in_nKeys & Keys::eButtonDown)) m_nCursorY++;
+
+ if (in_nKeys & Keys::eButtonLeft) m_nIndex--;
+ if (in_nKeys & Keys::eButtonRight) m_nIndex++;
+ break;
+
+ case Module::eModeChange:
+ setCursor(false,true);
+ showTracking(true);
+
+ if (in_nKeys & (Keys::eButtonUp | Keys::eButtonDown))
+ {
+ bool bUp = (in_nKeys & Keys::eButtonUp) ? true : false;
+ changeModule(bUp);
+ }
+
+ if (in_nKeys & Keys::eButtonLeft) m_nIndex--;
+ if (in_nKeys & Keys::eButtonRight) m_nIndex++;
+ break;
+ }
+
+ updateDisplay();
+}
+
+void MenuManager::setCursor(bool in_bCursor,bool in_bBlink)
+{
+ m_cLCD.showCursor(in_bCursor);
+ m_cLCD.showBlink(in_bBlink);
+}
+
+void MenuManager::setMode(Module::EModes in_eMode)
+{
+ m_eMode = in_eMode;
+
+ for (size_t i = 0; i < m_nModules; i++)
+ {
+ m_pModules[i]->onModeChange(m_eMode);
+ }
+}
+
+void MenuManager::showModules(bool in_bRefresh)
+{
+ for (size_t i = 0; i < m_cLCD.rows(); i++)
+ {
+ size_t nPos = (m_nMenuPos + i) % m_nModules;
+ m_cLCD.setCursor(2,i);
+
+ if (m_pModules[nPos]->canRefresh() || !in_bRefresh) m_pModules[nPos]->show(in_bRefresh);
+ }
+}
+
+void MenuManager::showTracking(bool in_bShow)
+{
+ if (in_bShow)
+ {
+ m_cLCD.setCursor(1,0);
+ m_cLCD._putc(eLeft);
+
+ m_cLCD.setCursor(1,1);
+ m_cLCD._putc(eRight);
+ }
+ else
+ {
+ m_cLCD.setCursor(1,0);
+ m_cLCD._putc(' ');
+
+ m_cLCD.setCursor(1,1);
+ m_cLCD._putc(' ');
+ }
+}
+
+void MenuManager::updateDisplay()
+{
+ showModules();
+
+ size_t nCurrent = (m_nMenuPos + m_nCursorY) % m_nModules;
+
+ int nOffsetX = m_pModules[nCurrent]->getCursorOffset(m_nIndex);
+
+ // If we didn't have anything, move the line
+ if (-1 == nOffsetX)
+ {
+ m_nCursorY = (m_nCursorY + 1) % m_cLCD.rows();
+
+ nCurrent = (m_nMenuPos + m_nCursorY) % m_nModules;
+
+ m_nIndex = 0;
+ nOffsetX = m_pModules[nCurrent]->getCursorOffset(m_nIndex);
+ }
+
+ if ((size_t)-1 != m_nIndex)
+ {
+ // Move cursor to new position
+ m_cLCD.setCursor(m_nCursorX + nOffsetX,m_nCursorY);
+ }
+ else
+ {
+ // If nothing to show - hide everything
+ setCursor(false,false);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MenuManager/MenuManager.h Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,45 @@
+#ifndef __MENUMANAGER_H__
+#define __MENUMANAGER_H__
+
+#include "lcd.h"
+#include "keys.h"
+
+class MenuManager
+{
+public:
+ MenuManager
+ (
+ Module ** in_pModules,
+ size_t in_nModules,
+ LCD & in_cLCD,
+ Keys & in_cKeys
+ );
+ void loop();
+
+protected:
+ void changeModule(bool in_bUp);
+ void createChars();
+ void initialise();
+ void processKeys(uint8_t in_nKeys);
+ void setCursor
+ (
+ bool in_bCursor,
+ bool in_bBlink
+ );
+ void setMode(Module::EModes in_eMode);
+ void showModules(bool in_bRefresh = false);
+ void showTracking(bool in_bShow);
+ void updateDisplay();
+
+protected:
+ Module ** m_pModules;
+ size_t m_nModules;
+ LCD & m_cLCD;
+ Keys & m_cKeys;
+ Module::EModes m_eMode;
+ size_t m_nMenuPos;
+ size_t m_nIndex;
+ int m_nCursorX, m_nCursorY;
+};
+
+#endif /* __MENUMANAGER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MenuManager/keys.cpp Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,7 @@
+#include "mbed.h"
+#include "keys.h"
+
+Keys::Keys(I2C & in_cI2C)
+ : m_cI2C(in_cI2C)
+{
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MenuManager/keys.h Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,26 @@
+#ifndef __KEYS_H__
+#define __KEYS_H__
+
+class Keys
+{
+public:
+ enum EButtons
+ {
+ eButtonNone = 0x00,
+ eButtonUp = 0x01,
+ eButtonDown = 0x02,
+ eButtonLeft = 0x04,
+ eButtonRight = 0x08,
+ eButtonSelect = 0x10,
+ };
+
+public:
+ Keys(I2C & in_cI2C);
+
+ virtual uint8_t readButtons() = 0;
+
+protected:
+ I2C & m_cI2C;
+};
+
+#endif // __KEYS_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MenuManager/lcd.cpp Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,8 @@
+#include "mbed.h"
+#include "lcd.h"
+
+LCD::LCD(I2C & in_cI2C)
+ : Serial(SERIAL_TX,SERIAL_RX)
+ , m_cI2C(in_cI2C)
+{
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MenuManager/lcd.h Thu Oct 09 08:03:20 2014 +0000
@@ -0,0 +1,25 @@
+#ifndef __LCD_H__
+#define __LCD_H__
+
+class LCD
+ : public Serial // for printf
+{
+public:
+ LCD(I2C & in_cI2C);
+ virtual int _putc(int c) = 0;
+
+ virtual void clear() = 0;
+ virtual uint8_t columns() = 0;
+ virtual void createChar(uint8_t location, uint8_t charmap[]) = 0;
+ virtual void home() = 0;
+ virtual uint8_t rows() = 0;
+ virtual void setCursor(uint8_t in_nX, uint8_t in_nY) = 0;
+ virtual void showBlink(bool in_bShow) = 0;
+ virtual void showCursor(bool in_bShow) = 0;
+ virtual void showDisplay(bool in_bShow) = 0;
+
+protected:
+ I2C & m_cI2C;
+};
+
+#endif // __LCD_H__
--- a/Modules/DateModule.cpp Wed Oct 08 16:42:17 2014 +0000
+++ b/Modules/DateModule.cpp Thu Oct 09 08:03:20 2014 +0000
@@ -98,5 +98,5 @@
// Ensure internal struct has new TM data
::memcpy(&m_sLastTM,&sTM,sizeof(m_sLastTM));
- m_cDisplay.printf ("%s %02i/%02i/%04i ", k_aWeekDays[sTM.tm_wday], sTM.tm_mday, sTM.tm_mon + 1, 1900 + sTM.tm_year);
+ m_cDisplay.printf ("%s %02i/%02i/%04i ", k_aWeekDays[sTM.tm_wday], sTM.tm_mday, sTM.tm_mon + 1, 1900 + sTM.tm_year);
}
--- a/Modules/TitleModule.cpp Wed Oct 08 16:42:17 2014 +0000
+++ b/Modules/TitleModule.cpp Thu Oct 09 08:03:20 2014 +0000
@@ -1,16 +1,41 @@
#include "mbed.h"
#include "TitleModule.h"
+#include "time_helper.h"
-TitleModule::TitleModule(Serial & in_cDisplay)
+TitleModule::TitleModule
+(
+ Serial & in_cDisplay,
+ RTclock & in_cRTclock
+)
: Module(in_cDisplay)
+ , m_cRTclock(in_cRTclock)
{
+ ::memset(&m_sLastTM,0,sizeof(m_sLastTM));
}
TitleModule::~TitleModule()
{
}
-void TitleModule::show(bool /*in_bRefresh*/)
+void TitleModule::show(bool in_bRefresh)
{
- m_cDisplay.printf("System Running");
+ tm sTM;
+
+ // to get the current time information
+ if (!m_cRTclock.getTime(sTM)) GetTime(sTM);
+
+ // if refreshing - only update if there's a change
+ if (in_bRefresh)
+ {
+ // Check for change based on hour (rest is irrelevant)
+ if (sTM.tm_hour == m_sLastTM.tm_hour) return;
+ }
+
+ // Ensure internal struct has new TM data
+ ::memcpy(&m_sLastTM,&sTM,sizeof(m_sLastTM));
+ if (sTM.tm_hour < 6) m_cDisplay.printf("Night Time ");
+ else if (sTM.tm_hour < 12) m_cDisplay.printf("Morning Time ");
+ else if (sTM.tm_hour < 18) m_cDisplay.printf("Afternoon Time ");
+ else if (sTM.tm_hour < 21) m_cDisplay.printf("Evening Time ");
+ else m_cDisplay.printf("Bedtime ");
}
--- a/Modules/TitleModule.h Wed Oct 08 16:42:17 2014 +0000
+++ b/Modules/TitleModule.h Thu Oct 09 08:03:20 2014 +0000
@@ -2,15 +2,25 @@
#define __TITLEMODULE_H__
#include "module.h"
+#include "RTclock.h"
class TitleModule
: public Module
{
public:
- TitleModule(Serial & in_cDisplay);
+ TitleModule
+ (
+ Serial & in_cDisplay,
+ RTclock & in_cRTclock
+ );
virtual ~TitleModule();
+ virtual bool canRefresh() { return true; }
virtual void show(bool in_bRefresh);
+
+protected:
+ RTclock & m_cRTclock;
+ tm m_sLastTM;
};
#endif /* __TITLEMODULE_H__ */
--- a/RTclock.lib Wed Oct 08 16:42:17 2014 +0000 +++ b/RTclock.lib Thu Oct 09 08:03:20 2014 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/vtraveller/code/RTclock/#d5b47ff12d17 +http://mbed.org/users/vtraveller/code/RTclock/#1645f55bd0ee
--- a/main.cpp Wed Oct 08 16:42:17 2014 +0000
+++ b/main.cpp Thu Oct 09 08:03:20 2014 +0000
@@ -1,6 +1,8 @@
#include "mbed.h"
-#include "Adafruit_RGBLCDShield.h"
+#include "lcdadafruit.h"
+#include "lcd2004.h"
+#include "keyreadernull.h"
#include "RTclock.h"
#include "DateModule.h"
@@ -18,12 +20,10 @@
// Share the I2C across multiple devices
I2C cI2C(I2C_SDA, I2C_SCL); // D3, D6
cI2C.frequency(400000); // I2C can handle two different frequencies - switch to high speed if asked
-
- MCP23017 cMCP23017(cI2C, 0x20 << 1);
- //MCP23017 cMCP23017(cI2C, 0x27 << 1, true);
-
- Adafruit_RGBLCDShield cLCD(cMCP23017);
- //Adafruit_RGBLCDShield cLCD(cMCP23017,1<<0,1<<1, 1<< 2, 1<<4, 1<<5, 1<<6, 1<<7);
+
+ //LCDadafruit cLCD(cI2C);
+ LCD2004 cLCD(cI2C);
+ KeyReaderNull cKeys(cI2C);
RTclock cClock(cI2C, 0x68 << 1, RTclock::eDS3231);
@@ -33,16 +33,16 @@
// Set up display modules
Module * aModules[] =
{
+ new TitleModule(cLCD,cClock),
new TempModule(cLCD,cI2C,0x18 << 1),
new TimeModule(cLCD,cClock),
new DateModule(cLCD,cClock),
new SyncModule(cLCD,cClock),
- new TitleModule(cLCD),
};
// Set up the menu manager
- MenuManager cMenuManager(aModules,_countof(aModules),cLCD,16,2);
- //MenuManager cMenuManager(aModules,_countof(aModules),cLCD,20,4);
+ // MenuManager cMenuManager(aModules,_countof(aModules),cLCD,cKeys,16,2);
+ MenuManager cMenuManager(aModules,_countof(aModules),cLCD,cKeys);
// Start menu manager loop
cMenuManager.loop();
