MCUFRIEND_kbv Library for Uno 2.4, 2.8, 3.5, 3.6, 3.95 inch mcufriend Shields

Adafruit examples deliberately omit the RST argument in the constructor.

Presumably to make their screens work and your screen fail.

Add the optional RST argument for your Red screen. Google "ILI9431 SPI Adafruit". Ask on relevant threads.

David.

Thanks for the offer, but I did not really understand what to do with RST.
Can you please explain?

Thanks.

Hello David, I modified the example "no_showBMP_Uno" with the purpose of simplifying it to show only one BMP (16 or 24bit) and build a specialized function after. It worked well but I think it could simplify more.
Could you please review the attached skecth for me?

  • All my modifications are marked with "@" ( "//@" "/@" or "@/")
  • Image files on SD --> 16 or 24bitBMP.
  • TFT Shield --> Mcufriend TFT 2.8 BLUE (HX8347D, ID 0x4747).

Thanks a lot my friend!!!!!

TESTE_show_1_BMP_not_Uno-MINHA.ino (10.1 KB)

Some of your edits are unwise. e.g. not testing for TFT ID or valid BMP ID.

I suggest that you always press ctl-T to format your code nicely. It makes all the difference to readability.

Personally, I would delete all the extraneous lines. Even with the ctl-T formatted sketch, it is still clearer without the unused lines.

Did you try my example?

David.

Yes, I tried your example and replied this on #1979:
"Fantastic!!! Thats just the solution for what I've been trying to do in the last days! It worked well, but slower then when loading bmp with showBMP. Now I'm trying to build a similar sketch for bmp files, but no success yet. Next step will be for jpeg files.
Many Thanks David!!!"

I learn more and more each time I read your posts. :slight_smile:
Here's the last and cleanest version of the adapted "show_BMP" that I could build:

// MCUFRIEND UNO shields have microSD on pins 10, 11, 12, 13
// The official <SD.h> library only works on the hardware SPI pins
// e.g. 11, 12, 13 on a Uno
// e.g. 50, 51, 52 on a Mega2560
// e.g. 74, 75, 76 on a Due
//
// if you are not using a UNO,  you must use Software SPI:
//
// install v1.0.1 of the <SdFat.h> library with the Arduino Library Manager.
// edit the src/SdFatConfig.h file to #define ENABLE_SOFTWARE_SPI_CLASS 1
//
// copy all your BMP files to the root directory on the microSD with your PC
// (or another directory)

//  * Adapted from "Show_BMP_not_Uno.ino" (One of the examples from "MCUFRIEND_kbv Library
//   for Uno 2.4, 2.8, 3.5, 3.6, 3.95 inch mcufriend Shields" by PRENTICE, DAVID).
//   https://github.com/prenticedavid/MCUFRIEND_kbv
//   PURPOSE: A simpler possible function to Load/Show only one BMP at a time from SD card.
//   RESTRICTED CONDITIONS:     - Image Files: 16 or 24bitBMP (w<=320, h<=240).
//                              - Uno tft Shield: mcufriend 2.8" Blue (HX8347D; ID=0x4747).
//                              - Shield plugged on Mega 2560 R3.
//   Still under construction.

//   VERY GRATEFUL TO DAVID FOR THE VALUABLE LESSONS AND KINDLY "PATIENCE" WITH A NEWBIE.

#include <SPI.h>             // f.k. for Arduino-1.5.2
#include <SdFat.h>           // Use the SdFat library
#include <Adafruit_GFX.h>    // Hardware-specific library

#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
SdFatSoftSpi<12, 11, 13> SD; //Bit-Bang on the Shield pins

#define BMPIMAGEOFFSET 54
#define BUFFPIXEL      20

void setup()
{ tft.begin(0x4747);
  SD.begin(10);
  tft.setRotation(3);
}

