Элегантное решение для обновления содержимого TFT-дисплея
В настоящее время я рисую черные прямоугольники поверх старого контента, прежде чем отображать постоянно обновляющийся контент на своем дисплее, например, для отображения температуры:
if (sensorTemp != nowTemp){
nowTemp = sensorTemp;
tft.fillRect(0,52,88,21,ILI9341_BLACK);
return nowTemp;
}
Если я этого не сделаю, дисплей будет просто накладывать контент, пока он не станет белым пятном.
Однако это решение приводит к тому, что на дисплее мерцает черный цвет, и я не могу точно контролировать, что и где обновляется. Так, например, когда я хочу отобразить текущее время или дату, она должна постоянно обновлять дату, даже если ничего не изменилось.
void loop() {
tft.setTextSize(2);
tft.setCursor(0,0);
tft.print(rtc.getDateStr());
tft.fillRect(144,0,199,15,ILI9341_BLACK); //Черный ящик нарисован поверх "старых" временных данных
tft.setCursor(144,0);
tft.print(rtc.getTimeStr()); // Рисуем новое время
tft.setCursor(0,52);
tft.print(tempCall()); //вызываем функцию для проверки температуры и при необходимости рисуем новые данные
}
Есть ли более элегантное решение этой проблемы?
@Streamline, 👍3
Обсуждение4 ответа
Лучший ответ:
В библиотеке Adafruit GFX есть две функции для установки цвета текста:
setTextColor(uint16_t c)
setTextColor(uint16_t c, uint16_t bg)
Первый задает один и тот же цвет для переднего плана и фона, а второй — два разных цвета. Вы можете спросить, почему вы хотите, чтобы передний план и фон были одинаковыми — ну, библиотека обрабатывает эту ситуацию как особый случай: она делает фон прозрачным.
Установив для переднего плана и фона разные цвета, вы заставляете библиотеку рисовать этот цвет фона поверх того, что уже есть на экране.
tft.setTextColor(ILI93481_WHITE, ILI9341_BLACK);
При этом любые фоновые пиксели в текстовой строке будут окрашены в черный цвет, а сам текст — в белый. Пока строка, которую вы печатаете, имеет ту же длину, что и текст, который уже есть, она будет полностью заменена.
Еще раз спасибо за вашу помощь, это сделало весь мой код намного проще и отображение данных стало более элегантным., @Streamline
Следует отметить, что это работает только со встроенным шрифтом GLCD. Пользовательские шрифты не могут быть перерисованы таким образом., @SoreDakeNoKoto
Если вы посмотрите в "Adafruit_GFX.cpp", вы увидите следующее.
void Adafruit_GFX::setTextColor(uint16_t c) {
// Для 'прозрачного' фона мы установим bg
// то же самое, что и fg, вместо использования флага
textcolor = textbgcolor = c;
}
void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) {
textcolor = c;
textbgcolor = b;
}
Если вы хотите нарисовать символ только с прозрачным фоном, это означает, что вы пишете символ setTextColor только в предписанных пикселях, не изменяя ни один из окружающих пикселей в блоке символов, определяемом x, y, setTextSize.
TFT.setTextColor(GREEN); //With Transparent Text Background not updating surrounding pixels.
Если вы хотите нарисовать символ с вашим фоновым цветом, замените пиксели приложения в символьном блоке, определяемом x, y, setTextSize, на выбранный вами цвет текста, а ваш фон должен совпадать с выбранным вами фоном. Это перезапишет все пиксели со старыми символами, которые больше не используются с фоновым цветом, и в то же время предотвратит путаницу пикселей и мигание символов.
TFT.setTextColor(GREEN, BLACK); // Цвет фона текста обновляет окружающие пиксели.
Хм, решение заключается в том, как написан код... никаких причудливых вещей... в стиле KIWI
//в функцию настройки добавляем tft.fillScreen(ST7735_GREEN);
void loop(){
int lightIntensity = myBH1750.getLux();
tft.setTextSize(3);
tft.setCursor(10,10);
tft.setTextColor(ST7735_RED);
tft.print(lightIntensity);
delay(3000);
tft.setTextColor(ST7735_GREEN);
tft.setCursor(10,10);
tft.print(lightIntensity);
tft.setCursor(10,50);
tft.setTextColor(ST7735_BLUE);
tft.print("LUX");
}
Этот код хорошо работает и учитывает значения разной длины.
void textValue() {
float newValue = @your input@;
int numChars = String(newValue).length(); // Получаем количество символов
int valueWidth = numChars * 6 * 2.5;
if (valueWidth != previousValue) {
tft.fillRect(0, 55, previousValue, 30, ST77XX_BLACK);
previousValue = valueWidth;
}
tft.setCursor(3,60);
tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
tft.setTextSize(2.5);
tft.print(newValue);
}
- Как использовать SPI на Arduino?
- Как сбросить или отформатировать Arduino?
- Управление скоростью вентилятора с помощью библиотеки Arduino PID
- Как получить уникальный идентификатор для всех плат Arduino?
- Как очистить буфер FIFO на MPU6050?
- Считывание нескольких поворотных энкодеров
- Что выбрать между датчиками температуры и влажности: AM230x или DHT22?
- Последовательная связь между двумя Arduino (запрос и получение)
Какую библиотеку вы используете? Вы либо хотите отобразить свою строку во внеэкранном буфере (что требует много памяти и библиотечных функций, которые поддерживают такие вещи), либо каким-то образом заставить символы печатать фон, а также цвет переднего плана - и это зависит от того, какая библиотека ты используешь. Uno плохо приспособлен для работы с TFT-экранами из-за нехватки памяти. Это определенно не было бы моим первым выбором (даже не попало бы в мой список...), @Majenko
@Majenko Я использую Mega с библиотекой Adafruit GFX для tft-экранов ILI9341. Я не знаю каких-либо других библиотек, которые работают с экранами SPI, но я еще не занимался этим., @Streamline
А, хорошо. Эта библиотека — та, на которой я изначально основывал DisplayCore (набор библиотек отображения ChipKIT). Это может быть сделано. Я объясню, как..., @Majenko
@ Маженко ах! Я помню тебя! Ты тот парень, который месяц назад рассказал мне о SPI :), @Streamline