ST7735S 0.96" 80x160 SPI - криво работает

Sirocco
Offline
Зарегистрирован: 28.09.2013

Приобрёл такой дисплей

Суть проблемы: 

1. Работает инверсно и боком. Инверсия по цвету. Чтоб работал не в портретной ориентации, надо программно переворачивать.

2. Существенная проблема - полосы шума по краям, бывает снизу, бывает сбоку.

В Arduino IDE 1.8.12 установил ядро ESP8266, через "Управление библиотеками" установил необходимые библиотеки Adafruit, смотрел этот PDF  http://www.icshopping.com.tw/368031001441/adafruit-mini-breakout.pdf

Использую ESP12S. Если инверсия просто неприятность, то полоски по бокам реально бесят. Я порыл инфу. Нашёл что у подобных экранов куча проблем. Матрица на которую контроллер запрограммирован 80x60, а по факту сам экран может оказаться 81х162 - отсюда полосы. И смещены координаты. Программно зажигаю пиксел 0,0, по факту загорается 1,2. (x,y). Информация была, что проблема есть, но решения не нашёл.

Может кто победил проблему?

Мой код:

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <SPI.h>
//На экране на плате не верно подписано, там не SDA и SCL, он не I2C, он имеет SPI интерфейс

#define TFT_DC    4     //DC экрана на GPIO 4
#define TFT_RST   2     //RES экрана на GPIO 2
#define TFT_CS    15    //CS экрана на GPIO 15
#define TFT_MOSI  13    //SDA пин экрана подключаем к GPIO 13 (MOSI)
#define TFT_SCLK  14    //SCL пин экрана подключаем к GPIO 14 (CLK)

#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_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

void setup(void) {
  Serial.begin(115200);
  tft.cp437(true);
  tft.initR(INITR_MINI160x80);
 
  tft.setRotation(1);

  //tft.invertDisplay(true);
  //tft.invertDisplay(false);
  tft.setCursor(20, 25);
  tft.fillScreen(ST77XX_WHITE);
  tft.setTextSize(3);
  tft.setTextColor(BLACK);
  tft.print(utf8rus("27.8 \xB0"));
  tft.print(utf8rus("C"));

}

void loop() {/*
  tft.invertDisplay(true);
  delay(500);
  tft.invertDisplay(false);
  delay(500);*/
}

