Собираю примитивное меню. при запуске дуни в цикле вызывается функция. выводит время на TFT Код (C++): void loop() { Serial.print("loop");// смотрим перешли ли мы в цикл. times(); } при нажатии на тач сразу перехожу в меню, ну и с меню обратно в часы по окончанию манипуляций ухожу с кнопки на таче. но минуты через 3 ардуинка именно в часах зависает. не знаю как реализовать бесконечный цикл. Код часов реализован так: Код (C++): void times() { Serial.println("times");// смотрим перешли ли мы unsigned long timer = 0, timerPrev = 0; timer = millis(); if (timer - timerPrev > 999) { // если прошла 1 секунда myGLCD.setColor(255, 255, 255); myGLCD.setFont(SevenSeg_XXXL_Num); myGLCD.print(String(time.gettime("H")), 12, 60); myGLCD.print(String(time.gettime("i")), 180, 60); myGLCD.fillCircle(160, 88, 7); //Верхняя точка myGLCD.fillCircle(160, 133, 7); //Нижняя точка myGLCD.setColor(0, 255, 0); myGLCD.setFont(SmallFont); myGLCD.print(String(time.gettime("d:m:Y")), CENTER, 190); myGLCD.print(String(time.gettime("s")), CENTER, 160);// для визуального наблюдения как тикают секунды } if (myTouch.dataAvailable()) { myGLCD.clrScr(); menu(); } loop(); } пробовал оставлять код в цикле, когда перехожу из меню в loop() то часики уже не ходят. И еще вопрос, допустим я остался в меню, как сделать что бы через 5 минут бездействия осуществлялся переход на часы?
Код (C++): void times() { // Serial.println("times");// смотрим перешли ли мы // нечего тут смотреть .. и так знаем что каждый новый цикл мы тут как тут // unsigned long timer = 0, timerPrev = 0; // это не надо // timer = millis(); // и это не надо // if (timer - timerPrev > 999) и это тоже можно удалить if((millis() % 1000) == 0) { // если прошла 1 секунда myGLCD.setColor(255, 255, 255); myGLCD.setFont(SevenSeg_XXXL_Num); myGLCD.print(String(time.gettime("H")), 12, 60); myGLCD.print(String(time.gettime("i")), 180, 60); myGLCD.fillCircle(160, 88, 7); //Верхняя точка myGLCD.fillCircle(160, 133, 7); //Нижняя точка myGLCD.setColor(0, 255, 0); myGLCD.setFont(SmallFont); myGLCD.print(String(time.gettime("d:m:Y")), CENTER, 190); myGLCD.print(String(time.gettime("s")), CENTER, 160);// для визуального наблюдения как тикают секунды } if (myTouch.dataAvailable()) { // если прикосновение то очищаем экран и валим в меню .. НО!!! меню нету и при каждой новой секунде мы опять что-то там выводим на экран!!!! может если мы в меню то надо забыть про дорогу в times() ??????????????? myGLCD.clrScr(); menu(); } } void loop(){ // Serial.print("loop");// смотрим перешли ли мы в цикл. // тут нечего смотреть потому что после загрузки ардуинки мы уже тут и бегаем по кругу между фигурными скобками times(); // каждый новый цикл забегаем на огонёк в times() }
Я не знаю как у вас выглядит процедура menu(), поэтому делаю некоторое допущение и предлагаю такой подход Код (C++): unsigned long last_tach=0; bool menuActiv = false; void times(int x, int y) { myGLCD.setFont(SevenSegNumFont); myGLCD.setColor(VGA_WHITE); myGLCD.printNumI(hour(), x, y, 2, '0'); myGLCD.printNumI(minute(), x+85, y, 2, '0'); // мигаем разделителем часов и минут if (second() % 2) myGLCD.setColor(myGLCD.getBackColor()); myGLCD.fillCircle(x+74, y+35, 4); myGLCD.fillCircle(x+74, y+14, 4); myGLCD.setColor(VGA_WHITE); myGLCD.setFont(BigFont); } void loop() { // если не активно Меню - выводим время if ( !menuActiv ) { times(635, 230); //координаты X, Y для отображения времени } if (myTouch.dataAvailable()) { last_tach = millis(); // в процедуре меню, после каждого нажатия на кнопку не забываем обновлять last_tach = millis() menuActiv = true; myGLCD.clrScr(); menu(); } if ( menuActiv && millis() - last_tach > 180000 ) { menuActiv = !menuActiv; //если ничего не нажимали 3 минуты - деактивируем меню myGLCD.clrScr(); } } для того что бы в скетче работали функции времени типа hour() и т.п. включите в проект <Time.h> и setup() нужно вызвать прцедуру установки времени setTime с соответсвующими параметрами.
Спасибо, ситуация прежняя, стоит покинуть часы после включения дуни, то при новом заходе на них время стоит. Спасибо за код, очень наглядный пример для себя, есть чему поучится) у меня библиотека RTC и очень нравится, вернул обращение к времени свои параметры. это поставил в меню Код (C++): if ( menuActiv && millis() - last_tach > 25000 ) { menuActiv = !menuActiv; //если ничего не нажимали 3 минуты - деактивируем меню myButtons.deleteAllButtons(); myGLCD.clrScr(); loop(); } но не стабатывает. при переходе в часы по тапу кнопки часики опять стоят) код меню Код (C++): void menu() { myGLCD.setFont(SmallFont); int but_hg, but_wh, otstup_x, otstup_y, check; but_hg = 30; but_wh = 85; otstup_x = 19; otstup_y = 10; Serial.print(menuActiv); int button1, button2, settime, button4, button5, button6, settings, block; button1 = myButtons.addButton(otstup_x, otstup_y, but_wh, but_hg, "Settings"); button2 = myButtons.addButton(otstup_x * 2 + but_wh, otstup_y, but_wh, but_hg, "Time"); settime = myButtons.addButton(but_wh * 2 + otstup_x * 3, otstup_y, but_wh, but_hg, "Set Time"); button4 = myButtons.addButton(otstup_x, otstup_y * 2 + but_hg, but_wh, but_hg, "Test"); button5 = myButtons.addButton(otstup_x * 2 + but_wh, otstup_y * 2 + but_hg, but_wh, but_hg, "Test"); button6 = myButtons.addButton(but_wh * 2 + otstup_x * 3, otstup_y * 2 + but_hg, but_wh, but_hg, "Test", BUTTON_DISABLED); // settings = but.addButton block = myButtons.addButton(279, 199, 40, 40, "Y", BUTTON_SYMBOL); myButtons.drawButtons(); while (1) { if (myTouch.dataAvailable() == true) { check = myButtons.checkButtons(); if (check == block) { if (myButtons.buttonEnabled(button6)) myButtons.disableButton(button6, true); else myButtons.enableButton(button6, true); } if (check == button2) { myButtons.deleteAllButtons(); menuActiv = false; myGLCD.clrScr(); loop(); } if (check == settime) { myButtons.deleteAllButtons(); myGLCD.clrScr(); setTimeData(); } if(check == button4){ } } if (check == button1) myGLCD.print("Settings Off ", 110, 220); if (check == -1) myGLCD.print("None ", 110, 220); } if ( menuActiv && millis() - last_tach > 25000 ) { menuActiv = !menuActiv; //если ничего не нажимали 3 минуты - деактивируем меню myButtons.deleteAllButtons(); myGLCD.clrScr(); loop(); } }
Заметил что когда я перехожу в часы, они стоят. Тап по тачу уже не работает. "Я как в комнате без дверей"), но по тапу в пустом месте вылезает None этот кусок кода из меню Код (C++): if (check == -1) // Если ткнули не по кнопке "любое пустое место" то .. myGLCD.print("None ", 110, 220); }
Если коротко: 1.Необходимо в процедуре Меню выполнять только отрисовку кнопок, затем идет возврат в стандартный Луп, где и происходит обработка нажатий кнопок. У вас же при входе в меню начинается бесконечный цикл. 2. Никогда не стоит на выходе из вызванной функции ставить вызов loop(), возвращение в луп происходит автоматически.
Опробовать работу кода не на чем, поэтому это примерный вариант Код (C++): void menu() { myGLCD.setFont(SmallFont); int but_hg, but_wh, otstup_x, otstup_y, check; but_hg = 30; but_wh = 85; otstup_x = 19; otstup_y = 10; Serial.print(menuActiv); int button1, button2, settime, button4, button5, button6, settings, block; button1 = myButtons.addButton(otstup_x, otstup_y, but_wh, but_hg, "Settings"); button2 = myButtons.addButton(otstup_x * 2 + but_wh, otstup_y, but_wh, but_hg, "Time"); settime = myButtons.addButton(but_wh * 2 + otstup_x * 3, otstup_y, but_wh, but_hg, "Set Time"); button4 = myButtons.addButton(otstup_x, otstup_y * 2 + but_hg, but_wh, but_hg, "Test"); button5 = myButtons.addButton(otstup_x * 2 + but_wh, otstup_y * 2 + but_hg, but_wh, but_hg, "Test"); button6 = myButtons.addButton(but_wh * 2 + otstup_x * 3, otstup_y * 2 + but_hg, but_wh, but_hg, "Test", BUTTON_DISABLED); // settings = but.addButton block = myButtons.addButton(279, 199, 40, 40, "Y", BUTTON_SYMBOL); myButtons.drawButtons(); } void loop() { if ( !menuActiv ) // если не активно Меню - выводим время { times(635, 230); //координаты X, Y для отображения времени if (myTouch.dataAvailable()) { last_tach = millis(); // в процедуре меню, после каждого нажатия на кнопку не забываем обновлять last_tach = millis() menuActiv = true; myGLCD.clrScr(); menu(); } } else if ( menuActiv ) // если не активно Меню - выводим время { if (myTouch.dataAvailable()) { last_tach = millis(); check = myButtons.checkButtons(); if (check == block) { if (myButtons.buttonEnabled(button6)) myButtons.disableButton(button6, true); else myButtons.enableButton(button6, true); } else if (check == button2) { myButtons.deleteAllButtons(); menuActiv = false; myGLCD.clrScr(); } else if (check == settime) { myButtons.deleteAllButtons(); myGLCD.clrScr(); setTimeData(); } else if(check == button4) { } else if (check == button1) { myGLCD.print("Settings Off ", 110, 220); } } if (check == -1) myGLCD.print("None ", 110, 220); } if ( menuActiv && millis() - last_tach > 180000 ) { menuActiv = !menuActiv; //если ничего не нажимали 3 минуты - деактивируем меню myGLCD.clrScr(); } }
Спасибо большое за код, но получилось у Вас как и у меня, не понятки в меню. горят часики, тапаю по тачу - улетаю в меню. И вот тут начинается самое не понятное. при нажатии как будто обновляется функция menu() больше похоже как функция вызывается повторно и экран быстро перерисовывает кнопки и никакой реакции на кнопки,еще 2-3 тапа по тачу, кнопки в прямом смысле текут по экрану изменив цвет. часы работают отлично меню как должно быть 3-4 тапа и началось зато в часы по таймеру возвращается)
первой строкой в процедуре menu() поставьте вывод контройльной строки в сериал Serial.println("Start menu"); И посмотрите сколько раз вызывается процедура. Вы взяли уже исправленный мой код? Это важно!
Исправления вводил, так как и предполагал, каждый тап в меню, повторный вызов функции. Terminal Start menu Start menu Start menu St //не понятно что это, тут кнопки поплыли
да с кнопками то как раз понятно, библиотека поддерживает определенное кол-во кнопок, потом начинает глючить. А раз menu() вызывается и предыдущие кнопки не удалены - вот и глюк. Не пойму пока почему происходит повторный вызов, ведь он стоит только в одном месте, и при условии что переменная menuActiv = false Может у вас в коде она еще где то вызывается?
У меня в коде есть еще функция setTimeData() но она не активна. Код (C++): else if (check == settime) { myButtons.deleteAllButtons(); myGLCD.clrScr(); setTimeData(); только тогда она вызывается. переменные в ней локальные, и названия переменных не повторяются, уверен что конфликты исключены.
Добавил в код проверку флага menuActiv, но это уже заплатка. Если и сейчас будет глючить - покажите скетч полностью. Код (C++): void menu() { Serial.print("menuActiv="); Serial.println(menuActiv); if ( !menuActiv ) { Serial.println("Start Menu"); menuActiv = true; myGLCD.setFont(SmallFont); int but_hg, but_wh, otstup_x, otstup_y, check; but_hg = 30; but_wh = 85; otstup_x = 19; otstup_y = 10; Serial.print(menuActiv); int button1, button2, settime, button4, button5, button6, settings, block; button1 = myButtons.addButton(otstup_x, otstup_y, but_wh, but_hg, "Settings"); button2 = myButtons.addButton(otstup_x * 2 + but_wh, otstup_y, but_wh, but_hg, "Time"); settime = myButtons.addButton(but_wh * 2 + otstup_x * 3, otstup_y, but_wh, but_hg, "Set Time"); button4 = myButtons.addButton(otstup_x, otstup_y * 2 + but_hg, but_wh, but_hg, "Test"); button5 = myButtons.addButton(otstup_x * 2 + but_wh, otstup_y * 2 + but_hg, but_wh, but_hg, "Test"); button6 = myButtons.addButton(but_wh * 2 + otstup_x * 3, otstup_y * 2 + but_hg, but_wh, but_hg, "Test", BUTTON_DISABLED); // settings = but.addButton block = myButtons.addButton(279, 199, 40, 40, "Y", BUTTON_SYMBOL); myButtons.drawButtons(); } } void loop() { if ( !menuActiv ) // если не активно Меню - выводим время { times(635, 230); //координаты X, Y для отображения времени if (myTouch.dataAvailable()) { last_tach = millis(); // в процедуре меню, после каждого нажатия на кнопку не забываем обновлять last_tach = millis() myGLCD.clrScr(); menu(); } } else if ( menuActiv ) // если не активно Меню - выводим время { if (myTouch.dataAvailable()) { last_tach = millis(); check = myButtons.checkButtons(); if (check == block) { if (myButtons.buttonEnabled(button6)) myButtons.disableButton(button6, true); else myButtons.enableButton(button6, true); } else if (check == button2) { myButtons.deleteAllButtons(); menuActiv = false; myGLCD.clrScr(); } else if (check == settime) { myButtons.deleteAllButtons(); myGLCD.clrScr(); setTimeData(); } else if(check == button4) { } else if (check == button1) { myGLCD.print("Settings Off ", 110, 220); } } if (check == -1) myGLCD.print("None ", 110, 220); } if ( menuActiv && millis() - last_tach > 180000 ) { menuActiv = !menuActiv; //если ничего не нажимали 3 минуты - деактивируем меню myGLCD.clrScr(); } } PS я бы мог поделться исходниками своего дисплейного модуля, но там около 2000 строк, вы скорее запутаетесь, чем разберетесь.
я точно не разберусь, и точно в элементарные основы не вникну, сейчас то делаю ошибки на каждом шаге) menuActiv=0 Start Menu 1 условие выполнено. весь мой код уже переписан Вами, нового там ничего нету. Код (C++): #include<UTFT.h> #include<UTouch.h> #include<UTFT_Buttons.h> #include <RTC.h> UTFT myGLCD(TFT01_32QVT, 38, 39, 40, 41); UTouch myTouch(6, 5, 4, 3, 2); UTFT_Buttons myButtons(&myGLCD, &myTouch); RTC time; bool menuActiv = false; unsigned long last_tach = 0; int check; int button1, button2, settime, button4, button5, button6, settings, block; extern uint8_t SmallFont[]; extern uint8_t BigFont[]; extern uint8_t SevenSegNumFont[]; extern uint8_t Dingbats1_XL[]; extern uint8_t SevenSeg_XXXL_Num[]; //Подключаем шрифт SevenSeg_XXXL_Num void setup() { time.begin(RTC_DS3231);// иницилизация часов myGLCD.InitLCD(); // иницидизация дисплея myGLCD.clrScr(); //очистка дисплея Serial.begin(9600); myTouch.InitTouch(); // иницидизация тача myButtons.setTextFont(SmallFont); myTouch.setPrecision(PREC_HI);// Чувствительность тача myButtons.setSymbolFont(Dingbats1_XL);//иконки } void loop() { if ( !menuActiv ) // если не активно Меню - выводим время { times(); //координаты X, Y для отображения времени if (myTouch.dataAvailable()) { last_tach = millis(); // в процедуре меню, после каждого нажатия на кнопку не забываем обновлять last_tach = millis() myGLCD.clrScr(); menu(); } } else if ( menuActiv ) // если не активно Меню - выводим время { if (myTouch.dataAvailable()) { last_tach = millis(); check = myButtons.checkButtons(); if (check == block) { if (myButtons.buttonEnabled(button6)) myButtons.disableButton(button6, true); else myButtons.enableButton(button6, true); } else if (check == button2) { myButtons.deleteAllButtons(); menuActiv = false; myGLCD.clrScr(); } else if (check == settime) { myButtons.deleteAllButtons(); myGLCD.clrScr(); setTimeData(); } else if(check == button4) { } else if (check == button1) { myGLCD.print("Settings Off ", 110, 220); } } if (check == -1) myGLCD.print("None ", 110, 220); } if ( menuActiv && millis() - last_tach > 180000 ) { menuActiv = !menuActiv; //если ничего не нажимали 3 минуты - деактивируем меню myGLCD.clrScr(); } } void times() { Serial.println("v time"); myGLCD.setColor(255, 255, 255); myGLCD.setFont(SevenSeg_XXXL_Num); myGLCD.print(String(time.gettime("H")), 12, 60); myGLCD.print(String(time.gettime("i")), 180, 60); myGLCD.setFont(SmallFont); myGLCD.print(String(time.gettime("s")), CENTER, 160); myGLCD.print(String(time.gettime("d:m:Y")), CENTER, 190); // мигаем разделителем часов и минут if (time.seconds % 2) myGLCD.setColor(myGLCD.getBackColor()); myGLCD.fillCircle(160, 88, 7); //Верхняя точка myGLCD.fillCircle(160, 133, 7); //Нижняя точка } void setTimeData() { myGLCD.setFont(BigFont); Serial.println("Set time"); /***********************Рамки*************************/ myGLCD.drawRoundRect(1, 1, 318, 100); myGLCD.print("Time:", 16, 42); myGLCD.drawRoundRect(1, 104, 318, 194); myGLCD.print("Date:", 16, 141); myGLCD.print(":", 175, 42 ); myGLCD.print(":", 245, 42); myGLCD.print(":", 175, 141); myGLCD.print(":", 245, 141); /******************берем данные времени************/ myGLCD.print(String(time.gettime("H")), 132, 42); myGLCD.print(String(time.gettime("i")), 202, 42); myGLCD.print(String(time.gettime("s")), 272, 42); /************************и даты********************/ myGLCD.print(String(time.gettime("d")), 132, 141); myGLCD.print(String(time.gettime("m")), 202, 141); myGLCD.print(String(time.gettime("y")), 272, 141); /*********************Изменение времени**************) /******************************************************/ short int hours_up, hours_down, min_up, min_down, sec_up, sec_down, month_up, month_down, day_up, day_down, year_up, year_duwn, cancel, save; short int but_hg, but_wh; int checkButtonSetTime; but_hg = 25; but_wh = 25; /**********************TIME BUTTONS****************************/ hours_up = myButtons.addButton(135, 10, but_wh, but_hg, " +"); hours_down = myButtons.addButton(135, 64, but_wh, but_hg, " -"); min_up = myButtons.addButton(205, 10, but_wh, but_hg, " +"); min_down = myButtons.addButton(205, 64, but_wh, but_hg, " -"); sec_up = myButtons.addButton(275, 10, but_wh, but_hg, " +"); sec_down = myButtons.addButton(275, 64, but_wh, but_hg, " -"); /**********************DATE BUTTONS****************************/ month_up = myButtons.addButton(135, 112, but_wh, but_hg, "+"); month_down = myButtons.addButton(135, 161, but_wh, but_hg, "-"); day_up = myButtons.addButton(205, 112, but_wh, but_hg, "+"); day_down = myButtons.addButton(205, 161, but_wh, but_hg, "-"); year_up = myButtons.addButton(275, 112, but_wh, but_hg, "+"); year_duwn = myButtons.addButton(275, 161, but_wh, but_hg, "-"); /**********************BUTTONS*************************/ cancel = myButtons.addButton(1, 200, 150, 39, "Cancel"); save = myButtons.addButton(167, 200, 150, 39, "Save"); myButtons.drawButtons(); while (1) { if (myTouch.dataAvailable() == true) { checkButtonSetTime = myButtons.checkButtons(); if (check == hours_up) { } if (checkButtonSetTime == cancel) { myButtons.deleteAllButtons(); myGLCD.clrScr(); menu(); } } } }
Забыл добавить, в меню переходит, но нажатия не обрабатываются, но тач работает. кнопки как бы нажимаются, но без результата
Мой косяк, переменные Код (C++): int button1, MyTime, settime, button4, button5, button6, settings, block; были объявлены глобально и локально в функции. удалил лишнее все встало на свои места. за помощь могу подкинуть на чай/кофе/пиво/шоколадку) все таки не мало времени пилили мой недоКод)
Вроде все летает как надо. Спасибо большое за помощь. Если можно еще это обьясните Код (C++): if (myTouch.dataAvailable()) { last_tach = millis()}; тут при нажатии счетчик начинает крутить заново заполняя переменную Код (C++): if ( menuActiv && millis() - last_tach > 180000 ) тут "если menuActiv==true" && last_tach > 180000 так бы я понял. а зачем millis() - last_tach > 180000. и для чего тире?