first commit

This commit is contained in:
Jérôme Delacotte
2025-03-06 11:15:32 +01:00
commit 7b30d6e298
5276 changed files with 2108927 additions and 0 deletions

21
libraries/LCDMenuLib/LICENSE Executable file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) [2017] [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.

74
libraries/LCDMenuLib/README.md Executable file
View File

@@ -0,0 +1,74 @@
Arduino LCDMenuLib with layers for any LCD Type (Row Displays, Graphic Displays, Console output)
=================================================================
Display System:
* max 254 menu elements
* max 254 menu elements per layer
* max 6 layers from root (configurable in LCDMenuLib.h)
* max support for 6 buttons up, down, left, right, back/quit, enter
* min 3 buttons needed up, down, enter
* separation of structural and functional level
* support for initscreen which is shown after x secounds or at begin (configurable)
* scrollbar when more menu elments in a layer then rows
* possibility to jump from one menu elment directly to another
* support for many different lcd librarys
* the menu function are only updated when a button is hit or a trigger is set
* different triggers for display function
* many small function for other things
Backend System
* max 255 backend function
* backend function work with different ms times, not with interrupts
* backend function can be stopped and started
* backend function use three functions setup,loop,stable
* backend function can be grouped, groups can start / stop together
* backend signals use one bit to transfer a status bit between backend functions
Description (german):
http://forum.arduino.cc/index.php?topic=73816.0
Images:
* 20x4
![20x4 display](extras/img/20x4_1.jpg?raw=true "20x4 display")
![20x4 display](extras/img/20x4_2.jpg?raw=true "20x4 display")
![20x4 display](extras/img/20x4_3.jpg?raw=true "20x4 display")
![20x4 display](extras/img/20x4_4.jpg?raw=true "20x4 display")
* glcd with u8glib
![Graphic display](extras/img/glcd_1.jpg?raw=true "Graphic display")
![Graphic display](extras/img/glcd_2.jpg?raw=true "Graphic display")
![Graphic display](extras/img/glcd_3.jpg?raw=true "Graphic display")
![Graphic display](extras/img/glcd_4.jpg?raw=true "Graphic display")
* serial monitor for testing or programming without a connected display
![Serial Monitor](extras/img/console_1.png?raw=true "Serial Monitor")
![Serial Monitor](extras/img/console_2.png?raw=true "Serial Monitor")
![Serial Monitor](extras/img/console_3.png?raw=true "Serial Monitor")
MIT License
Copyright (c) [2018] [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.

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,67 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
// update content
if (LCDML_DISP_update_content() || LCDML_DISP_update_cursor()) {
// clear menu
LCDML_lcd_menu_clear();
Serial.println(F("==========================================="));
Serial.println(F("================ Menu ===================="));
Serial.println(F("==========================================="));
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor char
if (n == LCDML.getCursorPos()) {
Serial.print(F("(x) "));
} else {
Serial.print(F("( ) "));
}
// print content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// Serial.print("special"); // or datetime or other things
// break;
default: // static content
Serial.print(LCDML.content[n]);
break;
}
Serial.println();
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
for(uint8_t i=0;i<15;i++) {
Serial.println();
}
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,169 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_information)
// *********************************************************************
{
// 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"));
}
void LCDML_DISP_loop(LCDML_FUNC_information)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_information)
{
// this functions is ever called when a DISP function is quit
// 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 (globale variable)
void LCDML_DISP_setup(LCDML_FUNC_timer_info)
// *********************************************************************
{
// setup function
Serial.println(F("==========================================="));
Serial.println(F("================ FUNC ===================="));
Serial.println(F("==========================================="));
Serial.println(F("wait 10 secounds or press back button"));
g_func_timer_info = 10; // reset and set timer
LCDML_DISP_triggerMenu(100); // starts a trigger event for the loop function every 100 millisecounds
}
void LCDML_DISP_loop(LCDML_FUNC_timer_info)
{
// 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
// this function is called every 100 millisecounds
// this timer checks every 1000 millisecounds if it is called
if((millis() - g_timer_1) >= 1000) {
g_timer_1 = millis();
g_func_timer_info--; // increment the value every secound
Serial.println(g_func_timer_info); // print the time counter value
}
// reset the initscreen timer
LCDML_DISP_resetIsTimer();
// this function can only be ended when quit button is pressed or the time is over
// check if the function ends normaly
if (g_func_timer_info <= 0)
{
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_timer_info)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
uint8_t g_button_value = 0; // button value counter (global variable)
void LCDML_DISP_setup(LCDML_FUNC_p2)
// *********************************************************************
{
// 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;
}
void LCDML_DISP_loop(LCDML_FUNC_p2)
{
// 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_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right)
{
if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) // check if button left is pressed
{
LCDML_BUTTON_resetLeft(); // reset the left button
LCDML_BUTTON_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) {
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_p2)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,112 @@
// ============================================================
// Example: LCDML_serialmonitor
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// This example shows how the menu works without any LCD.
// The output is print in serial console. This example can be
// extended with network functions to print this menu with telnet
// or other protocols.
// ============================================================
// include libs
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 11
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Change value" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_3 , 2 , "Something" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root , 4 , "Program" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root_4 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_4_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root_4_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_4_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_4_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (11 , _LCDML_G1 , LCDML_root_4 , 2 , "Program 2" , LCDML_FUNC_p2);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 10000000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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 all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,112 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
uint8_t scrollbar_min = 0;
uint8_t scrollbar_max = LCDML.getChilds();
uint8_t scrollbar_cur_pos = LCDML.getCursorPosAbs();
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
// update content
if (LCDML_DISP_update_content()) {
// clear menu
LCDML_lcd_menu_clear();
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
lcd.setCursor(1, n);
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// lcd.print("special"); // or datetime or other things
// break;
default: // static content
lcd.print(LCDML.content[n]);
break;
}
}
}
// update cursor and scrollbar
if (LCDML_DISP_update_cursor()) {
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor
lcd.setCursor(0, n);
//set cursor char
if (n == LCDML.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);
}
}
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
lcd.clear();
lcd.setCursor(0, 0);
}

View File

@@ -0,0 +1,529 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_static)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_static"));
Serial.println(F("==========================="));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_static)
{
Serial.println(F("Loop: LCDML_BACKEND_static"));
// return false = go to first backend function and check time
return false;
// return true = go to next backend function and check time
// return true;
}
void LCDML_BACK_stable(LCDML_BACKEND_static)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_static"));
Serial.println(F("================================="));
}
// *********************************************************************
unsigned long g_dynamic_counter = 1;
void LCDML_BACK_setup(LCDML_BACKEND_dynamic)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_dynamic"));
Serial.println(F("============================"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_dynamic)
{
// runs in loop with different times
Serial.print(F("Loop: LCDML_BACKEND_dynamic - last loop time: "));
Serial.println(LCDML_BACK_dynamic_getLoopTime(LCDML_BACKEND_dynamic));
// set next loop time
g_dynamic_counter++;
// read old loop time and div it through g_dynamic_counter
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_dynamic, (LCDML_BACK_dynamic_setDefaultTime(LCDML_BACKEND_dynamic) / g_dynamic_counter));
if(g_dynamic_counter > 30) {
// reset counter after 8 steps
g_dynamic_counter = 1;
// set loop time to default
LCDML_BACK_dynamic_setDefaultTime(LCDML_BACKEND_dynamic);
}
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_dynamic)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_dynamic"));
Serial.println(F("=================================="));
}
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_ge1)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_ge1"));
Serial.println(F("============================"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_ge1)
{
// runs in loop
Serial.println(F("Loop: LCDML_BACKEND_ge1"));
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_ge1)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_ge1"));
Serial.println(F("=================================="));
}
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_ge2)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_ge2"));
Serial.println(F("============================"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_ge2)
{
// runs in loop
Serial.println(F("Loop: LCDML_BACKEND_ge2"));
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_ge2)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_ge2"));
Serial.println(F("=================================="));
}
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_ge3)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_ge3"));
Serial.println(F("============================"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_ge3)
{
// runs in loop
Serial.println(F("Loop: LCDML_BACKEND_ge3"));
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_ge3)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_ge3"));
Serial.println(F("=================================="));
}
// *********************************************************************
uint8_t g_state_counter = 0;
void LCDML_BACK_setup(LCDML_BACKEND_state_1)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_state_1"));
Serial.println(F("============================"));
Serial.println(F("count until 5"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_state_1)
{
// runs in loop
if(g_state_counter == 5) {
// stopStable this function
LCDML_BACK_stopStable(LCDML_BACKEND_state_1);
// go to next state with restart (runs setup again)
LCDML_BACK_restart(LCDML_BACKEND_state_2);
} else {
// increment
g_state_counter++;
Serial.print(F("Loop: LCDML_BACKEND_state_1 - counter: "));
Serial.println(g_state_counter);
}
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_state_1)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_state_1"));
Serial.println(F("=================================="));
// reset counter
g_state_counter = 0;
}
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_state_2)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_state_2"));
Serial.println(F("============================"));
Serial.println(F("count until 10"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_state_2)
{
// runs in loop
if(g_state_counter == 10) {
// stopStable this function
LCDML_BACK_stopStable(LCDML_BACKEND_state_2);
// go to next state with restart (runs setup again)
LCDML_BACK_restart(LCDML_BACKEND_state_3);
} else {
// increment
g_state_counter++;
Serial.print(F("Loop: LCDML_BACKEND_state_2 - counter: "));
Serial.println(g_state_counter);
}
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_state_2)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_state_2"));
Serial.println(F("=================================="));
// reset counter
g_state_counter = 0;
}
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_state_3)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_state_3"));
Serial.println(F("============================"));
Serial.println(F("count until 2"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_state_3)
{
// runs in loop
if(g_state_counter == 2) {
// stopStable this function
LCDML_BACK_stopStable(LCDML_BACKEND_state_3);
// go to next state with restart (runs setup again)
LCDML_BACK_restart(LCDML_BACKEND_state_4);
} else {
// increment
g_state_counter++;
Serial.print(F("Loop: LCDML_BACKEND_state_3 - counter: "));
Serial.println(g_state_counter);
}
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_state_3)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_state_3"));
Serial.println(F("=================================="));
// reset counter
g_state_counter = 0;
}
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_state_4)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_state_4"));
Serial.println(F("============================"));
Serial.println(F("count until 5 and destroy itself"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_state_4)
{
// runs in loop
if(g_state_counter == 5) {
// stopStable this function
LCDML_BACK_stopStable(LCDML_BACKEND_state_4);
} else {
// increment
g_state_counter++;
Serial.print(F("Loop: LCDML_BACKEND_state_4 - counter: "));
Serial.println(g_state_counter);
}
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_state_4)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_state_4"));
Serial.println(F("=================================="));
// reset counter
g_state_counter = 0;
}
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_event)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_event"));
Serial.println(F("============================"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_event)
{
// runs in loop
Serial.println(F("Loop: LCDML_BACKEND_event - only loop is called and stopped once again"));
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_event)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_event"));
Serial.println(F("=================================="));
}
// *********************************************************************
uint8_t g_ping_pong_counter = 0;
void LCDML_BACK_setup(LCDML_BACKEND_signals_ping)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_signals_ping"));
Serial.println(F("============================"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_signals_ping)
{
// runs in loop
/*
if(LCDML_BACK_signal_get(signal_from_ping_to_ping)) {
if(g_ping_pong_counter >= 10) {
LCDML_BACK_stopStable(LCDML_BACKEND_signals_ping);
LCDML_BACK_stopStable(LCDML_BACKEND_signals_pong);
g_ping_pong_counter = 0;
LCDML_BACK_signal_clear(signal_from_ping_to_ping);
LCDML_BACK_signal_clear(signal_from_ping_to_pong);
}
LCDML_BACK_signal_clear(signal_from_ping_to_ping);
LCDML_BACK_signal_set(signal_from_ping_to_pong);
Serial.println(F("Loop: LCDML_BACKEND_signals_ping - get signal"));
g_ping_pong_counter++;
} else {
Serial.println(F("Loop: LCDML_BACKEND_signals_ping - no signal"));
}
*/
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_signals_ping)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_signals_ping"));
Serial.println(F("=================================="));
}
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_signals_pong)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_signals_pong"));
Serial.println(F("============================"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_signals_pong)
{
// runs in loop
/*
if(LCDML_BACK_signal_get(signal_from_ping_to_pong)) {
LCDML_BACK_signal_clear(signal_from_ping_to_pong);
LCDML_BACK_signal_set(signal_from_ping_to_ping);
Serial.println(F("Loop: LCDML_BACKEND_signals_pong - get signal"));
g_ping_pong_counter++;
} else {
Serial.println(F("Loop: LCDML_BACKEND_signals_pong - no signal"));
}
*/
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_signals_pong)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_signals_pong"));
Serial.println(F("=================================="));
}
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_kill_system_3)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_kill_system_3"));
Serial.println(F("============================"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_kill_system_3)
{
// runs in loop
Serial.println(F("Loop: LCDML_BACKEND_kill_system_3"));
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_kill_system_3)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_kill_system_3"));
Serial.println(F("=================================="));
}
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_kill_system_4)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_kill_system_4"));
Serial.println(F("============================"));
// set loop time to zero
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_kill_system_4, 0);
}
boolean LCDML_BACK_loop(LCDML_BACKEND_kill_system_4)
{
// runs in loop
Serial.println(F("Loop: LCDML_BACKEND_kill_system_4"));
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_kill_system_4)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Setup: LCDML_BACKEND_kill_system_4"));
Serial.println(F("============================"));
}
// *********************************************************************
unsigned long g_real_loop_time_old = millis();
void LCDML_BACK_setup(LCDML_BACKEND_idle)
// *********************************************************************
{
// setup
// is called only if it is started or restartet (reset+start)
Serial.println(F("Setup: LCDML_BACKEND_idle"));
Serial.println(F("============================"));
Serial.println(F("This function is called every 30 secounds"));
Serial.println(F("If this function is not called, the loop time of other threads was set wrong"));
}
boolean LCDML_BACK_loop(LCDML_BACKEND_idle)
{
// runs in loop
Serial.print(F("Loop: LCDML_BACKEND_idle - real loop time: "));
Serial.print((float)((millis() - g_real_loop_time_old)/1000.));
Serial.println(" [s]");
g_real_loop_time_old = millis();
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_idle)
{
// stable stop
// is called when a backend function is stopped with stopStable
Serial.println(F("Stop Stable: LCDML_BACKEND_event"));
Serial.println(F("=================================="));
}

