ST7789_t3 (part of ST7735 library) support for displays without CS pin

Good morning:

Yep - If you remember I was having issues with the larger eyes, that the pupil was wrong, that it never opened wide enough and when it got too narrow the image screwed up. Still have not back to fully debug yet. Any help would be great.
 
Soldering done, and now I have two eyes running, using Adafruit displays, and using SPI1 and SPI2. Maybe after work I'll have some time to look at the pupil issue (and/or looking at the newer Monster M4SK source, and starting a new port).
 
Good luck. Been trying to work out the math based on whats on the adafruit learning page and no matter what I tried still have the same issue. Was getting ready to get into the code to see what its doing with it. Right now the page states:
The optimal iris image width can be computed by multiplying the round iris diameter (in pixels) by pi — 3.14 — while the image height is the iris radius in pixels. Doesn’t have to be exact, just “ish.” The default iris is 80 pixels across, so the map image is 256x64 pixels.
You know as I typing think its beginning to get clearer on what I have to try next.

EDIT: set it up exactly but no dice. Has to be something in the code that has to get changed
 
Last edited:
Been playing around with the iris map for the last couple of days. Think the problem is something with the polar coordinate map that is generated by the python script but can't nail the problem down.
 
It is very possible I screwed it up when I was trying to get it to work...