/* Recode russian fonts from UTF-8 to Windows-1251 */
String utf8rus(String source)
{
  int i,k;
  String target;
  unsigned char n;
  char m[2] = { '0', '\0' };

  k = source.length(); i = 0;

  while (i < k) {
    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;
}

 

Sirocco
Offline
Зарегистрирован: 28.09.2013

Начал ковырять, что к чему... Пересчитал все пиксели, всё сходится, 80х160. И выявил проблему.

По хорошему нумерация пикселей идёт с 0:0. А по факту получилось (выяснено опытным путём), что самый первый пиксель, тот что должен быть 0:0, программой(библиотекой) определён как 1:2.

Отсюда и получилось смещение, отсюда и вылез шум на краях. Как раз по нижней границе шум в два пикселя и справа в один.

Как пправить смещение я не знаю. Всё что придумал - это задать в драйвере, типа разрешение экрана 82х161.

Это в файле Adafruit_ST77xx.h поправил строки 35 и 37.

Было:

#define ST7735_TFTWIDTH_128 128  // for 1.44 and mini
#define ST7735_TFTWIDTH_80 80    // for mini         
#define ST7735_TFTHEIGHT_128 128 // for 1.44" display
#define ST7735_TFTHEIGHT_160 160 // for 1.8" and mini display

Стало:

#define ST7735_TFTWIDTH_128 128  // for 1.44 and mini
#define ST7735_TFTWIDTH_80 82    // for mini                   //ВМЕСТО 80 стало 82
#define ST7735_TFTHEIGHT_128 128 // for 1.44" display
#define ST7735_TFTHEIGHT_160 161 // for 1.8" and mini display  //ВМЕСТО 160 стало 161

Если кто знает как поправить смещение, расскажите. Ну и с инверсией тоже пока не решено. Изначально экран перевернут на бок, и все цвета инвертированы. Если повернуть экран особо нет проблем, то вот исправить черезжопную цветность вопрос сложнее.

IVAN222
Offline
Зарегистрирован: 19.04.2017

Раньше я тоже пользовался этими библиотеками. Сейчас пользуюсь TFT_eSPI-master , Быстродействие выше. Даже видео в виде анимации можно смотреть . https://yadi.sk/i/OvliKj5UOToVNw в библиотеке откройте файл User_Setup.h и заточите его под Ваш монитор . там и ST7735 под Ваш чип, разрешения по пикселям и RGB, BGR- этим измените инверсию, а на счет боковой линии у меня такое было на мониторах 128-128. не надо писать прибавлять пиксели если разрешение 80-160 то так и писать, 1) способ как я убрал боковую полосу я сдвинул в право на 2 пикселя tft.pushImage(0,2,128,128,mercy1); 2) способ и самый лучший в файле где фото я указал ширину и высоту а в коде указал что надо обращатся тудаtft.pushImage(0,0,Width,Height,mercy2); тут я работаю с фото, а Вашем случае попробуйте в самом начале сделать черный экран и сдвиньте на 2-1 или 3 пикселя в право , для начала запустите эту библиотеку TFT_eSPI-master. Поройтесь в User_Setup.h по экспериментируйте может там уберете линию.

Sirocco
Offline
Зарегистрирован: 28.09.2013

Библиотека заработала нормально. И по цвету и по координатам. Только как туда кириллицу засунуть? Даже знак градуса вывести не может. Не, я видел, там типа уже есть куча кодовых страниц, я всё раскоментировал, но не работает.

IVAN222
Offline
Зарегистрирован: 19.04.2017

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

Sirocco
Offline
Зарегистрирован: 28.09.2013

Да есть там возможность подгрузить вообще любой шрифт. Тут описывается. https://github.com/Bodmer/TFT_eSPI/blob/master/Tools/Create_Smooth_Font/Create_font/Create_font.pde Только надо каким-то левым приложением создать этот шрифт в файле .vlw, а потом другим левым приложением закинуть этот шрифт в SPIFFS, потом его оттуда вызвать и он работает. Сегодня весь день потратил тупо на то, чтоб в SPIFFS выгрузку сделать. Не работало, сидел подбирал разные версии ядра и IDE, перелопатил кучу гитхаб веток. 

Загрузил пример Unicode test, там были три готовых шрифта. Дисплей отрисовал иероглифы и два красивых шрифта латиницей. 

Осталось понять как создать шрифт с кирилицей. Нужно Processing, нужна кровь девственницы, рог единорога, засушенный  COVID-19(0,5гр.), и пару суток на курение форумов чтоб из этого всего сварить кириллический шрифт.  Пока есть только первый ингридиент. Что делать с остальным не знаю. 

IVAN222
Offline
Зарегистрирован: 19.04.2017

Можно свой шрифт на кириллице создать, это каждую букву. С помощью этой программки lcd-image-converter изображение или шрифт преобразует в формат "С". Муторно конечно но работает. Делает и в цвете и в монохроме. 

Sirocco
Offline
Зарегистрирован: 28.09.2013

Да я начинаю вкуривать постепенно. Скачал эту processing-3.5.4

Там, в библиотеке, в папке TFT_eSPI-master\Tools\Create_Smooth_Font\Create_font есть файл Create_font.pde Этот файл нужно открыть в программе processing-3.5.4. Далее раскоментировать нужное, настроить под себя, и всё чудным чудом должно само сделаться. Но чуда не происходит, прога лепит файлы шрифтов только с латиницей, остальное квадратами. 

И как это победить - без понятия.

Но нашёл такую штуку:

В меню "Инструменты" есть "Создать шрифт". Выбираем шрифт, выбираем некоторые опции по количеству символов в шрифте (либо все вообще либо чуть-чуть, конкретные не выбрать), задаём размер в пикселях, потом шрифт только этого размера будет, изменить нельзя. И создаём...

Что получилось:

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

 

IVAN222
Offline
Зарегистрирован: 19.04.2017

Очень даже хорошо. Но почему геморно и не рационально, а есть еще какой то вариант лучше и быстрей?

Sirocco
Offline
Зарегистрирован: 28.09.2013

IVAN222 пишет:

Очень даже хорошо. Но почему геморно и не рационально, а есть еще какой то вариант лучше и быстрей?

Да. По замыслу автора его прога (Create_font.pde) должна делать именно те символы, которые нужны, и не больше. Ну для слова "Улица" мне нужно только 5 букв, или даже 4 кириллических символа, но мне приходится из-за этого подгружать все символы кириллической таблицы, а это от 80 до 250 кб, в зависимости от размера шрифта. Почему-то вес зависит от размера, видать там растровое изображение символов.

Или я бы просто закинул на килобайт свои пять символов. Можно конечно поставить флеху и не париться, или купить ESP c 16Mb памяти, но от этого ещё и быстродействие падает. 

Самый шустрый и удобный вариант - встроенные в скетч шрифты.

IVAN222
Offline
Зарегистрирован: 19.04.2017

Памяти занимает много , если взять картинку с разрешением 240-320 в цвете то во внутреннюю влеш память ESP32 можно запихать только 4.5 картинок. пробовал установить флешку на 2 гб , туда уже можно было запихать много , но скорость упала , воспроизведение стало паршивое верх уже загрузился а низ еще грузится и получилось плавающая картинка. Нашел я в энете автор там пользуется графической библиотекой с кириллицей. https://www.youtube.com/watch?v=1GEdd-N3GR0&t=3s

Sirocco
Offline
Зарегистрирован: 28.09.2013

Да там обычный адафрукт, его русифицировали давно. http://arduino.ru/forum/programmirovanie/rusifikatsiya-biblioteki-adafruit-gfx-i-vyvod-russkikh-bukv-na-displei-v-kodi?page=8#comment-427803

Проблема в моём случае- с этими библиотеками мой экран работает коряво.  Координаты смещены, цвета в инверсии. И скорость работы существенно ниже, нежели у нами обсуждаемой библиотеки. 

Но я вот закинул шрифт который нужен, он получился весом 265кб. И выводится примерно так:

Что вообще не круто. По замыслу должно мигать...

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

Sirocco пишет:

Но я вот закинул шрифт который нужен, он получился весом 265кб.

это какая-то ошибка. У вас весь экран чуть более 1 К размером, буква явно занимает не более 1/10 площади - отсюда вывод что фонт для сотни букв должен занимать максимум 10К. а не 265

Sirocco
Offline
Зарегистрирован: 28.09.2013

Откуда я знаю сколько там символов? Чем открыть файл .vlw и как посмотреть шрифты в нём? Может там 36 букв и тыщу всяких знаков? Вот  сейчас поставил минимальный набор - 153Кб, но уже нет знака градуса и процента.

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

Sirocco пишет:

Откуда я знаю сколько там символов? Чем открыть файл .vlw и как посмотреть шрифты в нём?

виндо-юзер ? :) думаешь буквы после точки в имени файла имеют сакральный смысл? - любой файл можно открыть в Нотепаде, например. Только в случае бинарного файла ты увидишь мешаниную закорючек,а в текстовом - осмысленное инфо

