Библиотека Adafruit_GFX

Leopoll
Offline
Зарегистрирован: 16.06.2016

Есть TFT дисплей 3.2 Продавец с Али в комплекте дал библиотеку Adafruit_GFX 1.0.2 (актуальная 1.3.6) и MCUFRIEND 2.9.1 (актуальная 2.9.9)

MCUFRIEND кое-как удалось сменить на актуальную.  А Adafruit никак. 

1. Есть ли шанс все же обновить Adafruit?

2. Собственно, пытался обновить ради ускорения. Очень медленно рисует, мои данные выводит 500мс.

Будет ли быстрее, если обновить удастся?

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Шанс есть. А в чем проблема-то? Нажимаем <ctrl> + <shift> + I . Находим там  Adafruit GFX и устанавливаем.

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

Leopoll пишет:

MCUFRIEND кое-как удалось сменить на актуальную.  А Adafruit никак. 

1. Есть ли шанс все же обновить Adafruit?

2. Собственно, пытался обновить ради ускорения. Очень медленно рисует, мои данные выводит 500мс.

Будет ли быстрее, если обновить удастся?

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

Насчет станет ли быстрее - я бы особо не рассчитывал. Чтобы убыстрить процесс в разы - обычно нужно переписать библиотеку с нуля, а не выпустить новую версию. Процентов 20 может прибавить в скорости - и то хорошо.

Для начала я бы тщательно пересмотрел свой собственный код работы с дисплеем - может это не библиотека виновата?

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

b707 пишет:

Для начала я бы тщательно пересмотрел свой собственный код работы с дисплеем - может это не библиотека виновата?

Неистово плюсую. Бывает, напишешь в лоб - вроде норм. Потом отложишь на пару дней, вернёшься, оптимизируешь - и получаешь прирост в производительности отрисовки в несколько раз. И такое постоянно :)

Leopoll
Offline
Зарегистрирован: 16.06.2016

Не, ну как обновлять библиотеки я все же понимаю. Проблема в том, что не встают.

И с MCUFRIEND я рано обрадовался. Пока ситуация такая. Если обновить Adafruit - ошибка "declaration of 'FreeSmallFont' as array of references". Причем SmallFont относится как раз к MCUFRIEND. Если обновить MCUFRIEND , на экран ничего не выводится. 

Двадцать процентов было бы уже не плохо. 

Насчет кода, вот код вывода который выполняется ок. 100 мс. Причем отнюдь не из-за опроса сенсора.

int PrintOneValue (String Name, uint8_t* TAdress, uint8_t Vpin, uint16_t PARAM, uint16_t Correct, uint16_t PosX, uint16_t PosY)  {
    tft.setCursor ( PosX, PosY );
    tft.setColor (CYAN); tft.setBackColor (BLUE);
    tft.print ( utf8rus( Name ), PosX, PosY); 
    tft.setColor (WHITE); tft.setBackColor (BLUE);
    uint16_t tmp = sensors.getTempC(TAdress)*10; //Опрос сенсора Dallas temperature
  
    if ( tmp == -1270) tmp = 0;
    tmp += Correct;             //Корректировка 
    if (tmp > 1100) return 0;
    tft.setTextSize(4);
    if (tmp >= PARAM) {tone (ALERT, 1000 , 300); Blynk.notify (String ("Темпeратура "+ Name+" "+ ( float(tmp)/10) )); //Предупреждение через  BLYNK. В норме не работает, так что на время не влияет
    tft.setColor (RED); tft.setBackColor (YELLOW);
      }
    tft.printNumF (float(tmp)/10,1,PosX+ 90 - 14, PosY,',');
    tft.println (" ");
    tft.setColor (WHITE); tft.setBackColor (BLUE);
    tft.setTextSize(2);
    tft.printNumF (float(PARAM)/10,1, PosX, PosY+18,',');
return tmp;
}

Много тут можно оптимизировать?

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

Leopoll пишет:

Много тут можно оптимизировать?

