Обновление дисплея ILI9341

Megawollt
Offline
Зарегистрирован: 06.12.2015

Поставил библиотеку Adafruit_ILI9341, так как она единственная стабильно работала в тесте, но вот какая проблема оказалась. При выводе показаний на дисплей цифры накладываются друг на друга, а команды стирания дисплея в библиотеке нет. Как быть?

Если использовать функцию заливки, то экран заливается около 2х секунд.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

1. В нормальной библиотеке должна быть настройка, как выводить символы - с прозрачным или непрозрачным фоном.

2. Если покаким-либо причинам такого в библиотеке обнаружить не удалось - не нужно чистить весь дисплей - достаточно только место под выводимые символы (лучше вообще по одному).

PS. По поводу заливки - как она выглядит, если заливать из центральной точки?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Megawollt пишет:

команды стирания дисплея в библиотеке нет. 

Как нет? А куда Вы её дели?

fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)

Зальёт прямоугольный регион за милую душу. Только заливайте не весь экран, а только место под Вашу букву. И все дела.

Если мы, конечноЮ об одной и той же библиотеке говорим.

Megawollt
Offline
Зарегистрирован: 06.12.2015

Спасибо. Про настройку я вообще не слышал. Дело в том, что на экране 32 изменяющихся параметра. Как то не очень удобно под каждый рисовать заливной квадратик.
Заливку из центральной точки не пробовал. До этого работал только с олед дисплеями. Там ничего заливать ненужно

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Megawollt пишет:
Спасибо. Про настройку я вообще не слышал. Дело в том, что на экране 32 изменяющихся параметра. Как то не очень удобно под каждый рисовать заливной квадратик.

Если нет режима рисования символов с непрнозоачным фоном - это единственное правильное решение. В противном случае экран будет сильно мерцать.

Megawollt
Offline
Зарегистрирован: 06.12.2015

Хмм...А как же по нему на ютубе видео крутят?

У меня честно говоря не очень большой опыт работы с экранами. То есть я так понимаю надо нарисовать красный квадрат на числе (чтобы его было видно на черном фоне), когда закрою число поменять цвет на черный и вставить весь этот код в начало программы?

Вот интересно, а памяти то хватит? Почему другие экраны обновляются сбросом и решит ли проблему смена библиотеки на UTFT или подобную?

Megawollt
Offline
Зарегистрирован: 06.12.2015

Товарищи, ну помогите же побороть дисплей :)

Стирать надписи частично удалось поставив тексту фон, но. Когда значение 100% все хорошо, но если оно становится двухзначным, то знак процента естественно сдвигается, но и на предыдущем месте он остается. Вот фрагмент кода

tft.setCursor(180, 95);
tft.setTextColor(ILI9341_YELLOW,ILI9341_BLACK); 
tft.print(val[3]); 
tft.print("%"); 

И еще программа сильно тормозит, хотя памяти занято всего 30%

Logik
Offline
Зарегистрирован: 05.08.2014

Про скорость. Так обсасывалось сто раз, например недавно  http://arduino.ru/forum/obshchii/skorost-raboty-displeev

 

Megawollt
Offline
Зарегистрирован: 06.12.2015

Спасибо. В моем случае тормозит не сам дисплей, а программа...

Bogdan
Offline
Зарегистрирован: 25.11.2015

Добрый день, уважаемое сообщество. Прошу разъяснить,про опрос датчиков и вывод значений на TFT дисплей на чипе ILI9341(китайский). Правильно ли я понимаю, что в из-за отсутствия буфера памяти у этого дисплея, в момент опроса датчиков, Arduino "забывает" о том что есть такое устройство, как дисплей, и из-за этого дисплей заливает белым? Или же используемые библиотеки не позволяют выполнить одновременный опрос барометра и часов реального времени без обновления экрана. Изначально идея была о выводе текущего времени(real time DS3231)  и раз в 5 минут опросе барометра с дальнейшим построением барограммы.

Код скетча ниже:

 

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library

