Is there another way to print float if using fonts without blinking and stacking

I know this is a stupid question, but this makes me curious

Is there another way to print float if using fonts without blinking and stacking?
I use Arduino Mega 2560

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPFD54124B.h>

#include <Fonts/FreeSevenSegNumFontPlusPlus.h>;
#include <Fonts/FreeMono9pt7b.h>;

#define TFT_CS      33
#define TFT_RESET  32
#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE           0xFFFF
#define GREY            0x7BEF
#define SCR_WD   128
#define SCR_HT   161

float A = 0;
int B = 0;

Adafruit_SPFD54124B display(TFT_RESET, TFT_CS); 

void setup(void) 
{

display.begin();
display.setRotation(1);
display.fillScreen(BLACK);
}


void loop()
{
  
  A = A+0.01;
//B++;
  //display.setFont(&FreeMono9pt7b);
  display.setFont(&FreeSevenSegNumFontPlusPlus);
  display.setCursor(20, 50);
  display.setTextColor(RED,BLACK);
  display.setTextSize(1);
  display.print(A);
//display.print(B);
//display.fillScreen(BLACK);
  delayMicroseconds(10);

}
  • characters look good if they don’t use fonts and without fiilScreen in loop
  • if i use font and fillScreen in loop, the character looks blinking VIDEO
  • if i use font and without fillScreen in loop, the previous character is not erased by the new character, so it looks stacked VIDEO

and how is the right way?
thanks, teddy

I am responsible for posting FreeSevenSegNumFontPlusPlus.h

You should only draw background colour for the minimal rectangle. i.e. fillRect() not fillScreen()
You can keep track of the digits. And just draw a changed digit.

Alternatively, you can treat the digits as separate bitmaps in Flash. Draw with drawBitMap(x, y, icon, w, h, color, bg)

Obviously not as convenient as print(number) but you only have to write the helper function once.

David.

thank you for the direction sir, I tried to use display.fillRect (0,0,140.50, BLACK), the blink frequency is slightly reduced, but I think it is not perfect.
cause i am very beginner in programming, i am not very good at what you mean by
Alternatively, you can treat the digits as separate bitmaps in Flash. Draw with drawBitMap(x, y, icon, w, h, color, bg)
willing you can give a little sample code

thanks, teddy

Here is an example. Obviously it is only tested with ST7735 but should work with any Adafruit_GFX style hardware libraries. Just change the #include, constructor() and begin() statements.

You can see that digits can be drawn fairly fast if you do them one at a time.
But sending a printable string e.g. “12.34” is less work.

#include <SPI.h>
#include <Adafruit_GFX.h>
//#include <Adafruit_ST7735.h>
#include <Adafruit_SPFD54124B.h>
#include "SevenSegNumFontPlusPlus.h"  //local tab

#define TFT_CS      33
#define TFT_RESET   32
//Adafruit_ST7735 display(10, 9, 8); //TFT_CS, TFT_DC, TFT_RESET
Adafruit_SPFD54124B display(TFT_RESET, TFT_CS);

#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE           0xFFFF
#define GREY            0x7BEF

void setup(void)
{
    //display.initR(INITR_BLACKTAB);  //for ST7735
    display.begin();  //for SPFD54128
    display.setRotation(1);
    display.fillScreen(BLACK);
}

int draw7seg(int x, int y, char c)
{
    const uint8_t *p = SevenSegNumFontPlusPlus;
    uint8_t w = pgm_read_byte(p + 0);
    uint8_t h = pgm_read_byte(p + 1);
    uint8_t first = pgm_read_byte(p + 2);
    uint8_t n = pgm_read_byte(p + 3);
    if (c == ' ') c = '/';  //the weird SevenSegNumFontPlusPlus uses '/'
    //numeric fonts might have range -,+./01234569: but no space
    if (c == ' ') {     //space is not in this font
        display.fillRect(x, y, w, h, GREY);
        return w;
    }
    if (c < first || c >= first + n) return 0; //out of range
    int ofs = (c - first) * (((w + 7) / 8) * h); //offset in bitmap
    display.drawBitmap(x, y, p + 4 + ofs, w, h, BLUE, GREY);
    return w;
}