View File

@@ -0,0 +1,264 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_static)
// *********************************************************************
{
// setup
// use parameter on menu init
uint8_t param = LCDML_DISP_getParameter();
switch(param)
{
case 1: // start backend
LCDML_BACK_start(LCDML_BACKEND_static);
break;
case 2: // reset backend
LCDML_BACK_reset(LCDML_BACKEND_static);
break;
case 3: // stop backend
LCDML_BACK_stop(LCDML_BACKEND_static);
break;
case 4: // restart backend
LCDML_BACK_reset(LCDML_BACKEND_static);
break;
case 5: // stop stable
LCDML_BACK_stopStable(LCDML_BACKEND_static);
break;
default:
Serial.println(F("Wrong Parameter: LCDML_FUNC_static"));
break;
}
// quit
LCDML_DISP_funcend();
}
void LCDML_DISP_loop(LCDML_FUNC_static)
{ // loop
}
void LCDML_DISP_loop_end(LCDML_FUNC_static)
{ // loop end
}
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_dynamic)
// *********************************************************************
{
// setup
// use parameter on menu init
uint8_t param = LCDML_DISP_getParameter();
switch(param)
{
case 1: // Start
LCDML_BACK_start(LCDML_BACKEND_dynamic);
break;
case 2: // Stop Stable
LCDML_BACK_stopStable(LCDML_BACKEND_dynamic);
break;
case 3:
Serial.println(F("not implemented -> next beta 4"));
break;
default:
Serial.println(F("Wrong Parameter: LCDML_FUNC_dynamic"));
break;
}
// quit
LCDML_DISP_funcend();
}
void LCDML_DISP_loop(LCDML_FUNC_dynamic)
{ // loop
}
void LCDML_DISP_loop_end(LCDML_FUNC_dynamic)
{ // loop end
}
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_group)
// *********************************************************************
{
// setup
// use parameter on menu init
uint8_t param = LCDML_DISP_getParameter();
switch(param)
{
case 1: // start group
LCDML_BACK_group_start(GROUP_group_example);
break;
case 2: // group stop
LCDML_BACK_group_stop(GROUP_group_example);
break;
default:
Serial.println(F("Wrong Parameter: LCDML_FUNC_group"));
break;
}
// quit
LCDML_DISP_funcend();
}
void LCDML_DISP_loop(LCDML_FUNC_group)
{ // loop
}
void LCDML_DISP_loop_end(LCDML_FUNC_group)
{ // loop end
}
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_state_start)
// *********************************************************************
{
// setup
// start backend function with restart (setup runs again)
LCDML_BACK_restart(LCDML_BACKEND_state_1);
LCDML_DISP_funcend();
}
void LCDML_DISP_loop(LCDML_FUNC_state_start)
{ // loop
}
void LCDML_DISP_loop_end(LCDML_FUNC_state_start)
{ // loop end
}
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_trigger_event)
// *********************************************************************
{
// setup
LCDML_BACK_start(LCDML_BACKEND_event);
LCDML_DISP_funcend();
}
void LCDML_DISP_loop(LCDML_FUNC_trigger_event)
{ // loop
}
void LCDML_DISP_loop_end(LCDML_FUNC_trigger_event)
{ // loop end
}
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_ping_pong)
// *********************************************************************
{
// starts backend functions
/*
LCDML_BACK_signal_set(signal_from_ping_to_ping);
LCDML_BACK_restart(LCDML_BACKEND_signals_ping);
LCDML_BACK_restart(LCDML_BACKEND_signals_pong);
*/
Serial.println(F("LCDML_FUNC_ping_pong: beta 4"));
LCDML_DISP_funcend();
}
void LCDML_DISP_loop(LCDML_FUNC_ping_pong)
{ // loop
}
void LCDML_DISP_loop_end(LCDML_FUNC_ping_pong)
{ // loop end
}
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_kill)
// *********************************************************************
{
// setup
// use parameter on menu init
uint8_t param = LCDML_DISP_getParameter();
switch(param)
{
case 1: // stop all backend function
LCDML_BACK_all_stop();
break;
case 2: // restart all backend function
LCDML_BACK_all_restart();
break;
case 3: // start a function with static time 0
LCDML_BACK_start(LCDML_BACKEND_kill_system_3);
break;
case 4: // start a dynamic function and set loop time to 0
LCDML_BACK_start(LCDML_BACKEND_kill_system_4);
break;
default:
Serial.println(F("Wrong Parameter: LCDML_FUNC_group"));
break;
}
// quit
LCDML_DISP_funcend();
}
void LCDML_DISP_loop(LCDML_FUNC_kill)
{ // loop
}
void LCDML_DISP_loop_end(LCDML_FUNC_kill)
{ // loop end
}

View File

@@ -0,0 +1,213 @@
// ============================================================
// Example: LCDML: serialmonitor
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
//
// ============================================================
// include libs
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// lcd object
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
LiquidCrystal lcd(4,5,6,7,8,9);
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
};
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 26
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add (id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
// LCDMenuLib_addMenu (id, group, prev_layer_element, new_element_num, lang_char_array)
// LCDMenuLib_addParam(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function, parameter [0-255]) // needs LCDML_DISP_initParam
//LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_initParam(_LCDML_DISP_cnt); // enbable parameters (needs one byte per menu element)
// Menu
LCDML_DISP_addMenu (0 , _LCDML_G1 , LCDML_root , 1 , "Backend Basic");
LCDML_DISP_addMenu (1 , _LCDML_G1 , LCDML_root_1 , 1 , "Func (static)");
LCDML_DISP_addParam (2 , _LCDML_G1 , LCDML_root_1_1 , 1 , "Start" , LCDML_FUNC_static, 1);
LCDML_DISP_addParam (3 , _LCDML_G1 , LCDML_root_1_1 , 2 , "Reset" , LCDML_FUNC_static, 2);
LCDML_DISP_addParam (4 , _LCDML_G1 , LCDML_root_1_1 , 3 , "Stop" , LCDML_FUNC_static, 3);
LCDML_DISP_addParam (5 , _LCDML_G1 , LCDML_root_1_1 , 4 , "Restart" , LCDML_FUNC_static, 4);
LCDML_DISP_addParam (6 , _LCDML_G1 , LCDML_root_1_1 , 5 , "Stop stable" , LCDML_FUNC_static, 5);
LCDML_DISP_addMenu (7 , _LCDML_G1 , LCDML_root_1 , 2 , "Func (dynamic)");
LCDML_DISP_addParam (8 , _LCDML_G1 , LCDML_root_1_2 , 1 , "Start" , LCDML_FUNC_dynamic, 1);
LCDML_DISP_addParam (9 , _LCDML_G1 , LCDML_root_1_2 , 2 , "Stop Stable" , LCDML_FUNC_dynamic, 2);
LCDML_DISP_addParam (10 , _LCDML_G1 , LCDML_root_1_2 , 3 , "Set Time" , LCDML_FUNC_dynamic, 3);
LCDML_DISP_addMenu (11 , _LCDML_G1 , LCDML_root , 2 , "Backend Groups");
LCDML_DISP_addParam (12 , _LCDML_G1 , LCDML_root_2 , 1 , "Group start" , LCDML_FUNC_group, 1);
LCDML_DISP_addParam (13 , _LCDML_G1 , LCDML_root_2 , 2 , "Group stop" , LCDML_FUNC_group, 2);
LCDML_DISP_addMenu (14 , _LCDML_G1 , LCDML_root , 3 , "Backend State-M.");
LCDML_DISP_add (15 , _LCDML_G1 , LCDML_root_3 , 1 , "Start" , LCDML_FUNC_state_start);
LCDML_DISP_addMenu (16 , _LCDML_G1 , LCDML_root , 4 , "Backend Event");
LCDML_DISP_add (17 , _LCDML_G1 , LCDML_root_4 , 1 , "Trigger" , LCDML_FUNC_trigger_event);
LCDML_DISP_addMenu (18 , _LCDML_G1 , LCDML_root , 5 , "Backend Signals");
LCDML_DISP_add (19 , _LCDML_G1 , LCDML_root_5 , 1 , "Ping Pong" , LCDML_FUNC_ping_pong);
LCDML_DISP_addMenu (20 , _LCDML_G1 , LCDML_root , 6 , "Destroy System");
LCDML_DISP_addMenu (21 , _LCDML_G1 , LCDML_root_6 , 1 , "restart helps");
LCDML_DISP_addMenu (22 , _LCDML_G1 , LCDML_root_6 , 2 , "Kill");
LCDML_DISP_addParam (23 , _LCDML_G1 , LCDML_root_6_2 , 1 , "stopp all" , LCDML_FUNC_kill, 1);
LCDML_DISP_addParam (24 , _LCDML_G1 , LCDML_root_6_2 , 2 , "restart all" , LCDML_FUNC_kill, 2);
LCDML_DISP_addParam (25 , _LCDML_G1 , LCDML_root_6_2 , 3 , "static init 0", LCDML_FUNC_kill, 3);
LCDML_DISP_addParam (26 , _LCDML_G1 , LCDML_root_6_2 , 4 , "dyn set to 0" , LCDML_FUNC_kill, 4);
// create Menu
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 16 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
// only for example - do not make this in your real program
LCDML_BACK_new_timebased_static (0 , ( 0UL ) , _LCDML_stop , LCDML_BACKEND_kill_system_3);
LCDML_BACK_new_timebased_dynamic (1 , ( 1000UL ) , _LCDML_stop , LCDML_BACKEND_kill_system_4);
// menu function and control function
LCDML_BACK_new_timebased_dynamic (2 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (3 , ( 1000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
// custom backend function
// static time example
LCDML_BACK_new_timebased_static (4 , ( 500UL ) , _LCDML_stop , LCDML_BACKEND_static);
// dynamic time example
LCDML_BACK_new_timebased_dynamic (5 , ( 4000UL ) , _LCDML_stop , LCDML_BACKEND_dynamic);
// groups example
LCDML_BACK_new_timebased_static (6 , ( 1533UL ) , _LCDML_stop , LCDML_BACKEND_ge1);
LCDML_BACK_new_timebased_static (7 , ( 2727UL ) , _LCDML_stop , LCDML_BACKEND_ge2);
LCDML_BACK_new_timebased_static (8 , ( 3918UL ) , _LCDML_stop , LCDML_BACKEND_ge3);
// state maschine
LCDML_BACK_new_timebased_static (9 , ( 500UL ) , _LCDML_stop , LCDML_BACKEND_state_1);
LCDML_BACK_new_timebased_static (10 , ( 500UL ) , _LCDML_stop , LCDML_BACKEND_state_2);
LCDML_BACK_new_timebased_static (11 , ( 500UL ) , _LCDML_stop , LCDML_BACKEND_state_3);
LCDML_BACK_new_timebased_static (12 , ( 500UL ) , _LCDML_stop , LCDML_BACKEND_state_4);
// event
LCDML_BACK_new_eventbased (13 , LCDML_BACKEND_event);
// signals - ping pong
LCDML_BACK_new_timebased_static (14 , ( 2000UL ) , _LCDML_stop , LCDML_BACKEND_signals_ping);
LCDML_BACK_new_timebased_static (15 , ( 500UL ) , _LCDML_stop , LCDML_BACKEND_signals_pong);
// this backend function is only for debug
LCDML_BACK_new_timebased_static (16 , ( 30000UL ) , _LCDML_start , LCDML_BACKEND_idle);
LCDML_BACK_create();
// Groups
// =========
// for group example
LCDML_BACK_group_init(GROUP_group_example, 3)
{
LCDML_BACK_group(LCDML_BACKEND_ge1),
LCDML_BACK_group(LCDML_BACKEND_ge2),
LCDML_BACK_group(LCDML_BACKEND_ge3),
};
// for state mashine
LCDML_BACK_group_init(GROUP_state_mashine, 4)
{
LCDML_BACK_group(LCDML_BACKEND_state_1),
LCDML_BACK_group(LCDML_BACKEND_state_2),
LCDML_BACK_group(LCDML_BACKEND_state_3),
LCDML_BACK_group(LCDML_BACKEND_state_4),
};
// for ping pong example
LCDML_BACK_group_init(GROUP_ping_pong, 2)
{
LCDML_BACK_group(LCDML_BACKEND_signals_ping),
LCDML_BACK_group(LCDML_BACKEND_signals_pong),
};
// Signals
// ========
// here are some signals defined
/* beta 4
LCDML_BACK_signal_init(2);
LCDML_BACK_signal(0, signal_from_ping_to_pong);
LCDML_BACK_signal(1, signal_from_pong_to_ping);
*/
// *********************************************************************
// 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]);
// Enable all items with _LCDML_G1 and _LCDML_G2
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,112 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
uint8_t scrollbar_min = 0;
uint8_t scrollbar_max = LCDML.getChilds();
uint8_t scrollbar_cur_pos = LCDML.getCursorPosAbs();
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
// update content
if (LCDML_DISP_update_content()) {
// clear menu
LCDML_lcd_menu_clear();
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
lcd.setCursor(1, n);
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// lcd.print("special"); // or datetime or other things
// break;
default: // static content
lcd.print(LCDML.content[n]);
break;
}
}
}
// update cursor and scrollbar
if (LCDML_DISP_update_cursor()) {
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor
lcd.setCursor(0, n);
//set cursor char
if (n == LCDML.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);
}
}
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
lcd.clear();
lcd.setCursor(0, 0);
}

View File

