Fonts

Status
Not open for further replies.

queenidog

Member
I have a sketch that has a scoreboard with count-down clock to display on an Adafruit 240x320 GLCD (It's a TFT but I don't use as such) I'm using Adafruit GFX and the ILI9341 library ( #include <Adafruit_ILI9341.h>) and a Teensy 3.2.

I want to replace the blocky size 7 regular installed font with something "crispier" and found the Teensy ILI9341_t3 library has what I want: #include <font_ArialBlack.h>.

My sketch which includes static text, a MP3 sound player, SD card bitmap display for graphics and scores that can be incremented, WORKS FINE with the <Adafruit_ILI9341.h> but I get a ton of errors when I try the Teensy ILI9341_t3 library.

I've run the Teensy (3.2) example program in the Teensy ILI9341_t3 library on this same display and it works fine. So there's a disconnect between the two libraries. I've tried to use both libraries, using two different object names, among other things. Should I just try using the font_ArialBlack.h with the Adafruit ILI9341 library? (I've tried to use it "raw" but it doesn't work, so I may have to run it though the Adafruit font converter.

Before I post the sketch (360 lines) or the myriad of errors I get, I thought I would ASK FIRST to see if there is a quick solution since someone must know how both these libraries work better than me and perhaps come across these same issues.

Any comments?
 
Yes - At one point both libraries started with pretty compatible stuff. But then both continued to evolve independent of each other.
Likewise I have the ili9341_t3n library, which is a supper set of the ili9341_t3 library.

For example the Adafruit added something later I think was called a canvas, which is not implemented in either of our libraries.
Mine has the concept of a frame buffer...

So none of them are complete replacements for the other. But in some cases they have the same capabilities done different ways. So without knowing what errors you are receiving hard to say.

Now as far as Fonts are concerned:

Adafruit library with GFX also has library of fonts. Not sure if any of them meet your needs or not. Note: the ILI9341_t3 library only is setup to use the ILI.. fonts. My ILI9341_t3n is setup to allow either ILI or GFX fonts

But again without additional information hard to know what you are running into.
 
This is good information since I thought any improvements to any library would be backward compatible. Otherwise there should be a totally different naming scheme.
It sounds like the ILI9341_T3N library could work. I don't really need the Adafruit library except for the fact I started with it and feel stuck with it.
One error I remembered when I compiled with the ILI9341_T3 library was "keyword set font() not a class member" or something similar to that. These libraries are not very well documented at the front end (before users download them)...maybe they are in the .h and .cpp files but that's getting too hairy!
Here's my code that compiles for a Teensy 3.2 with the ILI9341 library from Adafruit. Errors when the ILI9341_T3 library is used. I want to pop in a new font in the function "UpdateTimeDisplay".

Code:
    /***************************************************
        Name: RobDioramaTeensySDV25BETA   Use for testing/flogging, then copy to new version
        By:            
        Start Date:    29Apr21
        Last Rev:      18Jul21
        MCU:           Teensy3.2
        Hardware:      Teensy3.2, Adafruit GLCD (TFT), Aideepen MP3 player module
        Description:   Using GLCD/TFT for hockey scoreboard for hockey diorama
                       GLCD code and GFX library from Adafruit
                       Modified timer code from Odometer
                       Touch screen (TFT) only used as screen, not touch-enabled
        Vers History: V1.0   Start
                      V1.1   Added score rectangles, added credits
                      V1.2   Added pb for scores
                      V1.3   Added debounce library, used for pb switches and code to put scores in boxes
                      V2.0   Replaced Arduino UNO with Teensy 3.2. Using Adafruit, not Alan Senior library
                             Uses tft.print(buf) instead of tft.drawString(buf, x, y, size) which has been deprecated
                      V2.2   Added FE logo function.
                             (Added SD card to display bitmaps on screen, not working)
                      V2.3   Beta  SD card displaying bitmaps on key press.
                      V2.4   Sound module and amplifier added
                             GLCD stopped working.  Replaced with Adafruit GLCD with integral SD card
                      V2.5   Added pushbuttons to select function
                             Added interrupt service routine, using pin 5 ("score") to reset Teensy if in slideshow
                             Added Aideepen Sound module to play MP3 SFX through amp module
             
    */ 
