Тренд на Arduino Mega 2560 + TFT LCD 320х480 HX8357B

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

Привет все!

При попытке создания простого графика данных возникли вопросы и чем дальше тем больше...

Вопрос №1: Для того чтоб график рисовался красиво как на SCADA а не тупо по кругу и не найдя друго способа решил организовать хранение данных в массиве. Для этого сделал цикл смещения (устарение) данных типа buf[x+1]=buf[x]. Ширина графика 407 точек и поэтому массив имеет 407 элементов и такой массив не один, смещение циклом замедляет работу программы. И вот сам вопрос: есть ли более простой способ смещения данных в массиве или иной способ организовать непрерывный график?

Вопрос №2: Во время работы программы (непрерывно рисует график) экран покрывается хаотично расположенными точками разного цвета. Постояно перерисовывать весь экран отстойно, очень медленно и мерцание. Откуда могут возникать эти артефакты и как от них можно избавиться? На фото начало работы и 30 мин работы кода :(

начало работы30 минут работы

Вопрос №2: Хочу чтоб обновление графика и массива происходило раз в 1 секунду. Delay() не подходит ибо не учитывает время работы кода. Есть ли возможность устроить прерывание равное 1 сек и как правильно его оформить?

#include <UTFT.h>

// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];

UTFT myGLCD(HX8357B,38,39,40,41);

void setup()
{
  randomSeed(analogRead(0));
  
// Setup the LCD
  myGLCD.InitLCD();
  myGLCD.InitLCD();
}

void loop()
{
  int buf_pH_ai_sec[407], buf_pH_sp_sec[407];
  int buf_pH_ai_min[407], buf_pH_sp_min[407];
  int buf_pH_ai_hour[407], buf_pH_sp_hour[407];
  int x, xg, tg;
  int y, y2, yg;
  int r, lvl_ai=100, lvl_sp=100;
  float pH_ai=14.00, pH_sp=6.40, TDS_ai=2.00, TDS_sp=2.00, pH_g;
  boolean b1;
unsigned long time;
time = millis();
// Clear the screen and draw the frame
  myGLCD.clrScr();

  myGLCD.setFont(BigFont);
// Рисуем верхние большие квадраты
  myGLCD.setColor(25, 25, 255);
  myGLCD.setBackColor(25, 25, 255);
  myGLCD.fillRect(1, 2, 187, 44);
  myGLCD.fillRect(189, 2, 355, 44);
  myGLCD.fillRect(357, 2, 479, 44);
  myGLCD.setColor(255, 255, 0);
  myGLCD.print("pH", 78, 2);
  myGLCD.print("TDS/1000", 208, 2);
  myGLCD.print("Level", 378, 2); 
// Рисуем квадраты под показания
  myGLCD.setColor(0, 128, 0);
  myGLCD.fillRect(3, 20, 93, 42);
  myGLCD.fillRect(191, 20, 271, 42);
  myGLCD.fillRect(359, 20, 417, 42);
  myGLCD.setColor(240, 255, 240);
  myGLCD.setBackColor(0, 128, 0);
  myGLCD.print(String(pH_ai), 8, 24);
  myGLCD.print(String(TDS_ai), 199, 24);
  myGLCD.print(String(lvl_ai), 364, 24); 
// Рисуем квадраты под задания
  myGLCD.setColor(128, 0, 0);
  myGLCD.fillRect(95, 20, 185, 42);
  myGLCD.fillRect(273, 20, 353, 42);
  myGLCD.fillRect(419, 20, 477, 42);
  myGLCD.setColor(255, 255, 240);
  myGLCD.setBackColor(128, 0, 0);
  myGLCD.print(String(pH_sp), 100, 24);
  myGLCD.print(String(TDS_sp), 281, 24);
  myGLCD.print(String(lvl_sp), 424, 24); 
// Рисуем нижние квадраты
  myGLCD.setColor(25, 25, 112);
  myGLCD.setBackColor(25, 25, 112);
  myGLCD.fillRect(1, 274, 87, 318);
  myGLCD.fillRect(89, 274, 175, 318);
  myGLCD.fillRect(177, 274, 263, 318);
  myGLCD.fillRect(265, 274, 351, 318);
  myGLCD.fillRect(353, 274, 479, 318);
  myGLCD.setColor(255, 255, 255);
//  myGLCD.print("Set", 20, 286);
  myGLCD.print("Sec", 108, 286);
  myGLCD.print("Min", 196, 286);
  myGLCD.print("Hour", 276, 286);
  myGLCD.print("History", 360, 286);
// Сетка графика
  myGLCD.setColor(0,0,0);
  myGLCD.fillRect(32,50,479,250);
// Горизонтальные линии
  tg=50;
  pH_g=8.0;
  myGLCD.setFont(BigFont);
  for (yg=50; yg<=250; yg=yg+25)
    {
      myGLCD.setBackColor(0, 0, 0);
      if (yg==tg)
        {
          myGLCD.setColor(0, 0, 205);
          myGLCD.drawLine(72, yg, 478, yg);
          myGLCD.print(String(pH_g), 2, yg-4);
          tg=tg+50;
        }
       else
         {
          myGLCD.setColor(0, 0, 60);
          myGLCD.drawLine(72, yg, 478, yg);
          myGLCD.print(String(pH_g), 2, yg-4);
         }
       pH_g=pH_g-0.5;
    }
 // Вертикальные линии
  myGLCD.setFont(SmallFont);
  myGLCD.setBackColor(0, 0, 0);
  tg=0;
  for (xg=72; xg<=472; xg=xg+10)
    {
    if ((xg-72)==tg)
      {        
        myGLCD.setColor(0, 0, 255);
        myGLCD.drawLine(xg,50, xg, 254);
        myGLCD.print(String(tg), xg-8, 255);
        tg=tg+30;
      }
     else 
      {
        myGLCD.setColor(0, 0, 60);
        myGLCD.drawLine(xg,50, xg, 250);
      } 
    }
for (int temp=0; temp<=407; temp++)
{
buf_pH_ai_sec[temp]=0;
buf_pH_sp_sec[temp]=0;
}
 while(1)
 { 

// Рисуем график
  x=72;
  for (int i=1; i<(478*15); i++) 
  {
    if (x==480)
    {
    x=72;
    }
    for (int x2=0; x2<=407; x2++)
      {
        buf_pH_ai_sec[(407-x2)]=buf_pH_ai_sec[(406-x2)];
        buf_pH_sp_sec[(407-x2)]=buf_pH_sp_sec[(406-x2)];
      }
    buf_pH_ai_sec[1]=159+(sin(((i*0.7)*3.14)/180)*(90-(i / 100)));
    buf_pH_sp_sec[1]=250-int((pH_sp-4.0)*50);
    for (int x3=0; x3<=405; x3++)
      {
        if ((buf_pH_ai_sec[x3]>0)&&(buf_pH_sp_sec[x3]>0))
          {
            y=constrain(buf_pH_ai_sec[x3],50,250);
            y2=constrain(buf_pH_sp_sec[x3],50,250);
            myGLCD.setColor(0,255,255);
            if ((y>=50)&&(y<+250)) myGLCD.drawPixel(x3+72,y);
            myGLCD.setColor(255,0,0);
            if ((y2>=50)&&(y2<+250)) myGLCD.drawPixel(x3+72,y2);
            if (buf_pH_ai_sec[x3] != buf_pH_ai_sec[x3+1])
              {
                if ((x3==0)||(x3==30)||(x3==60)||(x3==90)||(x3==120)||(x3==150)||(x3==180)||(x3==210)||(x3==240)||(x3==270)||(x3==300)||(x3==330)||(x3==360)||(x3==390))
                  {
                    myGLCD.setColor(0,0,205);
                  }
                 else if ((buf_pH_ai_sec[x3+1]==50)||(buf_pH_ai_sec[x3+1]==150)||(buf_pH_ai_sec[x3+1]==250)||(buf_pH_ai_sec[x3+1]==100)||(buf_pH_ai_sec[x3+1]==200))
                   {
                    myGLCD.setColor(0,0,205);
                   }
                else if ((x3==10)||(x3==20)||(x3==40)||(x3==50)||(x3==70)||(x3==80)||(x3==100)||(x3==110)||(x3==130)||(x3==140)||(x3==160)||(x3==170)||(x3==190))
                  {
                    myGLCD.setColor(0,0,60);
                  }
                else if ((x3==200)||(x3==220)||(x3==230)||(x3==250)||(x3==70)||(x3==260)||(x3==280)||(x3==290)||(x3==310)||(x3==320)||(x3==340)||(x3==350)||(x3==370)||(x3==380))
                  {
                    myGLCD.setColor(0,0,60);
                  }
                 else if ((buf_pH_ai_sec[x3+1]==75)||(buf_pH_ai_sec[x3+1]==125)||(buf_pH_ai_sec[x3+1]==175)||(buf_pH_ai_sec[x3+1]==225))
                   {
                    myGLCD.setColor(0, 0, 60);
                   }
                 else myGLCD.setColor(0,0,0);
                 if ((buf_pH_ai_sec[x3+1]>=50)&&(buf_pH_ai_sec[x3+1]<+250)) myGLCD.drawPixel(x3+72,buf_pH_ai_sec[x3+1]);
 
              }
          }
      }
    x++;
  }
 }
}

 

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

и как спрятать код под "показать код"?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

во второй вкладке есть галочка скрывать код

но первое сообщение не отредактировать)

