first commit
21
libraries/LCDMenuLib2/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) [2021] [Nils Feldkämper]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
76
libraries/LCDMenuLib2/README.md
Normal file
@@ -0,0 +1,76 @@
|
||||
Arduino LCDMenuLib2 (LCDML) with layers for any LCD Type (Row Displays, Graphic Displays, Console output)
|
||||
=================================================================
|
||||
|
||||
https://github.com/Jomelo/LCDMenuLib2/wiki/Code-Reference
|
||||
|
||||
Features:
|
||||
* max 254 menu elements
|
||||
* max 254 menu elements per layer
|
||||
* based on a tree model (parent, child, sibling)
|
||||
* min 3 buttons needed up, down, enter
|
||||
* support for 6 defined buttons up, down, left, right, back/quit, enter
|
||||
* support for 64 custom events it could be a button click or something else. This events could be combined with a special handling to open a defined menu function when the status is changed.
|
||||
* separation of structural and functional level
|
||||
* support for screensaver which is shown after x seconds
|
||||
* display a scrollbar when more menu elements in a layer then display rows
|
||||
* the menu function are only updated when a button is hit / a custom event is called or a trigger is set
|
||||
* it is possible to set special conditions to display an element
|
||||
* it is possible to change parameter direct from the menu
|
||||
* possibility to jump from one menu element directly to another
|
||||
* examples for many different LCD libraries
|
||||
* examples for different functionality (change param, set params, ...)
|
||||
|
||||
|
||||
Attention:
|
||||
* when you change from LCDMenuLib v2.3.4 to LCDMenuLib2 v1.0.0 or higher
|
||||
** the backend system is removed from this lib use this when you need a task system: https://github.com/arkhipenko/TaskScheduler
|
||||
|
||||
|
||||
Description (German):
|
||||
http://forum.arduino.cc/index.php?topic=73816.0
|
||||
|
||||
Images:
|
||||
|
||||
* 20x4
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
* glcd with u8glib
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
* serial monitor for testing or programming without a connected display
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) [2021] [Nils Feldkämper]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
// ============================================================
|
||||
// Example: LCDML_serialmonitor
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example includes the complete functionality over some
|
||||
// tabs. All Tabs which are started with "LCDML_display_.."
|
||||
// generates an output on the display / console / ....
|
||||
// This example is for the author to test the complete functionality
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings for non arduino basic controllers
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// *********************************************************************
|
||||
// includes
|
||||
// *********************************************************************
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML display settings
|
||||
// *********************************************************************
|
||||
// settings for LCD
|
||||
#define _LCDML_DISP_cols 20
|
||||
#define _LCDML_DISP_rows 4
|
||||
|
||||
// enable this line (set to 1) to show a header above the first menu element
|
||||
// this function can be changed in LCDML_display_menu tab
|
||||
#define _LCDML_DSIP_use_header 0
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows-_LCDML_DSIP_use_header, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "P1 dummy" , NULL); // NULL = no menu function
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "P1 Settings" , NULL); // NULL = no menu function
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 1" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 2" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 3" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// Example function for event handling (only serial output in this example)
|
||||
LCDML_add (23 , LCDML_0 , 8 , "Event Handling" , mFunc_exampleEventHandling); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 23
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Some settings which can be used
|
||||
|
||||
// Enable Menu Rollover
|
||||
//LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
|
||||
// In the following line the new event handling system ins configured
|
||||
// you can use 0 - 3 special events when calling the LCDML.CE_set(id) function
|
||||
// when you need more events you can change in LCDMenuLib.h the number until 0-63
|
||||
LCDML.CE_setOnChangeCbFunction(0, mFunc_exampleEventHandling);
|
||||
//LCDML.CE_setOnChangeCbFunction(1, your_special_menu_function);
|
||||
//...
|
||||
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
LCDML.loop();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("dynValue:");
|
||||
Serial.print(g_dynParam);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
for(uint8_t i=0;i<15;i++) {
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// init vars
|
||||
//uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
|
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate() || LCDML.DISP_checkMenuCursorUpdate() ) {
|
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear();
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ Menu ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = (_LCDML_DISP_rows - _LCDML_DSIP_use_header) + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// Display a header with the parent element name
|
||||
if(_LCDML_DSIP_use_header > 0)
|
||||
{
|
||||
// only one line
|
||||
if(LCDML.MENU_getLayer() == 0)
|
||||
{
|
||||
// this text is displayed when no header is available
|
||||
Serial.println(F("Root Menu"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Display parent name
|
||||
LCDML_getContent(content_text, LCDML.MENU_getParentID());
|
||||
Serial.print(content_text);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// display cursor
|
||||
if (n == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
Serial.print(F("(x) "));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("( ) "));
|
||||
}
|
||||
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
Serial.print(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,414 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
Serial.println(F("To close this"));
|
||||
Serial.println(F("function press"));
|
||||
Serial.println(F("any button or use"));
|
||||
Serial.println(F("back button"));
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("wait 20 seconds or press back button"));
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000)) {
|
||||
g_func_timer_info--; // increment the value every second
|
||||
Serial.println(g_func_timer_info); // print the time counter value
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("press a or w"));
|
||||
Serial.println(F("count: 0 of 3"));
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
Serial.print(F("count: "));
|
||||
Serial.print(g_button_value); //print change content
|
||||
Serial.println(F(" of 3"));
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("start screensaver"));
|
||||
Serial.println(F("press any key to quit"));
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop())
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close())
|
||||
{
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.print(F("parameter: "));
|
||||
Serial.println(param);
|
||||
|
||||
Serial.println(F("press any key"));
|
||||
Serial.println(F("to leave it"));
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_exampleEventHandling(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
//LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
LCDML.FUNC_setGBA();
|
||||
|
||||
// display content
|
||||
Serial.println("Event handling function is active");
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
// this function is only working when a loop timer is set
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
|
||||
// check if any event is active
|
||||
if(LCDML.CE_checkAny())
|
||||
{
|
||||
// check if the defined command char is pressed
|
||||
if(LCDML.CE_check(0))
|
||||
{
|
||||
Serial.println(F("The defined command char is enabled"));
|
||||
}
|
||||
|
||||
// check if a special char was pressed
|
||||
// there are 10 defined special chars in control tab
|
||||
for(uint8_t i=1; i<=10; i++)
|
||||
{
|
||||
if(LCDML.CE_check(i))
|
||||
{
|
||||
Serial.print(F("The command number: "));
|
||||
Serial.print(i-1);
|
||||
Serial.println(F(" is pressed"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("This function is called by menu, not over the callback function"));
|
||||
Serial.println(F("Press 'c' or a number to display the content"));
|
||||
}
|
||||
LCDML.CE_resetAll();
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
|
||||
// reset all events
|
||||
LCDML.CE_resetAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
// ============================================================
|
||||
// Example: LCDML_serialmonitor
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example includes the complete functionality over some
|
||||
// tabs. All Tabs which are started with "LCDML_display_.."
|
||||
// generates an output on the display / console / ....
|
||||
// This example is for the author to test the complete functionality
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// *********************************************************************
|
||||
// includes
|
||||
// *********************************************************************
|
||||
#include <LiquidCrystal.h>
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML display settings
|
||||
// *********************************************************************
|
||||
// settings for LCD
|
||||
#define _LCDML_DISP_cols 20
|
||||
#define _LCDML_DISP_rows 4
|
||||
|
||||
// enable this line (set to 1) to show a header above the first menu element
|
||||
// this function can be changed in LCDML_display_menu tab
|
||||
#define _LCDML_DSIP_use_header 0
|
||||
|
||||
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
|
||||
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
|
||||
|
||||
// LCD object
|
||||
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
|
||||
LiquidCrystal lcd(22, 24, 9, 10, 11, 12);
|
||||
|
||||
const uint8_t scroll_bar[5][8] = {
|
||||
{B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top
|
||||
{B11111, B11111, B10001, B10001, B10001, B10001, B10001, B10001}, // scroll state 1
|
||||
{B10001, B10001, B11111, B11111, B10001, B10001, B10001, B10001}, // scroll state 2
|
||||
{B10001, B10001, B10001, B10001, B11111, B11111, B10001, B10001}, // scroll state 3
|
||||
{B10001, B10001, B10001, B10001, B10001, B10001, B11111, B11111} // scrollbar bottom
|
||||
};
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
// *********************************************************************
|
||||
// Global variables
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows-_LCDML_DSIP_use_header, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "P1 dummy" , NULL); // NULL = no menu function
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "P1 Settings" , NULL); // NULL = no menu function
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 1" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 2" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 3" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 22
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// LCD Begin
|
||||
lcd.begin(_LCDML_DISP_cols,_LCDML_DISP_rows);
|
||||
// set special chars for scrollbar
|
||||
lcd.createChar(0, (uint8_t*)scroll_bar[0]);
|
||||
lcd.createChar(1, (uint8_t*)scroll_bar[1]);
|
||||
lcd.createChar(2, (uint8_t*)scroll_bar[2]);
|
||||
lcd.createChar(3, (uint8_t*)scroll_bar[3]);
|
||||
lcd.createChar(4, (uint8_t*)scroll_bar[4]);
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Some settings which can be used
|
||||
|
||||
// Enable Menu Rollover
|
||||
LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
LCDML.loop();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "dynValue: %d", g_dynParam);
|
||||
|
||||
// use the line from function parameters
|
||||
lcd.setCursor(1, (line + _LCDML_DSIP_use_header));
|
||||
lcd.print(buf);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate()) {
|
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear();
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = (_LCDML_DISP_rows - _LCDML_DSIP_use_header) + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// Display a header with the parent element name
|
||||
if(_LCDML_DSIP_use_header > 0)
|
||||
{
|
||||
// only one line
|
||||
if(LCDML.MENU_getLayer() == 0)
|
||||
{
|
||||
// this text is displayed when no header is available
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print(F("Root Menu"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Display parent name
|
||||
LCDML_getContent(content_text, LCDML.MENU_getParentID());
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print(content_text);
|
||||
}
|
||||
}
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
lcd.setCursor(1, (n+_LCDML_DSIP_use_header));
|
||||
lcd.print(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.DISP_checkMenuCursorUpdate())
|
||||
{
|
||||
// init vars
|
||||
uint8_t n_max = (LCDML.MENU_getChilds() >= (_LCDML_DISP_rows - _LCDML_DSIP_use_header)) ? (_LCDML_DISP_rows - _LCDML_DSIP_use_header) : (LCDML.MENU_getChilds());
|
||||
uint8_t scrollbar_min = 0;
|
||||
uint8_t scrollbar_max = LCDML.MENU_getChilds();
|
||||
uint8_t scrollbar_cur_pos = LCDML.MENU_getCursorPosAbs();
|
||||
uint8_t scroll_pos = ((1.*n_max * (_LCDML_DISP_rows - _LCDML_DSIP_use_header)) / (scrollbar_max - 1) * scrollbar_cur_pos);
|
||||
|
||||
|
||||
// display rows
|
||||
for (uint8_t n = 0; n < n_max; n++)
|
||||
{
|
||||
//set cursor
|
||||
lcd.setCursor(0, (n+_LCDML_DSIP_use_header));
|
||||
|
||||
//set cursor char
|
||||
if (n == LCDML.MENU_getCursorPos()) {
|
||||
lcd.write(_LCDML_DISP_cfg_cursor);
|
||||
} else {
|
||||
lcd.write(' ');
|
||||
}
|
||||
|
||||
// delete or reset scrollbar
|
||||
if (_LCDML_DISP_cfg_scrollbar == 1) {
|
||||
if (scrollbar_max > n_max) {
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), (n+_LCDML_DSIP_use_header));
|
||||
lcd.write((uint8_t)0);
|
||||
}
|
||||
else {
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), (n+_LCDML_DSIP_use_header));
|
||||
lcd.print(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// display scrollbar
|
||||
if (_LCDML_DISP_cfg_scrollbar == 1) {
|
||||
if (scrollbar_max > n_max) {
|
||||
//set scroll position
|
||||
if (scrollbar_cur_pos == scrollbar_min) {
|
||||
// min pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), (0+_LCDML_DSIP_use_header));
|
||||
lcd.write((uint8_t)1);
|
||||
} else if (scrollbar_cur_pos == (scrollbar_max - 1)) {
|
||||
// max pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1 + _LCDML_DSIP_use_header));
|
||||
lcd.write((uint8_t)4);
|
||||
} else {
|
||||
// between
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), (scroll_pos / n_max + _LCDML_DSIP_use_header));
|
||||
lcd.write((uint8_t)(scroll_pos % n_max) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(F("To close this"));
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("function press"));
|
||||
lcd.setCursor(0, 2);
|
||||
lcd.print(F("any button or use"));
|
||||
lcd.setCursor(0, 3);
|
||||
lcd.print(F("back button"));
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
lcd.print(F("20 sec wait")); // print some content on first row
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000)) {
|
||||
g_func_timer_info--; // increment the value every second
|
||||
lcd.setCursor(0, 0); // set cursor pos
|
||||
lcd.print(F(" "));
|
||||
lcd.setCursor(0, 0); // set cursor pos
|
||||
lcd.print(g_func_timer_info); // print the time counter value
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
// print LCD content
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(F("press left or up"));
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("count: 0 of 3"));
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
// update LCD content
|
||||
lcd.setCursor(7, 1); // set cursor
|
||||
lcd.print(g_button_value); // print change content
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// update LCD content
|
||||
lcd.setCursor(0, 0); // set cursor
|
||||
lcd.print(F("screensaver")); // print change content
|
||||
lcd.setCursor(0, 1); // set cursor
|
||||
lcd.print(F("press any key"));
|
||||
lcd.setCursor(0, 2); // set cursor
|
||||
lcd.print(F("to leave it"));
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop())
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close())
|
||||
{
|
||||
// The screensaver go to the root menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function and go a layer back
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "parameter: %d", param);
|
||||
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(buf);
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("press any key"));
|
||||
lcd.setCursor(0, 2);
|
||||
lcd.print(F("to leave it"));
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
// ============================================================
|
||||
// Example: LCDML_simpleThread example
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example includes the complete functionality over some
|
||||
// tabs. All Tabs which are started with "LCDML_display_.."
|
||||
// generates an output on the display / console / ....
|
||||
// This example is for the author to test the complete functionality
|
||||
//
|
||||
// The simpleThread Library provides a method to to run more then
|
||||
// one loop function. The loop functions are called with a priority
|
||||
// and a time interval. The lib is not using interrupts.
|
||||
// When a function is called it runs until the function end is reached.
|
||||
//
|
||||
// Download simple thread:
|
||||
// https://github.com/Jomelo/simpleThread
|
||||
//
|
||||
// documentation (german):
|
||||
// https://forum.arduino.cc/index.php?topic=165552.0
|
||||
//
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// *********************************************************************
|
||||
// includes
|
||||
// *********************************************************************
|
||||
#include <LCDMenuLib2.h>
|
||||
#include <simpleThread.h>
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML display settings
|
||||
// *********************************************************************
|
||||
// settings for LCD
|
||||
#define _LCDML_DISP_cols 20
|
||||
#define _LCDML_DISP_rows 4
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Blink Thread" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "Start Thread" , mFunc_thread_start); // Thread control (start)
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "Stop Thread" , mFunc_thread_stop); // Thread control (stop)
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 1" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 2" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 3" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 22
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Simple Thread configuration
|
||||
// *********************************************************************
|
||||
// define the thread number _sT_cnt_1 => 1, _sT_cnt_2 => 2, ....
|
||||
#define _sT_cnt _sT_cnt_3
|
||||
|
||||
// initialisation
|
||||
simpleThread_init(_sT_cnt);
|
||||
|
||||
/* create a new thread
|
||||
* - params for "timebased_static" and "timebased_dynamic" (dynamic: the runtime can be changed)
|
||||
* param 1: priority (unique id) (the first is "_sT_P1", next one "_sT_P2", ...)
|
||||
* param 2: time mode: "_sT_millis" or "_sT_micros"
|
||||
* param 3: waittime as unsigned long ( 50UL or something else with UL at the end)
|
||||
* param 4: the current state of a thread "_sT_start" or "_sT_stop" or "_sT_stable"
|
||||
* ("_sT_stable" => a stable state function is called)
|
||||
* param 5: callback function name
|
||||
*
|
||||
* - params for "eventbased"
|
||||
* param 1: param 1: priority (unique id) (the first is "_sT_P1", next one "_sT_P2", ...)
|
||||
* param 2: callback function name
|
||||
*/
|
||||
simpleThread_new_timebased_static (_sT_P1 , _sT_micros, 0 , _sT_start , Thread_input_check);
|
||||
simpleThread_new_timebased_static (_sT_P2 , _sT_millis, 1000UL , _sT_stop , Thread_Serial_Blink_Example);
|
||||
simpleThread_new_timebased_static (_sT_P3 , _sT_millis, 100UL , _sT_start , Thread_LCDMenuLib);
|
||||
|
||||
/* simple thread control makros reference
|
||||
* initialisation:
|
||||
* ===============
|
||||
* void simpleThread_init( number of threads )
|
||||
* void simpleThread_new_timebased_static(unique_id, time_mode, wait_time, current_state, callback_function)
|
||||
* void simpleThread_new_timebased_dynamic(unique_id, time_mode, wait_time, current_state, callback_function)
|
||||
* void simpleThread_new_eventbased(unique_id, callback_function)
|
||||
*
|
||||
* setup initialisation:
|
||||
* ===============
|
||||
* void simpleThread_initSetup(_sT_cnt); // do no change something here
|
||||
*
|
||||
* loop initialisation:
|
||||
* ===============
|
||||
* void simpleThread_run(_sT_priority);
|
||||
* or
|
||||
* void simpleThread_run(_sT_no_priority); // the return value of simpleThread_loop is set to true
|
||||
*
|
||||
* create a thread function:
|
||||
* ===============
|
||||
* void simpleThread_setup(callback_function)
|
||||
* boolean simpleThread_loop(callback_function) // return true => go to the next function (use this when the
|
||||
* wait_time is 0 to call the other threads
|
||||
* // return false => go to the begin of the thread list
|
||||
* void simpleThread_stable(callback_function)
|
||||
*
|
||||
* thread handling:
|
||||
* ===============
|
||||
* void simpleThread_start(callback_function)
|
||||
* void simpleThread_stop(callback_function)
|
||||
* void simpleThread_reset(callback_function) // setup function is called on the next start
|
||||
* void simpleThread_restart(callback_function) // reset and start
|
||||
*
|
||||
* void simpleThread_event_start(callback_function)
|
||||
* void simpleThread_event_reset(callback_function) // setup function is called on the next start
|
||||
* void simpleThread_event_restart(callback_function) // reset and start
|
||||
*
|
||||
* call a thread directly:
|
||||
* ===============
|
||||
* void simpleThread_call(callback_function)
|
||||
*
|
||||
* call a part of a thread directly
|
||||
* ===============
|
||||
* void simpleThread_call_setup(callback_function)
|
||||
* boolean simpleThread_call_loop(callback_function)
|
||||
* void simpleThread_call_stable(callback_function)
|
||||
*
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
simpleThread_initSetup(_sT_cnt);
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Some settings which can be used
|
||||
|
||||
// Enable Menu Rollover
|
||||
//LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
simpleThread_run(_sT_priority);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("dynValue:");
|
||||
Serial.print(g_dynParam);
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
for(uint8_t i=0;i<15;i++) {
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// init vars
|
||||
//uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
|
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate() || LCDML.DISP_checkMenuCursorUpdate() ) {
|
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear();
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ Menu ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// display cursor
|
||||
if (n == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
Serial.print(F("(x) "));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("( ) "));
|
||||
}
|
||||
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
Serial.print(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_thread_start(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup
|
||||
// is called only if it is started
|
||||
simpleThread_start(Thread_Serial_Blink_Example);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_thread_stop(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup
|
||||
// is called only if it is started
|
||||
simpleThread_stop(Thread_Serial_Blink_Example);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
Serial.println(F("To close this"));
|
||||
Serial.println(F("function press"));
|
||||
Serial.println(F("any button or use"));
|
||||
Serial.println(F("back button"));
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("wait 20 seconds or press back button"));
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000)) {
|
||||
g_func_timer_info--; // increment the value every second
|
||||
Serial.println(g_func_timer_info); // print the time counter value
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("press a or w"));
|
||||
Serial.println(F("count: 0 of 3"));
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
Serial.print(F("count: "));
|
||||
Serial.print(g_button_value); //print change content
|
||||
Serial.println(F(" of 3"));
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("start screensaver"));
|
||||
Serial.println(F("press any key to quit"));
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop())
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close())
|
||||
{
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.print(F("parameter: "));
|
||||
Serial.println(param);
|
||||
|
||||
Serial.println(F("press any key"));
|
||||
Serial.println(F("to leave it"));
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
|
||||
|
||||
// =====================================================================
|
||||
void simpleThread_setup(Thread_Serial_Blink_Example)
|
||||
// =====================================================================
|
||||
{
|
||||
// for example set pinmode for some inputs
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
boolean simpleThread_loop(Thread_Serial_Blink_Example)
|
||||
{
|
||||
// generate a serial-output in the console every secound
|
||||
Serial.print(".");
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void simpleThread_stable(Thread_Serial_Blink_Example)
|
||||
{
|
||||
// stable state
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// =====================================================================
|
||||
void simpleThread_setup(Thread_input_check)
|
||||
// =====================================================================
|
||||
{
|
||||
// for example set pinmode for some inputs
|
||||
}
|
||||
|
||||
boolean simpleThread_loop(Thread_input_check)
|
||||
{
|
||||
// check inputs
|
||||
|
||||
// check LCDML inputs
|
||||
LCDML.loop_control();
|
||||
|
||||
// go to the next function because the wait time is set to 0
|
||||
// when this return value is "false" all threads with a higher priority will not be called
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void simpleThread_stable(Thread_input_check)
|
||||
{
|
||||
// stable state
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =====================================================================
|
||||
void simpleThread_setup(Thread_LCDMenuLib)
|
||||
// =====================================================================
|
||||
{
|
||||
}
|
||||
boolean simpleThread_loop(Thread_LCDMenuLib)
|
||||
{
|
||||
|
||||
LCDML.loop_menu();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void simpleThread_stable(Thread_LCDMenuLib)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
// ============================================================
|
||||
// Example: LCDML_simpleThread example
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example includes the complete functionality over some
|
||||
// tabs. All Tabs which are started with "LCDML_display_.."
|
||||
// generates an output on the display / console / ....
|
||||
// This example is for the author to test the complete functionality
|
||||
//
|
||||
// Add the TaskScheduler Libarary
|
||||
//
|
||||
// Download simple thread:
|
||||
// https://github.com/arkhipenko/TaskScheduler
|
||||
//
|
||||
//
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// *********************************************************************
|
||||
// includes
|
||||
// *********************************************************************
|
||||
#include <LCDMenuLib2.h>
|
||||
#include <TaskScheduler.h>
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML display settings
|
||||
// *********************************************************************
|
||||
// settings for LCD
|
||||
#define _LCDML_DISP_cols 20
|
||||
#define _LCDML_DISP_rows 4
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Blink Thread" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "Start Thread" , mFunc_thread_start); // Thread control (start)
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "Stop Thread" , mFunc_thread_stop); // Thread control (stop)
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 1" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 2" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 3" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 22
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Task Scheduler
|
||||
// *********************************************************************
|
||||
|
||||
// objects
|
||||
Scheduler r, hpr;
|
||||
|
||||
// Callback methods prototypes
|
||||
void Task_input_check();
|
||||
void Task_Serial_Blink_Example();
|
||||
void Task_LCDMenuLib();
|
||||
|
||||
// Tasks
|
||||
Task t1(10, TASK_FOREVER, &Task_input_check, &r); //adding task to the chain on creation
|
||||
Task t2(1000, TASK_FOREVER, &Task_Serial_Blink_Example, &r);
|
||||
Task t3(100, TASK_FOREVER, &Task_LCDMenuLib, &r);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// Enable input and LCDML Task
|
||||
t1.enable();
|
||||
t3.enable();
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Some settings which can be used
|
||||
|
||||
// Enable Menu Rollover
|
||||
//LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
r.execute();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("dynValue:");
|
||||
Serial.print(g_dynParam);
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
for(uint8_t i=0;i<15;i++) {
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// init vars
|
||||
//uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
|
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate() || LCDML.DISP_checkMenuCursorUpdate() ) {
|
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear();
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ Menu ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// display cursor
|
||||
if (n == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
Serial.print(F("(x) "));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("( ) "));
|
||||
}
|
||||
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
Serial.print(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_thread_start(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup
|
||||
// start thread
|
||||
if(t2.isEnabled() == false)
|
||||
{
|
||||
t2.enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("is enabled"));
|
||||
}
|
||||
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_thread_stop(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup
|
||||
// stop thread
|
||||
if(t2.isEnabled() == true)
|
||||
{
|
||||
t2.disable();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("is disabled"));
|
||||
}
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
Serial.println(F("To close this"));
|
||||
Serial.println(F("function press"));
|
||||
Serial.println(F("any button or use"));
|
||||
Serial.println(F("back button"));
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("wait 20 seconds or press back button"));
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000)) {
|
||||
g_func_timer_info--; // increment the value every second
|
||||
Serial.println(g_func_timer_info); // print the time counter value
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("press a or w"));
|
||||
Serial.println(F("count: 0 of 3"));
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
Serial.print(F("count: "));
|
||||
Serial.print(g_button_value); //print change content
|
||||
Serial.println(F(" of 3"));
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("start screensaver"));
|
||||
Serial.println(F("press any key to quit"));
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop())
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close())
|
||||
{
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.print(F("parameter: "));
|
||||
Serial.println(param);
|
||||
|
||||
Serial.println(F("press any key"));
|
||||
Serial.println(F("to leave it"));
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
|
||||
|
||||
// **********************************************************
|
||||
void Task_Serial_Blink_Example() {
|
||||
// **********************************************************
|
||||
|
||||
|
||||
Serial.println(".");
|
||||
}
|
||||
|
||||
// **********************************************************
|
||||
void Task_input_check() {
|
||||
// **********************************************************
|
||||
|
||||
// check LCDML inputs
|
||||
LCDML.loop_control();
|
||||
}
|
||||
|
||||
// **********************************************************
|
||||
void Task_LCDMenuLib() {
|
||||
// **********************************************************
|
||||
|
||||
|
||||
LCDML.loop_menu();
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
// ============================================================
|
||||
// Example: LCDML_dynamic_file_list
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example includes the complete functionality over some
|
||||
// tabs. All Tabs which are started with "LCDML_display_.."
|
||||
// generates an output on the display / console / ....
|
||||
// This example is for the author to test the complete functionality
|
||||
//
|
||||
// This example shows how a dynamic file list can be added
|
||||
// Program->Program 1-> Filelist
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// *********************************************************************
|
||||
// includes
|
||||
// *********************************************************************
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML display settings
|
||||
// *********************************************************************
|
||||
// settings for LCD
|
||||
#define _LCDML_DISP_cols 20
|
||||
#define _LCDML_DISP_rows 4
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "Filelist" , mFunc_filelist); // Add an filelist which can be scrolled
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "P1 Settings" , NULL); // NULL = no menu function
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 1" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 2" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 3" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 22
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Some settings which can be used
|
||||
|
||||
// Enable Menu Rollover
|
||||
//LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
LCDML.loop();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("dynValue:");
|
||||
Serial.print(g_dynParam);
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
for(uint8_t i=0;i<15;i++) {
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// init vars
|
||||
//uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
|
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate() || LCDML.DISP_checkMenuCursorUpdate() ) {
|
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear();
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ Menu ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// display cursor
|
||||
if (n == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
Serial.print(F("(x) "));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("( ) "));
|
||||
}
|
||||
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
Serial.print(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,536 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
// this needs some bytes in ram
|
||||
#define MAX_FILES_IN_LIST 20
|
||||
|
||||
// scroll row position
|
||||
uint8_t scroll_row;
|
||||
// cursor real position on lcd lines (0 - _LCDML_DISP_rows - 1)
|
||||
uint8_t cursor_real_pos;
|
||||
// max filelist count
|
||||
uint8_t current_max_list_count;
|
||||
// cursor position to file list entry
|
||||
uint8_t cursor_position_cur;
|
||||
// filelist
|
||||
static char filelist[MAX_FILES_IN_LIST][20];
|
||||
|
||||
// comment this line out when you are using a display like 20x4 or 16x4
|
||||
#define _LCDML_USE_SERIAL_MONITOR
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_filelist(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// use this to init some vars
|
||||
|
||||
// set max file counter
|
||||
current_max_list_count = 0;
|
||||
// set current cursor position
|
||||
cursor_position_cur = 0;
|
||||
//
|
||||
scroll_row = 0;
|
||||
cursor_real_pos = 0;
|
||||
|
||||
|
||||
// for example read sd card files here
|
||||
|
||||
// for example here only with a dummy list
|
||||
// with 12 dummyfiles
|
||||
// subfolders are not supported
|
||||
|
||||
// generate file names
|
||||
for(uint8_t i = 0; i<13; i++) {
|
||||
if(i < MAX_FILES_IN_LIST) {
|
||||
// copy dummy string to new position
|
||||
memcpy(filelist[i], "File .txt", 11);
|
||||
|
||||
if(i<10) { // filenames < 10
|
||||
filelist[i][5] = 0+48; // number + '0' '0' = 48
|
||||
filelist[i][6] = i+48; // number
|
||||
} else { // filenames >= 10
|
||||
filelist[i][5] = i/10+48;
|
||||
filelist[i][6] = i%10+48;
|
||||
}
|
||||
current_max_list_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button status change
|
||||
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// init some vars for scrollbar
|
||||
uint8_t n_max = (current_max_list_count >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (current_max_list_count);;
|
||||
uint8_t scrollbar_min = 0;
|
||||
uint8_t scrollbar_max = current_max_list_count;
|
||||
//uint8_t scrollbar_cur_pos = cursor_position_cur;
|
||||
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * cursor_position_cur);
|
||||
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
// scroll up
|
||||
if(cursor_position_cur > 0) { // check minimum cursor
|
||||
cursor_position_cur--; // scroll up
|
||||
if(cursor_real_pos == 0) {
|
||||
scroll_row--; // scroll display rows
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
// scroll down
|
||||
if(cursor_position_cur < (current_max_list_count-1)) { // check list end
|
||||
cursor_position_cur++; // go to next element
|
||||
if(cursor_real_pos == (_LCDML_DISP_rows-1)) { // check if current cursor is in last display line
|
||||
scroll_row++; // scroll content
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// clear display
|
||||
// ================
|
||||
lcdml_menu_clear();
|
||||
|
||||
// display content
|
||||
// ==================
|
||||
for (uint8_t n = scroll_row; n < (scroll_row+_LCDML_DISP_rows); n++)
|
||||
{
|
||||
#ifndef _LCDML_USE_SERIAL_MONITOR
|
||||
// set cursor
|
||||
lcd.setCursor(1, n-scroll_row);
|
||||
// set content
|
||||
lcd.print(filelist[n]);
|
||||
#else
|
||||
if (n == cursor_position_cur)
|
||||
{
|
||||
Serial.print(F("->"));
|
||||
cursor_real_pos = n-scroll_row;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
Serial.println(filelist[n]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// set cursor and scrollbar
|
||||
// =============================
|
||||
#ifndef _LCDML_USE_SERIAL_MONITOR
|
||||
for (uint8_t n = scroll_row; n <(scroll_row+_LCDML_DISP_rows); n++)
|
||||
{
|
||||
lcd.setCursor(0, n-scroll_row);
|
||||
|
||||
// set cursor
|
||||
// =====================
|
||||
if (n == cursor_position_cur) {
|
||||
lcd.write(_LCDML_DISP_cfg_cursor);
|
||||
cursor_real_pos = n-scroll_row;
|
||||
} else {
|
||||
lcd.write(' ');
|
||||
}
|
||||
|
||||
// display scrollbar
|
||||
// ==============================
|
||||
// delete or reset scrollbar
|
||||
if (scrollbar_max > n_max) {
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), n-scroll_row);
|
||||
lcd.write((uint8_t)0);
|
||||
}
|
||||
else {
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), n-scroll_row);
|
||||
lcd.print(' ');
|
||||
}
|
||||
|
||||
// set scrollbar
|
||||
if (scrollbar_max > n_max) {
|
||||
//set scroll position
|
||||
if (cursor_position_cur == scrollbar_min) {
|
||||
// min pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), 0);
|
||||
lcd.write((uint8_t)1);
|
||||
} else if (cursor_position_cur == (scrollbar_max - 1)) {
|
||||
// max pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1));
|
||||
lcd.write((uint8_t)4);
|
||||
} else {
|
||||
// between
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), scroll_pos / n_max);
|
||||
lcd.write((uint8_t)(scroll_pos % n_max) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
Serial.println(filelist[cursor_position_cur]);
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
Serial.println(F("To close this"));
|
||||
Serial.println(F("function press"));
|
||||
Serial.println(F("any button or use"));
|
||||
Serial.println(F("back button"));
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("wait 20 seconds or press back button"));
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000)) {
|
||||
g_func_timer_info--; // increment the value every second
|
||||
Serial.println(g_func_timer_info); // print the time counter value
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("press a or w"));
|
||||
Serial.println(F("count: 0 of 3"));
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
Serial.print(F("count: "));
|
||||
Serial.print(g_button_value); //print change content
|
||||
Serial.println(F(" of 3"));
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("start screensaver"));
|
||||
Serial.println(F("press any key to quit"));
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop())
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close())
|
||||
{
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.print(F("parameter: "));
|
||||
Serial.println(param);
|
||||
|
||||
Serial.println(F("press any key"));
|
||||
Serial.println(F("to leave it"));
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
// ============================================================
|
||||
// Example: LCDML_021_dynUpdatedContent
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// *********************************************************************
|
||||
// includes
|
||||
// *********************************************************************
|
||||
#include <LiquidCrystal.h>
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML display settings
|
||||
// *********************************************************************
|
||||
// settings for LCD
|
||||
#define _LCDML_DISP_cols 20
|
||||
#define _LCDML_DISP_rows 4
|
||||
|
||||
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
|
||||
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
|
||||
|
||||
// LCD object
|
||||
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
|
||||
LiquidCrystal lcd(22, 24, 9, 10, 11, 12);
|
||||
|
||||
const uint8_t scroll_bar[5][8] = {
|
||||
{B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top
|
||||
{B11111, B11111, B10001, B10001, B10001, B10001, B10001, B10001}, // scroll state 1
|
||||
{B10001, B10001, B11111, B11111, B10001, B10001, B10001, B10001}, // scroll state 2
|
||||
{B10001, B10001, B10001, B10001, B11111, B11111, B10001, B10001}, // scroll state 3
|
||||
{B10001, B10001, B10001, B10001, B10001, B10001, B11111, B11111} // scrollbar bottom
|
||||
};
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
// *********************************************************************
|
||||
// Global variables
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "P1 dummy" , NULL); // NULL = no menu function
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "P1 Settings" , NULL); // NULL = no menu function
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 1" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 2" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 3" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// 2. Example for dyn content
|
||||
// add a function which have a upwards timer with seconds / minutes / hours
|
||||
// the timer value is continuously updated
|
||||
// the initscreentimer is disabled for this function
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , NULL, "" , mDyn_time, 0, _LCDML_TYPE_dynParam_enableCustomRefresh); // NULL = no menu function
|
||||
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (23 , LCDML_0 , 8 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 23
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// LCD Begin
|
||||
lcd.begin(_LCDML_DISP_cols,_LCDML_DISP_rows);
|
||||
// set special chars for scrollbar
|
||||
lcd.createChar(0, (uint8_t*)scroll_bar[0]);
|
||||
lcd.createChar(1, (uint8_t*)scroll_bar[1]);
|
||||
lcd.createChar(2, (uint8_t*)scroll_bar[2]);
|
||||
lcd.createChar(3, (uint8_t*)scroll_bar[3]);
|
||||
lcd.createChar(4, (uint8_t*)scroll_bar[4]);
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Some settings which can be used
|
||||
|
||||
// Enable Menu Rollover
|
||||
LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
|
||||
// special gobal variables for this example
|
||||
boolean g_status_if_dyn_content_external_refresh_is_displayed = false;
|
||||
unsigned long g_timer_1000ms = 0;
|
||||
uint8_t dyn_hour = 0;
|
||||
uint8_t dyn_min = 0;
|
||||
uint8_t dyn_sec = 0;
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
// split loop() into loop_control() and loop_menu()
|
||||
LCDML.loop_control();
|
||||
|
||||
// add a counter (1000ms)
|
||||
if(LCDML.TIMER_ms(g_timer_1000ms, 1000))
|
||||
{
|
||||
// only update the menu when a dynamic content function is called
|
||||
// This variable is set in the LCDML_display_menu Tab on line 59/60
|
||||
if(LCDML.MENU_checkDynRContent() == true)
|
||||
{
|
||||
LCDML.MENU_display();
|
||||
}
|
||||
|
||||
// callculate a new value for the next update
|
||||
dyn_sec++;
|
||||
if(dyn_sec==60) {
|
||||
dyn_sec = 0;
|
||||
dyn_min++;
|
||||
if(dyn_min==60) {
|
||||
dyn_min = 0;
|
||||
dyn_hour++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// call the "normaly" menu content
|
||||
LCDML.loop_menu();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// clear the line manuel because clear the complete content is disabled when a external refreshed function is active
|
||||
lcd.setCursor(1, line);
|
||||
for(uint8_t i=0;i<_LCDML_DISP_cols-3;i++) // -3 because:
|
||||
// -1 for counter from 0 to x
|
||||
// -1 for cursor position
|
||||
// -1 for scrollbar on the end
|
||||
{
|
||||
lcd.print(F(" "));
|
||||
}
|
||||
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "dynValue: %d", g_dynParam);
|
||||
// use the line from function parameters
|
||||
lcd.setCursor(1, line);
|
||||
lcd.print(buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mDyn_time(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// clear the line manuel because clear the complete content is disabled when a external refreshed function is active
|
||||
lcd.setCursor(1, line);
|
||||
for(uint8_t i=0;i<_LCDML_DISP_cols-3;i++) // -3 because:
|
||||
// -1 for counter from 0 to x
|
||||
// -1 for cursor position
|
||||
// -1 for scrollbar on the end
|
||||
{
|
||||
lcd.print(F(" "));
|
||||
}
|
||||
|
||||
|
||||
char buf[20];
|
||||
// http://www.c-howto.de/tutorial/benutzerinteraktion/bildschirmausgaben/
|
||||
sprintf (buf, "Time %02d:%02d:%02d", dyn_hour, dyn_min, dyn_sec);
|
||||
|
||||
// use the line from function parameters
|
||||
lcd.setCursor(1, line);
|
||||
lcd.print(buf);
|
||||
|
||||
// reset initscreen timer when this function is displayed
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
if (LCDML.MENU_checkDynRContent() == false)
|
||||
{
|
||||
// clear only the display when the external content refresh is not displayed
|
||||
lcd.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate()) {
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear();
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
lcd.setCursor(1, n);
|
||||
lcd.print(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam())
|
||||
{
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.DISP_checkMenuCursorUpdate())
|
||||
{
|
||||
// init vars
|
||||
uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
uint8_t scrollbar_min = 0;
|
||||
uint8_t scrollbar_max = LCDML.MENU_getChilds();
|
||||
uint8_t scrollbar_cur_pos = LCDML.MENU_getCursorPosAbs();
|
||||
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
|
||||
|
||||
|
||||
// display rows
|
||||
for (uint8_t n = 0; n < n_max; n++)
|
||||
{
|
||||
//set cursor
|
||||
lcd.setCursor(0, n);
|
||||
|
||||
//set cursor char
|
||||
if (n == LCDML.MENU_getCursorPos()) {
|
||||
lcd.write(_LCDML_DISP_cfg_cursor);
|
||||
if(LCDML.MENU_checkDynRContent() == true)
|
||||
{
|
||||
LCDML.MENU_getDisplayedObj()->callback(n);
|
||||
}
|
||||
} else {
|
||||
lcd.write(' ');
|
||||
}
|
||||
|
||||
// delete or reset scrollbar
|
||||
if (_LCDML_DISP_cfg_scrollbar == 1) {
|
||||
if (scrollbar_max > n_max) {
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), n);
|
||||
lcd.write((uint8_t)0);
|
||||
}
|
||||
else {
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), n);
|
||||
lcd.print(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// display scrollbar
|
||||
if (_LCDML_DISP_cfg_scrollbar == 1) {
|
||||
if (scrollbar_max > n_max) {
|
||||
//set scroll position
|
||||
if (scrollbar_cur_pos == scrollbar_min) {
|
||||
// min pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), 0);
|
||||
lcd.write((uint8_t)1);
|
||||
} else if (scrollbar_cur_pos == (scrollbar_max - 1)) {
|
||||
// max pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1));
|
||||
lcd.write((uint8_t)4);
|
||||
} else {
|
||||
// between
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), scroll_pos / n_max);
|
||||
lcd.write((uint8_t)(scroll_pos % n_max) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(F("To close this"));
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("function press"));
|
||||
lcd.setCursor(0, 2);
|
||||
lcd.print(F("any button or use"));
|
||||
lcd.setCursor(0, 3);
|
||||
lcd.print(F("back button"));
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
lcd.print(F("20 sec wait")); // print some content on first row
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000)) {
|
||||
g_func_timer_info--; // increment the value every second
|
||||
lcd.setCursor(0, 0); // set cursor pos
|
||||
lcd.print(F(" "));
|
||||
lcd.setCursor(0, 0); // set cursor pos
|
||||
lcd.print(g_func_timer_info); // print the time counter value
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
// print LCD content
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(F("press left or up"));
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("count: 0 of 3"));
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
// update LCD content
|
||||
lcd.setCursor(7, 1); // set cursor
|
||||
lcd.print(g_button_value); // print change content
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// update LCD content
|
||||
lcd.setCursor(0, 0); // set cursor
|
||||
lcd.print(F("screensaver")); // print change content
|
||||
lcd.setCursor(0, 1); // set cursor
|
||||
lcd.print(F("press any key"));
|
||||
lcd.setCursor(0, 2); // set cursor
|
||||
lcd.print(F("to leave it"));
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop())
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close())
|
||||
{
|
||||
// The screensaver go to the root menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function and go a layer back
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "parameter: %d", param);
|
||||
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(buf);
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("press any key"));
|
||||
lcd.setCursor(0, 2);
|
||||
lcd.print(F("to leave it"));
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
// ============================================================
|
||||
// Example: LCDML_multilanguage
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example includes the complete functionality over some
|
||||
// tabs. All Tabs which are started with "LCDML_display_.."
|
||||
// generates an output on the display / console / ....
|
||||
// This example is for the author to test the complete functionality
|
||||
//
|
||||
// !!!!
|
||||
// Here are some diffcult parts, when something is not working in your code
|
||||
// look in this example and please read the comments
|
||||
// !!!!
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// *********************************************************************
|
||||
// includes
|
||||
// *********************************************************************
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML display settings
|
||||
// *********************************************************************
|
||||
// settings for LCD
|
||||
#define _LCDML_DISP_cols 30
|
||||
#define _LCDML_DISP_rows 4
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
// create a new language with a short name
|
||||
// parameter (id from the element above, short language name, string)
|
||||
LCDML_langDef (0, DE, "Information");
|
||||
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_langDef (1, DE, "Zeit Info");
|
||||
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_langDef (2, DE, "Programm");
|
||||
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_langDef (3, DE, "Programm 1");
|
||||
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "P1 dummy" , NULL); // NULL = no menu function
|
||||
LCDML_langDef (4, DE, "P1 Platzhalter");
|
||||
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "P1 Settings" , NULL); // NULL = no menu function
|
||||
LCDML_langDef (5, DE, "P1 Einstellungen");
|
||||
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_langDef (6, DE, "Warm");
|
||||
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_langDef (7, DE, "Kalt");
|
||||
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_langDef (8, DE, "Zur\365ck");
|
||||
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_langDef (9, DE, "Zur\365ck");
|
||||
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_langDef (10, DE, "Programm 2");
|
||||
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_langDef (11, DE, "Zur\365ck");
|
||||
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_langDef (12, DE, "Spezial");
|
||||
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_langDef (13, DE, "Geh zum Anfang");
|
||||
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_langDef (14, DE, "Springe zu Zeit Info");
|
||||
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_langDef (15, DE, "Zur\365ck");
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_langDef (16, DE, "Parameter");
|
||||
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 10" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_langDef (17, DE, "Parameter 10");
|
||||
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 20" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_langDef (18, DE, "Parameter 20");
|
||||
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 30" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_langDef (19, DE, "Parameter 30");
|
||||
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_langDef (20, DE, "Zur\365ck");
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
LCDML_langDef (21, DE, "");
|
||||
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , COND_hide, "" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_langDef (22, DE, "");
|
||||
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 22
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
// CREATE language types
|
||||
// the language definition here should not be the same like in the definition above
|
||||
// please write here "LANG_" before the short name
|
||||
// EN -> LANG_EN
|
||||
// DE -> LANG_DE
|
||||
// ...
|
||||
enum lang_types
|
||||
{
|
||||
LANG_DEFAULT = 0, // this value is every 0
|
||||
LANG_DE = 1 // the last element have no "," at the end
|
||||
// custom elements can be added
|
||||
};
|
||||
|
||||
// set the default language with the long name
|
||||
//lang_types g_lcdml_lang_select = DEFAULT_LANG;
|
||||
lang_types g_lcdml_lang_select = LANG_DE;
|
||||
|
||||
// in the source code you can change the language with this line:
|
||||
// g_lcdml_lang_select = DEFAULT_LANG;
|
||||
// g_lcdml_lang_select = LANG_DE;
|
||||
// ...
|
||||
|
||||
// create custom language with short name, not with the long name
|
||||
LCDML_createCustomLang(_LCDML_DISP_cnt, DE);
|
||||
|
||||
// next step when you add a new language:
|
||||
// go into the LCDML_display_menu tab and change or add a switch case condition
|
||||
|
||||
// next step:
|
||||
// change the menu function
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Some settings which can be used
|
||||
|
||||
// Enable Menu Rollover
|
||||
//LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
LCDML.loop();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("dynValue:");
|
||||
Serial.print(g_dynParam);
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
for(uint8_t i=0;i<15;i++) {
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// init vars
|
||||
//uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
|
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate() || LCDML.DISP_checkMenuCursorUpdate() ) {
|
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear();
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ Menu ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// display cursor
|
||||
if (n == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
Serial.print(F("(x) "));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("( ) "));
|
||||
}
|
||||
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
switch(g_lcdml_lang_select)
|
||||
{
|
||||
case LANG_DE: // custom language long name
|
||||
// get the custom language content with the short name of the language
|
||||
LCDML_getCustomContent(DE, content_text, tmp->getID());
|
||||
break;
|
||||
|
||||
/*
|
||||
// this is only an example for other languages
|
||||
case LANG_EN: // custom language long name
|
||||
// get the custom language content with the short name of the language
|
||||
LCDML_getCustomContent(EN, content_text, tmp->getID());
|
||||
break;
|
||||
*/
|
||||
|
||||
|
||||
default: // default language
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,411 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
switch(g_lcdml_lang_select)
|
||||
{
|
||||
case LANG_DE: // custom language long name
|
||||
Serial.println(F("Zum schlie\342en der"));
|
||||
Serial.println(F("Funktion, bitte druck"));
|
||||
Serial.println(F("irgendeine Taste oder"));
|
||||
Serial.println(F("den Zur\365ck Knopf"));
|
||||
break;
|
||||
|
||||
default:
|
||||
Serial.println(F("To close this"));
|
||||
Serial.println(F("function press"));
|
||||
Serial.println(F("any button or use"));
|
||||
Serial.println(F("back button"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
switch(g_lcdml_lang_select)
|
||||
{
|
||||
case LANG_DE: // custom language long name
|
||||
Serial.println(F("20 Sekunden warten oder Zur\365ck Knopf dr\365cken"));
|
||||
break;
|
||||
|
||||
default:
|
||||
Serial.println(F("wait 20 seconds or press back button"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000)) {
|
||||
g_func_timer_info--; // increment the value every second
|
||||
Serial.println(g_func_timer_info); // print the time counter value
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
switch(g_lcdml_lang_select)
|
||||
{
|
||||
case LANG_DE: // custom language long name
|
||||
Serial.println(F("Dr\365cke a oder w"));
|
||||
Serial.println(F("Z\341hler: 0 of 3"));
|
||||
break;
|
||||
|
||||
default:
|
||||
Serial.println(F("press a or w"));
|
||||
Serial.println(F("count: 0 of 3"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
switch(g_lcdml_lang_select)
|
||||
{
|
||||
case LANG_DE: // custom language long name
|
||||
Serial.print(F("Z\341hler: "));
|
||||
Serial.print(g_button_value); //print change content
|
||||
Serial.println(F(" von 3"));
|
||||
break;
|
||||
|
||||
default:
|
||||
Serial.print(F("count: "));
|
||||
Serial.print(g_button_value); //print change content
|
||||
Serial.println(F(" of 3"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
switch(g_lcdml_lang_select)
|
||||
{
|
||||
case LANG_DE: // custom language long name
|
||||
Serial.println(F("Bildschirmschoner gestartet"));
|
||||
Serial.println(F("Zum verlassen einen Knopf drucken"));
|
||||
break;
|
||||
|
||||
default:
|
||||
Serial.println(F("start screensaver"));
|
||||
Serial.println(F("press any key to quit"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop())
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close())
|
||||
{
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.print(F("parameter: "));
|
||||
Serial.println(param);
|
||||
|
||||
switch(g_lcdml_lang_select)
|
||||
{
|
||||
case LANG_DE: // custom language long name
|
||||
Serial.println(F("Irgendeine Taste dr\365cken"));
|
||||
Serial.println(F("zum verlassen"));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
Serial.println(F("press any key"));
|
||||
Serial.println(F("to leave it"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
// ============================================================
|
||||
// Example: LCDML_multilanguage
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example includes the complete functionality over some
|
||||
// tabs. All Tabs which are started with "LCDML_display_.."
|
||||
// generates an output on the display / console / ....
|
||||
// This example is for the author to test the complete functionality
|
||||
//
|
||||
// !!!!
|
||||
// Here are some diffcult parts, when something is not working in your code
|
||||
// look in this example and please read the comments
|
||||
// !!!!
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// *********************************************************************
|
||||
// includes
|
||||
// *********************************************************************
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML display settings
|
||||
// *********************************************************************
|
||||
// settings for LCD
|
||||
#define _LCDML_DISP_cols 30
|
||||
#define _LCDML_DISP_rows 4
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
// create a new language with a short name
|
||||
// parameter (id from the element above, short language name, string)
|
||||
LCDML_langDef (0, DE, "Information");
|
||||
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Change Language" , mFunc_switch_language); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_langDef (1, DE, "Sprache umstellen");
|
||||
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_langDef (2, DE, "Programm");
|
||||
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 2
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
// CREATE language types
|
||||
// the language definition here should not be the same like in the definition above
|
||||
// please write here "LANG_" before the short name
|
||||
// EN -> LANG_EN
|
||||
// DE -> LANG_DE
|
||||
// ...
|
||||
enum lang_types
|
||||
{
|
||||
LANG_DEFAULT = 0, // this value is every 0
|
||||
LANG_DE = 1 // the last element have no "," at the end
|
||||
// custom elements can be added
|
||||
};
|
||||
|
||||
// set the default language with the long name
|
||||
lang_types g_lcdml_lang_select = LANG_DEFAULT;
|
||||
//lang_types g_lcdml_lang_select = LANG_DE;
|
||||
|
||||
// in the source code you can change the language with this line:
|
||||
// g_lcdml_lang_select = DEFAULT_LANG;
|
||||
// g_lcdml_lang_select = LANG_DE;
|
||||
// ...
|
||||
|
||||
// create custom language with short name, not with the long name
|
||||
LCDML_createCustomLang(_LCDML_DISP_cnt, DE);
|
||||
|
||||
// next step when you add a new language:
|
||||
// go into the LCDML_display_menu tab and change or add a switch case condition
|
||||
|
||||
// next step:
|
||||
// change the menu function
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Some settings which can be used
|
||||
|
||||
// Enable Menu Rollover
|
||||
//LCDML.MENU_enRollover();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
LCDML.loop();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
// not needed in this example
|
||||
@@ -0,0 +1,108 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
for(uint8_t i=0;i<15;i++) {
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// init vars
|
||||
//uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
|
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate() || LCDML.DISP_checkMenuCursorUpdate() ) {
|
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear();
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ Menu ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// display cursor
|
||||
if (n == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
Serial.print(F("(x) "));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("( ) "));
|
||||
}
|
||||
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
switch(g_lcdml_lang_select)
|
||||
{
|
||||
case LANG_DE: // custom language long name
|
||||
// get the custom language content with the short name of the language
|
||||
LCDML_getCustomContent(DE, content_text, tmp->getID());
|
||||
break;
|
||||
|
||||
/*
|
||||
// this is only an example for other languages
|
||||
case LANG_EN: // custom language long name
|
||||
// get the custom language content with the short name of the language
|
||||
LCDML_getCustomContent(EN, content_text, tmp->getID());
|
||||
break;
|
||||
*/
|
||||
|
||||
|
||||
default: // default language
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
switch(g_lcdml_lang_select)
|
||||
{
|
||||
case LANG_DE: // custom language long name
|
||||
Serial.println(F("Zum schlie\342en der"));
|
||||
Serial.println(F("Funktion, bitte druck"));
|
||||
Serial.println(F("irgendeine Taste oder"));
|
||||
Serial.println(F("den Zur\365ck Knopf"));
|
||||
break;
|
||||
|
||||
default:
|
||||
Serial.println(F("To close this"));
|
||||
Serial.println(F("function press"));
|
||||
Serial.println(F("any button or use"));
|
||||
Serial.println(F("back button"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_switch_language(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
if(g_lcdml_lang_select == LANG_DE)
|
||||
{
|
||||
g_lcdml_lang_select = LANG_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_lcdml_lang_select = LANG_DE;
|
||||
}
|
||||
|
||||
switch(g_lcdml_lang_select)
|
||||
{
|
||||
case LANG_DE: // custom language long name
|
||||
Serial.println(F("Sprache geändert"));
|
||||
break;
|
||||
|
||||
default:
|
||||
Serial.println(F("wait 20 seconds or press back button"));
|
||||
break;
|
||||
}
|
||||
|
||||
// go back
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// not needed here
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
// ============================================================
|
||||
// Example: LCDML_condetions
|
||||
// ============================================================
|
||||
// Description:
|
||||
// ToDo
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings for non arduino basic controllers
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// *********************************************************************
|
||||
// includes
|
||||
// *********************************************************************
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML display settings
|
||||
// *********************************************************************
|
||||
// settings for LCD
|
||||
#define _LCDML_DISP_cols 20
|
||||
#define _LCDML_DISP_rows 4
|
||||
|
||||
// enable this line (set to 1) to show a header above the first menu element
|
||||
// this function can be changed in LCDML_display_menu tab
|
||||
#define _LCDML_DSIP_use_header 0
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
// *********************************************************************
|
||||
// Condetions
|
||||
// *********************************************************************
|
||||
// global variable for condetion
|
||||
boolean g_condetion_a = true;
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows-_LCDML_DSIP_use_header, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_addAdvanced (2 , LCDML_0 , 3 , COND_a, "Condetion A" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3 , 2 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_addAdvanced (5 , LCDML_0 , 4 , COND_not_a, "Condetion B" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (6 , LCDML_0_4 , 1 , "Program 2" , NULL); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (7 , LCDML_0_4 , 2 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (8 , LCDML_0 , 5 , NULL, "" , mDyn_change_condetion, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (9 , LCDML_0 , 6 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 9
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Some settings which can be used
|
||||
|
||||
// Enable Menu Rollover
|
||||
//LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
//LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
|
||||
// In the following line the new event handling system ins configured
|
||||
// you can use 0 - 3 special events when calling the LCDML.CE_set(id) function
|
||||
// when you need more events you can change in LCDMenuLib.h the number until 0-63
|
||||
//LCDML.CE_setOnChangeCbFunction(0, mFunc_exampleEventHandling);
|
||||
//LCDML.CE_setOnChangeCbFunction(1, your_special_menu_function);
|
||||
//...
|
||||
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
LCDML.loop();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide(void) // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_a(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
return g_condetion_a;
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_not_a(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// invert condetion a "!"
|
||||
return !g_condetion_a;
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_change_condetion(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft() || LCDML.BT_checkRight())
|
||||
{
|
||||
g_condetion_a = !g_condetion_a;
|
||||
|
||||
// this functions are new in this version
|
||||
|
||||
// The handling of condetions is changed in this version because a condetion must not called with every element call
|
||||
// The condetions would only be update when this function is called.
|
||||
LCDML.MENU_allCondetionRefresh();
|
||||
|
||||
// this function is usefull when content above this menu element needs an update.
|
||||
// for example one dyn function change the content of another dyn function above this line.
|
||||
LCDML.MENU_setDynFunctionContentUpdate();
|
||||
|
||||
// after the condetion changes it is usefull to go back to the root menu
|
||||
//LCDML.MENU_goRoot();
|
||||
// or set the cursor to the right defined position
|
||||
LCDML.OTHER_setCursorToID(8); // to this function
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(g_condetion_a == true)
|
||||
{
|
||||
Serial.println("change to condetion: < B >");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("change to condetion: < A >");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
for(uint8_t i=0;i<15;i++) {
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// init vars
|
||||
//uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
|
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate() || LCDML.DISP_checkMenuCursorUpdate() ) {
|
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear();
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ Menu ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = (_LCDML_DISP_rows - _LCDML_DSIP_use_header) + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// Display a header with the parent element name
|
||||
if(_LCDML_DSIP_use_header > 0)
|
||||
{
|
||||
// only one line
|
||||
if(LCDML.MENU_getLayer() == 0)
|
||||
{
|
||||
// this text is displayed when no header is available
|
||||
Serial.println(F("Root Menu"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Display parent name
|
||||
LCDML_getContent(content_text, LCDML.MENU_getParentID());
|
||||
Serial.print(content_text);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// display cursor
|
||||
if (n == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
Serial.print(F("(x) "));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("( ) "));
|
||||
}
|
||||
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
Serial.print(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
|
||||
Serial.println(F("To close this"));
|
||||
Serial.println(F("function press"));
|
||||
Serial.println(F("any button or use"));
|
||||
Serial.println(F("back button"));
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("================ FUNC ===================="));
|
||||
Serial.println(F("==========================================="));
|
||||
Serial.println(F("wait 20 seconds or press back button"));
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000)) {
|
||||
g_func_timer_info--; // increment the value every second
|
||||
Serial.println(g_func_timer_info); // print the time counter value
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
Serial.println(F("start screensaver"));
|
||||
Serial.println(F("press any key to quit"));
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop())
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close())
|
||||
{
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
// ============================================================
|
||||
// Example: DisplayType - I2C LiquidCrystal
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example includes the complete functionality over some
|
||||
// tabs. All Tabs which are started with "LCDML_display_.."
|
||||
// generates an output on the display / console / ....
|
||||
// This example is for the author to test the complete functionality
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// *********************************************************************
|
||||
// includes
|
||||
// *********************************************************************
|
||||
#include <Wire.h>
|
||||
#include <LiquidCrystal_I2C.h>
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML display settings
|
||||
// *********************************************************************
|
||||
// settings for LCD
|
||||
#define _LCDML_DISP_cols 20
|
||||
#define _LCDML_DISP_rows 4
|
||||
|
||||
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
|
||||
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
|
||||
|
||||
// LCD object
|
||||
// for i2c there are many different steps for initialization, some are listed here
|
||||
// when the rows and cols are not set here, they have to be set in the setup
|
||||
//LiquidCrystal_I2C lcd(0x27); // Set the LCD I2C address
|
||||
//LiquidCrystal_I2C lcd(0x27, BACKLIGHT_PIN, POSITIVE); // Set the LCD I2C address
|
||||
LiquidCrystal_I2C lcd(0x27,_LCDML_DISP_cols,_LCDML_DISP_rows);
|
||||
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
|
||||
|
||||
const uint8_t scroll_bar[5][8] = {
|
||||
{B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top
|
||||
{B11111, B11111, B10001, B10001, B10001, B10001, B10001, B10001}, // scroll state 1
|
||||
{B10001, B10001, B11111, B11111, B10001, B10001, B10001, B10001}, // scroll state 2
|
||||
{B10001, B10001, B10001, B10001, B11111, B11111, B10001, B10001}, // scroll state 3
|
||||
{B10001, B10001, B10001, B10001, B10001, B10001, B11111, B11111} // scrollbar bottom
|
||||
};
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
// *********************************************************************
|
||||
// Global variables
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "P1 dummy" , NULL); // NULL = no menu function
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "P1 Settings" , NULL); // NULL = no menu function
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (16 , LCDML_0 , 5 , "Dummy B" , NULL); // NULL = no menu function
|
||||
LCDML_add (17 , LCDML_0 , 6 , "Screensaver" , mFunc_screensaver); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 17
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// LCD Begin
|
||||
lcd.init();
|
||||
lcd.backlight();
|
||||
//lcd.begin(_LCDML_DISP_cols,_LCDML_DISP_rows); // some display types needs here the initialization
|
||||
|
||||
|
||||
// set special chars for scrollbar
|
||||
lcd.createChar(0, (uint8_t*)scroll_bar[0]);
|
||||
lcd.createChar(1, (uint8_t*)scroll_bar[1]);
|
||||
lcd.createChar(2, (uint8_t*)scroll_bar[2]);
|
||||
lcd.createChar(3, (uint8_t*)scroll_bar[3]);
|
||||
lcd.createChar(4, (uint8_t*)scroll_bar[4]);
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Some settings which can be used
|
||||
|
||||
// Enable Menu Rollover
|
||||
LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
LCDML.loop();
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,125 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate()) {
|
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear();
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
lcd.setCursor(1, n);
|
||||
lcd.print(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.DISP_checkMenuCursorUpdate())
|
||||
{
|
||||
// init vars
|
||||
uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
uint8_t scrollbar_min = 0;
|
||||
uint8_t scrollbar_max = LCDML.MENU_getChilds();
|
||||
uint8_t scrollbar_cur_pos = LCDML.MENU_getCursorPosAbs();
|
||||
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
|
||||
|
||||
|
||||
// display rows
|
||||
for (uint8_t n = 0; n < n_max; n++)
|
||||
{
|
||||
//set cursor
|
||||
lcd.setCursor(0, n);
|
||||
|
||||
//set cursor char
|
||||
if (n == LCDML.MENU_getCursorPos()) {
|
||||
lcd.write(_LCDML_DISP_cfg_cursor);
|
||||
} else {
|
||||
lcd.write(' ');
|
||||
}
|
||||
|
||||
// delete or reset scrollbar
|
||||
if (_LCDML_DISP_cfg_scrollbar == 1) {
|
||||
if (scrollbar_max > n_max) {
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), n);
|
||||
lcd.write((uint8_t)0);
|
||||
}
|
||||
else {
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), n);
|
||||
lcd.print(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// display scrollbar
|
||||
if (_LCDML_DISP_cfg_scrollbar == 1) {
|
||||
if (scrollbar_max > n_max) {
|
||||
//set scroll position
|
||||
if (scrollbar_cur_pos == scrollbar_min) {
|
||||
// min pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), 0);
|
||||
lcd.write((uint8_t)1);
|
||||
} else if (scrollbar_cur_pos == (scrollbar_max - 1)) {
|
||||
// max pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1));
|
||||
lcd.write((uint8_t)4);
|
||||
} else {
|
||||
// between
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), scroll_pos / n_max);
|
||||
lcd.write((uint8_t)(scroll_pos % n_max) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(F("To close this"));
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("function press"));
|
||||
lcd.setCursor(0, 2);
|
||||
lcd.print(F("any button or use"));
|
||||
lcd.setCursor(0, 3);
|
||||
lcd.print(F("back button"));
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
lcd.print(F("20 sec wait")); // print some content on first row
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000)) {
|
||||
g_func_timer_info--; // increment the value every second
|
||||
lcd.setCursor(0, 0); // set cursor pos
|
||||
lcd.print(F(" "));
|
||||
lcd.setCursor(0, 0); // set cursor pos
|
||||
lcd.print(g_func_timer_info); // print the time counter value
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
// print LCD content
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(F("press left or up"));
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("count: 0 of 3"));
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
// update LCD content
|
||||
lcd.setCursor(7, 1); // set cursor
|
||||
lcd.print(g_button_value); // print change content
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// update LCD content
|
||||
lcd.setCursor(0, 0); // set cursor
|
||||
lcd.print(F("screensaver")); // print change content
|
||||
lcd.setCursor(0, 1); // set cursor
|
||||
lcd.print(F("press any key"));
|
||||
lcd.setCursor(0, 2); // set cursor
|
||||
lcd.print(F("to leave it"));
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop())
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close())
|
||||
{
|
||||
// The screensaver go to the root menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function and go a layer back
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
// ============================================================
|
||||
// Example: LCDML DisplayType - LiquidCrystal
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example includes the complete functionality over some
|
||||
// tabs. All Tabs which are started with "LCDML_display_.."
|
||||
// generates an output on the display / console / ....
|
||||
// This example is for the author to test the complete functionality
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// *********************************************************************
|
||||
// includes
|
||||
// *********************************************************************
|
||||
#include <LiquidCrystal.h>
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML display settings
|
||||
// *********************************************************************
|
||||
// settings for LCD
|
||||
#define _LCDML_DISP_cols 20
|
||||
#define _LCDML_DISP_rows 4
|
||||
|
||||
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
|
||||
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
|
||||
|
||||
// LCD object
|
||||
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
|
||||
LiquidCrystal lcd(22, 24, 9, 10, 11, 12);
|
||||
|
||||
const uint8_t scroll_bar[5][8] = {
|
||||
{B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top
|
||||
{B11111, B11111, B10001, B10001, B10001, B10001, B10001, B10001}, // scroll state 1
|
||||
{B10001, B10001, B11111, B11111, B10001, B10001, B10001, B10001}, // scroll state 2
|
||||
{B10001, B10001, B10001, B10001, B11111, B11111, B10001, B10001}, // scroll state 3
|
||||
{B10001, B10001, B10001, B10001, B10001, B10001, B11111, B11111} // scrollbar bottom
|
||||
};
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
// *********************************************************************
|
||||
// Global variables
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "P1 dummy" , NULL); // NULL = no menu function
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "P1 Settings" , NULL); // NULL = no menu function
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 1" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 2" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 3" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 22
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// LCD Begin
|
||||
lcd.begin(_LCDML_DISP_cols,_LCDML_DISP_rows);
|
||||
// set special chars for scrollbar
|
||||
lcd.createChar(0, (uint8_t*)scroll_bar[0]);
|
||||
lcd.createChar(1, (uint8_t*)scroll_bar[1]);
|
||||
lcd.createChar(2, (uint8_t*)scroll_bar[2]);
|
||||
lcd.createChar(3, (uint8_t*)scroll_bar[3]);
|
||||
lcd.createChar(4, (uint8_t*)scroll_bar[4]);
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Some settings which can be used
|
||||
|
||||
// Enable Menu Rollover
|
||||
LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
LCDML.loop();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
}
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "dynValue: %d", g_dynParam);
|
||||
|
||||
// use the line from function parameters
|
||||
lcd.setCursor(1, line);
|
||||
lcd.print(buf);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
lcd.clear();
|
||||
lcd.setCursor(0, 0);
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate()) {
|
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear();
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
lcd.setCursor(1, n);
|
||||
lcd.print(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.DISP_checkMenuCursorUpdate())
|
||||
{
|
||||
// init vars
|
||||
uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
uint8_t scrollbar_min = 0;
|
||||
uint8_t scrollbar_max = LCDML.MENU_getChilds();
|
||||
uint8_t scrollbar_cur_pos = LCDML.MENU_getCursorPosAbs();
|
||||
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
|
||||
|
||||
|
||||
// display rows
|
||||
for (uint8_t n = 0; n < n_max; n++)
|
||||
{
|
||||
//set cursor
|
||||
lcd.setCursor(0, n);
|
||||
|
||||
//set cursor char
|
||||
if (n == LCDML.MENU_getCursorPos()) {
|
||||
lcd.write(_LCDML_DISP_cfg_cursor);
|
||||
} else {
|
||||
lcd.write(' ');
|
||||
}
|
||||
|
||||
// delete or reset scrollbar
|
||||
if (_LCDML_DISP_cfg_scrollbar == 1) {
|
||||
if (scrollbar_max > n_max) {
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), n);
|
||||
lcd.write((uint8_t)0);
|
||||
}
|
||||
else {
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), n);
|
||||
lcd.print(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// display scrollbar
|
||||
if (_LCDML_DISP_cfg_scrollbar == 1) {
|
||||
if (scrollbar_max > n_max) {
|
||||
//set scroll position
|
||||
if (scrollbar_cur_pos == scrollbar_min) {
|
||||
// min pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), 0);
|
||||
lcd.write((uint8_t)1);
|
||||
} else if (scrollbar_cur_pos == (scrollbar_max - 1)) {
|
||||
// max pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1));
|
||||
lcd.write((uint8_t)4);
|
||||
} else {
|
||||
// between
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), scroll_pos / n_max);
|
||||
lcd.write((uint8_t)(scroll_pos % n_max) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(F("To close this"));
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("function press"));
|
||||
lcd.setCursor(0, 2);
|
||||
lcd.print(F("any button or use"));
|
||||
lcd.setCursor(0, 3);
|
||||
lcd.print(F("back button"));
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
lcd.print(F("20 sec wait")); // print some content on first row
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000)) {
|
||||
g_func_timer_info--; // increment the value every second
|
||||
lcd.setCursor(0, 0); // set cursor pos
|
||||
lcd.print(F(" "));
|
||||
lcd.setCursor(0, 0); // set cursor pos
|
||||
lcd.print(g_func_timer_info); // print the time counter value
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
// print LCD content
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(F("press left or up"));
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("count: 0 of 3"));
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
// update LCD content
|
||||
lcd.setCursor(7, 1); // set cursor
|
||||
lcd.print(g_button_value); // print change content
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// update LCD content
|
||||
lcd.setCursor(0, 0); // set cursor
|
||||
lcd.print(F("screensaver")); // print change content
|
||||
lcd.setCursor(0, 1); // set cursor
|
||||
lcd.print(F("press any key"));
|
||||
lcd.setCursor(0, 2); // set cursor
|
||||
lcd.print(F("to leave it"));
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop())
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close())
|
||||
{
|
||||
// The screensaver go to the root menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function and go a layer back
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "parameter: %d", param);
|
||||
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print(buf);
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print(F("press any key"));
|
||||
lcd.setCursor(0, 2);
|
||||
lcd.print(F("to leave it"));
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
// ============================================================
|
||||
// Example: LCDML: graphic display with u8g
|
||||
// ============================================================
|
||||
// Author: Jomelo
|
||||
// Last update: 21.01.2018
|
||||
// License: MIT
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example shows how to use the u8glib with the LCDMenuLib
|
||||
// The menu can placed in a box that can be placed anywhere on
|
||||
// the screen.
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// include libs
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
// U8g2lib
|
||||
#include <Arduino.h>
|
||||
#include <U8g2lib.h>
|
||||
|
||||
#ifdef U8X8_HAVE_HW_SPI
|
||||
#include <SPI.h>
|
||||
#endif
|
||||
#ifdef U8X8_HAVE_HW_I2C
|
||||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
// *********************************************************************
|
||||
// U8GLIB
|
||||
// *********************************************************************
|
||||
// U8g2 Constructor List (Frame Buffer)
|
||||
// The complete list is available here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp
|
||||
// Please update the pin numbers according to your setup. Use U8X8_PIN_NONE if the reset pin is not connected
|
||||
U8G2_ST7920_128X64_F_HW_SPI u8g2(U8G2_R0, /* CS=*/ 53, /* reset=*/ U8X8_PIN_NONE); // (MEGA, ...
|
||||
//U8G2_ST7920_128X64_F_HW_SPI u8g2(U8G2_R0, /* CS=*/ 12, /* reset=*/ U8X8_PIN_NONE); // (Uno and co
|
||||
|
||||
// settings for u8g lib and LCD
|
||||
#define _LCDML_DISP_w 128 // LCD width
|
||||
#define _LCDML_DISP_h 64 // LCD height
|
||||
// font settings
|
||||
#define _LCDML_DISP_font u8g_font_6x13 // u8glib font (more fonts under u8g.h line 1520 ...)
|
||||
#define _LCDML_DISP_font_w 6 // font width
|
||||
#define _LCDML_DISP_font_h 13 // font height
|
||||
// cursor settings
|
||||
#define _LCDML_DISP_cursor_char "X" // cursor char
|
||||
#define _LCDML_DISP_cur_space_before 2 // cursor space between
|
||||
#define _LCDML_DISP_cur_space_behind 4 // cursor space between
|
||||
// menu position and size
|
||||
#define _LCDML_DISP_box_x0 0 // start point (x0, y0)
|
||||
#define _LCDML_DISP_box_y0 0 // start point (x0, y0)
|
||||
#define _LCDML_DISP_box_x1 128 // width x (x0 + width)
|
||||
#define _LCDML_DISP_box_y1 64 // hight y (y0 + height)
|
||||
#define _LCDML_DISP_draw_frame 1 // draw a box around the menu
|
||||
// scrollbar width
|
||||
#define _LCDML_DISP_scrollbar_w 6 // scrollbar width (if this value is < 3, the scrollbar is disabled)
|
||||
|
||||
// nothing change here
|
||||
#define _LCDML_DISP_cols_max ((_LCDML_DISP_box_x1-_LCDML_DISP_box_x0)/_LCDML_DISP_font_w)
|
||||
#define _LCDML_DISP_rows_max ((_LCDML_DISP_box_y1-_LCDML_DISP_box_y0-((_LCDML_DISP_box_y1-_LCDML_DISP_box_y0)/_LCDML_DISP_font_h))/_LCDML_DISP_font_h)
|
||||
|
||||
// rows and cols
|
||||
// when you use more rows or cols as allowed change in LCDMenuLib.h the define "_LCDML_DISP_cfg_max_rows" and "_LCDML_DISP_cfg_max_string_length"
|
||||
// the program needs more ram with this changes
|
||||
#define _LCDML_DISP_rows _LCDML_DISP_rows_max // max rows
|
||||
#define _LCDML_DISP_cols 20 // max cols
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "P1 dummy" , NULL); // NULL = no menu function
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "P1 Settings" , NULL); // NULL = no menu function
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 1" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 2" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 3" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 22
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
u8g2.begin();
|
||||
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Enable Menu Rollover
|
||||
LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
// this function must called here, do not delete it
|
||||
LCDML.loop();
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// check some errors - do not change here anything
|
||||
// *********************************************************************
|
||||
# if(_LCDML_glcd_tft_box_x1 > _LCDML_glcd_tft_w)
|
||||
# error _LCDML_glcd_tft_box_x1 is to big
|
||||
# endif
|
||||
|
||||
# if(_LCDML_glcd_tft_box_y1 > _LCDML_glcd_tft_h)
|
||||
# error _LCDML_glcd_tft_box_y1 is to big
|
||||
# endif
|
||||
@@ -0,0 +1,15 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
|
||||
LCDML.BT_resetEnter();
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
LCDML.BT_resetUp();
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
LCDML.BT_resetDown();
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
LCDML.BT_resetLeft();
|
||||
}
|
||||
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
LCDML.BT_resetRight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "dynValue: %d", g_dynParam);
|
||||
|
||||
// setup function
|
||||
u8g2.drawStr( _LCDML_DISP_box_x0+_LCDML_DISP_font_w + _LCDML_DISP_cur_space_behind, (_LCDML_DISP_font_h * (1+line)), buf); // the value can be changed with left or right
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// for first test set font here
|
||||
u8g2.setFont(_LCDML_DISP_font);
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// init vars
|
||||
uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
|
||||
uint8_t scrollbar_min = 0;
|
||||
uint8_t scrollbar_max = LCDML.MENU_getChilds();
|
||||
uint8_t scrollbar_cur_pos = LCDML.MENU_getCursorPosAbs();
|
||||
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
|
||||
|
||||
// generate content
|
||||
u8g2.firstPage();
|
||||
do {
|
||||
|
||||
|
||||
n = 0;
|
||||
i = LCDML.MENU_getScroll();
|
||||
// update content
|
||||
// ***************
|
||||
|
||||
// clear menu
|
||||
// ***************
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
u8g2.drawStr( _LCDML_DISP_box_x0+_LCDML_DISP_font_w + _LCDML_DISP_cur_space_behind, _LCDML_DISP_box_y0 + _LCDML_DISP_font_h * (n + 1), content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
|
||||
// set cursor
|
||||
u8g2.drawStr( _LCDML_DISP_box_x0+_LCDML_DISP_cur_space_before, _LCDML_DISP_box_y0 + _LCDML_DISP_font_h * (LCDML.MENU_getCursorPos() + 1), _LCDML_DISP_cursor_char);
|
||||
|
||||
if(_LCDML_DISP_draw_frame == 1) {
|
||||
u8g2.drawFrame(_LCDML_DISP_box_x0, _LCDML_DISP_box_y0, (_LCDML_DISP_box_x1-_LCDML_DISP_box_x0), (_LCDML_DISP_box_y1-_LCDML_DISP_box_y0));
|
||||
}
|
||||
|
||||
// display scrollbar when more content as rows available and with > 2
|
||||
if (scrollbar_max > n_max && _LCDML_DISP_scrollbar_w > 2)
|
||||
{
|
||||
// set frame for scrollbar
|
||||
u8g2.drawFrame(_LCDML_DISP_box_x1 - _LCDML_DISP_scrollbar_w, _LCDML_DISP_box_y0, _LCDML_DISP_scrollbar_w, _LCDML_DISP_box_y1-_LCDML_DISP_box_y0);
|
||||
|
||||
// calculate scrollbar length
|
||||
uint8_t scrollbar_block_length = scrollbar_max - n_max;
|
||||
scrollbar_block_length = (_LCDML_DISP_box_y1-_LCDML_DISP_box_y0) / (scrollbar_block_length + _LCDML_DISP_rows);
|
||||
|
||||
//set scrollbar
|
||||
if (scrollbar_cur_pos == 0) { // top position (min)
|
||||
u8g2.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y0 + 1 , (_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
else if (scrollbar_cur_pos == (scrollbar_max-1)) { // bottom position (max)
|
||||
u8g2.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y1 - scrollbar_block_length , (_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
else { // between top and bottom
|
||||
u8g2.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y0 + (scrollbar_block_length * scrollbar_cur_pos + 1),(_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
}
|
||||
} while ( u8g2.nextPage() );
|
||||
}
|
||||
@@ -0,0 +1,379 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
u8g2.setFont(_LCDML_DISP_font);
|
||||
u8g2.firstPage();
|
||||
do {
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 1), "To close this");
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 2), "function press");
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 3), "any button or use");
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 4), "back button");
|
||||
} while( u8g2.nextPage() );
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "wait %d seconds", g_func_timer_info);
|
||||
|
||||
u8g2.setFont(_LCDML_DISP_font);
|
||||
u8g2.firstPage();
|
||||
do {
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 1), buf);
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 2), "or press back button");
|
||||
} while( u8g2.nextPage() );
|
||||
|
||||
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000))
|
||||
{
|
||||
g_timer_1 = millis();
|
||||
g_func_timer_info--; // increment the value every second
|
||||
char buf[20];
|
||||
sprintf (buf, "wait %d seconds", g_func_timer_info);
|
||||
|
||||
u8g2.setFont(_LCDML_DISP_font);
|
||||
u8g2.firstPage();
|
||||
do {
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 1), buf);
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 2), "or press back button");
|
||||
} while( u8g2.nextPage() );
|
||||
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
char buf[17];
|
||||
sprintf (buf, "count: %d of 3", 0);
|
||||
|
||||
u8g2.setFont(_LCDML_DISP_font);
|
||||
u8g2.firstPage();
|
||||
do {
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 1), "press a or w button");
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 2), buf);
|
||||
} while( u8g2.nextPage() );
|
||||
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
char buf[20];
|
||||
sprintf (buf, "count: %d of 3", g_button_value);
|
||||
|
||||
u8g2.setFont(_LCDML_DISP_font);
|
||||
u8g2.firstPage();
|
||||
do {
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 1), "press a or w button");
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 2), buf);
|
||||
} while( u8g2.nextPage() );
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
u8g2.setFont(_LCDML_DISP_font);
|
||||
u8g2.firstPage();
|
||||
do {
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 1), "screensaver");
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 2), "press any key");
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 3), "to leave it");
|
||||
} while( u8g2.nextPage() );
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// The screensaver go to the root menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function and go a layer back
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "parameter: %d", param);
|
||||
|
||||
// setup function
|
||||
u8g2.setFont(_LCDML_DISP_font);
|
||||
u8g2.firstPage();
|
||||
do {
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 1), buf);
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 2), "press any key");
|
||||
u8g2.drawStr( 0, (_LCDML_DISP_font_h * 3), "to leave it");
|
||||
} while( u8g2.nextPage() );
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
// ============================================================
|
||||
// Example: LCDML: graphic display with u8g
|
||||
// ============================================================
|
||||
// Author: Jomelo
|
||||
// Last update: 21.01.2018
|
||||
// License: MIT
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example shows how to use the u8glib with the LCDMenuLib
|
||||
// The menu can placed in a box that can be placed anywhere on
|
||||
// the screen.
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// include libs
|
||||
#include <LCDMenuLib2.h>
|
||||
#include <U8glib.h>
|
||||
|
||||
// *********************************************************************
|
||||
// U8GLIB
|
||||
// *********************************************************************
|
||||
// setup u8g object, please remove comment from one of the following constructor calls
|
||||
// IMPORTANT NOTE: The following list is incomplete. The complete list of supported
|
||||
// devices with all constructor calls is here: https://github.com/olikraus/u8glib/wiki/device
|
||||
U8GLIB_ST7920_128X64 u8g(52, 51, 53, U8G_PIN_NONE);
|
||||
|
||||
// settings for u8g lib and LCD
|
||||
#define _LCDML_DISP_w 128 // LCD width
|
||||
#define _LCDML_DISP_h 64 // LCD height
|
||||
// font settings
|
||||
#define _LCDML_DISP_font u8g_font_6x13 // u8glib font (more fonts under u8g.h line 1520 ...)
|
||||
#define _LCDML_DISP_font_w 6 // font width
|
||||
#define _LCDML_DISP_font_h 13 // font height
|
||||
// cursor settings
|
||||
#define _LCDML_DISP_cursor_char "X" // cursor char
|
||||
#define _LCDML_DISP_cur_space_before 2 // cursor space between
|
||||
#define _LCDML_DISP_cur_space_behind 4 // cursor space between
|
||||
// menu position and size
|
||||
#define _LCDML_DISP_box_x0 0 // start point (x0, y0)
|
||||
#define _LCDML_DISP_box_y0 0 // start point (x0, y0)
|
||||
#define _LCDML_DISP_box_x1 128 // width x (x0 + width)
|
||||
#define _LCDML_DISP_box_y1 64 // hight y (y0 + height)
|
||||
#define _LCDML_DISP_draw_frame 1 // draw a box around the menu
|
||||
// scrollbar width
|
||||
#define _LCDML_DISP_scrollbar_w 6 // scrollbar width (if this value is < 3, the scrollbar is disabled)
|
||||
|
||||
// nothing change here
|
||||
#define _LCDML_DISP_cols_max ((_LCDML_DISP_box_x1-_LCDML_DISP_box_x0)/_LCDML_DISP_font_w)
|
||||
#define _LCDML_DISP_rows_max ((_LCDML_DISP_box_y1-_LCDML_DISP_box_y0-((_LCDML_DISP_box_y1-_LCDML_DISP_box_y0)/_LCDML_DISP_font_h))/_LCDML_DISP_font_h)
|
||||
|
||||
// rows and cols
|
||||
// when you use more rows or cols as allowed change in LCDMenuLib.h the define "_LCDML_DISP_cfg_max_rows" and "_LCDML_DISP_cfg_max_string_length"
|
||||
// the program needs more ram with this changes
|
||||
#define _LCDML_DISP_rows _LCDML_DISP_rows_max // max rows
|
||||
#define _LCDML_DISP_cols 20 // max cols
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "P1 dummy" , NULL); // NULL = no menu function
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "P1 Settings" , NULL); // NULL = no menu function
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 1" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 2" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 3" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 22
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Enable Menu Rollover
|
||||
LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
// this function must called here, do not delete it
|
||||
LCDML.loop();
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// check some errors - do not change here anything
|
||||
// *********************************************************************
|
||||
# if(_LCDML_glcd_tft_box_x1 > _LCDML_glcd_tft_w)
|
||||
# error _LCDML_glcd_tft_box_x1 is to big
|
||||
# endif
|
||||
|
||||
# if(_LCDML_glcd_tft_box_y1 > _LCDML_glcd_tft_h)
|
||||
# error _LCDML_glcd_tft_box_y1 is to big
|
||||
# endif
|
||||
@@ -0,0 +1,15 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
|
||||
LCDML.BT_resetEnter();
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
LCDML.BT_resetUp();
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
LCDML.BT_resetDown();
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
LCDML.BT_resetLeft();
|
||||
}
|
||||
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
LCDML.BT_resetRight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "dynValue: %d", g_dynParam);
|
||||
|
||||
// setup function
|
||||
u8g.drawStr( _LCDML_DISP_box_x0+_LCDML_DISP_font_w + _LCDML_DISP_cur_space_behind, (_LCDML_DISP_font_h * (1+line)), buf); // the value can be changed with left or right
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// for first test set font here
|
||||
u8g.setFont(_LCDML_DISP_font);
|
||||
//u8g.setColorIndex(1); // Instructs the display to draw with a pixel on.
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// init vars
|
||||
uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
|
||||
uint8_t scrollbar_min = 0;
|
||||
uint8_t scrollbar_max = LCDML.MENU_getChilds();
|
||||
uint8_t scrollbar_cur_pos = LCDML.MENU_getCursorPosAbs();
|
||||
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
|
||||
|
||||
|
||||
// for first test set font here
|
||||
u8g.setFont(_LCDML_DISP_font);
|
||||
u8g.setColorIndex(1); // Instructs the display to draw with a pixel on.
|
||||
|
||||
|
||||
// generate content
|
||||
u8g.firstPage();
|
||||
do {
|
||||
|
||||
|
||||
n = 0;
|
||||
i = LCDML.MENU_getScroll();
|
||||
// update content
|
||||
// ***************
|
||||
|
||||
// clear menu
|
||||
// ***************
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
u8g.drawStr( _LCDML_DISP_box_x0+_LCDML_DISP_font_w + _LCDML_DISP_cur_space_behind, _LCDML_DISP_box_y0 + _LCDML_DISP_font_h * (n + 1), content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
|
||||
// set cursor
|
||||
u8g.drawStr( _LCDML_DISP_box_x0+_LCDML_DISP_cur_space_before, _LCDML_DISP_box_y0 + _LCDML_DISP_font_h * (LCDML.MENU_getCursorPos() + 1), _LCDML_DISP_cursor_char);
|
||||
|
||||
if(_LCDML_DISP_draw_frame == 1) {
|
||||
u8g.drawFrame(_LCDML_DISP_box_x0, _LCDML_DISP_box_y0, (_LCDML_DISP_box_x1-_LCDML_DISP_box_x0), (_LCDML_DISP_box_y1-_LCDML_DISP_box_y0));
|
||||
}
|
||||
|
||||
// display scrollbar when more content as rows available and with > 2
|
||||
if (scrollbar_max > n_max && _LCDML_DISP_scrollbar_w > 2)
|
||||
{
|
||||
// set frame for scrollbar
|
||||
u8g.drawFrame(_LCDML_DISP_box_x1 - _LCDML_DISP_scrollbar_w, _LCDML_DISP_box_y0, _LCDML_DISP_scrollbar_w, _LCDML_DISP_box_y1-_LCDML_DISP_box_y0);
|
||||
|
||||
// calculate scrollbar length
|
||||
uint8_t scrollbar_block_length = scrollbar_max - n_max;
|
||||
scrollbar_block_length = (_LCDML_DISP_box_y1-_LCDML_DISP_box_y0) / (scrollbar_block_length + _LCDML_DISP_rows);
|
||||
|
||||
//set scrollbar
|
||||
if (scrollbar_cur_pos == 0) { // top position (min)
|
||||
u8g.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y0 + 1 , (_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
else if (scrollbar_cur_pos == (scrollbar_max-1)) { // bottom position (max)
|
||||
u8g.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y1 - scrollbar_block_length , (_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
else { // between top and bottom
|
||||
u8g.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y0 + (scrollbar_block_length * scrollbar_cur_pos + 1),(_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
}
|
||||
} while ( u8g.nextPage() );
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
u8g.setFont(_LCDML_DISP_font);
|
||||
u8g.firstPage();
|
||||
do {
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 1), F("To close this"));
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 2), F("function press"));
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 3), F("any button or use"));
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 4), F("back button"));
|
||||
} while( u8g.nextPage() );
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "wait %d seconds", g_func_timer_info);
|
||||
|
||||
u8g.setFont(_LCDML_DISP_font);
|
||||
u8g.firstPage();
|
||||
do {
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 1), buf);
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 2), F("or press back button"));
|
||||
} while( u8g.nextPage() );
|
||||
|
||||
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000))
|
||||
{
|
||||
g_timer_1 = millis();
|
||||
g_func_timer_info--; // increment the value every second
|
||||
char buf[20];
|
||||
sprintf (buf, "wait %d seconds", g_func_timer_info);
|
||||
|
||||
u8g.setFont(_LCDML_DISP_font);
|
||||
u8g.firstPage();
|
||||
do {
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 1), buf);
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 2), F("or press back button"));
|
||||
} while( u8g.nextPage() );
|
||||
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
char buf[17];
|
||||
sprintf (buf, "count: %d of 3", 0);
|
||||
|
||||
u8g.setFont(_LCDML_DISP_font);
|
||||
u8g.firstPage();
|
||||
do {
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 1), F("press a or w button"));
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 2), buf);
|
||||
} while( u8g.nextPage() );
|
||||
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
char buf[17];
|
||||
sprintf (buf, "count: %d of 3", g_button_value);
|
||||
|
||||
u8g.setFont(_LCDML_DISP_font);
|
||||
u8g.firstPage();
|
||||
do {
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 1), F("press a or w button"));
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 2), buf);
|
||||
} while( u8g.nextPage() );
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
u8g.setFont(_LCDML_DISP_font);
|
||||
u8g.firstPage();
|
||||
do {
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 1), F("screensaver"));
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 2), F("press any key"));
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 3), F("to leave it"));
|
||||
} while( u8g.nextPage() );
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// The screensaver go to the root menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function and go a layer back
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
char buf[20];
|
||||
sprintf (buf, "parameter: %d", param);
|
||||
|
||||
// setup function
|
||||
u8g.setFont(_LCDML_DISP_font);
|
||||
u8g.firstPage();
|
||||
do {
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 1), buf);
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 2), F("press any key"));
|
||||
u8g.drawStr( 0, (_LCDML_DISP_font_h * 3), F("to leave it"));
|
||||
} while( u8g.nextPage() );
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
// ============================================================
|
||||
// Example: LCDML: use ADAFRUIT i2c display ssd1306
|
||||
// ============================================================
|
||||
// Author: Jomelo
|
||||
// Last update: 12.11.2018
|
||||
// License: MIT
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example shows how to use the adafruit gfx library
|
||||
// with the LCDMenuLib.
|
||||
// The menu can placed in a box that can be placed anywhere on
|
||||
// the screen.
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// include libs
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
#include <SPI.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
|
||||
// *********************************************************************
|
||||
// Adufruit SSD1306
|
||||
// *********************************************************************
|
||||
// http://blog.simtronyx.de/ein-096-zoll-oled-display-i%C2%B2c-mit-128x64-pixel-und-ein-arduino/
|
||||
|
||||
#define _ADAFRUIT_I2C_ADR 0x3C
|
||||
|
||||
#define _ADAFRUIT_I2C_ADR 0x3C
|
||||
#define _LCDML_ADAFRUIT_TEXT_COLOR WHITE
|
||||
|
||||
#define _LCDML_ADAFRUIT_FONT_SIZE 1
|
||||
#define _LCDML_ADAFRUIT_FONT_W (6*_LCDML_ADAFRUIT_FONT_SIZE) // font width
|
||||
#define _LCDML_ADAFRUIT_FONT_H (8*_LCDML_ADAFRUIT_FONT_SIZE) // font heigt
|
||||
|
||||
// settings for u8g lib and lcd
|
||||
#define _LCDML_ADAFRUIT_lcd_w 128 // lcd width
|
||||
#define _LCDML_ADAFRUIT_lcd_h 64 // lcd height
|
||||
|
||||
#define OLED_RESET 4 // not used / nicht genutzt bei diesem Display
|
||||
Adafruit_SSD1306 display(OLED_RESET);
|
||||
|
||||
// nothing change here
|
||||
#define _LCDML_ADAFRUIT_cols_max (_LCDML_ADAFRUIT_lcd_w/_LCDML_ADAFRUIT_FONT_W)
|
||||
#define _LCDML_ADAFRUIT_rows_max (_LCDML_ADAFRUIT_lcd_h/_LCDML_ADAFRUIT_FONT_H)
|
||||
|
||||
// rows and cols
|
||||
// when you use more rows or cols as allowed change in LCDMenuLib.h the define "_LCDML_DISP_cfg_max_rows" and "_LCDML_DISP_cfg_max_string_length"
|
||||
// the program needs more ram with this changes
|
||||
#define _LCDML_ADAFRUIT_cols 20 // max cols
|
||||
#define _LCDML_ADAFRUIT_rows _LCDML_ADAFRUIT_rows_max // max rows
|
||||
|
||||
|
||||
// scrollbar width
|
||||
#define _LCDML_ADAFRUIT_scrollbar_w 6 // scrollbar width
|
||||
|
||||
// old defines with new content
|
||||
#define _LCDML_DISP_cols _LCDML_ADAFRUIT_cols
|
||||
#define _LCDML_DISP_rows _LCDML_ADAFRUIT_rows
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "P1 dummy" , NULL); // NULL = no menu function
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "P1 Settings" , NULL); // NULL = no menu function
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 1" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 2" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 3" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 22
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
/* INIT DISPLAY */
|
||||
// initialize with the I2C addr / mit I2C-Adresse initialisieren
|
||||
display.begin(SSD1306_SWITCHCAPVCC, _ADAFRUIT_I2C_ADR);
|
||||
|
||||
// clear lcd
|
||||
display.clearDisplay();
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * (3));
|
||||
display.println("LCDMenuLib v2.1.4 alpha");
|
||||
display.display();
|
||||
|
||||
/* INIT LCDML */
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Enable Menu Rollover
|
||||
LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
// this function must called here, do not delete it
|
||||
LCDML.loop();
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// check some errors - do not change here anything
|
||||
// *********************************************************************
|
||||
# if(_LCDML_glcd_tft_box_x1 > _LCDML_glcd_tft_w)
|
||||
# error _LCDML_glcd_tft_box_x1 is to big
|
||||
# endif
|
||||
|
||||
# if(_LCDML_glcd_tft_box_y1 > _LCDML_glcd_tft_h)
|
||||
# error _LCDML_glcd_tft_box_y1 is to big
|
||||
# endif
|
||||
@@ -0,0 +1,15 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
|
||||
LCDML.BT_resetEnter();
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
LCDML.BT_resetUp();
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
LCDML.BT_resetDown();
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
LCDML.BT_resetLeft();
|
||||
}
|
||||
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
LCDML.BT_resetRight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "dynValue: %d", g_dynParam);
|
||||
|
||||
display.setCursor(1, _LCDML_ADAFRUIT_FONT_H * (line));
|
||||
display.println(buf);
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// clear lcd
|
||||
display.clearDisplay();
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// init vars
|
||||
uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
|
||||
uint8_t scrollbar_min = 0;
|
||||
uint8_t scrollbar_max = LCDML.MENU_getChilds();
|
||||
uint8_t scrollbar_cur_pos = LCDML.MENU_getCursorPosAbs();
|
||||
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
|
||||
|
||||
|
||||
n = 0;
|
||||
i = LCDML.MENU_getScroll();
|
||||
// update content
|
||||
// ***************
|
||||
|
||||
// clear menu
|
||||
// ***************
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
display.setCursor(1, _LCDML_ADAFRUIT_FONT_H * (n));
|
||||
display.println(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
|
||||
// set cursor
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * (LCDML.MENU_getCursorPos()));
|
||||
display.println("X");
|
||||
|
||||
// ***** todo *****
|
||||
#ifdef _SCROLLBAR_TODO_
|
||||
if(_LCDML_DISP_draw_frame == 1) {
|
||||
u8g2.drawFrame(_LCDML_DISP_box_x0, _LCDML_DISP_box_y0, (_LCDML_DISP_box_x1-_LCDML_DISP_box_x0), (_LCDML_DISP_box_y1-_LCDML_DISP_box_y0));
|
||||
}
|
||||
|
||||
|
||||
// display scrollbar when more content as rows available and with > 2
|
||||
|
||||
if (scrollbar_max > n_max && _LCDML_DISP_scrollbar_w > 2)
|
||||
{
|
||||
// set frame for scrollbar
|
||||
//u8g2.drawFrame(_LCDML_DISP_box_x1 - _LCDML_DISP_scrollbar_w, _LCDML_DISP_box_y0, _LCDML_DISP_scrollbar_w, _LCDML_DISP_box_y1-_LCDML_DISP_box_y0);
|
||||
display.drawRect(_LCDML_ADAFRUIT_lcd_w - _LCDML_ADAFRUIT_scrollbar_w, 0,_LCDML_ADAFRUIT_scrollbar_w,_LCDML_ADAFRUIT_lcd_h, _LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
|
||||
// calculate scrollbar length
|
||||
uint8_t scrollbar_block_length = scrollbar_max - n_max;
|
||||
scrollbar_block_length = (_LCDML_DISP_box_y1-_LCDML_DISP_box_y0) / (scrollbar_block_length + _LCDML_DISP_rows);
|
||||
|
||||
//set scrollbar
|
||||
if (scrollbar_cur_pos == 0) { // top position (min)
|
||||
u8g2.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y0 + 1 , (_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
else if (scrollbar_cur_pos == (scrollbar_max-1)) { // bottom position (max)
|
||||
u8g2.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y1 - scrollbar_block_length , (_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
else { // between top and bottom
|
||||
u8g2.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y0 + (scrollbar_block_length * scrollbar_cur_pos + 1),(_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
display.display();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// clear lcd
|
||||
display.clearDisplay();
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(F("To close this"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(F("function press"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 2); // line 2
|
||||
display.println(F("any button or use"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 3); // line 3
|
||||
display.println(F("back button"));
|
||||
display.display();
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "wait %d seconds", g_func_timer_info);
|
||||
|
||||
// clear lcd
|
||||
display.clearDisplay();
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(buf);
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(F("or press back button"));
|
||||
display.display();
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000))
|
||||
{
|
||||
g_timer_1 = millis();
|
||||
g_func_timer_info--; // increment the value every second
|
||||
char buf[20];
|
||||
sprintf (buf, "wait %d seconds", g_func_timer_info);
|
||||
|
||||
// clear lcd
|
||||
display.clearDisplay();
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(buf);
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(F("or press back button"));
|
||||
display.display();
|
||||
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
char buf[17];
|
||||
sprintf (buf, "count: %d of 3", 0);
|
||||
|
||||
// clear lcd
|
||||
display.clearDisplay();
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(F("press a or w button"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(buf);
|
||||
display.display();
|
||||
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
char buf[20];
|
||||
sprintf (buf, "count: %d of 3", g_button_value);
|
||||
|
||||
// clear lcd
|
||||
display.clearDisplay();
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(F("press a or w button"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(buf);
|
||||
display.display();
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
|
||||
// clear lcd
|
||||
display.clearDisplay();
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(F("screensaver"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(F("press any key"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 2); // line 2
|
||||
display.println(F("to leave it"));
|
||||
display.display();
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// The screensaver go to the root menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function and go a layer back
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "parameter: %d", param);
|
||||
|
||||
// setup function
|
||||
// clear lcd
|
||||
display.clearDisplay();
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(buf);
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(F("press any key"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 2); // line 2
|
||||
display.println(F("to leave it"));
|
||||
display.display();
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
// ============================================================
|
||||
// Example: LCDML: use ADAFRUIT i2c display ssd1306
|
||||
// ============================================================
|
||||
// Author: Jomelo, Markus Rudel
|
||||
// Last update: 12.11.2018
|
||||
// License: MIT
|
||||
// ============================================================
|
||||
// Description:
|
||||
// This example shows how to use the adafruit gfx library
|
||||
// with the LCDMenuLib.
|
||||
// The menu can placed in a box that can be placed anywhere on
|
||||
// the screen.
|
||||
// ============================================================
|
||||
// *********************************************************************
|
||||
// special settings
|
||||
// *********************************************************************
|
||||
// enable this line when you are not usigng a standard arduino
|
||||
// for example when your chip is an ESP or a STM or SAM or something else
|
||||
|
||||
//#define _LCDML_cfg_use_ram
|
||||
|
||||
// include libs
|
||||
#include <LCDMenuLib2.h>
|
||||
|
||||
#include <SPI.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_ST7735.h> // Hardware-specific library
|
||||
|
||||
// *********************************************************************
|
||||
// Adafruit TFT_ST7735
|
||||
// *********************************************************************
|
||||
// https://learn.adafruit.com/1-8-tft-display/graphics-library
|
||||
|
||||
#define _LCDML_ADAFRUIT_TEXT_COLOR ST7735_WHITE
|
||||
#define _LCDML_ADAFRUIT_BACKGROUND_COLOR ST7735_BLACK
|
||||
|
||||
#define _LCDML_ADAFRUIT_FONT_SIZE 3
|
||||
#define _LCDML_ADAFRUIT_FONT_W (6*_LCDML_ADAFRUIT_FONT_SIZE) // font width
|
||||
#define _LCDML_ADAFRUIT_FONT_H (8*_LCDML_ADAFRUIT_FONT_SIZE) // font heigt
|
||||
|
||||
// settings for u8g lib and lcd
|
||||
#define _LCDML_ADAFRUIT_lcd_w 128 // lcd width
|
||||
#define _LCDML_ADAFRUIT_lcd_h 160 // lcd height
|
||||
|
||||
|
||||
|
||||
// TFT display and SD card will share the hardware SPI interface.
|
||||
// Hardware SPI pins are specific to the Arduino board type and
|
||||
// cannot be remapped to alternate pins. For Arduino Uno,
|
||||
// Duemilanove, etc., pin 11 = MOSI, pin 12 = MISO, pin 13 = SCK.
|
||||
#define TFT_CS 10 // Chip select line for TFT display
|
||||
#define TFT_RST 9 // Reset line for TFT (or see below...)
|
||||
#define TFT_DC 8 // Data/command line for TFT
|
||||
|
||||
#define SD_CS 4 // Chip select line for SD card
|
||||
Adafruit_ST7735 display = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
|
||||
|
||||
|
||||
|
||||
// nothing change here
|
||||
#define _LCDML_ADAFRUIT_cols_max (_LCDML_ADAFRUIT_lcd_w/_LCDML_ADAFRUIT_FONT_W)
|
||||
#define _LCDML_ADAFRUIT_rows_max (_LCDML_ADAFRUIT_lcd_h/_LCDML_ADAFRUIT_FONT_H)
|
||||
|
||||
// rows and cols
|
||||
// when you use more rows or cols as allowed change in LCDMenuLib.h the define "_LCDML_DISP_cfg_max_rows" and "_LCDML_DISP_cfg_max_string_length"
|
||||
// the program needs more ram with this changes
|
||||
#define _LCDML_ADAFRUIT_cols 20 // max cols
|
||||
#define _LCDML_ADAFRUIT_rows _LCDML_ADAFRUIT_rows_max // max rows
|
||||
|
||||
|
||||
// scrollbar width
|
||||
#define _LCDML_ADAFRUIT_scrollbar_w 6 // scrollbar width
|
||||
|
||||
|
||||
// old defines with new content
|
||||
#define _LCDML_DISP_cols _LCDML_ADAFRUIT_cols
|
||||
#define _LCDML_DISP_rows _LCDML_ADAFRUIT_rows
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Prototypes
|
||||
// *********************************************************************
|
||||
void lcdml_menu_display();
|
||||
void lcdml_menu_clear();
|
||||
void lcdml_menu_control();
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// Objects
|
||||
// *********************************************************************
|
||||
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// LCDML MENU/DISP
|
||||
// *********************************************************************
|
||||
// LCDML_0 => layer 0
|
||||
// LCDML_0_X => layer 1
|
||||
// LCDML_0_X_X => layer 2
|
||||
// LCDML_0_X_X_X => layer 3
|
||||
// LCDML_0_... => layer ...
|
||||
|
||||
// For beginners
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add (0 , LCDML_0 , 1 , "Information" , mFunc_information); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (1 , LCDML_0 , 2 , "Time info" , mFunc_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (2 , LCDML_0 , 3 , "Program" , NULL); // NULL = no menu function
|
||||
LCDML_add (3 , LCDML_0_3 , 1 , "Program 1" , NULL); // NULL = no menu function
|
||||
LCDML_add (4 , LCDML_0_3_1 , 1 , "P1 dummy" , NULL); // NULL = no menu function
|
||||
LCDML_add (5 , LCDML_0_3_1 , 2 , "P1 Settings" , NULL); // NULL = no menu function
|
||||
LCDML_add (6 , LCDML_0_3_1_2 , 1 , "Warm" , NULL); // NULL = no menu function
|
||||
LCDML_add (7 , LCDML_0_3_1_2 , 2 , "Cold" , NULL); // NULL = no menu function
|
||||
LCDML_add (8 , LCDML_0_3_1_2 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (9 , LCDML_0_3_1 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (10 , LCDML_0_3 , 2 , "Program 2" , mFunc_p2); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (11 , LCDML_0_3 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (12 , LCDML_0 , 4 , "Special" , NULL); // NULL = no menu function
|
||||
LCDML_add (13 , LCDML_0_4 , 1 , "Go to Root" , mFunc_goToRootMenu); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (14 , LCDML_0_4 , 2 , "Jump to Time info", mFunc_jumpTo_timer_info); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
LCDML_add (15 , LCDML_0_4 , 3 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Advanced menu (for profit) part with more settings
|
||||
// Example for one function and different parameters
|
||||
// It is recommend to use parameters for switching settings like, (small drink, medium drink, big drink) or (200ml, 400ml, 600ml, 800ml) ...
|
||||
// the parameter change can also be released with dynParams on the next example
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (16 , LCDML_0 , 5 , NULL, "Parameter" , NULL, 0, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (17 , LCDML_0_5 , 1 , NULL, "Parameter 1" , mFunc_para, 10, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (18 , LCDML_0_5 , 2 , NULL, "Parameter 2" , mFunc_para, 20, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_addAdvanced (19 , LCDML_0_5 , 3 , NULL, "Parameter 3" , mFunc_para, 30, _LCDML_TYPE_default); // NULL = no menu function
|
||||
LCDML_add (20 , LCDML_0_5 , 4 , "Back" , mFunc_back); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
|
||||
// Example for dynamic content
|
||||
// 1. set the string to ""
|
||||
// 2. use type _LCDML_TYPE_dynParam instead of _LCDML_TYPE_default
|
||||
// this function type can not be used in combination with different parameters
|
||||
// LCDMenuLib_addAdvanced(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (21 , LCDML_0 , 6 , NULL, "" , mDyn_para, 0, _LCDML_TYPE_dynParam); // NULL = no menu function
|
||||
|
||||
// Example for conditions (for example for a screensaver)
|
||||
// 1. define a condition as a function of a boolean type -> return false = not displayed, return true = displayed
|
||||
// 2. set the function name as callback (remove the braces '()' it gives bad errors)
|
||||
// LCDMenuLib_add(id, prev_layer, new_num, condition, lang_char_array, callback_function, parameter (0-255), menu function type )
|
||||
LCDML_addAdvanced (22 , LCDML_0 , 7 , COND_hide, "screensaver" , mFunc_screensaver, 0, _LCDML_TYPE_default); // this menu function can be found on "LCDML_display_menuFunction" tab
|
||||
|
||||
// ***TIP*** Try to update _LCDML_DISP_cnt when you add a menu element.
|
||||
|
||||
// menu element count - last element id
|
||||
// this value must be the same as the last menu element
|
||||
#define _LCDML_DISP_cnt 22
|
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt);
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// SETUP
|
||||
// *********************************************************************
|
||||
void setup()
|
||||
{
|
||||
// serial init; only be needed if serial control is used
|
||||
Serial.begin(9600); // start serial
|
||||
Serial.println(F(_LCDML_VERSION)); // only for examples
|
||||
|
||||
/* INIT DISPLAY */
|
||||
SPI.begin();
|
||||
|
||||
// Our supplier changed the 1.8" display slightly after Jan 10, 2012
|
||||
// so that the alignment of the TFT had to be shifted by a few pixels
|
||||
// this just means the init code is slightly different. Check the
|
||||
// color of the tab to see which init code to try. If the display is
|
||||
// cut off or has extra 'random' pixels on the top & left, try the
|
||||
// other option!
|
||||
// If you are seeing red and green color inversion, use Black Tab
|
||||
|
||||
// If your TFT's plastic wrap has a Black Tab, use the following:
|
||||
display.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab
|
||||
// If your TFT's plastic wrap has a Red Tab, use the following:
|
||||
//tft.initR(INITR_REDTAB); // initialize a ST7735R chip, red tab
|
||||
// If your TFT's plastic wrap has a Green Tab, use the following:
|
||||
//tft.initR(INITR_GREENTAB); // initialize a ST7735R chip, green tab
|
||||
|
||||
// clear lcd
|
||||
display.fillScreen(_LCDML_ADAFRUIT_BACKGROUND_COLOR);
|
||||
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * (3));
|
||||
display.println(_LCDML_VERSION);
|
||||
|
||||
/* INIT LCDML */
|
||||
// LCDMenuLib Setup
|
||||
LCDML_setup(_LCDML_DISP_cnt);
|
||||
|
||||
// Enable Menu Rollover
|
||||
LCDML.MENU_enRollover();
|
||||
|
||||
// Enable Screensaver (screensaver menu function, time to activate in ms)
|
||||
LCDML.SCREEN_enable(mFunc_screensaver, 10000); // set to 10 seconds
|
||||
//LCDML.SCREEN_disable();
|
||||
|
||||
// Some needful methods
|
||||
|
||||
// You can jump to a menu function from anywhere with
|
||||
//LCDML.OTHER_jumpToFunc(mFunc_p2); // the parameter is the function name
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// LOOP
|
||||
// *********************************************************************
|
||||
void loop()
|
||||
{
|
||||
// this function must called here, do not delete it
|
||||
LCDML.loop();
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// check some errors - do not change here anything
|
||||
// *********************************************************************
|
||||
# if(_LCDML_glcd_tft_box_x1 > _LCDML_glcd_tft_w)
|
||||
# error _LCDML_glcd_tft_box_x1 is to big
|
||||
# endif
|
||||
|
||||
# if(_LCDML_glcd_tft_box_y1 > _LCDML_glcd_tft_h)
|
||||
# error _LCDML_glcd_tft_box_y1 is to big
|
||||
# endif
|
||||
@@ -0,0 +1,15 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Conditions to show or hide a menu element on the display *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
boolean COND_hide() // hide a menu element
|
||||
// *********************************************************************
|
||||
{
|
||||
return false; // hidden
|
||||
}
|
||||
@@ -0,0 +1,646 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// CONTROL v2.2.0
|
||||
//
|
||||
// =====================================================================
|
||||
// *********************************************************************
|
||||
// Features
|
||||
// - max 6 Buttons with special names (enter, quit, up, down, left, right)
|
||||
// new Features on v2.2.0
|
||||
// - max 64 Events, this could be a button ore something (Counter 0 - 63)
|
||||
// - standard buttons and events can be used at the same time
|
||||
// - Event 0 - 3 can be used with a menu callback function (when set this event, the function is called)
|
||||
// - The range from 0 - 3 can be changed in LCDMenuLib2.h
|
||||
// Attention!!
|
||||
// - events have to be reset manual over LCDML.CE_reset(number) ore LCDML.CE_resetAll();
|
||||
// - they will not be reseted from the menu library
|
||||
// *********************************************************************
|
||||
// content:
|
||||
// (0) Control over serial interface with asdw_e_q
|
||||
// (1) Control over one analog input
|
||||
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
|
||||
// (3) Control over encoder [third party lib] (Download: https://github.com/PaulStoffregen/Encoder)
|
||||
// (4) Control with Keypad [third party lib] (Download: http://playground.arduino.cc/Main/KeypadTutorial )
|
||||
// (5) Control with an IRMP remote [third party lib] (Download: https://github.com/ukw100/IRMP )
|
||||
// (6) Control with a joystick
|
||||
// (7) Control over I2C PCF8574
|
||||
// *********************************************************************
|
||||
|
||||
#define _LCDML_CONTROL_cfg 0
|
||||
|
||||
// theory:
|
||||
// "#if" is a preprocessor directive and no error, look here:
|
||||
// (English) https://en.wikipedia.org/wiki/C_preprocessor
|
||||
// (German) https://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (0) CONTROL OVER SERIAL INTERFACE *******************
|
||||
// *********************************************************************
|
||||
#if(_LCDML_CONTROL_cfg == 0)
|
||||
// settings
|
||||
# define _LCDML_CONTROL_serial_enter 'e'
|
||||
# define _LCDML_CONTROL_serial_up 'w'
|
||||
# define _LCDML_CONTROL_serial_down 's'
|
||||
# define _LCDML_CONTROL_serial_left 'a'
|
||||
# define _LCDML_CONTROL_serial_right 'd'
|
||||
# define _LCDML_CONTROL_serial_quit 'q'
|
||||
|
||||
// example for the useage of events (not needed everywhere)
|
||||
// this defines are only for examples and can be renamed
|
||||
# define _LCDML_EVENT_command 'c'
|
||||
# define _LCDML_EVENT_char_0 '0'
|
||||
# define _LCDML_EVENT_char_1 '1'
|
||||
# define _LCDML_EVENT_char_2 '2'
|
||||
# define _LCDML_EVENT_char_3 '3'
|
||||
# define _LCDML_EVENT_char_4 '4'
|
||||
# define _LCDML_EVENT_char_5 '5'
|
||||
# define _LCDML_EVENT_char_6 '6'
|
||||
# define _LCDML_EVENT_char_7 '7'
|
||||
# define _LCDML_EVENT_char_8 '8'
|
||||
# define _LCDML_EVENT_char_9 '9'
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if(LCDML.CE_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
// check if new serial input is available
|
||||
if (Serial.available()) {
|
||||
// read one char from input buffer
|
||||
switch (Serial.read())
|
||||
{
|
||||
case _LCDML_CONTROL_serial_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_serial_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_serial_down: LCDML.BT_down(); break;
|
||||
case _LCDML_CONTROL_serial_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_serial_right: LCDML.BT_right(); break;
|
||||
case _LCDML_CONTROL_serial_quit: LCDML.BT_quit(); break;
|
||||
// example for event handling
|
||||
// custom event handling
|
||||
// is is also possible to enable more the one event on the same time
|
||||
// but when more then one events with callback functions are active
|
||||
// only the first callback function is called. (first = by number)
|
||||
case _LCDML_EVENT_command: LCDML.CE_set(0); break;
|
||||
case _LCDML_EVENT_char_0: LCDML.CE_set(1); break;
|
||||
case _LCDML_EVENT_char_1: LCDML.CE_set(2); break;
|
||||
case _LCDML_EVENT_char_2: LCDML.CE_set(3); break;
|
||||
case _LCDML_EVENT_char_3: LCDML.CE_set(4); break;
|
||||
case _LCDML_EVENT_char_4: LCDML.CE_set(5); break;
|
||||
case _LCDML_EVENT_char_5: LCDML.CE_set(6); break;
|
||||
case _LCDML_EVENT_char_6: LCDML.CE_set(7); break;
|
||||
case _LCDML_EVENT_char_7: LCDML.CE_set(8); break;
|
||||
case _LCDML_EVENT_char_8: LCDML.CE_set(9); break;
|
||||
case _LCDML_EVENT_char_9: LCDML.CE_set(10); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 1)
|
||||
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pin 0
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_enter_min 850 // Button Enter
|
||||
#define _LCDML_CONTROL_analog_enter_max 920
|
||||
#define _LCDML_CONTROL_analog_up_min 520 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 590
|
||||
#define _LCDML_CONTROL_analog_down_min 700 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 770
|
||||
#define _LCDML_CONTROL_analog_back_min 950 // Button Back
|
||||
#define _LCDML_CONTROL_analog_back_max 1020
|
||||
#define _LCDML_CONTROL_analog_left_min 430 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 500
|
||||
#define _LCDML_CONTROL_analog_right_min 610 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 680
|
||||
// *********************************************************************
|
||||
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analog pin for keypad
|
||||
|
||||
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML.BT_enter(); }
|
||||
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); }
|
||||
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); }
|
||||
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); }
|
||||
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); }
|
||||
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML.BT_quit(); }
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 2)
|
||||
// settings
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
|
||||
#define _LCDML_CONTROL_digital_low_active 0 // 0 = high active (pulldown) button, 1 = low active (pullup)
|
||||
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
|
||||
#define _LCDML_CONTROL_digital_enable_quit 1
|
||||
#define _LCDML_CONTROL_digital_enable_lr 1
|
||||
#define _LCDML_CONTROL_digital_enter 8
|
||||
#define _LCDML_CONTROL_digital_up 9
|
||||
#define _LCDML_CONTROL_digital_down 10
|
||||
#define _LCDML_CONTROL_digital_quit 11
|
||||
#define _LCDML_CONTROL_digital_left 12
|
||||
#define _LCDML_CONTROL_digital_right 13
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
// init buttons
|
||||
pinMode(_LCDML_CONTROL_digital_enter , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_up , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_down , INPUT_PULLUP);
|
||||
# if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_quit , INPUT_PULLUP);
|
||||
# endif
|
||||
# if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
pinMode(_LCDML_CONTROL_digital_left , INPUT_PULLUP);
|
||||
pinMode(_LCDML_CONTROL_digital_right , INPUT_PULLUP);
|
||||
# endif
|
||||
}
|
||||
|
||||
#if(_LCDML_CONTROL_digital_low_active == 1)
|
||||
# define _LCDML_CONTROL_digital_a !
|
||||
#else
|
||||
# define _LCDML_CONTROL_digital_a
|
||||
#endif
|
||||
|
||||
uint8_t but_stat = 0x00;
|
||||
|
||||
bitWrite(but_stat, 0, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_enter)));
|
||||
bitWrite(but_stat, 1, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_up)));
|
||||
bitWrite(but_stat, 2, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_down)));
|
||||
#if(_LCDML_CONTROL_digital_enable_quit == 1)
|
||||
bitWrite(but_stat, 3, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_quit)));
|
||||
#endif
|
||||
#if(_LCDML_CONTROL_digital_enable_lr == 1)
|
||||
bitWrite(but_stat, 4, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_left)));
|
||||
bitWrite(but_stat, 5, _LCDML_CONTROL_digital_a(digitalRead(_LCDML_CONTROL_digital_right)));
|
||||
#endif
|
||||
|
||||
if (but_stat > 0) {
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
if (bitRead(but_stat, 0)) { LCDML.BT_enter(); }
|
||||
if (bitRead(but_stat, 1)) { LCDML.BT_up(); }
|
||||
if (bitRead(but_stat, 2)) { LCDML.BT_down(); }
|
||||
if (bitRead(but_stat, 3)) { LCDML.BT_quit(); }
|
||||
if (bitRead(but_stat, 4)) { LCDML.BT_left(); }
|
||||
if (bitRead(but_stat, 5)) { LCDML.BT_right(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (3) CONTROL WITH ENCODER ****************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 3)
|
||||
/*
|
||||
* Thanks to "MuchMore" (Arduino forum) to add this encoder functionality
|
||||
*
|
||||
* rotate left = Up
|
||||
* rotate right = Down
|
||||
* push = Enter
|
||||
* push long = Quit
|
||||
* push + rotate left = Left
|
||||
* push + rotate right = Right
|
||||
*/
|
||||
|
||||
/* encoder connection
|
||||
* button * (do not use an external resistor, the internal pullup resistor is used)
|
||||
* .-------o Arduino Pin
|
||||
* |
|
||||
* |
|
||||
* o /
|
||||
* /
|
||||
* /
|
||||
* o
|
||||
* |
|
||||
* '-------o GND
|
||||
*
|
||||
* encoder * (do not use an external resistor, the internal pullup resistors are used)
|
||||
*
|
||||
* .---------------o Arduino Pin A
|
||||
* | .------o Arduino Pin B
|
||||
* | |
|
||||
* o / o /
|
||||
* / /
|
||||
* / /
|
||||
* o o
|
||||
* | |
|
||||
* '--------o----o GND (common pin)
|
||||
*/
|
||||
|
||||
// global defines
|
||||
#define encoder_A_pin 20 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_B_pin 21 // physical pin has to be 2 or 3 to use interrupts (on mega e.g. 20 or 21), use internal pullups
|
||||
#define encoder_button_pin 49 // physical pin , use internal pullup
|
||||
|
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> //for Encoder Download: https://github.com/PaulStoffregen/Encoder
|
||||
|
||||
Encoder ENCODER(encoder_A_pin, encoder_B_pin);
|
||||
|
||||
unsigned long g_LCDML_CONTROL_button_press_time = millis();
|
||||
bool g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
// *********************************************************************
|
||||
{
|
||||
// declare variable for this function
|
||||
int32_t g_LCDML_CONTROL_Encoder_position = ENCODER.read();
|
||||
bool g_LCDML_button = digitalRead(encoder_button_pin);
|
||||
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup())
|
||||
{
|
||||
// runs only once
|
||||
|
||||
// init pins, enable pullups
|
||||
pinMode(encoder_A_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_B_pin , INPUT_PULLUP);
|
||||
pinMode(encoder_button_pin , INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction A
|
||||
if(g_LCDML_CONTROL_Encoder_position <= -3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_left();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_down();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position+4);
|
||||
}
|
||||
|
||||
// check if encoder is rotated on direction B
|
||||
else if(g_LCDML_CONTROL_Encoder_position >= 3)
|
||||
{
|
||||
// check if the button is pressed and the encoder is rotated
|
||||
// the button is low active
|
||||
if(g_LCDML_button == LOW)
|
||||
{
|
||||
// button is pressed
|
||||
LCDML.BT_right();
|
||||
|
||||
// reset button press time for next detection
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDML.BT_up();
|
||||
}
|
||||
|
||||
// init encoder for the next step
|
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if the button was pressed for a shortly time or a long time
|
||||
|
||||
//falling edge, button pressed, no action
|
||||
if(g_LCDML_button == LOW && g_LCDML_CONTROL_button_prev == HIGH)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = LOW;
|
||||
g_LCDML_CONTROL_button_press_time = millis();
|
||||
}
|
||||
|
||||
// rising edge, button not pressed, check how long was it pressed
|
||||
else if(g_LCDML_button == HIGH && g_LCDML_CONTROL_button_prev == LOW)
|
||||
{
|
||||
g_LCDML_CONTROL_button_prev = HIGH;
|
||||
|
||||
// check how long was the button pressed and detect a long press or a short press
|
||||
|
||||
// check long press situation
|
||||
if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press)
|
||||
{
|
||||
// long press detected
|
||||
LCDML.BT_quit();
|
||||
}
|
||||
// check short press situation
|
||||
else if((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press)
|
||||
{
|
||||
// short press detected
|
||||
LCDML.BT_enter();
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (4) CONTROL WITH A KEYPAD ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 4)
|
||||
// include
|
||||
// more information under http://playground.arduino.cc/Main/KeypadTutorial
|
||||
#include <Keypad.h>
|
||||
// settings
|
||||
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
|
||||
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
|
||||
// global vars
|
||||
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'#','0','*'}
|
||||
};
|
||||
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 9, 8, 7, 6 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
|
||||
byte colPins[_LCDML_CONTROL_keypad_cols] = { 12, 11, 10 }; // Create the Keypad
|
||||
// objects
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
char key = kpd.getKey();
|
||||
if(key) // Check for a valid key.
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
// this is the default configuration
|
||||
case '#': LCDML.BT_enter(); break;
|
||||
case '2': LCDML.BT_up(); break;
|
||||
case '8': LCDML.BT_down(); break;
|
||||
case '4': LCDML.BT_left(); break;
|
||||
case '6': LCDML.BT_right(); break;
|
||||
case '*': LCDML.BT_quit(); break;
|
||||
|
||||
// when you want to use all characters you have to use the CE_ functionality
|
||||
// CE stands for "custom event" and you can define 64 evetns
|
||||
// the following code is only an example
|
||||
/*
|
||||
case '1': LCDML.CE_set(2); break;
|
||||
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
|
||||
case '3': LCDML.CE_set(4); break;
|
||||
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
|
||||
case '5': LCDML.CE_set(6); break;
|
||||
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
|
||||
case '7': LCDML.CE_set(8); break;
|
||||
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
|
||||
case '9': LCDML.CE_set(10); break;
|
||||
case '0': LCDML.CE_set(1); break;
|
||||
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
|
||||
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
|
||||
*/
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (5) CONTROL WITH IR REMOTE ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 5)
|
||||
// IR include (this lib have to be installed)
|
||||
// Download path: https://github.com/ukw100/IRMP
|
||||
#define IRMP_INPUT_PIN PA0
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>
|
||||
#include <irmpSelectMain15Protocols.h> // This enables 15 main protocols
|
||||
|
||||
#include <irmp.c.h>
|
||||
|
||||
IRMP_DATA irmp_data[1];
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void handleReceivedIRData();
|
||||
|
||||
// *********************************************************************
|
||||
// change in this function the IR values to your values
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
if (irmp_get_data(&irmp_data[0]))
|
||||
{
|
||||
// comment this line out, to check the correct code
|
||||
//Serial.println(results.value, HEX);
|
||||
|
||||
// in this switch case you have to change the value 0x...1 to the correct IR code
|
||||
switch (irmp_data[0].command)
|
||||
{
|
||||
case 0x52: LCDML.BT_enter(); break;
|
||||
case 0x50: LCDML.BT_up(); break;
|
||||
case 0x51: LCDML.BT_down(); break;
|
||||
case 0x55: LCDML.BT_left(); break;
|
||||
case 0x56: LCDML.BT_right(); break;
|
||||
case 0x23: LCDML.BT_quit(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (6) CONTROL OVER JOYSTICK ***************************
|
||||
// *********************************************************************
|
||||
#elif(_LCDML_CONTROL_cfg == 6)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
// settings
|
||||
#define _LCDML_CONTROL_analog_pinx A0
|
||||
#define _LCDML_CONTROL_analog_piny A1
|
||||
#define _LCDML_CONTROL_digitalread 33 //don't work with u8glib
|
||||
|
||||
// when you did not use a button set the value to zero
|
||||
#define _LCDML_CONTROL_analog_up_min 612 // Button Up
|
||||
#define _LCDML_CONTROL_analog_up_max 1023
|
||||
#define _LCDML_CONTROL_analog_down_min 0 // Button Down
|
||||
#define _LCDML_CONTROL_analog_down_max 412
|
||||
#define _LCDML_CONTROL_analog_left_min 612 // Button Left
|
||||
#define _LCDML_CONTROL_analog_left_max 1023
|
||||
#define _LCDML_CONTROL_analog_right_min 0 // Button Right
|
||||
#define _LCDML_CONTROL_analog_right_max 412
|
||||
// *********************************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
pinMode (_LCDML_CONTROL_digitalread, INPUT);
|
||||
}
|
||||
// check debounce timer
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset debounce timer
|
||||
|
||||
uint16_t valuex = analogRead(_LCDML_CONTROL_analog_pinx); // analogpinx
|
||||
uint16_t valuey = analogRead(_LCDML_CONTROL_analog_piny); // analogpinx
|
||||
uint16_t valuee = digitalRead(_LCDML_CONTROL_digitalread); //digitalpinenter
|
||||
|
||||
|
||||
if (valuey >= _LCDML_CONTROL_analog_up_min && valuey <= _LCDML_CONTROL_analog_up_max) { LCDML.BT_up(); } // up
|
||||
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML.BT_down(); } // down
|
||||
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML.BT_left(); } // left
|
||||
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML.BT_right(); } // right
|
||||
|
||||
if(valuee == true) {LCDML.BT_enter();} // enter
|
||||
|
||||
// back buttons have to be included as menu item
|
||||
// lock at the example LCDML_back_button
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// *************** (7) CONTROL OVER PCF8574 ****************************
|
||||
// *********************************************************************
|
||||
|
||||
#elif(_LCDML_CONTROL_cfg == 7)
|
||||
unsigned long g_LCDML_DISP_press_time = 0;
|
||||
#define PCF8574_1 0x26 // I2C address for the buttons
|
||||
|
||||
#define PCF8574_Pin0 254
|
||||
#define PCF8574_Pin1 253
|
||||
#define PCF8574_Pin2 251
|
||||
#define PCF8574_Pin3 247
|
||||
#define PCF8574_Pin4 239
|
||||
#define PCF8574_Pin5 223
|
||||
#define PCF8574_Pin6 191
|
||||
#define PCF8574_Pin7 127
|
||||
|
||||
// Specify the PCF8574 pins here
|
||||
#define _LCDML_CONTROL_PCF8574_enable_quit 0
|
||||
#define _LCDML_CONTROL_PCF8574_enable_lr 0
|
||||
|
||||
#define _LCDML_CONTROL_PCF8574_enter PCF8574_Pin0
|
||||
#define _LCDML_CONTROL_PCF8574_up PCF8574_Pin1
|
||||
#define _LCDML_CONTROL_PCF8574_down PCF8574_Pin2
|
||||
#define _LCDML_CONTROL_PCF8574_left PCF8574_Pin3
|
||||
#define _LCDML_CONTROL_PCF8574_right PCF8574_Pin4
|
||||
#define _LCDML_CONTROL_PCF8574_quit PCF8574_Pin5
|
||||
// **********************************************************
|
||||
void lcdml_menu_control(void)
|
||||
{
|
||||
// If something must init, put in in the setup condition
|
||||
if(LCDML.BT_setup()) {
|
||||
// runs only once
|
||||
}
|
||||
|
||||
if((millis() - g_LCDML_DISP_press_time) >= 200) {
|
||||
g_LCDML_DISP_press_time = millis(); // reset press time
|
||||
|
||||
Wire.write(0xff); // All pins as input?
|
||||
Wire.requestFrom(PCF8574_1, 1);
|
||||
if (Wire.available()) {
|
||||
switch (Wire.read())
|
||||
{
|
||||
case _LCDML_CONTROL_PCF8574_enter: LCDML.BT_enter(); break;
|
||||
case _LCDML_CONTROL_PCF8574_up: LCDML.BT_up(); break;
|
||||
case _LCDML_CONTROL_PCF8574_down: LCDML.BT_down(); break;
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_quit == 1)
|
||||
case _LCDML_CONTROL_PCF8574_quit: LCDML.BT_quit(); break;
|
||||
#endif
|
||||
|
||||
#if(_LCDML_CONTROL_PCF8574_enable_lr == 1)
|
||||
case _LCDML_CONTROL_PCF8574_left: LCDML.BT_left(); break;
|
||||
case _LCDML_CONTROL_PCF8574_right: LCDML.BT_right(); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// *********************************************************************
|
||||
// ******************************* END *********************************
|
||||
// *********************************************************************
|
||||
|
||||
|
||||
#else
|
||||
#error _LCDML_CONTROL_cfg is not defined or not in range
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Dynamic content *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
|
||||
uint8_t g_dynParam = 100; // when this value comes from an EEPROM, load it in setup
|
||||
// at the moment here is no setup function (To-Do)
|
||||
void mDyn_para(uint8_t line)
|
||||
// *********************************************************************
|
||||
{
|
||||
// check if this function is active (cursor stands on this line)
|
||||
if (line == LCDML.MENU_getCursorPos())
|
||||
{
|
||||
// make only an action when the cursor stands on this menu item
|
||||
//check Button
|
||||
if(LCDML.BT_checkAny())
|
||||
{
|
||||
if(LCDML.BT_checkEnter())
|
||||
{
|
||||
// this function checks returns the scroll disable status (0 = menu scrolling enabled, 1 = menu scrolling disabled)
|
||||
if(LCDML.MENU_getScrollDisableStatus() == 0)
|
||||
{
|
||||
// disable the menu scroll function to catch the cursor on this point
|
||||
// now it is possible to work with BT_checkUp and BT_checkDown in this function
|
||||
// this function can only be called in a menu, not in a menu function
|
||||
LCDML.MENU_disScroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// enable the normal menu scroll function
|
||||
LCDML.MENU_enScroll();
|
||||
}
|
||||
|
||||
// do something
|
||||
// ...
|
||||
|
||||
LCDML.BT_resetEnter();
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkUp())
|
||||
{
|
||||
g_dynParam++;
|
||||
LCDML.BT_resetUp();
|
||||
}
|
||||
|
||||
// This check have only an effect when MENU_disScroll is set
|
||||
if(LCDML.BT_checkDown())
|
||||
{
|
||||
g_dynParam--;
|
||||
LCDML.BT_resetDown();
|
||||
}
|
||||
|
||||
|
||||
if(LCDML.BT_checkLeft())
|
||||
{
|
||||
g_dynParam++;
|
||||
LCDML.BT_resetLeft();
|
||||
}
|
||||
|
||||
if(LCDML.BT_checkRight())
|
||||
{
|
||||
g_dynParam--;
|
||||
LCDML.BT_resetRight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "dynValue: %d", g_dynParam);
|
||||
|
||||
display.setCursor(1, _LCDML_ADAFRUIT_FONT_H * (line));
|
||||
display.println(buf);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
// =====================================================================
|
||||
//
|
||||
// Output function
|
||||
//
|
||||
// =====================================================================
|
||||
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_clear()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
void lcdml_menu_display()
|
||||
/* ******************************************************************** */
|
||||
{
|
||||
// clear lcd
|
||||
display.fillScreen(_LCDML_ADAFRUIT_BACKGROUND_COLOR);
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp;
|
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll();
|
||||
uint8_t maxi = _LCDML_DISP_rows + i;
|
||||
uint8_t n = 0;
|
||||
|
||||
// init vars
|
||||
uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
|
||||
|
||||
uint8_t scrollbar_min = 0;
|
||||
uint8_t scrollbar_max = LCDML.MENU_getChilds();
|
||||
uint8_t scrollbar_cur_pos = LCDML.MENU_getCursorPosAbs();
|
||||
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
|
||||
|
||||
|
||||
n = 0;
|
||||
i = LCDML.MENU_getScroll();
|
||||
// update content
|
||||
// ***************
|
||||
|
||||
// clear menu
|
||||
// ***************
|
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
|
||||
{
|
||||
// loop to display lines
|
||||
do
|
||||
{
|
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition())
|
||||
{
|
||||
// check the type off a menu element
|
||||
if(tmp->checkType_menu() == true)
|
||||
{
|
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID());
|
||||
display.setCursor(1, _LCDML_ADAFRUIT_FONT_H * (n));
|
||||
display.println(content_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmp->checkType_dynParam()) {
|
||||
tmp->callback(n);
|
||||
}
|
||||
}
|
||||
// increment some values
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
|
||||
}
|
||||
|
||||
// set cursor
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * (LCDML.MENU_getCursorPos()));
|
||||
display.println("X");
|
||||
|
||||
// ***** todo *****
|
||||
#ifdef _SCROLLBAR_TODO_
|
||||
if(_LCDML_DISP_draw_frame == 1) {
|
||||
u8g2.drawFrame(_LCDML_DISP_box_x0, _LCDML_DISP_box_y0, (_LCDML_DISP_box_x1-_LCDML_DISP_box_x0), (_LCDML_DISP_box_y1-_LCDML_DISP_box_y0));
|
||||
}
|
||||
|
||||
|
||||
// display scrollbar when more content as rows available and with > 2
|
||||
|
||||
if (scrollbar_max > n_max && _LCDML_DISP_scrollbar_w > 2)
|
||||
{
|
||||
// set frame for scrollbar
|
||||
//u8g2.drawFrame(_LCDML_DISP_box_x1 - _LCDML_DISP_scrollbar_w, _LCDML_DISP_box_y0, _LCDML_DISP_scrollbar_w, _LCDML_DISP_box_y1-_LCDML_DISP_box_y0);
|
||||
display.drawRect(_LCDML_ADAFRUIT_lcd_w - _LCDML_ADAFRUIT_scrollbar_w, 0,_LCDML_ADAFRUIT_scrollbar_w,_LCDML_ADAFRUIT_lcd_h, _LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
|
||||
// calculate scrollbar length
|
||||
uint8_t scrollbar_block_length = scrollbar_max - n_max;
|
||||
scrollbar_block_length = (_LCDML_DISP_box_y1-_LCDML_DISP_box_y0) / (scrollbar_block_length + _LCDML_DISP_rows);
|
||||
|
||||
//set scrollbar
|
||||
if (scrollbar_cur_pos == 0) { // top position (min)
|
||||
u8g2.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y0 + 1 , (_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
else if (scrollbar_cur_pos == (scrollbar_max-1)) { // bottom position (max)
|
||||
u8g2.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y1 - scrollbar_block_length , (_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
else { // between top and bottom
|
||||
u8g2.drawBox(_LCDML_DISP_box_x1 - (_LCDML_DISP_scrollbar_w-1), _LCDML_DISP_box_y0 + (scrollbar_block_length * scrollbar_cur_pos + 1),(_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -0,0 +1,417 @@
|
||||
/* ===================================================================== *
|
||||
* *
|
||||
* Menu Callback Function *
|
||||
* *
|
||||
* ===================================================================== *
|
||||
*
|
||||
* EXAMPLE CODE:
|
||||
|
||||
// *********************************************************************
|
||||
void your_function_name(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
//LCDML_UNUSED(param);
|
||||
// setup
|
||||
// is called only if it is started
|
||||
|
||||
// starts a trigger event for the loop function every 100 milliseconds
|
||||
LCDML.FUNC_setLoopInterval(100);
|
||||
|
||||
// uncomment this line when the menu should go back to the last called position
|
||||
// this could be a cursor position or the an active menu function
|
||||
// GBA means => go back advanced
|
||||
//LCDML.FUNC_setGBA()
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop
|
||||
// is called when it is triggered
|
||||
// - with LCDML_DISP_triggerMenu( milliseconds )
|
||||
// - with every button or event status change
|
||||
|
||||
// uncomment this line when the screensaver should not be called when this function is running
|
||||
// reset screensaver timer
|
||||
//LCDML.SCREEN_resetTimer();
|
||||
|
||||
// check if any button is pressed (enter, up, down, left, right)
|
||||
if(LCDML.BT_checkAny()) {
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// loop end
|
||||
// you can here reset some global vars or delete it
|
||||
// this function is always called when the functions ends.
|
||||
// this means when you are calling a jumpTo ore a goRoot function
|
||||
// that this part is called before a function is closed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* ===================================================================== *
|
||||
*/
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_information(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// clear lcd
|
||||
display.fillScreen(_LCDML_ADAFRUIT_BACKGROUND_COLOR);
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(F("To close this"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(F("function press"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 2); // line 2
|
||||
display.println(F("any button or use"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 3); // line 3
|
||||
display.println(F("back button"));
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if(LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_func_timer_info = 0; // time counter (global variable)
|
||||
unsigned long g_timer_1 = 0; // timer variable (global variable)
|
||||
void mFunc_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
g_func_timer_info = 20; // reset and set timer
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "wait %d seconds", g_func_timer_info);
|
||||
|
||||
// clear lcd
|
||||
display.fillScreen(_LCDML_ADAFRUIT_BACKGROUND_COLOR);
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(buf);
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(F("or press back button"));
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
|
||||
LCDML.TIMER_msReset(g_timer_1);
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// reset screensaver timer
|
||||
LCDML.SCREEN_resetTimer();
|
||||
|
||||
// this function is called every 100 milliseconds
|
||||
|
||||
// this method checks every 1000 milliseconds if it is called
|
||||
if(LCDML.TIMER_ms(g_timer_1, 1000))
|
||||
{
|
||||
g_timer_1 = millis();
|
||||
g_func_timer_info--; // increment the value every second
|
||||
char buf[20];
|
||||
sprintf (buf, "wait %d seconds", g_func_timer_info);
|
||||
|
||||
// clear lcd
|
||||
display.fillScreen(_LCDML_ADAFRUIT_BACKGROUND_COLOR);
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(buf);
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(F("or press back button"));
|
||||
|
||||
}
|
||||
|
||||
// this function can only be ended when quit button is pressed or the time is over
|
||||
// check if the function ends normally
|
||||
if (g_func_timer_info <= 0)
|
||||
{
|
||||
// leave this function
|
||||
LCDML.FUNC_goBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
uint8_t g_button_value = 0; // button value counter (global variable)
|
||||
void mFunc_p2(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
// print LCD content
|
||||
char buf[17];
|
||||
sprintf (buf, "count: %d of 3", 0);
|
||||
|
||||
// clear lcd
|
||||
display.fillScreen(_LCDML_ADAFRUIT_BACKGROUND_COLOR);
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(F("press a or w button"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(buf);
|
||||
|
||||
// Reset Button Value
|
||||
g_button_value = 0;
|
||||
|
||||
// Disable the screensaver for this function until it is closed
|
||||
LCDML.FUNC_disableScreensaver();
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
if (LCDML.BT_checkLeft() || LCDML.BT_checkUp()) // check if button left is pressed
|
||||
{
|
||||
LCDML.BT_resetLeft(); // reset the left button
|
||||
LCDML.BT_resetUp(); // reset the left button
|
||||
g_button_value++;
|
||||
|
||||
// update LCD content
|
||||
char buf[20];
|
||||
sprintf (buf, "count: %d of 3", g_button_value);
|
||||
|
||||
// clear lcd
|
||||
display.fillScreen(_LCDML_ADAFRUIT_BACKGROUND_COLOR);
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(F("press a or w button"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(buf);
|
||||
}
|
||||
}
|
||||
|
||||
// check if button count is three
|
||||
if (g_button_value >= 3) {
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_screensaver(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// setup function
|
||||
|
||||
// clear lcd
|
||||
display.fillScreen(_LCDML_ADAFRUIT_BACKGROUND_COLOR);
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(F("screensaver"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(F("press any key"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 2); // line 2
|
||||
display.println(F("to leave it"));
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// The screensaver go to the root menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_back(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function and go a layer back
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_goToRootMenu(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_jumpTo_timer_info(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
// remmove compiler warnings when the param variable is not used:
|
||||
LCDML_UNUSED(param);
|
||||
|
||||
// Jump to main screen
|
||||
LCDML.OTHER_jumpToFunc(mFunc_timer_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
void mFunc_para(uint8_t param)
|
||||
// *********************************************************************
|
||||
{
|
||||
if(LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{
|
||||
|
||||
char buf[20];
|
||||
sprintf (buf, "parameter: %d", param);
|
||||
|
||||
// setup function
|
||||
// clear lcd
|
||||
display.fillScreen(_LCDML_ADAFRUIT_BACKGROUND_COLOR);
|
||||
// set text color / Textfarbe setzen
|
||||
display.setTextColor(_LCDML_ADAFRUIT_TEXT_COLOR);
|
||||
// set text size / Textgroesse setzen
|
||||
display.setTextSize(_LCDML_ADAFRUIT_FONT_SIZE);
|
||||
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 0); // line 0
|
||||
display.println(buf);
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 1); // line 1
|
||||
display.println(F("press any key"));
|
||||
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * 2); // line 2
|
||||
display.println(F("to leave it"));
|
||||
|
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{
|
||||
// For example
|
||||
switch(param)
|
||||
{
|
||||
case 10:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// do something
|
||||
break;
|
||||
|
||||
case 30:
|
||||
// do something
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{
|
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
}
|
||||
}
|
||||
|
||||
if(LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{
|
||||
// you can here reset some global vars or do nothing
|
||||
}
|
||||
}
|
||||
BIN
libraries/LCDMenuLib2/extras/img/20x4_1.jpg
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
libraries/LCDMenuLib2/extras/img/20x4_2.jpg
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
libraries/LCDMenuLib2/extras/img/20x4_3.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
libraries/LCDMenuLib2/extras/img/20x4_4.jpg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
libraries/LCDMenuLib2/extras/img/console_1.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
libraries/LCDMenuLib2/extras/img/console_2.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
libraries/LCDMenuLib2/extras/img/console_3.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
libraries/LCDMenuLib2/extras/img/glcd_1.jpg
Normal file
|
After Width: | Height: | Size: 84 KiB |