void loop() { //FOR TESTS
  char *imagefile = "/test/MOTO_CORRIDA_16bit.bmp"; //var imagefile MUST BE ASSIGNED ON THE MAIN SKECTH
  tft.fillScreen(0);
  showBMP(imagefile, 0, 0);
  delay(1000);
  imagefile = "tiger_24bit.bmp"; //var imagefile MUST BE ASSIGNED ON THE MAIN SKECTH
  tft.fillScreen(0);
  showBMP(imagefile, 0, 0);
  delay(1000);
}

uint16_t read16(File& f) {
  uint16_t result;         // read little-endian
  f.read(&result, sizeof(result));
  return result;
}

uint32_t read32(File& f) {
  uint32_t result;
  f.read(&result, sizeof(result));
  return result;
}

uint8_t showBMP(char *imagefile, int x, int y)
{

  File bmpFile;
  int bmpWidth, bmpHeight;    // W+H in pixels
  uint8_t bmpDepth;           // Bit depth (currently must be 24, 16, 8, 4, 1)
  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[1 + BUFFPIXEL];
  uint8_t bitmask, bitshift;
  boolean flip = true;        // BMP is stored bottom-to-top
  int w, h, row, col, lcdbufsiz = 1 + BUFFPIXEL, buffidx;
  uint32_t pos;               // seek position
  boolean is565 = false;      //
  uint8_t ret;

  bmpFile = SD.open(imagefile);      // Parse BMP header

  (void) read16(bmpFile);
  (void) read32(bmpFile);     // Read & ignore file size
  (void) read32(bmpFile);     // Read & ignore creator bytes
  bmpImageoffset = read32(bmpFile);       // Start of image data

  (void) read32(bmpFile);     // Read & ignore DIB header size
  bmpWidth = read32(bmpFile);
  bmpHeight = read32(bmpFile);

  (void)read16(bmpFile);
  bmpDepth = read16(bmpFile); // bits per pixel
  pos = read32(bmpFile);      // format
  bool first = true;
  is565 = (pos == 3);               // ?already in 16-bit format
  // BMP rows are padded (if needed) to 4-byte boundary
  rowSize = (bmpWidth * bmpDepth / 8 + 3) & ~3;
  if (bmpHeight < 0) {              // If negative, image is in top-down order.
    bmpHeight = -bmpHeight;
    flip = false;
  }

  w = bmpWidth;
  h = bmpHeight;

  // 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).
    uint8_t r, g, b, *sdptr;
    int lcdidx, lcdleft;
    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; ) {  //pixels in row
      lcdleft = w - col;
      if (lcdleft > lcdbufsiz) lcdleft = lcdbufsiz;
      for (lcdidx = 0; lcdidx < lcdleft; lcdidx++) { // buffer at a time
        uint16_t color;
        // Time to read more pixel data?
        if (buffidx >= sizeof(sdbuffer)) { // Indeed
          bmpFile.read(sdbuffer, sizeof(sdbuffer));
          buffidx = 0; // Set index to beginning
          r = 0;
        }
        switch (bmpDepth) {          // Convert pixel from BMP to TFT format
          case 24:
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            color = tft.color565(r, g, b);
            break;
          case 16:
            b = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            if (is565)
              color = (r << 8) | (b);
            else
              color = (r << 9) | ((b & 0xE0) << 1) | (b & 0x1F);
            break;
        }
        lcdbuffer[lcdidx] = color;

      }
      tft.pushColors(lcdbuffer, lcdidx, first);
      first = false;
      col += lcdidx;
    }           // end cols
  }               // end rows
  tft.setAddrWindow(0, 0, tft.width() - 1, tft.height() - 1); //restore full screen
  bmpFile.close();
}

Many Thanks David!!!

How to load Bitmap with library utftglue?

WHY?

What kind of Bitmap?

I kludge this UTFT method in UTFTGLUE:

void	drawBitmap(int x, int y, int sx, int sy, bitmapdatatype data, int scale=1);

but I make no attempt to draw a bitmap at an angle i.e. this UTFT method:

void	drawBitmap(int x, int y, int sx, int sy, bitmapdatatype data, int deg, int rox, int roy);