/*******************************************************************/
   
    #include <Adafruit_GFX.h>
    #include <Adafruit_ILI9341.h>
    GFXcanvas1 canvas(320,240);
    //#include <ILI9341_t3.h>
    //#include <font_ArialBlack.h>
    #include <SPI.h>
    #include <SD.h>
    #include <ezButton.h>//debounce library
    //#include <Fonts/Dialog_plain_16.h>//Custom font conversion at http://oleddisplay.squix.ch/
    //#include <Fonts/Open_24_Display_St20pt7b.h>
    #define TFT_DC  10
    #define TFT_CS  15
    #define TFT_RST 9
    #define SD_CS   20  //chip select for SD card standard SPI pins MOSI 11, SCK 13 in library
    /************Defines for Aideepen MP3 Sound Card***********************/
    #include <SoftwareSerial.h>
    #define Teensy_RX 0//connect to Tx of module
    #define Teensy_TX 1//connect to Rx of module
    SoftwareSerial mySerial(Teensy_RX, Teensy_TX);
    static int8_t Send_buf[8] = {0} ;
    #define CMD_SEL_DEV 0X09
    #define DEV_TF 0X02
    #define CMD_PLAY_W_VOL 0X22
    // SFX stolen from the web, voice using free Text to Speech converter
    #define charge 0x1702//SFX, next five
    #define horn 0x1704
    #define neverbehind 0x1701//not implemented
    #define oneminute 0x1703
    #define notallowed 0x1705//not implemented
    int x = 0; //variable to update interrupt for scoreboard reset
    ezButton canpb(2);//this is D2, not pin 2 - actually pin 4
    ezButton oilpb(3);//D3, pin 5
    ezButton slide(4);//D4, pin 6
    ezButton score(5);//D5, pin 7//interrupt is on this pin.  All digital pins on Teensy have interrupt capability
    
    Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
    //ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC,TFT_RST);
    //Countdown variables
    int countDirection = -1; // direction of count: 1 for up, -1 for down, 0 for stopped
    int nowMinutes=1; // "minutes" part of time
    int nowSeconds=30; // "seconds" part of time
    unsigned long millisNow = 0; // value of millis() at most recent 1/10 second
    int setmin = nowMinutes;//needed for reset
    int setsec = nowSeconds;
    const unsigned long millisTick = 1000; // number of milliseconds per 1/10 second
    int countCan = 0; //reset to zero every power cycle
    int countOil = 0;
    /***********************Setup***********************************/
    void setup(void) {
      Serial.begin(9600);//for troubleshooting
      mySerial.begin(9600);//for MP3 play
      delay(500);//Wait chip initialization is complete
      sendCommand(CMD_SEL_DEV, DEV_TF);//select the TF card
      delay(200);//wait for 200ms
      attachInterrupt(5, Reset, FALLING);//this is used to reset Teensy using pin 5
      canpb.setDebounceTime(50); // set debounce time to 50 milliseconds
      oilpb.setDebounceTime(50);
      canpb.setCountMode(COUNT_RISING);
      oilpb.setCountMode(COUNT_RISING);
      tft.begin();
      if (!SD.begin(SD_CS))//check of SD card is available
      { Serial.println("failed!"); }
      Serial.println("OK!");
      tft.setRotation(3);//can't use with slideshow
      Scoreboard();   //static text, run once, stay on.
      sendCommand(CMD_PLAY_W_VOL, charge);
      delay(4000);
      //credits();//credits for the design, start by switch?  Maybe existing PB, held down to activate
    }
    /*****************************Loop******************************/
    void loop() {
      canpb.loop(); // MUST call the loop() function first for debounce switches
      oilpb.loop();
      slide.loop();
      score.loop();
      //int canpbState = canpb.getState();
     // int oilpbState = oilpb.getState();
      int slideState = slide.getState();
      int scoreState = score.getState();
      if (slideState == LOW)//choose slideshow or scoreboard button
        Slideshow();
      else if (scoreState == LOW)
      { tft.setRotation(3);
        Scoreboard();
      }
      int countCan = canpb.getCount();
      int countOil = oilpb.getCount();
      //if (countOil >= countCan)
      //sendCommand(CMD_PLAY_W_VOL, notallowed);
      //delay (3000);
     // countOil=countOil--;
      tft.setTextSize(4);
      tft.setCursor(70, 105); //put score in Montreal box
      tft.println(countCan);
      tft.setCursor(240, 105); //put score in Oilers box
      tft.println(countOil); 
      
      //Start Countdown
      if ((millis() - millisNow) >= millisTick) {
        nowSeconds += countDirection;
        millisNow += millisTick;
        // trade 60 seconds for 1 minute
        if (nowSeconds >= 60) {
          nowSeconds -= 60;//remove 60 seconds
          nowMinutes++;//add one minute
        }
        // trade 1 minute for 60 seconds
        if (nowSeconds < 0) {
          nowMinutes--;//remove minute
          nowSeconds += 60;
        }//add 60 seconds
      }
      if ((nowMinutes == 1) && (nowSeconds == 0)) {
        sendCommand(CMD_PLAY_W_VOL, oneminute);//"1 minute to play" SFX
      }
    
      //countdown is over
      if ((nowMinutes == 0) && (nowSeconds == 0)) {
        delay(100);
        nowMinutes = setmin;
        nowSeconds = setsec;
        delay (500);
        sendCommand(CMD_PLAY_W_VOL, horn);//time up, sound horn
        delay(3000);
      }
      updateTimeDisplay();
    }
    /********************sendCommand function for MP3 sound card*****************/
    void sendCommand(int8_t command, int16_t dat)
    { delay(20);
      Send_buf[0] = 0x7e; //starting byte
      Send_buf[1] = 0xff; //version
      Send_buf[2] = 0x06; //the number of bytes of the command without starting byte and ending byte
      Send_buf[3] = command; //
      Send_buf[4] = 0x00;//0x00 = no feedback, 0x01 = feedback
      Send_buf[5] = (int8_t)(dat >> 8);//datah
      Send_buf[6] = (int8_t)(dat); //datal
      Send_buf[7] = 0xef; //ending byte
      for (uint8_t i = 0; i < 8; i++) //
      { mySerial.write(Send_buf[i]) ; }
    }
   /*********************ISR Reset**********************************/
    void Reset() {
      SCB_AIRCR = 0x05FA0004;//PB on pin D5 gets us here to reset MCU
    }
    /********************Function Scoreboard************************/
   void Scoreboard() {//all static, run once at startup Note: was unsigned long instead of void
      //tft.setFont(&Dialog_plain_16);//try different fonts
      //tft.setFont (&Roboto_Medium_11);
      tft.fillScreen(ILI9341_BLACK);
      tft.setTextColor(ILI9341_CYAN);
      tft.setTextSize(4);//def 4 for default font
      tft.setCursor(0, 0); //x,y
      tft.println(" FOUND FORUM");
      tft.setTextColor(ILI9341_GREEN);
      tft.setTextSize(3);//def 3 for default font
      tft.setCursor(0, 40); //x,y
      tft.println("Canadiens  Oilers");
      //tft.setFont();//reset font. Use when using non default fonts
      //Draw rectangles for scores
      tft.drawRect(50, 90, 70, 50, ILI9341_RED); //(x,y,w,h,color) Canadiens on left
      tft.drawRect(220, 90, 70, 50, ILI9341_RED); //Oilers right
      tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
      //tft.setTextSize(3);
      //return 0;
    }
    /************************Function UpdateTimeDisplay****************/
    void updateTimeDisplay () {
      char buf[8];
      //tft.setFont(&Open_24_Display_St20pt7b);
      //tft.setFont (&DSEG7_Classic_Mini_Regular_18);//seven segment font not updated
      //tft.setFont (&DSEG7_Modern_Regular_18);
      //tft.setFont(ArialBlack_60);
      tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK); //need black background or letters pile up
      tft.setCursor(-20, 170); //x,y was -40,230 for open_24 font
      tft.setTextSize(7);//def 7 for large regular font
      sprintf(buf, "  %02d:%02d", nowMinutes, nowSeconds);
       tft.print(buf);
      //tft.setTextSize(3);//reset for score
      tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);//reset for score
    }
    /*****************************Function Slideshow************************/
    void Slideshow()
    { tft.fillScreen(ILI9341_BLACK);
      bmpDraw("Goalie.bmp", 0, 0); //okay
      delay (5000);
    
      tft.fillScreen(ILI9341_BLACK);
      bmpDraw("RobChris.bmp", 0, 0);//okay
      delay (5000);
    
      tft.fillScreen(ILI9341_BLACK);
      bmpDraw("RobBob.bmp", 0, 0);//okay
      delay (5000);
      tft.fillScreen(ILI9341_BLACK);
    
      tft.fillScreen(ILI9341_BLACK);
      bmpDraw("FElogo.bmp", 0, 0);//okay
      delay (5000);
      tft.fillScreen(ILI9341_BLACK);
    }
    #define BUFFPIXEL 40 //increased from 20   
    /*********************Function: draw bitmaps on GLCD*************************/
    void bmpDraw(char *filename, uint8_t x, uint16_t 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 buffer (R+G+B 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();
    
      if ((x >= tft.width()) || (y >= tft.height())) return;
    //All print commands display on monitor if connected.  Not needed here but good for troubleshooting
      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.print(F("File not found"));
        return;
      }
      // Parse BMP header
      if (read16(bmpFile) == 0x4D42) { // BMP signature
        Serial.print(F("File size: ")); Serial.println(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));
        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 < 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...
              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 pixel...
                if (buffidx >= sizeof(sdbuffer)) { // Read more pixel data
                  bmpFile.read(sdbuffer, sizeof(sdbuffer));
                  buffidx = 0; // Set index to beginning
                }
    
                // Convert pixel from BMP to TFT format, push to display
                b = sdbuffer[buffidx++];
                g = sdbuffer[buffidx++];
                r = sdbuffer[buffidx++];
                tft.pushColor(tft.color565(r, g, b));
              } // end pixel
            } // end scanline
            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."));
    }
    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;
    }
 
