centering text on a Copperhill TFT LCD board (T4.1)with ST7789_t3

Status
Not open for further replies.

bschena

Active member
I've been trying to find some way to write a 3,4, or 5 digit number centered in the same spot on the 240x240 TFT display on this board https://copperhilltech.com/teensy-4-1-triple-can-bus-board-with-240x240-lcd-and-ethernet/

FWIW, this is my first attempt at graphic LCDs.

here's what I'm doing that works, more or less:

Code:
void tft_update( int rate ) {
  int dynamicX;
  int dynamicY;
 
  itoa( packetRate, packetRateString, 10 ); // convert integer to char array (number, string, base)
  tft.setFont( packetRateTextSize );
  tft.setTextColor( ST77XX_BLACK );
  tft.getTextBounds( packetRateString, x, y, &posX, &posY, &w, &h );
  dynamicX = centerX - w / 2 - fudgeFactorOffset; // subtract fudge factor for some unexplained misalignment/bug in getTextBounds()
  dynamicY = centerY - h / 2;
  tft.fillRoundRect( dynamicX, dynamicY, w, h, whiteBoxCornerRad, ST77XX_WHITE ); //clear the screen for the next write
  tft.setCursor( dynamicX, dynamicY ); // locate the upper left cursor point based on the bounding box size
  tft.println( packetRateString );
  return;
}

I did see some reference in the ST7735_t3.cpp file about "centering":

// added support for drawing strings/numbers/floats with centering
// modified from tft_ili9341_ESP github library
// Handle numbers
int16_t drawNumber(long long_num,int poX, int poY);

but I tried drawNumber() and it just seemed to do the standard left-justified thing.

Is there a smarter way to center a variable-width text field (number) on a TFT panel?

Also, note the "fudgeFactorOffset" in my snippet - for some reason the w&h that I'm getting back from getTextBounds doesn't really seem to center the text exactly so I have to fudge it to look right (but it's close).

Anyone know what's going on there?
 
A couple things.

Before doing a drawNumber you need to tell it what datum you want to use via a
Code:
setDatum(Datum)

Where Datum goes from 0-8. Datum has the following definitions:
Code:
//These enumerate the text plotting alignment (reference datum point)
#define TL_DATUM 0 // Top left (default)
#define TC_DATUM 1 // Top centre
#define TR_DATUM 2 // Top right
#define ML_DATUM 3 // Middle left
#define CL_DATUM 3 // Centre left, same as above
#define MC_DATUM 4 // Middle centre
#define CC_DATUM 4 // Centre centre, same as above
#define MR_DATUM 5 // Middle right
#define CR_DATUM 5 // Centre right, same as above
#define BL_DATUM 6 // Bottom left
#define BC_DATUM 7 // Bottom centre
#define BR_DATUM 8 // Bottom right

To get an idea of what it can do you can try the example "TFT_String_Align.ino" that is part of the library.

As for the fudge factor @KurtE took that into account as well with the following:
Code:
  // Or use this initializer (uncomment) for Some 1.44" displays use different memory offsets
  // Try it if yours is not working properly
  // May need to tweek the offsets
  tft.setRowColStart(32,0);

This will allow you to adjust the offsets in x and y.

Hope it helps :)
 
A couple things.

Before doing a drawNumber you need to tell it what datum you want to use via a
Code:
setDatum(Datum)

Where Datum goes from 0-8. Datum has the following definitions:
Code:
//These enumerate the text plotting alignment (reference datum point)
#define TL_DATUM 0 // Top left (default)
#define TC_DATUM 1 // Top centre
#define TR_DATUM 2 // Top right
#define ML_DATUM 3 // Middle left
#define CL_DATUM 3 // Centre left, same as above
#define MC_DATUM 4 // Middle centre
#define CC_DATUM 4 // Centre centre, same as above
#define MR_DATUM 5 // Middle right
#define CR_DATUM 5 // Centre right, same as above
#define BL_DATUM 6 // Bottom left
#define BC_DATUM 7 // Bottom centre
#define BR_DATUM 8 // Bottom right

To get an idea of what it can do you can try the example "TFT_String_Align.ino" that is part of the library.

As for the fudge factor @KurtE took that into account as well with the following:
Code:
  // Or use this initializer (uncomment) for Some 1.44" displays use different memory offsets
  // Try it if yours is not working properly
  // May need to tweek the offsets
  tft.setRowColStart(32,0);

This will allow you to adjust the offsets in x and y.

Hope it helps :)


ah-ha! datum. I saw mention of that but thought it had to do with scrolling text (way beyond my pay grade).

is there a way to ARBITRARILY define the datum, or do I have to use one of the 9 pre-defined ones listed above? my ideal text location is L/R centered, but approximately 3/4 of the way down the panel.

EDIT: I see now (I think) that datum is relative to the text, not the panel...
EDIT2: ok, I got it working, modulo the "offset" problem. progress!

thanks for the tip on the setRowColStart - I'll go take a look at that now.
 
Last edited:
As for the fudge factor @KurtE took that into account as well with the following:
Code:
  // Or use this initializer (uncomment) for Some 1.44" displays use different memory offsets
  // Try it if yours is not working properly
  // May need to tweek the offsets
  tft.setRowColStart(32,0);

This will allow you to adjust the offsets in x and y.

Hope it helps :)

I googled around but haven't found any examples for how to use setRowColStart(). I tried this, it compiles, but has no effect.

Code:
void tft_update_datum( long rate ) {

  tft.fillScreen( backgroundColor );
  tft.setRowColStart(200, 200);   // big numbers just to see if anything happens
  tft.setTextDatum( 4 ); // Set datum to middle center (4)

  tft.setFont( packetRateTextSize );
  tft.setTextColor( ST77XX_BLACK );

  tft.drawNumber(rate, 120, 120);  // aiming the text at the center of the display
  
  return;

}

clearly I'm not understanding how to use tft.setRowColStart().

Is this a "global"/persistent offset for the entire panel or is it supposed to be used as a "local" tweak like what I need here - to nudge some text around by a few pixels when used in conjunction with setTextDatum()?

Thx!
 
Morning
Just saw the post. When you use setRowCol you need to do it right at the beginning of the sketch when you do your initialization:
Code:
  // Or use this initializer (uncomment) for Some 1.44" displays use different memory offsets
  // Try it if yours is not working properly
  // May need to tweek the offsets
  //tft.setRowColStart(32,0);

  // Or use this initializer (uncomment) if you're using a 1.54" 240x240 TFT
  tft.init(240, 240);   // initialize a ST7789 chip, 240x240 pixels
This is documented in the graphicstest.ino example of the library.

setRowCol is a global setup for the display and not meant to be used for "local tweaking" like you did there to nudge text around.
 
Morning
Just saw the post. When you use setRowCol you need to do it right at the beginning of the sketch when you do your initialization:
Code:
  // Or use this initializer (uncomment) for Some 1.44" displays use different memory offsets
  // Try it if yours is not working properly
  // May need to tweek the offsets
  //tft.setRowColStart(32,0);

  // Or use this initializer (uncomment) if you're using a 1.54" 240x240 TFT
  tft.init(240, 240);   // initialize a ST7789 chip, 240x240 pixels
This is documented in the graphicstest.ino example of the library.

setRowCol is a global setup for the display and not meant to be used for "local tweaking" like you did there to nudge text around.

Thanks for the great explanation. I'll give it a go!
 
Status
Not open for further replies.
Back
Top