Много. Во-первых, в строке номер 1 надо передавать String по ссылке, а не по значению. Во-вторых - вангую, что в функции utf8rus ( строка 4) - тоже идёт передача параметра типа String по значению. В-третьих - мешаем мух с котлетами: зачем-то в этой функции идёт работа с Blynk. В-четвёртых - в строке 12 совершенно дикое склеивание. В-пятых: вы несколько раз делаете float(tmp)/10 - вместо этого можно делать это один раз в начале функции, потом уже используя результат. В-шестых: в строке 6 идёт опрос датчиков температуры - опять путанье мух с котлетами. В-седьмых: функция tone - блокирующая, и опять тут не к месту, т.к. очередная порция смешения мух с котлетами.

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

Это то, что сразу бросилось в глаза.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Leopoll пишет:

Не, ну как обновлять библиотеки я все же понимаю. Проблема в том, что не встают.

По нормальному объяснить, в чем проблема, так и  не желаете?  

 

Leopoll
Offline
Зарегистрирован: 16.06.2016

DIYMan, спасибо. Посмотрю, что можно сделать. Разносить опрос датчика, обработку и вывод его значения будет весьма неудобно. Но что не сделаешь для быстродействия.

asam, очень желаю. Подскажите, как. Могу только повторить. При обновлении MCUFRIEND ошибок нет, но вывода на экран не происходит. Это видно и по скорости работы программы. 

При обновлении Adafruit  вылезает ошибка 

declaration of 'FreeSmallFont' as array of references

В коде есть строка 

extern uint8_t SmallFont[];

которая относиться как раз к библиотеке MCUFRIEND. Чем еще можно прояснить ситуацию?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

дак это две разные декларации

FreeSmallFont

и 

extern uint8_t SmallFont[];

Leopoll
Offline
Зарегистрирован: 16.06.2016

Да, но компилятор при ошибке указывает именно на эту строку.

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

Leopoll пишет:

Да, но компилятор при ошибке указывает именно на эту строку.

И что теперь? Вешаться?

В общем, Вас уже дважды просили объяснить толком. Для особо непонятливых, объясняю смысл слова "толком".

1. Проверочный скетч в студию полностью (копипастом)

2. Ссылку на библиотеку в студию

3. Текст сообщения об ошибке в студию полностью (копипастом)

Если, по каким-то причинам, "нет", то "на нет и суда нет".

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

Leopoll пишет:

DIYMan, спасибо. Посмотрю, что можно сделать. Разносить опрос датчика, обработку и вывод его значения будет весьма неудобно. Но что не сделаешь для быстродействия.

Leopoll - вы не поняли. Разносить надо обязательно, и делать это надо всегда, не только потому, что у вас тормозит вывод на экран. И пусть это для вас "неудобно". А чтобы в следующий раз не было "неудобно" исправлять - сразу пишите правильно.

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

 

Цитата:
asam, очень желаю. Подскажите, как. Могу только повторить.

несмотря на "желание" -  вы так и не написали, как вы обновляете библиотеки. Понимаете, библиотеки при обновлении просто в принципе  не могут "не встать" - поэтому вас и просят написать, как вы это делаете.

Или же вы просто выражаться не умеете и термином "библиотеки не встали" описываете то, что у вас с обновленными либами код не собирается? - ну так это не потому, что "библиотеки не установились", а потому что ваш код написан под старую библиотеку и для новой не подходит. Перепишите код под новую библиотеку и все заработает.

 

Leopoll
Offline
Зарегистрирован: 16.06.2016

b707, спасибо, конечно вы правы. Если не трудно, дайте ссылку, как создавать неблокирующий режим. Мне казалось, полноценной многозадачности в ардуино нет. Во время выполнения любой фунции остальные не работают. 

Да, видимо выражаться не умею. Конечно, код написан под старые библиотеки. Надеялся на обратную совместимость. Нет нигде мануала, как адаптировать код под новые? Наверно ведь не так много отличий, и многие должны были это проходить. Если нет, то сделаю все "в студию", надо время.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ну вот к примеру идеальные неблокирующие функции и, даже три