andreyii
Offline
Зарегистрирован: 15.04.2020

Если работать с Adafruit, после инициализации дисплея вызвать : tft.invertDisplay(true) , это починит цвета.

В "Adafruit_ST7735.cpp" строки 233,234 (_colstart = 24;_rowstart = 0;), поменять знчения на 26 и 1, это уберет смещения.

 

Sirocco
Offline
Зарегистрирован: 28.09.2013

Ооо! Я смотрю у нас тут спецы подтянулись!

b707 пишет:

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

Ну вот шрифт в нот пад, И чё?

Теперь, так понимаю, погуглите и предложите открыть его в processing ? Сразу нет. До этого я и без вас догадался.

andreyii пишет:

Если работать с Adafruit, после инициализации дисплея вызвать : tft.invertDisplay(true) , это починит цвета.

Нет. Не починит. Черный в белый оно обратит, и только. А красный оно покажет как синий в случае с tft.invertDisplay(true), а в случае tft.invertDisplay(false)  красный будет рыжим.

andreyii пишет:

В "Adafruit_ST7735.cpp" строки 233,234 (_colstart = 24;_rowstart = 0;), поменять знчения на 26 и 1, это уберет смещения.

это возможно. Я пока решил другим способом - расширил область до 81х162. Но надо попробовать.

andreyii
Offline
Зарегистрирован: 15.04.2020

Разобрался...

Все таки tft.invertDisplay(true) надо использовать и перепутаны красный с синим...

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

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

Sirocco
Offline
Зарегистрирован: 28.09.2013