//Include the Wire library for I2C access.
#include <Wire.h>
//Include the Love Electronics BMP180 library.
#include <BMP085.h>
#include <SD.h>
#include <DS3231.h>

#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0

#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

//Assign human-readable names to some common 16-bit color values:
#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);
RTClib RTC;
BMP085 barometer = BMP085();
File myFile;

long currentTemperature = 0, currentPressure = 0, currentAltitude = 0;
byte massiv[240];
unsigned long myTimer1, myTimer2;


void setup()
{  
  myFile = SD.open("massiv", FILE_READ);  
  //tft.begin(0x9341);
  //tft.reset();
  getBarodata();
  printTime();
  printPressureTemperature();
  drawStaticPart();
  drawBarogramm();  
}

void loop()
{
  if (millis() - myTimer1 >=300000)
  {
    myTimer1 = millis();
    getBarodata();
    String t = getBarodata();
    printTime();
    printPressureTemperature();
    drawStaticPart();
    drawBarogramm();
  }
}

void getBarodata()
{
  Wire.begin(0x77);
  barometer.init();
  barometer.getPressure(&currentPressure);
  barometer.getTemperature(&currentTemperature);
  barometer.getAltitude(&currentAltitude);
}

void printTime()
{
  Wire.begin(0x68);
  DateTime now = RTC.now();
  tft.begin(0x9341);
  //tft.fillRect(0,0,240,320, BLACK);
  tft.fillScreen(BLACK);
  tft.setCursor(4,100);
  tft.setTextSize(2);
  tft.setTextColor(YELLOW, BLACK);
  tft.print(now.year(), DEC);
  tft.print("/");
  tft.print(now.month(), DEC);
  tft.print("/");
  tft.print(now.day(), DEC);
  tft.print(" ");
  tft.print(now.hour(), DEC);
  tft.print(":");
  tft.print(now.minute(), DEC);
  tft.print(":");
  tft.print(now.second(), DEC);  
}

void printPressureTemperature()
{
   //вывод значений давления, высоты и температуры
  //tft.setCursor(0, 0);
  tft.setTextColor(WHITE);
  tft.setCursor(4, 4);
  tft.setTextSize(2);
  tft.println(utf8rus("Давление: "));
  tft.setCursor(110, 4);
  if (currentPressure / 133.32 < 750)
  {
    tft.setTextColor(GREEN);
  }
  else
  {
    tft.setTextColor(RED);
  }
  tft.print(currentPressure / 133.32, 1);
  tft.setCursor(170, 11);
  tft.setTextColor(YELLOW);
  tft.setTextSize(1);
  tft.println(utf8rus("мм.рт.ст"));
  /*tft.setTextColor(WHITE);
  tft.setCursor(4, 30);
  tft.setTextSize(2);
  tft.println(utf8rus("Высота: "));
  tft.setCursor(90, 26);
  tft.setTextColor(GREEN);
  tft.print(currentAltitude);
  tft.setTextColor(YELLOW);
  tft.setTextSize(1);
  tft.print(utf8rus(" м"));*/
  tft.setTextColor(BLUE);
  tft.setCursor(40, 150);
  tft.setTextSize(1);
  tft.println(utf8rus("Обновление раз в 5 минут"));
  tft.setTextSize(2);
  tft.setCursor(4, 50);
  tft.setTextColor(WHITE);
  tft.println(utf8rus("Температура: "));
  tft.setCursor(148, 50);
  if (currentTemperature < 24)
  {
    tft.setTextColor(GREEN);
  }
  else
  {
    tft.setTextColor(RED);
  }
  tft.print(currentTemperature/10, 1);
  tft.setTextColor(YELLOW, BLACK);
  tft.write(176);
  tft.println("C");
}