Note this compiles with ILI9341_t3n...
I did edit one of your functions that was giving compile warnings of converting strings to char *
(Just added const to parameter...)

Note: I did not look over it much but there may be problems with how it is drawing the bitmaps... You may want to look at the updated examples in the library that hopefully get around the issue.


Code:
/***************************************************
     Name: RobDioramaTeensySDV25BETA   Use for testing/flogging, then copy to new version
     By:
     Start Date:    29Apr21
     Last Rev:      18Jul21
     MCU:           Teensy3.2
     Hardware:      Teensy3.2, Adafruit GLCD (TFT), Aideepen MP3 player module
     Description:   Using GLCD/TFT for hockey scoreboard for hockey diorama
                    GLCD code and GFX library from Adafruit
                    Modified timer code from Odometer
                    Touch screen (TFT) only used as screen, not touch-enabled
     Vers History: V1.0   Start
                   V1.1   Added score rectangles, added credits
                   V1.2   Added pb for scores
                   V1.3   Added debounce library, used for pb switches and code to put scores in boxes
                   V2.0   Replaced Arduino UNO with Teensy 3.2. Using Adafruit, not Alan Senior library
                          Uses tft.print(buf) instead of tft.drawString(buf, x, y, size) which has been deprecated
                   V2.2   Added FE logo function.
                          (Added SD card to display bitmaps on screen, not working)
                   V2.3   Beta  SD card displaying bitmaps on key press.
                   V2.4   Sound module and amplifier added
                          GLCD stopped working.  Replaced with Adafruit GLCD with integral SD card
                   V2.5   Added pushbuttons to select function
                          Added interrupt service routine, using pin 5 ("score") to reset Teensy if in slideshow
                          Added Aideepen Sound module to play MP3 SFX through amp module

*/
/*******************************************************************/

