D_buttons_menu.ino

This example demonstrates how to use buttons, callback functions and changing text variables.

/*
* LiquidMenu library - buttons_menu.ino
*
* This example demonstrates how to use buttons, callback
* functions and changing text variables.
*
* It creates three screens. The first one displays static
* information. The second displays the analog reading and the
* state of the LED on pin 13. And the third one displays the
* PWM value applied on pin 3. The analog value is read periodically
* and assigned to the attached variable "const short analogValue".
* The LED on pin 13 is changing its state periodically and its
* attached variable is changed also. The PWM output pin 3 is
* controlled via the callback functions attached to its line:
* "void pwm_up()" and "void pwm_down()". To call the functions
* navigate to the third screen using the "left" or "right" buttons,
* focus the line using the "enter" button and then click the "up" or
* "down" button.
*
* The circuit:
* https://github.com/VasilKalchev/LiquidMenu/blob/master/examples/D_buttons_menu/D_buttons_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
* - An LED to Arduino pin 13 (optional)
* - some analog input to Arduino pin A5 (unconnected also works)
*
* 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 to VO
LiquidCrystal lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
/*
* 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).
*/
// Button objects instantiation
const bool pullup = true;
Button left(A0, pullup);
Button right(7, pullup);
Button up(8, pullup);
Button down(9, pullup);
Button enter(10, pullup);
// Variables used to demonstrate PWM control with callback functions.
/*
* Variable 'pwmLevel' is later passed to 'pwm_line' object to be
* displayed and a function is attached to the same LiquidLine object.
* Functions are attached to different LiquidLine objects with a number
* for identification e.g. pwm_line.attach_function(2, func); then when
* menu.call_function(2) is called on some event e.g. button press, the
* function identified with 2 for the focused line is called. Similar
* functions (e.g. for incrementing) can be attached to the different
* LiquidLine objects with the same identification number and then called
* on some event (e.g. 'UP' button) with menu.call_function(2), that will
* call only the function for the focused line that is identified with
* the number 2.
*/
const byte pwmPin = 6;
byte pwmLevel = 0;
// Variables for controlling a pin and displaying the state with text.
// char* is used for adding changing text to the LiquidLine object.
const byte ledPin = LED_BUILTIN;
bool ledState = LOW;
char* ledState_text;
/*
* Variable 'analogValue' is later configured to be printed on the display.
* This time a static variable is used for holding the previous analog value.
*/
const byte analogPin = A5;
unsigned short analogValue = 0;
LiquidLine welcome_line1(1, 0, "LiquidMenu ", LIQUIDMENU_VERSION);
LiquidLine welcome_line2(0, 1, "Buttons example");
LiquidScreen welcome_screen(welcome_line1, welcome_line2);
LiquidLine analog_line(0, 0, "Analog: ", analogValue);
LiquidLine ledState_line(0, 1, "LED is ", ledState_text);
LiquidScreen screen2(analog_line, ledState_line);
LiquidLine pwm_line(0, 0, "PWM level: ", pwmLevel);
LiquidScreen pwm_screen(pwm_line);
LiquidMenu menu(lcd);
// Function to be attached to the pwm_line object.
/*
* This function is used for incrementing the PWM level on the
* 'pwmPin'. It increments the value of 'pwmLevel' and then
* writes it to the pin.
*/
void pwm_up() {
if (pwmLevel < 225) {
pwmLevel += 25;
} else {
pwmLevel = 250;
}
analogWrite(pwmPin, pwmLevel);
}
// Function to be attached to the pwm_line object.
void pwm_down() {
if (pwmLevel > 25) {
pwmLevel -= 25;
} else {
pwmLevel = 0;
}
analogWrite(pwmPin, pwmLevel);
}
void setup() {
Serial.begin(250000);
pinMode(analogPin, INPUT);
pinMode(ledPin, OUTPUT);
pinMode(pwmPin, OUTPUT);
lcd.begin(16, 2);
// Function to attach functions to LiquidLine objects.
pwm_line.attach_function(1, pwm_up);
pwm_line.attach_function(2, pwm_down);
menu.add_screen(welcome_screen);
menu.add_screen(screen2);
menu.add_screen(pwm_screen);
}
void loop() {
// Check all the buttons
if (right.check() == LOW) {
Serial.println(F("RIGHT button pressed"));
menu.next_screen();
}
if (left.check() == LOW) {
Serial.println(F("LEFT button pressed"));
menu.previous_screen();
}
if (up.check() == LOW) {
Serial.println(F("UP button pressed"));
// Calls the function identified with one
// for the focused line.
menu.call_function(1);
}
if (down.check() == LOW) {
Serial.println(F("DOWN button pressed"));
menu.call_function(2);
}
if (enter.check() == LOW) {
Serial.println(F("ENTER button pressed"));
// Switches focus to the next line.
menu.switch_focus();
}
// Periodically switches the state of the LED.
static unsigned long lastMillis = 0;
static unsigned int period = 2000;
if (millis() - lastMillis > period) {
lastMillis = millis();
Serial.print("LED turned ");
if (ledState == LOW) {
ledState = HIGH;
// Changes the text that is printed on the display.
ledState_text = (char*)"ON";
Serial.println(ledState_text);
menu.update();
} else {
ledState = LOW;
ledState_text = (char*)"OFF";
Serial.println(ledState_text);
menu.update();
}
digitalWrite(ledPin, ledState);
// The 'analogValue' is updated every second.
analogValue = analogRead(analogPin);
static unsigned short lastAnalogValue = 0;
if (analogValue != lastAnalogValue) {
lastAnalogValue = analogValue;
menu.update();
}
}
}