превывание не умею делать. но можно использовать millis

kortium
Offline
Зарегистрирован: 23.01.2015

это косяк этого экрана при работе с UTFT либой, попробуй в цикле просто слово какое-н много раз напечатать и эти точки полезут

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

Ты прав, при частом выводе на экран любой инфы точки лезут, чем чаще вывод информации тем больше точек. Экранирование ЛСД модуля может спасти ситуацию?

nevkon
Offline
Зарегистрирован: 20.01.2015

Очень похоже на плохой контакт ножек у шлейфа. Я перебрал несколько IDE шлейфов прежде чем нашел более-менее рабочий для своего экрана.

По самой задаче - а зачем смещать массив если можно просто хранить нулевую позицию и смещать цикл вывода. Приведу для примера на 4 значениях:

1-2-3-4

4-1-2-3

3-4-1-2

2-3-4-1

Получается просто переписываешь нулевую позицию. Единственно придется сделать переменную для этой позиции.

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

Спасибо за дельную идею :) сейчас буду обмозговывать.

А по шлейфу - это пленочный шлейф от платы-переходника на сам экран?

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

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

nevkon
Offline
Зарегистрирован: 20.01.2015

Есть одна идея. Правда тоже через одно место, но позволит ускорить отрисовку.

На текущей координате отрисовывается 2 точки: текущая нужным цветом и предыдущая цветом фона. Будет много быстрей чем выводить весь экран по новой.