/********Раздел функций таймера под пищалку *****************/

enum Prescalers {
   PRESCALER_1 = 1, PRESCALER_8 = 2, PRESCALER_64 = 3, PRESCALER_256 = 4, PRESCALER_1024 = 5
};

void init_Timer(){
   uint8_t prescaler = PRESCALER_256;
   uint16_t topValue = 62499;
   pinMode(10, OUTPUT);
   TCCR1A = 0x10;              // Инвертирование пина 10 по сравнению
   TCCR1B = 0x08 | prescaler;  // Установить СТС режим и делитель частоты
   OCR1A = topValue;           // установить TOP равным topValue
}

void start_Timer(){
  TCCR1A = 0x10; 
}

void end_Timer(){
  TCCR1A &= ~0x30;
  digitalWrite(PIN_ZUM, LOW);
}

 

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

Leopoll пишет:

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

Полноценной многозадачности нет, но можно несколько задач выполнять попеременно. Именно поэтому большие задачи надо разбивать на маленькие кусочки, выполняющиеся как можно быстрее - чтобы между частями одной задачи успевать выполнять части других. Например, одновременно а)выводить на TFT экран секундомер, б)прокручивать на том же экране движущуюся строку, в)при этом без задержек реагировать на кнопки управления и г) еще в фоне 30 раз в секунду считывать и регулировать какой-нибудь параметр. А пользователю будет казаться, что программа все это делает разом.

Цитата:
Нет нигде мануала, как адаптировать код под новые?

мануала не встречал. Общий принцип простой - внимательно читаете ошибки, которые выдает компилятор(включить в опциях расширенный вывод) - находите в библиотеке строки, в которых ошибки возникают, сравниваете эти места со старой версией и разбираетесь, что надо поменять.

 

Leopoll
Offline
Зарегистрирован: 16.06.2016

А имеет смысл проверять предыдущее значение и вывод на экран делать только если данные изменились? Тогда время обработки будет сильно зависить от потока данных.

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

Leopoll пишет:

А имеет смысл проверять предыдущее значение и вывод на экран делать только если данные изменились? Тогда время обработки будет сильно зависить от потока данных.

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Leopoll пишет:

А имеет смысл проверять предыдущее значение и вывод на экран делать только если данные изменились? Тогда время обработки будет сильно зависить от потока данных.

все в конце концов сводится к автоматному программированию(программирование с помощью автоматов) явно или завуалировано. У данных есть переменная состояние - от состояния получить , обработать до состояния вывести. И вот в зависимости от значения это переменной состояния в разных участках работающей программы и происходит выполнения. Как созрели данные до состояния вывести , то их выводят индивидуально или всем пакетом, если созрело до состояния вывести много данных. А если не созрело, то пропускаем вывод и вся мощь процессора кидается на другие участки обработки программы.

Leopoll
Offline
Зарегистрирован: 16.06.2016

Всем спасибо за помощь. 

Еще есть вопрос. Не буду создавать новую тему. Использую библиотеку SimpleTimer. Работает не очень. Есть проблемы с именованными таймерами. Например в коде: 

  timer_reconnect = timer.setInterval(30155L, reconnect); 
  timer_showvaluse =  timer.setInterval(2031L, showvaluse);    
  timer_induction = timer.setInterval (3600387L, induciton);

Любой таймер, помещенный на первом месте в этом списке, работать не будет.

Можете подсказать хорошую библиотеку таймера, если возможно, то чтобы синтаксис команд не очень отличался?

 

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

Leopoll пишет:

Например в коде: 

  timer_reconnect = timer.setInterval(30155L, reconnect); 
  timer_showvaluse =  timer.setInterval(2031L, showvaluse);    
  timer_induction = timer.setInterval (3600387L, induciton);

Любой таймер, помещенный на первом месте в этом списке, работать не будет.

