Помогите рабочим примером скетча вывода картинки на TFT ili9486

Roman2344
Offline
Зарегистрирован: 09.09.2015

Вообщем то есть ТФТ дисплей 4 дюйма на ili9486 + ардуино мега2560, дисплей с разьёмом micro CD управление пин 53. Примеры с нета либо не работают, либо не компилируются в ардуино ИДЕ ошибки разные, удалось мне вывести картинку но с маленьким разрешениемгде - то 50*30. С памяти проца выводится но тоже ж приходится маленькое разрешение делать, а потом масштабировать, но оно ж такое размытое получается, хотелось бы вывести картинку разрешением где - то 290*200 в нормальном разрешении с микро СД. Но не могу нормальный рабочий пример найти. Помогите пожалуйста.

Roman2344
Offline
Зарегистрирован: 09.09.2015

Кроме картинки вывожу текст, и прямоугольники использую библиотеку UTFT

Roman2344
Offline
Зарегистрирован: 09.09.2015

Взял с нета и переделал, но не идёт компилирование в ардуино ИДЕ


#define DEBUG
#include <UTFT.h>
#include <SPI.h>
#include <SD.h>

#define SD_CS 53


#define SD_SCK 13
#define SD_MISO 12
#define SD_MOSI 11


UTFT myGLCD(ILI9486,38,39,40,41);

void setup()
{

 myGLCD.InitLCD();// инициализация LCD 
myGLCD.clrScr();// очистка дисплея

  myGLCD.setFont(BigFont);// включаем большой шрифт
myGLCD.setColor(VGA_RED);
  myGLCD.print(F("Initializing SD card..."));
  #if defined __AVR_ATmega2560__
  if (!SD.begin(SD_CS, SD_MOSI, SD_MISO, SD_SCK )) {
        myGLCD.setFont(BigFont);// включаем большой шрифт
myGLCD.setColor(VGA_RED);

    myGLCD.print(F("failed!"));
    return;
  }
  #else
  if (!SD.begin(SD_CS)) {
        myGLCD.setFont(BigFont);// включаем большой шрифт
myGLCD.setColor(VGA_RED);

   myGLCD.print(F("failed!"));
    return;
  }
  #endif
  delay(500);


}

void loop()
{ 
     
#ifndef DEBUG
  for(int i = 0; i<4; i++) {
    delay(1000);
    utft.setRotation(i);
    utft.fillScreen(0);
    for(int j=0; j <= 200; j += 50) {
      bmpDraw("miniardu.bmp", j, j);
    }

  }
#endif
}


#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 >= utft.width()) || (y >= utft.height())) return;

#ifdef DEBUG
fillScreen(0);
#endif
  // Open requested file on SD card
  if ((bmpFile = SD.open(filename)) == NULL) {
    #ifdef DEBUG
        myGLCD.setFont(BigFont);// включаем большой шрифт
myGLCD.setColor(VGA_RED);

    myGLCD.print(F("File not found"));
    #endif
    return;
  }

  // Parse BMP header
  if(read16(bmpFile) == 0x4D42) {
      // BMP signature
    #ifdef DEBUG
       myGLCD.setFont(BigFont);// включаем большой шрифт
myGLCD.setColor(VGA_RED);

   myGLCD.print(F("File size: ")); myGLCD.print(read32(bmpFile));
    #else
        read32(bmpFile);
    #endif
    (void)read32(bmpFile); // Read & ignore creator bytes
    bmpImageoffset = read32(bmpFile); // Start of image data
    #ifdef DEBUG]
       myGLCD.setFont(BigFont);// включаем большой шрифт
myGLCD.setColor(VGA_RED);

   myGLCD.print(F("Image Offset: ")); myGLCD.print(bmpImageoffset, DEC);
    // Read DIB header
       myGLCD.setFont(BigFont);// включаем большой шрифт
myGLCD.setColor(VGA_RED);

    myGLCD.print(F("Header size: ")); myGLCD.print(read32(bmpFile));
    #else
    read32(bmpFile);
    #endif

    bmpWidth  = read32(bmpFile);
    bmpHeight = read32(bmpFile);
    if(read16(bmpFile) == 1) { // # planes -- must be '1'
      bmpDepth = read16(bmpFile); // bits per pixel
      #ifdef DEBUG
      Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
      #endif
      if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed

        goodBmp = true; // Supported BMP format -- proceed!
        #ifdef DEBUG
           myGLCD.setFont(BigFont);// включаем большой шрифт
myGLCD.setColor(VGA_RED);

        myGLCD.print(F("Image size: "));
        myGLCD.print(bmpWidth);
           myGLCD.setFont(BigFont);// включаем большой шрифт
myGLCD.setColor(VGA_RED);

        myGLCD.print('x');
        myGLCD.print(bmpHeight);
        delay(3000);
        #endif
        // 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) >= utft.width())  w = utft.width()  - x;
        if((y+h-1) >= utft.height()) h = utft.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 column...
            // Time to read more pixel data?
            if (buffidx >= sizeof(sdbuffer)) { // Indeed
              // Push LCD buffer to the display first
              if(lcdidx > 0) {
                tft.pushColors(lcdbuffer, lcdidx, first);
                lcdidx = 0;
                first  = false;
              }
              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) {
          tft.pushColors(lcdbuffer, lcdidx, first);
        }

      } // end goodBmp
    }
  }

  bmpFile.close();
  if(!goodBmp)
  myGLCD.setFont(BigFont);// включаем большой шрифт