А про шлейф я писал который на пины одевается

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

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

Плата - адаптер экранчика имеет жестко впаяные пины (папа) и втыкается в плату контроллера без шлейфа, сам экранчик приклеен к плате - адаптеру и имеет пленочный шлейф и чтоб до него добраться надо отрывать экранчик от платы. Первой мыслью у меня было что от большой частоты переключений (когда идут команды на экранчик) происходит наводка на соседние пины или некоторые пины просто не успевают переключиться, но последняя мысль выглядит еще бредовее первой :)) . Мусор сыпится когда идет вывод любой графики, чем чаще идут команды на экранчик тем быстрее засирается мусором, эксперементировал с текстом и с графическими объектами, вывод один - пока не обращаешься к экрану мусор не появляется.

Появится лишнее время попробую порисовать без использования библиотеки... Мож чо и добьюсь :) .

 

kortium
Offline
Зарегистрирован: 23.01.2015

я пробова отклеивать экран, промывать шлейф, кондеры на питание, ничего не помогает

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

Да, бяда. Остается только библиотека и сам контроллер (если исключить возможность некачественной сборки экранчика)

kortium
Offline
Зарегистрирован: 23.01.2015

штук 10 плат пробовал, у всех одинаковая беда

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Значит непропай на разьемах ардуино.