void drawStaticPart()
{
 //Рисуем статичное наполнение графика давления
  tft.drawFastHLine(0, 200, 239, RED); //верхний предел 800 мм.рт.ст
  tft.setTextSize(1);
  tft.setCursor(3, 190);
  tft.print("800");
  tft.drawFastHLine(0, 300, 239, CYAN); //нижний предел 700 мм.рт.ст
  tft.setCursor(3, 290);
  tft.print("700");
  tft.drawFastHLine(0, 250, 239, GREEN); // соответсвие 750 мм.рт.ст
  tft.setCursor(3, 240);
  tft.print("750");
  tft.setCursor(80, 304);
  tft.setTextSize(1);
  tft.print(utf8rus("График давления"));
  tft.drawFastHLine(0, 200, 10, YELLOW);
  tft.drawFastHLine(0, 210, 10, YELLOW);
  tft.drawFastHLine(0, 220, 10, YELLOW);
  tft.drawFastHLine(0, 230, 10, YELLOW);
  tft.drawFastHLine(0, 240, 10, YELLOW);
  tft.drawFastHLine(0, 250, 10, YELLOW);
  tft.drawFastHLine(0, 260, 10, YELLOW);
  tft.drawFastHLine(0, 270, 10, YELLOW);
  tft.drawFastHLine(0, 280, 10, YELLOW);
  tft.drawFastHLine(0, 290, 10, YELLOW);
  tft.drawFastHLine(0, 300, 10, YELLOW); 
}

void drawBarogramm()
{
 //for (byte i = 0; i < 240; i++)
  //{
    byte j = round(currentPressure / 133.32 - 546);
    for (byte b = 0; b < 239; b++)
    {
      massiv[b] = massiv[b + 1];
    }    
    massiv[239] = j;
    
    for (byte v = 0; v < 240; v++)
    {
      tft.drawPixel(v, 454 - massiv[v], MAGENTA);
    }
    
    myFile = SD.open("massiv", FILE_WRITE);
    SD.begin(10);
    myFile.write(j);
    myFile.close();    
  //} 
}

String utf8rus(String source)
{
  int i = 0;
  String target;
  unsigned char n;
  char m[2] = { '0', '\0' };
  while (i < source.length()) {
    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;
}

 

b707
Offline
Зарегистрирован: 26.05.2017

>> правильно ли я понимаю....

неправильно. дисплей у вас заливается белым, потому что вы делаете его переинициализацию при каждом обновлении часов на экране, а это неверно. Оператор tft.begin() нужно вызывать один раз при старте скетча, а не каждую секунду....

Bogdan
Offline
Зарегистрирован: 25.11.2015

Если я перестаю инициализировать экран tft.begin(0x9341); в функции printTime(); тогда экран просто заливает белым при старте ардуины.

https://youtu.be/e32CtbUq5io

на 34 секунде произошла загрузка скетча, и экран побелел.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Bogdan пишет:

Если я перестаю инициализировать экран tft.begin(0x9341); в функции printTime(); тогда экран просто заливает белым при старте ардуины.

https://youtu.be/e32CtbUq5io

на 34 секунде произошла загрузка скетча, и экран побелел.

Ещё раз: вызов tft.begin(0x9341); должен быть вставлен в setup, а с остальных мест - убран. Так же как и Wire.begin.

Bogdan
Offline
Зарегистрирован: 25.11.2015

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

void setup()
{  
  myFile = SD.open("massiv", FILE_READ);  
  Wire.begin();
  getBarodata();
  tft.begin(0x9341);
  tft.reset();
  printTime();
  printPressureTemperature();
  drawStaticPart();
  drawBarogramm();  
}

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Wire.begin и tft.begin - в самое начало setup. Неплохо было бы и SD.begin до первого вызова SD.open сделать, не находите?

Bogdan
Offline
Зарегистрирован: 25.11.2015

Изменил setup, теперь примерно на 1 секунду появляется отзеркаленное справо-на-лево изображение. и опять заливается белым. https://youtu.be/nnRdgX99SpQ

Wire.begin();
  tft.begin(0x9341);
  SD.begin(10);
  myFile = SD.open("massiv", FILE_READ);  
  getBarodata();
.......
sadman41
Offline
Зарегистрирован: 19.10.2016

Что-то у меня в подсознании воспоминания постов, где люди писали про белые экраны. И в этом было, по-моему, замешано то ли напряжение питания, то ли несогласованность уровней интерфейса.

Хотя, зеркальное изображение может еще намекать и на проблему с драйвером - мошт не тот? Поменяйте библиотеку. В u8g мошт есть саппорт этого чипа?

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

Что-то у меня в подсознании воспоминания постов, где люди писали про белые экраны.

та не... у ТС все работало с этой библиотекой, пока он на форум не пришел.

Богдан, разбирайтесь с кодом, ищите другие ошибки. Они наверняка есть, судя по первому коду программист из вас еще тот...

Bogdan
Offline
Зарегистрирован: 25.11.2015

Библиотеки кроме adafruit'овской ни одна не подошли "as is"

Как правильно заметил b707, я ни разу не программист, скорее сочувствующий =)

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

