mcufriend shield 0x4535 слабая яркость
- Войдите на сайт для отправки комментариев
Сб, 27/08/2016 - 01:30
Здравствуйте, прошу помощи. Приехал ко мне китайский дисплей+тач шилд, воткнул его в ардуину, склепал скетч фоторамки, работает - но картинки выводятся с очень низкой яркостью (гаммой?). Но если нажать ресет, то в течение следующей секунды бесхозный дисплей без мастера отображает эту картинку с нормальной яркостью. Есть подозрение, что такое поведение у дисплея из-за подключенной sd-карты, пока скетч побайтово читает картинку с неё, экран сильно мерцает. Подскажите плиз, что делать, куда копать?
#include <Adafruit_GFX.h> // Core graphics library #include <AdaLGDP4535TFTLCD.h> // Hardware-specific library #include <TrueRandom.h> #include "SdFat.h" SdFat SD; #define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin #define LCD_CS A3 // Chip Select goes to Analog 3 #define LCD_CD A2 // Command/Data goes to Analog 2 #define LCD_WR A1 // LCD Write goes to Analog 1 #define LCD_RD A0 // LCD Read goes to Analog 0 #define SD_CS 10 // Card select for shield use Adafruit_TFTLCD tft( LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET ); uint8_t spi_save; File root; void setup() { Serial.begin(9600); tft.reset(); tft.begin( tft.readID() ); tft.setRotation(3); Serial.print(F("Initializing SD card...")); if (!SD.begin( SD_CS )) { Serial.println(F("failed!")); return; } Serial.println(F("OK!")); spi_save = SPCR; } void loop() { String bitmap = (String) TrueRandom.random( 2400 ) + ".bmp"; tft.fillScreen(0); bmpDraw( string2char( bitmap ), 0, 0 ); delay(5000); } char* string2char( String command ) { if (command.length() != 0) { char *p = const_cast<char*>(command.c_str()); return p; } } // This function opens a Windows Bitmap (BMP) file and // displays it at the given coordinates. It's sped up // by reading many pixels worth of data at a time // (rather than pixel by pixel). Increasing the buffer // size takes more of the Arduino's precious RAM but // makes loading a little faster. 20 pixels seems a // good balance. #define BUFFPIXEL 20 void bmpDraw(char *filename, int x, int 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 in buffer (R+G+B per pixel) uint16_t lcdbuffer[BUFFPIXEL]; // pixel out buffer (16-bit 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(); uint8_t lcdidx = 0; boolean first = true; if ((x >= tft.width()) || (y >= tft.height())) return; Serial.println(); Serial.print( F("Loading image '") ); Serial.print(filename); Serial.println('\''); // Open requested file on SD card SPCR = spi_save; if ((bmpFile = SD.open(filename, O_READ)) == NULL) { Serial.print("File not found"); return; } // Parse BMP header if (sdcard_read16(bmpFile) == 0x4D42) { // BMP signature Serial.print(F("File size: ")); Serial.println(sdcard_read32(bmpFile)); (void)sdcard_read32(bmpFile); // Read & ignore creator bytes bmpImageoffset = sdcard_read32(bmpFile); // Start of image data Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC); // Read DIB header Serial.print(F("Header size: ")); Serial.println(sdcard_read32(bmpFile)); bmpWidth = sdcard_read32(bmpFile); bmpHeight = sdcard_read32(bmpFile); if (sdcard_read16(bmpFile) == 1) { // # planes -- must be '1' bmpDepth = sdcard_read16(bmpFile); // bits per pixel Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth); if ((bmpDepth == 24) && (sdcard_read32(bmpFile) == 0)) { // 0 = uncompressed goodBmp = true; // Supported BMP format -- proceed! Serial.print(F("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 SPCR = 0; 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; SPCR = spi_save; if (bmpFile.position() != pos) { // Need seek? bmpFile.seek(pos); buffidx = sizeof(sdbuffer); // Force buffer reload } for (col = 0; col < w; col++) { // For each column... // Time to read more pixel data? if (buffidx >= sizeof(sdbuffer)) { // Indeed // Push LCD buffer to the display first if (lcdidx > 0) { SPCR = 0; tft.pushColors(lcdbuffer, lcdidx, first); lcdidx = 0; first = false; } SPCR = spi_save; bmpFile.read(sdbuffer, sizeof(sdbuffer)); buffidx = 0; // Set index to beginning } // Convert pixel from BMP to TFT format b = sdbuffer[buffidx++]; g = sdbuffer[buffidx++]; r = sdbuffer[buffidx++]; lcdbuffer[lcdidx++] = tft.color565(r, g, b); } // end pixel } // end scanline // Write any remaining data to LCD if (lcdidx > 0) { SPCR = 0; tft.pushColors(lcdbuffer, lcdidx, first); } Serial.print(F("Loaded in ")); Serial.print(millis() - startTime); Serial.println(" ms"); } // end goodBmp } } bmpFile.close(); if (!goodBmp) Serial.println("BMP format not recognized."); } // sdfat.h fix uint16_t sdcard_read16(File &f) { uint16_t result; ((uint8_t *)&result)[0] = f.read(); // LSB ((uint8_t *)&result)[1] = f.read(); // MSB return result; } // sdfat.h fix uint32_t sdcard_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; }
Adafruit_GFX - помоему там есть контрастности регулировка.. по крайней мере на OLED дисплеях работает. И непонятно низкая гамма/констрастность или низкая яркость подсветки??
дисплей может мерцать при нехватке тока, или плохой контакт земли или vcc
Очень сложно сфотографировать телефоном экран, да ещё и чтобы показать яркость, но я попробовал:
"слабая яркость" - все цвета блеклые, тёмные, картинка плохо просматривается даже вблизи и с включенным светом, с расстояния в пол-метра - метр уже не разобрать, что же там нарисовано:
но после нажатия ресета - (пока сам дисплей и microsd карта неинициализирована?), картинку на дисплее видно ярко, ясно и чётко, так же, как на большом брате, цвета яркие, сочные, видно орлиным глазом метров за несколько:
На глазок этот эффект больше похож на пониженный уровень гамма-коррекции. Диоды подсветки видно с боков экрана, их яркость, вроде как, при моих манипуляциях не изменяется. Питание переключал, пробовал и от usb, и от БП на 9В/1А, и оба вместе - на ситуацию это не повлияло.
UPD: про мерцание при выводе bmp - думаю, что шилд всё же воткнут крепко - потому что оно как бы на самом деле не мерцание, а просто глазом отмечается, как быстрое дрожание эдаких бегущих полосок, видимо глаз таким образом отмечает задержки между чтением буфера с карты и отправкой его на дисплей.
последняя версия библиотеки, попробуйте
https://github.com/prenticedavid/MCUFRIEND_kbv
Пробовал, белый экран, не дружит она с китайским поделием на 4535 :(
Если прервать крутящийся демо скетч от mcufriend заливкой моего, то после ресета на дисплее на миг видно нарисованные демкой прямоугольники, то есть внизу, "под белым экраном" оно всё-таки как-то работает и в память дисплея пересылает байтики правильно.
Мучения продолжаются, пока удалось в инициализации выставить все резисторы для гамма-коррекции в 0 Ом, стало чуть поярче, но все ещё далеко от идеала, который виден из видеопамяти после нажатия ресета.
Мучения продолжаются, пока удалось в инициализации выставить все резисторы для гамма-коррекции в 0 Ом, стало чуть поярче, но все ещё далеко от идеала, который виден из видеопамяти после нажатия ресета.
(1) попробуйте просто закоментить регистры гаммы, пусть будут значения по умолчанию в контроллере после сброса.
Для минимального инита вообще хватает 3-4 команды в нем , (2) попробуйте путем коментирования исключать один регистр за другим, оставить самые необходимые.
http://arduino.ru/forum/apparatnye-voprosy/arduino-i-displei-ot-sotikov-mobilnykh-telefonov?page=1#comment-175988
Вообще похоже что инит не соответствует контроллеру, (4) попробуйте считать тип контроллера, в примерах адафруита он посылает его в сериал порт,
Есть ещё одно предположение, это изменение уровня питания диспа (5) проверте мультиметром в обоих случаях. Мож использование карты , а она же включена в дешевых шилдах напрямую, логические уровни 5в с ардуины поднимают через нее питалово 3,3в ( т.к. microSD и дисп запитаны от одного стаба 3,3в. ) А от повышенного питалова , внутренние преобразователи на кристалле на стекле, начинают выше кочегарить разновеликие доплнительные напряжения для матрицы, из-за этого и бывает изменение яркости и контраста. Правда подключенная подсветка напрямую к стабу немного нагружает его, но надо бы проветь, мало ли с 3,3в он поднимается до 3,6в или нежелательно ещё выше.
// при полном ините, в регистры изменяются параметры по умолчанию, по подведенному питанию - для 3,3в надо одни значения , для 2,8в - другие, при максимально-критическом 3,6в - третьи.
slider спасибо, программные советы с утра уже успел поперебирать :( . Первым делом (4) считал примером lcd_id_readreg, оттуда получил 0х4535 и все остальные регистры по нулям, в тексте mcufriend нет поддержки этого контроллера. Нашёл даташит на LG4535, (3) инит в используемой библиотеке оказался полностью скопирован из даташита. Комментировал (1) регистры гаммы, пробовал (2) комментировать другие регистры - все безрезультатно, яркость по-прежнему остаётся слабой. Пробовал отправлять ардуину в сон после отрисовки, пробуждался обратно по таймеру - но и во сне яркость та же. Найти минимальный инит вот ещё только не пробовал. Боюсь, как бы не (5) - а при ресете microSD [отваливается/засыпает/ещё что-нибудь] и яркость на секунду становится максимальной.
Вот сдесь посмотрите http://ceezblog.info/2015/04/20/240x320-28-tft-shield-driver-4535-for-ar...
Выдалось ещё немного времени покопаться с этим дисплей шилдом.
Последнюю библиотеку смотрел, да тачскрин-то работает, и инит в этой библиотеке такой же. Вынул microSD, вывел битмап с компа через сериал - яркость всё та же, низкая. Если с выведенной картинкой зажать и держать ресет, тем самым отрубив ардуину - высокая. Нашел на форуме arduino.cc несколько постов, люди пишут про ту же проблему, шилды у них подобные, но на других чипах, так что, по ходу, такой уж мне достался дисплей с али - самому рисовать примитивы ещё приемлемо, а для фоторамки слишком тёмный => видимо, расходимся, всем спасибо за внимание.