/*
MUIInputVersatileRotaryEncoder.ino
MUI: https://github.com/olikraus/u8g2/wiki/muimanual
U8g2 Menu with Rotary Encoder (Versatile_RotaryEncoder library).
Short Button Press: Switch between field movement and data increment/decrement
Long Button Press: Return to main menu
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2022, [email protected]
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <Arduino.h>
#include <Wire.h>
#include <U8g2lib.h>
#include <MUIU8g2.h>
#include <Versatile_RotaryEncoder.h>
#include <ResponsiveAnalogRead.h>
// Set here your encoder reading pins
#define clk 2
#define dt 3
#define sw 4
// Create encoder object
Versatile_RotaryEncoder versatile_encoder(clk, dt, sw);
ResponsiveAnalogRead pot_ch1(A6, true);
ResponsiveAnalogRead pot_ch2(A7, true);
#define ICEPOWER_700AS1_OVERCURRENTMONITOR_PIN 12
#define ICEPOWER_700AS1_THERMALSHUTDOWN_PIN 11
#define ICEPOWER_700AS1_TEMPERATUREMONITOR_PIN A3 //3.3V -> 25~35℃ ~ 0.3V -> 120~130℃
struct ICEPOWER700AS1 {
bool isOC;
bool isTS;
uint16_t temperature;
};
ICEPOWER700AS1 poweramp;
// NJU72341
// Preamp config
struct ChannelConfig {
uint16_t vol_a_gain_idx;
uint16_t zerocross_idx;
uint16_t vol_b_idx;
};
// ChannelConfig cnf_ch1;
// ChannelConfig cnf_ch2;
struct NJU72341 {
ChannelConfig cnf_ch1;
ChannelConfig cnf_ch2;
};
NJU72341 preamp;
NJU72341 preamp_prev;
// #define PREAMP_I2C_ADDRESS 0x88
#define PREAMP_I2C_ADDRESS 0x44
// Please UNCOMMENT one of the contructor lines below
// U8g2 Contructor List (Picture Loop Page 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_NULL u8g2(U8G2_R0); // null device, a 8x8 pixel display which does nothing
//U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 12, /* dc=*/ 4, /* reset=*/ 6); // Arduboy (Production, Kickstarter Edition)
//U8G2_SSD1306_128X64_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_1_3W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_1_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 8);
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// U8G2_SSD1306_128X64_NONAME_1_2ND_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SSD1306_128X64_ALT0_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // same as the NONAME variant, but may solve the "every 2nd line skipped" problem
//U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* reset=*/ 8);
// U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
// U8G2_SSD1306_128X64_NONAME_2_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
// U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
//U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 16, /* data=*/ 17, /* reset=*/ U8X8_PIN_NONE); // ESP32 Thing, pure SW emulated I2C
//U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 16, /* data=*/ 17); // ESP32 Thing, HW I2C with pin remapping
//U8G2_SSD1306_128X64_NONAME_1_6800 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_1_8080 u8g2(U8G2_R0, 13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8);
//U8G2_SSD1306_128X64_VCOMH0_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but maximizes setContrast() range
//U8G2_SSD1306_128X64_ALT0_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but may solve the "every 2nd line skipped" problem
//U8G2_SSD1306_102X64_EA_OLEDS102_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); // same as the NONAME variant, but may solve the "every 2nd line skipped" problem
// End of constructor list
MUIU8G2 mui;
/*
global variables which form the communication gateway between the user interface and the rest of the code
*/
// global variables for menu redraw and input event handling
uint8_t is_redraw = 1;
uint8_t rotate_event = 0; // 0 = not turning, 1 = CW, 2 = CCW
uint8_t press_event = 0; // 0 = not pushed, 1 = pushed
uint8_t long_press_event = 0; // 0 = not pushed, 1 = pushed
uint8_t num_value = 0;
uint8_t bar_value = 0;
uint16_t animal_idx = 0;
/**
* list of volume A Gains
*/
const char *vol_a_gains[] = { "0", "+3", "+6", "+9" };
uint16_t vol_a_gain_list_get_cnt(void *data) {
return sizeof(vol_a_gains)/sizeof(*vol_a_gains); /* number of vol_a_gains */
}
const char *vol_a_gain_list_get_str(void *data, uint16_t index) {
return vol_a_gains[index];
}
/**
* list of OffOns
*/
const char *offons[] = { "OFF", "ON" };
uint16_t offon_list_get_cnt(void *data) {
return sizeof(offons)/sizeof(*offons); /* number of offons */
}
const char *offon_list_get_str(void *data, uint16_t index) {
return offons[index];
}
/**
* list of Volume B
*/
const char *vol_b[] = { "MUTE", "-95", "-94", "-93", "-92", "-91", "-90",
"-89", "-88", "-87", "-86", "-85", "-84", "-83", "-82", "-81", "-80",
"-79", "-78", "-77", "-76", "-75", "-74", "-73", "-72", "-71", "-70",
"-69", "-68", "-67", "-66", "-65", "-64", "-63", "-62", "-61", "-60",
"-59", "-58", "-57", "-56", "-55", "-54", "-53", "-52", "-51", "-50",
"-49", "-48", "-47", "-46", "-45", "-44", "-43", "-42", "-41", "-40",
"-39", "-38", "-37", "-36", "-35", "-34", "-33", "-32", "-31", "-30",
"-29", "-28", "-27", "-26", "-25", "-24", "-23", "-22", "-21", "-20",
"-19", "-18", "-17", "-16", "-15", "-14", "-13", "-12", "-11", "-10",
"-9", "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1", "0",};
uint16_t vol_b_list_get_cnt(void *data) {
return sizeof(vol_b)/sizeof(*vol_b); /* number of vol_b */
}
const char *vol_b_list_get_str(void *data, uint16_t index) {
return vol_b[index];
}
uint8_t mui_hrule(mui_t *ui, uint8_t msg) {
if ( msg == MUIF_MSG_DRAW ) {
u8g2.drawHLine(0, mui_get_y(ui), u8g2.getDisplayWidth());
}
return 0;
}
uint8_t show_power_status(mui_t *ui, uint8_t msg) {
if ( msg == MUIF_MSG_DRAW ) {
u8g2_uint_t x = mui_get_x(ui);
u8g2_uint_t y = mui_get_y(ui);
u8g2.setCursor(x+5, y);
u8g2.print("OverCurrent");
u8g2.setCursor(x+90, y);
u8g2.print(":");
const char strOC[8];
bool_to_str(poweramp.isOC, strOC);
u8g2.print(strOC);
u8g2.setCursor(x+5, y+12);
u8g2.print("ThermalShutDown");
u8g2.setCursor(x+90, y+12);
u8g2.print(":");
const char strTS[8];
bool_to_str(poweramp.isTS, strTS);
u8g2.print(strTS);
u8g2.setCursor(x+5, y+24);
u8g2.print("Temperature");
u8g2.setCursor(x+90, y+24);
u8g2.print(":");
u8g2.print(poweramp.temperature);
is_redraw = 1;
}
return 0;
}
void bool_to_str(bool data, char * ret) {
if (data) {
strlcpy(ret, "Normal", sizeof("Normal"));
} else {
strlcpy(ret, "Error", sizeof("Error"));
}
return;
}
muif_t muif_list[] = {
MUIF_U8G2_FONT_STYLE(0, u8g2_font_helvR08_tr), /* regular font */
MUIF_U8G2_FONT_STYLE(1, u8g2_font_helvB08_tr), /* bold font */
MUIF_RO("HR", mui_hrule),
MUIF_U8G2_LABEL(),
MUIF_RO("GP",mui_u8g2_goto_data),
MUIF_BUTTON("GC", mui_u8g2_goto_form_w1_pi),
// ChannelConfig
MUIF_U8G2_U16_LIST("1A", &preamp.cnf_ch1.vol_a_gain_idx, NULL, vol_a_gain_list_get_str, vol_a_gain_list_get_cnt, mui_u8g2_u16_list_line_wa_mud_pi),
MUIF_U8G2_U16_LIST("2A", &preamp.cnf_ch2.vol_a_gain_idx, NULL, vol_a_gain_list_get_str, vol_a_gain_list_get_cnt, mui_u8g2_u16_list_line_wa_mud_pi),
MUIF_U8G2_U16_LIST("1Z", &preamp.cnf_ch1.zerocross_idx, NULL, offon_list_get_str, offon_list_get_cnt, mui_u8g2_u16_list_line_wa_mud_pi),
MUIF_U8G2_U16_LIST("2Z", &preamp.cnf_ch2.zerocross_idx, NULL, offon_list_get_str, offon_list_get_cnt, mui_u8g2_u16_list_line_wa_mud_pi),
MUIF_U8G2_U16_LIST("1B", &preamp.cnf_ch1.vol_b_idx, NULL, vol_b_list_get_str, vol_b_list_get_cnt, mui_u8g2_u16_list_line_wa_mud_pi),
MUIF_U8G2_U16_LIST("2B", &preamp.cnf_ch2.vol_b_idx, NULL, vol_b_list_get_str, vol_b_list_get_cnt, mui_u8g2_u16_list_line_wa_mud_pi),
/* register custom function to show the data */
MUIF_RO("SH", show_power_status),
/* a button for the menu... */
//MUIF_BUTTON("GO", mui_u8g2_btn_goto_wm_fi)
MUIF_EXECUTE_ON_SELECT_BUTTON("GO", mui_u8g2_btn_goto_wm_fi),
MUIF_BUTTON("B0", mui_u8g2_btn_exit_wm_fi),
MUIF_BUTTON("XX", mui_u8g2_btn_exit_wm_fi)
};
fds_t fds_data[] =
// ROOT
MUI_FORM(1)
MUI_STYLE(1)
MUI_LABEL(5, 8, "CONFIGURATION")
MUI_STYLE(0)
MUI_XY("HR", 0,11)
MUI_DATA("GP",
MUI_11 "Power Status|"
MUI_21 "Pre Channe l|"
MUI_22 "Pre Channe 2")
MUI_XYA("GC", 5, 24, 0)
MUI_XYA("GC", 5, 36, 1)
MUI_XYA("GC", 5, 48, 2)
MUI_XYT("B0", 114, 60, " Ok ")
MUI_FORM(11)
MUI_STYLE(1)
MUI_LABEL(5, 8, "Power Status")
MUI_XY("HR", 0,11)
MUI_STYLE(0)
MUI_XY("SH", 0, 23)
MUI_XYAT("GO", 114, 60, 1, " Ok ")
MUI_FORM(21)
MUI_STYLE(1)
MUI_LABEL(5, 8, "Pre Channel 1")
MUI_XY("HR", 0,11)
MUI_STYLE(0)
MUI_LABEL(5,23, "Volume A (Gain)")
MUI_LABEL(5,35, "ZeroCross")
MUI_LABEL(5,47, "Volume B")
MUI_LABEL(85,23, ":")
MUI_LABEL(85,35, ":")
MUI_LABEL(85,47, ":")
MUI_XY("1A", 90, 23)
MUI_XY("1Z", 90, 35)
MUI_XY("1B", 90, 47)
MUI_XYAT("GO", 114, 60, 1, " Ok ")
MUI_FORM(22)
MUI_STYLE(1)
MUI_LABEL(5, 8, "Pre Channel 2")
MUI_XY("HR", 0,11)
MUI_STYLE(0)
MUI_LABEL(5,23, "Volume A (Gain)")
MUI_LABEL(5,35, "ZeroCross")
MUI_LABEL(5,47, "Volume B")
MUI_LABEL(85,23, ":")
MUI_LABEL(85,35, ":")
MUI_LABEL(85,47, ":")
MUI_XY("2A", 90, 23)
MUI_XY("2Z", 90, 35)
MUI_XY("2B", 90, 47)
MUI_XYAT("GO", 114, 60, 1, " Ok ")
;
// Functions prototyping to be handled on each Encoder Event
void handleRotate(int8_t rotation) {
if ( rotation > 0 ) {
Serial.println("rotate CW");
rotate_event = 2; // CW
} else {
Serial.println("rotate CCW");
rotate_event = 1; // CCW
}
}
void handlePressRelease() {
Serial.println("press release");
press_event = 1;
}
void handleLongPressRelease() {
Serial.println("long press release");
long_press_event = 1;
}
void handleLongPress() {
Serial.println("long press");
long_press_event = 1;
}
void setup(void) {
Serial.begin(9600);
// Serial.begin(115200);
// Load to the encoder all nedded handle functions here (up to 9 functions)
versatile_encoder.setHandleRotate(handleRotate);
versatile_encoder.setHandlePressRelease(handlePressRelease);
// versatile_encoder.setHandleLongPressRelease(handleLongPressRelease);
versatile_encoder.setHandleLongPress(handleLongPress);
// Start I2C
Wire.begin();
// oled
// u8g2.begin();
// mui.begin(u8g2, fds_data, muif_list, sizeof(muif_list)/sizeof(muif_t));
}
void detect_events(void) {
versatile_encoder.ReadEncoder();
pot_ch1.update();
pot_ch2.update();
}
void handle_events(void) {
// 0 = not pushed, 1 = pushed
if ( press_event == 1 ) {
mui.sendSelect();
is_redraw = 1;
press_event = 0;
}
// 0 = not pushed, 1 = pushed
if ( long_press_event == 1 ) {
if ( mui.isFormActive() ) {
} else {
mui.gotoForm(/* form_id= */ 1, /* initial_cursor_position= */ 0);
}
is_redraw = 1;
// mui.sendSelectWithExecuteOnSelectFieldSearch();
long_press_event = 0;
}
// 0 = not turning, 1 = CW, 2 = CCW
if ( rotate_event == 1 ) {
mui.nextField();
is_redraw = 1;
rotate_event = 0;
}
if ( rotate_event == 2 ) {
mui.prevField();
is_redraw = 1;
rotate_event = 0;
}
// channel 1
if (pot_ch1.hasChanged()) {
// Serial.println("pot_ch1.hasChanged");
int ch1_vol_b_wk = map(pot_ch1.getValue(), 0, 1023, 0, (sizeof(vol_b)/sizeof(*vol_b) -1));
if (preamp.cnf_ch1.vol_b_idx != ch1_vol_b_wk) {
// Serial.println(sizeof(vol_b)/sizeof(*vol_b));
preamp.cnf_ch1.vol_b_idx = ch1_vol_b_wk;
// set_preamp();
is_redraw = 1;
}
}
// channel 2
if (pot_ch2.hasChanged()) {
// Serial.println("pot_ch2.hasChanged");
int ch2_vol_b_wk = map(pot_ch2.getValue(), 0, 1023, 0, (sizeof(vol_b)/sizeof(*vol_b) -1));
if (preamp.cnf_ch2.vol_b_idx != ch2_vol_b_wk) {
// Serial.println(sizeof(vol_b)/sizeof(*vol_b));
preamp.cnf_ch2.vol_b_idx = ch2_vol_b_wk;
is_redraw = 1;
}
}
// Over Current Monitor Pin
if (digitalRead(ICEPOWER_700AS1_OVERCURRENTMONITOR_PIN) == LOW) {
// Serial.println("power Over Current !");
if (poweramp.isOC == true) {
// true -> false changed
// Serial.println("ICEPOWER_700AS1_OVERCURRENTMONITOR_PIN true -> false");
is_redraw = 1;
}
poweramp.isOC = false;
} else {
if (poweramp.isOC == false) {
// false -> true changed
// Serial.println("ICEPOWER_700AS1_OVERCURRENTMONITOR_PIN false -> true");
is_redraw = 1;
}
poweramp.isOC = true;
}
// Thermal Shutdown Pin
if (digitalRead(ICEPOWER_700AS1_THERMALSHUTDOWN_PIN) == LOW) {
// Serial.println("Thermal Shutdown !");
if (poweramp.isTS == true) {
// true -> false changed
// Serial.println("ICEPOWER_700AS1_THERMALSHUTDOWN_PIN true -> false");
is_redraw = 1;
}
poweramp.isTS = false;
} else {
if (poweramp.isTS == false) {
// false -> true changed
// Serial.println("ICEPOWER_700AS1_THERMALSHUTDOWN_PIN false -> true");
is_redraw = 1;
}
poweramp.isTS = true;
}
// Temperature Monitor Pin
int read_wk = analogRead(ICEPOWER_700AS1_TEMPERATUREMONITOR_PIN);
float volt_f_wk = read_wk * 5.0 / 1023.0;
uint16_t temp_wk = calc_temperature(volt_f_wk);
if (poweramp.temperature != temp_wk) {
poweramp.temperature = calc_temperature(volt_f_wk);
is_redraw = 1;
}
if (memcmp(&preamp, &preamp_prev, sizeof(NJU72341)) == 0) {
// 一致
// nothing
} else {
// 不一致
set_preamp();
memcpy(&preamp_prev, &preamp, sizeof(NJU72341));
}
}
uint16_t calc_temperature(double volt) {
uint16_t ans = 0;
// 3.3V -> 35℃
// 0.3V -> 130℃
// x : 温度
// y : 電圧
// x = -(95/3)y + (1395/10)
ans = (uint16_t)( ( -(95.0/3.0) * volt) + (1395.0/10.0));
// Serial.print("volt : ");
// Serial.print(volt);
// Serial.print("\t temp : ");
// Serial.println(ans);
return ans;
}
void set_preamp(void) {
byte work = 0b00000000;
// vol a setting
byte vol_a = 0b00000000;
byte ch1_vol_a = 0b00000000;
byte ch2_vol_a = 0b00000000;
// TODO
// cnf_ch1.vol_a_gain_idx = 3;
// cnf_ch2.vol_a_gain_idx = 3;
switch (preamp.cnf_ch1.vol_a_gain_idx) {
case 0:
// +0
// D1 D0
// 0 0
ch1_vol_a = 0b00000000;
break;
case 1:
// +3
// D1 D0
// 0 1
ch1_vol_a = 0b00000001;
break;
case 2:
// +6
// D1 D0
// 1 0
ch1_vol_a = 0b00000010;
break;
case 3:
// +9
// D1 D0
// 1 1
ch1_vol_a = 0b00000011;
break;
default:
break;
}
switch (preamp.cnf_ch2.vol_a_gain_idx) {
case 0:
// +0
// D3 D2
// 0 0
ch2_vol_a = 0b00000000;
break;
case 1:
// +3
// D3 D2
// 0 1
ch2_vol_a = 0b00000100;
break;
case 2:
// +6
// D3 D2
// 1 0
ch2_vol_a = 0b00001000;
break;
case 3:
// +9
// D3 D2
// 1 1
ch2_vol_a = 0b00001100;
break;
default:
break;
}
vol_a = vol_a | ch1_vol_a | ch2_vol_a;
// select address 00H
Wire.beginTransmission(PREAMP_I2C_ADDRESS);
Wire.write(0x00); // regist address
Wire.write(vol_a); // vol_a
Wire.endTransmission();
// vol b setting
byte vol_1b = 0b00000000;
byte vol_2b = 0b00000000;
byte vol_1_zerocross = byte(preamp.cnf_ch1.zerocross_idx);
byte vol_2_zerocross = byte(preamp.cnf_ch2.zerocross_idx);
vol_1b = byte(preamp.cnf_ch1.vol_b_idx + 23);
bitWrite(vol_1b, 7, preamp.cnf_ch1.zerocross_idx);
vol_2b = byte(preamp.cnf_ch2.vol_b_idx + 23);
bitWrite(vol_2b, 7, preamp.cnf_ch2.zerocross_idx);
// select address 01H
Wire.beginTransmission(PREAMP_I2C_ADDRESS);
Wire.write(0x01); // regist address
Wire.write(vol_1b); // vol_1b
Wire.endTransmission();
// select address 01H
Wire.beginTransmission(PREAMP_I2C_ADDRESS);
Wire.write(0x02); // regist address
Wire.write(vol_2b); // vol_2b
Wire.endTransmission();
}
void loop(void) {
// /* check whether the menu is active */
// if ( mui.isFormActive() ) {
// /* update the display content, if the redraw flag is set */
// if ( is_redraw ) {
// u8g2.firstPage();
// do {
// detect_events();
// mui.draw();
// detect_events();
// } while( u8g2.nextPage() );
// is_redraw = 0; /* clear the redraw flag */
// }
// detect_events();
// handle_events();
// } else {
// /* menu not active: show something else */
// u8g2.firstPage();
// do {
// detect_events();
// u8g2.setCursor(0,20);
// u8g2.print(millis());
// detect_events();
// } while( u8g2.nextPage() );
// detect_events();
// handle_events();
// } /* mui.isFormActive() */
detect_events();
handle_events();
} /* loop */
ch1.vol_b
ch2.vol_b