//#include <Adafruit_GFX.h>
//#include <Adafruit_ILI9341.h>
//GFXcanvas1 canvas(320, 240);
#include <ILI9341_t3n.h>
//#include <font_ArialBlack.h>
#include <SPI.h>
#include <SD.h>
#include <ezButton.h>//debounce library
//#include <Fonts/Dialog_plain_16.h>//Custom font conversion at http://oleddisplay.squix.ch/
//#include <Fonts/Open_24_Display_St20pt7b.h>
#define TFT_DC  10
#define TFT_CS  15
#define TFT_RST 9
#define SD_CS   20  //chip select for SD card standard SPI pins MOSI 11, SCK 13 in library
/************Defines for Aideepen MP3 Sound Card***********************/
#include <SoftwareSerial.h>
#define Teensy_RX 0//connect to Tx of module
#define Teensy_TX 1//connect to Rx of module
SoftwareSerial mySerial(Teensy_RX, Teensy_TX);
static int8_t Send_buf[8] = {0} ;
#define CMD_SEL_DEV 0X09
#define DEV_TF 0X02
#define CMD_PLAY_W_VOL 0X22
// SFX stolen from the web, voice using free Text to Speech converter
#define charge 0x1702//SFX, next five
#define horn 0x1704
#define neverbehind 0x1701//not implemented
#define oneminute 0x1703
#define notallowed 0x1705//not implemented
int x = 0; //variable to update interrupt for scoreboard reset
ezButton canpb(2);//this is D2, not pin 2 - actually pin 4
ezButton oilpb(3);//D3, pin 5
ezButton slide(4);//D4, pin 6
ezButton score(5);//D5, pin 7//interrupt is on this pin.  All digital pins on Teensy have interrupt capability