Дети легли спать, воцарила домашняя карантинная тишина. Мозг остыл и начал работать. Допёр как это делается. По сути - читаем коменты в файле Create_font.pde. Не дошло? Ну тут всё просто - перечитываем заново. Этот файл включен в состав библиотеки TFT_eSPI-master и лежит тут: TFT_eSPI-master\Tools\Create_Smooth_Font\Create_font 

Начинаем с того, что устанавливаем в систему шрийт который нам нужен. Далее скачиваем прогу processing. Это какой-то бесплатный IDE типа ардуино IDE, работает из папки без установки, на текущий момент это processing-3.5.4. Открываем этой прогой файл Create_font.pde и сразу запускаем кнопкой с треугольником "запустить". Произойдут какие-то там операции, на данном этапе важно лишь то, что прога создаст файл с отображением и нумерацией шрифтов в операционной системе. Это файл System_Font_List.txt. Открываем, ищем свой шрифт по названию:

Нужный мне шрифт находится в строке 61 под номером 60. Запоминаем порядковый номер шрифта.

Далее возвращаемся в processing и редактируем файл Create_font.pde

Что нужно менять? Строка 124 (ну это текущая, ясно что потом может измениться)

int fontNumber = -1; // << Use [Number] in brackets from the fonts listed.

в этой строке задаём номер шрифта

int fontNumber = 60; // << Use [Number] in brackets from the fonts listed.

А в строке 130 пишем как он будет называться, имя файла

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

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

Далее можно раскоментировать все символы которые необходимы, так сказать набор кодировок.  Нужна кириллица - откройте её. Я же решил сделать только необходимые мне символы, и их всего пять. Это занимает существенно меньше памяти, существенно быстрее делается выборка - быстрее перерисовывается изображение. Для выбора конкретных символов идём ниже.

Указываем коды символов которые нужны. Берём их из википедии, например, https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)

На этом всё. Жмём "Запустить" и создаётся файл шрифта только с нашими символами и только необходимого нам размера, и ни бита лишней информации. У меня получилось это:

Шрифт из четырёх символов высотой 46 пикселей весом 4,10 КБ (4 202 байт).

P.S. Теперь он выводится в 3-5 раз быстрее, ем ранее: http://arduino.ru/forum/apparatnye-voprosy/st7735s-096-80x160-spi-krivo-rabotaet#comment-529994

Раньше:

теперь:

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

а всего-то надо было прочитать инструкцию.

Что касается фонта - опять собрали неправильно. Читайте что написано в самой верхней строке:

перевожу - сюда вставить Юникоды символов, которые должны быть ДОБАВЛЕНЫ с стандартному ASCII. А у вас используются обычная латиница. поэтому ничего добавлять не надо. Ну и по размеру полученного файла (4к) очевидно, что в нем не 4 символа, а вся ASCII таблица полностью

Для проверки можете, не меняя фонта, попробовать вывести на экран слово "STOP" - вы увидите. что оно выводится. хотя этих букв вы "не заказывали"

Sirocco
Offline
Зарегистрирован: 28.09.2013

b707 пишет:

а всего-то надо было прочитать инструкцию.

Что касается фонта - опять собрали неправильно. Читайте что написано в самой верхней строке:

перевожу - сюда вставить Юникоды символов, которые должны быть ДОБАВЛЕНЫ с стандартному ASCII. А у вас используются обычная латиница. поэтому ничего добавлять не надо. Ну и по размеру полученного файла (4к) очевидно, что в нем не 4 символа, а вся ASCII таблица полностью

Для проверки можете, не меняя фонта, попробовать вывести на экран слово "STOP" - вы увидите. что оно выводится. хотя этих букв вы "не заказывали"

Какой стандартный ASCII? Для кого он стандартный? для китайцев? для иврита?для арабов? Я ж вроде чётко написал, что выключил ВСЁ, и добавил эти символы. Сугубо эти. И даже привёл скрин получившегося файла шрифта состоящего из всех четырёх символов. По поводу веса споры непонятны. Вы вкурсе что символы передаются по сути в формате Bitmap, ибо как контроллер будет с векторами работать? И сколько по вашему должен весить файл картинки с разрешением 46x40 пикселей? Два байта?

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

Sirocco пишет:

 И сколько по вашему должен весить файл картинки с разрешением 46x40 пикселей?

