0

Adafruit RA8875 and external fonts help
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Adafruit RA8875 and external fonts help

by PlastiBots on Sat May 21, 2016 8:00 am

I've got an Adafruit RA8875 hooked up to their 5" LCD and driving it with a Huzzah ESP8266. I am tying to the the external font examples documented here, but they don't work. I keep getting the default font. Any suggestions?

Code: Select all | TOGGLE FULL SIZE
//for RA8875 LCD
#include <Adafruit_GFX.h>    // Core graphics library
#include "Adafruit_RA8875.h"
#include <SPI.h>
#include <Wire.h>   
#include <SD.h>

#include "Adafruit_RA8875.h"
#include <Fonts/FreeSansBold24pt7b.h>  //these are located in the Adafruit GFX library

#define RA8875_INT 0  //TX pin on the Huzzah
#define RA8875_CS 15  //pin 15
#define RA8875_RESET 2  //pin 2
//// end for RA8875 LCD


//TFT library
Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET);

void setup()
{
  Serial.begin(115200);
   
   if (!SD.begin(sd_cs))
  {
    Serial.println("SD initialization failed!");
    return;
  }
 
  Serial.println("SD initialization done.");

  Serial.println("RA8875 start");

  /* Initialise the display using 'RA8875_480x272' or 'RA8875_800x480' */
  if (!tft.begin(RA8875_800x480)) {
    Serial.println("RA8875 Not Found!");
    while (1);
  }

  Serial.println("Found RA8875");

 
  //start the TFT
 
  tft.displayOn(true);
  tft.GPIOX(true);      // Enable TFT - display enable tied to GPIOX
  tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight
  tft.PWM1out(255);
  yield();
  doTextSample();
}



void loop()
{
//nothing
}

void doTextSample()
{
  tft.graphicsMode();                 // go back to graphics mode
  tft.fillScreen(RA8875_BLACK);
  /* Switch to text mode */ 
  tft.textMode();
  tft.setFont(&FreeSansBold24pt7b);

  tft.textSetCursor(10, 10);
  /* Render some text! */
  char string[15] = "Hello, World! ";
  tft.textTransparent(RA8875_WHITE);
  tft.textWrite(string);
  tft.textColor(RA8875_WHITE, RA8875_RED);
  tft.textWrite(string);
  //tft.textTransparent(RA8875_CYAN);
  tft.textWrite(string);
  //tft.textTransparent(RA8875_GREEN);
  tft.textWrite(string);
  tft.textColor(RA8875_YELLOW, RA8875_CYAN);
  tft.textWrite(string);
  tft.textColor(RA8875_BLACK, RA8875_MAGENTA);
  tft.textWrite(string);
  tft.textTransparent(RA8875_WHITE);
 
  /* Change the cursor location and color ... */ 
  tft.textSetCursor(100, 100);
  /* If necessary, enlarge the font */
  tft.textEnlarge(1);
  /* ... and render some more text! */
  //tft.setFont(&FreeSansBold24pt7b);
  tft.textWrite(string);

  //tft.setFont(&FreeSerifItalic24pt7b);
  tft.textEnlarge(3);
  tft.textSetCursor(100, 300);

  tft.textWrite(string);
  //tft.drawChar(300,300, 'A', RA8875_CYAN, RA8875_BLACK, 1);
  //drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)
 
  //tft.graphicsMode();     
  //tft.fillScreen(RA8875_BLACK);
  //myDelay(100);   //need these to reset the watchdog so it does not rst the processor.  every 3 seconds.
  //bmpDraw("00.bmp", 0, 0);
  //bmpDraw("01.bmp", 101, 0);
  //bmpDraw("02.bmp", 202, 0);
  //bmpDraw("03.bmp", 303, 0);
  //bmpDraw("09.bmp", 404, 0);
  //bmpDraw("12.bmp", 505, 0);
  //bmpDraw("13.bmp", 606, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 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 80   //original was 20 px increased due to larger RAM on ESP

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
  if ((bmpFile = SD.open(filename)) == NULL) {
    //Serial.println(F("File not found"));
    return;
  }

  // Parse BMP header
  if(read16(bmpFile) == 0x4D42) { // BMP signature
    //Serial.println(F("File size: "));
    //Serial.println(read32(bmpFile));
    read32(bmpFile);
    (void)read32(bmpFile); // Read & ignore creator bytes
    bmpImageoffset = 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(read32(bmpFile));
    read32(bmpFile);
    bmpWidth  = read32(bmpFile);
    bmpHeight = read32(bmpFile);

    if(read16(bmpFile) == 1) { // # planes -- must be '1'
      bmpDepth = read16(bmpFile); // bits per pixel
      //Serial.print(F("Bit Depth: "));
      //Serial.println(bmpDepth);
      if((bmpDepth == 24) && (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

        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.drawPixel(col+x, row+y, lcdbuffer[lcdidx]);
                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] = color565(r,g,b);
            tft.drawPixel(col+x, row+y, lcdbuffer[lcdidx]);
            //***********************************************
            yield(); //added due to WTD reset issue with ESP.
            //***********************************************           
          } // end pixel

        } // end scanline

        // Write any remaining data to LCD
        if(lcdidx > 0) {
          tft.drawPixel(col+x, row+y, lcdbuffer[lcdidx]);
        }

        //Serial.print(F("Loaded in "));
        //Serial.print(millis() - startTime);
        //Serial.println(" ms");

      } // end goodBmp
    }
  }

  bmpFile.close();
  if(!goodBmp) Serial.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;
}

uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}

byte decToBcd(byte val){
  // Convert normal decimal numbers to binary coded decimal
  return ( (val/10*16) + (val%10) );
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

PlastiBots
 
Posts: 113
Joined: Fri Mar 25, 2011 7:12 pm
Location: Ontario

Re: Adafruit RA8875 and external fonts help

by ecdowney on Sun Jul 10, 2016 12:26 pm

I got this to work as follows:

1. Edit Adafruit_RA8875.h and comment out the virtual size_t write() function
2. Use tft.graphicsMode() for the GFX functions:
Code: Select all | TOGGLE FULL SIZE
 
tft.graphicsMode();
tft.setFont(&FreeSansBold24pt7b);
tft.setCursor(100,300);
tft.setTextSize(1);
tft.print(string);

ecdowney
 
Posts: 40
Joined: Fri Oct 14, 2011 8:40 am

Re: Adafruit RA8875 and external fonts help

by rmetzner49 on Sun Apr 16, 2017 11:05 pm

Great tips, thank you. I was struggling with this as well.
You might mention the tft.setTextSize(2); still seems to work though it's fairly fuzzy around the edges.
I might bite the bullet and roll a 48pt font or find one already done. Now if I could just get the blasted GSL1680 touch controller to work ... Doesn't help I'm doing all this with the ESP32, for which many things aren't fully debugged yet. I have my display working SPI mode but I can't upload a sketch unless I remove the "SS" pin from the display to the ESP32.

Bob M.

rmetzner49
 
Posts: 4
Joined: Wed Jul 01, 2015 10:51 am

Re: Adafruit RA8875 and external fonts help

by rmetzner49 on Tue Apr 18, 2017 3:44 pm

So on an issue related to the SPI mode of the RA8875 Board, how do we determine if this board as "Transaction Support"?

Is the Arduino SPI Library treating this properly? What I believe SHOULD happen as I view the code is; the SPI Bus is supposed to be initialized as an object that has mosi, miso, clk and ss. I see where the code "attaches" and "detaches" the first three, but I don't see 'ss' being handled.

My symptom is; all works fine on the display, but I MUST leave "ss" disconnected while uploading a sketch. This is because the ESP32-Thing has an SPI flash chip. What I think happens is, "ss" must interfere by enabling MISO thereby clobbering the upload process.

Any suggestions would be appreciated.

rmetzner49
 
Posts: 4
Joined: Wed Jul 01, 2015 10:51 am

Re: Adafruit RA8875 and external fonts help

by cmpxchg8b on Fri Apr 21, 2017 3:02 am

rmetzner49 wrote:So on an issue related to the SPI mode of the RA8875 Board, how do we determine if this board as "Transaction Support"?

If you mean SPI transactions, they are purely a software concept. So the question is not whether the board supports them, but whether the Adafruit RA8875 library uses them. The library does use them.
My symptom is; all works fine on the display, but I MUST leave "ss" disconnected while uploading a sketch. This is because the ESP32-Thing has an SPI flash chip. What I think happens is, "ss" must interfere by enabling MISO thereby clobbering the upload process.

Not sure about the SS pin, but the RA8875 chip has a hardware bug where it continues to drive the MISO pin all the time, which makes it a bad citizen that will have problems sharing an SPI bus with other devices. If you're having trouble talking to other SPI devices when your RA8875 is connected, you might look into that as a possible cause.

cmpxchg8b
 
Posts: 243
Joined: Sat Dec 19, 2015 8:38 pm

Re: Adafruit RA8875 and external fonts help

by rmetzner49 on Fri Apr 21, 2017 12:35 pm

Thanks, I did read that little quirk about the RA8875 and am awaiting a 74AUP1G2 to arrive and scab into my board. The weird thing is, I made the problem go away by using D0 instead of D2 for the /CS. That doesn't make any sense but it lets me upload for now. WRT the MISO line, I plan to scab the 74AUP1G2 in the series path back to the ESP32. I don't want to chew up an output to drive the /OE pin on it, so I'll try to see if just having it run from the RA8875 - /CS, so it's only ON when accessing the dispay.

I checked the ESP32-THING artwork and there is no other connection to D2, so unless I want to pick apart the BIOS to see if something else is tweaking D2, this will have to do.

Regards,
Bob M.

rmetzner49
 
Posts: 4
Joined: Wed Jul 01, 2015 10:51 am

Please be positive and constructive with your questions and comments.