Проблема с подсветкой
- Войдите на сайт для отправки комментариев
Ср, 08/01/2020 - 18:02
Всем привет!!! Помогите найти проблему. Хотел сделать, чтобы при событиях на энкодере счетчик подсветки переназначался на дефолтное значение. Соответсвенно если активности у энкодера нету то считчик уменьшается до 0 и посдсветка отключается. Вроде все работает, но если я захожу в меню при повороте энкодера в таймер попадают странные значения, может 0 прилететь или 8425 хотя в скетче идет отсчте от 20.
#include <microLiquidCrystal_I2C.h> #include <microDS3231.h> #include <GyverEncoder.h> #define CLK 4 #define DT 3 #define SW 2 #define POWER_ON 5 LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей MicroDS3231 timeClock;// Устанавливаем часы Encoder enc1(CLK, DT, SW); // Устанавливаем енкодер // =================== НОВЫЕ ПЕРЕМЕННЫЕ ====================== // ---------------- Меню ------------------ const byte menu = 10; const byte sub_menu = 20; const byte first = 100; bool active_menu = false; bool active_submenu = false; int8_t current_item = 0; int8_t dispayed_item = 1; byte currentPage; // ---------------- Таймер ------------------ int secondLast = 0; bool secondChanges = true; int cur_time; int display_time; int work_time_value = 0; bool work_time_min = true; // ---------------- Оповещение ------------------ bool time_error = false; bool power_enable = false; // ---------------- Кнопка ------------------ bool btn_active = true; int btn_timer; // ---------------- Дисплей ------------------ bool backlight_enable = true; // ---------------- Конфиг ------------------ int8_t cfg_timer_backlight = 20; int8_t cfg_time_sys_h; int8_t cfg_time_sys_m; int8_t cfg_time_poweron = 8; int8_t cfg_time_poweroff = 23; int8_t cfg_time_highlight; // =================== НОВЫЕ ПЕРЕМЕННЫЕ ====================== const char *menu_items[] = { "System time", // 0 "Time power on", // 1 "Time power off", // 2 "Highlight on", // 2 "Display led", // 2 }; const char *menu_items_set[] = { }; void setup() { Serial.begin(9600); lcd.init(); lcd.backlight(); enc1.setType(TYPE1); if (timeClock.lostPower()) { lcd.setCursor(1, 0); lcd.print('RTC lost power'); lcd.blink(); timeClock.setTime(COMPILE_TIME); time_error = true; } display_time = timeClock.getMinutes(); btn_timer = cfg_timer_backlight; calcWorkTime(); goPage(first); } void loop() { powerBp(); calcWorkTime(); checkActivity(); displayBacklight(); goPage(currentPage); } void powerBp(){ int curHours = timeClock.getHours(); if (cfg_time_poweron < curHours && cfg_time_poweroff > curHours){ if(power_enable) return; digitalWrite(POWER_ON, HIGH); Serial.println("high"); power_enable = true; }else{ power_enable = false; digitalWrite(POWER_ON, LOW); Serial.println("low"); } } void goPage(byte menuItem){ char firstLine[16]; char secondLine[16]; switch (menuItem) { case menu: sprintf(firstLine,"%s","Options ========"); sprintf(secondLine,"-%s ",menu_items[dispayed_item]); break; case sub_menu: sprintf(firstLine,"%s ===========",menu_items[dispayed_item]); sprintf(secondLine,"%s",menu_items_set[dispayed_item]); break; default: sprintf(firstLine,"Time %d:%d:%d",timeClock.getHours(),timeClock.getMinutes(),timeClock.getSeconds()); sprintf(secondLine,"work %d %s",work_time_value,(work_time_min)?"minutes":"hours"); break; } checkTimer(); if(secondChanges){ lcd.clear(); } lcd.setCursor(0, 0); lcd.print(firstLine); if(time_error){ lcd.setCursor(14, 0); lcd.print(" x"); } lcd.setCursor(0, 1); lcd.print(secondLine); } void calcWorkTime(){ if(work_time_min){ cur_time = millis()/60000; }else{ cur_time = millis()/360000; } if (display_time != cur_time){ display_time = cur_time; work_time_value++; if (work_time_value > 59 && work_time_min){ work_time_value = 1; work_time_min = false; display_time = millis()/360000; } } } void checkTimer(){ if(millis()/1000 != secondLast){ secondLast = millis()/1000; secondChanges = true; return; } secondChanges = false; } void checkActivity(){ enc1.tick(); bool btn_click = enc1.isClick(); bool btn_left = enc1.isLeft(); bool btn_right = enc1.isRight(); bool btn_turn = enc1.isTurn(); if(secondChanges && btn_timer > 0 ){ btn_timer--; }; if (btn_click || btn_turn){ Serial.println("turn or click"); btn_timer = cfg_timer_backlight; }; if (btn_click){ Serial.println("click"); if(!active_menu && !active_submenu){ toggleStateMenu(menu); return; } if(active_menu){ toggleStateMenu(sub_menu); } } if (enc1.isHolded()){ lcd.clear(); if(active_submenu){ toggleStateMenu(menu); }else{ toggleStateMenu(first); } }; if (btn_right && active_menu){ Serial.println("right"); dispayed_item++; if(dispayed_item == 5) dispayed_item = 0; }; if (btn_left && active_menu){ Serial.println("left"); dispayed_item--; if(dispayed_item <= 0) dispayed_item = 4; }; } void displayBacklight(){ if (btn_timer == 0){ toggleStateMenu(first); lcd.noBacklight(); }else{ lcd.backlight(); }; } void toggleStateMenu(byte state){ switch (state) { case menu: active_menu = true; currentPage = menu; break; case sub_menu: active_menu = false; active_submenu = true; currentPage = sub_menu; break; default: active_menu = false; active_submenu = false; currentPage = first; } }
Дак это, наерна, к нему:
003
#include <GyverEncoder.h>
004
В какой таймер попадает 8425 и откуда?
а библиотека может изменять мои значения переменных, которые я объявлял в скетче? вот собственно часть кода, в которой я работаю с данной переменной
В мире всякое может быть. Даже вирус глупости может завестись в ардуине и портить дев.. переменные.
Для начала Вам нужно сформулировать свою проблему понятно для остальных людей. Из приведённого кода не усматривается попадание какой-то там 8425 в таймер (по секрету скажу, что запихать нечто в таймер - весьма нетривиальная операция). Может у Вас значение некоторой переменной принимает неожидаемое значение в некий момент времени? Подумайте над этим и спросите ещё раз.
Может быть я неправильные слова подобрал. Но меня волнует вопрос почему в переменной появляются странные значения, наблюдаю я их в консоли. логика у меня такая
1. объявил переменную.
2. установил дефолтное значение, которое взял из другой переменной ( типы у них одинаковые)
3. если срабатывает событие на энкодере (поворот, клик), то я устанавливаю переменной дефолтное значение
4. если события не происходят, то я уменьшаю значение переменной на единицу каждую секунду ( дойдя до нуля перестаю уменьшать и выключаю подсветку)
код отрабатывает, но иногда в моей переменной при срабатывании события на энкодере неожиданно может появиться 0 хотя предыдущее значение было допустим 10
объявление переменной
присваиваю деф значение
часть функции в которой работаю с переменной
Криминала я тут не усматриваю.
Посему возникает два вопроса: в каком месте "портится" переменная и каким образом контролируется "порча"?
Вы же понимаете, что можно сделать так:
И экспериментально определить - портится ли переменная в процессе присвоения или же туда попадает уже "испорченное", таким образом локализовав проблемное место в коде и, в последствии, сосредоточить внимание на нём и его взаимосвязях с остальными частями прошивки.
Предваряя вопрос, отвечаю: более простого пути нет и волшебного фонаря, который подсветит ошибку в коде - тоже нет. Всё в этом деле - через тернии к звёздам.
вот вывод в консоль
все работает стабильно пока не сработает клик по энкодеру, после него несколько раз повернул и получил 0
и в чем собственно жопа, уважаемый??? можете более детально для простых людей объяснить на примере??
Если же Вы хотите организовать меню через автомат. Да я этой методы то где это??
А ежели так сделать: btn_timer = 20; - в переменной после "... after" тоже 0 будет?
Удивительное, конечно дело. Что-то я не могу придумать иных причин, кроме порчи значений вследствие недостатка памяти. Сколько IDE пишет в остатках RAM после компиляции?
Надо брать слона целиком, если конечно интересует слон а не его филейные части.
Напрямую присвоил цифру 20, итого нуль все равно.
по памяти вот что пишет, насколько понимаю вполне хватает
А что за компилятор такой странный?
Я тут не могу ничего пояснить. Если уж константа не присваивается, то дело пахнет керосином.
Надо брать слона целиком, если конечно интересует слон а не его филейные части.
теперь понятно почему у вас был такой пролог
да вы правы в моем коде есть часть вашего, но это было не просто копи паст, я искал варианты решения. наткнулся на этот форум. читал ветку на форуме с вашим кодом, вот и отложилось, но просто у меня проблема как мне кажется в другом
А что за компилятор такой странный?
Я тут не могу ничего пояснить. Если уж константа не присваивается, то дело пахнет керосином.
я через sublime text 3 c модулем для ардуино компилирую
попробовал скомпилировать в Arduino IDE
Для теста:
firstLine[50];
secondLine[50];
Хотя, уже понятно, что \0 не учитываете, суёте в буфер 17 символов и функция ещё сама 0x00 лепит в конец:
------------
The size of the buffer should be large enough to contain the entire resulting string (see snprintf for a safer version).
A terminating null character is automatically appended after the content.
------------
Для теста:
firstLine[50];
secondLine[50];
Хотя, уже понятно, что \0 не учитываете, суёте в буфер 17 символов и функция ещё сама 0x00 лепит в конец:
------------
The size of the buffer should be large enough to contain the entire resulting string (see snprintf for a safer version).
A terminating null character is automatically appended after the content.
------------
подправил, и все норм заработало. видимо в этом и была проблема. Спасибо Вам большое!
Ну, тогда надо snprintf использовать, чтобы не было пересечений переменных в памяти.
Ну, тогда надо snprintf использовать, чтобы не было пересечений переменных в памяти.
честно говоря я не знал, что может быть такое. после этого теперь буду учитывать. это как раз первые тернии, про которые вы говорили
Просто помните, что компилятор - Ваш друг.
И лучше всего будет включить вывод всех предупреждений, не игнорируя их. Тогда 90% ошибок отсеются сразу.