@@ -0,0 +1,36 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,191 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_back)
// *********************************************************************
{
// setup
// is called only if it is started
}
void LCDML_DISP_loop(LCDML_FUNC_back)
{
// loop
// is called when it is triggert
LCDML_DISP_resetIsTimer(); // reset the initscreen timer
LCDML.goBack(); // go back
LCDML_DISP_funcend(); // LCDML_DISP_funcend calls the loop_end function
}
void LCDML_DISP_loop_end(LCDML_FUNC_back)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_information)
// *********************************************************************
{
// setup function
lcd.setCursor(0, 0);
lcd.print(F("Um Funktion zu"));
lcd.setCursor(0, 1);
lcd.print(F("schliessen eine"));
lcd.setCursor(0, 2);
lcd.print(F("Taste druecken oder"));
lcd.setCursor(0, 3);
lcd.print(F("Back Taste verwenden"));
}
void LCDML_DISP_loop(LCDML_FUNC_information)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_information)
{
// this functions is ever called when a DISP function is quit
// 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 (globale variable)
void LCDML_DISP_setup(LCDML_FUNC_timer_info)
// *********************************************************************
{
// setup function
lcd.print(F("x sec warten")); // print some content on first row
g_func_timer_info = 10; // reset and set timer
LCDML_DISP_triggerMenu(100); // starts a trigger event for the loop function every 100 millisecounds
}
void LCDML_DISP_loop(LCDML_FUNC_timer_info)
{
// 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
// this function is called every 100 millisecounds
// this timer checks every 1000 millisecounds if it is called
if((millis() - g_timer_1) >= 1000) {
g_timer_1 = millis();
g_func_timer_info--; // increment the value every secound
lcd.setCursor(0, 0); // set cursor pos
lcd.print(g_func_timer_info); // print the time counter value
}
// reset the initscreen timer
LCDML_DISP_resetIsTimer();
// this function can only be ended when quit button is pressed or the time is over
// check if the function ends normaly
if (g_func_timer_info <= 0)
{
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_timer_info)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
uint8_t g_button_value = 0; // button value counter (global variable)
void LCDML_DISP_setup(LCDML_FUNC_p2)
// *********************************************************************
{
// setup function
// 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;
}
void LCDML_DISP_loop(LCDML_FUNC_p2)
{
// 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_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right)
{
if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) // check if button left is pressed
{
LCDML_BUTTON_resetLeft(); // reset the left button
LCDML_BUTTON_resetUp(); // reset the left button
g_button_value++;
// 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) {
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_p2)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,143 @@
// ============================================================
// Example: LCDML: back_button as menuitem
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// This example shows how the menu works without any LCD.
// The output is print in serial console. This example can be
// extended with network functions to print this menu with telnet
// or other protocols.
// ============================================================
// include libs
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// lcd object
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
LiquidCrystal lcd(4,5,6,7,8,9);
#if (_LCDML_DISP_cfg_scrollbar == 1)
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
};
#endif
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 12
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Back" , LCDML_FUNC_back);
LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_3 , 2 , "Change value" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root_3 , 3 , "Something" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root , 4 , "Program" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_4 , 1 , "Back" , LCDML_FUNC_back);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root_4 , 2 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_4_2 , 1 , "Back" , LCDML_FUNC_back);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_4_2 , 2 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (11 , _LCDML_G1 , LCDML_root_4_2 , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (12 , _LCDML_G1 , LCDML_root_4_2_3 , 1 , "Back" , LCDML_FUNC_back);
LCDML_DISP_add (13 , _LCDML_G1 , LCDML_root_4_2_3 , 2 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (14 , _LCDML_G1 , LCDML_root_4_2_3 , 3 , "Long" , LCDML_FUNC);
LCDML_DISP_add (15 , _LCDML_G1 , LCDML_root_4 , 3 , "Program 2" , LCDML_FUNC_p2);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 10000000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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]);
// Enable all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,113 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
uint8_t scrollbar_min = 0;
uint8_t scrollbar_max = LCDML.getChilds();
uint8_t scrollbar_cur_pos = LCDML.getCursorPosAbs();
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
// update content
if (LCDML_DISP_update_content()) {
// clear menu
LCDML_lcd_menu_clear();
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
lcd.setCursor(1, n);
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
case 0:
lcd.print("Sec counter: "); // or datetime or other things
lcd.print(g_sec_counter);
break;
default: // static content
lcd.print(LCDML.content[n]);
break;
}
}
}
// update cursor and scrollbar
if (LCDML_DISP_update_cursor()) {
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor
lcd.setCursor(0, n);
//set cursor char
if (n == LCDML.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);
}
}
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
lcd.clear();
lcd.setCursor(0, 0);
}

View File

@@ -0,0 +1,60 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/
/* ******************************************************************** */
void LCDML_BACK_setup(LCDML_BACKEND_sec_counter)
/* ******************************************************************** */
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_sec_counter)
{
// runs in loop
g_sec_counter++;
// Update menu if no function is running (the check is in LCDML_DISP_update_menu_direct())
// the update function check if the parameter id is realy displayed on the screen only then
// the display is realy updated.
LCDML_DISP_update_menu_direct(0);
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_sec_counter)
{
// stable stop
// is called when a backend function is stopped with stopStable
}

View File

@@ -0,0 +1,166 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_information)
// *********************************************************************
{
// setup function
lcd.setCursor(0, 0);
lcd.print(F("Um Funktion zu"));
lcd.setCursor(0, 1);
lcd.print(F("schliessen eine"));
lcd.setCursor(0, 2);
lcd.print(F("Taste druecken oder"));
lcd.setCursor(0, 3);
lcd.print(F("Back Taste verwenden"));
}
void LCDML_DISP_loop(LCDML_FUNC_information)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_information)
{
// this functions is ever called when a DISP function is quit
// 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 (globale variable)
void LCDML_DISP_setup(LCDML_FUNC_timer_info)
// *********************************************************************
{
// setup function
lcd.print(F("x sec warten")); // print some content on first row
g_func_timer_info = 10; // reset and set timer
LCDML_DISP_triggerMenu(100); // starts a trigger event for the loop function every 100 millisecounds
}
void LCDML_DISP_loop(LCDML_FUNC_timer_info)
{
// 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
// this function is called every 100 millisecounds
// this timer checks every 1000 millisecounds if it is called
if((millis() - g_timer_1) >= 1000) {
g_timer_1 = millis();
g_func_timer_info--; // increment the value every secound
lcd.setCursor(0, 0); // set cursor pos
lcd.print(g_func_timer_info); // print the time counter value
}
// reset the initscreen timer
LCDML_DISP_resetIsTimer();
// this function can only be ended when quit button is pressed or the time is over
// check if the function ends normaly
if (g_func_timer_info <= 0)
{
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_timer_info)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
uint8_t g_button_value = 0; // button value counter (global variable)
void LCDML_DISP_setup(LCDML_FUNC_p2)
// *********************************************************************
{
// setup function
// 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;
}
void LCDML_DISP_loop(LCDML_FUNC_p2)
{
// 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_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right)
{
if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) // check if button left is pressed
{
LCDML_BUTTON_resetLeft(); // reset the left button
LCDML_BUTTON_resetUp(); // reset the left button
g_button_value++;
// 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) {
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_p2)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,142 @@
// ============================================================
// Example: LCDML: change menuitem text on runtime
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// This examples thows how the static menu text can be dynamical
// update. For example for a clock as text.
// In this Tab is a backend function added. In this function is
// the refresh call for the menu. In the FUNC_DISP tab is the
// content switch for the menu.
// ============================================================
// include libs
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// lcd object
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
LiquidCrystal lcd(4,5,6,7,8,9);
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
};
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 12
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Change value" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_3 , 2 , "Something" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root , 4 , "Program" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root_4 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_4_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root_4_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_4_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_4_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (11 , _LCDML_G1 , LCDML_root_4 , 2 , "Program 2" , LCDML_FUNC_p2);
LCDML_DISP_add (12 , _LCDML_G1 , LCDML_root , 5 , "Settings" , LCDML_FUNC);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 2 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 1000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_new_timebased_dynamic (2 , ( 1000UL ) , _LCDML_start , LCDML_BACKEND_sec_counter);
LCDML_BACK_create();
// *********************************************************************
// INIT SOME GLOBAL VARS
// *********************************************************************
unsigned int g_sec_counter = 0;
// *********************************************************************
// 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]);
// Enable all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,112 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
uint8_t scrollbar_min = 0;
uint8_t scrollbar_max = LCDML.getChilds();
uint8_t scrollbar_cur_pos = LCDML.getCursorPosAbs();
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
// update content
if (LCDML_DISP_update_content()) {
// clear menu
LCDML_lcd_menu_clear();
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
lcd.setCursor(1, n);
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// lcd.print("special"); // or datetime or other things
// break;
default: // static content
lcd.print(LCDML.content[n]);
break;
}
}
}
// update cursor and scrollbar
if (LCDML_DISP_update_cursor()) {
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor
lcd.setCursor(0, n);
//set cursor char
if (n == LCDML.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);
}
}
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
lcd.clear();
lcd.setCursor(0, 0);
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,221 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// 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];
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_dyn_filelist)
// *********************************************************************
{
// 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++;
}
}
}
void LCDML_DISP_loop(LCDML_FUNC_dyn_filelist)
{
// 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);
// clear display
// ================
lcd.clear();
// display content
// ==================
for (uint8_t n = scroll_row; n < (scroll_row+_LCDML_DISP_rows); n++)
{
// set cursor
lcd.setCursor(1, n-scroll_row);
// set content
lcd.print(filelist[n]);
}
// set cursor and scrollbar
// =============================
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);
}
}
}
// control
// =====================================
// move up in list
if(LCDML_BUTTON_checkUp()) {
LCDML_BUTTON_resetAll();
// 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
}
}
// update content above or remove this line and copy button checks on top of this function
LCDML_BACK_start(LCDML_BACKEND_menu);
}
// move down in list
if(LCDML_BUTTON_checkDown()) {
LCDML_BUTTON_resetAll();
// 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
}
}
// update content above or remove this line and copy button checks on top of this function
LCDML_BACK_start(LCDML_BACKEND_menu);
}
// enter file name
if(LCDML_BUTTON_checkEnter()) {
LCDML_BUTTON_resetAll();
// save selected file (serial.print)
LCDML_DISP_funcend();
// output of current line
Serial.println(filelist[cursor_position_cur]);
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_dyn_filelist)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
// Display selected file name
}

View File

