From 9d51c90f72f4f9ae93d651985e1b0fff93cdf1b7 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 8 Oct 2019 12:23:48 +0200 Subject: [PATCH] Added 2nd encoder and menu. --- MicroDexed.ino | 5 +- UI.hpp | 250 ++++++++++++++++++++++++++++++++++++++++++------- config.h | 3 - 3 files changed, 220 insertions(+), 38 deletions(-) diff --git a/MicroDexed.ino b/MicroDexed.ino index b1cca47..e59544d 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -142,9 +142,9 @@ void setup() // LCDMenuLib Setup LCDML_setup(_LCDML_DISP_cnt); // Enable Menu Rollover - LCDML.MENU_enRollover(); + //LCDML.MENU_enRollover(); // Enable Screensaver (screensaver menu function, time to activate in ms) - LCDML.SCREEN_enable(UI_func_screensaver, 10000); // set to 10 seconds + //LCDML.SCREEN_enable(UI_func_screensaver, 10000); // set to 10 seconds #else Serial.println(F("NO LCD DISPLAY ENABLED!")); #endif @@ -338,6 +338,7 @@ void loop() #ifdef ENABLE_LCD_UI // LCD Menu LCDML.loop(); + LCDML_Voice.loop(); #endif control_rate = 0; diff --git a/UI.hpp b/UI.hpp index 67e8d06..191d126 100644 --- a/UI.hpp +++ b/UI.hpp @@ -50,9 +50,13 @@ const uint8_t scroll_bar[5][8] = { {B10001, B10001, B10001, B10001, B10001, B10001, B11111, B11111} // scrollbar bottom }; +enum { ENC_R, ENC_L }; + void lcdml_menu_display(void); +void lcdml_voice_menu_display(void); void lcdml_menu_clear(void); void lcdml_menu_control(void); +void lcdml_voice_menu_control(void); void UI_func_sound(uint8_t param); void UI_func_reverb_roomsize(uint8_t param); void UI_func_reverb_damping(uint8_t param); @@ -71,12 +75,18 @@ void UI_func_panorama(uint8_t param); void UI_func_stereo_mono(uint8_t param); void UI_func_polyphony(uint8_t param); void UI_func_engine(uint8_t param); +void UI_func_information(uint8_t param); void UI_func_back(uint8_t param); void UI_func_goToRootMenu(uint8_t param); -LCDMenuLib2_menu LCDML_0(255, 0, 0, NULL, NULL); // root menu element (do not change) +// normal menu +LCDMenuLib2_menu LCDML_0(255, 0, 0, NULL, NULL); // normal root menu element (do not change) LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control); +// voice menu +LCDMenuLib2_menu LCDML_1(255, 0, 0, NULL, NULL); // voice root menu element (do not change) +LCDMenuLib2 LCDML_Voice(LCDML_1, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_voice_menu_display, lcdml_menu_clear, lcdml_voice_menu_control); + // LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function) LCDML_add(0, LCDML_0, 1, "Sound", UI_func_sound); LCDML_add(1, LCDML_0, 2, "Effect", NULL); @@ -103,9 +113,10 @@ LCDML_add(21, LCDML_0_4, 3, "Panorama", UI_func_panorama); LCDML_add(22, LCDML_0_4, 4, "Stereo/Mono", UI_func_stereo_mono); LCDML_add(23, LCDML_0_4, 5, "Polyphony", UI_func_polyphony); LCDML_add(24, LCDML_0_4, 6, "Engine", UI_func_engine); -LCDML_add(25, LCDML_0, 5, "Info", NULL); - -#define _LCDML_DISP_cnt 25 +LCDML_add(25, LCDML_0, 5, "Info", UI_func_information); +LCDML_add(26, LCDML_1, 1, "Bank", NULL); +LCDML_add(27, LCDML_1, 2, "Voice", NULL); +#define _LCDML_DISP_cnt 27 // create menu LCDML_createMenu(_LCDML_DISP_cnt); @@ -117,76 +128,71 @@ LCDML_createMenu(_LCDML_DISP_cnt); #define g_LCDML_CONTROL_button_short_press 40 // ms //#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega) -Encoder ENCODER[2] = {Encoder(ENC_L_PIN_A, ENC_L_PIN_B), Encoder(ENC_R_PIN_A, ENC_R_PIN_B)}; +Encoder ENCODER[NUM_ENCODER] = {Encoder(ENC_R_PIN_B, ENC_R_PIN_A), Encoder(ENC_L_PIN_B, ENC_L_PIN_A)}; -long g_LCDML_CONTROL_button_press_time[2] = {0, 0}; -bool g_LCDML_CONTROL_button_prev[2] = {HIGH, HIGH}; +long g_LCDML_CONTROL_button_press_time[NUM_ENCODER] = {0, 0}; +bool g_LCDML_CONTROL_button_prev[NUM_ENCODER] = {HIGH, HIGH}; void lcdml_menu_control(void) { // If something must init, put in in the setup condition if (LCDML.BT_setup()) { - //pinMode(ENC_R_PIN_A, INPUT_PULLUP); - //pinMode(ENC_R_PIN_B, INPUT_PULLUP); pinMode(BUT_R_PIN, INPUT_PULLUP); - pinMode(BUT_L_PIN, INPUT_PULLUP); } //Volatile Variable - long g_LCDML_CONTROL_Encoder_position[2] = {ENCODER[0].read(), ENCODER[1].read()}; - bool button[2] = {digitalRead(BUT_R_PIN), digitalRead(BUT_L_PIN)}; - - if (g_LCDML_CONTROL_Encoder_position[0] <= -3) { + long g_LCDML_CONTROL_Encoder_position = ENCODER[ENC_R].read(); + bool button_r = digitalRead(BUT_R_PIN); - if (!button[0]) + if (g_LCDML_CONTROL_Encoder_position <= -3) { + if (!button_r) { LCDML.BT_left(); - g_LCDML_CONTROL_button_prev[0] = LOW; - g_LCDML_CONTROL_button_press_time[0] = -1; + g_LCDML_CONTROL_button_prev[ENC_R] = LOW; + g_LCDML_CONTROL_button_press_time[ENC_R] = -1; } else { LCDML.BT_down(); } - ENCODER[0].write(g_LCDML_CONTROL_Encoder_position[0] + 4); + ENCODER[ENC_R].write(g_LCDML_CONTROL_Encoder_position + 4); } - else if (g_LCDML_CONTROL_Encoder_position[0] >= 3) + else if (g_LCDML_CONTROL_Encoder_position >= 3) { - - if (!button[0]) + if (!button_r) { LCDML.BT_right(); - g_LCDML_CONTROL_button_prev[0] = LOW; - g_LCDML_CONTROL_button_press_time[0] = -1; + g_LCDML_CONTROL_button_prev[ENC_R] = LOW; + g_LCDML_CONTROL_button_press_time[ENC_R] = -1; } else { LCDML.BT_up(); } - ENCODER[0].write(g_LCDML_CONTROL_Encoder_position[0] - 4); + ENCODER[ENC_R].write(g_LCDML_CONTROL_Encoder_position - 4); } else { - if (!button[0] && g_LCDML_CONTROL_button_prev[0]) //falling edge, button pressed + if (!button_r && g_LCDML_CONTROL_button_prev[ENC_R]) //falling edge, button_r pressed { - g_LCDML_CONTROL_button_prev[0] = LOW; - g_LCDML_CONTROL_button_press_time[0] = millis(); + g_LCDML_CONTROL_button_prev[ENC_R] = LOW; + g_LCDML_CONTROL_button_press_time[ENC_R] = millis(); } - else if (button[0] && !g_LCDML_CONTROL_button_prev[0]) //rising edge, button not active + else if (button_r && !g_LCDML_CONTROL_button_prev) //rising edge, button_r not active { - g_LCDML_CONTROL_button_prev[0] = HIGH; + g_LCDML_CONTROL_button_prev[ENC_R] = HIGH; - if (g_LCDML_CONTROL_button_press_time[0] < 0) + if (g_LCDML_CONTROL_button_press_time[ENC_R] < 0) { - g_LCDML_CONTROL_button_press_time[0] = millis(); + g_LCDML_CONTROL_button_press_time[ENC_R] = millis(); //Reset for left right action } - else if ((millis() - g_LCDML_CONTROL_button_press_time[0]) >= 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(); } - else if ((millis() - g_LCDML_CONTROL_button_press_time[0]) >= 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(); } @@ -194,6 +200,74 @@ void lcdml_menu_control(void) } } +void lcdml_voice_menu_control(void) +{ + // If something must init, put in in the setup condition + if (LCDML_Voice.BT_setup()) + { + pinMode(BUT_L_PIN, INPUT_PULLUP); + } + + //Volatile Variable + long g_LCDML_CONTROL_Encoder_position = ENCODER[ENC_L].read(); + bool button_l = digitalRead(BUT_L_PIN); + + if (g_LCDML_CONTROL_Encoder_position <= -3) { + if (!button_l) + { + LCDML_Voice.BT_left(); + g_LCDML_CONTROL_button_prev[ENC_L] = LOW; + g_LCDML_CONTROL_button_press_time[ENC_L] = -1; + } + else + { + LCDML_Voice.BT_down(); + } + ENCODER[ENC_L].write(g_LCDML_CONTROL_Encoder_position + 4); + } + else if (g_LCDML_CONTROL_Encoder_position >= 3) + { + if (!button_l) + { + LCDML_Voice.BT_right(); + g_LCDML_CONTROL_button_prev[ENC_L] = LOW; + g_LCDML_CONTROL_button_press_time[ENC_L] = -1; + } + else + { + LCDML_Voice.BT_up(); + } + ENCODER[ENC_L].write(g_LCDML_CONTROL_Encoder_position - 4); + } + else + { + if (!button_l && g_LCDML_CONTROL_button_prev[ENC_L]) //falling edge, button_l pressed + { + g_LCDML_CONTROL_button_prev[ENC_L] = LOW; + g_LCDML_CONTROL_button_press_time[ENC_L] = millis(); + } + else if (button_l && !g_LCDML_CONTROL_button_prev[ENC_L]) //rising edge, button_l not active + { + g_LCDML_CONTROL_button_prev[ENC_L] = HIGH; + + if (g_LCDML_CONTROL_button_press_time[ENC_L] < 0) + { + g_LCDML_CONTROL_button_press_time[ENC_L] = millis(); + //Reset for left right action + } + else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_L]) >= g_LCDML_CONTROL_button_long_press) + { + LCDML_Voice.BT_quit(); + } + else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_L]) >= g_LCDML_CONTROL_button_short_press) + { + Serial.println("------------------------------------------------->LLLLLLLLLLLLLLLLLLLLLLLLLLLLL"); + LCDML_Voice.BT_enter(); + } + } + } +} + /*********************************************************************** DISPLAY ***********************************************************************/ @@ -313,6 +387,116 @@ void lcdml_menu_display(void) } } +void lcdml_voice_menu_display(void) +{ + // update content + // *************** + if (LCDML_Voice.DISP_checkMenuUpdate()) { + // clear menu + // *************** + LCDML_Voice.DISP_clear(); + + // declaration of some variables + // *************** + // content variable + char content_text[_LCDML_DISP_cols]; // save the content text of every menu element + // menu element object + LCDMenuLib2_menu *tmp; + // some limit values + uint8_t i = LCDML_Voice.MENU_getScroll(); + uint8_t maxi = _LCDML_DISP_rows + i; + uint8_t n = 0; + + // check if this element has children + if ((tmp = LCDML_Voice.MENU_getDisplayedObj()) != NULL) + { + // loop to display lines + do + { + // check if a menu element has a condition and if the condition be true + if (tmp->checkCondition()) + { + // check the type off a menu element + if (tmp->checkType_menu() == true) + { + // display normal content + LCDML_getContent(content_text, tmp->getID()); + lcd.setCursor(1, n); + lcd.print(content_text); + } + else + { + if (tmp->checkType_dynParam()) { + tmp->callback(n); + } + } + // increment some values + i++; + n++; + } + // try to go to the next sibling and check the number of displayed rows + } while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi)); + } + } + + if (LCDML_Voice.DISP_checkMenuCursorUpdate()) + { + // init vars + uint8_t n_max = (LCDML_Voice.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML_Voice.MENU_getChilds()); + uint8_t scrollbar_min = 0; + uint8_t scrollbar_max = LCDML_Voice.MENU_getChilds(); + uint8_t scrollbar_cur_pos = LCDML_Voice.MENU_getCursorPosAbs(); + uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos); + + + // display rows + for (uint8_t n = 0; n < n_max; n++) + { + //set cursor + lcd.setCursor(0, n); + + //set cursor char + if (n == LCDML_Voice.MENU_getCursorPos()) { + lcd.write(_LCDML_DISP_cfg_cursor); + } else { + lcd.write(' '); + } + + // delete or reset scrollbar + if (_LCDML_DISP_cfg_scrollbar == 1) { + if (scrollbar_max > n_max) { + lcd.setCursor((_LCDML_DISP_cols - 1), n); + lcd.write((uint8_t)0); + } + else { + lcd.setCursor((_LCDML_DISP_cols - 1), n); + lcd.print(' '); + } + } + } + + // display scrollbar + if (_LCDML_DISP_cfg_scrollbar == 1) { + if (scrollbar_max > n_max) { + //set scroll position + if (scrollbar_cur_pos == scrollbar_min) { + // min pos + lcd.setCursor((_LCDML_DISP_cols - 1), 0); + lcd.write((uint8_t)1); + } else if (scrollbar_cur_pos == (scrollbar_max - 1)) { + // max pos + lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1)); + lcd.write((uint8_t)4); + } else { + // between + lcd.setCursor((_LCDML_DISP_cols - 1), scroll_pos / n_max); + lcd.write((uint8_t)(scroll_pos % n_max) + 1); + } + } + } + } +} + /*********************************************************************** MENU ***********************************************************************/ diff --git a/config.h b/config.h index 8e7412a..a109732 100644 --- a/config.h +++ b/config.h @@ -130,7 +130,6 @@ #define SDCARD_SCK_PIN 13 // not actually used // Encoder with button -#define ENC_VOL_STEPS 43 #define ENC_FILTER_RES_STEPS 100 #define ENC_FILTER_CUT_STEPS 100 #define ENC_DELAY_TIME_STEPS 50 @@ -140,11 +139,9 @@ #define ENC_L_PIN_A 3 #define ENC_L_PIN_B 2 #define BUT_L_PIN 4 -#define INITIAL_ENC_L_VALUE 0 #define ENC_R_PIN_A 28 #define ENC_R_PIN_B 29 #define BUT_R_PIN 30 -#define INITIAL_ENC_R_VALUE 0 #define BUT_DEBOUNCE_MS 20 #define LONG_BUTTON_PRESS 500