I provide example showBMP sketches for rendering BMP files from SD card.
The Adafruit_GFX class has several methods:

    drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[],
      int16_t w, int16_t h, uint16_t color),
    drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[],
      int16_t w, int16_t h, uint16_t color, uint16_t bg),
    drawBitmap(int16_t x, int16_t y, uint8_t *bitmap,
      int16_t w, int16_t h, uint16_t color),
    drawBitmap(int16_t x, int16_t y, uint8_t *bitmap,
      int16_t w, int16_t h, uint16_t color, uint16_t bg),
    drawXBitmap(int16_t x, int16_t y, const uint8_t bitmap[],
      int16_t w, int16_t h, uint16_t color),
    drawGrayscaleBitmap(int16_t x, int16_t y, const uint8_t bitmap[],
      int16_t w, int16_t h),
    drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap,
      int16_t w, int16_t h),
    drawGrayscaleBitmap(int16_t x, int16_t y,
      const uint8_t bitmap[], const uint8_t mask[],
      int16_t w, int16_t h),
    drawGrayscaleBitmap(int16_t x, int16_t y,
      uint8_t *bitmap, uint8_t *mask, int16_t w, int16_t h),
    drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[],
      int16_t w, int16_t h),
    drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap,
      int16_t w, int16_t h),
    drawRGBBitmap(int16_t x, int16_t y,
      const uint16_t bitmap[], const uint8_t mask[],
      int16_t w, int16_t h),
    drawRGBBitmap(int16_t x, int16_t y,
      uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h),

The GFX drawBitmap() methods are monochrome. The GFX methods end up by drawing one pixel at a time. It is faster to use TFT hardware.

David.

Thanks!

I'd like to to draw a bitmap from sd card.

showBMP_kbv_as7 works fine, but this sketch work on MCUFRIEND_kbv tft - not utftglue.

Why do you want UTFTGLUE?
UTFTGLUE only sends UTFT methods to the underlying MCUFRIEND_kbv object.

What do you want to do with UTFT style methods that can not be done with Adafruit_GFX methods?

In fact you will find that a UTFTGLUE object is able to perform both UTFT and GFX methods.
I strongly advise you to stick to GFX. Only use UTFTGLUE for a legacy UTFT program. Never try to mix both styles because it gets confusing.

David.

So I shoud use MCUFRIEND_kbv? How to, for example change text font?

Read the Adafruit_GFX docs for setFont().
There are FreeFonts versions of the UTFT DefaultFonts if you happen to enjoy those particular fonts.

If there is some unusual font that you want to use, just ask. Make sure that you provide a link to this special font. I will possibly convert it to FreeFont for you.

David.

Thanks David!

Is it possible to change brightness?

Thanks for all your hard work David. If it wasn't for your MCUFriend library I would have never gotten my display to do anything. I'm fairly new to programming and It’s probably obvious to most, but after searching for several weeks I'm still trying to figure out the significance of the # that precedes many of the keyword2's in the Mcufriend_kbv keywords.txt file.

My sketch begins with:

#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

and the examples show that one preceeds the keywords without an # with tft. but how does one use the keywords with an #. In particular I’ve been trying to make use of printNumF, but all I ever get is errors, such as 'class MCUFRIEND_kbv' has no member named 'printNumF'. (I’m guesing some other library is also needed.)

Just wanted to write real quick about a problem I was having and how I fixed it.

I have a mcuFriend 3.5" display, with the HX8357-D (0x8357) controller.
When I fired up example projects, there were 2 problems: the colors were inverted, and everything was mirrored.

Solution:

  1. Go to the MCUFRIEND_KBV.cpp file
  2. Locate the line with "case 0x8357:" (this was line 1620 for me)
  3. Replace the line right below that with this text:
    "_lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS | INVERT_GS | READ_24BITS;"
  4. The screen should now have correct colors and display correctly!

Hope this will help someone!

Also just want to say thanks to David for all his hard work on this library! It's rare to find a library that is so constantly well-maintained! :slight_smile:

