st7735 160 на 128 подсветка барахлит
- Войдите на сайт для отправки комментариев
Втр, 09/08/2022 - 19:39
Пришла пара дисплеев таких
С подключением разобрался, скетчи примеров работают, с подсветкой не ясно. При включении внешнего резистора 220 ом экран один тускло, другой никак не горит. Вывод информации сопровождается мерцанием и сбоями картинки у первого. Если включать без резистора всё светит ярко и чётко. Устойчиво, почти, работает при 27 омах. Очень хорошо при питании от аккумулятора всё работает. Почему так происходит? В цепях выводов информационных стоят резисторы по 1,5 кОм. Нахрена они надо?(все ставят зачем то)
:)
Как грамотно управлять светодиодом, или может просто выбраковку прислали?
#include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific library #include <SPI.h> // For the breakout, you can use any 2 or 3 pins // These pins will also work for the 1.8" TFT shield #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 0! #define TFT_DC 8 // 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); float p = 3.1415926; void setup(void) { Serial.begin(9600); Serial.print("Hello! ST7735 TFT Test"); // Use this initializer if you're using a 1.8" TFT tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab // Use this initializer (uncomment) if you're using a 1.44" TFT // tft.initR(INITR_144GREENTAB); // initialize a ST7735S chip, black tab Serial.println("Initialized"); uint16_t time = millis(); tft.fillScreen(ST7735_BLACK); time = millis() - time; Serial.println(time, DEC); delay(500); // large block of text tft.fillScreen(ST7735_BLACK); testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST7735_WHITE); delay(1000); // tft print function! tftPrintTest(); delay(4000); // a single pixel tft.drawPixel(tft.width()/2, tft.height()/2, ST7735_GREEN); delay(500); // line draw test testlines(ST7735_YELLOW); delay(500); // optimized lines testfastlines(ST7735_RED, ST7735_BLUE); delay(500); testdrawrects(ST7735_GREEN); delay(500); testfillrects(ST7735_YELLOW, ST7735_MAGENTA); delay(500); tft.fillScreen(ST7735_BLACK); testfillcircles(10, ST7735_BLUE); testdrawcircles(10, ST7735_WHITE); delay(500); testroundrects(); delay(500); testtriangles(); delay(500); mediabuttons(); delay(500); Serial.println("done"); delay(1000); } void loop() { tft.invertDisplay(true); delay(500); tft.invertDisplay(false); delay(500); } void testlines(uint16_t color) { tft.fillScreen(ST7735_BLACK); for (int16_t x=0; x < tft.width(); x+=6) { tft.drawLine(0, 0, x, tft.height()-1, color); } for (int16_t y=0; y < tft.height(); y+=6) { tft.drawLine(0, 0, tft.width()-1, y, color); } tft.fillScreen(ST7735_BLACK); for (int16_t x=0; x < tft.width(); x+=6) { tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color); } for (int16_t y=0; y < tft.height(); y+=6) { tft.drawLine(tft.width()-1, 0, 0, y, color); } tft.fillScreen(ST7735_BLACK); for (int16_t x=0; x < tft.width(); x+=6) { tft.drawLine(0, tft.height()-1, x, 0, color); } for (int16_t y=0; y < tft.height(); y+=6) { tft.drawLine(0, tft.height()-1, tft.width()-1, y, color); } tft.fillScreen(ST7735_BLACK); for (int16_t x=0; x < tft.width(); x+=6) { tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color); } for (int16_t y=0; y < tft.height(); y+=6) { tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color); } } void testdrawtext(char *text, uint16_t color) { tft.setCursor(0, 0); tft.setTextColor(color); tft.setTextWrap(true); tft.print(text); } void testfastlines(uint16_t color1, uint16_t color2) { tft.fillScreen(ST7735_BLACK); for (int16_t y=0; y < tft.height(); y+=5) { tft.drawFastHLine(0, y, tft.width(), color1); } for (int16_t x=0; x < tft.width(); x+=5) { tft.drawFastVLine(x, 0, tft.height(), color2); } } void testdrawrects(uint16_t color) { tft.fillScreen(ST7735_BLACK); for (int16_t x=0; x < tft.width(); x+=6) { tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color); } } void testfillrects(uint16_t color1, uint16_t color2) { tft.fillScreen(ST7735_BLACK); for (int16_t x=tft.width()-1; x > 6; x-=6) { tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1); tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2); } } void testfillcircles(uint8_t radius, uint16_t color) { for (int16_t x=radius; x < tft.width(); x+=radius*2) { for (int16_t y=radius; y < tft.height(); y+=radius*2) { tft.fillCircle(x, y, radius, color); } } } void testdrawcircles(uint8_t radius, uint16_t color) { for (int16_t x=0; x < tft.width()+radius; x+=radius*2) { for (int16_t y=0; y < tft.height()+radius; y+=radius*2) { tft.drawCircle(x, y, radius, color); } } } void testtriangles() { tft.fillScreen(ST7735_BLACK); int color = 0xF800; int t; int w = tft.width()/2; int x = tft.height()-1; int y = 0; int z = tft.width(); for(t = 0 ; t <= 15; t++) { tft.drawTriangle(w, y, y, x, z, x, color); x-=4; y+=4; z-=4; color+=100; } } void testroundrects() { tft.fillScreen(ST7735_BLACK); int color = 100; int i; int t; for(t = 0 ; t <= 4; t+=1) { int x = 0; int y = 0; int w = tft.width()-2; int h = tft.height()-2; for(i = 0 ; i <= 16; i+=1) { tft.drawRoundRect(x, y, w, h, 5, color); x+=2; y+=3; w-=4; h-=6; color+=1100; } color+=100; } } void tftPrintTest() { tft.setTextWrap(false); tft.fillScreen(ST7735_BLACK); tft.setCursor(0, 30); tft.setTextColor(ST7735_RED); tft.setTextSize(1); tft.println("Hello World!"); tft.setTextColor(ST7735_YELLOW); tft.setTextSize(2); tft.println("Hello World!"); tft.setTextColor(ST7735_GREEN); tft.setTextSize(3); tft.println("Hello World!"); tft.setTextColor(ST7735_BLUE); tft.setTextSize(4); tft.print(1234.567); delay(1500); tft.setCursor(0, 0); tft.fillScreen(ST7735_BLACK); tft.setTextColor(ST7735_WHITE); tft.setTextSize(0); tft.println("Hello World!"); tft.setTextSize(1); tft.setTextColor(ST7735_GREEN); tft.print(p, 6); tft.println(" Want pi?"); tft.println(" "); tft.print(8675309, HEX); // print 8,675,309 out in HEX! tft.println(" Print HEX!"); tft.println(" "); tft.setTextColor(ST7735_WHITE); tft.println("Sketch has been"); tft.println("running for: "); tft.setTextColor(ST7735_MAGENTA); tft.print(millis() / 1000); tft.setTextColor(ST7735_WHITE); tft.print(" seconds."); } void mediabuttons() { // play tft.fillScreen(ST7735_BLACK); tft.fillRoundRect(25, 10, 78, 60, 8, ST7735_WHITE); tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_RED); delay(500); // pause tft.fillRoundRect(25, 90, 78, 60, 8, ST7735_WHITE); tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_GREEN); tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_GREEN); delay(500); // play color tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_BLUE); delay(50); // pause color tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_RED); tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_RED); // play color tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_GREEN); }
/* Arduino TFT text example This example demonstrates how to draw text on the TFT with an Arduino. The Arduino reads the value of an analog sensor attached to pin A0, and writes the value to the LCD screen, updating every quarter second. This example code is in the public domain Created 15 April 2013 by Scott Fitzgerald http://www.arduino.cc/en/Tutorial/TFTDisplayText */ #include <TFT.h> // Arduino LCD library #include <SPI.h> // pin definition for the Uno #define cs 10 #define dc 8 #define rst 9 // pin definition for the Leonardo // #define cs 7 // #define dc 0 // #define rst 1 // create an instance of the library TFT TFTscreen = TFT(cs, dc, rst); // char array to print to the screen char sensorPrintout[5]; void setup() { // Put this line at the beginning of every sketch that uses the GLCD: TFTscreen.begin(); // clear the screen with a black background TFTscreen.background(0, 0, 0); // write the static text to the screen // set the font color to white TFTscreen.stroke(255, 255, 255); // set the font size TFTscreen.setTextSize(2); // write the text to the top left corner of the screen TFTscreen.text("Sensor Value :\n ", 0, 0); // ste the font size very large for the loop TFTscreen.setTextSize(5); } void loop() { // Read the value of the sensor on A0 String sensorVal = String(analogRead(A0)); // convert the reading to a char array sensorVal.toCharArray(sensorPrintout, 5); // set the font color TFTscreen.stroke(255, 255, 255); // print the sensor value TFTscreen.text(sensorPrintout, 0, 20); // wait for a moment delay(250); // erase the text you just wrote TFTscreen.stroke(0, 0, 0); TFTscreen.text(sensorPrintout, 0, 20); }
Неясно почему верхние схемы преобладают над нижними?
1. 220 Ом для подсветки, очевидно, слишком много. Разумный диапазон 10-47 Ом.
2. Я так и не смог установить соответствия между распиновкой в нулевом сообщении и схемами в первом.
3. Самое главное, непонятно, куда именно Вы включаете резистор - ни на одной схеме его нет. Судя по тому, что нарушается работа дисплея, Вы ставите его неправильно.
4. Резисторы в цепях управления, очевидно, связаны с тем, что дисплей 3.3-вольтовый.
*. Вспомнил, что 47 Ом - это я ставил на монохромный дисплей. Для цветного, очевидно, ток должен быть втрое выше, т.е. номинал вряд ли должен превышать 20 Ом.
andriano диод подсветки один, так что номинал резистора +- одинаковый для цветного и монохромного.
ТС ШИМ подайте туда и регулируйте яркость как хотите.
andriano диод подсветки один, так что номинал резистора +- одинаковый для цветного и монохромного.
ТС ШИМ подайте туда и регулируйте яркость как хотите.
Убедительно.
2. Я так и не смог установить соответствия между распиновкой в нулевом сообщении и схемами в первом.
4. Резисторы в цепях управления, очевидно, связаны с тем, что дисплей 3.3-вольтовый.
Вот так заработал на тест-скетче нормально. Зачем тогда стабилизатор ему на плате? Почему токаограничительный резистор только 3,3 Ома? Подсветка жрёт 29 мА, сам дисплей около 0,1 мА. Зачем резисторы в схеме?, если токаограничительные почему малый номинал, не 100 кОм, а порядка одного. Если ограничивают напряжение, где делители? Как уменьшить число соединений?
Как всегда одни вопросы. А дисплей очень такой доступный, всего 130 рублей.
Зачем тогда стабилизатор ему на плате?
Почему токаограничительный резистор только 3,3 Ома?
Зачем резисторы в схеме?
Как всегда одни вопросы.
я тут намедни протупил. без резисторов включил (использовал для ESP ранее), так что теперь - был у меня один дисплей )))
ЗЫ первые потери да 6 лет...
Если экран чик один можно так сократить резисторы. Удивительно, но такой вариант схемы работает надёжно. Замерял авометром электронным, на резисторе к SDA падает 0,8-0,9В при питании от 5 В и всего 0,06 при питании от аккума (3,8В). Как то я в смущении от их пользы, но убирать не стану :)
Ну в целом ни так и не сяк. Отрисовка медленней чем на SSD1306. Но цвета красивые. Как узоры будут смотреться неизвестно.
Офф: lilik, не в службу, скинь ссылку на свою тему, где ты шары на адресных светодиодах делал ))
https://arduino.ru/forum/proekty/zalivaem-shary-k-prazdniku
Спасибо))
Отрисовка медленней чем на SSD1306.
А скорость передачи ?
И там, и там передача последовательная. Так что даже 4 Мбит/с SPI против 400 кбит/ I2C не могут изменить соотношение на обратное.
И, кстати, 1306 вполне способен работать по I2C на 2 Мбит/с. Да и с интерфейсом SPI они бывают. Так что в принципе возможности разгона у 1306 выше.
Да, в целом не шустро, но если смотреть в прищур, то даже пламя похоже на пламя.
lilik, Сколько памяти кушают скетчи?
lilik, Сколько памяти кушают скетчи?
Секундомер 38% памяти и 6% динамической, узоры 25 и 5 соответственно.
Спасибо.
Это у 328й?
Да.
lilik, Сколько памяти кушают скетчи?
Секундомер 38% памяти и 6% динамической, узоры 25 и 5 соответственно.
а можешь код секундомера выложить?
Секундомер.
С ч\б картинками разобрался, осталось научится их раскрашивать в разные цвета, имея одноцветный массив. Наверное из библиотеки функцию изымать и выдумывать зависимости цвета от счётчиков пикселей - i, j :)
секундомера стрелку (некстати) сделал накладывающейся - как настоящая.
Код секундомера для RP2040, русских шрифтов нет, увы...
А почему такая медленная перерисовка?
А почему такая медленная перерисовка?
пока не знаю, скорость на SPI выставлена по максимуму
Код секундомера для RP2040, русских шрифтов нет, увы...
А картинка?
Я по ходу забыл, в файлы библиотеки "...GFX" надо добавить
glcdfont.c файл называется.
Новая версия, ещё более тормознутая отрисовка стрелки.
А почему такая медленная перерисовка?
пока не знаю, скорость на SPI выставлена по максимуму
Давай считать: Для одного пикселя нужно записать 16 бит, что при 4МГц будет 4 мкс, что соответствует 64 тактам при 16 МГц. Ну еще преобразование 1 бита 16 - это 8-10 инструкций, пусть будет еще 16 тактов. Итого 80 тактов или 5 мкс.
На экране 160*128=20к пикселей, по 5 мкс на каждый - 100 мс. Т.е. должно быть порядка 10 fps. Мы видим явно меньше, вопрос - почему?
andriano он же через библиотеку выводит ... - дели скорость на 100 :-)
Не 10 кадров в секунду, а 10 секунда на кадр ...
andriano он же через библиотеку выводит ... - дели скорость на 100 :-)
Не 10 кадров в секунду, а 10 секунда на кадр ...
Вот поэтому я никогда и не пользуюсь стандартными библиотеками для экрана, а предпочитаю писать сам.
lilik, покажи тот фрагмент, который выводит на экран первый рисунок из сообщения №25.
lilik На какой частоте работает плата ? Если на 16, то fosc/2 - это 8, а не 4 ...
Жаль что нет буфера как на UART - ожидание окончания вывода даёт паузы между байтами ...
Спасибо! Вторая половина кодовой таблицы с выбором языка оказывается только ручками )))
Что-то я на этом тормознулся, хотя с DOS был жеж более чем в теме... Осень...
Да, я добавил в ваш код установку скорости SPI, отрабатывает ли должным образом
надо разбираться, но если ставить скорость 60000000 то дисплей не АЛЛЁ )))
lilik, покажи тот фрагмент, который выводит на экран первый рисунок из сообщения №25.
Да, я добавил в ваш код установку скорости SPI, отрабатывает ли должным образом...
Скетч не компилируется.
lilik На какой частоте работает плата ? Если на 16, то fosc/2 - это 8, а не 4 ...
Жаль что нет буфера как на UART - ожидание окончания вывода даёт паузы между байтами ...
Плата UNO китайская с CH340.
50 МГц ??? У вас Uno, а не RP2040 !!!
50 МГц ??? У вас Uno, а не RP2040 !!!
Да!, но не компилируется не из-за чисел :)
Вот так компилируется и работает, но число 16000000 (и любые другие) ни на что не влияют.
lilik, покажи тот фрагмент, который выводит на экран первый рисунок из сообщения №25.
Ну а раз так - сообщения №32-33.
На UNO 16 МНц частота SPI не может быть выше 8 МНц
SPI.setClockDivider(SPI_CLOCK_DIV2);
Ну и кроме того, по моим наблюдениям, 8МГц на AVR практически не отличается от 4МГц.
Да и вообще, с реализацией SPI на Arduino нужно как следует разбираться: если для AVR я установил лишь факт, описанный выше (т.е. относительное значение), то для stm32 получил абсолютное: на практике скорость передачи 1/7 от теоретического значения.
Ну и кроме того, по моим наблюдениям, 8МГц на AVR практически не отличается от 4МГц.
Да и вообще, с реализацией SPI на Arduino нужно как следует разбираться: если для AVR я установил лишь факт, описанный выше (т.е. относительное значение), то для stm32 получил абсолютное: на практике скорость передачи 1/7 от теоретического значения.
а как померить реальную скорость?
Есть такая функция - millis().
Ну и, кроме того, у "железячников" должен быть осциллограф (или логический анализатор).
На UNO 16 МНц частота SPI не может быть выше 8 МНц
SPI.setClockDivider(SPI_CLOCK_DIV2);
Подставил в скетч, так же медленно как и было. Мне вот что интересно - все функции рисования картинок приводят к функции рисования одной точки. Сегодня мне интересно из одноцветной картинки делать разноцветную. Вот пример трансформации библиотечной функции в самописную.
Она переделывает одну картинку в другую.
Может дело в попиксельном выводе данных?
пока вы не переделаете вывод пикселей картинки напрямую дисплею в память, скорости нормальной не получите.
Да, выводить попиксельно - это неправильно.
В контроллерах цветных дисплеев (во всех, с которыми мне приходилось работать) специально для увеличения скорости вывода пикселей используется функция, задающая прямоугольник, в который осуществляется вывод. Например, для вывода символа в знакоместо 10*16 задается прямоугольная область такого размера, а потом просто поочередно передаются цвета точек, которые последовательно заполняют эту область.
Т.е. на вывод 160 точек в примере выше мы сначала задаем команду 6-16 байт, а потом цвета всех 160 точек, т.е. еще 320 байт. Т.е. из примерно 330 байт 320 передают информацию о цвете точек.
При попиксельном выводе все то же самое, только на 3-16 байт служебной информации (задающей координаты точки) приходится только 2 байта на цвет (единственной точки).
В случае картинки и невозможности уместить ее в памяти целиком, целесообразно выводить построчно: т.е. задали строку 128*1 пискель, посчитали в буфер (256 байт) и вывели на экран. Потом - следующую.
пока вы не переделаете вывод пикселей картинки напрямую дисплею в память, скорости нормальной не получите.
В примерах, что я опытничаю, внутри библиотек две функции рисования точки. Какая работает мне не ясно.
Кстати такой блок нашёл, он на скорость влиет?
пока вы не переделаете вывод пикселей картинки напрямую дисплею в память, скорости нормальной не получите.
В примерах, что я опытничаю, внутри библиотек две функции рисования точки. Какая работает мне не ясно.
ну вот же она, задается координаты вывода, как выше писали. Формируете буфер данных для вывода, и по SPI шлете все это дисплею.
вот из проекта для ili9341, суть та же. (только это для STM + DMA)