//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC,TFT_RST);
//Countdown variables
int countDirection = -1; // direction of count: 1 for up, -1 for down, 0 for stopped
int nowMinutes = 1; // "minutes" part of time
int nowSeconds = 30; // "seconds" part of time
unsigned long millisNow = 0; // value of millis() at most recent 1/10 second
int setmin = nowMinutes;//needed for reset
int setsec = nowSeconds;
const unsigned long millisTick = 1000; // number of milliseconds per 1/10 second
int countCan = 0; //reset to zero every power cycle
int countOil = 0;
/***********************Setup***********************************/
void setup(void) {
  Serial.begin(9600);//for troubleshooting
  mySerial.begin(9600);//for MP3 play
  delay(500);//Wait chip initialization is complete
  sendCommand(CMD_SEL_DEV, DEV_TF);//select the TF card
  delay(200);//wait for 200ms
  attachInterrupt(5, Reset, FALLING);//this is used to reset Teensy using pin 5
  canpb.setDebounceTime(50); // set debounce time to 50 milliseconds
  oilpb.setDebounceTime(50);
  canpb.setCountMode(COUNT_RISING);
  oilpb.setCountMode(COUNT_RISING);
  tft.begin();
  if (!SD.begin(SD_CS))//check of SD card is available
  {
    Serial.println("failed!");
  }
  Serial.println("OK!");
  tft.setRotation(3);//can't use with slideshow
  Scoreboard();   //static text, run once, stay on.
  sendCommand(CMD_PLAY_W_VOL, charge);
  delay(4000);
  //credits();//credits for the design, start by switch?  Maybe existing PB, held down to activate
}
/*****************************Loop******************************/
void loop() {
  canpb.loop(); // MUST call the loop() function first for debounce switches
  oilpb.loop();
  slide.loop();
  score.loop();
  //int canpbState = canpb.getState();
  // int oilpbState = oilpb.getState();
  int slideState = slide.getState();
  int scoreState = score.getState();
  if (slideState == LOW)//choose slideshow or scoreboard button
    Slideshow();
  else if (scoreState == LOW)
  { tft.setRotation(3);
    Scoreboard();
  }
  int countCan = canpb.getCount();
  int countOil = oilpb.getCount();
  //if (countOil >= countCan)
  //sendCommand(CMD_PLAY_W_VOL, notallowed);
  //delay (3000);
  // countOil=countOil--;
  tft.setTextSize(4);
  tft.setCursor(70, 105); //put score in Montreal box
  tft.println(countCan);
  tft.setCursor(240, 105); //put score in Oilers box
  tft.println(countOil);

  //Start Countdown
  if ((millis() - millisNow) >= millisTick) {
    nowSeconds += countDirection;
    millisNow += millisTick;
    // trade 60 seconds for 1 minute
    if (nowSeconds >= 60) {
      nowSeconds -= 60;//remove 60 seconds
      nowMinutes++;//add one minute
    }
    // trade 1 minute for 60 seconds
    if (nowSeconds < 0) {
      nowMinutes--;//remove minute
      nowSeconds += 60;
    }//add 60 seconds
  }
  if ((nowMinutes == 1) && (nowSeconds == 0)) {
    sendCommand(CMD_PLAY_W_VOL, oneminute);//"1 minute to play" SFX
  }

  //countdown is over
  if ((nowMinutes == 0) && (nowSeconds == 0)) {
    delay(100);
    nowMinutes = setmin;
    nowSeconds = setsec;
    delay (500);
    sendCommand(CMD_PLAY_W_VOL, horn);//time up, sound horn
    delay(3000);
  }
  updateTimeDisplay();
}
/********************sendCommand function for MP3 sound card*****************/
void sendCommand(int8_t command, int16_t dat)
{ delay(20);
  Send_buf[0] = 0x7e; //starting byte
  Send_buf[1] = 0xff; //version
  Send_buf[2] = 0x06; //the number of bytes of the command without starting byte and ending byte
  Send_buf[3] = command; //
  Send_buf[4] = 0x00;//0x00 = no feedback, 0x01 = feedback
  Send_buf[5] = (int8_t)(dat >> 8);//datah
  Send_buf[6] = (int8_t)(dat); //datal
  Send_buf[7] = 0xef; //ending byte
  for (uint8_t i = 0; i < 8; i++) //
  {
    mySerial.write(Send_buf[i]) ;
  }
}
/*********************ISR Reset**********************************/
void Reset() {
  SCB_AIRCR = 0x05FA0004;//PB on pin D5 gets us here to reset MCU
}
/********************Function Scoreboard************************/
void Scoreboard() {//all static, run once at startup Note: was unsigned long instead of void
  //tft.setFont(&Dialog_plain_16);//try different fonts
  //tft.setFont (&Roboto_Medium_11);
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_CYAN);
  tft.setTextSize(4);//def 4 for default font
  tft.setCursor(0, 0); //x,y
  tft.println(" FOUND FORUM");
  tft.setTextColor(ILI9341_GREEN);
  tft.setTextSize(3);//def 3 for default font
  tft.setCursor(0, 40); //x,y
  tft.println("Canadiens  Oilers");
  //tft.setFont();//reset font. Use when using non default fonts
  //Draw rectangles for scores
  tft.drawRect(50, 90, 70, 50, ILI9341_RED); //(x,y,w,h,color) Canadiens on left
  tft.drawRect(220, 90, 70, 50, ILI9341_RED); //Oilers right
  tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
  //tft.setTextSize(3);
  //return 0;
}
/************************Function UpdateTimeDisplay****************/
void updateTimeDisplay () {
  char buf[8];
  //tft.setFont(&Open_24_Display_St20pt7b);
  //tft.setFont (&DSEG7_Classic_Mini_Regular_18);//seven segment font not updated
  //tft.setFont (&DSEG7_Modern_Regular_18);
  //tft.setFont(ArialBlack_60);
  tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK); //need black background or letters pile up
  tft.setCursor(-20, 170); //x,y was -40,230 for open_24 font
  tft.setTextSize(7);//def 7 for large regular font
  sprintf(buf, "  %02d:%02d", nowMinutes, nowSeconds);
  tft.print(buf);
  //tft.setTextSize(3);//reset for score
  tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);//reset for score
}
/*****************************Function Slideshow************************/
void Slideshow()
{ tft.fillScreen(ILI9341_BLACK);
  bmpDraw("Goalie.bmp", 0, 0); //okay
  delay (5000);

  tft.fillScreen(ILI9341_BLACK);
  bmpDraw("RobChris.bmp", 0, 0);//okay
  delay (5000);

  tft.fillScreen(ILI9341_BLACK);
  bmpDraw("RobBob.bmp", 0, 0);//okay
  delay (5000);
  tft.fillScreen(ILI9341_BLACK);

  tft.fillScreen(ILI9341_BLACK);
  bmpDraw("FElogo.bmp", 0, 0);//okay
  delay (5000);
  tft.fillScreen(ILI9341_BLACK);
}
#define BUFFPIXEL 40 //increased from 20   
/*********************Function: draw bitmaps on GLCD*************************/
void bmpDraw(const char *filename, uint8_t x, uint16_t 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 buffer (R+G+B 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();

  if ((x >= tft.width()) || (y >= tft.height())) return;
  //All print commands display on monitor if connected.  Not needed here but good for troubleshooting
  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.print(F("File not found"));
    return;
  }
  // Parse BMP header
  if (read16(bmpFile) == 0x4D42) { // BMP signature
    Serial.print(F("File size: ")); Serial.println(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));
    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 < 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...
          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 pixel...
            if (buffidx >= sizeof(sdbuffer)) { // Read more pixel data
              bmpFile.read(sdbuffer, sizeof(sdbuffer));
              buffidx = 0; // Set index to beginning
            }

            // Convert pixel from BMP to TFT format, push to display
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            tft.pushColor(tft.color565(r, g, b));
          } // end pixel
        } // end scanline
        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."));
}
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;
}
 
