Добрый день, столкнулся со следующей проблемой. Вроде как все работает, но энкодер через какое-то количество срабатываний в подменю "Ручной режим" зависает. Проблема исчезает если либо заменить кирилицу на латиницу либо если перестать вызывать любую из функций внутри функции "manual_mod". Добавил кнопки в обход библиотеки EncButton2. После зависания энкодера программа продолжает работать при управлении кнопками. Помогите пожалуйста решить данную проблему.
Код:
#include <EEPROM.h> // Подключаем библиотеку для работы с EEPROM
#include <U8g2lib.h>
#include <SPI.h>
#include <microDS18B20.h> //библиотека датчика температуры
#include <EncButton2.h> //библиотека энкодера
EncButton2<EB_ENCBTN> enc(INPUT_PULLUP, 2, 3, 4); // энкодер с кнопкой
U8G2_ST7920_128X64_F_HW_SPI u8g2(U8G2_R0, /* CS=[I]/ 10, /[/I] reset=*/ 8);
#define heater_pin 9 //пин управление тэн
#define buzzer_pin 5 // Пин подключения пассивной пищалки
#define EB_DEB 20 // дебаунс кнопки, мс по умолчанию 50
MicroDS18B20<6> ds; //датчик температуры на 6 пин Раскоментировать
uint8_t main_ptr = 1; //Указатель главного меню
uint8_t program_ptr = 1; //Указатель меню выбора и редактирования программ
//bool end_loop; //Флаг выхода из меню выбора и редактирования программ
float cur_temp = 0; //текущаяя температура
bool update = true;
void setup() {
pinMode(buzzer_pin, OUTPUT);
pinMode(heater_pin, OUTPUT);
pinMode(A1, INPUT_PULLUP); //Enter
pinMode(A2, INPUT_PULLUP); //Esc
pinMode(A3, INPUT_PULLUP); //внмз
pinMode(A4, INPUT_PULLUP); //Вверх
pinMode(A5, OUTPUT);
digitalWrite(A5, LOW); //Земля для кнопок
Serial.begin(115200);
attachInterrupt(0, isr, CHANGE);
attachInterrupt(1, isr, CHANGE);
u8g2.begin(); // enable UTF8 support for the Arduino print() function
u8g2.enableUTF8Print();
}
void isr() {
enc.tickISR(); // тикер в прерывании
}
void loop() {
enc.tick();
u8g2.firstPage(); //очищает буфер экрана
u8g2.setFont(u8g2_font_7x13_t_cyrillic);
u8g2.setDrawColor(2);
u8g2.setCursor(22, 9);
u8g2.print("Главное меню");
u8g2.drawLine(20, 11, 106, 11);
u8g2.setCursor(2, 26);
u8g2.print("Выбор программы");
u8g2.setCursor(2, 40);
u8g2.print("Редактор программ");
u8g2.setCursor(2, 54);
u8g2.print("Ручной режим");
u8g2.drawRBox(0,main_ptr*14+1,127,14,0);
u8g2.nextPage();
if (enc.right() || digitalRead(A3) == LOW) {
main_ptr++;
if (main_ptr == 4) main_ptr = 1;
}
if (enc.left() || digitalRead(A4) == LOW) {
main_ptr--;
if (main_ptr == 0) main_ptr = 3;
}
if (enc.click() || digitalRead(A1) == LOW) {
//if (main_ptr == 1) { Program_selection(); }
//if (main_ptr == 2) { Program_editing(); }
if (main_ptr == 3) { Manual_mod(); }
}
}
void Manual_mod() { //Ручной режим
int8_t ptr = 1; // Указатель
bool flag = false; // Флаг выхода на температурный режим
uint32_t Tmr_ms; //Таймер температурного режима
static int8_t temp_pow[] = {50, 80}; // температура, мощность
bool heater_on = false; //Нагреватель выключен
for (;;) {
get_temp();
u8g2.firstPage(); //очищает буфер экрана
u8g2.setFont(u8g2_font_6x12_t_cyrillic);
u8g2.setDrawColor(2);
//u8g2.setCursor(28, 7);
u8g2.drawUTF8(28, 7, "Ручной режим");
//u8g2.print("Ruchnoy rezhim");
u8g2.drawLine(26, 10, 100, 10);
//u8g2.setCursor(2, 22);
//u8g2.print("Tek. temp-ra ");
u8g2.drawUTF8(2, 22, "Тек. темп-ра ");
u8g2.setCursor(90, 22);
u8g2.print(cur_temp,1);
u8g2.setFont(u8g2_font_6x12_tf);
u8g2.print("°C");
u8g2.setFont(u8g2_font_6x12_t_cyrillic);
//u8g2.setCursor(2, 34);
//u8g2.print("Ust. temp-ra ");
u8g2.drawUTF8(2, 34, "Уст. темп-ра ");
u8g2.setCursor(90, 34);
u8g2.print(temp_pow [0]);
u8g2.setFont(u8g2_font_6x12_tf);
u8g2.print("°C");
u8g2.setFont(u8g2_font_6x12_t_cyrillic);
//u8g2.setCursor(2, 46);
//u8g2.print("Moschnost TENa ");
u8g2.drawUTF8(2, 46, "Мощность ТЭНа ");
u8g2.setCursor(90, 46);
u8g2.print(temp_pow [1]);
u8g2.print("%");
//u8g2.setCursor(2, 58);
if (heater_on){
//u8g2.print("TEN Vkl ");
u8g2.drawUTF8(2, 58, "ТЭН Вкл");
} else {
//u8g2.print("TEN Vikl ");
u8g2.drawUTF8(2, 58, "ТЭН Выкл");
}
u8g2.drawRBox(0,ptr*12+13,127,12,0);
u8g2.nextPage(); // Выводит содержимое буфера на экран
if (cur_temp > temp_pow[0] - 0.5 && !flag){
flag = true;
Tmr_ms = millis();
}
if (heater_on) heat(temp_pow[0], temp_pow[1]);
else digitalWrite(heater_pin, LOW);
enc.tick();
if (enc.leftH()) {
if (ptr < 3) {
temp_pow[ptr-1]--;
} else {
heater_on = !heater_on;
}
if(ptr == 1 && flag){
flag = false;
digitalWrite(buzzer_pin, LOW);
}
}
if (enc.left() || digitalRead(A4) == LOW){
ptr--;
if(ptr == 0) ptr=3;
}
if (enc.rightH()) {
if (ptr < 3) {
temp_pow[ptr-1]++;
} else {
heater_on = !heater_on;
}
if(ptr == 1 && flag){
flag = false;
digitalWrite(buzzer_pin, LOW);
}
}
if (enc.right() || digitalRead(A3) == LOW){
ptr++;
if(ptr == 4) ptr=1;
}
if ((enc.click() || digitalRead(A1) == LOW) && ptr == 3) heater_on = !heater_on;
temp_pow[0] = constrain(temp_pow[0], 20, 100);
temp_pow[1] = constrain(temp_pow[1], 10, 100);
if (enc.held() || digitalRead(A2) == LOW) break;
}
digitalWrite(heater_pin, LOW);
digitalWrite(buzzer_pin, LOW);
}
void get_temp() {
static uint32_t temp_timer = 0;
if (millis() - temp_timer >= 1000) {
temp_timer = millis();
if (ds.readTemp()) {
cur_temp = ds.getTemp();
ds.requestTemp();
}
}
}
void heat(int8_t set_temp, int8_t power){
static uint16_t activePeriod = 0;
static uint32_t pwm_tmr = 0;
if (millis() - pwm_tmr >= 1000) {
pwm_tmr = millis();
if (set_temp < 100){ // пид регулятор
const float kp = 25;
const float ki = 0.3;
const float kd = 15;
static float integral = 0, prevErr = 0;
float err = set_temp - cur_temp; // Пропорциональная составляющая
if(err < 0) integral = constrain(integral + err, (-2 + err * 10), (2 - 10 * err)); //Интегральная составляющая
else integral = constrain(integral + err, (-2 - err * 10), (2 + 10 * err)); //Интегральная составляющая
float D = err - prevErr; //Дифференциальная состовляющая
prevErr = err;
activePeriod = round(constrain(err * kp + integral * ki + D * kd, 0, power)) * 10;
Serial.print(cur_temp);
Serial.print(" ,");
Serial.print(err);
Serial.print(" ,");
Serial.print(err * kp);
Serial.print(" ,");
Serial.print(integral * ki);
Serial.print(" ,");
Serial.print(D * kd);
Serial.print(" ,");
Serial.println(activePeriod/10);
} else {
activePeriod = power * 10;
}
}
if (millis() - pwm_tmr <= activePeriod) digitalWrite(heater_pin, HIGH);
else {
digitalWrite(heater_pin, LOW);
}
}