Доброго времени суток. Прошу помочь с такой проблемкой. Решил собрать часы на Меге 2560 и 2.4"тфт экранчике. Модуль часов на DS1307. Из функций - отображение времени, даты, будильника, настройка всего этого, различные реакции на определенные действия (например проигрывание аудиофайла при наклоне часов, подсветка при снижении освещенности и т.д). Пока что риализованы лишь только часы, остальное пилю по малу. Проблема в следующем, срабатывание тачскрина (управление часами ведется с него) неадекватное. Бывает срабатывает сразу, бывает надо раз 10 тыкнуть в кнопку, что бы сработал. В общем беда. Посмотрите пожалуйста, кому не трудно, что не так делаю? Что поправить? И еще. Стандартный шрифт Adafruit уж больно "квадратный", особенно большие цифры. Искал какие-нибудь более красивые шрифты с поддержкой кирилицы и ничего не нашел... Может подскажите где найти? Собственно сам код: Код (C++): // Подключаем библиотеки #include <Adafruit_GFX.h> // Базовая графическая библиотека дисплея #include <Adafruit_TFTLCD.h> // Аппаратно-зависимая библиотека дисплея #include <TouchScreen.h> // Библиотека тачскрина #include <iarduino_RTC.h> // Подключение библиотеки для часового модуля iarduino_RTC time(RTC_DS1307); // объявляем переменную для работы с RTC модулем, указывая название модуля // Назначение Аналоговых пинов для дисплея #define LCD_CS A3 // Chip Select подключаем к Analog 3 #define LCD_CD A2 // Command/Data подключаем к Analog 2 #define LCD_WR A1 // LCD Write подключаем к Analog 1 #define LCD_RD A0 // LCD Read подключаем к Analog 0 #define LCD_RESET A4 // Reset подключаем к Analog 4 /* Линии данных дисплея подключаем к цифровым пинам (для Mega) D0 connects to digital pin 22 D1 connects to digital pin 23 D2 connects to digital pin 24 D3 connects to digital pin 25 D4 connects to digital pin 26 D5 connects to digital pin 27 D6 connects to digital pin 28 D7 connects to digital pin 29 */ // Назначение пинов для тачскрина #define YP A1 // Подключаем к Analog 1 #define XM A2 // Подключаем к Analog 2 #define YM 29 // Подключаем к digital pin 29 #define XP 28 // Подключаем к digital pin 28 // Минемальные и максимальные координаты по осям тачскрина #define TS_MINX 180 #define TS_MINY 183 #define TS_MAXX 895 #define TS_MAXY 942 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); // Подключение тачскрина // Назначение удобочитаемых имен некоторым общим 16-разрядным цветовым значениям: #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); // Подключаем дисплей // Объявляем переменные и константы: const uint8_t PIN_alarm_TONE = 5; // указываем номер вывода arduino, к которому подключён зуммер будильника uint8_t VAR_mode_SET = 0; // режим работы часов: 0-время 1-установка будильника 2-меню 3-установка часов 4-установка даты 5-настройка датчиков uint8_t VAR_alarm_MIN = 0; // будильник минуты uint8_t VAR_alarm_HOUR = 0; // будильник часы bool VAR_alarm_FLAG1 = true; // будильник разрешение работы bool VAR_alarm_FLAG2 = false; // будильник совершение действий (сигнализация) void setup(void) { digitalWrite(PIN_alarm_TONE, LOW); // устанавливаем уровень логического «0» на выводе PIN_alarm_TONE tft.reset(); // Очищаем дисплей time.begin(); // Инициируем RTC модуль // time.settime(0,45,15,03,05,18,4); // Записываем время в модуль: 0 сек, 45 мин, 15 час, 03, мая, 2018 года, четверг. tft.begin(0x9341); // Инициируем дисплей tft.cp437(true); // Включаем поддержку русского шрифта tft.setRotation(3); // Поворачиваем экран в горизонт tft.fillScreen(BLACK); // Закрашиваем экран черным } // Минимальная и максимальная сила нажатия #define MINPRESSURE 10 #define MAXPRESSURE 1000 }
Весь код не влез, продолжение: Код (C++): void loop(void) { int weekday, month; // назначаем переменные weekday = time.weekday; // присваиваем значения переменным month = time.month; /* // Чтение тачскрина Serial.begin(9600); Serial.println(F("Calibrovka")); TSPoint p = ts.getPoint(); // Считывание координат pinMode(XM, OUTPUT); // Объявление пинов как выход pinMode(YP, OUTPUT); // **************************** ОБРАБОТКА НАЖАТИЯ НА ТАЧСКРИН ******************************************** // Если сила нажатия попадает в допустимый диапазон то начинаем обработку if (p.z > MINPRESSURE && p.z < MAXPRESSURE) { Serial.print("X = "); Serial.print(p.x); Serial.print("\tY = "); Serial.print(p.y); Serial.print("\tPressure = "); Serial.println(p.z); Serial.print("\tVAR_mode_SET = "); Serial.println(VAR_mode_SET); // Маштабирование координат из 0-1023 в 320-240 // p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0); // p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0); } */ // if(millis()%1000==0){ // если прошла 1 секунда if(VAR_mode_SET==0){ // Если выводится время // Выводим день недели tft.setTextColor(MAGENTA, BLACK); // Цвет текста и фона tft.setTextSize(3); // Объявляем размер шрифта tft.setCursor(40, 10); // Ставим курсор time.gettime(); // Опрашиваем модуль часов if (weekday == 0){tft.print(utf8rus ("Воскресенье"));} // Выводим Воскресенье if (weekday == 1){tft.print(utf8rus ("Понедельник"));} // Выводим Понедельник if (weekday == 2){tft.print(utf8rus ("Вторник "));} // Выводим Вторник if (weekday == 3){tft.print(utf8rus ("Среда "));} // Выводим Среда if (weekday == 4){tft.print(utf8rus ("Четверг "));} // Выводим Четверг if (weekday == 5){tft.print(utf8rus ("Пятница "));} // Выводим Пятница if (weekday == 6){tft.print(utf8rus ("Суббота "));} // Выводим Суббота // Выводим секунды tft.setTextColor(BLUE, BLACK); // Цвет текста и фона tft.setCursor(260, 10); // Ставим курсор tft.print(time.gettime("s")); // Выводим секунды //Выводим часы и минуты tft.setTextColor(GREEN, BLACK); // Цвет текста и фона tft.setTextSize(11); // Объявляем размер шрифта tft.setCursor(12, 60); // Ставим курсор tft.print(time.gettime("H")); // Выводим часы tft.setCursor(188, 60); // Ставим курсор tft.print(time.gettime("i")); // Выводим минуты tft.fillCircle(160, 80, 7, RED); // Ставим верхнюю точку tft.fillCircle(160, 120, 7, RED); // ставим нижнюю точку // Выводим дату tft.setTextColor(YELLOW, BLACK); // Цвет текста и фона tft.setTextSize(3); // Объявляем размер шрифта tft.setCursor(30, 160); // Ставим курсор для даты tft.print(time.gettime("d")); // Выводим дату // Выводим месяц tft.setCursor(80, 160); // Ставим курсор if (month == 1){tft.print(utf8rus ("Января "));} // Выводим Январь if (month == 2){tft.print(utf8rus ("Февраля "));} // Выводим Февраль if (month == 3){tft.print(utf8rus ("Марта "));} // Выводим Март if (month == 4){tft.print(utf8rus ("Апреля "));} // Выводим Апрель if (month == 5){tft.print(utf8rus ("Мая "));} // Выводим Май if (month == 6){tft.print(utf8rus ("Июня "));} // Выводим Июнь if (month == 7){tft.print(utf8rus ("Июля "));} // Выводим Июль if (month == 8){tft.print(utf8rus ("Августа "));} // Выводим Август if (month == 9){tft.print(utf8rus ("Сентября"));} // Выводим Сентябрь if (month == 10){tft.print(utf8rus ("Октября "));} // Выводим Октябрь if (month == 11){tft.print(utf8rus ("Ноября "));} // Выводим Ноябрь if (month == 12){tft.print(utf8rus ("Декабря "));} // Выводим Декабрь // Выводим год tft.setCursor(230, 160); // Ставим курсор tft.print(time.gettime("Y")); // Выводим Год /* // проверка будильника if(VAR_alarm_FLAG1){ // Если будильник включён if(time.seconds==00){ // Если в текущем времени 0 секунд if(time.minutes==VAR_alarm_MIN){ // Если совпали минуты if(time.Hours==VAR_alarm_HOUR){ // Если совпали часы VAR_alarm_FLAG2=true; // устанавливаем флаг разрешающий совершение действий будильника (сигнализация) } } } }else{VAR_alarm_FLAG2=false;} // Если будильник выключен, то сбрасываем флаг разрешающий совершение действий будильника (сигнализация) if(VAR_alarm_FLAG2){Func_alarm_action();} // Запускаем действия будильника */ // Кнопки меню tft.setTextSize(3); // Объявляем размер шрифта tft.setTextColor(CYAN, BLACK); // Цвет текста и фона tft.drawRoundRect(20, 192, 130, 36, 10, CYAN); // Рисуем поле кнопки Часы tft.setCursor(46, 198); // Ставим курсор tft.print(utf8rus ("Меню")); // Выводим название кнопки Меню tft.drawRoundRect(170, 192, 130, 36, 10, CYAN); // Рисуем поле кнопки Сигнал tft.setCursor(185, 198); // Ставим курсор tft.print(utf8rus ("Сигнал")); // Выводим название кнопки будильника // **************************** ОБРАБОТКА НАЖАТИЯ НА ТАЧСКРИН ******************************************** TSPoint p = ts.getPoint(); // Считывание координат pinMode(XM, OUTPUT); // Объявление пинов как выход pinMode(YP, OUTPUT); if (p.z > MINPRESSURE && p.z < MAXPRESSURE) { if (p.x > 760 && p.x < 860 && p.y > 230 && p.y < 530) { // Если попали в кнопку Сигнал tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_mode_SET = 1; // Объявляем режим 1 } if (p.x > 760 && p.x < 860 && p.y > 590 && p.y < 890) { // Если попали в кнопку Меню tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_mode_SET = 2; // Объявляем режим 2 } } }
Далее: Код (C++): if(VAR_mode_SET==1){ // Если будильник устанавливается tft.setTextColor(MAGENTA, BLACK); // Цвет текста и фона tft.setTextSize(2); // Объявляем размер шрифта tft.setCursor(40, 10); // Ставим курсор tft.print(utf8rus ("Установка будильника")); // Выводим текст tft.setTextColor(GREEN, BLACK); // Цвет текста и фона tft.setTextSize(4); // Объявляем размер шрифта tft.setCursor(96, 80); // Ставим курсор tft.print(VAR_alarm_HOUR); // Выводим часы будильника tft.setCursor(180, 80); // Ставим курсор tft.print(VAR_alarm_MIN); // Выводим минуты будильника tft.fillCircle(160, 86, 3, GREEN); // Ставим верхнюю точку tft.fillCircle(160, 102, 3, GREEN); // ставим нижнюю точку // Кнопки настройки tft.setTextSize(3); // Объявляем размер шрифта tft.setTextColor(YELLOW, BLACK); // Цвет текста tft.drawCircle(60, 60, 20, YELLOW); // Рисуем поле кнопки + tft.setCursor(53, 50); // Ставим курсор tft.print("+"); // Выводим название кнопки tft.drawCircle(260, 60, 20, YELLOW); // Рисуем поле кнопки + tft.setCursor(253, 50); // Ставим курсор tft.print("+"); // Выводим название кнопки tft.drawCircle(60, 130, 20, YELLOW); // Рисуем поле кнопки - tft.setCursor(53, 120); // Ставим курсор tft.print("-"); // Выводим название кнопки tft.drawCircle(260, 130, 20, YELLOW); // Рисуем поле кнопки - tft.setCursor(253, 120); // Ставим курсор tft.print("-"); // Выводим название кнопки tft.setTextColor(CYAN, BLACK); // Цвет текста tft.drawRoundRect(170, 192, 130, 36, 10, CYAN); // Рисуем поле кнопки Назад tft.setCursor(190, 198); // Ставим курсор tft.print(utf8rus ("Назад")); // Выводим название кнопки // **************************** ОБРАБОТКА НАЖАТИЯ НА ТАЧСКРИН ******************************************** TSPoint p = ts.getPoint(); // Считывание координат pinMode(XM, OUTPUT); // Объявление пинов как выход pinMode(YP, OUTPUT); if (p.z > MINPRESSURE && p.z < MAXPRESSURE) { if (p.x > 760 && p.x < 860 && p.y > 230 && p.y < 530) { // Если попали в кнопку Назад tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_mode_SET = 0; // Объявляем режим 0 } if (p.x > 300 && p.x < 430 && p.y > 740 && p.y < 840) { // Если попали в кнопку + часы // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_alarm_HOUR=VAR_alarm_HOUR==23?0:VAR_alarm_HOUR+1; // Увеличиваем значение часов на 1 } if (p.x > 520 && p.x < 640 && p.y > 740 && p.y < 840) { // Если попали в кнопку - часы // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_alarm_HOUR=VAR_alarm_HOUR==0?23:VAR_alarm_HOUR-1; // Уменьшаем значение часов на 1 } if (p.x > 300 && p.x < 430 && p.y > 270 && p.y < 370) { // Если попали в кнопку + минуты // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_alarm_MIN =VAR_alarm_MIN ==59?0:VAR_alarm_MIN +1; // Увеличиваем значение минут на 1 } if (p.x > 520 && p.x < 640 && p.y > 270 && p.y < 370) { // Если попали в кнопку - минуты // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_alarm_MIN =VAR_alarm_MIN ==0?59:VAR_alarm_MIN -1; // Уменьшаем значение минут на 1 } } } if(VAR_mode_SET==2){ // Если вошли в Меню tft.setTextColor(MAGENTA, BLACK); // Цвет текста и фона tft.setTextSize(2); // Объявляем размер шрифта tft.setCursor(140, 10); // Ставим курсор tft.print(utf8rus ("Меню")); // Выводим текст // Кнопки Меню tft.setTextSize(3); // Объявляем размер шрифта tft.setTextColor(YELLOW, BLACK); // Цвет текста и фона tft.drawRoundRect(60, 40, 200, 40, 10, YELLOW); // Рисуем поле кнопки Время tft.setCursor(100, 50); // Ставим курсор tft.print(utf8rus ("Время")); // Выводим название кнопки tft.drawRoundRect(60, 90, 200, 40, 10, YELLOW); // Рисуем поле кнопки Дата tft.setCursor(100, 100); // Ставим курсор tft.print(utf8rus ("Дата")); // Выводим название кнопки tft.drawRoundRect(60, 140, 200, 40, 10, YELLOW); // Рисуем поле кнопки Датчики tft.setCursor(100, 150); // Ставим курсор tft.print(utf8rus ("Датчики")); // Выводим название кнопки tft.drawRoundRect(60, 190, 200, 40, 10, CYAN); // Рисуем поле кнопки Назад tft.setCursor(100,200); // Ставим курсор tft.print(utf8rus ("Назад")); // Выводим название кнопки // **************************** ОБРАБОТКА НАЖАТИЯ НА ТАЧСКРИН ******************************************** TSPoint p = ts.getPoint(); // Считывание координат pinMode(XM, OUTPUT); // Объявление пинов как выход pinMode(YP, OUTPUT); if (p.z > MINPRESSURE && p.z < MAXPRESSURE) { if (p.x > 300 && p.x < 420 && p.y > 320 && p.y < 790) { // Если попали в кнопку Время tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_mode_SET = 3; // Объявляем режим 3 } if (p.x > 460 && p.x < 570 && p.y > 320 && p.y < 790) { // Если попали в кнопку Дата tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_mode_SET = 4; // Объявляем режим 4 } if (p.x > 610 && p.x < 720 && p.y > 320 && p.y < 790) { // Если попали в кнопку Датчики tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_mode_SET = 5; // Объявляем режим 5 } if (p.x > 760 && p.x < 870 && p.y > 320 && p.y < 790) { // Если попали в кнопку Назад tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_mode_SET = 0; // Объявляем режим 0 } } }
Далее: Код (C++): if(VAR_mode_SET==3){ // Если время устанавливается tft.setTextColor(MAGENTA, BLACK); // Цвет текста и фона tft.setTextSize(2); // Объявляем размер шрифта tft.setCursor(60, 10); // Ставим курсор tft.print(utf8rus ("Настройка времени")); // Выводим текст tft.setTextColor(GREEN, BLACK); // Цвет текста и фона tft.setTextSize(4); // Объявляем размер шрифта tft.setCursor(96, 80); // Ставим курсор tft.print(time.gettime("H")); // Выводим часы tft.setCursor(180, 80); // Ставим курсор tft.print(time.gettime("i")); // Выводим минуты tft.fillCircle(160, 86, 3, GREEN); // Ставим верхнюю точку tft.fillCircle(160, 102, 3, GREEN); // ставим нижнюю точку // Кнопки настройки tft.setTextSize(3); // Объявляем размер шрифта tft.setTextColor(YELLOW, BLACK); // Цвет текста и фона tft.drawCircle(60, 60, 20, YELLOW); // Рисуем поле кнопки + tft.setCursor(53, 50); // Ставим курсор tft.print("+"); // Выводим название кнопки tft.drawCircle(260, 60, 20, YELLOW); // Рисуем поле кнопки + tft.setCursor(253, 50); // Ставим курсор tft.print("+"); // Выводим название кнопки tft.drawCircle(60, 130, 20, YELLOW); // Рисуем поле кнопки - tft.setCursor(53, 120); // Ставим курсор tft.print("-"); // Выводим название кнопки tft.drawCircle(260, 130, 20, YELLOW); // Рисуем поле кнопки - tft.setCursor(253, 120); // Ставим курсор tft.print("-"); // Выводим название кнопки tft.setTextColor(CYAN, BLACK); // Цвет текста и фона tft.drawRoundRect(170, 192, 130, 36, 10, CYAN); // Рисуем поле кнопки Назад tft.setCursor(190, 198); // Ставим курсор tft.print(utf8rus ("Назад")); // Выводим название кнопки // **************************** ОБРАБОТКА НАЖАТИЯ НА ТАЧСКРИН ******************************************** TSPoint p = ts.getPoint(); // Считывание координат pinMode(XM, OUTPUT); // Объявление пинов как выход pinMode(YP, OUTPUT); if (p.z > MINPRESSURE && p.z < MAXPRESSURE) { if (p.x > 760 && p.x < 860 && p.y > 230 && p.y < 530) { // Если попали в кнопку Назад tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_mode_SET = 0; // Объявляем режим 0 } if (p.x > 300 && p.x < 430 && p.y > 740 && p.y < 840) { // Если попали в кнопку + часы // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, -1, (time.Hours==23?0:time.Hours+1), -1, -1, -1, -1); // Увеличиваем значение часов на 1 } if (p.x > 520 && p.x < 640 && p.y > 740 && p.y < 840) { // Если попали в кнопку - часы // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, -1, (time.Hours==0?23:time.Hours-1), -1, -1, -1, -1); // Уменьшаем значение часов на 1 } if (p.x > 300 && p.x < 430 && p.y > 270 && p.y < 370) { // Если попали в кнопку + минуты // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, (time.minutes==59?0:time.minutes+1), -1, -1, -1, -1, -1); // Увеличиваем значение минут на 1 } if (p.x > 520 && p.x < 640 && p.y > 270 && p.y < 370) { // Если попали в кнопку - минуты // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, (time.minutes==0?59:time.minutes-1), -1, -1, -1, -1, -1); // Уменьшаем значение минут на 1 } } } }
Чеж так мало влезает то.. : Код (C++): if(VAR_mode_SET==4){ // Если дата устанавливается //tft.reset(); // Очищаем дисплей tft.setTextColor(MAGENTA, BLACK); // Цвет текста и фона tft.setTextSize(2); // Объявляем размер шрифта tft.setCursor(60, 10); // Ставим курсор tft.print(utf8rus ("Настройка Даты")); // Выводим текст tft.setTextColor(GREEN, BLACK); // Цвет текста и фона tft.setTextSize(3); // Объявляем размер шрифта tft.setCursor(20, 72); // Ставим курсор tft.print(time.gettime("d")); // Выводим дату tft.setCursor(70, 72); // Ставим курсор if (month == 1){tft.print(utf8rus ("Января "));} // Выводим Январь if (month == 2){tft.print(utf8rus ("Февраля "));} // Выводим Февраль if (month == 3){tft.print(utf8rus ("Марта "));} // Выводим Март if (month == 4){tft.print(utf8rus ("Апреля "));} // Выводим Апрель if (month == 5){tft.print(utf8rus ("Мая "));} // Выводим Май if (month == 6){tft.print(utf8rus ("Июня "));} // Выводим Июнь if (month == 7){tft.print(utf8rus ("Июля "));} // Выводим Июль if (month == 8){tft.print(utf8rus ("Августа "));} // Выводим Август if (month == 9){tft.print(utf8rus ("Сентября"));} // Выводим Сентябрь if (month == 10){tft.print(utf8rus ("Октября "));} // Выводим Октябрь if (month == 11){tft.print(utf8rus ("Ноября "));} // Выводим Ноябрь if (month == 12){tft.print(utf8rus ("Декабря "));} // Выводим Декабрь tft.setCursor(230, 72); // Ставим курсор tft.print(time.gettime("Y")); // Выводим Год tft.setCursor(66, 150); // Ставим курсор if (weekday == 0){tft.print(utf8rus ("Воскресенье"));} // Выводим Воскресенье if (weekday == 1){tft.print(utf8rus ("Понедельник"));} // Выводим Понедельник if (weekday == 2){tft.print(utf8rus ("Вторник "));} // Выводим Вторник if (weekday == 3){tft.print(utf8rus ("Среда "));} // Выводим Среда if (weekday == 4){tft.print(utf8rus ("Четверг "));} // Выводим Четверг if (weekday == 5){tft.print(utf8rus ("Пятница "));} // Выводим Пятница if (weekday == 6){tft.print(utf8rus ("Суббота "));} // Выводим Суббота // Кнопки настройки tft.setTextSize(3); // Объявляем размер шрифта tft.setTextColor(YELLOW, BLACK); // Цвет текста и фона tft.drawCircle(36, 50, 14, YELLOW); // Рисуем поле кнопки + tft.setCursor(29, 40); // Ставим курсор tft.print("+"); // Выводим название кнопки tft.drawCircle(120, 50, 14, YELLOW); // Рисуем поле кнопки + tft.setCursor(113, 40); // Ставим курсор tft.print("+"); // Выводим название кнопки tft.drawCircle(260, 50, 14, YELLOW); // Рисуем поле кнопки + tft.setCursor(253, 40); // Ставим курсор tft.print("+"); // Выводим название кнопки tft.drawCircle(36, 115, 14, YELLOW); // Рисуем поле кнопки - tft.setCursor(29, 105); // Ставим курсор tft.print("-"); // Выводим название кнопки tft.drawCircle(120, 115, 14, YELLOW); // Рисуем поле кнопки - tft.setCursor(113, 105); // Ставим курсор tft.print("-"); // Выводим название кнопки tft.drawCircle(260, 115, 14, YELLOW); // Рисуем поле кнопки - tft.setCursor(253, 105); // Ставим курсор tft.print("-"); // Выводим название кнопки tft.drawCircle(36, 160, 14, YELLOW); // Рисуем поле кнопки + tft.setCursor(29, 150); // Ставим курсор tft.print("+"); // Выводим название кнопки tft.drawCircle(280, 160, 14, YELLOW); // Рисуем поле кнопки - tft.setCursor(273, 150); // Ставим курсор tft.print("-"); // Выводим название кнопки tft.setTextColor(CYAN, BLACK); // Цвет текста и фона tft.drawRoundRect(170, 192, 130, 36, 10, CYAN); // Рисуем поле кнопки Назад tft.setCursor(190, 198); // Ставим курсор tft.print(utf8rus ("Назад")); // Выводим название кнопки // **************************** ОБРАБОТКА НАЖАТИЯ НА ТАЧСКРИН ******************************************** TSPoint p = ts.getPoint(); // Считывание координат pinMode(XM, OUTPUT); // Объявление пинов как выход pinMode(YP, OUTPUT); if (p.z > MINPRESSURE && p.z < MAXPRESSURE) { if (p.x > 760 && p.x < 860 && p.y > 230 && p.y < 530) { // Если попали в кнопку Назад tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_mode_SET = 0; // Объявляем режим 0 } if (p.x > 290 && p.x < 380 && p.y > 820 && p.y < 890) { // Если попали в кнопку + Дата // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, -1, -1, (time.day==31?1:time.day+1), -1, -1, -1); // Увеличиваем значение даты на 1 } if (p.x > 480 && p.x < 570 && p.y > 820 && p.y < 890) { // Если попали в кнопку - Дата // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, -1, -1, (time.day==1?31:time.day-1), -1, -1, -1); // Уменьшаем значение даты на 1 } if (p.x > 290 && p.x < 380 && p.y > 620 && p.y < 690) { // Если попали в кнопку + месяц // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, -1, -1, -1, (time.month==12?1:time.month+1), -1, -1); // Увеличиваем значение месяца на 1 } if (p.x > 480 && p.x < 570 && p.y > 620 && p.y < 690) { // Если попали в кнопку - месяц // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, -1, -1, -1, (time.month==1?12:time.month-1), -1, -1); // Уменьшаем значение месяца на 1 } if (p.x > 290 && p.x < 380 && p.y > 280 && p.y < 360) { // Если попали в кнопку + год // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, -1, -1, -1, -1, (time.year==99?0:time.year+1), -1); // Увеличиваем значение года на 1 } if (p.x > 480 && p.x < 570 && p.y > 280 && p.y < 360) { // Если попали в кнопку - год // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, -1, -1, -1, -1, (time.year==0?99:time.year-1), -1); // Уменьшаем значение года на 1 } if (p.x > 630 && p.x < 710 && p.y > 820 && p.y < 890) { // Если попали в кнопку + день // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, -1, -1, -1, -1, -1, (time.weekday==6?0:time.weekday+1) ); // Увеличиваем значение дня на 1 } if (p.x > 630 && p.x < 710 && p.y > 230 && p.y < 310) { // Если попали в кнопку - день // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие time.settime(-1, -1, -1, -1, -1, -1, (time.weekday==0?6:time.weekday-1) ); // Уменьшаем значение дня на 1 } } }
И последнее: Код (C++): if(VAR_mode_SET==5){ // Если настраиваем датчики // tft.reset(); // Очищаем дисплей tft.setTextColor(MAGENTA, BLACK); // Цвет текста и фона tft.setTextSize(2); // Объявляем размер шрифта tft.setCursor(50, 10); // Ставим курсор tft.print(utf8rus ("Настройка Датчиков")); // Выводим текст // Кнопки настройки tft.setTextSize(3); // Объявляем размер шрифта tft.setTextColor(YELLOW, BLACK); // Цвет текста tft.drawRoundRect(30, 60, 120, 100, 10, YELLOW); // Рисуем поле кнопки Вкл tft.setCursor(64, 100); // Ставим курсор tft.print(utf8rus ("Вкл")); // Выводим текст tft.drawRoundRect(180, 60, 120, 100, 10, YELLOW);// Рисуем поле кнопки Выкл tft.setCursor(204, 100); // Ставим курсор tft.print(utf8rus ("Выкл")); // Выводим текст tft.setTextColor(CYAN, BLACK); // Цвет текста tft.drawRoundRect(170, 192, 130, 36, 10, CYAN); // Рисуем поле кнопки Назад tft.setCursor(190, 198); // Ставим курсор tft.print(utf8rus ("Назад")); // Выводим название кнопки // **************************** ОБРАБОТКА НАЖАТИЯ НА ТАЧСКРИН ******************************************** TSPoint p = ts.getPoint(); // Считывание координат pinMode(XM, OUTPUT); // Объявление пинов как выход pinMode(YP, OUTPUT); if (p.z > MINPRESSURE && p.z < MAXPRESSURE) { if (p.x > 360 && p.x < 660 && p.y > 580 && p.y < 870) { // Если попали в кнопку Вкл // tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие // VAR_mode_SET = 3; // Объявляем режим 3 } if (p.x > 360 && p.x < 660 && p.y > 230 && p.y < 510) { // Если попали в кнопку Выкл // tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие // VAR_mode_SET = 4; // Объявляем режим 4 } if (p.x > 760 && p.x < 860 && p.y > 230 && p.y < 530) { // Если попали в кнопку Назад tft.fillScreen(BLACK); // Закрашиваем экран черным // delay (300); // ждем 0,3 сек чтобы предотвратить повторное нажатие VAR_mode_SET = 0; // Объявляем режим 0 } } } // } } /* Перекодировать русские шрифты из UTF-8 в Windows-1251 */ String utf8rus(String source) { int i,k; String target; unsigned char n; char m[2] = { '0', '\0' }; k = source.length(); i = 0; while (i < k) { n = source[i]; i++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = source[i]; i++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n + 0x30; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x70; break; } } } m[0] = n; target = target + String(m); } return target; }
Можете блок-схемой нарисовать ваш алгоритм. Непонятно где начинаются и где заканчиваются процедуры. У вас всё в loop находится? сколько времени выполняется код от начала до конца? Я думаю вам нужно: 1. оптимизировать код (почему у вас постоянно аналоговые пины конфигурируются на выход в коде несколько раз?) 2. переходить на прерывания Ардуина хороша для начала обучения, сейчас, скорее всего, вы натолкнулись на темную сторону ардуины, она все операции выполняет последовательно. Допустим ваш код выполняется 2 (2 000 000 мкс) секунды, ардуина считает нажатие примерно за 200 мкс (2 пина). Так вот за всё время работы прохождения цикла один раз АЦП опрашивается очень короткий промежуток времени (попробуйте долго (время одного цикла) держать палец). Вы, может быть, так нажимаете в те моменты времени, когда мк не отцифровывает пины.
Блоксхему попробую нарисовать, послезавтра. Завтра не смогу, а сегодня поздновато уже... Да, все в loop. По поводу времени выполнения кода - не могу сказать. Просто не знаю как это замерить. Я только пробую освоить Arduino и очень мало знаю. По поводу конфигурации пинов на выход, точно сказать не могу, так было во всех примерах работы с тачскрином. Объяснялось необходимостью так делать и все. Если запустить скетч и держать кнопку нажатой, то она срабатывает. По времени по разному. Бывает сразу, бывает где-то через секунду-полторы. В том то и вопрос, что можно изменить, что бы срабатывание происходило сразу?
выведите в сериал текущее время в мк в начале лупа и в конце, вычтете одно из другого и будет время. Прерывания. (по ссылке выше почитайте, вам как раз корды нажатия нужны, вот там ацп и обсуждается. Не библиотеками же постоянно пользоваться) Слишком часто пишете Начинайте глубже изучать микроконтроллер - принцип его работы и как он устроен.
AVR Но, поймите, если всё делать правильно, то это переписывать код. Для того, чтобы завершить текущий проект, я бы начал с прерываний в ардуино программируя в ардуино ide. Уж после этого, со спокойной душой начал бы изучать тонкости.
Вы вроде в других ветках грамотно отвечаете, не ожидал от вас такую ерунду услыхать Никакой "темной стороны" ардуины тут нет , любой контроллер выполняет действия последовательно. Для того чтобы кнопки срабатывали сразу, нужно просто их опрашивать как минимум 5-10 раз в секунду. При правильно проектировании программы это легко достижимо в скетче практически любого уровня сложности. Изучайте для начала программирование на языке Си и теорию алгоритмов. В частности, как уже сказал Daniil, старайте больше использовать процедуры и функции. Все программа, запихнутая в ЛУП - это откровенно чайниковый стиль. Стремитесь к тому, чтобы ЛУП, как и другие процедуры, был не длинне одного экрана. А переходить от Ардуино к Атмелу вам еще рано. Все ваши проблемы легко решаются и в рамках ардуино.
Прерывания - вещь хорошая, но завершить подобный проект можно и без них. В скетче же, фактически, ничего не происходит - нафига там прерывания?
Я понимаю, что код... Как бы это сказать... кривой и косой. Я учусь. Вернее пытаюсь. Не спорю. Первый блин просто обязан быть комом. Но он должен быть.
Каюсь, хотел написать ответ как можно короче. У ТС, получается, каждый цикл в лупе выводится новая картинка на дисплей, даже если эта новая и не отличается от предыдущей. Поэтому, нужно вызывать отрисовку только того, что изменилось, чтобы мк не делал лишних движений и не тратил время попусту.
Если я правильно понял, что такое блок-схема, то вот: По поводу Лупа, да, проверки на изменение отображаемых значений нет. Я так понимаю перед отрисовкой нужно проводить сравнение каждого параметра? То есть, если параметр час не изменился, то идем дальше, если параметр минута изменился, то выводим новое значение? Время одного прохода в Луп при SET=0 460-465 мс. В других режимах меньше, но там и кнопки работают почти без проблем. То есть опрос кнопок происходит примерно раз в пол секунды и я просто тыкая не попадаю в период опроса, я правильно понимаю? Честно говоря не представляю как можно все это упихать в один экран (в смысле все, что в Луп) ...
Daniil, b707 спасибо! Понял, осознал, ушел в литературу. Теперь вижу, что код необходимо корячить и дробить. И доделывать. И местами переделывать.. В общем направление понял, пошел изучать.
Очень похоже. (Пока писал текст ниже, понял, что можно попробовать обойтись без прерываний) По сути всё и так будет сидеть в лупе=) Старайтесь разбить большую задачу на маленькие подзадачи. Пользуйтесь процедурами для удобного чтения ваших же программ в настоящем и в будущем. Продумайте заранее, как ваша программа должна работать, порисуйте блок-схемы (см. ниже). Программа запутанная не потому что вы её так написали, а потому что она комплексная и от того имеет много решений, много состояний, в голове их сразу удержать сложно. Нууу, я хотел, что-то вроде такого, только не каждого действия а более глобального действия на псевдоязыке. Так можно было бы легче увидеть, что у вас в цикле, что в одном блоке if, что в другом, а что в else... Примерно так: Спойлер: Блок-схемы По работе делал такой алгоритм, где меняется частота генератора и синхронно с изменением частоты нужно считать данные с датчиков. Каждый блочок это тоже программа, вот блок "набор статистики" И опять таки каждый блок можно расширить ещё глубже Я всё таки попробую объяснить на примере, что мы насоветовали. Допустим у вас есть 2 экрана: Тогда в цикле луп будет такой алгоритм: Всего лишь 2 процедуры, лаконично. Теперь распишем эти 2 процедуры. 1. Проверить нажатие. Сначала надо определить их координаты. Потом определить какой экран. Если координаты совпадают с какой-либо кнопкой на выбранном экране, то выполнить действие. 2. Обновить экран. Нужно понять какой экран выводить, должен быть флаг (код). Спойлер: коды Для экрана с часами (главного экрана) код может быть равен 1 Для экрана с настройками 2 с секундомером 3 ...ит.п. Если экран №2 (экран настроек) То надо следить за индикацией настройки (чтобы пользователь знал какой режим сейчас) Если настройка изменилась, надо просигнализировать, если нет, то ничего не делать. Если экран №1, то нужно следить за изменением ЧЧ и ММ, если они не меняются, то и выводить их нет необходимости. При выводе ЧЧ, надо следить за настройками. Можете заметить, что везде сравнивается "текущее" значение с "новым", если "текущее"=="новому", то ничего делать не нужно, если "текущее"!="новому", то надо среагировать и не забыть приравнять "текущее"="новому", т.к. после реакции на новое значение "новое" стало "текущим" =). Поэтому удобно будет хранить много "текущих" состояний и много "новых", сравнение которых даст вам возможность определить, что делать далее. Именно этот момент и сэкономит вам время на выполнение программы, но заплатить придётся памятью на хранение "текущих" и "новых" значений. В процедуре "обновления экрана" сделана ошибка! Я не проверяю какой экран выведен сейчас (текущий), а какой должен быть (новый), если произошло события вынуждающее сменить экран, то "новый" экран должен быть выведен полностью! В моих гипотетических часах в вакууме только 2 экрана, поэтому я обошёлся двумя (+ одна малюсенькая для loop) блок-схемами, но если у вас их больше или чувствуете, что блок-схема становится громоздкой и малоуправляемой, то спокойно рисуйте блок "обработка экрана №Х" (сделать то-то/процедура такая-то). А уж его обработку можно расписать в отдельной блок-схеме и, соответственно, отдельной подпрограмме. Я не претендую на идеальный алгоритм мечты.
Daniil, да, что-то такое я вчера и представлял, просто по человечески описать не мог. Значит движусь в правильном направлении и читаю как раз то, что нужно. Если время позволит и во всем разберусь, то думаю к концу недели скетч переделаю. Еще раз спасибо.
Все получилось! Спасибо всем, кто помог. В итоге время выполнения кода в каждом из режимов сократилось с 465 мс до 10-12 мс, соответственно реакция на нажатие тачскрина мгновенная Что было сделано: 1. Луп разбит на несколько функций (По мне, это больше эстетическая сторона и на скорость не влияет. Может я не прав, но мне так показалось) Код (C++): void loop() { // Времы одного прохода Serial.print("\tOn: "); times = millis(); // запомнить значение времени Serial.print(times); Buttons_control(); // Работаем с кнопками Print_tft(); // Выводим на экран 2. Проверка изменения данных для отрисовки. В режиме показа времени это: - проверка секунд. Если да, то мигаем точками между часами и минутами. - проверка минут. Если да, то отрисовываем новые минуты. - проверка часов. Если да, то отрисовываем весь остальной экран. - в остальных режимах (настройка времени, даты, будильника и т.д.) отрисовка экрана если было нажатие на тачскрин. Остался вопрос по шрифтам... Если кто подскажет где их найти, буду весьма благодарен.