int draw7seg_str(int x, int y, char *s)
{
    char c;
    int len = 0;
    while (c = *s++) {
        len += draw7seg(x + len, y, c);
    }
    return len;
}

void loop()
{
    int x = 20, y = 10, w = 32;
    char buf[10];
    for (int unit = '0'; unit < '5'; unit++) {
        draw7seg(x + w * 0, y, unit);
        draw7seg(x + w * 1, y, '.');
        for (int dec1 = '0'; dec1 <= '9'; dec1++) {
            draw7seg(x + w * 2, y, dec1);
            for (int dec2 = '0'; dec2 <= '9'; dec2++) {
                draw7seg(x + w * 3, y, dec2);
            }
        }
        for (float f = 5.00; f < 25.00; f += 0.87) {
            dtostrf(f, 4, 1, buf);
            draw7seg_str(5, 70, buf);
        }
        delay(1000);
    }
}

SevenSegNumFontPlusPlus.h (16.3 KB)

true with what you say "Obviously not as comfortable as printing (numbers)", therefore for this case I have not been able to think further to solve it, and I have to study it again.

after I try, the display clearly does not blink, only the movement of numbers is not as fast without using fonts, i think the lcd driver is not compatible with fast movement.

on another day I will try to use another type of LCD that is possible.

but thank you for the time you take.

I posted a way to use the standard Adafruit_GFX methods.
I don't have your hardware. I had never heard of the SPFD54124B.

As far as I can see, "Adafruit_SPFD54124B.h" was not written by Adafruit. It just inherits from Adafruit_GFX like a lot of other hardware libraries.

I don't think that any other library or person supports this controller.

Of course, I could use the SPFD54124B hardware to make it faster. I don't have the hardware and you are probably not prepared to provide any testing.

One reader downloaded the H file. This was done several days ago. Was it you?

David.

Before printing a number, print an '8' in black. This will hide any old value you had then print the number you want.

-jim lee

[/quote]

david_prentice:
I posted a way to use the standard Adafruit_GFX methods.
I don't have your hardware. I had never heard of the SPFD54124B.

As far as I can see, "Adafruit_SPFD54124B.h" was not written by Adafruit. It just inherits from Adafruit_GFX like a lot of other hardware libraries.

I don't think that any other library or person supports this controller.

Of course, I could use the SPFD54124B hardware to make it faster. I don't have the hardware and you are probably not prepared to provide any testing.

One reader downloaded the H file. This was done several days ago. Was it you?

David.

yes, i downloaded
SevenSegNumFontPlusPlus.h and copy it into the font folder inside adafruit library

That will be similar to fillRect(BLACK). Although the SevenSeg font has a lot of background fillRect() is much more efficient.

The OP was upset by seeing a "blink" as the background was painted.
Hence the drawBitmap() suggestion. Slow but less visually distressing.

David.

jimLee:
Before printing a number, print an '8' in black. This will hide any old value you had then print the number you want.

-jim lee

Alright, I'll try later, thank you

david_prentice:
That will be similar to fillRect(BLACK). Although the SevenSeg font has a lot of background fillRect() is much more efficient.

The OP was upset by seeing a "blink" as the background was painted.
Hence the drawBitmap() suggestion. Slow but less visually distressing.

David.

I will replace the type of LCD with a new one, and certainly different library too, to ascertain its constraints, whether from the LCD driver or my inability to think

@JimLee,

Drawing an “8” in background colour works very well. You get much faster performance than the multi-character drawBitnap().

    ...
    display.setFont(&FreeSevenSegNumFontPlusPlus);
        ...
        for (float f = 15.00; f < 25.00; f += 0.87) {
            dtostrf(f, 4, 1, buf);
            display.setCursor(5, 120);
            display.setTextColor(BLACK); //or background colour
            display.print("88.8");
            display.setCursor(5, 120);
            display.setTextColor(RED);
            display.print(buf);
        }
        ...

You can obviously insert some intelligence into the “string” function e.g. by keeping a copy of the current string and only re-drawing the changed digits.
In practice, this would look like my top #.## output. i.e. very fast for a single digit which is the most common situation.

However the bottom ##.# output deliberately makes 3 digits change in every loop. And the period does not cost much to print.

If you are really “intelligent” you would only re-draw the segments that change.

David.

Cool! Glad I could help.

-jim lee