#include <Arduino.h>
#include <GyverOLED.h>
GyverOLED<SSD1306_128x64, OLED_BUFFER> oled;
/////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// EncButton /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// Начальные установки
//#include <Arduino.h>
// #define EB_NO_FOR // отключить поддержку pressFor/holdFor/stepFor и счётчик степов (экономит 2 байта оперативки)
// #define EB_NO_CALLBACK // отключить обработчик событий attach (экономит 2 байта оперативки)
// #define EB_NO_COUNTER // отключить счётчик энкодера (экономит 4 байта оперативки)
// #define EB_NO_BUFFER // отключить буферизацию энкодера (экономит 1 байт оперативки)
#define EB_DEB_TIME 50 // таймаут гашения дребезга кнопки (кнопка)
#define EB_CLICK_TIME 500 // таймаут ожидания кликов (кнопка)
#define EB_HOLD_TIME 600 // таймаут удержания (кнопка)
#define EB_STEP_TIME 200 // таймаут импульсного удержания (кнопка)
#define EB_FAST_TIME 60 // таймаут быстрого поворота (энкодер) .// 30
#define EB_TOUT_TIME 1000 // таймаут действия (кнопка и энкодер)
#include <EncButton.h>
#define EncButton_Pin_CLK 35
#define EncButton_Pin_DT 32
#define EncButton_Pin_SW 33
//EncButton eb(EncButton_Pin_CLK, EncButton_Pin_DT, EncButton_Pin_SW); //eb(2, 3, 4); // CLK, DT, SW // Энкодер с кнопкой <A, B, KEY>
EncButton eb(EncButton_Pin_DT, EncButton_Pin_CLK, EncButton_Pin_SW, INPUT); //eb(2, 3, 4); // CLK, DT, SW // Энкодер с кнопкой <A, B, KEY>
// EncButton eb(2, 3, 4, INPUT); // + режим пинов энкодера
// EncButton eb(2, 3, 4, INPUT, INPUT_PULLUP); // + режим пинов кнопки
class uButton {
public:
uButton(uint8_t pin) : pin(pin) {
pinMode(pin, INPUT_PULLUP);
}
operator bool() {
if (f != !digitalRead(pin)) {
f ^= 1;
delay(10);
if (f) return true;
}
return false;
}
private:
uint8_t pin;
bool f = 0;
};
uButton center(12);
uButton left(25);
uButton right(26);
uButton up(27);
uButton down(14);
// #define GM_NO_PAGES
#include <GyverMenu.h>
GyverMenu menu(20, 4);
int GMenuX = 0;
int GMenuY = 16;
int GMenuW = 127;
int GMenuH = 32; // 4 * 8
int GMenuScale = 1;
int SMenuScale = 8;
bool sw1, sw2, sw3, sw4, sw5;
uint8_t sldr1, sldr2, sldr3, sldr4, sldr5;
bool sw;
uint8_t sel;
int vali;
float valf;
bool btns, lbls;
uint8_t tab;
int val;
//bool sw;
#define V_memory_count 128 // the size of V memory. You can change it to a number <=255)
float V[V_memory_count]; // This array is synchronized with Virtuino V memory. You can change the type to int, long etc.
bool MySlider0(gm::Builder& b, const char* label, uint8_t maxv, uint8_t* var) {
if (!b.beginWidget()) return false;
bool changed = false;
bool render = false;
switch (b.getAction()) {
case gm::Builder::Action::Refresh:
render = true;
break;
case gm::Builder::Action::Set:
b.menu.toggle();
render = changed = true;
break;
case gm::Builder::Action::SetUp:
case gm::Builder::Action::Right:
if (*var < maxv) {
++*var;
b.change();
render = changed = true;
}
break;
case gm::Builder::Action::SetDown:
case gm::Builder::Action::Left:
if (*var) {
--*var;
b.change();
render = changed = true;
}
break;
default: break;
}
if (render && b.beginRender()) {
oled.rect(8, b.menu.currentRow() * 16, 127, (b.menu.currentRow() + 1) * 16 - 1, OLED_CLEAR);
oled.setCursor(12, b.menu.currentRow() * 2);
oled.print(label);
if (b.menu.isActive()) oled.print(':');
oled.roundRect(127 - 50, b.menu.currentRow() * 16, 127, b.menu.currentRow() * 16 + 15, OLED_STROKE);
oled.roundRect(127 - 50, b.menu.currentRow() * 16, 127 - 50 + map(*var, 0, maxv, 5, 50), b.menu.currentRow() * 16 + 15, OLED_FILL);
}
return changed;
}
bool MySwitch0(gm::Builder& b, const char* label, bool* var) {
if (!b.beginWidget()) return false;
bool changed = false;
bool render = false;
switch (b.getAction()) {
case gm::Builder::Action::Refresh:
render = true;
break;
case gm::Builder::Action::Set:
*var = !*var;
render = changed = true;
b.change();
break;
case gm::Builder::Action::SetUp:
case gm::Builder::Action::Right:
if (!*var) {
*var = true;
render = changed = true;
b.change();
}
break;
case gm::Builder::Action::SetDown:
case gm::Builder::Action::Left:
if (*var) {
*var = false;
render = changed = true;
b.change();
}
break;
default: break;
}
if (render && b.beginRender()) {
oled.rect(8, b.menu.currentRow() * 16, 127, (b.menu.currentRow() + 1) * 16 - 1, OLED_CLEAR);
oled.setCursor(12, b.menu.currentRow() * 2);
oled.print(label);
oled.roundRect(127 - 10, b.menu.currentRow() * 16 + 2, 127, b.menu.currentRow() * 16 + 2 + 10, OLED_CLEAR);
oled.roundRect(127 - 10, b.menu.currentRow() * 16 + 2, 127, b.menu.currentRow() * 16 + 2 + 10, *var ? OLED_FILL : OLED_STROKE);
}
return changed;
}
bool MySwitch(gm::Builder& b, const char* label, bool* var, void (*cb)(bool v) = nullptr) {
if (!b.beginWidget()) return false;
bool changed = false;
bool render = false;
switch (b.getAction()) {
case gm::Builder::Action::Refresh:
render = true;
break;
case gm::Builder::Action::Set:
*var = !*var;
render = changed = true;
b.change();
break;
case gm::Builder::Action::SetUp:
case gm::Builder::Action::Right:
if (!*var) {
*var = true;
render = changed = true;
b.change();
}
break;
case gm::Builder::Action::SetDown:
case gm::Builder::Action::Left:
if (*var) {
*var = false;
render = changed = true;
b.change();
}
break;
default: break;
}
if (changed && cb) cb(*var);
if (render && b.beginRender()) {
//menu.print(label);
//menu.pad(menu.left - 3);
//menu.print(*var ? "[x]" : "[ ]", 3);
//oled.rect(8, b.menu.currentRow() * 8, 127, (b.menu.currentRow() + 1) * 8 - 1, OLED_CLEAR);
oled.rect(GMenuX, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)), GMenuW, GMenuY + ((b.menu.currentRow() + 1) * (GMenuScale * SMenuScale) - 1), OLED_CLEAR);
oled.setScale(GMenuScale);
//oled.setCursor(12, b.menu.currentRow() * 1);
//oled.setCursor(GMenuX, (GMenuY / 8) + (b.menu.currentRow() * GMenuScale));
oled.setCursorXY(GMenuX, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)));
oled.print(label);
//oled.print(*var ? "[x]" : "[ ]", 3);
oled.setCursorXY(GMenuX + (GMenuW - 24), GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)));
oled.print(String(*var ? "[x]" : "[ ]").c_str());
//oled.roundRect(GMenuX + (GMenuW - 5), GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale) + 2), GMenuX + GMenuW, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale) + 2 + 5), OLED_CLEAR);
//oled.roundRect(GMenuX + (GMenuW - 5), GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale) + 2), GMenuX + GMenuW, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale) + 2 + 5), *var ? OLED_FILL : OLED_STROKE);
}
return changed;
}
bool MySelect(gm::Builder& b, const char* label, uint8_t* var, const char* opts, void (*cb)(uint8_t n, const char* str, uint8_t len) = nullptr) {
if (!b.beginWidget()) return false;
bool changed = false;
bool render = false;
switch (b.getAction()) {
case gm::Builder::Action::Refresh:
render = true;
break;
case gm::Builder::Action::Set:
b.menu.toggle();
render = true;
break;
case gm::Builder::Action::SetUp:
case gm::Builder::Action::Right:
if (*var < mutil::countSub(opts, ';') - 1) {
++*var;
render = changed = true;
b.change();
}
break;
case gm::Builder::Action::SetDown:
case gm::Builder::Action::Left:
if (*var) {
--*var;
render = changed = true;
b.change();
}
break;
default: break;
}
if (changed && cb) {
const char* start;
uint8_t slen = mutil::getSub(opts, ';', *var, &start);
cb(*var, start, slen);
}
if (render && b.beginRender(var)) {
const char* start;
uint8_t len = mutil::getSub(opts, ';', *var, &start);
uint8_t letters;
mutil::strlenU(start, &letters, len);
oled.rect(GMenuX, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)), GMenuW, GMenuY + ((b.menu.currentRow() + 1) * (GMenuScale * SMenuScale) - 1), OLED_CLEAR);
oled.setScale(GMenuScale);
oled.setCursorXY(GMenuX, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)));
oled.print(label);
if (b.menu.isActive()) oled.print(':');
//b.menu.pad(b.menu.left - (letters + 2));
//menu.print('<');
//menu.print(start, len, letters);
//menu.print('>');
oled.setCursorXY(GMenuX + 60, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)));
oled.print('<');
b.menu.print(start, len, letters);
oled.print('>');
}
return changed;
}
bool MyTabs(gm::Builder& b, uint8_t* var, const char* tabs, void (*cb)(uint8_t n, const char* str, uint8_t len) = nullptr) {
if (!b.beginWidget()) return false;
bool changed = false;
bool render = false;
switch (b.getAction()) {
case gm::Builder::Action::Refresh:
render = true;
break;
case gm::Builder::Action::Set:
b.menu.toggle();
render = true;
break;
case gm::Builder::Action::SetUp:
case gm::Builder::Action::Right:
if (*var < mutil::countSub(tabs, ';') - 1) {
++*var;
render = changed = true;
b.change();
}
break;
case gm::Builder::Action::SetDown:
case gm::Builder::Action::Left:
if (*var) {
--*var;
render = changed = true;
b.change();
}
break;
default: break;
}
if (changed && cb) {
const char* start;
uint8_t slen = mutil::getSub(tabs, ';', *var, &start);
cb(*var, start, slen);
}
if (render && b.beginRender(var)) {
const char* start;
uint8_t slen = mutil::getSub(tabs, ';', *var, &start);
int16_t start_i = (b.menu.left / 2) - ((start - tabs) + slen / 2);
int16_t len = strlen(tabs);
int8_t i = 0;
while (b.menu.left) { //////
if (i >= start_i && i <= start_i + len) {
const char* t = tabs + i - start_i;
//if (t == start) menu.print(menu.isActive() ? '<' : '[');
//else if (t == start + slen) menu.print(menu.isActive() ? '>' : ']');
//menu.print((!*t || *t == ';') ? ' ' : *t);
//oled.rect(GMenuX, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)), GMenuW, GMenuY + ((b.menu.currentRow() + 1) * (GMenuScale * SMenuScale) - 1), OLED_CLEAR);
oled.setScale(GMenuScale);
//oled.setCursorXY(GMenuX, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)));
//if (t == start) oled.print(b.menu.isActive() ? '<' : '[');
//else if (t == start + slen) oled.print(b.menu.isActive() ? '>' : ']');
if (t == start) b.menu.print(b.menu.isActive() ? '<' : '[');
else if (t == start + slen) b.menu.print(b.menu.isActive() ? '>' : ']');
//oled.print((!*t || *t == ';') ? ' ' : *t);
b.menu.print((!*t || *t == ';') ? ' ' : *t);
} else {
//oled.rect(GMenuX, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)), GMenuW, GMenuY + ((b.menu.currentRow() + 1) * (GMenuScale * SMenuScale) - 1), OLED_CLEAR);
oled.setScale(GMenuScale);
//oled.setCursorXY(GMenuX, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)));
//oled.print(' ');
b.menu.print(' ');
}
i++;
}
}
return changed;
}
// =================== VALUE_INT ===================
//template <typename T>
//bool MyValueInt(gm::Builder& b, const char* label, T* var, T minv, T maxv, T step, uint8_t base = 10, const char* unit = "", void (*cb)(T v) = nullptr) {
// return b.menu._value(label, var, minv, maxv, step, base, unit, cb);
//}
// =================== VALUE_FLOAT ===================
//bool MyValueFloat(gm::Builder& b, const char* label, float* var, float minv, float maxv, float step, uint8_t dec = 2, const char* unit = "", void (*cb)(float v) = nullptr) {
// return b.menu._value(label, var, minv, maxv, step, dec, unit, cb);
//}
bool MySlider(gm::Builder& b, const char* label, uint8_t maxv, uint8_t* var) {
if (!b.beginWidget()) return false;
bool changed = false;
bool render = false;
switch (b.getAction()) {
case gm::Builder::Action::Refresh:
render = true;
break;
case gm::Builder::Action::Set:
b.menu.toggle();
render = changed = true;
break;
case gm::Builder::Action::SetUp:
case gm::Builder::Action::Right:
if (*var < maxv) {
++*var;
b.change();
render = changed = true;
}
break;
case gm::Builder::Action::SetDown:
case gm::Builder::Action::Left:
if (*var) {
--*var;
b.change();
render = changed = true;
}
break;
default: break;
}
if (render && b.beginRender()) {
//oled.rect(8, b.menu.currentRow() * 16, 127, (b.menu.currentRow() + 1) * 16 - 1, OLED_CLEAR);
//oled.setCursor(12, b.menu.currentRow() * 2);
//oled.print(label);
//if (b.menu.isActive()) oled.print(':');
//oled.roundRect(127 - 50, b.menu.currentRow() * 16, 127, b.menu.currentRow() * 16 + 15, OLED_STROKE);
//oled.roundRect(127 - 50, b.menu.currentRow() * 16, 127 - 50 + map(*var, 0, maxv, 5, 50), b.menu.currentRow() * 16 + 15, OLED_FILL);
oled.rect(GMenuX, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)), GMenuW, GMenuY + ((b.menu.currentRow() + 1) * (GMenuScale * SMenuScale) - 1), OLED_CLEAR);
oled.setScale(GMenuScale);
oled.setCursorXY(GMenuX, GMenuY + (b.menu.currentRow() * (GMenuScale * SMenuScale)));
oled.print(label);
if (b.menu.isActive()) oled.print(':');
oled.roundRect(GMenuW - 60, GMenuY + (b.menu.currentRow() * SMenuScale), GMenuW - 8, GMenuY + (b.menu.currentRow() * SMenuScale + SMenuScale - 1), OLED_STROKE);
oled.roundRect(GMenuW - 60, GMenuY + (b.menu.currentRow() * SMenuScale), GMenuW - 60 + map(*var, 0, maxv, 5, 50) + 2, GMenuY + (b.menu.currentRow() * SMenuScale + SMenuScale - 1), OLED_FILL);
}
return changed;
}
void setup() {
Serial.begin(115200);
EncButton_setup();
GyverOLED_setup();
}
void loop() {
EncButton_loop();
GyverOLED_loop();
}
void GyverOLED_setup() {
oled.init();
//oled.setCursor(0, 2); // поставить курсор для символа столбец 0-127, строка 0-8(4)
//oled.setCursorXY(0, 16); // курсор в (пиксель X, пиксель Y) // поставить курсор для символа столбец 0-127, пиксель 0-63(31)
//oled.setScale(2);
//GyverOLED_Test_01_loop();
GyverOLED_Test_02_loop();
//GyverOLED_Menu_setup();
}
void GyverOLED_loop() {
//oled.home(); // курсор в 0,0
//oled.setCursor(0, 2); // поставить курсор для символа столбец 0-127, строка 0-8(4)
//oled.setCursorXY(0, 16); // курсор в (пиксель X, пиксель Y) // поставить курсор для символа столбец 0-127, пиксель 0-63(31)
//OLED_Interfeis_Download_loop();
//GyverOLED_Menu_loop();
delay(100);
}
void GyverOLED_Test_01_loop() {
oled.clear();
oled.setCursor(0, 2); // поставить курсор для символа столбец 0-127, строка 0-8(4)
//oled.setCursorXY(0, 0); // курсор в (пиксель X, пиксель Y) // поставить курсор для символа столбец 0-127, пиксель 0-63(31)
oled.setScale(1);
oled.invertText(false); // инвертируй текст! // true/false
oled.print("Поиск и подключение к");
oled.setScale(2);
oled.setCursor(30, 4); // поставить курсор для символа столбец 0-127, строка 0-8(4)
oled.print("Wi-Fi");
oled.update();
}
void GyverOLED_Test_02_loop() {
oled.clear();
oled.setScale(1);
oled.setCursor(0, 0); // поставить курсор для символа столбец 0-127, строка 0-8(4)
oled.print("Кнопка нажата при");
oled.setCursor(40, 1); // поставить курсор для символа столбец 0-127, строка 0-8(4)
oled.print("старте");
oled.setCursor(0, 2); // поставить курсор для символа столбец 0-127, строка 0-8(4)
//oled.setCursorXY(0, 0); // курсор в (пиксель X, пиксель Y) // поставить курсор для символа столбец 0-127, пиксель 0-63(31)
oled.setScale(1);
oled.invertText(false); // инвертируй текст! // true/false
//oled.print("Поиск и подключение к");
oled.print("Wi-Fi Подключен к ");
//oled.print("Wi-Fi Подключен к сети:");
oled.setCursor(0, 3); // поставить курсор для символа столбец 0-127, строка 0-8(4)
oled.print("сети:");
oled.setScale(1);
oled.setCursor(35, 3); // поставить курсор для символа столбец 0-127, строка 0-8(4)
oled.print("WiFi.SSID()");
oled.setScale(1);
oled.setCursor(0, 5); // поставить курсор для символа столбец 0-127, строка 0-8(4)
oled.print("Сила сигнала (RSSI): ");
oled.setScale(1);
oled.setCursor(35, 6); // поставить курсор для символа столбец 0-127, строка 0-8(4)
oled.print("WiFi.RSSI()");
oled.setCursor(85, 6); // поставить курсор для символа столбец 0-127, строка 0-8(4)
oled.print("dBm");
oled.update();
// Serial.print("Wi-Fi Подключен к сети: "); Serial.println(WiFi.SSID());
// Serial.print("Сила сигнала (RSSI): "); Serial.print(WiFi.RSSI()); Serial.print(" dBm");
}
int OLED_Cursor_Step_Vol;
void OLED_Interfeis_Download_loop() {
OLED_Cursor_Step_Vol = OLED_Cursor_Step_Vol + 1;
if (OLED_Cursor_Step_Vol >= 5) { OLED_Cursor_Step_Vol = 0;}
oled.setCursorXY(0, 0); // курсор в (пиксель X, пиксель Y) // поставить курсор для символа столбец 0-127, пиксель 0-63(31)
oled.setScale(0);
oled.invertText(0); // инвертируй текст!
oled.print(OLED_Cursor_Step_Vol);
OLED_Interfeis_Download(90, 36, 1, 0, '>', OLED_Cursor_Step_Vol);
//GyverOLED_Menu_loop();
delay(100);
}
void OLED_Interfeis_Download(int OLED_Cursor_X, int OLED_Cursor_Y, int OLED_Cursor_Scale, int OLED_Cursor_invert, char OLED_Cursor_label, int OLED_Cursor_Step) {
//oled.clear();
oled.clear(OLED_Cursor_X, OLED_Cursor_Y, OLED_Cursor_X + ((5 * (OLED_Cursor_Scale + 2)) * OLED_Cursor_Step), OLED_Cursor_Y + (7 * OLED_Cursor_Scale)); // очистить область
//oled.invertText(0); // инвертируй текст!
//oled.rect(OLED_Cursor_X, OLED_Cursor_Y, OLED_Cursor_X + ((5 * OLED_Cursor_Scale) * OLED_Cursor_Step), OLED_Cursor_Y + (7 * OLED_Cursor_Scale)); // прямоугольник (лев. верхн, прав. нижн)
//oled.setCursor(0, 2); // поставить курсор для символа столбец 0-127, строка 0-8(4)
//oled.setCursorXY(OLED_Cursor_X, OLED_Cursor_Y); // курсор в (пиксель X, пиксель Y) // поставить курсор для символа столбец 0-127, пиксель 0-63(31)
//oled.setScale(OLED_Cursor_Scale);
//oled.invertText(OLED_Cursor_invert); // инвертируй текст!
//for(byte i = 0; i < 8; i++) { //
oled.setCursorXY(OLED_Cursor_X + ((5 * OLED_Cursor_Scale) * OLED_Cursor_Step), OLED_Cursor_Y); // курсор в (пиксель X, пиксель Y) // поставить курсор для символа столбец 0-127, пиксель 0-63(31)
oled.setScale(OLED_Cursor_Scale);
oled.invertText(OLED_Cursor_invert); // инвертируй текст!
oled.print(OLED_Cursor_label);
// }
//oled.invertText(1); // инвертируй текст!
//oled.rect(OLED_Cursor_X, OLED_Cursor_Y + 30, OLED_Cursor_X + ((5 * OLED_Cursor_Scale) * OLED_Cursor_Step) + (5 * OLED_Cursor_Scale), OLED_Cursor_Y + ((7 * OLED_Cursor_Scale) + 30)); // прямоугольник (лев. верхн, прав. нижн)
oled.update();
//delay(500);
}
void GyverOLED_Menu_setup() {
menu.onBuild([](gm::Builder& b) {
//b.Label("QuadroBot");
MySwitch(b, "SW1", &sw1);
MySlider(b, "SLD1", 16, &sldr1);
MySwitch(b, "SW2", &sw2);
MySlider(b, "SLD2", 5, &sldr2);
MySwitch(b, "SW3", &sw3);
MySelect(b,"Select", &sel, "abc;123;test", [](uint8_t n, const char* str, uint8_t len) { Serial.write(str, len); });
MySwitch(b, "SW4", &sw4);
MySwitch(b, "SW5", &sw5);
b.Button("Button", []() { Serial.println("click!"); });
b.Switch("Switch", &sw, [](bool v) { Serial.println(v); });
b.ValueStr("ValueStr", "foo");
b.Label("Some line");
b.Select("Select", &sel, "abc;123;test", [](uint8_t n, const char* str, uint8_t len) { Serial.write(str, len); });
b.ValueInt<int>("ValueInt", &vali, -10, 10, 2, DEC, "%", [](int v) { Serial.println(v); });
b.ValueInt<int>("ValIntfast", &vali, -100, 100, eb.fast() ? 10 : 1); // при быстром вращении энкодера шаг будет 10 (грубый), а при медленном - 1 (точный)
b.ValueFloat("ValueFloat", &valf, -5, 5, 0.25, 3, "mm", [](float v) { Serial.println(v); });
//MyValueInt<int>(b, "ValueInt", &vali, -10, 10, 2, DEC, "%", [](int v) { Serial.println(v); });
//MyValueInt<int>(b, "ValIntfast", &vali, -100, 100, eb.fast() ? 10 : 1); // при быстром вращении энкодера шаг будет 10 (грубый), а при медленном - 1 (точный)
//MyValueFloat(b, "ValueFloat", &valf, -5, 5, 0.25, 3, "mm", [](float v) { Serial.println(v); });
b.ValueInt<int>("ValueInt", &vali, -10, 10, 2, DEC, "%", [](int v) { Serial.println(v); });
b.ValueInt<int>("ValIntfast", &vali, -100, 100, eb.fast() ? 10 : 1); // при быстром вращении энкодера шаг будет 10 (грубый), а при медленном - 1 (точный)
b.ValueFloat("ValueFloat", &valf, -5, 5, 0.25, 3, "mm", [](float v) { Serial.println(v); });
sel = int(V[96]);
b.Select("Reschim", &sel, "1;2;3", [](uint8_t n, const char* str, uint8_t len) { Serial.write(str, len); Serial.print("-"); Serial.print(sel); Serial.print("=");Serial.print(str); Serial.print("-"); Serial.print(len);Serial.println(" ");});
V[96] = float(sel);/////////////////////////////////
//if (b.Tabs(&tab, "btns;labels;ints;switch")) b.refresh();
if (MyTabs(b, &tab, "btns;labels;ints;switch")) b.refresh();
switch (tab) {
case 0:
for (int i = 0; i < 5; i++) {
//if (b.Button(String16("Button ") + i)) Serial.println(String16("Button") + i);
MySwitch(b, String("SW" + i).c_str(), &sw1);
}
break;
case 1:
MySwitch(b, "SW1", &sw1);
MySlider(b, "SLD1", 16, &sldr1);
MySwitch(b, "SW2", &sw2);
MySlider(b, "SLD2", 5, &sldr2);
MySwitch(b, "SW3", &sw3);
MySelect(b,"Select", &sel, "abc;123;test", [](uint8_t n, const char* str, uint8_t len) { Serial.write(str, len); });
MySwitch(b, "SW4", &sw4);
MySwitch(b, "SW5", &sw5);
break;
case 2:
MySwitch(b, "SW4", &sw4);
MySwitch(b, "SW5", &sw5);
break;
case 3:
MySwitch(b, "SW5", &sw5);
MySwitch(b, "SW5", &sw5);
MySwitch(b, "SW5", &sw5);
MySwitch(b, "SW5", &sw5);
break;
}
});
/* void printer(const char* str, size_t len) {
//str - строка для вывода на дисплей
//если str == nullptr - отрисовка меню закончена (для случаев когда нужно обновить экран)
//len - кол-во символов в строке
//if (str) oled.Print::write(str, len); /////////////////////////////////
if (str) {//oled.Print(str, len); /////////////////////////////////
oled.setCursor(str, len); // поставить курсор для символа столбец 0-127, строка 0-8(4)
//oled.setCursorXY(0, 16); // курсор в (пиксель X, пиксель Y) // поставить курсор для символа столбец 0-127, пиксель 0-63(31)
}
else { oled.update(); }
}
menu.onPrint(printer); */
menu.onPrint([](const char* str, size_t len) { // подключить рендер вида void(const char* str, size_t len). Придёт nullptr после окончания вывода
//if (!str) oled.update();
// else
//if (str) oled.Print::write(str, len);
//if (str) oled.setCursor(str, len); // поставить курсор для символа столбец 0-127, строка 0-8(4)//write(str, len);
if (str) oled.Print::write(str, len); /////////////////////////////////
else oled.update();
//if (str) Serial.write(str, len);
// else Serial.println();
});
menu.onCursor([](uint8_t row, bool chosen, bool active) -> uint8_t {
/* {
oled.setCursor(0, row * 2);
if (chosen && !active) {
oled.rect(0, row * 16 + 5, 8, row * 16 + 10, OLED_FILL);
} else {
oled.rect(0, row * 16, 8, row * 16 + 16, OLED_CLEAR);
}
return 1;
} // else */
{
oled.setCursor(0, row + 2);
oled.invertText(chosen);
return 0;
}
/* {
Serial.println();
Serial.print(chosen && !active ? '>' : ' ');
return 1;
} */
});
menu.setFastCursor(false);
menu.refresh();
}
void GyverOLED_setup0() {
oled.init();
//oled.setCursor(0, 2); // поставить курсор для символа столбец 0-127, строка 0-8(4)
//oled.setCursorXY(0, 16); // курсор в (пиксель X, пиксель Y) // поставить курсор для символа столбец 0-127, пиксель 0-63(31)
//oled.setScale(2);
menu.onBuild([](gm::Builder& b) {
b.Label("QuadroBot");
b.Page(GM_NEXT, "QuadroBot", [](gm::Builder& b) {
b.Label("QuadroBot");
b.Page(GM_NEXT, "Virtuino", [](gm::Builder& b) {
b.Label("Virtuino");
b.Page(GM_NEXT, "Start", [](gm::Builder& b) {
b.Label("Start");
b.ValueFloat("Стоп_Старт", &V[0], 0, 10, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Направление", &V[1], -100, 100, 1, 3, "PWM", [](float v) { Serial.println(v); });
b.ValueFloat("Газ", &V[2], -100, 100, 1, 3, "PWM", [](float v) { Serial.println(v); });
b.ValueFloat("Тормоз", &V[3], 0, 100, 1, 3, "PWM", [](float v) { Serial.println(v); });
b.ValueFloat("Макс Поворот", &V[4], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Макс Газ", &V[5], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Плавн Поворота", &V[6], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Плавн Газа", &V[7], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Передний привод", &V[8], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Задний привод", &V[9], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
});
b.Page(GM_NEXT, "Car", [](gm::Builder& b) {
b.Label("Car");
b.ValueFloat("Стоп_Старт", &V[0], 0, 10, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Направление", &V[1], -100, 100, 1, 3, "PWM", [](float v) { Serial.println(v); });
b.ValueFloat("Газ", &V[2], -100, 100, 1, 3, "PWM", [](float v) { Serial.println(v); });
b.ValueFloat("Тормоз", &V[3], 0, 100, 1, 3, "PWM", [](float v) { Serial.println(v); });
b.ValueFloat("Макс Поворот", &V[4], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Макс Газ", &V[5], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Плавн Поворота", &V[6], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Плавн Газа", &V[7], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Передний привод", &V[8], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Задний привод", &V[9], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
});
b.Page(GM_NEXT, "Servo", [](gm::Builder& b) {
b.Label("Servo");
b.ValueFloat("Servo 00", &V[80], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 01", &V[81], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 02", &V[82], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 03", &V[83], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 04", &V[84], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 05", &V[85], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 06", &V[86], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 07", &V[87], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 08", &V[88], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 09", &V[89], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 10", &V[90], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 11", &V[91], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 12", &V[92], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 13", &V[93], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 14", &V[94], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 15", &V[95], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
});
b.Page(GM_NEXT, "Motor", [](gm::Builder& b) {
b.Label("Motor");
b.ValueFloat("Motor 00", &V[80], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Motor 01", &V[81], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Motor 02", &V[82], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Motor 03", &V[83], 0, 100, 1, 3, "n", [](float v) { Serial.println(v); });
});
b.Page(GM_NEXT, "PCA9685", [](gm::Builder& b) {
b.Label("PCA9685");
b.ValueFloat("PCA9685 00", &V[110], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 01", &V[111], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 02", &V[112], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 03", &V[113], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 04", &V[114], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 05", &V[115], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 06", &V[116], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 07", &V[117], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 08", &V[118], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 09", &V[119], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 10", &V[120], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 11", &V[121], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 12", &V[122], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 13", &V[123], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 14", &V[124], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("PCA9685 15", &V[125], 0, 4096, 1, 3, "n", [](float v) { Serial.println(v); });
});
b.Page(GM_NEXT, "Servo 1", [](gm::Builder& b) {
b.Label("Servo");
b.ValueFloat("Servo 00", &V[80], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 01", &V[81], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 02", &V[82], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 03", &V[83], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 04", &V[84], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 05", &V[85], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 06", &V[86], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 07", &V[87], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 08", &V[88], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 09", &V[89], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 10", &V[90], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 11", &V[91], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 12", &V[92], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 13", &V[93], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 14", &V[94], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
b.ValueFloat("Servo 15", &V[95], 0, 179, 1, 3, "n", [](float v) { Serial.println(v); });
});
});
});
b.Page(GM_NEXT, "Настройки", [](gm::Builder& b) {
b.Label("Настройки ESP32");
b.Page(GM_NEXT, "WiFi", [](gm::Builder& b) {
b.Label("WiFi");
//b.ValueStr("WiFi", "WiFi.SSID(0)"); // найденные сети
//b.ValueStr("WiFi", "WiFi.RSSI(0)");
b.ValueStr("Сеть WiFi", "WiFi.SSID()");
b.ValueStr("Сила сигнала", "WiFi.RSSI()"); //Serial.println(" dBm"); // Вот как можно получить значение силы сигнала (RSSI) в миллидецибелах (dBm)
b.Page(GM_NEXT, "Start", [](gm::Builder& b) {
b.Label("Start");
b.ValueFloat("Стоп_Старт", &V[0], 0, 10, 1, 3, "n", [](float v) { Serial.println(v); });
});
/* //Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i)); // signal
void loop000() { // Вот как можно получить значение силы сигнала (RSSI) в миллидецибелах (dBm)
// Получаем значение RSSI
int rssi = WiFi.RSSI();
Serial.print("Сила сигнала (RSSI): ");
Serial.print(rssi);
Serial.println(" dBm"); // Вот как можно получить значение силы сигнала (RSSI) в миллидецибелах (dBm)
// Показатели силы сигнала (RSSI)
// -60 dBm до -70 dBm: Отличный/Хороший сигнал.
// -70 dBm до -80 dBm: Средний уровень сигнала.
// -80 dBm до -90 dBm: Плохой/Неудовлетворительный уровень (могут быть проблемы с передачей, и быстрый разряд батареи.).
// Значения RSSI всегда отрицательные. Чем ближе число к нулю, тем сильнее сигнал:
// Значение (дБм) Качество сигнала Рекомендации
// от -30 до -50 Отличное Максимальная скорость и стабильность.
// от -51 до -65 Хорошее Надежное соединение для большинства задач.
// от -66 до -75 Среднее Возможны кратковременные задержки или снижение скорости.
// от -76 до -90 Слабое Нестабильное соединение, частые разрывы.
// ниже -90 Непригодное Связь практически отсутствует.
delay(2000); // Выводим каждые 2 секунды
} */
});
b.Page(GM_NEXT, "Bluetooth", [](gm::Builder& b) {
b.Label("Bluetooth");
b.Page(GM_NEXT, "Bluetooth Start", [](gm::Builder& b) {
b.Label("Bluetooth Start");
//b.ValueFloat("Bluetooth_Старт", &V[0], 0, 10, 1, 3, "n", [](float v) { Serial.println(v); });
});
});
b.Button("Button", []() { Serial.println("click!"); });
b.Switch("Switch", &sw, [](bool v) { Serial.println(v); });
b.ValueStr("ValueStr", "foo");
b.Label("Some line");
b.Select("Select", &sel, "abc;123;test", [](uint8_t n, const char* str, uint8_t len) { Serial.write(str, len); });
b.ValueInt<int>("ValueInt", &vali, -10, 10, 2, DEC, "%", [](int v) { Serial.println(v); });
b.ValueInt<int>("ValIntfast", &vali, -100, 100, eb.fast() ? 10 : 1); // при быстром вращении энкодера шаг будет 10 (грубый), а при медленном - 1 (точный)
b.ValueFloat("ValueFloat", &valf, -5, 5, 0.25, 3, "mm", [](float v) { Serial.println(v); });
});
MySwitch(b, "SW1", &sw1);
MySlider(b, "SLD1", 16, &sldr1);
MySwitch(b, "SW2", &sw2);
MySlider(b, "SLD2", 5, &sldr2);
MySwitch(b, "SW3", &sw2);
/*b.Button("Button", []() { Serial.println("click!"); });
b.Switch("Switch", &sw, [](bool v) { Serial.println(v); });
b.ValueStr("ValueStr", "foo");
b.Label("Some line");
b.Select("Select", &sel, "abc;123;test", [](uint8_t n, const char* str, uint8_t len) { Serial.write(str, len); });
b.ValueInt<int>("ValueInt", &vali, -10, 10, 2, DEC, "%", [](int v) { Serial.println(v); });
b.ValueFloat("ValueFloat", &valf, -5, 5, 0.25, 3, "mm", [](float v) { Serial.println(v); });
*/
/* if (b.Switch("Buttons", &btns)) b.refresh();
if (btns) {
for (int i = 0; i < 5; i++) {
if (b.Button(String16("Button ") + i)) Serial.println(String16("Button") + i);
}
}
if (b.Switch("Labels", &lbls)) b.refresh();
if (lbls) {
for (int i = 0; i < 5; i++) {
b.ValueStr(String16("ValueStr ") + i, String16("kek") + (i * 10));
}
} */
//////////////////////////////////////////////////
b.Label("root");
b.Page(GM_NEXT, "Submenu", [](gm::Builder& b) {
b.Label("in sub 1");
b.Page(GM_NEXT, "sub 2", [](gm::Builder& b) {
b.Label("in sub 2");
});
});
// или так
if (b.PageBegin(GM_NEXT, "Submenu")) {
b.Label("in sub 1");
if (b.PageBegin(GM_NEXT, "sub 2")) {
b.Label("in sub 2");
b.PageEnd();
}
b.PageEnd();
}
////////////////////////////////////////////////////
////////////////////////////////////////////////////
/*if (b.Tabs(&tab, "btns;labels;ints;switch")) b.refresh();
switch (tab) {
case 0:
for (int i = 0; i < 5; i++) {
if (b.Button(String16("Button ") + i)) Serial.println(String16("Button") + i);
}
break;
case 1:
b.ValueStr("label", "value 1");
b.ValueStr("label", "value 2");
b.ValueStr("label", "value 3");
b.ValueStr("label", "value 4");
break;
case 2:
b.ValueInt("int 1", &val, -10, 10, 2);
b.ValueInt("int 2", &val, -10, 10, 2);
break;
case 3:
b.Switch("Switch 1", &sw);
b.Switch("Switch 2", &sw);
b.Switch("Switch 3", &sw);
b.Switch("Switch 4", &sw);
break;
} */
});
/* void printer(const char* str, size_t len) {
//str - строка для вывода на дисплей
//если str == nullptr - отрисовка меню закончена (для случаев когда нужно обновить экран)
//len - кол-во символов в строке
//if (str) oled.Print::write(str, len); /////////////////////////////////
if (str) {//oled.Print(str, len); /////////////////////////////////
oled.setCursor(str, len); // поставить курсор для символа столбец 0-127, строка 0-8(4)
//oled.setCursorXY(0, 16); // курсор в (пиксель X, пиксель Y) // поставить курсор для символа столбец 0-127, пиксель 0-63(31)
}
else { oled.update(); }
}
menu.onPrint(printer); */
menu.onPrint([](const char* str, size_t len) { // подключить рендер вида void(const char* str, size_t len). Придёт nullptr после окончания вывода
//if (!str) oled.update();
// else
//if (str) oled.Print::write(str, len);
//if (str) oled.setCursor(str, len); // поставить курсор для символа столбец 0-127, строка 0-8(4)//write(str, len);
if (str) oled.Print::write(str, len); /////////////////////////////////
else oled.update();
//if (str) Serial.write(str, len);
// else Serial.println();
});
menu.onCursor([](uint8_t row, bool chosen, bool active) -> uint8_t {
/* {
oled.setCursor(0, row * 2);
if (chosen && !active) {
oled.rect(0, row * 16 + 5, 8, row * 16 + 10, OLED_FILL);
} else {
oled.rect(0, row * 16, 8, row * 16 + 16, OLED_CLEAR);
}
return 1;
} // else */
{
oled.setCursor(0, row);
oled.invertText(chosen);
return 0;
}
/* {
Serial.println();
Serial.print(chosen && !active ? '>' : ' ');
return 1;
} */
});
menu.setFastCursor(false);
menu.refresh();
}
void setup2() {
oled.init();
menu.onPrint([](const char* str, size_t len) {
if (str) oled.Print::write(str, len);
else oled.update();
});
menu.onCursor([](uint8_t row, bool chosen, bool active) -> uint8_t {
oled.setCursor(0, row);
oled.invertText(chosen);
return 0;
});
menu.onBuild([](gm::Builder& b) {
b.Button("Button", []() { Serial.println("click!"); });
b.Switch("Switch", &sw, [](bool v) { Serial.println(v); });
b.ValueStr("ValueStr", "foo");
b.Label("Some line");
b.Select("Select", &sel, "abc;123;test", [](uint8_t n, const char* str, uint8_t len) { Serial.write(str, len); });
b.ValueInt<int>("ValueInt", &vali, -10, 10, 2, DEC, "%", [](int v) { Serial.println(v); });
b.ValueFloat("ValueFloat", &valf, -5, 5, 0.25, 3, "mm", [](float v) { Serial.println(v); });
});
menu.setFastCursor(false);
menu.refresh();
}
void GyverOLED_Menu_loop() {
//oled.home(); // курсор в 0,0
//oled.setCursor(0, 2); // поставить курсор для символа столбец 0-127, строка 0-8(4)
oled.setCursorXY(0, 16); // курсор в (пиксель X, пиксель Y) // поставить курсор для символа столбец 0-127, пиксель 0-63(31)
if (center) menu.set(); // кнопка выбора
if (up) menu.up(); // кнопка вверх
if (down) menu.down(); // кнопка вниз
if (left) menu.left(); // уменьшить напрямую
if (right) menu.right(); // увеличить напрямую
// Энкодер: up и down на вращение, set на клик, зажатый поворот как left и right
// Удержание кнопки - back. Очень долгое удержание - home
if (eb.click()) menu.set(); // однократно при клике
if (eb.hasClicks()) {
//if (eb.getClicks() == 1) menu.set(); // кнопка выбора // click()) Serial.println("click"); // однократно выведет при клике
if (eb.getClicks() == 2) menu.back(); // на предыдущее меню
//if (eb.getClicks() == 3) menu.home(); // в главное меню
}
if (eb.release()) { // кнопка отпущена, смотрим сколько её удерживали
if (eb.pressFor() > 1000 && eb.pressFor() <= 2000) menu.back(); // от 1 до 2 секунд
else if (eb.pressFor() > 2000 && eb.pressFor() <= 3000) menu.home(); // от 2 до 3 секунд // в главное меню
}
if (eb.turn()) { // меняем переменную
if (eb.dir() == 1) menu.up(); // кнопка вверх
if (eb.dir() == -1) menu.down(); // кнопка вниз
if (eb.pressing() == -1) menu.left();
if (eb.pressing() == 1) menu.right();
//if ((eb.fast() ? 2 : 1) * (eb.pressing() ? 5 : 1) * eb.dir() >= 1) menu.right();
}
//V[0] += float((eb.fast() ? 2 : 1) * (eb.pressing() ? 5 : 1) * eb.dir()); // изменение с шагом 1, при быстром вращении шаг 2, при зажатой кнопке шаг 5 // выбранная переменная
/* static uint32_t tmr;
if (millis() - tmr >= 2000) {
tmr = millis();
vali = random(10);
menu.update(&vali);
sel = random(3);
menu.update(&sel);
} */
}
IRAM_ATTR void isr() { // esp8266/esp32
//void isr() {
eb.tickISR();
}
void EncButton_setup() {
// показаны значения по умолчанию
eb.setBtnLevel(LOW);
eb.setDebTimeout(50); // таймаут гашения дребезга кнопки (кнопка)
eb.setClickTimeout(500); // таймаут ожидания кликов (кнопка)
eb.setHoldTimeout(600); // таймаут удержания (кнопка)
eb.setStepTimeout(200); // таймаут импульсного удержания (кнопка)
eb.setEncReverse(0);
eb.setEncType(EB_STEP4_LOW); //EB_STEP4_LOW - активный низкий сигнал (подтяжка к VCC). Полный период (4 фазы) за один щелчок. Установлен по умолчанию
//EB_STEP4_HIGH - активный высокий сигнал (подтяжка к GND). Полный период (4 фазы) за один щелчок
//EB_STEP2 - половина периода (2 фазы) за один щелчок
//EB_STEP1 - четверть периода (1 фаза) за один щелчок, а также энкодеры без фиксации
eb.setFastTimeout(30); // таймаут быстрого поворота (энкодер)
//Serial.println(eb.counter); // читать
//eb.counter += 1234; // менять
eb.counter = 0; // сбросить счётчик энкодера // обнулять
/////////////////////////////////////////////////////////////////////////
//btn.tick();
//if (btn.press()) Serial.println("Кнопка нажата при старте");
//// btn.setBtnLevel(LOW); // можно настроить уровень
//// if (btn.read()) Serial.println("Кнопка нажата при старте");
//eb.tick();
//if (eb.press()) Serial.println("Кнопка нажата при старте");
////////////////////////////////////////////////////////////////////////
attachInterrupt(EncButton_Pin_CLK, isr, CHANGE); //Подкючаем аппаратное прерывание по изменению состояния пина
attachInterrupt(EncButton_Pin_DT, isr, CHANGE); //Подкючаем аппаратное прерывание по изменению состояния пина
eb.setEncISR(true);
////////////////////////////////////////////////////////////////////////
{ // Serial.println("Кнопка нажата при старте");
eb.tick();
while (eb.busy()) {
eb.tick();
if (eb.hold()) Serial.println("hold");
if (eb.step()) Serial.println("step");
}
//Serial.println("program start");
}
}
void EncButton_loop() {
eb.tick(); // Опрос энкодера
if (eb.action()) {
//Led_Status_Action_Start(20); // Led_Action_Millis_Interval // // LOW - HIGH // OFF - ON // ESP32 Led OUT Pin 2 Arduino Pin 13
//EncButton_Redraw_Action = 1;
}
// 1
//EncButton_Start_loop();
//EncButton_Read_loop();
//EncButton_End_loop();
// 2
//EncButton_Controller_Read_loop();
#ifdef EncButton_Serial_Debug_ON
if (EncButton_Serial_Debug) {
EncButton_Serial_loop();
}
#endif
}