myGLCD.setColor(VGA_RED);
 
myGLCD.print(F("BMP format not recognized."));
}


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;
}

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Roman2344 пишет:

но не идёт компилирование в ардуино ИДЕ

Не идёт... Бежит чтоле?

Roman2344
Offline
Зарегистрирован: 09.09.2015

Зелёная полоса начинается и всё так и стоит

Roman2344
Offline
Зарегистрирован: 09.09.2015

Взято за основу пример вывода изображения с SD для Adafruit

// This sketch has been Refurbished by BUHOSOFT
// BMP-loading example specifically for the TFTLCD breakout board.
// If using the Arduino shield, use the tftbmp_shield.pde sketch instead!
// If using an Arduino Mega make sure to use its hardware SPI pins, OR make
// sure the SD library is configured for 'soft' SPI in the file Sd2Card.h.
//No DEBUG Mode: Sketch uses 30.070 bytes (93%) of program storage space. Maximum is 32.256 bytes.
//DEBUG Mode: Sketch uses 31.046 bytes (96%) of program storage space. Maximum is 32.256 bytes.

#define DEBUG
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <SPI.h>
#include <SD.h>

// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
#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

// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
//   D0 connects to digital pin 8  (Notice these are
//   D1 connects to digital pin 9   NOT in order!)
//   D2 connects to digital pin 2
//   D3 connects to digital pin 3
//   D4 connects to digital pin 4
//   D5 connects to digital pin 5
//   D6 connects to digital pin 6
//   D7 connects to digital pin 7
// For the Arduino Mega, use digital pins 22 through 29
// (on the 2-row header at the end of the board).

// For Arduino Uno/Duemilanove, etc
//  connect the SD card with DI going to pin 11, DO going to pin 12 and SCK going to pin 13 (standard)
//  Then pin 10 goes to CS (or whatever you have set up)
#if defined __AVR_ATmega2560__
#define SD_SCK 13
#define SD_MISO 12
#define SD_MOSI 11

#endif
#define SD_CS 10     // Set the chip select line to whatever you use (10 doesnt conflict with the library)

// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)
// There are examples in the sketch folder

// our TFT wiring
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, A4);

void setup()
{
  tft.reset();
//this sketch force the  ILI9341 LCD driver chage the next code line to chage the driver
//0x9325  ILI9325 LCD driver
//0x9328  ILI9328 LCD driver
//0x7575  HX8347G LCD driver
//0x9341  ILI9341 LCD driver
//0x8357  HX8357D LCD driver
  tft.begin(0x9341);
  tft.setTextSize(2);
  tft.fillScreen(0);
  tft.setRotation(1);
  tft.println(F("Initializing SD card..."));
  #if defined __AVR_ATmega2560__
  if (!SD.begin(SD_CS, SD_MOSI, SD_MISO, SD_SCK )) {
    tft.println(F("failed!"));
    return;
  }
  #else
  if (!SD.begin(SD_CS)) {
    tft.println(F("failed!"));
    return;
  }
  #endif
  delay(500);

  bmpDraw("Test.bmp", 0, 0);

}