Кстати,если заливать тестовый скетч "graphictest", это где всякие геометрические фигуры рисуются, там fillScreen(BLACK); коректно отрабатывает, медленно, но верно. Но стоит добавить в тот скетч любое обращение к внешним датчикам, как скетч начинает работать абсолютно также как и мой самописный, т.е. с белым экраном 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

А, ну, я понял. Посмотрите на LCD_RESET и пины, которые используются для I2C (датчики и часы).

b707
Offline
Зарегистрирован: 26.05.2017

а ардуина какая?

b707
Offline
Зарегистрирован: 26.05.2017

sadman41 пишет:

А, ну я понял. Посмотрите на LCD_RESET и пины, которые используются для I2C (датчики и часы).

а, ну точно :) Поэтому ему и пришлось Wire.begin() всюду натыкать - потому что обращение к датчикам портило экран, а обращение к экрану - вырубало датчики :)

Bogdan
Offline
Зарегистрирован: 25.11.2015

Arduino UNO, BMP180 и DS3231 сидят на ногах A4/A5 ардуины, LCD_RESET дисплея сидит тоже на А4. Ради интереса перерезал Reset на дисплей, но он не заводится, пришлось греть паяльник =)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Не стоит пин Reset дисплея заводить на пины, на которых работают I2C. Перенесите на другой пин, свободный.  И в прошивке переназначьте.

vvadim
Offline
Зарегистрирован: 23.05.2012

Bogdan пишет:

Как правильно заметил b707, я ни разу не программист, скорее сочувствующий =)

 

 

если так, то нафига сразу лезть в датчики и прочее.

запустите один дисплей, поиграйтесь с примерами.

а потом уже добавляйте датчики-кнопочки.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

vvadim пишет:

Bogdan пишет:

ни разу не программист

если так, то нафига сразу лезть в датчики и прочее. запустите один дисплей, поиграйтесь с примерами.

Вы всё перепутали. Так поступают как раз программисты. Вот сейчас я ковыряюсь с e-paper именно так - кроме дисплея ничего, практикуюсь рисовать на нём что мне нужно, а когда рисование будет готово, начну добавлять другие приблуды. А "ни разу не программисты" - те всегда валят в одну кучу всё и сразу, а потом идут на форум за "помощью". Это общая практика.

vvadim
Offline
Зарегистрирован: 23.05.2012

ЕвгенийП пишет:

vvadim пишет:

Bogdan пишет:

ни разу не программист

если так, то нафига сразу лезть в датчики и прочее. запустите один дисплей, поиграйтесь с примерами.

Вы всё перепутали. Так поступают как раз программисты. Вот сейчас я ковыряюсь с e-paper именно так - кроме дисплея ничего, практикуюсь рисовать на нём что мне нужно, а когда рисование будет готово, начну добавлять другие приблуды. А "ни разу не программисты" - те всегда валят в одну кучу всё и сразу, а потом идут на форум за "помощью". Это общая практика.

пардон, звиняйте)))))