Элегантное решение для обновления содержимого 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());  //вызываем функцию для проверки температуры и при необходимости рисуем новые данные
}

Есть ли более элегантное решение этой проблемы?

, 👍3

Обсуждение

Какую библиотеку вы используете? Вы либо хотите отобразить свою строку во внеэкранном буфере (что требует много памяти и библиотечных функций, которые поддерживают такие вещи), либо каким-то образом заставить символы печатать фон, а также цвет переднего плана - и это зависит от того, какая библиотека ты используешь. Uno плохо приспособлен для работы с TFT-экранами из-за нехватки памяти. Это определенно не было бы моим первым выбором (даже не попало бы в мой список...), @Majenko

@Majenko Я использую Mega с библиотекой Adafruit GFX для tft-экранов ILI9341. Я не знаю каких-либо других библиотек, которые работают с экранами SPI, но я еще не занимался этим., @Streamline

А, хорошо. Эта библиотека — та, на которой я изначально основывал DisplayCore (набор библиотек отображения ChipKIT). Это может быть сделано. Я объясню, как..., @Majenko

@ Маженко ах! Я помню тебя! Ты тот парень, который месяц назад рассказал мне о SPI :), @Streamline


4 ответа


Лучший ответ:

3

В библиотеке Adafruit GFX есть две функции для установки цвета текста:

setTextColor(uint16_t c)
setTextColor(uint16_t c, uint16_t bg)

Первый задает один и тот же цвет для переднего плана и фона, а второй — два разных цвета. Вы можете спросить, почему вы хотите, чтобы передний план и фон были одинаковыми — ну, библиотека обрабатывает эту ситуацию как особый случай: она делает фон прозрачным.

Установив для переднего плана и фона разные цвета, вы заставляете библиотеку рисовать этот цвет фона поверх того, что уже есть на экране.

tft.setTextColor(ILI93481_WHITE, ILI9341_BLACK);

При этом любые фоновые пиксели в текстовой строке будут окрашены в черный цвет, а сам текст — в белый. Пока строка, которую вы печатаете, имеет ту же длину, что и текст, который уже есть, она будет полностью заменена.

,

Еще раз спасибо за вашу помощь, это сделало весь мой код намного проще и отображение данных стало более элегантным., @Streamline

Следует отметить, что это работает только со встроенным шрифтом GLCD. Пользовательские шрифты не могут быть перерисованы таким образом., @SoreDakeNoKoto


5

Если вы посмотрите в "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); // Цвет фона текста обновляет окружающие пиксели.
,

1

Хм, решение заключается в том, как написан код... никаких причудливых вещей... в стиле 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");
}
,

2

Этот код хорошо работает и учитывает значения разной длины.

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);
}
,