void loop()
{
    delay(2000);
    bmpDraw("arduinoW.bmp", 0, 0);
    delay(2000);
    bmpDraw("AUnoR3.bmp", 0, 0);
    delay(2000);
    bmpDraw("arduinoG.bmp", 0, 0);
    delay(1000);
#ifndef DEBUG
  for(int i = 0; i<4; i++) {
    delay(1000);
    tft.setRotation(i);
    tft.fillScreen(0);
    for(int j=0; j <= 200; j += 50) {
      bmpDraw("miniardu.bmp", j, j);
    }

  }
#endif
}

// 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;

#ifdef DEBUG
  tft.fillScreen(0);
  tft.setCursor(0,0);
  tft.print(F("Loading image '"));
  tft.print(filename);
  tft.println('\'');
#endif
  // Open requested file on SD card
  if ((bmpFile = SD.open(filename)) == NULL) {
    #ifdef DEBUG
    tft.println(F("File not found"));
    #endif
    return;
  }

  // Parse BMP header
  if(read16(bmpFile) == 0x4D42) {
      // BMP signature
    #ifdef DEBUG
    tft.println(F("File size: ")); tft.println(read32(bmpFile));
    #else
        read32(bmpFile);
    #endif
    (void)read32(bmpFile); // Read & ignore creator bytes
    bmpImageoffset = read32(bmpFile); // Start of image data
    #ifdef DEBUG
    tft.print(F("Image Offset: ")); tft.println(bmpImageoffset, DEC);
    // Read DIB header
    tft.print(F("Header size: ")); tft.println(read32(bmpFile));
    #else
    read32(bmpFile);
    #endif

    bmpWidth  = read32(bmpFile);
    bmpHeight = read32(bmpFile);
    if(read16(bmpFile) == 1) { // # planes -- must be '1'
      bmpDepth = read16(bmpFile); // bits per pixel
      #ifdef DEBUG
      Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
      #endif
      if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed

        goodBmp = true; // Supported BMP format -- proceed!
        #ifdef DEBUG
        tft.print(F("Image size: "));
        tft.print(bmpWidth);
        tft.print('x');
        tft.println(bmpHeight);
        delay(3000);
        #endif
        // 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 column...
            // Time to read more pixel data?
            if (buffidx >= sizeof(sdbuffer)) { // Indeed
              // Push LCD buffer to the display first
              if(lcdidx > 0) {
                tft.pushColors(lcdbuffer, lcdidx, first);
                lcdidx = 0;
                first  = false;
              }
              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) {
          tft.pushColors(lcdbuffer, lcdidx, first);
        }

      } // end goodBmp
    }
  }

  bmpFile.close();
  if(!goodBmp) tft.println(F("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;
}

 

releyshic
Offline
Зарегистрирован: 20.11.2015

Roman2344 пишет:
Вообщем то есть ТФТ дисплей 4 дюйма на ili9486 + ардуино мега2560, дисплей с разьёмом micro CD управление пин 53. Примеры с нета либо не работают, либо не компилируются в ардуино ИДЕ ошибки разные, удалось мне вывести картинку но с маленьким разрешениемгде - то 50*30. С памяти проца выводится но тоже ж приходится маленькое разрешение делать, а потом масштабировать, но оно ж такое размытое получается, хотелось бы вывести картинку разрешением где - то 290*200 в нормальном разрешении с микро СД. Но не могу нормальный рабочий пример найти. Помогите пожалуйста.

В АДафруите есть в примерах такой с выводом изображения вот его и пользуй

Roman2344
Offline
Зарегистрирован: 09.09.2015

Нашёл образец в библиотеке UTFT_tinyFAT, интересует в этом примере мне нужно вывести картинку 220*176

и тут есть такое

 char* files220[]={"PIC501.RAW", "PIC502.RAW", "PIC503.RAW", "PIC504.RAW", "PIC505.RAW", "PIC506.RAW", "PIC507.RAW", "PIC508.RAW", "PIC509.RAW", "PIC510.RAW"};

Так вот понятно что картинку сжимаем на 220*176, далее конвертируем в .RAW, но не пойму почему десять картинок? Это мне что нужно сжать картинку на 220*176, потом эту картинку разрезать на 10 частей, потом каждую часть сконвертировать в .RAW?

 

 

 

 

 

 

 

// Demo_Portrait 
// Copyright (C)2015 Rinky-Dink Electronics, Henning Karlsen. All right reserved
// web: http://www.RinkyDinkElectronics.com/
//
// This program is a demo of the loadBitmap()-function.
//
// This program requires UTFT_tinyFAT, UTFT v2.41 or higher, 
// as well as tinyFAT v3.0 or higher.
//
// The image files must be present in the root folder 
// of a FAT16 formatted SDcard in the module cardslot.
//
// Please note that this demo only supports the following
// display sizes:
//      176x220
//      240x320
//      240x400

#include <tinyFAT.h>
#include <UTFT.h>
#include <UTFT_tinyFAT.h>

// Declare which fonts we will be using
extern uint8_t SmallFont[];

UTFT         myGLCD(ITDB32S, 38, 39, 40, 41);   // Remember to change the model parameter to suit your display module!
UTFT_tinyFAT myFiles(&myGLCD);

// List of filenames for pictures to display. 
char* files320[]={"PIC101.RAW", "PIC102.RAW", "PIC103.RAW", "PIC104.RAW", "PIC105.RAW", "PIC106.RAW", "PIC107.RAW", "PIC108.RAW", "PIC109.RAW", "PIC110.RAW"}; // 240x320
char* files400[]={"PIC201.RAW", "PIC202.RAW", "PIC203.RAW", "PIC204.RAW", "PIC205.RAW", "PIC206.RAW", "PIC207.RAW", "PIC208.RAW", "PIC209.RAW", "PIC210.RAW"}; // 240x400
char* files220[]={"PIC501.RAW", "PIC502.RAW", "PIC503.RAW", "PIC504.RAW", "PIC505.RAW", "PIC506.RAW", "PIC507.RAW", "PIC508.RAW", "PIC509.RAW", "PIC510.RAW"}; // 176x220
char* files[10];

int picsize_x, picsize_y;
boolean display_rendertime=false;  // Set this to true if you want the rendertime to be displayed after a picture is loaded
boolean display_filename=true;  // Set this to false to disable showing of filename

word res;
long sm, em;

void setup()
{
  myGLCD.InitLCD(PORTRAIT);
  myGLCD.clrScr();
  file.initFAT();
  myGLCD.setColor(255,255,255);
  myGLCD.setFont(SmallFont);
  picsize_x=myGLCD.getDisplayXSize();
  picsize_y=myGLCD.getDisplayYSize();
  switch (picsize_y)
  {
    case 220:
      for (int z=0; z<sizeof(files220)/sizeof(*files220);z++)
        files[z] = files220[z];
      break;
    case 320:
      for (int z=0; z<sizeof(files320)/sizeof(*files320);z++)
        files[z] = files320[z];
      break;
    case 400:
      for (int z=0; z<sizeof(files400)/sizeof(*files400);z++)
        files[z] = files400[z];
      break;
  }
}

void loop()
{
  
  for (int i=0; i<(sizeof(files)/sizeof(*files)); i++)
  {
    if (files[i]!="")
    {
      sm=millis();
      res=myFiles.loadBitmap(0, 0, picsize_x, picsize_y, files[i]);
      em=millis();
      if (res!=0)
      {
        if (res==0x10)
        {
          myGLCD.print("File not found...", 0, 0);
          myGLCD.print(files[i], 0, 14);
        }
        else
        {
          myGLCD.print("ERROR: ", 0, 0);
          myGLCD.printNumI(res, 56, 0);
        }
        delay(3000);
        myGLCD.clrScr();
      }
      else
      {
        if (display_rendertime==true)
        {
          myGLCD.print("Rendertime (secs):", 0, 0);
          myGLCD.printNumF(float((em-sm)/1000.0), 2, 160,0);
        }
        if (display_filename==true)
        {
           myGLCD.print(files[i], CENTER, myGLCD.getDisplayYSize()-12);
       }
        delay(3000);
      }
    }
  }
}