46*40 /8 = 230 байт

Итого в ваших 4к должно поместится примерно 20 символов.

Если же вы думаете, что там байт на пиксель - туда и 4 символа такого размера не влезли бы

Sirocco
Offline
Зарегистрирован: 28.09.2013

Объясните мне тогда такую вещь. Эти 4 символа в размере 46 пикселей весят 4,10 КБ (4 202 байт).

А в размере 23 пикселя 1,20 КБ (1 237 байт)

Почему?

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

формат фонта какой? Все тот же неведомый .vlw или теперь внутри файла обычный массив Progmem. как в Адафруте?

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

Nikolaha53rus
Offline
Зарегистрирован: 17.04.2016

Приветствую. Залил картинку с SD карты. На машине поворотник оранжевый, на экране он голубой. Инверсия по цветам, черный  и белый нормально всё, а вот желтый, синий в инверсии. Подскажите как и где это поправить? 

если в скетче написать tft.invertDisplay(false);

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

Обсуждалось ранее -за смещение изображения спасибо.

IVAN222
Offline
Зарегистрирован: 19.04.2017

Если пользуетесь этой библиотекой #include <TFT_eSPI.h>, в ней есть User_Setup , раскоментируйте что то из этого. 

 //  #define TFT_RGB_ORDER TFT_RGB  // Colour order Red-Green-Blue

//  #define TFT_RGB_ORDER TFT_BGR  // Colour order Blue-Green-Red
Nikolaha53rus
Offline
Зарегистрирован: 17.04.2016

Пользуюсь ими Adafruit_GFX и Adafruit_ST7735

на борту Nano, модуль SD, экран 0,96 80x160.

IVAN222
Offline
Зарегистрирован: 19.04.2017

#define MADCTL_RGB_PARAM 0     // ‘0’ =RGB панель цветового фильтраl, ‘1’ =BGR панель цветового фильтра)

Nikolaha53rus
Offline
Зарегистрирован: 17.04.2016

IVAN222

#define MADCTL_RGB_PARAM 0     // ‘0’ =RGB панель цветового фильтраl, ‘1’ =BGR панель цветового фильтра)

 

Не помогает.

Писал не сам, вытащил из простор, пытался править под себя, мозгов не хватает самому написать.

Если не правильно вставил, не по правилам форума, поправьте меня, наведите на путь истинный.

вот код:

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
#include <SD.h>
 
#define TFT_CS  10  // Chip select line for TFT display
#define TFT_RST  8  // Reset line for TFT (or see below...)
#define TFT_DC   9  // Data/command line for TFT
#define SD_CS    4  // Chip select line for SD card
 
#define TFT_CS     10
#define TFT_RST    9  // you can also connect this to the Arduino reset
                      // in which case, set this #define pin to -1!
#define TFT_DC     8
#define MADCTL_RGB_PARAM 1
// Option 1 (recommended): must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);
 
// Option 2: use any pins but a little slower!
#define TFT_SCLK 13   // set these to be whatever pins you like!
#define TFT_MOSI 11   // set these to be whatever pins you like!
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
 
void setup(void) {
  Serial.begin(9600);
 
  //tft.initR(INITR_BLACKTAB);
//tft.cp437(true);
  tft.initR(INITR_MINI160x80);
  tft.invertDisplay(true);
  Serial.print("Initializing SD card...");
  if (!SD.begin(SD_CS)) {
    Serial.println("failed!");
    return;
  }
  Serial.println("OK!");
 
  tft.setRotation(1); // Landscape
 
}
 
void loop() {
 
  bmpDraw("1.bmp", 0, 0);
  delay(4000);
  bmpDraw("2.bmp",0,0);
  delay(4000);
  bmpDraw("3.bmp",0,0);
  delay(4000);
  bmpDraw("4.bmp",0,0);
  delay(4000);
  bmpDraw("5.bmp",0,0);
  delay(5000);
 
}
 
 
#define BUFFPIXEL 20
 
