I have several SPI displays running on ESP and Arduino using the TFT_eSPI library, this is working fine.
But I am trying to use an 8 bit display on an Arduino nano using the McuFriends library and can't get the basics working.
All I need are some lines of text with different fonts and displaying variables so the previous text must be erased.
It seems that this must be done with tft.fillRect(), so I tried to create several rectangles with the text but it doesn't work. The vertical size of the rectangles are not correct and the colours are wrong also. Google can't help me (once again)...
I have this display: https://ae01.alicdn.com/kf/HTB1FlyNKpXXXXaqXpXXq6xXFXXX2.jpg
The reported ID is 0x99
This is the sketch:
#include <Adafruit_GFX.h> // Core graphics library
#include <MCUFRIEND_kbv.h> // Hardware-specific library
MCUFRIEND_kbv tft;
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSans18pt7b.h>
#include <Fonts/FreeSans24pt7b.h>
#include <FreeDefaultFonts.h>
#define TFT_GREY 0x5AEB // Background color
#define Arial_9 &FreeSans9pt7b // Arial fonts
#define Arial_12 &FreeSans12pt7b
#define Arial_18 &FreeSans18pt7b
#define Arial_24 &FreeSans24pt7b
//#define GREY 0x5AEB // Background color
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
void setup(void)
{
//pinMode(70, OUTPUT); // Set SDA1 high to enable backlight on DUE
// digitalWrite(70, HIGH);
Serial.begin(9600);
uint16_t ID = tft.readID();
Serial.print("found ID = 0x");
Serial.println(ID, HEX);
if (ID == 0xD3D3) ID = 0x9481; //force ID if write-only display
tft.begin(ID);
tft.setRotation(0);
}
void loop(void)
{
int xpos = 0;
int ypos = 0;
tft.fillScreen(BLACK);
tft.setTextSize(2);
tft.setFont(0); // Header using standard font
tft.setTextColor(MAGENTA);
tft.fillRect(0, 0, 319, 29, BLUE);
tft.setCursor(100, 8); // Cursor is top of text for standard font
tft.print("Header");
tft.setTextColor(GREEN); // Set parameters for body
tft.setTextSize(1); // size for freefonts
tft.setFont(Arial_24);
tft.fillRect(0, 30, 319, 56, WHITE);
tft.setCursor(20, 70); // Cursor needs to be very low to fit in the rectangle
tft.print("A24_Ijg");
tft.setTextColor(GREEN);
tft.setTextSize(1); // size for freefonts //////////////////////////////
tft.setFont(Arial_12);
tft.fillRect(0, 57, 319, 71, CYAN);
tft.setCursor(20, 70);
tft.print("A12Ijg");
tft.setTextColor(GREEN);
tft.setTextSize(1); // size for freefonts //////////////////////////////
tft.setFont(Arial_12);
tft.fillRect(0, 200, 319, 214, YELLOW);
tft.setCursor(20, 213);
tft.print("A12Ijg");
delay(10000);
}
You're blanking the screen, putting up some info, then going to sleep for a long time, then redoing the same thing. I don't see the purpose of what you're doing.
Let's work with this little example for a minute:
tft.setCursor(20, 70);
tft.print("A12Ijg");
tft.setCursor(20, 70);
tft.print(" ");
Should blank that space. Are you saying it does not? Remember, the display remembers the last location it wrote to when you do a print, so you have to reset the cursor to the start of the place where the text is that you wish to blank.
Thanks for the reply.
The sketch needs to display parameters collected through UDP only once every minute, and couldn't get it to work. This why I made this very basic sketch.
Your example works, but I need variables and the code below doesn't work.
#include <Adafruit_GFX.h> // Core graphics library
#include <MCUFRIEND_kbv.h> // Hardware-specific library
MCUFRIEND_kbv tft;
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSans18pt7b.h>
#include <Fonts/FreeSans24pt7b.h>
#include <FreeDefaultFonts.h>
#define TFT_GREY 0x5AEB // Background color
#define Arial_9 &FreeSans9pt7b // Arial fonts
#define Arial_12 &FreeSans12pt7b
#define Arial_18 &FreeSans18pt7b
#define Arial_24 &FreeSans24pt7b
//#define GREY 0x5AEB // Background color
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
int text = 0;
void setup(void)
{
Serial.begin(9600);
uint16_t ID = tft.readID();
Serial.print("found ID = 0x");
Serial.println(ID, HEX);
if (ID == 0xD3D3) ID = 0x9481; //force ID if write-only display
tft.begin(ID);
tft.setRotation(0);
tft.invertDisplay(1);
tft.fillScreen(BLACK);
}
void loop(void)
{
tft.setTextColor(GREEN); // Set parameters for body
tft.setTextSize(1); // size for freefonts
tft.setFont(Arial_24);
tft.setCursor(40, 70);
tft.print(" "); // Erase previous text
tft.setCursor(40, 70);
tft.print(text);
delay(1000);
text++;
}
Writing spaces to the display will not work when the font is transparent, and proportional spaced fonts result in characters not having the same width as a space.
You can overwrite the text with a rectangle of the background color. The Adafruit library has a function for calculating the size of the rectangle from the text, but it is easier to just plan for the largest possible text.
A faster method is to erase the previous text by setting the text color to the background color and overwriting the text on the display, then set the text color back to normal and write the new text.
int text = 0;
int textPrevious;
void loop(void)
{
tft.setTextColor(GREEN); // Set parameters for body
tft.setTextSize(1); // size for freefonts
tft.setFont(Arial_24);
tft.setTextColor(BLACK);
tft.setCursor(40, 70);
tft.print(textPrevious); // Erase previous text
tft.setTextColor(GREEN);
tft.setCursor(40, 70);
tft.print(text);
textPrevious = text;
delay(1000);
text++;
}
I knew that and wanted to create rectangles just large enough to hold the text and then only fill the rectangle and rewrite the text when it has changed to minimize flickering, see post 1.
This didn't work, the rectangles were all wrong on the screen, there is probably something wrong
with the screen ID.
This is the shield:
And the output from LCD_ID_readnew:
07:58:19.638 -> Read Special Registers on MCUFRIEND UNO shield
07:58:19.678 -> controllers either read as single 16-bit
07:58:19.718 -> e.g. the ID is at readReg(0)
07:58:19.758 -> or as a sequence of 8-bit values
07:58:19.798 -> in special locations (first is dummy)
07:58:19.838 ->
07:58:19.838 -> diagnose any controller
07:58:19.878 -> reg(0x0000) 00 00 ID: ILI9320, ILI9325, ILI9335, ...
07:58:19.918 -> reg(0x0004) 00 00 80 00 Manufacturer ID
07:58:19.958 -> reg(0x0009) 00 00 61 00 00 Status Register
07:58:19.998 -> reg(0x000A) 00 08 Get Power Mode
07:58:20.038 -> reg(0x000C) 00 06 Get Pixel Format
07:58:20.088 -> reg(0x0030) 30 30 30 30 30 PTLAR
07:58:20.118 -> reg(0x0033) 33 33 33 33 33 33 33 VSCRLDEF
07:58:20.158 -> reg(0x0061) 61 61 RDID1 HX8347-G
07:58:20.198 -> reg(0x0062) 62 62 RDID2 HX8347-G
07:58:20.238 -> reg(0x0063) 63 63 RDID3 HX8347-G
07:58:20.278 -> reg(0x0064) 64 64 RDID1 HX8347-A
07:58:20.318 -> reg(0x0065) 65 65 RDID2 HX8347-A
07:58:20.318 -> reg(0x0066) 66 66 RDID3 HX8347-A
07:58:20.358 -> reg(0x0067) 67 67 RDID Himax HX8347-A
07:58:20.398 -> reg(0x0070) 00 09 Panel Himax HX8347-A
07:58:20.438 -> reg(0x00A1) 00 00 00 00 00 RD_DDB SSD1963
07:58:20.478 -> reg(0x00B0) B0 B0 RGB Interface Signal Control
07:58:20.558 -> reg(0x00B3) B3 B3 B3 B3 B3 Frame Memory
07:58:20.598 -> reg(0x00B4) B4 B4 Frame Mode
07:58:20.638 -> reg(0x00B6) B6 B6 B6 B6 B6 Display Control
07:58:20.678 -> reg(0x00B7) B7 B7 Entry Mode Set
07:58:20.718 -> reg(0x00BF) BF BF BF BF BF BF ILI9481, HX8357-B
07:58:20.758 -> reg(0x00C0) C0 C0 C0 C0 C0 C0 C0 C0 C0 Panel Control
07:58:20.798 -> reg(0x00C1) C1 C1 C1 C1 Display Timing
07:58:20.838 -> reg(0x00C5) C5 C5 Frame Rate
07:58:20.878 -> reg(0x00C8) C8 C8 C8 C8 C8 C8 C8 C8 C8 C8 C8 C8 C8 GAMMA
07:58:20.958 -> reg(0x00CC) CC CC Panel Control
07:58:20.958 -> reg(0x00D0) D0 D0 D0 D0 Power Control
07:58:20.998 -> reg(0x00D1) D1 D1 D1 D1 VCOM Control
07:58:21.038 -> reg(0x00D2) D2 D2 D2 Power Normal
07:58:21.088 -> reg(0x00D3) D3 D3 D3 D3 ILI9341, ILI9488
07:58:21.158 -> reg(0x00D4) D4 D4 D4 D4 Novatek
07:58:21.158 -> reg(0x00DA) 00 00 RDID1
07:58:21.198 -> reg(0x00DB) 00 80 RDID2
07:58:21.238 -> reg(0x00DC) 00 00 RDID3
07:58:21.238 -> reg(0x00E0) E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 GAMMA-P
07:58:21.318 -> reg(0x00E1) E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 GAMMA-N
07:58:21.398 -> reg(0x00EF) EF EF EF EF EF EF ILI9327
07:58:21.438 -> reg(0x00F2) F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 Adjust Control 2
07:58:21.518 -> reg(0x00F6) F6 F6 F6 F6 Interface Control
I got it working now, didn't realize that the origin x-y coordinates of the rectangle were absolute and the second ones relative to the origin.
Aligning text in those rectangles can be done but it's very complicated with those Adafruit GFX fonts. Their function for calculating the size of the rectangle from the text is a possibility but I don't have the time right now to try it.
I will try your suggestion to save the old text and erase it before writing a new one.
It works quite well for my purpose. But I'm not playing with fonts or graphics, I just wanted a 21-charx8 line display for a small debugging screen; my other option was a 20x4 LCD for 2x the cost, 3x the real estate. I use a simpler library(ss_oled), with only 2 fonts, and I may eventually strip the larger of the two.
I was struggling with this problem a few weeks ago and surprisingly, the "blanking rectangle" method was faster. At least, it resulted in less flicker.
IIRC, I settled on using writing to a GFXCanvas and then writing that canvas to the screen. That gave the best results.
Since then, I gave up on my mcufriend displays and switched to TFT_eSPI and an ESP32 and my problems are gone
@camsysca : I need several nice looking displays to put on a desk, table or wall. With some nice fonts and a bit of colour.
I just tried to get some text on the screen but aligning is difficult. I am aware of that "canvas" option but it seems complicated especially because I have already 2 SPI lcd's on a simple ESP8266MOD module with TFT_eSPI and this works great.
Took the same decision a while ago and ordered another SPI display. Bodmer's TFT_eSPI library is so easy to create a nice looking display: Automatic centering of text, his free font is great and supports the degree sign, erasing text is no problem, etc..
There is another reason for my decision to use ESP: A LCD shield blocks access to other IO pins that I need (SPI for ethernet, ...) so an additional in between shield is needed creating an ugly stack of boards.
Would an 8bit LCD work on a ESP32? I know that TFT_eSPI supports 8bit display's but I have no idea of the speed.
Assuming you have enough pins available, I think it will. ISTR that there is some mention of configuring an ESP32 for parallel output with TFT_eSPI in UserSetup.h
Haven't tried it, but I do have my parallel mcufriend displays working on an Adafruit Metro M0 Express, which is a SAMD21 processor.
The other reason I gave up on the mcufriend is that I wanted to play around with LVGL which requires far more resources but renders beautiful displays. Even the SAMD21 didn't have enough RAM for it, so I had to use the ESP.