kortium
Offline
Зарегистрирован: 23.01.2015

да всё пропаяно, я же говорю 10 комплектов проверял

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

Пробовал с библиотекой и с одним и тем жеш контроллером спаривать?

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

kortium пишет:

да всё пропаяно, я же говорю 10 комплектов проверял


Значит нужно проверить подключить к другому компу!

kortium
Offline
Зарегистрирован: 23.01.2015

какому компу? она к атмеге подключается

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

kortium пишет:

какому компу? она к атмеге подключается


Вот мегу и подключить к другому компу. Коротким шнурком в задний узб. Походу питания не хватает.
чудеса бывают только в сказке

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

просто человек пытается до нас донести что электротехника - это наука о контатах :))

kortium
Offline
Зарегистрирован: 23.01.2015

при чем тут комп, я от внешнего источника запитывал. Я не настока ламер чтобы это все не перепробовать, я спиртом плату промывал, кондеры там на питание вешал, и к DUE подключал ее и к меге, везде одно и то же, и от аккума питал

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

пока читал вашу перепалку в голову забрела мысль и возможно не глупая :) . Что если стандартная библиотека не учитывает необходимые задержки между необходимыми переключениями режимов и командами на экран?

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

kortium пишет:

при чем тут комп, я от внешнего источника запитывал. Я не настока ламер чтобы это все не перепробовать, я спиртом плату промывал, кондеры там на питание вешал, и к DUE подключал ее и к меге, везде одно и то же, и от аккума питал


Угу. А помимо экрана еще гирлянда на 2 киловата от меги запитана? :)

kortium
Offline
Зарегистрирован: 23.01.2015

пробуй, если получится расскажи )

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

redmaxs пишет:

пока читал вашу перепалку в голову забрела мысль и возможно не глупая :) . Что если стандартная библиотека не учитывает необходимые задержки между необходимыми переключениями режимов и командами на экран?


Я вам уже говорил что ютфт слишком общая и есть библиотека у ада

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

Глобальной переделкой библиотеки смогу заняться только зимой. Сейчас дома огород а на работе - работа... Как в анекдоте -"Всем хороша работа пожарника, но как пожар хоть увольняйся" :))

kortium
Offline
Зарегистрирован: 23.01.2015

что такое ада? 

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

и опять жеш менять шило на мыло. Взять одну общую библиотеку и поменять на неизвестную, что ту лопатить что эту...

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

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

kortium
Offline
Зарегистрирован: 23.01.2015

язык программирования есть АДА

kortium
Offline
Зарегистрирован: 23.01.2015

и в кусты спрятался...

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

kortium пишет:

и в кусты спрятался...


Вас в гуглях забанили что ли? Я понимаю что мир полон идиотов. Но зачем это на себе показывать?
https://github.com/adafruit/Adafruit_HX8357_Library

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

1. Данная библиотека сделана под HX8357D, на моем экранчике стоит контроллер HX8357B. По даташитам там много отличий в командах.

2. Заточена под SPI а у меня подключен по 16 пинам

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Ну тогда выкиньте и купите как у всех.
из моего опыта такие артефакты в одниз и тех же местах возникают от плохой пропайки между видео контролером и контролером матрицы.

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

появляющийся мусор не имеет географической привязки, он появляется хаотично по всей поверхности экрана

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Не важно. Раз было что просто кусок экрана показывал какие то неизвестные цвета.. после пропайки все прошло.
но в вашем случае нужно снимать кожух и смотреть что там внутри.

zhenya_alex
Offline
Зарегистрирован: 09.06.2015

