You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
319 lines
8.7 KiB
319 lines
8.7 KiB
/*
|
|
* LiquidMenu library - functions_menu.ino
|
|
*
|
|
* This example demonstrates how to attach functions to the
|
|
* "lines" in the menu.
|
|
*
|
|
* Attaching functions to the different "lines" in the menu makes it
|
|
* possible to execute an action through the menu (e.g. dimming an LED,
|
|
* adjusting preferences...). To attach a function to a line you need
|
|
* to create with signature "void functionName(void)". After creating it,
|
|
* the function is ready to be attached to a line. To dothat call bool
|
|
* LiquidLine::attach_function(uint8_t number, void (*function)(void)).
|
|
* LiquidLine is the line object you wish to attach the function to,
|
|
* number is the "id" of the function for that line, void (*function)(void)
|
|
* is just the name of the function without the "()". The "id" of the function
|
|
* makes possible attaching multiple functions to a single line. An example use
|
|
* of multiple functions on a single line is for incrementing or decrementing
|
|
* some value (e.g. dimming an LED). It is convenient to attach all the different
|
|
* incrementing functions (e.g. increase_brightness(), increase_volume()) to the
|
|
* different lines (e.g. LED brightness: 5, Sound volume: 10) using the same id
|
|
* (e.g. 1). Same goes for the decrementing functions (e.g. LED brightness: 5 (line)
|
|
* with attached function decrease_brightness() (function) with id 2,
|
|
* Sound volume: 10 (line) with attached function decrease_volume() (function) with id 2).
|
|
* Similar functions should be attached to their corresponding lines with the same "id",
|
|
* because then they can be called from the same event (e.g. pressing button "UP"
|
|
* calls the incrementing function of whatever the focused line is).
|
|
* This example has a line that shows the current PWM of the LED and lines
|
|
* that allow a fade or blink loop to be turned ON/OFF and configured.
|
|
*
|
|
* The circuit:
|
|
* https://github.com/VasilKalchev/LiquidMenu/blob/master/examples/functions_menu/C_functions_menu.png
|
|
* - LCD RS pin to Arduino pin 12
|
|
* - LCD E pin to Arduino pin 11
|
|
* - LCD D4 pin to Arduino pin 5
|
|
* - LCD D5 pin to Arduino pin 4
|
|
* - LCD D6 pin to Arduino pin 3
|
|
* - LCD D7 pin to Arduino pin 2
|
|
* - LCD R/W pin to ground
|
|
* - LCD VSS pin to ground
|
|
* - LCD VDD pin to 5V
|
|
* - 10k ohm potentiometer: ends to 5V and ground, wiper to LCD V0
|
|
* - 150 ohm resistor from 5V to LCD Anode
|
|
* - LCD Cathode to ground
|
|
* - ----
|
|
* - Button (left) to Arduino pin A0 and ground
|
|
* - Button (right) to Arduino pin 7 and ground
|
|
* - Button (up) to Arduino pin 8 and ground
|
|
* - Button (down) to Arduino pin 9 and ground
|
|
* - Button (enter) to Arduino pin 10 and ground
|
|
* - A PWM controlled device (LED...) to Arduino pin 6
|
|
*
|
|
* Created July 24, 2016
|
|
* by Vasil Kalchev
|
|
*
|
|
* https://github.com/VasilKalchev/LiquidMenu
|
|
*
|
|
*/
|
|
|
|
#include <LiquidCrystal.h>
|
|
#include <LiquidMenu.h>
|
|
#include "Button.h"
|
|
|
|
// Pin mapping for the display
|
|
const byte LCD_RS = 12;
|
|
const byte LCD_E = 11;
|
|
const byte LCD_D4 = 5;
|
|
const byte LCD_D5 = 4;
|
|
const byte LCD_D6 = 3;
|
|
const byte LCD_D7 = 2;
|
|
//LCD R/W pin to ground
|
|
//10K potentiometer wiper to VO
|
|
LiquidCrystal lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
|
|
|
|
// This variable can be passed to the LiquidMenu object to set the starting screen.
|
|
const byte startingScreen = 2;
|
|
|
|
// Button objects instantiation
|
|
/*
|
|
* The Button class is not a part of the LiquidMenu library. The first
|
|
* parameter is the button's pin, the second enables or disables the
|
|
* internal pullup resistor (not required) and the third is the debounce
|
|
* time (not required).
|
|
*/
|
|
const bool pullup = true;
|
|
Button left(A0, pullup);
|
|
Button right(7, pullup);
|
|
Button up(8, pullup);
|
|
Button down(9, pullup);
|
|
Button enter(10, pullup);
|
|
|
|
/*
|
|
* An enumerator can be used for the callback functions. It sets the number
|
|
* for similar functions. Later when a function is attached it can be passed
|
|
* with this enum rather than a magic number.
|
|
*/
|
|
// There are two types of functions for this example, one that increases some
|
|
// value and one that decreases it.
|
|
enum FunctionTypes {
|
|
increase = 1,
|
|
decrease = 2,
|
|
};
|
|
|
|
// These are the pin definitions and variables for their PWM state.
|
|
const byte led = 6;
|
|
byte led_level = 0;
|
|
|
|
// Variables used for setting "preferences".
|
|
bool isFading = false;
|
|
char* isFading_text;
|
|
unsigned int fadePeriod = 100;
|
|
bool isBlinking = false;
|
|
char* isBlinking_text;
|
|
unsigned int blinkPeriod = 1000;
|
|
|
|
|
|
LiquidLine welcome_line1(1, 0, "LiquidMenu ", LIQUIDMENU_VERSION);
|
|
LiquidLine welcome_line2(1, 1, "Functions ex.");
|
|
LiquidScreen welcome_screen(welcome_line1, welcome_line2);
|
|
|
|
LiquidLine ledTitleLine(6, 0, "LED");
|
|
LiquidLine led_line(4, 1, "Level: ", led_level);
|
|
LiquidScreen led_screen(ledTitleLine, led_line);
|
|
|
|
LiquidLine fade_line(0, 0, "Fade - ", isFading_text);
|
|
LiquidLine fadePeriod_line(0, 1, "Period: ", fadePeriod, "ms");
|
|
LiquidScreen fade_screen(fade_line, fadePeriod_line);
|
|
|
|
LiquidLine blink_line(0, 0, "Blink - ", isBlinking_text);
|
|
LiquidLine blinkPeriod_line(0, 1, "Period: ", blinkPeriod, "ms");
|
|
LiquidScreen blink_screen(blink_line, blinkPeriod_line);
|
|
|
|
LiquidMenu menu(lcd, startingScreen);
|
|
|
|
// Callback functions
|
|
void increase_led_level() {
|
|
if (led_level < 225) {
|
|
led_level += 25;
|
|
} else {
|
|
led_level = 0;
|
|
}
|
|
analogWrite(led, led_level);
|
|
}
|
|
|
|
void decrease_led_level() {
|
|
if (led_level > 25) {
|
|
led_level -= 25;
|
|
} else {
|
|
led_level = 250;
|
|
}
|
|
analogWrite(led, led_level);
|
|
}
|
|
|
|
void fade_switch() {
|
|
led_off();
|
|
if (isFading == true) {
|
|
isFading = false;
|
|
isFading_text = (char*)"OFF";
|
|
} else {
|
|
isFading = true;
|
|
isFading_text = (char*)"ON";
|
|
isBlinking = false;
|
|
isBlinking_text = (char*)"OFF";
|
|
}
|
|
}
|
|
|
|
void increase_fadePeriod() {
|
|
if (fadePeriod < 3000) {
|
|
fadePeriod += 10;
|
|
}
|
|
}
|
|
|
|
void decrease_fadePeriod() {
|
|
if (fadePeriod > 10) {
|
|
fadePeriod -= 10;
|
|
}
|
|
}
|
|
|
|
void blink_switch() {
|
|
led_off();
|
|
if (isBlinking == true) {
|
|
isBlinking = false;
|
|
isBlinking_text = (char*)"OFF";
|
|
} else {
|
|
isBlinking = true;
|
|
isBlinking_text = (char*)"ON";
|
|
isFading = false;
|
|
isFading_text = (char*)"OFF";
|
|
}
|
|
}
|
|
|
|
void increase_blinkPeriod() {
|
|
if (blinkPeriod < 3000) {
|
|
blinkPeriod += 50;
|
|
}
|
|
}
|
|
|
|
void decrease_blinkPeriod() {
|
|
if (blinkPeriod > 50) {
|
|
blinkPeriod -= 50;
|
|
}
|
|
}
|
|
|
|
void led_off() {
|
|
led_level = 0;
|
|
analogWrite(led, led_level);
|
|
}
|
|
|
|
// Checks all the buttons.
|
|
void buttonsCheck() {
|
|
if (right.check() == LOW) {
|
|
menu.next_screen();
|
|
}
|
|
if (left.check() == LOW) {
|
|
menu.previous_screen();
|
|
}
|
|
if (up.check() == LOW) {
|
|
// Calls the function identified with
|
|
// increase or 1 for the focused line.
|
|
menu.call_function(increase);
|
|
}
|
|
if (down.check() == LOW) {
|
|
menu.call_function(decrease);
|
|
}
|
|
if (enter.check() == LOW) {
|
|
// Switches focus to the next line.
|
|
menu.switch_focus();
|
|
}
|
|
}
|
|
|
|
// The fading function.
|
|
void fade() {
|
|
static bool goingUp = true;
|
|
if (goingUp) {
|
|
led_level += 25;
|
|
} else {
|
|
led_level -= 25;
|
|
}
|
|
if (led_level > 225) {
|
|
goingUp = false;
|
|
led_level = 250;
|
|
}
|
|
if (led_level < 25 && goingUp == false) {
|
|
goingUp = true;
|
|
led_level = 0;
|
|
}
|
|
analogWrite(led, led_level);
|
|
}
|
|
|
|
// The blinking function.
|
|
void blink() {
|
|
static bool blinkState = LOW;
|
|
if (blinkState == LOW) {
|
|
blinkState = HIGH;
|
|
led_level = 255;
|
|
} else {
|
|
blinkState = LOW;
|
|
led_level = 0;
|
|
}
|
|
analogWrite(led, led_level);
|
|
}
|
|
|
|
void setup() {
|
|
Serial.begin(250000);
|
|
|
|
pinMode(led, OUTPUT);
|
|
|
|
lcd.begin(16, 2);
|
|
|
|
// The increasing functions are attached with identification of 1.
|
|
/*
|
|
* This function can later be called by pressing the 'UP' button
|
|
* when 'led_line' is focused. If some other line is focused it's
|
|
* corresponding function will be called.
|
|
*/
|
|
led_line.attach_function(increase, increase_led_level);
|
|
// The decreasing functions are attached with identification of 2.
|
|
led_line.attach_function(decrease, decrease_led_level);
|
|
|
|
// Here the same function is attached with two different identifications.
|
|
// It will be called on 'UP' or 'DOWN' button press.
|
|
fade_line.attach_function(1, fade_switch);
|
|
fade_line.attach_function(2, fade_switch);
|
|
fadePeriod_line.attach_function(increase, increase_fadePeriod);
|
|
fadePeriod_line.attach_function(decrease, decrease_fadePeriod);
|
|
|
|
blink_line.attach_function(1, blink_switch);
|
|
blink_line.attach_function(2, blink_switch);
|
|
blinkPeriod_line.attach_function(increase, increase_blinkPeriod);
|
|
blinkPeriod_line.attach_function(decrease, decrease_blinkPeriod);
|
|
|
|
menu.add_screen(welcome_screen);
|
|
menu.add_screen(led_screen);
|
|
menu.add_screen(fade_screen);
|
|
menu.add_screen(blink_screen);
|
|
|
|
isFading_text = (char*)"OFF";
|
|
isBlinking_text = (char*)"OFF";
|
|
|
|
menu.update();
|
|
}
|
|
|
|
void loop() {
|
|
buttonsCheck();
|
|
|
|
static unsigned long lastMillis_blink = 0;
|
|
if ((isFading == true) && ((millis() - lastMillis_blink) > fadePeriod)) {
|
|
lastMillis_blink = millis();
|
|
fade();
|
|
menu.update();
|
|
}
|
|
|
|
static unsigned long lastMillis_fade = 0;
|
|
if ((isBlinking == true) && ((millis() - lastMillis_fade) > blinkPeriod)) {
|
|
lastMillis_fade = millis();
|
|
blink();
|
|
menu.update();
|
|
}
|
|
|
|
}
|
|
|