jyclop:
I have a mcuFriend 3.5" display, with the HX8357-D (0x8357) controller.

Update your Library via the Library Manager. (currently v2.9.7)
HX8357-B has ID = 0x8357
HX8357-D has ID = 0x9090

I have never seen a HX8357-B. I rely on feedback from owners.
Please can you confirm whether v2.9.7 is correct for your display.

David.

Barry_S:
Thanks for all your hard work David. If it wasn't for your MCUFriend library I would have never gotten my display to do anything. I'm fairly new to programming and It’s probably obvious to most, but after searching for several weeks I'm still trying to figure out the significance of the # that precedes many of the keyword2's in the Mcufriend_kbv keywords.txt file.

My sketch begins with:

#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

and the examples show that one preceeds the keywords without an # with tft. but how does one use the keywords with an #. In particular I’ve been trying to make use of printNumF, but all I ever get is errors, such as 'class MCUFRIEND_kbv' has no member named 'printNumF'. (I’m guesing some other library is also needed.)

MCUFRIEND_kbv uses regular "Print.h" methods e.g.
tft.print(0.1234567) and tft.print(9.87654, precision)
You have to use tft.setTextCursor() to position where to start printing.
Obviously there is also println() which positions the cursor to the next line afterwards.

UTFTGLUE has a method called printNumF() with a description in the UTFT docs.

I suggest that you stick to the regular Adafruit_GFX.h and Print.h methods in new projects.

Only use UTFTGLUE if you have a legacy UTFT program.

If you want help, post a link to the original working UTFT sketch.
Or explain what you want to do for a new project.

David.

Greetings David,

I tried to run your graphicstest om my arduino Uno but it keeps on failing to build, could you help me please as i'm quite new to this.

This is the Error i get while building:

 C:\Users\User\AppData\Local\Temp\Temp1_MCUFRIEND_kbv-2.9.3.zip\MCUFRIEND_kbv-2.9.3\examples\graphictest_kbv\graphictest_kbv.ino: In function 'void loop()':

C:\Users\User\AppData\Local\Temp\Temp1_MCUFRIEND_kbv-2.9.3.zip\MCUFRIEND_kbv-2.9.3\examples\graphictest_kbv\graphictest_kbv.ino:141:5: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

     };

     ^

C:\Users\User\AppData\Local\Temp\Temp1_MCUFRIEND_kbv-2.9.3.zip\MCUFRIEND_kbv-2.9.3\examples\graphictest_kbv\graphictest_kbv.ino:141:5: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\User\AppData\Local\Temp\Temp1_MCUFRIEND_kbv-2.9.3.zip\MCUFRIEND_kbv-2.9.3\examples\graphictest_kbv\graphictest_kbv.ino:141:5: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\User\AppData\Local\Temp\Temp1_MCUFRIEND_kbv-2.9.3.zip\MCUFRIEND_kbv-2.9.3\examples\graphictest_kbv\graphictest_kbv.ino:141:5: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\User\AppData\Local\Temp\Temp1_MCUFRIEND_kbv-2.9.3.zip\MCUFRIEND_kbv-2.9.3\examples\graphictest_kbv\graphictest_kbv.ino:142:58: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

     char *colorname[] = { "BLUE", "GREEN", "RED", "GRAY" };

                                                          ^

C:\Users\User\AppData\Local\Temp\Temp1_MCUFRIEND_kbv-2.9.3.zip\MCUFRIEND_kbv-2.9.3\examples\graphictest_kbv\graphictest_kbv.ino:142:58: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\User\AppData\Local\Temp\Temp1_MCUFRIEND_kbv-2.9.3.zip\MCUFRIEND_kbv-2.9.3\examples\graphictest_kbv\graphictest_kbv.ino:142:58: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\User\AppData\Local\Temp\Temp1_MCUFRIEND_kbv-2.9.3.zip\MCUFRIEND_kbv-2.9.3\examples\graphictest_kbv\graphictest_kbv.ino:142:58: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