@@ -0,0 +1,122 @@
// ============================================================
// Example: LCDML: dynamic menu list
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// This example shows you, how to generate a dynamic menu list
//
// ============================================================
// include libs
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// lcd object
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
LiquidCrystal lcd(4,5,6,7,8,9);
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
};
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 0
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Dyn Filelist" , LCDML_FUNC_dyn_filelist);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 100000000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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]);
// Enable all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,112 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
uint8_t scrollbar_min = 0;
uint8_t scrollbar_max = LCDML.getChilds();
uint8_t scrollbar_cur_pos = LCDML.getCursorPosAbs();
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
// update content
if (LCDML_DISP_update_content()) {
// clear menu
LCDML_lcd_menu_clear();
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
lcd.setCursor(1, n);
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// lcd.print("special"); // or datetime or other things
// break;
default: // static content
lcd.print(LCDML.content[n]);
break;
}
}
}
// update cursor and scrollbar
if (LCDML_DISP_update_cursor()) {
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor
lcd.setCursor(0, n);
//set cursor char
if (n == LCDML.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);
}
}
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
lcd.clear();
lcd.setCursor(0, 0);
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,91 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_program_enable)
// *********************************************************************
{
// setup function
LCDML_DISP_groupDisable(_LCDML_G2); // enable group 2
LCDML_DISP_groupEnable(_LCDML_G3); // enable group 2
LCDML.goRoot(); // go to root element (first element of this menu with id=0)
}
void LCDML_DISP_loop(LCDML_FUNC_program_enable)
{
// 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
}
void LCDML_DISP_loop_end(LCDML_FUNC_program_enable)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_program_disable)
// *********************************************************************
{
// setup function
LCDML_DISP_groupDisable(_LCDML_G3); // enable group 2
LCDML_DISP_groupEnable(_LCDML_G2); // enable group 2
LCDML.goRoot(); // go to root element (first element of this menu with id=0)
}
void LCDML_DISP_loop(LCDML_FUNC_program_disable)
{
// 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
}
void LCDML_DISP_loop_end(LCDML_FUNC_program_disable)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,134 @@
// ============================================================
// Example: LCDML: hidden menu elements
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// In this example menu elements are in different groups.
// Groups can be enabled (displayed) and disabled (not displayed).
// You can change under "Settings" the status from "Program" Menu.
// ============================================================
// include libs
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// lcd object
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
LiquidCrystal lcd(4,5,6,7,8,9);
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
};
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 9
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (1 , _LCDML_G2 , LCDML_root_1 , 1 , "En Program" , LCDML_FUNC_program_enable);
LCDML_DISP_add (2 , _LCDML_G3 , LCDML_root_1 , 2 , "Dis Program" , LCDML_FUNC_program_disable);
LCDML_DISP_add (3 , _LCDML_G3 , LCDML_root , 2 , "Program" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G3 , LCDML_root_2 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G3 , LCDML_root_2_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G3 , LCDML_root_2_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G3 , LCDML_root_2_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G3 , LCDML_root_2_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G3 , LCDML_root_2 , 2 , "Program 2" , LCDML_FUNC);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 1000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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]);
// Enable all items with _LCDML_G1 and _LCDML_G2
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
LCDML_DISP_groupEnable(_LCDML_G2); // enable group 2
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,112 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
uint8_t scrollbar_min = 0;
uint8_t scrollbar_max = LCDML.getChilds();
uint8_t scrollbar_cur_pos = LCDML.getCursorPosAbs();
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
// update content
if (LCDML_DISP_update_content()) {
// clear menu
LCDML_lcd_menu_clear();
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
lcd.setCursor(1, n);
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// lcd.print("special"); // or datetime or other things
// break;
default: // static content
lcd.print(LCDML.content[n]);
break;
}
}
}
// update cursor and scrollbar
if (LCDML_DISP_update_cursor()) {
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor
lcd.setCursor(0, n);
//set cursor char
if (n == LCDML.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);
}
}
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
lcd.clear();
lcd.setCursor(0, 0);
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,203 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_information)
// *********************************************************************
{
// setup function
lcd.setCursor(0, 0);
lcd.print(F("Um Funktion zu"));
lcd.setCursor(0, 1);
lcd.print(F("schliessen eine"));
lcd.setCursor(0, 2);
lcd.print(F("Taste druecken oder"));
lcd.setCursor(0, 3);
lcd.print(F("Back Taste verwenden"));
}
void LCDML_DISP_loop(LCDML_FUNC_information)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_information)
{
// this functions is ever called when a DISP function is quit
// 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 (globale variable)
void LCDML_DISP_setup(LCDML_FUNC_timer_info)
// *********************************************************************
{
// setup function
lcd.print(F("x sec warten")); // print some content on first row
g_func_timer_info = 10; // reset and set timer
LCDML_DISP_triggerMenu(100); // starts a trigger event for the loop function every 100 millisecounds
}
void LCDML_DISP_loop(LCDML_FUNC_timer_info)
{
// 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
// this function is called every 100 millisecounds
// this timer checks every 1000 millisecounds if it is called
if((millis() - g_timer_1) >= 1000) {
g_timer_1 = millis();
g_func_timer_info--; // increment the value every secound
lcd.setCursor(0, 0); // set cursor pos
lcd.print(g_func_timer_info); // print the time counter value
}
// reset the initscreen timer
LCDML_DISP_resetIsTimer();
// this function can only be ended when quit button is pressed or the time is over
// check if the function ends normaly
if (g_func_timer_info <= 0)
{
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_timer_info)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
uint8_t g_button_value = 0; // button value counter (global variable)
void LCDML_DISP_setup(LCDML_FUNC_p2)
// *********************************************************************
{
// setup function
// 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;
}
void LCDML_DISP_loop(LCDML_FUNC_p2)
{
// 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_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right)
{
if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) // check if button left is pressed
{
LCDML_BUTTON_resetLeft(); // reset the left button
LCDML_BUTTON_resetUp(); // reset the left button
g_button_value++;
// 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) {
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_p2)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
unsigned long g_initscreen_example_counter = 0;
void LCDML_DISP_setup(LCDML_FUNC_initscreen)
// *********************************************************************
{
// setup function
LCDML_DISP_triggerMenu(1000); // set trigger for this function to 1000 millisecounds
lcd.print(F("InitScreen")); // print first line to lcd display
g_initscreen_example_counter = 0; // reset or set example counter
}
void LCDML_DISP_loop(LCDML_FUNC_initscreen)
{
// 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
g_initscreen_example_counter++; // count the example counter above
lcd.setCursor(0,1); // clear the secound line on lcd
lcd.print(F(" "));
lcd.setCursor(0,1); // print new value to lcd
lcd.print(g_initscreen_example_counter);
g_lcdml_initscreen = millis(); // reset initscreen timer
if(LCDML_BUTTON_checkAny()) { // check if any button is pressed to left this function
LCDML_DISP_funcend(); // function end
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_initscreen)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
LCDML.goRoot(); // go to root element (first element of this menu with id=0)
}

View File

@@ -0,0 +1,145 @@
// ============================================================
// Example: LCDML: initscreen
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// This example shows you how the initscreen or standbyscreen
// works. The initscreen is a hidden menu element (example 004)
// witch it is not displayed in menu. The initscreen is called
// when no action or trigger is set after ...cfg_initscreen_time
// milliseconds. When a other menu function is active, this function
// is stoped stable before initscreen function is started.
// ============================================================
// include libs
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
#define _LCDML_DISP_cfg_initscreen_time 10000 // enable initscreen time
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// lcd object
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
LiquidCrystal lcd(4,5,6,7,8,9);
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
};
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 12
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Change value" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_3 , 2 , "Something" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root , 4 , "Program" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root_4 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_4_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root_4_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_4_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_4_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (11 , _LCDML_G1 , LCDML_root_4 , 2 , "Program 2" , LCDML_FUNC_p2);
LCDML_DISP_add (12 , _LCDML_G7 , LCDML_root , 5 , "Program 2" , LCDML_FUNC_initscreen); // in g7 => hidden
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 1000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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]);
// Enable all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// example for init screen
if((millis() - g_lcdml_initscreen) >= _LCDML_DISP_cfg_initscreen_time) {
g_lcdml_initscreen = millis(); // reset init screen time
LCDML_DISP_jumpToFunc(LCDML_FUNC_initscreen); // jump to initscreen
}
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,67 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
// update content
if (LCDML_DISP_update_content() || LCDML_DISP_update_cursor()) {
// clear menu
LCDML_lcd_menu_clear();
Serial.println(F("==========================================="));
Serial.println(F("================ Menu ===================="));
Serial.println(F("==========================================="));
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor char
if (n == LCDML.getCursorPos()) {
Serial.print(F("(x) "));
} else {
Serial.print(F("( ) "));
}
// print content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// Serial.print("special"); // or datetime or other things
// break;
default: // static content
Serial.print(LCDML.content[n]);
break;
}
Serial.println();
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
for(uint8_t i=0;i<15;i++) {
Serial.println();
}
}

View File

@@ -0,0 +1,112 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/
/* ===================================================================== */
void LCDML_BACK_setup(LCDML_BACKEND_stepper)
/* ===================================================================== */
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_stepper)
{
// runs in loop
// Loop for stepper 1
// ============================================
// check if backend task for stepper 1 is running
switch(g_stepper_1_mode) {
case 'r': // speed
stepper1.runSpeed();
break;
case 'p': // position
if (stepper1.distanceToGo() > 0) {
stepper1.run();
}
break;
case 's': // stop direct and hold
stepper1.stop();
break;
default: // do nothing
break;
}
// Loop for stepper 2
// ============================================
// check if backend task for stepper 1 is running
switch(g_stepper_2_mode) {
case 'r': // speed
stepper2.runSpeed();
break;
case 'p': // position
if (stepper2.distanceToGo() > 0) {
stepper2.run();
}
break;
case 's': // stop direct and hold
stepper2.stop();
break;
default: // do nothing
break;
}
return true; // this value have to be true because the menu is otherwise blocked
}
void LCDML_BACK_stable(LCDML_BACKEND_stepper)
{
// stable stop
// is called when a backend function is stopped with stopStable
}

View File

@@ -0,0 +1,129 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
/* ===================================================================== */
void LCDML_DISP_setup(LCDML_FUNC_stepper_on)
/* ===================================================================== */
{
// setup
uint8_t param = LCDML_DISP_getParameter();
switch(param)
{
case 1: // stepper 1 on
LCDML_DISP_groupDisable(_LCDML_G2);
LCDML_DISP_groupEnable(_LCDML_G3);
stepper1.setMaxSpeed(850);
stepper1.setSpeed(-850);
g_stepper_1_mode = 'r';
break;
case 2: // stepper 2 on
LCDML_DISP_groupDisable(_LCDML_G4);
LCDML_DISP_groupEnable(_LCDML_G5);
stepper2.setMaxSpeed(850);
stepper2.setSpeed(850);
g_stepper_2_mode = 'r';
break;
default:
break;
}
}
void LCDML_DISP_loop(LCDML_FUNC_stepper_on)
{
// end function direct
LCDML_DISP_funcend();
}
void LCDML_DISP_loop_end(LCDML_FUNC_stepper_on)
{
// loop end
// this functions is ever called when a DISP function is quit
}
/* ===================================================================== */
void LCDML_DISP_setup(LCDML_FUNC_stepper_off)
/* ===================================================================== */
{
// setup
uint8_t param = LCDML_DISP_getParameter();
switch(param)
{
case 1: // stepper 1 off
LCDML_DISP_groupEnable(_LCDML_G2);
LCDML_DISP_groupDisable(_LCDML_G3);
g_stepper_1_mode = 0;
break;
case 2: // stepper 2 off
LCDML_DISP_groupEnable(_LCDML_G4);
LCDML_DISP_groupDisable(_LCDML_G5);
g_stepper_2_mode = 0;
break;
default:
break;
}
}
void LCDML_DISP_loop(LCDML_FUNC_stepper_off)
{
// end function direct
LCDML_DISP_funcend();
}
void LCDML_DISP_loop_end(LCDML_FUNC_stepper_off)
{
// loop end
// this functions is ever called when a DISP function is quit
}

View File