И на втором месте - тоже не будет работать. В таком коде, что у вас - ТОЛЬКО ПОСЛЕlНИЙ ТАЙМЕР работает. Потому что у вас в коде только один таймер, а не три.

Чтобы было понятнее, ваш код аналогичен вот такому:

a = 10;
a  = 20;
a = 30;

как выдумаете, если последовательно ОДНОЙ И ТОЙ ЖЕ переменной присвоить разные значения - она будет все их помнить? :) - смешной вопрос, правда?

Ну так у вас точно также - у вас везде один и тот же таймер с названием timer...

Правильный код для трех таймеров:

  SimpleTimer timer1, timer2, timer3;

   timer1.setInterval(30155L, reconnect); 
   timer2.setInterval(2031L, showvaluse);    
   timer3.setInterval (3600387L, induciton);

 

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

а вообще, для таких редких событий никакие библиотеки с таймерами вовсе не нужны, это пишется в одну строку на основе millis

Leopoll
Offline
Зарегистрирован: 16.06.2016

Совершенно точно, все таймеры кроме первого работают. И в официальном примере timer1, timer2 нет.
http://playground.arduino.cc/Code/SimpleTimer#Example

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

ну Ок, Вы правы - ваши таймеры поддерживают несколько интервалов в одном инстансе таймера.

Почему первый не запускается - я поискал в Гугле и нашел, что часть пользователей тоже жалуется на это, а другие пишут, что у них все ОК. Возможно, библиотека плохо совместима с какими-то версиями Ардуино ИДЕ.

Вообще, я бы на Вашем месте отказался от этой библиотеки. Чуть выше в ветке мы с вами обсуждали "многозадачность" Ардуино - так вот, эта библиотека абсолютно никк не помогает построить программу. быстро переключающуся между задачами. Чтобы получить быстро выполняющийся код - нужно рабивать каждую задачу на маленькие подзадачки и выполнять их по отдельности. Эта библиотека просто запускает большие задачи по заданным интервалам,  что, как я уже говорил - в разы проще делать вручную буквально одной строкой кода.

Leopoll
Offline
Зарегистрирован: 16.06.2016

Ну, с библиотекой удобнее. У меня не только редкие события, это для примера. Ну, ладно. 

Все же прошу помощи с MCUFRIEND.

Тестовый код:

#include <UTFTGLUE.h>              // class methods are in here
UTFTGLUE tft(0x9341,A2,A1,A3,A4,A0);

//extern uint8_t SmallFont[];

#define BLUE    0x001F
#define WHITE   0xFFFF

void setup() {
  // put your setup code here, to run once:
    Serial.begin(9600);
    Serial.println(" ");
    Serial.println("Launch");

     tft.InitLCD();
    // tft.setFont(SmallFont);
    // tft.begin(9600);
    // tft.reset();
     uint16_t identifier;
     identifier = tft.readID(); // 37671

     tft.begin(identifier);
     tft.setRotation(1);
}

void loop() {
 
    tft.fillScreen(BLUE);
    tft.setColor (WHITE); 
    tft.drawRoundRect (0, 0, 200, 100 );                   
    
    tft.setTextSize(2);                                       
    tft.setBackColor(BLUE); 
    tft.setColor (WHITE);
    tft.setCursor ( 2, 2 );
    tft.print (  "Example" , 2, 2 ); 
    
delay (10000);
   
}

Библиотеки продавца, с ними работает. Тамже доки на экран.

 https://drive.google.com/open?id=0B6uNNXJ2z4CxYktCQlViUkI1Sms

На новой MCUFRIEND не работает. Ошибок нет. На экран ничего не выводится. Может экран такой кривой, что только с этой версией и может работать?

 

 

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

Leopoll пишет:

Все же прошу помощи с MCUFRIEND.

Может экран такой кривой, что только с этой версией и может работать?

в MCUFriend по умолчанию поддержка части дисплеев выключена.

В папке examples этой библиотеки есть два скетча для диагностики дисплея - LCD_ID_readnew  и LCD_ID_readreg