void bmpDraw(char *filename, uint8_t x, uint8_t y) {
 
  File     bmpFile;
  int      bmpWidth, bmpHeight;   // W+H in pixels
  uint8_t  bmpDepth;              // Bit depth (currently must be 24)
  uint32_t bmpImageoffset;        // Start of image data in file
  uint32_t rowSize;               // Not always = bmpWidth; may have padding
  uint8_t  sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
  uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
  boolean  goodBmp = false;       // Set to true on valid header parse
  boolean  flip    = true;        // BMP is stored bottom-to-top
  int      w, h, row, col;
  uint8_t  r, g, b;
  uint32_t pos = 0, startTime = millis();
 
  if((x >= tft.width()) || (y >= tft.height())) return;
 
  Serial.println();
  Serial.print("Loading image '");
  Serial.print(filename);
  Serial.println('\'');
 
  // Open requested file on SD card
  if ((bmpFile = SD.open(filename)) == NULL) {
    Serial.print("File not found");
    return;
  }
 
  // Parse BMP header
  if(read16(bmpFile) == 0x4D42) { // BMP signature
    Serial.print("File size: "); Serial.println(read32(bmpFile));
    (void)read32(bmpFile); // Read & ignore creator bytes
    bmpImageoffset = read32(bmpFile); // Start of image data
    Serial.print("Image Offset: "); Serial.println(bmpImageoffset, DEC);
    // Read DIB header
    Serial.print("Header size: "); Serial.println(read32(bmpFile));
    bmpWidth  = read32(bmpFile);
    bmpHeight = read32(bmpFile);
    if(read16(bmpFile) == 1) { // # planes -- must be '1'
      bmpDepth = read16(bmpFile); // bits per pixel
      Serial.print("Bit Depth: "); Serial.println(bmpDepth);
      if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
 
        goodBmp = true; // Supported BMP format -- proceed!
        Serial.print("Image size: ");
        Serial.print(bmpWidth);
        Serial.print('x');
        Serial.println(bmpHeight);
 
        // BMP rows are padded (if needed) to 4-byte boundary
        rowSize = (bmpWidth * 3 + 3) & ~3;
 
        // If bmpHeight is negative, image is in top-down order.
        // This is not canon but has been observed in the wild.
        if(bmpHeight < 0) {
          bmpHeight = -bmpHeight;
          flip      = false;
        }
 
        // Crop area to be loaded
        w = bmpWidth;
        h = bmpHeight;
        if((x+w-1) >= tft.width())  w = tft.width()  - x;
        if((y+h-1) >= tft.height()) h = tft.height() - y;
 
        // Set TFT address window to clipped image bounds
        tft.setAddrWindow(x, y, x+w-1, y+h-1);
 
        for (row=0; row<h; row++) { // For each scanline...
 
          // Seek to start of scan line.  It might seem labor-
          // intensive to be doing this on every line, but this
          // method covers a lot of gritty details like cropping
          // and scanline padding.  Also, the seek only takes
          // place if the file position actually needs to change
          // (avoids a lot of cluster math in SD library).
          if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
            pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
          else     // Bitmap is stored top-to-bottom
            pos = bmpImageoffset + row * rowSize;
          if(bmpFile.position() != pos) { // Need seek?
            bmpFile.seek(pos);
            buffidx = sizeof(sdbuffer); // Force buffer reload
          }
 
          for (col=0; col<w; col++) { // For each pixel...
            // Time to read more pixel data?
            if (buffidx >= sizeof(sdbuffer)) { // Indeed
              bmpFile.read(sdbuffer, sizeof(sdbuffer));
              buffidx = 0; // Set index to beginning
            }
 
            // Convert pixel from BMP to TFT format, push to display
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            tft.pushColor(tft.Color565(r,g,b));
          } // end pixel
        } // end scanline
        Serial.print("Loaded in ");
        Serial.print(millis() - startTime);
        Serial.println(" ms");
      } // end goodBmp
    }
  }
 
  bmpFile.close();
  if(!goodBmp) Serial.println("BMP format not recognized.");
}
 
// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.
 
uint16_t read16(File f) {
  uint16_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read(); // MSB
  return result;
}
 
uint32_t read32(File f) {
  uint32_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read();
  ((uint8_t *)&result)[2] = f.read();
  ((uint8_t *)&result)[3] = f.read(); // MSB
  return result;
}

 

 

IVAN222
Offline
Зарегистрирован: 19.04.2017
 Вставь в loop это.
   tft.initR(INITR_GREENTAB);
   tft.setRotation(ST7735_MADCTL_BGR);
Nikolaha53rus
Offline
Зарегистрирован: 17.04.2016