Кто знает как можно этот дисплей программно отключать ? Ну или может есть способ подсветку как-то выключить?

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

если используешь библиотеку УТФТ то там есть команды

lcdOff
lcdOn
redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

в самой библиотеке есть файлик keywords.txt и там перечислины все команды этой библиотеки

zhenya_alex
Offline
Зарегистрирован: 09.06.2015

Если бы всё было так просто, я бы не спрашивал. Ваш дисплей включается/отключается этими командами? Вы пробовали? Мой никак на них не реагирует.

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

проверял - реагирует адекватно. тип контроллера экранчика указал правильно? по даташиту имеет такую функцию?

kortium
Offline
Зарегистрирован: 23.01.2015

подсветка не вырубится, там диоды напрямую к питанию подключены, управления нет

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

у меня черный становится, с лупой не рассматривал, но подсветка замечена не была при выключении командой

zhenya_alex
Offline
Зарегистрирован: 09.06.2015

 

Тип контроллера аналогичен как в названии темы. К тому же экран и по clrScr() тоже чернеет. 

redmaxs Раз у вас всё получается, поделитесь своей версией UTFT библиотеки с поддержкой данного контроллера? Возможно у меня не совсем верный вариант.

kortium Звучит очень правдоподобно про подсветку.

 

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

Не микроконтроллер а контроллер который установлен на экранчике, у меня установлен HX8357B (в моей проге смотри строку 7). А библиотека стандартная, кажется идет с программой для написания скетчей.

zhenya_alex
Offline
Зарегистрирован: 09.06.2015

Абсолютно верно, HX8357B. Ведёт себя полностью аналогично вашему, артефакты в рандомных местах точно так же вылезают со временем при работе, но это всё ладно, хочу выключать его и пока не понимаю как это сделать, стандартные lcdOff и lcdOn не работают.  Хотя в даташите есть и Set_display_of, и Enter_sleep_mode и ещё несколько различных режимов, подозреваю ничего из этого в библиотеку не выведено, только понять не могу как оно у вас может работать, всё ведь аналогично подключаю.

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

Видимо действительно когда проверял lcdOff и lcdOn использовал какую-то другую библиотеку. Доработал стандартную добавлением следующего - в файле UTFT.cpp дописал строки 1286-1288 и 1305-1307

void UTFT::lcdOff()
{
	cbi(P_CS, B_CS);
	switch (display_model)
	{
	case PCF8833:
		LCD_Write_COM(0x28);
		break;
	case CPLD:
		LCD_Write_COM_DATA(0x01,0x0000);
		LCD_Write_COM(0x0F);   
		break;
	case HX8357B:
		LCD_Write_COM(0x28);   
		break;
	}
	sbi(P_CS, B_CS);
}

void UTFT::lcdOn()
{
	cbi(P_CS, B_CS);
	switch (display_model)
	{
	case PCF8833:
		LCD_Write_COM(0x29);
		break;
	case CPLD:
		LCD_Write_COM_DATA(0x01,0x0010);
		LCD_Write_COM(0x0F);   
		break;
	case HX8357B:
		LCD_Write_COM(0x29);   
		break;
	}
	sbi(P_CS, B_CS);
}

Теперь экран выключается но подсветка не гаснет

 

kortium
Offline
Зарегистрирован: 23.01.2015

а смысл в таком выключении? что именно происходит? Стирание всех точек с экрана?

redmaxs
redmaxs аватар
Offline
Зарегистрирован: 24.04.2015

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

kortium
Offline
Зарегистрирован: 23.01.2015

zhenya_alex
Offline
Зарегистрирован: 09.06.2015

redmaxs пишет:

Видимо действительно когда проверял lcdOff и lcdOn использовал какую-то другую библиотеку. Доработал стандартную добавлением следующего - в файле UTFT.cpp дописал строки 1286-1288 и 1305-1307

Теперь экран выключается но подсветка не гаснет

Мдя, все оказалось предельно просто, спасибо за подсказку. Осталось с подсветкой что-то придумать и будет совсем отлично.