Or maybe it overflowed some max value (like might fit into a byte...
 
Been playing around with the iris map for the last couple of days. Think the problem is something with the polar coordinate map that is generated by the python script but can't nail the problem down.

Yeah, my head hurt when I looked at the code, and I looked at the Monster M4SK code, and it was completely different (and more wired into the M4 dma structure).

One thing that I noticed is the use of double and sqrt/pow functions. On the Teensy 4 that is fine, but I should try changing the Teensy 3.5 version to use float specifically and powf/sqrtf to see if it improves the frame rate.

It is very possible I screwed it up when I was trying to get it to work...

Or maybe it overflowed some max value (like might fit into a byte...

I noticed several hardwired 128's etc. in the code. They may need adjusting also. Now is when I really wish we had easy gdb support to the Teensy.

<edit>
I replaced the uint8_t's in drawEye (uT, lT, screenX, and screenY) and it didn't seem to help.
 
It is very possible I screwed it up when I was trying to get it to work...

Or maybe it overflowed some max value (like might fit into a byte...

No - the polar matrix is in the tablegen.py file and I did that independently from you and still getting the same results. Tried different sizes bmp maps for the iris as well.

@MichaelM - I changed most of the 128's in the .py file as well except for the polar function which I wasn't sure about. The other ones seemed to be size limit tests for the BMPs.
 
One thing that I noticed is the use of double and sqrt/pow functions. On the Teensy 4 that is fine, but I should try changing the Teensy 3.5 version to use float specifically and powf/sqrtf to see if it improves the frame rate.

I tried it on the 3.5 version, and it didn't seem to speed up the frame rate (56 frames/second for OLED 128x128 displays). I have to imagine that the calculation done is swamped by the time it takes to write out the OLED displays and wait for the transfer to finish. In looking at the code, there are two places where it is used:
  • If you have a light sensor and turn on scaling, it did some double arithmetic and called pow. The solution was to use float and powf instead, and to make sure the light scaling factor has a 'f' suffix (for Teensy 3.x it doesn't matter because fp constants are done as float even without the suffix); (or)
  • If you define a joystick, it uses sqrt and the solution is to use sqrtf.

Normally I don't have either turned on. I did try it using a POT in place of the light sensor, and as I said, it didn't seem to change the frame rate.
[*]
 
@KurtE - @MichaelMeissner - @defragster

Think we are all pretty dense and missed something obvious and took me 3 days to figure it out. Don't think there is anything wrong with our scaling of the images. Finally found something in the code that finally registered:
Code:
  // And scale to iris range (IRIS_MAX is size at LIGHT_MIN)
  v = map(v, 0, (LIGHT_MAX - LIGHT_MIN), IRIS_MAX, IRIS_MIN);
so essentially you have to change IRIS_MIN to about 500 for the larger eye while for the std iris (80 pixels its 120). Once you change it to 500 all works. Only thing that I can figure out. Have to test this on the smaller eyes to see what happens. Thouhts?

EDIT: Well that wasn't it. I just tried it with the ST7735 and lowering down to 20 and worked fine. So something else driving it.
 
Last edited:
@KurtE - @MichaelMeissner - @defragster

Think we are all pretty dense and missed something obvious and took me 3 days to figure it out. Don't think there is anything wrong with our scaling of the images. Finally found something in the code that finally registered:
Code:
  // And scale to iris range (IRIS_MAX is size at LIGHT_MIN)
  v = map(v, 0, (LIGHT_MAX - LIGHT_MIN), IRIS_MAX, IRIS_MIN);
so essentially you have to change IRIS_MIN to about 500 for the larger eye while for the std iris (80 pixels its 120). Once you change it to 500 all works. Only thing that I can figure out. Have to test this on the smaller eyes to see what happens. Thouhts

It is an ordering problem. In uncannyEyes_async_st7735 has:

Code:
#include "config.h"     // ****** CONFIGURATION IS DONE IN HERE ******

#ifdef USE_ST7789
typedef ST7789_t3 displayType; // Using TFT display(s)
#define DISPLAY_SIZE 240
#else
typedef ST7735_t3 displayType; // Using TFT display(s)
#define DISPLAY_SIZE 128
#endif

and config.h has:

Code:
  #if DISPLAY_SIZE > 128
  #if !defined(IRIS_MIN)	// Each eye might have its own MIN/MAX
  #define IRIS_MIN	 500	// Iris size (0-1023) in brightest light
  #endif
  #if !defined(IRIS_MAX)
  #define IRIS_MAX	 700	// Iris size (0-1023) in darkest light
  #endif

  #else
  #if !defined(IRIS_MIN)	// Each eye ight have its own MIN/MAX
  #define IRIS_MIN	 120	// Iris size (0-1023) in brightest light
  #endif
  #if !defined(IRIS_MAX)
  #define IRIS_MAX	 720	// Iris size (0-1023) in darkest light
  #endif

If you change uncannyEyes_async_st7735 to:

Code:
#ifdef USE_ST7789
typedef ST7789_t3 displayType; // Using TFT display(s)
#define DISPLAY_SIZE 240
#else
typedef ST7735_t3 displayType; // Using TFT display(s)
#define DISPLAY_SIZE 128
#endif

#include "config.h"     // ****** CONFIGURATION IS DONE IN HERE ******

#define RGBColor(r, g, b) ST7735_t3x::Color565(r, g, b)

It works better. Thanks!
 
Last edited:
Not sure, I figured it would be something simple. I tried yesterday to use one of the tables from smaller version instead of larger to see if that made a difference? It did not...

But may have to try out the change... And see how it works!

Yep - works pretty well, I just added the min/max to start of default_large.h
Code:
#define IRIS_MIN  500
#define IRIS_MAX 900

#define SCLERA_WIDTH  375
#define SCLERA_HEIGHT 375

Like some of the other shaped eyes had defines...

Maybe should have done this earlier as I noticed it go bad around 500 awhile ago...
 
The next time you do a pull request for st7735_t3, it may make sense to put a version of uncannyEyes in the examples directory (assuming there isn't a problem with copyright). Or possibly two versions (one for 3.x with 128x128 displays, and one for 4.0 with the 240x240 displays).

It was amusing last night after I left the computer (running Linux fedora), the random screen saver popped up with a display of two eyeballs. Gee that is familiar. :)
 
@mjs513 - I am/was curious how bad it would be to support Adafruit Fonts as well as our own fonts.

So I implemented it ;) But now still trying to figure out way to properly handle the y_cursor...

https://github.com/KurtE/ST7735_t3/tree/T4_Rewrite_Adafruit_fonts

It is based off your T4 rewrite.

Figure if adafruit fonts worked, then don't have to worry as much about compatibility...

I hacked up the St7735 frame buffer test program, that checked the rotations, to add simple
command: t
which outputs a text page (like my ili93241...)
and: o
which outputs text again Opaque
Note their fonts did not support Opaque - I still have not looked into this part...

But you can see where they run into each other in Y part...

View attachment st7735_t3_simpletest_FB-190927a.zip
 
@MichaelMeissner - @KurtE

Done. I incorporated two of the uncanny sketches in the ST7735_t4_rewrite branch that I have: https://github.com/mjs513/ST7735_t3/tree/ST7735_T4_rewrite. I also just did a PR to Paul for these changes as well: https://github.com/PaulStoffregen/ST7735_t3/pull/4

Nice, downloaded - limping on one ST7789 now … will look to update LIB and look at it.

I put my analogWrite PR onto the please-try-to-keep-an-eye-out-for-forum-threads-reporting-bugs post #2 in case Paul looks to that and finds it a useful and orderly work list when he comes back to gather for the next release.
 
@mjs513 - I am/was curious how bad it would be to support Adafruit Fonts as well as our own fonts.

So I implemented it ;) But now still trying to figure out way to properly handle the y_cursor...

https://github.com/KurtE/ST7735_t3/tree/T4_Rewrite_Adafruit_fonts

It is based off your T4 rewrite.

Figure if adafruit fonts worked, then don't have to worry as much about compatibility...

I hacked up the St7735 frame buffer test program, that checked the rotations, to add simple
command: t
which outputs a text page (like my ili93241...)
and: o
which outputs text again Opaque
Note their fonts did not support Opaque - I still have not looked into this part...

But you can see where they run into each other in Y part...

View attachment 17744

Just gave it a try - took me longer to get the display stuff sorted out and pick the right display :)

What it looks like is when you switch to the Adafruit font it looses the looses the line spacing from the last y-test line or newline. If you do this:
Code:
  tft.println("0123456789zyxwvutu");
[COLOR="#FF0000"]tft.println();[/COLOR]  //throw in new line before switching fonts
  tft.setFont(&FreeMonoBoldOblique12pt7b);
//  tft.setTextSize(2);
  tft.println("AdaFruit");
seems to put it at the correct y position.

Now if you do this:
Code:
  tft.println("FreeSan12");
//  tft.setTextSize(1);
  tft.setFont(Arial_10);
  tft.println("0123456789zyxwvutu");
it seems to add an extra newline between the Adafruit font and our font.
 
@mjs513 - It sort of looks like it semi screws up the same way with Adafruit font and built in font.

Here is a quick and dirty version running with adafruit library... Obviously did not use our fonts...
Code:
#include <Adafruit_ST7735.h>
#include <Adafruit_ST7789.h>
#include <Adafruit_ST77xx.h>

#include <Adafruit_GFX.h>    // Core graphics library
#include <SPI.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>
#include <Fonts/FreeSerif12pt7b.h>
#define TFT_SCLK 13  // SCLK can also use pin 14
#define TFT_MOSI 11  // MOSI can also use pin 7
#define TFT_CS   10  // CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC    9  //  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST   8  // RST can use any pin
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
float p = 3.1415926;


void setup(void) {
  pinMode(TFT_CS, INPUT_PULLUP);

  while (!Serial && millis() < 5000) ;
  Serial.begin(9600);
  Serial.print("hello!");

  tft.init(240, 240, SPI_MODE2) ; // use for ILI9488
  Serial.printf("init CS:%d DC:%d MOSI:%d SCLK:%d RST:%d\n ", TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
  tft.fillScreen(ST77XX_RED);
  delay(250);
  tft.fillScreen(ST77XX_GREEN);
  delay(250);
  tft.fillScreen(ST77XX_BLUE);
  delay(250);
  tft.fillScreen(ST77XX_WHITE);
  delay(250);
  tft.fillScreen(ST77XX_BLACK);
  delay(250);
}

uint8_t rotation = 0;
void drawTestScreen(uint16_t background_color) {
  tft.fillScreen(background_color);
  tft.fillRect(tft.width() / 2 - 32, 20, 64, tft.height() - 40, ST7735_GREEN);
  tft.fillRect(tft.width() / 4 - 16, tft.height() / 4 - 16, 32, 32, ST7735_BLUE);
  tft.fillRect(tft.width() * 3 / 4 - 16, tft.height() * 3 / 4 - 16, 32, 32, ST7735_WHITE);
  tft.fillRect(tft.width() * 3 / 4 - 16, tft.height() / 4 - 16, 32, 32, ST7735_BLACK);
  tft.fillRect(0, 0, 8, 8, ST7735_BLACK);
  tft.fillRect(tft.width() - 8, tft.height() - 8, 8, 8, ST7735_WHITE);
  tft.drawPixel(0, 0, ST7735_YELLOW);
  tft.drawPixel(1, 1, ST7735_RED);
  tft.drawPixel(2, 2, ST7735_BLUE);
  tft.setCursor(0, tft.height() / 2 - 4);
  tft.printf("R:%d W:%d H:%d", rotation, tft.width(), tft.height());
  tft.drawPixel(tft.width() - 1, tft.height() - 1, ST7735_YELLOW);
  tft.drawPixel(tft.width() - 2, tft.height() - 2, ST7735_RED);
  tft.drawPixel(tft.width() - 3, tft.height() - 3, ST7735_BLUE);
}
void drawTextScreen(bool fOpaque) {
  tft.fillScreen(ST77XX_RED);
  if (fOpaque)
    tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK );
  else
    tft.setTextColor(ST77XX_WHITE);
  tft.setFont();
  tft.setCursor(0, 5);
  Serial.printf("ASC: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.println("AbCdEf");
  Serial.printf("A Abcd: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.setTextSize(2);
  tft.println("0123456789");
  Serial.printf("A 01234: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.setTextSize(1);

  tft.setFont(&FreeMonoBoldOblique12pt7b);
  Serial.printf("A SF: %d %d\n", tft.getCursorX(), tft.getCursorY());


  tft.println("AdaFruit");
  Serial.printf("A Adafruit: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.setFont(&FreeSerif12pt7b);
  Serial.printf("A SF: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.println("FreeSan12");
  Serial.printf("A FreeSans: %d %d\n", tft.getCursorX(), tft.getCursorY());

}

void loop() {
  tft.setRotation(rotation);
  Serial.printf("Set Rotation: %d width: %d height: %d\n", rotation, tft.width(), tft.height());
  rotation = (rotation + 1) & 0x3;
  elapsedMillis timer;
  drawTestScreen(ST7735_RED);
  // large block of text
  //delay(2500);
  Serial.println("Hit any key to continue");
  uint8_t loffset = 0;
  for (;;) {
    while (!Serial.available()) ;
    char ch = Serial.read();
    while (Serial.read() != -1) ;

    if (ch == '.') {
      tft.drawRect(loffset, loffset, tft.width() - 2 * loffset, tft.height() - 2 * loffset, ST7735_GREEN);
      loffset++;
    } else if (ch == 't') {
      drawTextScreen(0);
    } else if (ch == 'o') {
      drawTextScreen(1);
    } else {
      break;
    }
  }
}


void testContinuousUpdate() {
}
Question is, should I do a PR?
 
@KurtE
Don't know. Just tried the sketch on my 7789 240x320 display and all the text is on top of each other except for the last text line. So something is not quite right.

edit: if you do this it seems to be better:
Code:
//#define NEW_THE_DISP
#include <Adafruit_GFX.h>    // Core graphics library
#include <ST7735_t3.h> // Hardware-specific library
#include <ST7789_t3.h> // Hardware-specific library
#include <SPI.h>
#include <st7735_t3_font_Arial.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>
#include <Fonts/FreeSerif12pt7b.h>

#if defined(__IMXRT1052__) || defined(__IMXRT1062__)  // Teensy 4.x
//#define USE_SPI1
//#define USE_SPI2
//#define NON_SPI_PINS
#ifdef USE_SPI2
#define TFT_SCLK 37  // 
//#define TFT_MISO 34
#define TFT_MOSI 35  // MOSI can also use pin 7
#define TFT_CS   -1//36  // CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC   38  //  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST   39  // RST can use any pin
#elif defined(USE_SPI1)
#define TFT_SCLK 27  // SCLK can also use pin 14
#define TFT_MOSI 26  // MOSI can also use pin 7
#define TFT_CS   0  // CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC    2  //  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST   3  // RST can use any pin

#elif defined(NON_SPI_PINS)
#define TFT_SCLK 7  // SCLK can also use pin 14
#define TFT_MOSI 8  // MOSI can also use pin 7
#define TFT_CS   10  // CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC    9  //  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST   20  // RST can use any pin
#else
#define TFT_SCLK 13  // SCLK can also use pin 14
#define TFT_MOSI 11  // MOSI can also use pin 7
#define TFT_CS   10  // CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC    9  //  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST   8  // RST can use any pin
#endif
#define SD_CS     4  // CS for SD card, can use any pin
#else
//--------------------------------------------
// T3.X
//#define USE_SPI1
//#define USE_SPI2
#define USE_SPI1_NOT_HARDWARE_CSDC
#if defined(USE_SPI1_NOT_HARDWARE_CSDC)
#define TFT_SCLK  20   // SCLK can also use pin 14
#define TFT_MOSI  21  // MOSI can also use pin 7
#define TFT_CS    2  // CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC    3  //  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST   8  // RST can use any pin
#define SD_CS     4  // CS for SD card, can use any pin

#elif defined(USE_SPI1)
#define TFT_SCLK 32  // T3.5/T3.6
#define TFT_MOSI 0   // 
#define TFT_CS   30  // random digital pin
#define TFT_DC   31   // Only Hardware CS pin on SPI1
#define TFT_RST  29  // RST can use any pin
#elif defined(USE_SPI2)
#define TFT_SCLK 46  // T3.5/T3.6
#define TFT_MOSI 44   // 
#define TFT_CS   54  // Hardware CS on SPI2
#define TFT_DC   55   // Hardware CS pin on SPI2
#else
#define TFT_SCLK 13  // SCLK can also use pin 14
#define TFT_MOSI 11  // MOSI can also use pin 7
#define TFT_CS   10  // CS & DC can use pins 2, 6, 9, 10, 15, 20, 21, 22, 23
#define TFT_DC    9  //  but certain pairs must NOT be used: 2+10, 6+9, 20+23, 21+22
#define TFT_RST   8  // RST can use any pin
#endif
#define SD_CS     4  // CS for SD card, can use any pin
#endif
//#define TFT_CS2   7
#define TFT_BLK 7

ST7789_t3 tft = ST7789_t3(TFT_CS, TFT_DC, TFT_RST);
ST7789_t3 *ptft = &tft;

float p = 3.1415926;


void setup(void) {
  pinMode(TFT_CS, INPUT_PULLUP);

  while (!Serial && millis() < 5000) ;
  Serial.begin(9600);
  Serial.print("hello!");

  tft.init(240, 320) ; // use for ILI9488
  Serial.printf("init CS:%d DC:%d MOSI:%d SCLK:%d RST:%d\n ", TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
  tft.fillScreen(ST77XX_RED);
  delay(250);
  tft.fillScreen(ST77XX_GREEN);
  delay(250);
  tft.fillScreen(ST77XX_BLUE);
  delay(250);
  tft.fillScreen(ST77XX_WHITE);
  delay(250);
  tft.fillScreen(ST77XX_BLACK);
  delay(250);
}

uint8_t rotation = 0;
void drawTestScreen(uint16_t background_color) {
  tft.fillScreen(background_color);
  tft.fillRect(tft.width() / 2 - 32, 20, 64, tft.height() - 40, ST7735_GREEN);
  tft.fillRect(tft.width() / 4 - 16, tft.height() / 4 - 16, 32, 32, ST7735_BLUE);
  tft.fillRect(tft.width() * 3 / 4 - 16, tft.height() * 3 / 4 - 16, 32, 32, ST7735_WHITE);
  tft.fillRect(tft.width() * 3 / 4 - 16, tft.height() / 4 - 16, 32, 32, ST7735_BLACK);
  tft.fillRect(0, 0, 8, 8, ST7735_BLACK);
  tft.fillRect(tft.width() - 8, tft.height() - 8, 8, 8, ST7735_WHITE);
  tft.drawPixel(0, 0, ST7735_YELLOW);
  tft.drawPixel(1, 1, ST7735_RED);
  tft.drawPixel(2, 2, ST7735_BLUE);
  tft.setCursor(0, tft.height() / 2 - 4);
  tft.printf("R:%d W:%d H:%d", rotation, tft.width(), tft.height());
  tft.drawPixel(tft.width() - 1, tft.height() - 1, ST7735_YELLOW);
  tft.drawPixel(tft.width() - 2, tft.height() - 2, ST7735_RED);
  tft.drawPixel(tft.width() - 3, tft.height() - 3, ST7735_BLUE);
}
void drawTextScreen(bool fOpaque) {
  tft.fillScreen(ST77XX_RED);
  if (fOpaque)
    tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK );
  else
    tft.setTextColor(ST77XX_WHITE);
  tft.setFont();
  tft.setCursor(0, 5);
  Serial.printf("ASC: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.println("AbCdEf");
  tft.println();
  Serial.printf("A Abcd: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.setTextSize(2);
  tft.println("0123456789");
  tft.println();
  Serial.printf("A 01234: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.setTextSize(1);
  tft.println();
  tft.setFont(&FreeMonoBoldOblique12pt7b);
  Serial.printf("A SF: %d %d\n", tft.getCursorX(), tft.getCursorY());

  tft.println("AdaFruit");1
  
  Serial.printf("A Adafruit: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.setFont(&FreeSerif12pt7b);
  Serial.printf("A SF: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.println("FreeSan12");
  Serial.printf("A FreeSans: %d %d\n", tft.getCursorX(), tft.getCursorY());

}

void loop() {
  tft.setRotation(rotation);
  Serial.printf("Set Rotation: %d width: %d height: %d\n", rotation, tft.width(), tft.height());
  rotation = (rotation + 1) & 0x3;
  elapsedMillis timer;
  drawTestScreen(ST7735_RED);
  // large block of text
  //delay(2500);
  Serial.println("Hit any key to continue");
  uint8_t loffset = 0;
  for (;;) {
    while (!Serial.available()) ;
    char ch = Serial.read();
    while (Serial.read() != -1) ;

    if (ch == '.') {
      tft.drawRect(loffset, loffset, tft.width() - 2 * loffset, tft.height() - 2 * loffset, ST7735_GREEN);
      loffset++;
    } else if (ch == 't') {
      drawTextScreen(0);
    } else if (ch == 'o') {
      drawTextScreen(1);
    } else {
      break;
    }
  }
}


void testContinuousUpdate() {
}

EDIT: Dummy that I am - I didn't notice you switched to using the Adafruit ST7735 library. Sorry - I was just using out T4_rewrite.
 
Last edited:
@KurtE

Was playing around over coffee this morning and made one change and its seems to be working better:
Code:
// Maybe support GFX Fonts as well?
void ST7735_t3::setFont(const GFXfont *f) {
	font = NULL;	// turn off the other font... 
    if(f) {            // Font struct pointer passed in?
        if(!gfxFont) { // And no current font struct?
            // Switching from classic to new font behavior.
            // Move cursor pos down 6 pixels so it's on baseline.
            [COLOR="#FF0000"]cursor_y += 16;[/COLOR] [B] // uncommented and increased to 16[/B]
        }
    } else if(gfxFont) { // NULL passed.  Current font struct defined?
        // Switching from new to classic font behavior.
        // Move cursor pos up 6 pixels so it's at top-left of char.
        [COLOR="#FF0000"]cursor_y -= 6;[/COLOR][B]  //uncommented[/B]
    }
    gfxFont = f;
}
 
Good Morning, (4000th post above)

Still need more coffee!

There are a few interesting questions, which include. Do we make it feel right, or be feature (bug) compatible with Adafruit?

That is if you run the test app with Adafruit_ST7735 up a few posts (#193), and update the drawTextScreen like:
Code:
void drawTextScreen(bool fOpaque) {
  tft.fillScreen(ST77XX_RED);
  if (fOpaque)
    tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK );
  else
    tft.setTextColor(ST77XX_WHITE);
  tft.setFont();
  tft.setCursor(0, 5);
  Serial.printf("ASC: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.println("AbCdEf");
  Serial.printf("A Abcd: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.setTextSize(2);
  tft.println("0123456789");
  Serial.printf("A 01234: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.setTextSize(1);

  tft.setFont(&FreeMonoBoldOblique12pt7b);
  Serial.printf("A SF: %d %d\n", tft.getCursorX(), tft.getCursorY());


  tft.println("AdaFruit");
  Serial.printf("A Adafruit: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.setFont(&FreeSerif12pt7b);
  Serial.printf("A SF: %d %d\n", tft.getCursorX(), tft.getCursorY());
  tft.println("FreeSan12");
  Serial.printf("A FreeSans: %d %d\n", tft.getCursorX(), tft.getCursorY());

  tft.setCursor(30, 100);
  tft.drawRect(30, 100, 60, 20, ST7735_GREEN);
  tft.print("FreeSans");
  tft.setFont();
  tft.setCursor(30, 130);
  tft.drawRect(30, 130, 60, 20, ST7735_GREEN);
  tft.print("System");
  tft.setCursor(30, 160);
  tft.setFont(&FreeSerif12pt7b);
  tft.drawRect(30, 160, 60, 20, ST7735_GREEN);
  tft.print("FreeSans");
}
IMG_0894.jpg

The 3 last outputs. The first one I set the cursor position, and I have current font as a GFX Font, and draw a rectangle at cursor, and you see the text draws above the cursor,
The second one I go to default font, and set position, and the text draws in the rectangle.

The last output, I set position, then set font (I re-enabled the +-6 offset), and then draw the rect and text and the text is part way into rect...

Again all Adafruit code...

I think the +6 versus +16 is more to do with which font was choosen. Probably a larger font would need larger value. I think their two font systems, System font draws from the top and the GFXFonts draw from Bottom or maybe some hypothetical base line?

There are still a few missing pieces here. In here (taken from ILI9341_t3n I think, which I pulled in from a PR) is a function strPixelLen which is supposed to find out how long the string is in pixels. Which probably needs GFX font changes.

BUT Adafruit now has some different functions:
Code:
    getTextBounds(const char *string, int16_t x, int16_t y,
      int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h),
    getTextBounds(const __FlashStringHelper *s, int16_t x, int16_t y,
      int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h),
    getTextBounds(const String &str, int16_t x, int16_t y,
      int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h),
Question is do we worry about those?

Also another question:
Adafruit added the ability to now scale fonts differently for X and Y, that is they have:

Code:
    setTextSize(uint8_t s),
    setTextSize(uint8_t sx, uint8_t sy),
Again question is, is this worth pulling in?

Note: when done with this, I expect to probably pull in these changes back into ILI9341_t3n as well...
 
KurtE said:
I think the +6 versus +16 is more to do with which font was choosen. Probably a larger font would need larger value. I think their two font systems, System font draws from the top and the GFXFonts draw from Bottom or maybe some hypothetical base line?
That is probably the problem. When you start mixing fonts the baseline changes so the delta between baselines need to adjusted when you switch the fonts by some value delta-y. That is what the +-6 is suppose to do: https://learn.adafruit.com/adafruit-gfx-graphics-library/using-fonts
whereas the cursor position when printing with the classic font identified the top-left corner of the character cell, with new fonts the cursor position indicates the baseline — the bottom-most row — of subsequent text. Characters may vary in size and width, and don’t necessarily begin at the exact cursor column (as in below, this character starts one pixel left of the cursor, but others may be on or to the right of it).

When switching between built-in and custom fonts, the library will automatically shift the cursor position up or down 6 pixels as needed to continue along the same baseline.
But that looks like it only applies when printing on the same line (not sure about this).

Was reading about getTestBounds from same source:
getTextBounds expects a string, a starting cursor X&Y position (the current cursor position will not be altered), and addresses of two signed and two unsigned 16-bit integers. These last four values will then contain the upper-left corner and the width & height of the area covered by this text — these can then be passed directly as arguments to fillRect().
This will unfortunately “blink” the text when erasing and redrawing, but is unavoidable. The old scheme of drawing background pixels in the same pass only creates a new set of problems.

KurtE said:
There are still a few missing pieces here. In here (taken from ILI9341_t3n I think, which I pulled in from a PR) is a function strPixelLen which is supposed to find out how long the string is in pixels. Which probably needs GFX font changes.
Yeah just noticed that when going through the code.

Not sure getTextBounds is needed since I am not sure how its used :) As for the scaling in both x,y directions might be interesting :)
 
@mjs513 - I updated my fork/branch to nowalso have getTextBounds, plus setTextSize(x, y),
Still some issues of size reporting for ILI9341 like fonts, reporting between getTextBounds and strPixelLen.

I did a PR back to you, so you can take a look and see what else we might want...

If it looks reasonable I will try to pull back into ili9341_t3n...
 
Out of curiosity, the reset pin on these displays (ST7735, ST7789, ILI9341, etc.), is it setting the charge ground resets the display, and keeping it HIGH does not reset the display?

I am wondering whether I should include a pull-up resistor for the reset line, like I use on CS and DC pins. And is this true of all displays you've worked on?
 
Hi Michael,

I am not sure. Your guess is as good as mine... I think a lot of them, are probably pulled high internally.

I have found that some displays don't work reliably for me, without using the reset pin. And I have done a few boards I played with, of tying the reset pin of the display to the processors reset pin. So each time the board resets, it causes the display to reset as well, without tying up an IO Pin. If I remember correctly I first saw that on one of @Frank B's boards.
 
Back
Top