@@ -0,0 +1,122 @@
// ============================================================
// Example: LCDML_serialmonitor with stepper
// ============================================================
// Autor: Nils Feldkämper
// Last update: 12.01.2017
// License: MIT
// ============================================================
// Descripton:
// This examples works with a serial menu (baudrate 250000)
// The content is a stepper control for two steppers with
// hidden menu elements and parametern
// ============================================================
// include libs
#include <LCDMenuLib.h>
#include <AccelStepper.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// *********************************************************************
// Stepper Objects and global variables
// *********************************************************************
AccelStepper stepper1; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
AccelStepper stepper2(AccelStepper::FULL4WIRE, 6, 7, 8, 9);
char g_stepper_1_mode = 0;
char g_stepper_2_mode = 0;
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 10
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_initParam(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Stepper" , LCDML_FUNC);
LCDML_DISP_addParam (1 , _LCDML_G2 , LCDML_root_1 , 1 , "Stepper 1 on" , LCDML_FUNC_stepper_on , 1);
LCDML_DISP_addParam (2 , _LCDML_G3 , LCDML_root_1 , 2 , "Stepper 1 off" , LCDML_FUNC_stepper_off , 1);
LCDML_DISP_addParam (3 , _LCDML_G4 , LCDML_root_1 , 3 , "Stepper 2 on" , LCDML_FUNC_stepper_on , 2);
LCDML_DISP_addParam (4 , _LCDML_G5 , LCDML_root_1 , 4 , "Stepper 2 off" , LCDML_FUNC_stepper_off , 2);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root , 2 , "Stepper 1 Mode" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root_2 , 1 , "Only speed" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_2 , 2 , "Position" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root , 3 , "Stepper 2 Mode" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_3 , 1 , "Only speed" , LCDML_FUNC);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_3 , 2 , "Position" , LCDML_FUNC);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 2 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_static (0 , ( 0UL ) , _LCDML_start , LCDML_BACKEND_stepper); // set here the time to null and use in backend loop the return value with true
LCDML_BACK_new_timebased_dynamic (1 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (2 , ( 10000000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// SETUP
// *********************************************************************
void setup()
{
// serial init; only be needed if serial control is used
Serial.begin(250000); // start serial
Serial.println(F(_LCDML_VERSION)); // only for examples
// Enable all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
LCDML_DISP_groupEnable(_LCDML_G2); // stepper 1 off on startup
LCDML_DISP_groupEnable(_LCDML_G4); // stepper 2 off on startup
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,112 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
uint8_t scrollbar_min = 0;
uint8_t scrollbar_max = LCDML.getChilds();
uint8_t scrollbar_cur_pos = LCDML.getCursorPosAbs();
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
// update content
if (LCDML_DISP_update_content()) {
// clear menu
LCDML_lcd_menu_clear();
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
lcd.setCursor(1, n);
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// lcd.print("special"); // or datetime or other things
// break;
default: // static content
lcd.print(LCDML.content[n]);
break;
}
}
}
// update cursor and scrollbar
if (LCDML_DISP_update_cursor()) {
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor
lcd.setCursor(0, n);
//set cursor char
if (n == LCDML.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);
}
}
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
lcd.clear();
lcd.setCursor(0, 0);
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,85 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_program_change)
// *********************************************************************
{
// setup function
// use parameter on menu init
uint8_t param = LCDML_DISP_getParameter();
switch(param)
{
case 0: // enable program
LCDML_DISP_groupDisable(_LCDML_G2); // disable group 2
LCDML_DISP_groupEnable(_LCDML_G3); // enable group 3
break;
case 1:
LCDML_DISP_groupEnable(_LCDML_G2); // enable group 2
LCDML_DISP_groupDisable(_LCDML_G3); // disable group 3
break;
default:
//get parameter errors
break;
}
LCDML.goRoot(); // go to root element (first element of this menu with id=0)
}
void LCDML_DISP_loop(LCDML_FUNC_program_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
}
void LCDML_DISP_loop_end(LCDML_FUNC_program_change)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,133 @@
// ============================================================
// Example: LCDML: use menuitems with parameters
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// same function with different parameters
// ============================================================
// include libs
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// lcd object
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
LiquidCrystal lcd(4,5,6,7,8,9);
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
};
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 9
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
//LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_initParam(_LCDML_DISP_cnt); // enbable parameters (needs one byte per menu element)
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Settings" , LCDML_FUNC);
LCDML_DISP_addParam (1 , _LCDML_G2 , LCDML_root_1 , 1 , "En Program" , LCDML_FUNC_program_change, 0);
LCDML_DISP_addParam (2 , _LCDML_G3 , LCDML_root_1 , 2 , "Dis Program" , LCDML_FUNC_program_change, 1);
LCDML_DISP_add (3 , _LCDML_G3 , LCDML_root , 2 , "Program" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G3 , LCDML_root_2 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G3 , LCDML_root_2_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G3 , LCDML_root_2_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G3 , LCDML_root_2_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G3 , LCDML_root_2_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G3 , LCDML_root_2 , 2 , "Program 2" , LCDML_FUNC);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 1000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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]);
// Enable all items with _LCDML_G1 and _LCDML_G2
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
LCDML_DISP_groupEnable(_LCDML_G2); // enable group 2
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,88 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// clear lcd
display.clearDisplay();
// set text color / Textfarbe setzen
display.setTextColor(_LCDML_ADAFRUITE_TEXT_COLOR);
// set text size / Textgroesse setzen
display.setTextSize(_LCDML_ADAFRUITE_FONT_SIZE);
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_ADAFRUITE_rows) ? ((_LCDML_ADAFRUITE_rows > _LCDML_ADAFRUITE_rows_max) ? _LCDML_ADAFRUITE_rows : _LCDML_ADAFRUITE_rows_max) : (LCDML.getChilds());
// display rows and cursor
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
if (n == LCDML.getCursorPos()) {
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * (n));
display.println("X");
}
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0: // dynamic content
// display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * (n));
// display.println("var_datetime");
// break;
default: // static content
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * (n));
display.println(LCDML.content[n]);
break;
}
}
// display scrollbar when more content as rows available
if (LCDML.getChilds() > n_max) {
// set frame for scrollbar
display.drawRect(_LCDML_ADAFRUITE_lcd_w - _LCDML_ADAFRUITE_scrollbar_w, 0,_LCDML_ADAFRUITE_scrollbar_w,_LCDML_ADAFRUITE_lcd_h, _LCDML_ADAFRUITE_TEXT_COLOR);
// calculate scrollbar length
uint8_t scrollbar_block_length = LCDML.getChilds() - n_max;
scrollbar_block_length = _LCDML_ADAFRUITE_lcd_h / (scrollbar_block_length + _LCDML_DISP_rows);
//set scrollbar
// hier muss du mal schauen wie du blöcke einfügen kannst, bei der u8glib geht das wie unten angezeigt, bei deiner lib weis ich das nicht
if (LCDML.getCursorPosAbs() == 0) { // top position (min)
//u8g.drawBox(_LCDML_ADAFRUITE_lcd_w - (_LCDML_ADAFRUITE_scrollbar_w-1), 1 , (_LCDML_ADAFRUITE_scrollbar_w-2) , scrollbar_block_length);
}
else if (LCDML.getCursorPosAbs() == (LCDML.getChilds())) { // bottom position (max)
//u8g.drawBox(_LCDML_ADAFRUITE_lcd_w - (_LCDML_ADAFRUITE_scrollbar_w-1), _LCDML_ADAFRUITE_lcd_h - scrollbar_block_length , (_LCDML_ADAFRUITE_scrollbar_w-2) , scrollbar_block_length);
}
else { // between top and bottom
//u8g.drawBox(_LCDML_ADAFRUITE_lcd_w - (_LCDML_ADAFRUITE_scrollbar_w-1), (scrollbar_block_length * LCDML.getCursorPosAbs() + 1),(_LCDML_ADAFRUITE_scrollbar_w-2) , scrollbar_block_length);
}
}
}
display.display();
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,226 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_information)
// *********************************************************************
{
// setup function
// clear lcd
display.clearDisplay();
// set text color / Textfarbe setzen
display.setTextColor(_LCDML_ADAFRUITE_TEXT_COLOR);
// set text size / Textgroesse setzen
display.setTextSize(_LCDML_ADAFRUITE_FONT_SIZE);
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 0); // line 0
display.println(F("To close this"));
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 1); // line 1
display.println(F("function press"));
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 2); // line 2
display.println(F("any button or use"));
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 3); // line 3
display.println(F("back button"));
display.display();
}
void LCDML_DISP_loop(LCDML_FUNC_information)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_information)
{
// this functions is ever called when a DISP function is quit
// 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 (globale variable)
void LCDML_DISP_setup(LCDML_FUNC_timer_info)
// *********************************************************************
{
// setup function
char buf[20];
sprintf (buf, "wait %d secounds", 10);
// clear lcd
display.clearDisplay();
// set text color / Textfarbe setzen
display.setTextColor(_LCDML_ADAFRUITE_TEXT_COLOR);
// set text size / Textgroesse setzen
display.setTextSize(_LCDML_ADAFRUITE_FONT_SIZE);
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 0); // line 0
display.println(buf);
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 1); // line 1
display.println(F("or press back button"));
display.display();
g_func_timer_info = 10; // reset and set timer
LCDML_DISP_triggerMenu(100); // starts a trigger event for the loop function every 100 millisecounds
}
void LCDML_DISP_loop(LCDML_FUNC_timer_info)
{
// 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
// this function is called every 100 millisecounds
// this timer checks every 1000 millisecounds if it is called
if((millis() - g_timer_1) >= 1000) {
g_timer_1 = millis();
g_func_timer_info--; // increment the value every secound
char buf[20];
sprintf (buf, "wait %d secounds", g_func_timer_info);
// clear lcd
display.clearDisplay();
// set text color / Textfarbe setzen
display.setTextColor(_LCDML_ADAFRUITE_TEXT_COLOR);
// set text size / Textgroesse setzen
display.setTextSize(_LCDML_ADAFRUITE_FONT_SIZE);
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 0); // line 0
display.println(buf);
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 1); // line 1
display.println(F("or press back button"));
display.display();
}
// reset the initscreen timer
LCDML_DISP_resetIsTimer();
// this function can only be ended when quit button is pressed or the time is over
// check if the function ends normaly
if (g_func_timer_info <= 0)
{
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_timer_info)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
uint8_t g_button_value = 0; // button value counter (global variable)
void LCDML_DISP_setup(LCDML_FUNC_p2)
// *********************************************************************
{
// 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_ADAFRUITE_TEXT_COLOR);
// set text size / Textgroesse setzen
display.setTextSize(_LCDML_ADAFRUITE_FONT_SIZE);
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 0); // line 0
display.println(F("press a or w button"));
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 1); // line 1
display.println(buf);
display.display();
// Reset Button Value
g_button_value = 0;
}
void LCDML_DISP_loop(LCDML_FUNC_p2)
{
// 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_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right)
{
if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) // check if button left is pressed
{
LCDML_BUTTON_resetLeft(); // reset the left button
LCDML_BUTTON_resetUp(); // reset the left button
g_button_value++;
// update lcd content
char buf[17];
sprintf (buf, "count: %d of 3", g_button_value);
// clear lcd
display.clearDisplay();
// set text color / Textfarbe setzen
display.setTextColor(_LCDML_ADAFRUITE_TEXT_COLOR);
// set text size / Textgroesse setzen
display.setTextSize(_LCDML_ADAFRUITE_FONT_SIZE);
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 0); // line 0
display.println(F("press a or w button"));
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * 1); // line 1
display.println(buf);
display.display();
}
}
// check if button count is three
if (g_button_value >= 3) {
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_p2)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,168 @@
// ============================================================
// Example: LCDML: use adafruite i2c display ssd1306
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// ============================================================
// include libs
#include <LCDMenuLib.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
// *********************************************************************
// Adufruit SSD1306
// *********************************************************************
// http://blog.simtronyx.de/ein-096-zoll-oled-display-i%C2%B2c-mit-128x64-pixel-und-ein-arduino/
#define _ADAFRUITE_I2C_ADR 0x3C
#define _LCDML_ADAFRUITE_TEXT_COLOR WHITE
#define _LCDML_ADAFRUITE_FONT_SIZE 1
#define _LCDML_ADAFRUITE_FONT_W (6*_LCDML_ADAFRUITE_FONT_SIZE) // font width
#define _LCDML_ADAFRUITE_FONT_H (8*_LCDML_ADAFRUITE_FONT_SIZE) // font heigt
// settings for u8g lib and lcd
#define _LCDML_ADAFRUITE_lcd_w 128 // lcd width
#define _LCDML_ADAFRUITE_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_ADAFRUITE_cols_max (_LCDML_ADAFRUITE_lcd_w/_LCDML_ADAFRUITE_FONT_W)
#define _LCDML_ADAFRUITE_rows_max (_LCDML_ADAFRUITE_lcd_h/_LCDML_ADAFRUITE_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_ADAFRUITE_cols 20 // max cols
#define _LCDML_ADAFRUITE_rows _LCDML_ADAFRUITE_rows_max // max rows
// scrollbar width
#define _LCDML_ADAFRUITE_scrollbar_w 6 // scrollbar width
// old defines with new content
#define _LCDML_DISP_cols _LCDML_ADAFRUITE_cols
#define _LCDML_DISP_rows _LCDML_ADAFRUITE_rows
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 16
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Change value" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_3 , 2 , "Something" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root , 4 , "Program" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root_4 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_4_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root_4_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_4_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_4_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (11 , _LCDML_G1 , LCDML_root_4 , 2 , "Program 2" , LCDML_FUNC_p2);
LCDML_DISP_add (12 , _LCDML_G1 , LCDML_root , 5 , "Mode" , LCDML_FUNC);
LCDML_DISP_add (13 , _LCDML_G1 , LCDML_root , 6 , "Serial No." , LCDML_FUNC);
LCDML_DISP_add (14 , _LCDML_G1 , LCDML_root , 7 , "Display Type" , LCDML_FUNC);
LCDML_DISP_add (15 , _LCDML_G1 , LCDML_root , 8 , "Something 1" , LCDML_FUNC);
LCDML_DISP_add (16 , _LCDML_G1 , LCDML_root , 9 , "Something 2" , LCDML_FUNC);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 10000000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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 all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// initialize with the I2C addr / mit I2C-Adresse initialisieren
display.begin(SSD1306_SWITCHCAPVCC, _ADAFRUITE_I2C_ADR);
// clear lcd
display.clearDisplay();
// set text color / Textfarbe setzen
display.setTextColor(_LCDML_ADAFRUITE_TEXT_COLOR);
// set text size / Textgroesse setzen
display.setTextSize(_LCDML_ADAFRUITE_FONT_SIZE);
display.setCursor(0, _LCDML_ADAFRUITE_FONT_H * (3));
display.println("LCDMenuLib v2.1.4 alpha");
display.display();
delay(1000);
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_ADAFRUITE_rows_max)
# error change value of _LCDML_ADAFRUITE_rows_max in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,88 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_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);
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_ADAFRUIT_rows) ? ((_LCDML_ADAFRUIT_rows > _LCDML_ADAFRUIT_rows_max) ? _LCDML_ADAFRUIT_rows : _LCDML_ADAFRUIT_rows_max) : (LCDML.getChilds());
// display rows and cursor
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
if (n == LCDML.getCursorPos()) {
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * (n));
display.println("X");
}
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0: // dynamic content
// display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * (n));
// display.println("var_datetime");
// break;
default: // static content
display.setCursor(0, _LCDML_ADAFRUIT_FONT_H * (n));
display.println(LCDML.content[n]);
break;
}
}
// display scrollbar when more content as rows available
if (LCDML.getChilds() > n_max) {
// set frame for scrollbar
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 = LCDML.getChilds() - n_max;
scrollbar_block_length = _LCDML_ADAFRUIT_lcd_h / (scrollbar_block_length + _LCDML_DISP_rows);
//set scrollbar
// hier muss du mal schauen wie du blöcke einfügen kannst, bei der u8glib geht das wie unten angezeigt, bei deiner lib weis ich das nicht
if (LCDML.getCursorPosAbs() == 0) { // top position (min)
//u8g.drawBox(_LCDML_ADAFRUIT_lcd_w - (_LCDML_ADAFRUIT_scrollbar_w-1), 1 , (_LCDML_ADAFRUIT_scrollbar_w-2) , scrollbar_block_length);
}
else if (LCDML.getCursorPosAbs() == (LCDML.getChilds())) { // bottom position (max)
//u8g.drawBox(_LCDML_ADAFRUIT_lcd_w - (_LCDML_ADAFRUIT_scrollbar_w-1), _LCDML_ADAFRUIT_lcd_h - scrollbar_block_length , (_LCDML_ADAFRUIT_scrollbar_w-2) , scrollbar_block_length);
}
else { // between top and bottom
//u8g.drawBox(_LCDML_ADAFRUIT_lcd_w - (_LCDML_ADAFRUIT_scrollbar_w-1), (scrollbar_block_length * LCDML.getCursorPosAbs() + 1),(_LCDML_ADAFRUIT_scrollbar_w-2) , scrollbar_block_length);
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,226 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_information)
// *********************************************************************
{
// 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"));
}
void LCDML_DISP_loop(LCDML_FUNC_information)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_information)
{
// this functions is ever called when a DISP function is quit
// 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 (globale variable)
void LCDML_DISP_setup(LCDML_FUNC_timer_info)
// *********************************************************************
{
// setup function
char buf[20];
sprintf (buf, "wait %d secounds", 10);
// 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"));
g_func_timer_info = 10; // reset and set timer
LCDML_DISP_triggerMenu(100); // starts a trigger event for the loop function every 100 millisecounds
}
void LCDML_DISP_loop(LCDML_FUNC_timer_info)
{
// 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
// this function is called every 100 millisecounds
// this timer checks every 1000 millisecounds if it is called
if((millis() - g_timer_1) >= 1000) {
g_timer_1 = millis();
g_func_timer_info--; // increment the value every secound
char buf[20];
sprintf (buf, "wait %d secounds", 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"));
}
// reset the initscreen timer
LCDML_DISP_resetIsTimer();
// this function can only be ended when quit button is pressed or the time is over
// check if the function ends normaly
if (g_func_timer_info <= 0)
{
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_timer_info)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
uint8_t g_button_value = 0; // button value counter (global variable)
void LCDML_DISP_setup(LCDML_FUNC_p2)
// *********************************************************************
{
// 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;
}
void LCDML_DISP_loop(LCDML_FUNC_p2)
{
// 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_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right)
{
if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) // check if button left is pressed
{
LCDML_BUTTON_resetLeft(); // reset the left button
LCDML_BUTTON_resetUp(); // reset the left button
g_button_value++;
// update lcd content
char buf[17];
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) {
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_p2)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,191 @@
// ============================================================
// Example: LCDML: use adafruit i2c display ssd1306
// ============================================================
// Autor: Nils Feldkämper, Markus Rudel
// Last update: 18.01.2017
// License: MIT
// ============================================================
// Descripton:
// ============================================================
// include libs
#include <LCDMenuLib.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
// *********************************************************************
// 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 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 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
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 16
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Change value" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_3 , 2 , "Something" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root , 4 , "Program" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root_4 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_4_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root_4_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_4_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_4_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (11 , _LCDML_G1 , LCDML_root_4 , 2 , "Program 2" , LCDML_FUNC_p2);
LCDML_DISP_add (12 , _LCDML_G1 , LCDML_root , 5 , "Mode" , LCDML_FUNC);
LCDML_DISP_add (13 , _LCDML_G1 , LCDML_root , 6 , "Serial No." , LCDML_FUNC);
LCDML_DISP_add (14 , _LCDML_G1 , LCDML_root , 7 , "Display Type" , LCDML_FUNC);
LCDML_DISP_add (15 , _LCDML_G1 , LCDML_root , 8 , "Something 1" , LCDML_FUNC);
LCDML_DISP_add (16 , _LCDML_G1 , LCDML_root , 9 , "Something 2" , LCDML_FUNC);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 10000000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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 all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
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("LCDMenuLib v2.1.4 alpha");
delay(1000);
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_ADAFRUIT_rows_max)
# error change value of _LCDML_ADAFRUIT_rows_max in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,88 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// for first test set font here
u8g2.setFont(_LCDML_DISP_font);
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? ((_LCDML_DISP_rows > _LCDML_DISP_rows_max) ? _LCDML_DISP_rows : _LCDML_DISP_rows_max) : (LCDML.getChilds());
uint8_t gCP = LCDML.getCursorPos();
uint8_t gCPABS= LCDML.getCursorPosAbs();
uint8_t gC = LCDML.getChilds();
// set page
u8g2.firstPage();
// generate content
do {
// display rows and cursor
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
if (n == gCP) {
u8g2.drawStr( _LCDML_DISP_box_x0+_LCDML_DISP_cur_space_before, _LCDML_DISP_box_y0 + _LCDML_DISP_font_h * (n + 1), _LCDML_DISP_cursor_char);
}
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// 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), "var_datetime"); // or datetime or other things
// break;
default: // static content
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), LCDML.content[n]);
break;
}
}
// drow a box around the menu
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 (gC > 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 = gC - n_max;
scrollbar_block_length = (_LCDML_DISP_box_y1-_LCDML_DISP_box_y0) / (scrollbar_block_length + _LCDML_DISP_rows);
//set scrollbar
if (gCPABS == 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 (gCPABS == (gC-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 * gCPABS + 1),(_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
}
}
} while ( u8g2.nextPage() );
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,195 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_information)
// *********************************************************************
{
// setup function
u8g2.setFont(_LCDML_DISP_font);
u8g2.firstPage();
do {
u8g2.drawStr( 0, 13, "To close this");
u8g2.drawStr( 0, 26, "function press");
u8g2.drawStr( 0, 39, "any button or use");
u8g2.drawStr( 0, 52, "back button");
} while( u8g2.nextPage() );
}
void LCDML_DISP_loop(LCDML_FUNC_information)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_information)
{
// this functions is ever called when a DISP function is quit
// 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 (globale variable)
void LCDML_DISP_setup(LCDML_FUNC_timer_info)
// *********************************************************************
{
// setup function
char buf[20];
sprintf (buf, "wait %d secounds", 10);
u8g2.setFont(_LCDML_DISP_font);
u8g2.firstPage();
do {
u8g2.drawStr( 0, 13, buf);
u8g2.drawStr( 0, 26, "or press back button");
} while( u8g2.nextPage() );
g_func_timer_info = 10; // reset and set timer
LCDML_DISP_triggerMenu(100); // starts a trigger event for the loop function every 100 millisecounds
}
void LCDML_DISP_loop(LCDML_FUNC_timer_info)
{
// 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
// this function is called every 100 millisecounds
// this timer checks every 1000 millisecounds if it is called
if((millis() - g_timer_1) >= 1000) {
g_timer_1 = millis();
g_func_timer_info--; // increment the value every secound
char buf[20];
sprintf (buf, "wait %d secounds", g_func_timer_info);
u8g2.setFont(_LCDML_DISP_font);
u8g2.firstPage();
do {
u8g2.drawStr( 0, 13, buf);
u8g2.drawStr( 0, 26, "or press back button");
} while( u8g2.nextPage() );
}
// reset the initscreen timer
LCDML_DISP_resetIsTimer();
// this function can only be ended when quit button is pressed or the time is over
// check if the function ends normaly
if (g_func_timer_info <= 0)
{
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_timer_info)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
uint8_t g_button_value = 0; // button value counter (global variable)
void LCDML_DISP_setup(LCDML_FUNC_p2)
// *********************************************************************
{
// 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, 13, "press a or w button");
u8g2.drawStr( 0, 26, buf);
} while( u8g2.nextPage() );
// Reset Button Value
g_button_value = 0;
}
void LCDML_DISP_loop(LCDML_FUNC_p2)
{
// 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_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right)
{
if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) // check if button left is pressed
{
LCDML_BUTTON_resetLeft(); // reset the left button
LCDML_BUTTON_resetUp(); // reset the left button
g_button_value++;
// update lcd content
char buf[17];
sprintf (buf, "count: %d of 3", g_button_value);
u8g2.setFont(_LCDML_DISP_font);
u8g2.firstPage();
do {
u8g2.drawStr( 0, 13, "press a or w button");
u8g2.drawStr( 0, 26, buf);
} while( u8g2.nextPage() );
}
}
// check if button count is three
if (g_button_value >= 3) {
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_p2)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,164 @@
// ============================================================
// Example: LCDML: grafik display with u8g2
// ============================================================
// Autor: Nils Feldkämper
// Last update: 12.01.2017
// License: MIT
// ============================================================
// Descripton:
// This example shows how to use the u8g2lib with the lcdmenulib
// The menu can placed in a box that can be placed anywhere on
// the screen.
// ============================================================
// include libs
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
// 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
// *********************************************************************
// U8G2LIB
// *********************************************************************
// U8g2 Contructor 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=*/ 12, /* reset=*/ U8X8_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 heigt
// 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
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 16
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Change value" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_3 , 2 , "Something" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root , 4 , "Program" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root_4 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_4_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root_4_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_4_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_4_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (11 , _LCDML_G1 , LCDML_root_4 , 2 , "Program 2" , LCDML_FUNC_p2);
LCDML_DISP_add (12 , _LCDML_G1 , LCDML_root , 5 , "Mode" , LCDML_FUNC);
LCDML_DISP_add (13 , _LCDML_G1 , LCDML_root , 6 , "Serial No." , LCDML_FUNC);
LCDML_DISP_add (14 , _LCDML_G1 , LCDML_root , 7 , "Display Type" , LCDML_FUNC);
LCDML_DISP_add (15 , _LCDML_G1 , LCDML_root , 8 , "Something 1" , LCDML_FUNC);
LCDML_DISP_add (16 , _LCDML_G1 , LCDML_root , 9 , "Something 2" , LCDML_FUNC);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 10000000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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
// Enable all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,89 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_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.
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? ((_LCDML_DISP_rows > _LCDML_DISP_rows_max) ? _LCDML_DISP_rows : _LCDML_DISP_rows_max) : (LCDML.getChilds());
uint8_t gCP = LCDML.getCursorPos();
uint8_t gCPABS= LCDML.getCursorPosAbs();
uint8_t gC = LCDML.getChilds();
// set page
u8g.firstPage();
// generate content
do {
// display rows and cursor
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
if (n == gCP) {
u8g.drawStr( _LCDML_DISP_box_x0+_LCDML_DISP_cur_space_before, _LCDML_DISP_box_y0 + _LCDML_DISP_font_h * (n + 1), _LCDML_DISP_cursor_char);
}
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// 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), "var_datetime"); // or datetime or other things
// break;
default: // static content
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), LCDML.content[n]);
break;
}
}
// drow a box around the menu
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 (gC > 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 = gC - n_max;
scrollbar_block_length = (_LCDML_DISP_box_y1-_LCDML_DISP_box_y0) / (scrollbar_block_length + _LCDML_DISP_rows);
//set scrollbar
if (gCPABS == 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 (gCPABS == (gC-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 * gCPABS + 1),(_LCDML_DISP_scrollbar_w-2) , scrollbar_block_length);
}
}
} while ( u8g.nextPage() );
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,195 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_information)
// *********************************************************************
{
// setup function
u8g.setFont(_LCDML_DISP_font);
u8g.firstPage();
do {
u8g.drawStr( 0, 13, F("To close this"));
u8g.drawStr( 0, 26, F("function press"));
u8g.drawStr( 0, 39, F("any button or use"));
u8g.drawStr( 0, 52, F("back button"));
} while( u8g.nextPage() );
}
void LCDML_DISP_loop(LCDML_FUNC_information)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_information)
{
// this functions is ever called when a DISP function is quit
// 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 (globale variable)
void LCDML_DISP_setup(LCDML_FUNC_timer_info)
// *********************************************************************
{
// setup function
char buf[20];
sprintf (buf, "wait %d secounds", 10);
u8g.setFont(_LCDML_DISP_font);
u8g.firstPage();
do {
u8g.drawStr( 0, 13, buf);
u8g.drawStr( 0, 26, F("or press back button"));
} while( u8g.nextPage() );
g_func_timer_info = 10; // reset and set timer
LCDML_DISP_triggerMenu(100); // starts a trigger event for the loop function every 100 millisecounds
}
void LCDML_DISP_loop(LCDML_FUNC_timer_info)
{
// 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
// this function is called every 100 millisecounds
// this timer checks every 1000 millisecounds if it is called
if((millis() - g_timer_1) >= 1000) {
g_timer_1 = millis();
g_func_timer_info--; // increment the value every secound
char buf[20];
sprintf (buf, "wait %d secounds", g_func_timer_info);
u8g.setFont(_LCDML_DISP_font);
u8g.firstPage();
do {
u8g.drawStr( 0, 13, buf);
u8g.drawStr( 0, 26, F("or press back button"));
} while( u8g.nextPage() );
}
// reset the initscreen timer
LCDML_DISP_resetIsTimer();
// this function can only be ended when quit button is pressed or the time is over
// check if the function ends normaly
if (g_func_timer_info <= 0)
{
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_timer_info)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
uint8_t g_button_value = 0; // button value counter (global variable)
void LCDML_DISP_setup(LCDML_FUNC_p2)
// *********************************************************************
{
// 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, 13, F("press a or w button"));
u8g.drawStr( 0, 26, buf);
} while( u8g.nextPage() );
// Reset Button Value
g_button_value = 0;
}
void LCDML_DISP_loop(LCDML_FUNC_p2)
{
// 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_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right)
{
if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) // check if button left is pressed
{
LCDML_BUTTON_resetLeft(); // reset the left button
LCDML_BUTTON_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, 13, F("press a or w button"));
u8g.drawStr( 0, 26, buf);
} while( u8g.nextPage() );
}
}
// check if button count is three
if (g_button_value >= 3) {
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_p2)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,158 @@
// ============================================================
// Example: LCDML: grafik display with u8g
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// 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.
// ============================================================
// include libs
#include <LCDMenuLib.h>
#include <U8glib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
// *********************************************************************
// 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(13, 11, 12, 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 heigt
// 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
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 16
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Change value" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_3 , 2 , "Something" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root , 4 , "Program" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root_4 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_4_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root_4_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_4_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_4_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (11 , _LCDML_G1 , LCDML_root_4 , 2 , "Program 2" , LCDML_FUNC_p2);
LCDML_DISP_add (12 , _LCDML_G1 , LCDML_root , 5 , "Mode" , LCDML_FUNC);
LCDML_DISP_add (13 , _LCDML_G1 , LCDML_root , 6 , "Serial No." , LCDML_FUNC);
LCDML_DISP_add (14 , _LCDML_G1 , LCDML_root , 7 , "Display Type" , LCDML_FUNC);
LCDML_DISP_add (15 , _LCDML_G1 , LCDML_root , 8 , "Something 1" , LCDML_FUNC);
LCDML_DISP_add (16 , _LCDML_G1 , LCDML_root , 9 , "Something 2" , LCDML_FUNC);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 10000000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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 all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif
# 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

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,112 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
uint8_t scrollbar_min = 0;
uint8_t scrollbar_max = LCDML.getChilds();
uint8_t scrollbar_cur_pos = LCDML.getCursorPosAbs();
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
// update content
if (LCDML_DISP_update_content()) {
// clear menu
LCDML_lcd_menu_clear();
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
lcd.setCursor(1, n);
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// lcd.print("special"); // or datetime or other things
// break;
default: // static content
lcd.print(LCDML.content[n]);
break;
}
}
}
// update cursor and scrollbar
if (LCDML_DISP_update_cursor()) {
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor
lcd.setCursor(0, n);
//set cursor char
if (n == LCDML.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);
}
}
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
lcd.clear();
lcd.setCursor(0, 0);
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,166 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_information)
// *********************************************************************
{
// setup function
lcd.setCursor(0, 0);
lcd.print(F("Um Funktion zu"));
lcd.setCursor(0, 1);
lcd.print(F("schliessen eine"));
lcd.setCursor(0, 2);
lcd.print(F("Taste druecken oder"));
lcd.setCursor(0, 3);
lcd.print(F("Back Taste verwenden"));
}
void LCDML_DISP_loop(LCDML_FUNC_information)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_information)
{
// this functions is ever called when a DISP function is quit
// 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 (globale variable)
void LCDML_DISP_setup(LCDML_FUNC_timer_info)
// *********************************************************************
{
// setup function
lcd.print(F("x sec warten")); // print some content on first row
g_func_timer_info = 10; // reset and set timer
LCDML_DISP_triggerMenu(100); // starts a trigger event for the loop function every 100 millisecounds
}
void LCDML_DISP_loop(LCDML_FUNC_timer_info)
{
// 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
// this function is called every 100 millisecounds
// this timer checks every 1000 millisecounds if it is called
if((millis() - g_timer_1) >= 1000) {
g_timer_1 = millis();
g_func_timer_info--; // increment the value every secound
lcd.setCursor(0, 0); // set cursor pos
lcd.print(g_func_timer_info); // print the time counter value
}
// reset the initscreen timer
LCDML_DISP_resetIsTimer();
// this function can only be ended when quit button is pressed or the time is over
// check if the function ends normaly
if (g_func_timer_info <= 0)
{
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_timer_info)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
uint8_t g_button_value = 0; // button value counter (global variable)
void LCDML_DISP_setup(LCDML_FUNC_p2)
// *********************************************************************
{
// setup function
// 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;
}
void LCDML_DISP_loop(LCDML_FUNC_p2)
{
// 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_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right)
{
if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) // check if button left is pressed
{
LCDML_BUTTON_resetLeft(); // reset the left button
LCDML_BUTTON_resetUp(); // reset the left button
g_button_value++;
// 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) {
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_p2)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,142 @@
// ============================================================
// Example: LCDML: display with liquidcrystal and i2c
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// This example is like the liquidcrystal example with another
// lcd object.
// ============================================================
// include libs
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// lcd object
//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, 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
};
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 12
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Change value" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_3 , 2 , "Something" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root , 4 , "Program" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root_4 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_4_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root_4_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_4_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_4_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (11 , _LCDML_G1 , LCDML_root_4 , 2 , "Program 2" , LCDML_FUNC_p2);
LCDML_DISP_add (12 , _LCDML_G1 , LCDML_root , 5 , "Last Point" , LCDML_FUNC);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 1000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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);
lcd.home (); // go home
// 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]);
lcd.setCursor(0,0);
lcd.print(F("booting"));
// Enable all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,112 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
uint8_t scrollbar_min = 0;
uint8_t scrollbar_max = LCDML.getChilds();
uint8_t scrollbar_cur_pos = LCDML.getCursorPosAbs();
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
// update content
if (LCDML_DISP_update_content()) {
// clear menu
LCDML_lcd_menu_clear();
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
lcd.setCursor(1, n);
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// lcd.print("special"); // or datetime or other things
// break;
default: // static content
lcd.print(LCDML.content[n]);
break;
}
}
}
// update cursor and scrollbar
if (LCDML_DISP_update_cursor()) {
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor
lcd.setCursor(0, n);
//set cursor char
if (n == LCDML.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);
}
}
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
lcd.clear();
lcd.setCursor(0, 0);
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,166 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_information)
// *********************************************************************
{
// setup function
lcd.setCursor(0, 0);
lcd.print(F("Um Funktion zu"));
lcd.setCursor(0, 1);
lcd.print(F("schliessen eine"));
lcd.setCursor(0, 2);
lcd.print(F("Taste druecken oder"));
lcd.setCursor(0, 3);
lcd.print(F("Back Taste verwenden"));
}
void LCDML_DISP_loop(LCDML_FUNC_information)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_information)
{
// this functions is ever called when a DISP function is quit
// 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 (globale variable)
void LCDML_DISP_setup(LCDML_FUNC_timer_info)
// *********************************************************************
{
// setup function
lcd.print(F("x sec warten")); // print some content on first row
g_func_timer_info = 10; // reset and set timer
LCDML_DISP_triggerMenu(100); // starts a trigger event for the loop function every 100 millisecounds
}
void LCDML_DISP_loop(LCDML_FUNC_timer_info)
{
// 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
// this function is called every 100 millisecounds
// this timer checks every 1000 millisecounds if it is called
if((millis() - g_timer_1) >= 1000) {
g_timer_1 = millis();
g_func_timer_info--; // increment the value every secound
lcd.setCursor(0, 0); // set cursor pos
lcd.print(g_func_timer_info); // print the time counter value
}
// reset the initscreen timer
LCDML_DISP_resetIsTimer();
// this function can only be ended when quit button is pressed or the time is over
// check if the function ends normaly
if (g_func_timer_info <= 0)
{
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_timer_info)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
uint8_t g_button_value = 0; // button value counter (global variable)
void LCDML_DISP_setup(LCDML_FUNC_p2)
// *********************************************************************
{
// setup function
// 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;
}
void LCDML_DISP_loop(LCDML_FUNC_p2)
{
// 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_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right)
{
if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) // check if button left is pressed
{
LCDML_BUTTON_resetLeft(); // reset the left button
LCDML_BUTTON_resetUp(); // reset the left button
g_button_value++;
// 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) {
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_p2)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,137 @@
// ============================================================
// Example: LCDML: display liquid crystal
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// This example shows you, how to use this lib with LiquidCrystal
// lib. The LCD object have to create in this tab. In "LCDML_DISO"
// you can edit the layout of the menu. (content, cursor, scrollbar)
//
// When you rewrite this function, you can use every other LCD
// or graphic LCD Lib with this menu.
// ============================================================
// include libs
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// lcd object
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
LiquidCrystal lcd(4,5,6,7,8,9);
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
};
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 11
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Change value" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_3 , 2 , "Something" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root , 4 , "Program" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root_4 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_4_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root_4_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_4_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_4_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (11 , _LCDML_G1 , LCDML_root_4 , 2 , "Program 2" , LCDML_FUNC_p2);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 1000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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]);
// Enable all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,112 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
uint8_t scrollbar_min = 0;
uint8_t scrollbar_max = LCDML.getChilds();
uint8_t scrollbar_cur_pos = LCDML.getCursorPosAbs();
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
// update content
if (LCDML_DISP_update_content()) {
// clear menu
LCDML_lcd_menu_clear();
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
// set cursor
lcd.setCursor(1, n);
// set content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// lcd.print("special"); // or datetime or other things
// break;
default: // static content
lcd.print(LCDML.content[n]);
break;
}
}
}
// update cursor and scrollbar
if (LCDML_DISP_update_cursor()) {
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor
lcd.setCursor(0, n);
//set cursor char
if (n == LCDML.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);
}
}
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
lcd.clear();
lcd.setCursor(0, 0);
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,145 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
/* ===============================================
* Set Time
* =============================================== */
// you can remove this part when you are using a time lib
// this makros are only for this examples and can be delete
uint8_t vh, vmi, vs, vd,vmo, vy = 0;
#define hour() vh
#define minute() vmi
#define second() vs
#define day() vd
#define month() vmo
#define year() vy
#define setTime(h,mi,s,d,mo,y) vh=h; vmi=mi; vs=s; vd=d; vmo=mo; vy=y;
// define global variable
uint8_t _pos = 0;
// define help function to set the current time
void HELP_FUNC_set_dat(int8_t l_i)
{
switch(_pos)
{
case 0: setTime(hour()+l_i,minute(),second(),day(),month(),year()); break; // hour
case 1: setTime(hour(),minute()+l_i,second(),day(),month(),year()); break; // min
case 2: setTime(hour(),minute(),second(),day()+l_i,month(),year()); break; // day
case 3: setTime(hour(),minute(),second(),day(),month()+l_i,year()); break; // month
case 4: setTime(hour(),minute(),second(),day(),month(),year()+l_i); break; // year
}
}
// define help function to display the current clock settings
void digitalClockDisplay(){
lcd.setCursor(3,0);
printDigits(hour());
lcd.print(":");
if(_pos == 1) { lcd.print(" "); }
printDigits(minute());
lcd.print(":");
printDigits(second());
lcd.setCursor(3,1);
lcd.print(day());
lcd.print(".");
if(_pos == 3) { lcd.print(" "); }
lcd.print(month());
lcd.print(".");
if(_pos == 4) { lcd.print(" "); }
lcd.print(year());
// set cursor
switch(_pos) {
case 0: lcd.setCursor(2,0); lcd.blink(); break; //hour
case 1: lcd.setCursor(6,0); lcd.blink(); break; //min
case 2: lcd.setCursor(2,1); lcd.blink(); break; //day
case 3: lcd.setCursor(5+((day()<10)?0:1),1); lcd.blink(); break;//month
case 4: lcd.setCursor(7+((day()<10)?0:1)+((month()<10)?0:1),1); lcd.blink(); break; //year
default: lcd.noBlink(); break;
}
}
// define help function to display digits in front of the value
void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
if(digits < 10) {
lcd.print('0');
}
lcd.print(digits);
}
// ===============================================
// Set Time
void LCDML_DISP_setup(LCDML_FUNC_change_datetime)
// ********************************************************************* */
{
// setup function
//LCDML_DISP_triggerMenu(500); // set trigger for this function to 1000 millisecounds
// print default value
digitalClockDisplay();
}
void LCDML_DISP_loop(LCDML_FUNC_change_datetime)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
if (LCDML_BUTTON_checkUp()) { HELP_FUNC_set_dat(+1); LCDML_BUTTON_resetUp(); }
if (LCDML_BUTTON_checkDown()) { HELP_FUNC_set_dat(-1); LCDML_BUTTON_resetDown(); }
if (LCDML_BUTTON_checkRight()) { _pos=(_pos+1)%5; LCDML_BUTTON_resetRight(); }
lcd.clear();
digitalClockDisplay() ;
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_change_datetime)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
// disable the cursor
lcd.noBlink();
}

