#define ENC_BUTTON 4
#define ENC_CLK 7 // PINB 1
#define ENC_DT 8 // PINB 0
#define PWM 5 // PWM
#include <GyverOLED.h>
#include <EncButton.h>
#include <PinChangeInterrupt.h>
GyverOLED<SSD1306_128x64, OLED_BUFFER> oled;
//GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;
//GyverNTC therm(NTC_PIN, 10000, 3950);
EncButton<EB_TICK, ENC_CLK, ENC_DT, ENC_BUTTON> enc; // энкодер с кнопкой <A, B, KEY>
bool scr_update_flag = true, adc_flag, tip_error;
uint8_t scr_state, PWM_duty; // Состояние меню, значение ШИМ
uint16_t setpoint, new_setpoint, adc_amb_temp, adc_relative_temp;
float disp_temp, current_temp, amb_temp, relative_temp;
uint32_t menu_tmr, meas_tmr, adc_tmr, current_millis;
void setup() {
Serial.begin(9600);
pinMode(ENC_BUTTON, INPUT_PULLUP);
pinMode(ENC_CLK, INPUT_PULLUP);
pinMode(ENC_DT, INPUT_PULLUP);
attachPCINT(digitalPinToPCINT(ENC_CLK), isr, CHANGE);
attachPCINT(digitalPinToPCINT(ENC_DT), isr, CHANGE);
oled.init(); // инициализация
oled.clear(); // очистить дисплей (или буфер)
}
void isr() {
enc.tickISR(); // в прерывании вызываем тик ISR
}
class My_encoder {
public:
//My_encoder() {} // Конструктор по умолчанию прописывать не обязательно
// ========== Опрос входов ==========
void tick() {
now_millis = millis();
clk = bitRead(PINB, 1); // digitalRead(ENC_CLK);
dt = bitRead(PINB, 0); // digitalRead(ENC_DT);
btn_state = !bitRead(PIND, ENC_BUTTON);
}
bool is_turn() {
if (clk != clk_prev) {
clk_prev = clk;
if (!clk) return true; // Реакция только по спаду импульса
}
return false;
}
/*
int8_t dir() {
if (is_turn()) {
if (dt) return -1; // Если при вращении dt == 1 (true), то направление влево
else return 1;
}
return 0;
}
*/
bool is_left() {
if (is_turn()) {
if (dt) return true;
}
return false;
}
bool is_right() {
if (is_turn()) {
if (!dt) return true;
}
return false;
}
// ========== Опрос кнопки ==========
void button_state() {
// нажали (с антидребезгом)
if (btn_state && !btn_flag && now_millis - btn_timer > debounce) {
btn_flag = 1; // флаг
btn_HO = 1; // флаг hold once
btn_press = 1;
btn_timer = now_millis;
}
// если отпустили до hold, считать отпущенной
if (!btn_state && btn_flag && now_millis - btn_timer < hold) {
btn_flag = 0;
btn_timer = now_millis;
}
// Если удерживается более hold, то считать удержанием
if (btn_flag && !btn_H && now_millis - btn_timer > hold) {
btn_H = 1;
}
// Если отпущена после hold, то считать, что была удержана
if (!btn_state && btn_flag && now_millis - btn_timer > hold) {
btn_flag = 0;
btn_H = 0;
btn_timer = now_millis;
}
}
bool is_press() {
//tick(); // Опрос во время вызова
button_state();
if (btn_press) {
btn_press = false;
return true;
}
return false;
}
bool is_hold_once() {
//tick(); // Опрос во время вызова
button_state();
if (btn_H && btn_HO) {
btn_HO = false;
return true;
}
return false;
}
private:
bool clk = false; // храним состояние энкодера
bool clk_prev = false; // храним предыдущее состояние энкодера
bool dt = false; // храним состояние энкодера
bool btn_state = false; // храним состояние кнопок
bool btn_flag = false; // флаг кнопки
bool btn_press = false; // флаг кнопки на нажатие
bool btn_H = false; // флаг кнопки на удержание (многократный вызов) (H - Hold)
bool btn_HO = false; // флаг кнопки на удержание (один вызов при нажатии) (HO - Hold Once)
uint16_t hold = 500; // время (мс), после которого кнопка считается зажатой
uint16_t debounce = 80; // (мс), антидребезг
uint32_t btn_timer = 0; // таймер последнего нажатия кнопки
uint32_t now_millis = 0; // текущее значение millis
};
My_encoder encoder; // При создании объекта без аргументов скобки не нужны
void loop() {
enc.tick();
encoder.tick();
if (enc.turn()) {
oled.clear();
oled.home();
oled.setScale(4);
oled.println("Turn");
oled.update();
Serial.print("turn ");
}
if (enc.left()) { // поворот налево
oled.clear();
oled.home();
oled.setScale(4);
oled.print("Left");
oled.update();
Serial.println("left");
}
if (enc.right()) { // поворот направо
oled.clear();
oled.home();
oled.setScale(4);
oled.print("Right");
oled.update();
Serial.println("right");
}
if (enc.held()) { // Удержание кнопки
uint32_t us = micros();
oled.clear();
//us = micros();
oled.home();
oled.setScale(4);
oled.print("Held");
oled.update();
us = micros() - us;
Serial.println(us);
us = micros();
Serial.println("Held");
us = micros() - us;
Serial.println(us);
}
if (enc.click()) { // Кнопка была нажата и ОТПУЩЕНА
oled.clear();
oled.home();
oled.setScale(4);
oled.print("Click");
oled.update();
Serial.println("Click");
}
//delay(200);
}
/*
// Замер скорости выполнения
void loop() {
uint32_t us = micros();
// измеряемый код
delay(123);
// измеряемый код
us = micros() - us;
Serial.println(us);
delay(1000);
}
*/