Arduino 16x2 LCD Keypad Shield + Nucleo-F030R8 controlling PWM LED with LCD menu
Fork of Nucleo_LCD_Keypad_Shield by
Diff: main.cpp
- Revision:
- 1:fbe0e730a150
- Parent:
- 0:8f6ff5bb5a2d
- Child:
- 2:f07832d7a563
--- a/main.cpp Wed Dec 23 16:58:19 2015 +0000 +++ b/main.cpp Fri Jul 15 12:21:12 2016 +0000 @@ -1,57 +1,363 @@ #include "mbed.h" #include "TextLCD.h" -Serial pc(SERIAL_TX, SERIAL_RX); -AnalogIn button(A0); // Init button (SELECT, LEFT, UP, DOWN, RIGHT) -// LCD (RS, E, D4, D5, D6, D7); +//////////////////////////////// +// instantiations +//////////////////////////////// +Serial pc(SERIAL_TX, SERIAL_RX); +AnalogIn button(A0); // Init button (SELECT, LEFT, UP, DOWN, RIGHT) TextLCD lcd(D8, D9, D4, D5, D6, D7); -PwmOut backlight(D10); // Backlight LCD -DigitalOut led(LED1); +PwmOut backlight(D10); // Backlight LCD +PwmOut blueLed(D15); +Timer t; + +//////////////////////////////// +// variables and constants +//////////////////////////////// + +// keyboard keys +#define COMMAND_NONE 0 +#define COMMAND_UP 1 +#define COMMAND_DOWN 2 +#define COMMAND_LEFT 3 +#define COMMAND_RIGHT 4 +#define COMMAND_SELECT 5 + +// config menu options +#define MENU_NONE 0 +#define MENU_LED_STATE 1 +#define MENU_LED_VALUE 2 + +int menuOptions[2] = { + MENU_LED_STATE, + MENU_LED_VALUE +}; + +// config +struct config_t { + bool ledLit; + bool ledChanged; + float ledValue; -int main() { - - // Set backlight period and duty cycle + config_t():ledLit(true), ledChanged(true), ledValue(0.5){} + +} config; + +// variables +int meas; + +int command = COMMAND_NONE; +int lastCommand = COMMAND_NONE; +bool isInConfig = false; + +int currentOption = MENU_NONE; +int lastOption = currentOption; + +int lastDebounceTime; // the last time the output pin was toggled +int debounceDelay = 100; // the debounce time; increase if the output flickers +int debounceReading = COMMAND_NONE; // last read command from keyboard +int debounceCommand = COMMAND_NONE; // current command +int debounceLastCommand = COMMAND_NONE; // last command + +void printFirstScreen() +{ + lcd.cls(); // Clear LCD + lcd.locate(0, 0); // Set the pointer to the first column, first row + lcd.printf("Press SELECT to enter setup"); // first time initialization +} + +void initialize() +{ + // Start serial USB + pc.baud(9600); + + // Set the LCD backlight backlight.period(0.002); - backlight = 1; - - - lcd.cls(); // Clear LCD - lcd.locate(1,0); // Set locate (1 row, 2 column) - lcd.printf("LCD Key Shield"); - wait(1); - - int meas; - - while(1) { - led = (led == 1) ? 0 : 1; + backlight = 0.7; + + // Print on LCD + printFirstScreen(); + + // Set the LED backlight + blueLed.period(0.001); // blueLed.period: 0.01 = 100Hz; 0.02 = 50Hz; 0.001 = 1kHz; 0.0001 = 10kHz; + + // Start the timer + t.start(); - meas = button.read() * 1000; // Read the analog input value (value from 0.0 to 1.0) and convert to int value (from 0 to 1000) - - lcd.cls(); - lcd.locate(0,0); - lcd.printf("Press button"); - lcd.locate(0,1); - - if (meas < 50) { - lcd.printf("BUTTON: Right "); - backlight = 0.5; // Set 50% backlight + // Serial debug + pc.printf("Initialization complete\n"); +} + +// the debounce was taken from https://www.arduino.cc/en/Tutorial/Debounce +void readKeyboard() +{ + meas = button.read() * 1000; // Read the analog input value (value from 0.0 to 1.0) and convert to int value (from 0 to 1000) + + // read the buttons + // right < 40 + // up: 130 - 170 + // down: 360 - 400 + // left: 580 - 620 + // select: 920 - 960 + // no button pressed: 1000 + + // set a temporary command for the button that has been pushed + if (meas < 40) { // right button + debounceReading = COMMAND_RIGHT; + } + else if (meas > 130 && meas < 170) { // up button + debounceReading = COMMAND_UP; + } + else if (meas > 360 && meas < 400) { // down button + debounceReading = COMMAND_DOWN; + } + else if (meas > 580 && meas < 620) { // left button + debounceReading = COMMAND_LEFT; + } + else if (meas > 920 && meas < 960) { // select button + debounceReading = COMMAND_SELECT; + } + else { + debounceReading = COMMAND_NONE; + } + + int milliseconds = t.read_ms(); + int lastPushedTime = milliseconds - lastDebounceTime; + + // a button has been pushed or released + if (debounceReading != debounceLastCommand) { + // reset the debouncing timer + lastDebounceTime = t.read_ms(); + } + + if (lastPushedTime > debounceDelay && debounceReading != debounceCommand) { + debounceCommand = debounceReading; + command = debounceCommand; + } + + debounceLastCommand = debounceReading; + + // reset the timer if keyboard is idle for a specific amount of time + if (debounceReading == COMMAND_NONE && lastPushedTime > 1200e3) { // 1200e3 = 20min + t.reset(); + } +} + +/* +void printKeyboardCommandOnLCD() +{ + if (command != lastCommand) + { + if (command != COMMAND_NONE) { + lcd.cls(); + lcd.locate(0, 0); } - else if (meas < 210) { + + if (command == COMMAND_RIGHT) { + lcd.printf("BUTTON: Right"); + } + else if (command == COMMAND_UP) { lcd.printf("BUTTON: Up"); - backlight = 1; // Power ON backlight - } - else if (meas < 460){ + } + else if (command == COMMAND_DOWN) { lcd.printf("BUTTON: Down"); - backlight = 0; // Power OFF backlight - } - else if (meas < 720){ - lcd.printf("BUTTON: Left"); - } - else if (meas > 950){ + } + else if (command == COMMAND_LEFT) { + lcd.printf("BUTTON: Left"); + } + else if (command == COMMAND_SELECT) { lcd.printf("BUTTON: Select"); } - pc.printf("BUTTON: %4d\n", meas); - - wait(0.1); + } +} +*/ + +void resetKeyboardCommand() +{ + lastCommand = command; +} + +void resetMenuOption() +{ + lastOption = currentOption; +} + +void handleLed() +{ + // LED config has changed + if (config.ledChanged) + { + config.ledChanged = false; + + if (config.ledLit) { + blueLed = config.ledValue; // the LED is off + } else { + blueLed = 0; + } + } +} + +void clearLCDSecondRow() +{ + lcd.locate(0, 1); + lcd.printf(" "); + //lcd.printf("%*.0i", 16, 0); +} + +void printLedStateConfig() +{ + lcd.locate(0, 1); + lcd.printf("< LED On:"); + lcd.locate(10, 1); + lcd.printf(config.ledLit ? "Yes" : "No"); + lcd.locate(14, 1); + lcd.printf(" >"); +} + +void printLedValueConfig() +{ + lcd.locate(0, 1); + lcd.printf("< LED Val:"); + lcd.locate(10, 1); + lcd.printf("%.2f", config.ledValue); + lcd.locate(14, 1); + lcd.printf(" >"); +} + +// handle keyboard input +void handleConfigMenu() +{ + // a new command has been triggered + if (command != lastCommand) + { + if (isInConfig) + { + // exit the config menu + if (command == COMMAND_SELECT) + { + printFirstScreen(); + isInConfig = false; + + // revert/reset everything to the first state + currentOption = MENU_NONE; + resetMenuOption(); + command = COMMAND_NONE; + resetKeyboardCommand(); + } + // scroll through menu options + else if (command == COMMAND_LEFT || command == COMMAND_RIGHT) + { + // search for current element position + int menuOptionsSize = sizeof(menuOptions) / sizeof(int); + int pos = 0; + while (pos < menuOptionsSize && currentOption != menuOptions[pos]) { + pos++; + } + + if (command == COMMAND_LEFT) + { + if (pos == 0) { + currentOption = menuOptions[menuOptionsSize - 1]; + } else { + currentOption = menuOptions[--pos]; + } + } + else if (command == COMMAND_RIGHT) + { + if (pos == (menuOptionsSize - 1)) { + currentOption = menuOptions[0]; + } else { + currentOption = menuOptions[++pos]; + } + } + } + // scroll through menu settings + else if (command == COMMAND_UP || command == COMMAND_DOWN) + { + // the LED state has changed + if (currentOption == MENU_LED_STATE) { + config.ledLit = !config.ledLit; + config.ledChanged = true; + + clearLCDSecondRow(); + printLedStateConfig(); + } + // the LED value has changed + else if (currentOption == MENU_LED_VALUE) { + bool valChanged = false; + if (command == COMMAND_UP) { + if (config.ledValue < 1.0f) { + config.ledValue += 0.1; + valChanged = true; + } + } else if (command == COMMAND_DOWN) { + if (config.ledValue > 0.2) { + config.ledValue -= 0.1; + valChanged = true; + } + } + + if (valChanged) { + config.ledChanged = true; + + clearLCDSecondRow(); + printLedValueConfig(); + } + } + } + } + else { + // enter in config menu + if (command == COMMAND_SELECT) + { + lcd.cls(); + lcd.locate(0, 0); + lcd.printf("MENU CONFIG"); + + isInConfig = true; + currentOption = MENU_LED_STATE; + } + } + + // a new command has been triggered + // browse through options + if (currentOption != lastOption) + { + // clear second row + clearLCDSecondRow(); + + // LED state + if (currentOption == MENU_LED_STATE) + { + printLedStateConfig(); + } + // LED value + else if (currentOption == MENU_LED_VALUE) + { + printLedValueConfig(); + } + } + } +} + +int main() +{ + initialize(); + + while(1) + { + // keyboard routines + readKeyboard(); + //printKeyboardCommandOnLCD(); + + // config menu routines + handleConfigMenu(); + + // actions routines + handleLed(); + + // reset everything + resetKeyboardCommand(); + resetMenuOption(); } } \ No newline at end of file