Запустите их и напишите сюда ID вашего дисплея

 

 

Leopoll
Offline
Зарегистрирован: 16.06.2016

 В тестовом примере на старой библиотеке команда tft.readID() выдает 37671.

Скетчи из exapmles похоже дисплей не опознают. 

Read Registers on MCUFRIEND UNO shield
controllers either read as single 16-bit
e.g. the ID is at readReg(0)
or as a sequence of 8-bit values
in special locations (first is dummy)

diagnose any controller
reg(0x0000) 04 04	ID: ILI9320, ILI9325, ILI9335, ...
reg(0x0004) 04 04 04 04	Manufacturer ID
reg(0x0009) 0C 0C 0C 0C 0C	Status Register
reg(0x000A) 0C 0C	Get Powsr Mode
reg(0x000C) 0C 0C	Get Pixel Format
reg(0x0030) 04 04 04 04 04	PTLAR
reg(0x0033) 04 04 04 04 04 04 04	VSCRLDEF
reg(0x0061) 04 04	RDID1 HX8347-G
reg(0x0062) 04 04	RDID2 HX8347-G
reg(0x0063) 04 04	RDID3 HX8347-G
reg(0x0064) 04 04	RDID1 HX8347-A
reg(0x0065) 04 04	RDID2 HX8347-A
reg(0x0066) 04 04	RDID3 HX8347-A
reg(0x0067) 04 04	RDID Himax HX8347-A
reg(0x0070) 04 04	Panel Himax HX8347-A
reg(0x00A1) 04 04 D7 04 04	RD_DDB SSD1963
reg(0x00B0) 04 04	RGB Interface Signal Control
reg(0x00B3) 04 06 04 04 04	Frame Memory
reg(0x00B4) 04 04	Frame Mode
reg(0x00B6) 04 04 04 04 04	Display Control
reg(0x00B7) 04 06	Entry Mode Set
reg(0x00BF) 0E 0E 0C 0C 0C 0C	ILI9481, HX8357-B
reg(0x00C0) 04 04 04 04 04 04 04 04 04	Panel Control
reg(0x00C1) 04 04 04 04	Display Timing
reg(0x00C5) 04 04	Frame Rate
reg(0x00C8) 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C	GAMMA
reg(0x00CC) 0C 0C	Panel Control
reg(0x00D0) 04 04 04 04	Power Control
reg(0x00D1) 04 06 06 06	VCOM Control
reg(0x00D2) 06 06 06	Power Normal
reg(0x00D3) 06 06 06 06	ILI9341, ILI9488
reg(0x00D4) 06 04 04 04	Novatek
reg(0x00DA) 0C 0C	RDID1
reg(0x00DB) 0C 0C	RDID2
reg(0x00DC) 0C 0C	RDID3
reg(0x00E0) 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04	GAMMA-P
reg(0x00E1) 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04	GAMMA-N
reg(0x00EF) 0C 0C 0C 0C 0C 0C	ILI9327
reg(0x00F2) 04 04 04 04 04 04 04 04 04 04 04 04	Adjust Control 2
reg(0x00F6) 04 04 04 04	Interface Control

В скетче read_new в комментах указаны другие варианты распиновки. Надо пробовать? У меня Mega 2560.

 

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

попробуйте еще пример

dioagnose_TFT_support

Leopoll
Offline
Зарегистрирован: 16.06.2016
tft.readID() finds: ID = 0x454
Да, и пишет что не поддерживается.
andriano
andriano аватар
Онлайн
Зарегистрирован: 20.06.2015

Leopoll пишет:

 В тестовом примере на старой библиотеке команда tft.readID() выдает 37671.

В HEX это 9327.

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

Leopoli

в файле mcufriend.cpp раскомментируйте строчку #define OFFSET_9327 32 - примерно 20-ая - 23-я строка

Leopoll
Offline
Зарегистрирован: 16.06.2016

Она не закомментирована.

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