View File

@@ -0,0 +1,120 @@
// ============================================================
//
// Example: LCDML_104_change_value
//
// ============================================================
// This example shows different methods to change values
// For menu element "Set Datetime" thanks to skorpi08 @ arduino forum
// Other methods to change value coming soon
// ============================================================
// include libs
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// lcd object
// liquid crystal needs (rs, e, dat4, dat5, dat6, dat7)
LiquidCrystal lcd(4,5,6,7,8,9);
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
};
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 0
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Set Datetime" , LCDML_FUNC_change_datetime);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 100000000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// 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]);
// Enable all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

View File

@@ -0,0 +1,546 @@
// =====================================================================
//
// CONTROL
//
// =====================================================================
// *********************************************************************
// *********************************************************************
// content:
// (0) Control over serial interface
// (1) Control over one analog input
// (2) Control over 4 - 6 digital input pins (internal pullups enabled)
// (3) Control over encoder (internal pullups enabled)
// (4) Control with Keypad
// (5) Control with an ir remote
// (6) Control with a youstick
// *********************************************************************
#define _LCDML_CONTROL_cfg 0
// therory:
// "#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
// *********************************************************************
// CONTROL TASK, DO NOT CHANGE
// *********************************************************************
void LCDML_BACK_setup(LCDML_BACKEND_control)
// *********************************************************************
{
// call setup
LCDML_CONTROL_setup();
}
// backend loop
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// call loop
LCDML_CONTROL_loop();
// go to next backend function and do not block it
return true;
}
// backend stop stable
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
}
// *********************************************************************
// *************** (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'
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// 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_BUTTON_enter(); break;
case _LCDML_CONTROL_serial_up: LCDML_BUTTON_up(); break;
case _LCDML_CONTROL_serial_down: LCDML_BUTTON_down(); break;
case _LCDML_CONTROL_serial_left: LCDML_BUTTON_left(); break;
case _LCDML_CONTROL_serial_right: LCDML_BUTTON_right(); break;
case _LCDML_CONTROL_serial_quit: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (1) CONTROL OVER ONE ANALOG PIN *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 1)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset debounce timer
uint16_t value = analogRead(_LCDML_CONTROL_analog_pin); // analogpin for keypad
if (value >= _LCDML_CONTROL_analog_enter_min && value <= _LCDML_CONTROL_analog_enter_max) { LCDML_BUTTON_enter(); }
if (value >= _LCDML_CONTROL_analog_up_min && value <= _LCDML_CONTROL_analog_up_max) { LCDML_BUTTON_up(); }
if (value >= _LCDML_CONTROL_analog_down_min && value <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); }
if (value >= _LCDML_CONTROL_analog_left_min && value <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); }
if (value >= _LCDML_CONTROL_analog_right_min && value <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); }
if (value >= _LCDML_CONTROL_analog_back_min && value <= _LCDML_CONTROL_analog_back_max) { LCDML_BUTTON_quit(); }
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (2) CONTROL OVER DIGITAL PINS ***********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 2)
// settings
#define _LCDML_CONTROL_digital_low_active 0 // (1 = low active (pullup), 0 = high active (pulldown) button
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// 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
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
#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) >= _LCDML_DISP_cfg_button_press_time) {
g_LCDML_DISP_press_time = millis(); // reset press time
if (bitRead(but_stat, 0)) { LCDML_BUTTON_enter(); }
if (bitRead(but_stat, 1)) { LCDML_BUTTON_up(); }
if (bitRead(but_stat, 2)) { LCDML_BUTTON_down(); }
if (bitRead(but_stat, 3)) { LCDML_BUTTON_quit(); }
if (bitRead(but_stat, 4)) { LCDML_BUTTON_left(); }
if (bitRead(but_stat, 5)) { LCDML_BUTTON_right(); }
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (3) CONTROL WITH ENCODER ****************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 3)
// settings
#define _LCDML_CONTROL_encoder_pin_a 4 // pin encoder b
#define _LCDML_CONTROL_encoder_pin_b 5 // pin encoder a
#define _LCDML_CONTROL_encoder_pin_button 7 // pin taster
#define _LCDML_CONTROL_encoder_high_active 0 // (0 = low active (pullup), 1 = high active (pulldown)) button
// http://playground.arduino.cc/CommonTopics/PullUpDownResistor
#define _LCDML_CONTROL_encoder_refresh_time 5UL // 5ms
#define _LCDML_CONTROL_encoder_switch_time 75UL // 75 ms
// macros which define the functionality
#define _LCDML_CONTROL_encoder_switch_press_short() LCDML_BUTTON_enter()
#define _LCDML_CONTROL_encoder_rotary_a() LCDML_BUTTON_up()
#define _LCDML_CONTROL_encoder_rotary_b() LCDML_BUTTON_down()
#define _LCDML_CONTROL_encoder_advanced_switch 1
#define _LCDML_CONTROL_encoder_switch_press_long() LCDML_BUTTON_quit()
#define _LCDML_CONTROL_encoder_advanced_rotary 1
#define _LCDML_CONTROL_encoder_rotary_a_and_press() LCDML_BUTTON_left()
#define _LCDML_CONTROL_encoder_rotary_b_and_press() LCDML_BUTTON_right()
#define _LCDML_CONTROL_encoder_t_long_press 1000 // maximum is 1275 (5*255)
// global defines
uint8_t g_LCDML_CONTROL_encoder_t_prev = 0;
uint8_t g_LCDML_CONTROL_encoder_a_prev = 0;
uint8_t g_LCDML_CONTROL_t_pressed = 0;
uint8_t g_LCDML_CONTROL_t_press_time = 0;
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
// set encoder update intervall time
LCDML_BACK_dynamic_setLoopTime(LCDML_BACKEND_control, _LCDML_CONTROL_encoder_refresh_time); // 5ms
// init pins
if(_LCDML_CONTROL_encoder_high_active == 0)
{
pinMode(_LCDML_CONTROL_encoder_pin_a , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_b , INPUT_PULLUP);
pinMode(_LCDML_CONTROL_encoder_pin_button , INPUT_PULLUP);
}
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// read encoder status
unsigned char a = digitalRead(_LCDML_CONTROL_encoder_pin_a);
unsigned char b = digitalRead(_LCDML_CONTROL_encoder_pin_b);
unsigned char t = digitalRead(_LCDML_CONTROL_encoder_pin_button);
// change button status if high and low active are switched
if (_LCDML_CONTROL_encoder_high_active == 1) {
t = !t;
}
// check if the button was pressed and save this state
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_CONTROL_encoder_switch_time) {
g_LCDML_DISP_press_time = millis(); // reset button press time
// press button once
if (t == false && g_LCDML_CONTROL_encoder_t_prev == 0)
{
g_LCDML_CONTROL_t_pressed = 1;
}
else {
g_LCDML_CONTROL_encoder_t_prev = 0;
}
}
// check if button is currently pressed
if(t == false)
{
// check if the advanced rotary function is enabled
if(_LCDML_CONTROL_encoder_advanced_rotary == 1)
{
// check if the rotary encoder was moved
if (a == false && g_LCDML_CONTROL_encoder_a_prev ) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
// switch active and rotary b moved
_LCDML_CONTROL_encoder_rotary_b_and_press();
}
else
{
// switch active and rotary a moved
_LCDML_CONTROL_encoder_rotary_a_and_press();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
}
}
// check advanced mode "long press switch"
if(_LCDML_CONTROL_encoder_advanced_switch == 1)
{
// button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
// check overrun and stop
if(g_LCDML_CONTROL_t_press_time < 255)
{
g_LCDML_CONTROL_t_press_time++;
}
}
}
}
else
{
// switch is not active
// check encoder
if (a == false && g_LCDML_CONTROL_encoder_a_prev) {
g_LCDML_CONTROL_encoder_t_prev = 1;
if (b == false)
{
_LCDML_CONTROL_encoder_rotary_a();
}
else
{
_LCDML_CONTROL_encoder_rotary_b();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
// check if an button was pressed
if(g_LCDML_CONTROL_t_pressed == 1)
{
if(g_LCDML_CONTROL_t_press_time * _LCDML_CONTROL_encoder_refresh_time >= _LCDML_CONTROL_encoder_t_long_press && _LCDML_CONTROL_encoder_advanced_switch == 1)
{
_LCDML_CONTROL_encoder_switch_press_long();
}
else
{
_LCDML_CONTROL_encoder_switch_press_short();
}
g_LCDML_CONTROL_t_pressed = 0;
g_LCDML_CONTROL_t_press_time = 0;
g_LCDML_DISP_press_time = millis();
}
}
g_LCDML_CONTROL_encoder_a_prev = a; // set new encoder status
}
// *********************************************************************
// ******************************* 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 );
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '#': LCDML_BUTTON_enter(); break;
case '2': LCDML_BUTTON_up(); break;
case '8': LCDML_BUTTON_down(); break;
case '4': LCDML_BUTTON_left(); break;
case '6': LCDML_BUTTON_right(); break;
case '*': LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (5) CONTROL WITH IR REMOTE ***************************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 5)
// ir include (this lib have to be installed)
#include <IRremote.h>
// ir global vars
int RECV_PIN = 11;
// ir objects
IRrecv irrecv(RECV_PIN);
decode_results results;
// *********************************************************************
// setup (nothing change here)
void LCDML_CONTROL_setup()
{
irrecv.enableIRIn(); // Start the receiver
}
// *********************************************************************
// loop
// change in this function the ir values to your values
void LCDML_CONTROL_loop()
{
if (irrecv.decode(&results))
{
// 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 (results.value)
{
case 0x00000001: LCDML_BUTTON_enter(); break;
case 0x00000002: LCDML_BUTTON_up(); break;
case 0x00000003: LCDML_BUTTON_down(); break;
case 0x00000004: LCDML_BUTTON_left(); break;
case 0x00000005: LCDML_BUTTON_right(); break;
case 0x00000006: LCDML_BUTTON_quit(); break;
default: break;
}
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
// *********************************************************************
// *************** (6) CONTROL OVER JOYSTICK *********************
// *********************************************************************
#elif(_LCDML_CONTROL_cfg == 6)
// 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
// *********************************************************************
// setup
void LCDML_CONTROL_setup()
{
pinMode (_LCDML_CONTROL_digitalread, INPUT);
}
// *********************************************************************
// loop
void LCDML_CONTROL_loop()
{
// check debounce timer
if((millis() - g_LCDML_DISP_press_time) >= _LCDML_DISP_cfg_button_press_time) {
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_BUTTON_up(); } // up
if (valuey >= _LCDML_CONTROL_analog_down_min && valuey <= _LCDML_CONTROL_analog_down_max) { LCDML_BUTTON_down(); } // down
if (valuex >= _LCDML_CONTROL_analog_left_min && valuex <= _LCDML_CONTROL_analog_left_max) { LCDML_BUTTON_left(); } // left
if (valuex >= _LCDML_CONTROL_analog_right_min && valuex <= _LCDML_CONTROL_analog_right_max) { LCDML_BUTTON_right(); } // right
if(valuee == true) {LCDML_BUTTON_enter();} // enter
// back buttons have to be included as menuitem
// lock at the examle LCDML_back_button
}
}
// *********************************************************************
// ******************************* END *********************************
// *********************************************************************
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif

View File

@@ -0,0 +1,67 @@
// =====================================================================
//
// Output function
//
// =====================================================================
/* ******************************************************************** */
void LCDML_lcd_menu_display()
/* ******************************************************************** */
{
// check if menu needs an update
if (LCDML_DISP_update()) {
// init vars
uint8_t n_max = (LCDML.getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.getChilds());
// update content
if (LCDML_DISP_update_content() || LCDML_DISP_update_cursor()) {
// clear menu
LCDML_lcd_menu_clear();
Serial.println(F("==========================================="));
Serial.println(F("================ Menu ===================="));
Serial.println(F("==========================================="));
// display rows
for (uint8_t n = 0; n < n_max; n++)
{
//set cursor char
if (n == LCDML.getCursorPos()) {
Serial.print(F("(x) "));
} else {
Serial.print(F("( ) "));
}
// print content
// with content id you can add special content to your static menu or replace the content
// the content_id contains the id wich is set on main tab for a menuitem
switch(LCDML.content_id[n])
{
//case 0:
// Serial.print("special"); // or datetime or other things
// break;
default: // static content
Serial.print(LCDML.content[n]);
break;
}
Serial.println();
}
}
}
// reinit some vars
LCDML_DISP_update_end();
}
// lcd clear
void LCDML_lcd_menu_clear()
{
for(uint8_t i=0;i<15;i++) {
Serial.println();
}
}

View File

@@ -0,0 +1,33 @@
/* ===================================================================== *
* *
* BACKEND SYSTEM *
* *
* ===================================================================== *
* every "backend function" needs three functions
* - void LCDML_BACK_setup(..func_name..)
* - void LCDML_BACK_loop(..func_name..)
* - void LCDML_BACK_stable(..func_name..)
*
* - every BACKEND function can be stopped and started
* EXAMPLE CODE:
void LCDML_BACK_setup(LCDML_BACKEND_control)
{
// setup
// is called only if it is started or restartet (reset+start)
}
boolean LCDML_BACK_loop(LCDML_BACKEND_control)
{
// runs in loop
return false;
}
void LCDML_BACK_stable(LCDML_BACKEND_control)
{
// stable stop
// is called when a backend function is stopped with stopStable
}
* ===================================================================== *
*/

View File

@@ -0,0 +1,169 @@
/* ===================================================================== *
* *
* DISPLAY SYSTEM *
* *
* ===================================================================== *
* every "disp menu function" needs three functions
* - void LCDML_DISP_setup(func_name)
* - void LCDML_DISP_loop(func_name)
* - void LCDML_DISP_loop_end(func_name)
*
* EXAMPLE CODE:
void LCDML_DISP_setup(..menu_func_name..)
{
// setup
// is called only if it is started
// starts a trigger event for the loop function every 100 millisecounds
LCDML_DISP_triggerMenu(100);
}
void LCDML_DISP_loop(..menu_func_name..)
{
// loop
// is called when it is triggert
// - with LCDML_DISP_triggerMenu( millisecounds )
// - with every button status change
// check if any button is presed (enter, up, down, left, right)
if(LCDML_BUTTON_checkAny()) {
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(..menu_func_name..)
{
// loop end
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
* ===================================================================== *
*/
// *********************************************************************
void LCDML_DISP_setup(LCDML_FUNC_information)
// *********************************************************************
{
// 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"));
}
void LCDML_DISP_loop(LCDML_FUNC_information)
{
// 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_BUTTON_checkAny()) { // check if any button is presed (enter, up, down, left, right)
// LCDML_DISP_funcend calls the loop_end function
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_information)
{
// this functions is ever called when a DISP function is quit
// 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 (globale variable)
void LCDML_DISP_setup(LCDML_FUNC_timer_info)
// *********************************************************************
{
// setup function
Serial.println(F("==========================================="));
Serial.println(F("================ FUNC ===================="));
Serial.println(F("==========================================="));
Serial.println(F("wait 10 secounds or press back button"));
g_func_timer_info = 10; // reset and set timer
LCDML_DISP_triggerMenu(100); // starts a trigger event for the loop function every 100 millisecounds
}
void LCDML_DISP_loop(LCDML_FUNC_timer_info)
{
// 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
// this function is called every 100 millisecounds
// this timer checks every 1000 millisecounds if it is called
if((millis() - g_timer_1) >= 1000) {
g_timer_1 = millis();
g_func_timer_info--; // increment the value every secound
Serial.println(g_func_timer_info); // print the time counter value
}
// reset the initscreen timer
LCDML_DISP_resetIsTimer();
// this function can only be ended when quit button is pressed or the time is over
// check if the function ends normaly
if (g_func_timer_info <= 0)
{
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_timer_info)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}
// *********************************************************************
uint8_t g_button_value = 0; // button value counter (global variable)
void LCDML_DISP_setup(LCDML_FUNC_p2)
// *********************************************************************
{
// 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;
}
void LCDML_DISP_loop(LCDML_FUNC_p2)
{
// 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_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right)
{
if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) // check if button left is pressed
{
LCDML_BUTTON_resetLeft(); // reset the left button
LCDML_BUTTON_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) {
// end function for callback
LCDML_DISP_funcend();
}
}
void LCDML_DISP_loop_end(LCDML_FUNC_p2)
{
// this functions is ever called when a DISP function is quit
// you can here reset some global vars or do nothing
}

View File

@@ -0,0 +1,111 @@
// ============================================================
// Example: LCDML_serialmonitor
// ============================================================
// Autor: Nils Feldkämper
// Last update: 08.01.2017
// License: MIT
// ============================================================
// Descripton:
// This example shows how the menu works without any LCD.
// The output is print in serial console. This example can be
// extended with network functions to print this menu with telnet
// or other protocols.
// ============================================================
// include libs
#include <LCDMenuLib.h>
// lib config
#define _LCDML_DISP_cfg_button_press_time 200 // button press time in ms
// *********************************************************************
// LCDML TYPE SELECT
// *********************************************************************
// settings for lcd
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
// *********************************************************************
// LCDML MENU/DISP
// *********************************************************************
// create menu
// menu element count - last element id
// this value must be the same as the last menu element
#define _LCDML_DISP_cnt 11
// LCDML_root => layer 0
// LCDML_root_X => layer 1
// LCDML_root_X_X => layer 2
// LCDML_root_X_X_X => layer 3
// LCDML_root_... => layer ...
// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function)
LCDML_DISP_init(_LCDML_DISP_cnt);
LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Information" , LCDML_FUNC_information);
LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root , 2 , "Time info" , LCDML_FUNC_timer_info);
LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root , 3 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_3 , 1 , "Change value" , LCDML_FUNC);
LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_3 , 2 , "Something" , LCDML_FUNC);
LCDML_DISP_add (5 , _LCDML_G1 , LCDML_root , 4 , "Program" , LCDML_FUNC);
LCDML_DISP_add (6 , _LCDML_G1 , LCDML_root_4 , 1 , "Program 1" , LCDML_FUNC);
LCDML_DISP_add (7 , _LCDML_G1 , LCDML_root_4_1 , 1 , "P1 start" , LCDML_FUNC);
LCDML_DISP_add (8 , _LCDML_G1 , LCDML_root_4_1 , 2 , "Settings" , LCDML_FUNC);
LCDML_DISP_add (9 , _LCDML_G1 , LCDML_root_4_1_2 , 1 , "Warm" , LCDML_FUNC);
LCDML_DISP_add (10 , _LCDML_G1 , LCDML_root_4_1_2 , 2 , "Long" , LCDML_FUNC);
LCDML_DISP_add (11 , _LCDML_G1 , LCDML_root_4 , 2 , "Program 2" , LCDML_FUNC_p2);
LCDML_DISP_createMenu(_LCDML_DISP_cnt);
// *********************************************************************
// LCDML BACKEND (core of the menu, do not change here anything yet)
// *********************************************************************
// define backend function
#define _LCDML_BACK_cnt 1 // last backend function id
LCDML_BACK_init(_LCDML_BACK_cnt);
LCDML_BACK_new_timebased_dynamic (0 , ( 20UL ) , _LCDML_start , LCDML_BACKEND_control);
LCDML_BACK_new_timebased_dynamic (1 , ( 10000000UL ) , _LCDML_stop , LCDML_BACKEND_menu);
LCDML_BACK_create();
// *********************************************************************
// SETUP
// *********************************************************************
void setup()
{
Serial.begin(9600); // start serial
Serial.println(F(_LCDML_VERSION)); // only for examples
// Enable all items with _LCDML_G1
LCDML_DISP_groupEnable(_LCDML_G1); // enable group 1
// Enable menu rollover if needed
//LCDML.enRollover();
// LCDMenu Setup
LCDML_setup(_LCDML_BACK_cnt);
}
// *********************************************************************
// LOOP
// *********************************************************************
void loop()
{
// this function must called here, do not delete it
LCDML_run(_LCDML_priority);
}
// *********************************************************************
// check some errors - do not change here anything
// *********************************************************************
# if(_LCDML_DISP_rows > _LCDML_DISP_cfg_max_rows)
# error change value of _LCDML_DISP_cfg_max_rows in LCDMenuLib.h
# endif
# if(_LCDML_DISP_cols > _LCDML_DISP_cfg_max_string_length)
# error change value of _LCDML_DISP_cfg_max_string_length in LCDMenuLib.h
# endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Some files were not shown because too many files have changed in this diff Show More