Тренд на Arduino Mega 2560 + TFT LCD 320х480 HX8357B
- Войдите на сайт для отправки комментариев
Привет все!
При попытке создания простого графика данных возникли вопросы и чем дальше тем больше...
Вопрос №1: Для того чтоб график рисовался красиво как на SCADA а не тупо по кругу и не найдя друго способа решил организовать хранение данных в массиве. Для этого сделал цикл смещения (устарение) данных типа buf[x+1]=buf[x]. Ширина графика 407 точек и поэтому массив имеет 407 элементов и такой массив не один, смещение циклом замедляет работу программы. И вот сам вопрос: есть ли более простой способ смещения данных в массиве или иной способ организовать непрерывный график?
Вопрос №2: Во время работы программы (непрерывно рисует график) экран покрывается хаотично расположенными точками разного цвета. Постояно перерисовывать весь экран отстойно, очень медленно и мерцание. Откуда могут возникать эти артефакты и как от них можно избавиться? На фото начало работы и 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++; } } }
и как спрятать код под "показать код"?
во второй вкладке есть галочка скрывать код
но первое сообщение не отредактировать)
превывание не умею делать. но можно использовать millis
это косяк этого экрана при работе с UTFT либой, попробуй в цикле просто слово какое-н много раз напечатать и эти точки полезут
Ты прав, при частом выводе на экран любой инфы точки лезут, чем чаще вывод информации тем больше точек. Экранирование ЛСД модуля может спасти ситуацию?
Очень похоже на плохой контакт ножек у шлейфа. Я перебрал несколько IDE шлейфов прежде чем нашел более-менее рабочий для своего экрана.
По самой задаче - а зачем смещать массив если можно просто хранить нулевую позицию и смещать цикл вывода. Приведу для примера на 4 значениях:
1-2-3-4
4-1-2-3
3-4-1-2
2-3-4-1
Получается просто переписываешь нулевую позицию. Единственно придется сделать переменную для этой позиции.
Спасибо за дельную идею :) сейчас буду обмозговывать.
А по шлейфу - это пленочный шлейф от платы-переходника на сам экран?
Чего тут думать.
1. Возмите нормальную библиотеку. Специально для этого контролера, а не универсальную фигню работающую через задний проход. Например у ада есть, правда не все реализовано там вроде.
2. Скорости меги не хватит отрисовывать экран и не мигать. Но контролер имеет свою память, изучайте даташит и пользуйтесь всеми его возможностями напрямую.
Есть одна идея. Правда тоже через одно место, но позволит ускорить отрисовку.
На текущей координате отрисовывается 2 точки: текущая нужным цветом и предыдущая цветом фона. Будет много быстрей чем выводить весь экран по новой.
А про шлейф я писал который на пины одевается
Идея хорошая и в данном случае уже реализована :) . В конце проги где длинные if идет востановление сетки, а если точка не попадает в сетку то красит черным. На фото видно что мусор присутствует сверху и снизу, ибо где кривая графика проходит мусор затирается. Вся проблема в том что за пределами кривой графика мусор (цветные точки) постоянно респится и чтоб его затереть надо обновлять экран, а это не есть гуд :(
Плата - адаптер экранчика имеет жестко впаяные пины (папа) и втыкается в плату контроллера без шлейфа, сам экранчик приклеен к плате - адаптеру и имеет пленочный шлейф и чтоб до него добраться надо отрывать экранчик от платы. Первой мыслью у меня было что от большой частоты переключений (когда идут команды на экранчик) происходит наводка на соседние пины или некоторые пины просто не успевают переключиться, но последняя мысль выглядит еще бредовее первой :)) . Мусор сыпится когда идет вывод любой графики, чем чаще идут команды на экранчик тем быстрее засирается мусором, эксперементировал с текстом и с графическими объектами, вывод один - пока не обращаешься к экрану мусор не появляется.
Появится лишнее время попробую порисовать без использования библиотеки... Мож чо и добьюсь :) .
я пробова отклеивать экран, промывать шлейф, кондеры на питание, ничего не помогает
Да, бяда. Остается только библиотека и сам контроллер (если исключить возможность некачественной сборки экранчика)
штук 10 плат пробовал, у всех одинаковая беда
Значит непропай на разьемах ардуино.
да всё пропаяно, я же говорю 10 комплектов проверял
Пробовал с библиотекой и с одним и тем жеш контроллером спаривать?
да всё пропаяно, я же говорю 10 комплектов проверял
Значит нужно проверить подключить к другому компу!
какому компу? она к атмеге подключается
какому компу? она к атмеге подключается
Вот мегу и подключить к другому компу. Коротким шнурком в задний узб. Походу питания не хватает.
чудеса бывают только в сказке
просто человек пытается до нас донести что электротехника - это наука о контатах :))
при чем тут комп, я от внешнего источника запитывал. Я не настока ламер чтобы это все не перепробовать, я спиртом плату промывал, кондеры там на питание вешал, и к DUE подключал ее и к меге, везде одно и то же, и от аккума питал
пока читал вашу перепалку в голову забрела мысль и возможно не глупая :) . Что если стандартная библиотека не учитывает необходимые задержки между необходимыми переключениями режимов и командами на экран?
при чем тут комп, я от внешнего источника запитывал. Я не настока ламер чтобы это все не перепробовать, я спиртом плату промывал, кондеры там на питание вешал, и к DUE подключал ее и к меге, везде одно и то же, и от аккума питал
Угу. А помимо экрана еще гирлянда на 2 киловата от меги запитана? :)
пробуй, если получится расскажи )
пока читал вашу перепалку в голову забрела мысль и возможно не глупая :) . Что если стандартная библиотека не учитывает необходимые задержки между необходимыми переключениями режимов и командами на экран?
Я вам уже говорил что ютфт слишком общая и есть библиотека у ада
Глобальной переделкой библиотеки смогу заняться только зимой. Сейчас дома огород а на работе - работа... Как в анекдоте -"Всем хороша работа пожарника, но как пожар хоть увольняйся" :))
что такое ада?
и опять жеш менять шило на мыло. Взять одну общую библиотеку и поменять на неизвестную, что ту лопатить что эту...
Сорри за офтоп. Но была такая песня "мы дети из ада", но когда ее слушаешь то кажется что песня совешенно не про ад ))
язык программирования есть АДА
и в кусты спрятался...
и в кусты спрятался...
Вас в гуглях забанили что ли? Я понимаю что мир полон идиотов. Но зачем это на себе показывать?
https://github.com/adafruit/Adafruit_HX8357_Library
1. Данная библиотека сделана под HX8357D, на моем экранчике стоит контроллер HX8357B. По даташитам там много отличий в командах.
2. Заточена под SPI а у меня подключен по 16 пинам
Ну тогда выкиньте и купите как у всех.
из моего опыта такие артефакты в одниз и тех же местах возникают от плохой пропайки между видео контролером и контролером матрицы.
появляющийся мусор не имеет географической привязки, он появляется хаотично по всей поверхности экрана
Не важно. Раз было что просто кусок экрана показывал какие то неизвестные цвета.. после пропайки все прошло.
но в вашем случае нужно снимать кожух и смотреть что там внутри.
Кто знает как можно этот дисплей программно отключать ? Ну или может есть способ подсветку как-то выключить?
если используешь библиотеку УТФТ то там есть команды
в самой библиотеке есть файлик keywords.txt и там перечислины все команды этой библиотеки
Если бы всё было так просто, я бы не спрашивал. Ваш дисплей включается/отключается этими командами? Вы пробовали? Мой никак на них не реагирует.
проверял - реагирует адекватно. тип контроллера экранчика указал правильно? по даташиту имеет такую функцию?
подсветка не вырубится, там диоды напрямую к питанию подключены, управления нет
у меня черный становится, с лупой не рассматривал, но подсветка замечена не была при выключении командой
Тип контроллера аналогичен как в названии темы. К тому же экран и по clrScr() тоже чернеет.
redmaxs Раз у вас всё получается, поделитесь своей версией UTFT библиотеки с поддержкой данного контроллера? Возможно у меня не совсем верный вариант.
kortium Звучит очень правдоподобно про подсветку.
Не микроконтроллер а контроллер который установлен на экранчике, у меня установлен HX8357B (в моей проге смотри строку 7). А библиотека стандартная, кажется идет с программой для написания скетчей.
Абсолютно верно, HX8357B. Ведёт себя полностью аналогично вашему, артефакты в рандомных местах точно так же вылезают со временем при работе, но это всё ладно, хочу выключать его и пока не понимаю как это сделать, стандартные lcdOff и lcdOn не работают. Хотя в даташите есть и Set_display_of, и Enter_sleep_mode и ещё несколько различных режимов, подозреваю ничего из этого в библиотеку не выведено, только понять не могу как оно у вас может работать, всё ведь аналогично подключаю.
Видимо действительно когда проверял lcdOff и lcdOn использовал какую-то другую библиотеку. Доработал стандартную добавлением следующего - в файле UTFT.cpp дописал строки 1286-1288 и 1305-1307
Теперь экран выключается но подсветка не гаснет
а смысл в таком выключении? что именно происходит? Стирание всех точек с экрана?
Если тупо стирать экран, то потом надо перерисовывать содержимое. А выключив не надо перерисовывать, информация остается и при включении картинка та-жеш. Посветку не отрубишь, подключена напрямую к 5В.
Видимо действительно когда проверял lcdOff и lcdOn использовал какую-то другую библиотеку. Доработал стандартную добавлением следующего - в файле UTFT.cpp дописал строки 1286-1288 и 1305-1307
Теперь экран выключается но подсветка не гаснет
Мдя, все оказалось предельно просто, спасибо за подсказку. Осталось с подсветкой что-то придумать и будет совсем отлично.