C:\Users\User\AppData\Local\Temp\cceWWwOn.ltrans0.ltrans.o: In function `pushColors':

C:\Users\User\Documents\Arduino\libraries\MCUFRIEND_kbv/MCUFRIEND_kbv.cpp:664: undefined reference to `penguin'

C:\Users\User\Documents\Arduino\libraries\MCUFRIEND_kbv/MCUFRIEND_kbv.cpp:664: undefined reference to `penguin'

C:\Users\User\Documents\Arduino\libraries\MCUFRIEND_kbv/MCUFRIEND_kbv.cpp:665: undefined reference to `penguin'

C:\Users\User\Documents\Arduino\libraries\MCUFRIEND_kbv/MCUFRIEND_kbv.cpp:665: undefined reference to `penguin'

collect2.exe: error: ld returned 1 exit status

And this is what the LCD_ID_readreg gives:
Attached picture of it.

Edit: Finally got it loaded onto my arduino by moving the files. Still problem remains that my screen stays full white.

Thanks in advance.

Hello David,
i am back to you with my problems.
I wish to write programs for 2 differents displays in the same time and i have a libraries problem.
First : i use 2,4" TFT LCD Shield from mcufriend (Ili9325 and ST7789V) with the the latest versions of Adafruit_GFX.h and MCUFRIEND_kbv.h without any problems. Fine.

Second : i want to use OPEN-SMART shield with larger display

Dealextreme link
not running. Screen is white and "flash" from time to time.
I found their libraries and example here :

Google Drive link
They use the same libraries as you but not the same size ???
Their MCUFRIEND_kbv.cpp is 93560 and your is 114219
Their MCUFRIEND_kbv.h is 2227 and your is 2550
Same for Adafruit_GFX
Their Adafruit_GFX.cpp is 16213 and the latest official revision is 43410
Their Adafruit_GFX.h is 3944 and the latest official revision is 7554
Their cards use "ILI9327 Special" and "HX8352B" chips (i have one of each).
Open-Smart shields used a different wiring as Mcufriend but are directly plugable on Aduino Uno board.

My request :
Where is the "link" between the library and the electrical wiring ?
Did you have any idea how to solve my problem ?

Many thanks in advance
Jacques

Apologies for my bad English, i am french (belgian) user

Bfortbattle:
Greetings David,

I tried to run your graphicstest om my arduino Uno but it keeps on failing to build, could you help me please as i'm quite new to this.

This is the Error i get while building:

 C:\Users\User\AppData\Local\Temp\Temp1_MCUFRIEND_kbv-2.9.3.zip\MCUFRIEND_kbv-2.9.3\examples\graphictest_kbv\graphictest_kbv.ino: In function 'void loop()':

...

Please Install/Upgrade your library with the Library Manager. The current version is v2.9.7

I do not recognise your controller from the LCD_ID_readreg sketch.
Perhaps the current library can find the ID.
Please copy-paste from the Serial Terminal instead of posting a screenshot.

David.

JMe87:
Hello David,
i am back to you with my problems.
I wish to write programs for 2 differents displays in the same time and i have a libraries problem.
First : i use 2,4" TFT LCD Shield from mcufriend (Ili9325 and ST7789V) with the the latest versions of Adafruit_GFX.h and MCUFRIEND_kbv.h without any problems. Fine.

Second : i want to use OPEN-SMART shield with larger display

You can use OPEN-SMART with a Uno or Mega by editing these files:
MCUFRIEND_kbv.cpp: #define SUPPORT_8352A
mcufriend_shield.h: #define USE_SPECIAL
mcufriend_special.h: #define USE_OPENSMART_SHIELD_PINOUT

The "editing" involves removing the two slash characters on those lines.

When you are building for the OPEN_SMART boards, define USE_SPECIAL
When you are building for the regular Shields, comment the USE_SPECIAL define

You can leave the other edits unchanged.

The ILI9327 should work by default. I am not sure whether the HX8352-B will work with my HX8352-A code. Please let me know.

David.