|
|
@ -27,7 +27,7 @@ |
|
|
|
#define _UI_HPP_ |
|
|
|
#define _UI_HPP_ |
|
|
|
|
|
|
|
|
|
|
|
#include "config.h" |
|
|
|
#include "config.h" |
|
|
|
#include <LiquidCrystal_I2C.h> |
|
|
|
#include "LiquidCrystalPlus_I2C.h" |
|
|
|
#include <LCDMenuLib2.h> |
|
|
|
#include <LCDMenuLib2.h> |
|
|
|
#include <Encoder.h> |
|
|
|
#include <Encoder.h> |
|
|
|
|
|
|
|
|
|
|
@ -37,10 +37,20 @@ |
|
|
|
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
|
|
|
|
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
|
|
|
|
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
|
|
|
|
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern config_t configuration; |
|
|
|
|
|
|
|
void set_volume(float v, float p); |
|
|
|
|
|
|
|
extern char bank_names[MAX_BANKS][BANK_NAME_LEN]; |
|
|
|
|
|
|
|
extern char bank_name[BANK_NAME_LEN]; |
|
|
|
|
|
|
|
extern char voice_name[VOICE_NAME_LEN]; |
|
|
|
|
|
|
|
extern char voice_names[MAX_VOICES][VOICE_NAME_LEN]; |
|
|
|
|
|
|
|
extern void strip_extension(char* s, char *target); |
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
/***********************************************************************
|
|
|
|
GLOBAL |
|
|
|
GLOBAL |
|
|
|
***********************************************************************/ |
|
|
|
************************************************************************/ |
|
|
|
LiquidCrystal_I2C lcd(0x27, _LCDML_DISP_cols, _LCDML_DISP_rows); |
|
|
|
elapsedMillis back_from_volume; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LiquidCrystalPlus_I2C lcd(LCD_I2C_ADDRESS, _LCDML_DISP_cols, _LCDML_DISP_rows); |
|
|
|
|
|
|
|
|
|
|
|
const uint8_t scroll_bar[5][8] = { |
|
|
|
const uint8_t scroll_bar[5][8] = { |
|
|
|
{B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top
|
|
|
|
{B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top
|
|
|
@ -51,8 +61,8 @@ const uint8_t scroll_bar[5][8] = { |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
enum { ENC_R, ENC_L }; |
|
|
|
enum { ENC_R, ENC_L }; |
|
|
|
enum { MENU_VOICE, MENU_EDIT}; |
|
|
|
enum { MENU_START, MENU_VOICE, MENU_EDIT, MENU_VOLUME }; |
|
|
|
uint8_t menu_state = MENU_EDIT; |
|
|
|
uint8_t menu_state = MENU_START; |
|
|
|
|
|
|
|
|
|
|
|
void lcdml_menu_display(void); |
|
|
|
void lcdml_menu_display(void); |
|
|
|
void lcdml_voice_menu_display(void); |
|
|
|
void lcdml_voice_menu_display(void); |
|
|
@ -79,6 +89,7 @@ void UI_func_polyphony(uint8_t param); |
|
|
|
void UI_func_engine(uint8_t param); |
|
|
|
void UI_func_engine(uint8_t param); |
|
|
|
void UI_func_information(uint8_t param); |
|
|
|
void UI_func_information(uint8_t param); |
|
|
|
void UI_func_voice_selection(uint8_t param); |
|
|
|
void UI_func_voice_selection(uint8_t param); |
|
|
|
|
|
|
|
void UI_func_volume(uint8_t param); |
|
|
|
void UI_func_back(uint8_t param); |
|
|
|
void UI_func_back(uint8_t param); |
|
|
|
void UI_func_goToRootMenu(uint8_t param); |
|
|
|
void UI_func_goToRootMenu(uint8_t param); |
|
|
|
|
|
|
|
|
|
|
@ -121,8 +132,8 @@ LCDML_createMenu(_LCDML_DISP_cnt); |
|
|
|
/***********************************************************************
|
|
|
|
/***********************************************************************
|
|
|
|
CONTROL |
|
|
|
CONTROL |
|
|
|
***********************************************************************/ |
|
|
|
***********************************************************************/ |
|
|
|
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
|
|
|
#define g_LCDML_CONTROL_button_long_press LONG_BUTTON_PRESS |
|
|
|
#define g_LCDML_CONTROL_button_short_press 40 // ms
|
|
|
|
#define g_LCDML_CONTROL_button_short_press BUT_DEBOUNCE_MS |
|
|
|
|
|
|
|
|
|
|
|
//#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
|
|
|
//#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
|
|
|
Encoder ENCODER[NUM_ENCODER] = {Encoder(ENC_R_PIN_B, ENC_R_PIN_A), Encoder(ENC_L_PIN_B, ENC_L_PIN_A)}; |
|
|
|
Encoder ENCODER[NUM_ENCODER] = {Encoder(ENC_R_PIN_B, ENC_R_PIN_A), Encoder(ENC_L_PIN_B, ENC_L_PIN_A)}; |
|
|
@ -140,11 +151,19 @@ void lcdml_menu_control(void) |
|
|
|
pinMode(BUT_L_PIN, INPUT_PULLUP); |
|
|
|
pinMode(BUT_L_PIN, INPUT_PULLUP); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (back_from_volume > BACK_FROM_VOLUME_MS && menu_state == MENU_VOLUME) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
UI_func_voice_selection(0); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Volatile Variable
|
|
|
|
//Volatile Variable
|
|
|
|
long g_LCDML_CONTROL_Encoder_position[NUM_ENCODER] = {ENCODER[ENC_R].read(), ENCODER[ENC_L].read()}; |
|
|
|
long g_LCDML_CONTROL_Encoder_position[NUM_ENCODER] = {ENCODER[ENC_R].read(), ENCODER[ENC_L].read()}; |
|
|
|
bool button[NUM_ENCODER] = {digitalRead(BUT_R_PIN), digitalRead(BUT_L_PIN)}; |
|
|
|
bool button[NUM_ENCODER] = {digitalRead(BUT_R_PIN), digitalRead(BUT_L_PIN)}; |
|
|
|
|
|
|
|
|
|
|
|
// Right encoder
|
|
|
|
/************************************************************************************
|
|
|
|
|
|
|
|
Right encoder |
|
|
|
|
|
|
|
************************************************************************************/ |
|
|
|
if (g_LCDML_CONTROL_Encoder_position[ENC_R] <= -3) |
|
|
|
if (g_LCDML_CONTROL_Encoder_position[ENC_R] <= -3) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!button[ENC_R]) |
|
|
|
if (!button[ENC_R]) |
|
|
@ -155,8 +174,19 @@ void lcdml_menu_control(void) |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (menu_state == MENU_EDIT) |
|
|
|
switch (menu_state) |
|
|
|
LCDML.BT_down(); |
|
|
|
{ |
|
|
|
|
|
|
|
case MENU_EDIT: |
|
|
|
|
|
|
|
case MENU_VOLUME: |
|
|
|
|
|
|
|
menu_state = MENU_EDIT; |
|
|
|
|
|
|
|
LCDML.BT_down(); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case MENU_VOICE: |
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
|
|
|
Serial.println(F("State: MENU_VOICE, Encoder left down")); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
ENCODER[ENC_R].write(g_LCDML_CONTROL_Encoder_position[ENC_R] + 4); |
|
|
|
ENCODER[ENC_R].write(g_LCDML_CONTROL_Encoder_position[ENC_R] + 4); |
|
|
|
} |
|
|
|
} |
|
|
@ -171,8 +201,19 @@ void lcdml_menu_control(void) |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (menu_state == MENU_EDIT) |
|
|
|
switch (menu_state) |
|
|
|
LCDML.BT_up(); |
|
|
|
{ |
|
|
|
|
|
|
|
case MENU_EDIT: |
|
|
|
|
|
|
|
case MENU_VOLUME: |
|
|
|
|
|
|
|
menu_state = MENU_EDIT; |
|
|
|
|
|
|
|
LCDML.BT_up(); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case MENU_VOICE: |
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
|
|
|
Serial.println(F("State: MENU_VOICE, Encoder left up")); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
ENCODER[ENC_R].write(g_LCDML_CONTROL_Encoder_position[ENC_R] - 4); |
|
|
|
ENCODER[ENC_R].write(g_LCDML_CONTROL_Encoder_position[ENC_R] - 4); |
|
|
|
} |
|
|
|
} |
|
|
@ -195,15 +236,36 @@ void lcdml_menu_control(void) |
|
|
|
else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_R]) >= g_LCDML_CONTROL_button_long_press) |
|
|
|
else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_R]) >= g_LCDML_CONTROL_button_long_press) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LCDML.BT_quit(); |
|
|
|
LCDML.BT_quit(); |
|
|
|
|
|
|
|
if (menu_state == MENU_EDIT) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LCDML.BT_quit(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (menu_state == MENU_VOICE) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
|
|
|
Serial.println(F("State: MENU_VOICE, button long press")); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_R]) >= g_LCDML_CONTROL_button_short_press) |
|
|
|
else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_R]) >= g_LCDML_CONTROL_button_short_press) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LCDML.BT_enter(); |
|
|
|
if (menu_state == MENU_EDIT) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LCDML.BT_enter(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (menu_state == MENU_VOICE) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
|
|
|
Serial.println(F("State: MENU_VOICE, button short press")); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Left encoder
|
|
|
|
/************************************************************************************
|
|
|
|
|
|
|
|
Left encoder |
|
|
|
|
|
|
|
************************************************************************************/ |
|
|
|
if (g_LCDML_CONTROL_Encoder_position[ENC_L] <= -3) |
|
|
|
if (g_LCDML_CONTROL_Encoder_position[ENC_L] <= -3) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!button[ENC_L]) |
|
|
|
if (!button[ENC_L]) |
|
|
@ -214,10 +276,14 @@ void lcdml_menu_control(void) |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
#ifdef DEBUG |
|
|
|
Serial.println(F("Volume +")); |
|
|
|
Serial.println(F("Volume +")); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
if (configuration.vol < 1.0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
set_volume(configuration.vol + 0.05, configuration.pan); |
|
|
|
|
|
|
|
UI_func_volume(0); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
ENCODER[ENC_L].write(g_LCDML_CONTROL_Encoder_position[ENC_L] + 4); |
|
|
|
ENCODER[ENC_L].write(g_LCDML_CONTROL_Encoder_position[ENC_L] + 4); |
|
|
|
} |
|
|
|
} |
|
|
@ -235,6 +301,11 @@ void lcdml_menu_control(void) |
|
|
|
#ifdef DEBUG |
|
|
|
#ifdef DEBUG |
|
|
|
Serial.println(F("Volume -")); |
|
|
|
Serial.println(F("Volume -")); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
if (configuration.vol > 0.0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
set_volume(configuration.vol - 0.05, configuration.pan); |
|
|
|
|
|
|
|
UI_func_volume(0); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
ENCODER[ENC_L].write(g_LCDML_CONTROL_Encoder_position[ENC_L] - 4); |
|
|
|
ENCODER[ENC_L].write(g_LCDML_CONTROL_Encoder_position[ENC_L] - 4); |
|
|
|
} |
|
|
|
} |
|
|
@ -270,7 +341,7 @@ void lcdml_menu_control(void) |
|
|
|
if (menu_state == MENU_EDIT) |
|
|
|
if (menu_state == MENU_EDIT) |
|
|
|
{ |
|
|
|
{ |
|
|
|
menu_state = MENU_VOICE; |
|
|
|
menu_state = MENU_VOICE; |
|
|
|
LCDML.OTHER_jumpToFunc(UI_func_voice_selection,0); |
|
|
|
UI_func_voice_selection(0); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (menu_state == MENU_VOICE) |
|
|
|
else if (menu_state == MENU_VOICE) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -542,31 +613,53 @@ void UI_func_information(uint8_t param) |
|
|
|
|
|
|
|
|
|
|
|
void UI_func_voice_selection(uint8_t param) |
|
|
|
void UI_func_voice_selection(uint8_t param) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (LCDML.FUNC_setup()) // ****** SETUP *********
|
|
|
|
#ifdef DEBUG |
|
|
|
{ |
|
|
|
Serial.println(F("UI_func_voice_selection()")); |
|
|
|
// update LCD content
|
|
|
|
#endif |
|
|
|
lcd.clear(); |
|
|
|
|
|
|
|
lcd.setCursor(0, 0); // set cursor
|
|
|
|
|
|
|
|
lcd.print("screensaver"); // print change content
|
|
|
|
|
|
|
|
lcd.setCursor(0, 1); // set cursor
|
|
|
|
|
|
|
|
lcd.print("press any key"); |
|
|
|
|
|
|
|
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (LCDML.FUNC_loop()) |
|
|
|
menu_state = MENU_VOICE; |
|
|
|
{ |
|
|
|
|
|
|
|
if (LCDML.BT_checkEnter()) |
|
|
|
// update LCD content
|
|
|
|
{ |
|
|
|
LCDML.DISP_clear(); |
|
|
|
LCDML.MENU_goRoot(); |
|
|
|
|
|
|
|
} |
|
|
|
lcd.show(0, 0, 2, configuration.bank); |
|
|
|
} |
|
|
|
lcd.show(0, 2, 1, " "); |
|
|
|
|
|
|
|
strip_extension(bank_names[configuration.bank], bank_name); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lcd.show(0, 2, 1, " "); |
|
|
|
|
|
|
|
lcd.show(0, 3, 8, bank_name); |
|
|
|
|
|
|
|
lcd.show(0, 11, 1, " "); |
|
|
|
|
|
|
|
|
|
|
|
if (LCDML.FUNC_close()) |
|
|
|
lcd.show(1, 0, 2, configuration.voice + 1); |
|
|
|
|
|
|
|
lcd.show(1, 2, 1, " "); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lcd.show(1, 2, 1, "["); |
|
|
|
|
|
|
|
lcd.show(1, 3, 10, voice_names[configuration.voice]); |
|
|
|
|
|
|
|
lcd.show(1, 14, 1, "]"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void UI_func_volume(uint8_t param) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
|
|
|
Serial.println(F("UI_func_volume()")); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
menu_state = MENU_VOLUME; |
|
|
|
|
|
|
|
back_from_volume = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// update LCD content
|
|
|
|
|
|
|
|
LCDML.DISP_clear(); |
|
|
|
|
|
|
|
lcd.setCursor(0, 0); // set cursor
|
|
|
|
|
|
|
|
lcd.print("Volume"); // print change content
|
|
|
|
|
|
|
|
lcd.setCursor(0, 1); // set cursor
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < LCD_cols; i++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// The screensaver go to the root menu
|
|
|
|
if (i < int(LCD_cols * configuration.vol + 0.5)) |
|
|
|
LCDML.MENU_goRoot(); |
|
|
|
lcd.print("*"); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
lcd.print(" "); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
#endif |
|
|
|