Вставил  tft.initR(INITR_GREENTAB);

цвета пришли в норму, а вот изображение сместилось на 1/3 вверх, ну да ладно. Буду пробовать подвинуть.

От 2-й строки никаких видимых изменений

Спасибо.!!!

Всё поправил, догадался. Нужно было в Adafruit_ST7735.cpp изменить строки 

if(options == INITR_GREENTAB) {
    commandList(Rcmd2green);
    colstart = 26;
    rowstart = 1;
IVAN222
Offline
Зарегистрирован: 19.04.2017

Правильно при этом изображение сместится немного в сторону . Попробуйте просто перевернуть изображение на 180 градусов в строке 41 поставьте 3.

Nikolaha53rus
Offline
Зарегистрирован: 17.04.2016

Вопрос решён, еще раз спасибо. Поправил пост выше.

Nikolaha53rus
Offline
Зарегистрирован: 17.04.2016

Приветствую! Еще вопрос по данному дисплею. Подключаю его к ESP8266. Работает, завёл. Пытаюсь грузить картинки в память ESP. Грузятся, вижу что файл есть. Не могу вывести на экран, без SD карты, видел с другим дисплеем делают. Тему новую создать? Или тут можно писать? Вроде тема о данном экране.

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

Nikolaha53rus пишет:

Приветствую! Еще вопрос по данному дисплею. Подключаю его к ESP8266. Работает, завёл. Пытаюсь грузить картинки в память ESP. Грузятся, вижу что файл есть. Не могу вывести на экран, без SD карты, видел с другим дисплеем делают. Тему новую создать? Или тут можно писать? Вроде тема о данном экране.

Если без SD не работает, ка с SD работает, то при чем тут "данный экран".

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

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

Nikolaha53rus
Offline
Зарегистрирован: 17.04.2016

Обязательно, поэтому и спросил. Неправильно немного изложил проблему.

IVAN222
Offline
Зарегистрирован: 19.04.2017

Создай тему, я объясню как на ESP запустить демонстрацию фотографий без флешки. 

Nikolaha53rus
Offline
Зарегистрирован: 17.04.2016
vektorss
vektorss аватар
Offline
Зарегистрирован: 15.10.2019

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

EvgenDRV
Offline
Зарегистрирован: 11.09.2011

Доброго времени суток. Третий раз заказываю TFT 0.96 80x160 использую библиотеку Adafruit_ST7735_and_ST7789_Library и каждый раз что-то новое. Смещение на два пикселя победил благодаря вам. Потом дисплеи пришли в зеркальном отображении, тоже победил. Третий раз пришли вообще с головоломкой, тупо смещено в лево на 1/4. Даже если в библиотеке смещаю (для примера на 50 вправо и вверх) полоса черная всё равно остаётся. Перерыл весь интернет, неужели никто не сталкивался с такой проблемой. Спасибо

 

5ta550n
Offline
Зарегистрирован: 26.08.2021

#define RST 9
#define DC 8
#define CS 10

word col;
byte pos,dir=1;
byte g,a,x,y;
byte MRST,MCS,MDC,*PRST,*PCS,*PDC;
void setup(){
//spi
pinMode(6,OUTPUT);analogWrite(6,4);
TFTInit();

}

void loop(){
pos+=dir;
if(pos>39)dir=-1;
if(pos<1)dir=1;
col=rand()*2;
area(0+pos,0,119+pos,79);
*PDC|=MDC;
*PCS &=~ MCS;
for(word i=0;i<0x2580;i++){
pixel16(col);
}
*PCS |= MCS;

//delay(50);
}
void area(byte x1,byte y1,byte x2,byte y2){
writecommand(0x2A);writedata(0);writedata(x1);writedata(0);writedata(x2);
writecommand(0x2B);writedata(0);writedata(y1+24);writedata(0);writedata(y2+24);
writecommand(0x2C);
}
void pixel16(uint16_t col){SPDR=col>>8;while(!(SPSR & (1< void pixel565(uint8_t r, uint8_t g, uint8_t b){SPDR=(r&0xF8)|((g & 0xFC)>>5);while(!(SPSR & (1<>3);while(!(SPSR & (1< void writedata(uint8_t c){*PDC|=MDC;spiwrite(c);}
void writecommand(uint8_t c){*PDC&=~MDC;spiwrite(c);}
void spiwrite(uint8_t c){*PCS &=~MCS;SPDR=c;while(!(SPSR & (1< void TFTInit(){
PRST = portOutputRegister(digitalPinToPort(RST));
PCS = portOutputRegister(digitalPinToPort(CS));
PDC = portOutputRegister(digitalPinToPort(DC));
MRST = digitalPinToBitMask(RST);
MDC = digitalPinToBitMask(DC);
MCS = digitalPinToBitMask(CS);
*(portModeRegister(digitalPinToPort(RST)))|=MRST;
*(portModeRegister(digitalPinToPort(CS)))|=MCS;
*(portModeRegister(digitalPinToPort(DC)))|=MDC;
*(portModeRegister(digitalPinToPort(MOSI)))|=digitalPinToBitMask(MOSI);
*(portModeRegister(digitalPinToPort(SCK)))|=digitalPinToBitMask(SCK);
SPSR = 1;SPCR = 80;
*PCS&=~MCS;
*PRST|= MRST;delay(4);
writecommand(0x11);// после сброса дисплей спит - даем команду проснуться
writecommand(0xfe); //
writecommand(0xef); // | Переключаем разрешение
writecommand(0xb6);writedata(0x11); // | экрана 80x160
writecommand(0xac);writedata(0x0b); ///
writecommand(0x3A);writedata(0x05);// режим цвета:16 бит
writecommand(0x36); // направление вывода изображения:
// X Y X-Y Vrfrsh rgbbgr hrfrsh
writedata((0<<7)|(1<<6)|(1<<5)|(0<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0)); // снизу вверх, справа на лево, порядок цветов RGB
// writecommand(0x2B);writedata(0);writedata(0);writedata(0);writedata(159);
// writecommand(0x2A);writedata(0);writedata(24);writedata(0);writedata(79+24);
writecommand(0x29);// включаем изображение
writecommand(0x2C);
}

5ta550n
Offline
Зарегистрирован: 26.08.2021

мне пришел такой же обрезаный, я даташит изучил вдоль и поперек, там написано по GM0 и GM1, что от них зависит разрешение, но как их поменять нигде нет. были мысли что есть недокументированные команды, я даже написал скетч который сыплет случайными командами(за исключением некоторых типа софтресета и выкл) с рандомными параметрами -- за час чуда не произошло, я уж признаться решил что партия бракованая. Решение подсказал продавец, скинул скетч из которого я и выудил нужную мантру: две команды без параметров 0xfe, 0xef потом две команды с параметрами по одному на каждую 0xb6 c параметром 0x11, 0xac с параметром 0x0b и о чудо - весь экран заработал

almarona
Offline
Зарегистрирован: 28.09.2021

EvgenDRV пишет:

Доброго времени суток. Третий раз заказываю TFT 0.96 80x160 использую библиотеку Adafruit_ST7735_and_ST7789_Library и каждый раз что-то новое. Смещение на два пикселя победил благодаря вам. Потом дисплеи пришли в зеркальном отображении, тоже победил. Третий раз пришли вообще с головоломкой, тупо смещено в лево на 1/4. Даже если в библиотеке смещаю (для примера на 50 вправо и вверх) полоса черная всё равно остаётся. Перерыл весь интернет, неужели никто не сталкивался с такой проблемой. Спасибо

 

Приветствую вас . Не подскажете как победили зеркальное отображение.?

almarona
Offline
Зарегистрирован: 28.09.2021

Приветствую вас . Не подскажете как победили зеркальное отображение ? у меня экран 0.96 "80x160(RGB)IPS

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

almarona пишет:

Приветствую вас . Не подскажете как победили зеркальное отображение ? у меня экран 0.96 "80x160(RGB)IPS

Обращением координаты

например. чтобы обратить изображение по горизонтали - вместо координаты Х пишем в координату 80 -Х

almarona
Offline
Зарегистрирован: 28.09.2021

Спасибо !  изменить в скейтче или в библиотеке?

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

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

almarona
Offline
Зарегистрирован: 28.09.2021

Спасибо разобрался .

almarona
Offline
Зарегистрирован: 28.09.2021

 

 


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

простите вы правда настолько наивны,или считаете других идиоами?

Кто будет копаться в двух простынях кода по 1000 строк забесплатно?

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

Напиши в Adafruit, мошт, у них сёдня день благотворительности.