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

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