Loaded your library and, as you indicated, the sketch compiles. I fixed the warnings.
I had some success loading two fonts created with Font Converter (http://oleddisplay.squix.ch/#/home) that created the style I wanted for GFX font library. The first one did a double strike to get "bold" but I didn't like it so tried another, created in the same fashion. This one was better but I cannot place it property on my display. It overwrites other text and my attempts to move it failed. At y value of 0, text is at top, at 100 it moves down, at 200 it's about middle, at 300 it stays where it was. negative values (as I use for x) do not work. Perhaps the rotation command has something to do with this. I'll try a couple more fonts. But I like your library because even though I put the font in the Adafruit_ILI9341 library, it was "discovered" by yours. So yeah, your's is definitely a super-set.
 
Kurt, I was trying out the example programs in your library and getting numerous errors. Eg, in the program ILI_Ada_FontTest3 (or 4) I get these errors:
I tired commenting out the offending font that wouldn't load but got errors on the next font. DemoSauce did not work. ILI_GFX Font test worked and so did the TFT_String_Align.

Where does the library look for fonts? I've got them all over the place including in the Teensy hardware library (C:/programsx86...). When I was thrashing about, I was moving font files into the library I was currently TRYING to use. Should there be ONE, and ONLY ONE Font directory?


Code:
Arduino: 1.8.13 (Windows 10), TD: 1.53, Board: "Teensy 3.2 / 3.1, Serial, 96 MHz (overclock), Faster, US English"





















C:\Users\bobfo\AppData\Local\Temp\arduino_modified_sketch_855607\ILI_Ada_FontTest3.ino:9:27: fatal error: font_OpenSans.h: No such file or directory

Multiple libraries were found for "font_Arial.h"

compilation terminated.

 Used: D:\ArduinoSketch\libraries\ILI9341_t3

 Not used: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\ILI9341_t3

Multiple libraries were found for "SPI.h"

 Used: D:\ArduinoSketch\libraries\SPI

 Not used: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SPI

 Not used: D:\ArduinoSketch\libraries\SPITeensy

 Not used: D:\ArduinoSketch\libraries\SPI-master

Error compiling for board Teensy 3.2 / 3.1.



This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
 
You might want to check the Readme file for the library. There is a section on Font Support

Some of the example sketches, such as the ILI_Ada_FontTest3 and ILI_Ada_FontTest4 may require an additional library of fonts to work.
You can find this font library up at: https://github.com/mjs513/ILI9341_fonts
This font library is setup, to create an archive file of all of the fonts, such that it won't pull in every font file in this directory,
unlike some other libraries. Likewise it is setup to hopefully work with several of our libraries by conditionally including header files
to try to match which display library you are using.
 
Good news is that I found a font that works for me and displays properly on my 240x320 display.
I wish ALL libraries were as well documented as yours. Adafruit documentation really sucks, sorry guys, but it does.
Finally, now that I have the ILI9341-t3n loaded and in use, should I DELETE all the other ILI9341 libraries? My system has so many libraries the IDE takes a long time to load as it scans through the libraries for updates (which I may not need, since I don't use every library). I want to clean the whole mess up and get the fonts in one area.
Thanks for your assistance thus far. It helped me out. Nice dog too.
 
Status
Not open for further replies.
Back
Top