Forum Rule: Always post complete source code & details to reproduce any issue!
Page 27 of 27 FirstFirst ... 17 25 26 27
Results 651 to 673 of 673

Thread: Highly optimized ILI9341 (320x240 TFT color display) library

  1. #651
    Junior Member
    Join Date
    Sep 2022
    Posts
    5
    Hello,
    I'm new with this library and I found it impressive so far. I'm converting the code to use in a Bluepill (STM32F103C8), all the graphics works pretty well, but I'm stuck in the fonts. I checked all the source code in the repository https://github.com/PaulStoffregen/ILI9341_t3, in the examples and fonts but I didn't find the source code for the function "print".
    For example, in this code:
    Code:
        tft.setTextColor(ILI9341_YELLOW);
        tft.setFont(Arial_18);
        tft.setCursor(98, 42);
        tft.print("waiting for");
    Everything is there, except the "print".
    Can someone help pointing me in the right direction to find that source code?
    Thanks a lot!

  2. #652
    Senior Member
    Join Date
    Aug 2018
    Location
    Brisbane, Australia
    Posts
    185
    Code:
    class ILI9341_t3 : public Print
    Look for Print.h and Print.cpp in cores/<model>

  3. #653
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,781
    In my own version of the library (ili9341_t3n), it is also derived from Print

    The Print class has a couple of virtual functions which I overwrite:
    Code:
      // overwrite print functions:
      virtual size_t write(uint8_t);
      virtual size_t write(const uint8_t *buffer, size_t size);
    The first one is mandatory, that is I believe it is defined as a pure virtual in the base class.
    The second one is optional; default is to simply iterate over the array passed in and call the single char method.

    Note: my version also supports the Adafruit fonts as well as the ILI9341 fonts...

  4. #654
    Junior Member
    Join Date
    Sep 2022
    Posts
    5
    Thanks guys,
    I found the source code at https://github.com/arduino/ArduinoCo.../cores/arduino
    Also I created my own version of the "print" function in pure C:

    Code:
    int16_t ILI9341_t3_print(char *string)
    {
        int16_t n = 0;
        while (1) {
            if (string[n] == 0) break;
            if (ILI9341_t3_write(string[n])) n++;
            else break;
        }
        return n;
    }

  5. #655
    Junior Member
    Join Date
    Sep 2022
    Posts
    5
    Hello,
    That's me again
    Am I wrong or the function drawFontBits(), from https://github.com/PaulStoffregen/IL...1_t3.cpp#L1657, does not apply background color?
    I'm trying to use
    Code:
    print("     ");
    to clear the text but it's not working.
    Did I forgot something?
    Thanks again.

  6. #656
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,781
    Hi Chuckero,

    Maybe I am missing something, but I believe that you are trying to adapt this code to some other platform STM32F103C8, which is fine as the code is all open source.

    However, I am wondering if you might be better off starting with the Adafruit code base:
    https://github.com/adafruit/Adafruit_ILI9341
    which uses their library: https://github.com/adafruit/Adafruit-GFX-Library

    And I believe they already have some support for at least some STM32 boards.

    The font drawing code in most of our libraries, support both transparent and opaque text drawing.
    This is controlled by the call: void setTextColor(uint16_t c, uint16_t bg);
    if you call this with 2 parameters: the first is the foreground color the second is background color, it will use the bg color to fill in.
    If you call this with 1 parameter, it will draw transparent and leave whatever was in the background.

  7. #657
    Junior Member
    Join Date
    Sep 2022
    Posts
    5
    Hello KurtE, thanks for your comments.

    At this point I can not start or restart with Adafruit code base, as I already have done 95% of the work. All the communications with the LCD are done, all graphics are working perfectly and the text is also working, except the text background.

    So, at this point I think I'm not using the last version of the library, or something is missing in somewhere, or I'm lost in all these thousands of lines...

    With the code I got from GitHub, I was checking...

    At the start:
    Code:
    font = NULL;
    Then we set the font:
    Code:
    tft.setFont(Arial_18);
    tft.setTextColor(ILI9341_YELLOW);
    And we print something:
    Code:
    tft.setCursor(20, 20);
    tft.print("Test");
    The function print(), calls the function write() for each character.
    Inside the function write() (https://github.com/PaulStoffregen/IL...1_t3.cpp#L1284) there is a test that checks if the variable font is set or not, if yes, then it calls the function drawFontChar() which is the function that prints the custom fonts, otherwise, the function drawChar() is called, which is responsible to print the standard 5x8 font.

    The function drawChar(), for the regular 5x8 font, can use background colors and transparent mode (https://github.com/PaulStoffregen/IL...1_t3.cpp#L1312).

    But the function drawFontChar() for custom fonts does not use background color at all (https://github.com/PaulStoffregen/IL...1_t3.cpp#L1472).

    I'm afraid to change something in that code because, maybe it's not the last version and I can loose time working on something already fixed, and that code is not simple to change it in just a few hours.

    Can you please, take a look on that, just to make sure if my reasoning is correct.

    Thanks again.

  8. #658
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,781
    Yes, it looks like this did not get integrated into here, from my extensions in my own version of the library.
    https://github.com/kurte/ili9341_t3n

    You will see in my version: there are two parts to that function:
    https://github.com/KurtE/ILI9341_t3n..._t3n.cpp#L3581

  9. #659
    Junior Member
    Join Date
    Sep 2022
    Posts
    5
    Now that make sense. I'll check your implementation.
    Thanks KurtE!

  10. #660
    Junior Member
    Join Date
    Nov 2022
    Posts
    3
    Hello,
    I am trying to figure out what the length of pixels are being written on the display. I am working on a gauge that creates tick marks based off degrees and write the degree values at each tick mark. The problem is that I need to find the center of each of these numbers so they can be offset in the X coord's. any help would be great. here is the code that I am working with.

    ////////////////////////////////////////// Includes Information //////////////////////////////////////////
    #include "SPI.h"
    #include "font_Arial.h"
    #include "ILI9341_t3.h"

    ////////////////////////////////////////// Connections Gauge 1 //////////////////////////////////////////
    #define TFT1_DC 9
    #define TFT1_CS 10
    #define TFT1_RST 255 // 255 = unused, connect to 3.3V
    #define TFT1_MOSI 11
    #define TFT1_SCLK 13
    #define TFT1_MISO 12
    ILI9341_t3 tft1 = ILI9341_t3(TFT1_CS, TFT1_DC, TFT1_RST, TFT1_MOSI, TFT1_SCLK, TFT1_MISO);

    ////////////////////////////////////////// int variables //////////////////////////////////////////
    int TFT_Reset = 24; // tft reset pin
    int StartDeg = 45; // gauge start degrees
    int EndDeg = 315; // gauge end degrees
    int Ltickdegrees = 45; // long tick mark degrees
    int line_OD = 120; //OD of outside radius in pixels
    int tll = 15; //length of the large tick marks
    int longtickcolorS = ILI9341_WHITE; // color of long tick mark
    int textcolorS = ILI9341_WHITE; // color of gauge text values
    int textcolorG = ILI9341_BLUE; // color of gauge name text
    int Xstart = 160; // start of X line start in pixels
    int Ystart = 120; // start of Y line start in pixels
    int gts = 2; // gauge name text size
    int ts = 2; //gauge values text size
    String gname = "GAUGE"; //gauge name



    void setup() {

    //////////////////////////////////////////////////////////////////// Display 1 Start up ////////////////////////////
    pinMode(TFT_Reset, OUTPUT);
    digitalWrite(TFT_Reset, HIGH);
    delay(500);
    tft1.begin();
    tft1.setRotation(1);
    tft1.fillScreen(ILI9341_BLACK);

    //////////////////////////////////////////////////////////////////// Draw numbers or names on degrees ////////////////////////////
    for (int i = StartDeg; i < (EndDeg + 1); i += Ltickdegrees)
    {
    // start drawing the gauge tick marks
    float sx = cos((i - 270) * 0.0174532925); // Coodinates of X tick line to draw
    float sy = sin((i - 270) * 0.0174532925); // Coodinates of Y tick line to draw
    float x0 = sx * (line_OD - tll) + Xstart; // tick mark start in pixels
    float y0 = sy * (line_OD - tll) + Ystart; // tick mark start in pixels
    float x1 = sx * line_OD + Xstart; // tick mark end in pixels
    float y1 = sy * line_OD + Ystart; // tick mark end in pixels
    tft1.drawLine(x0, y0, x1, y1, longtickcolorS); // Draw tick marks
    // start drawing the gauge numbers
    float x2 = sx * ((line_OD - tll)- 25) + Xstart; // text start in pixels
    float y2 = sy * ((line_OD - tll)- 25) + Ystart; // text mark start in pixels
    tft1.setTextColor(textcolorS); // standard tick mark colors
    tft1.setTextSize(ts); // set gauge number text size
    tft1.setCursor((x2-10), y2-10); // place cursor for writing text
    tft1.println(i-45); // -45 is the offset for the displayed value of tick mark
    delay(250); // delay to slow disply startup drawing
    }

    //////////////////////////////////////////////////////////////////// Draw Gauge Name ////////////////////////////
    tft1.setTextColor(textcolorG); // Gauge text color
    tft1.setTextSize(gts); // gauge text size
    int length = gname.length(); // place gauge "string" name into variable
    length = ((length * 6)*gts); //length of text in pixels
    length = length/2; //divide the length of pixels by two to find center offset value
    tft1.setCursor((Xstart - length), 200); //place cursor for writing text
    tft1.print(gname); //print gauge name
    }

    void loop()
    {
    }

  11. #661
    Senior Member
    Join Date
    Aug 2018
    Location
    Brisbane, Australia
    Posts
    185
    Did you try calling measureTextWidth() / measureTextHeight() to retrieve the bounds of the rendered text?

  12. #662
    Junior Member
    Join Date
    Nov 2022
    Posts
    3
    thebigg,
    I did try. But I was not understanding how to use the call. could you help with an example of how to use the call

  13. #663
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,376
    Code:
    ////////////////////////////////////////// Includes Information //////////////////////////////////////////
    #include "SPI.h"
    #include "font_Arial.h"
    #include "ILI9341_t3.h"
    
    ////////////////////////////////////////// Connections Gauge 1 //////////////////////////////////////////
    #define TFT1_DC 9
    #define TFT1_CS 10
    #define TFT1_RST 255 // 255 = unused, connect to 3.3V
    #define TFT1_MOSI 11
    #define TFT1_SCLK 13
    #define TFT1_MISO 12
    ILI9341_t3 tft1 = ILI9341_t3(TFT1_CS, TFT1_DC, TFT1_RST, TFT1_MOSI, TFT1_SCLK, TFT1_MISO);
    
    ////////////////////////////////////////// int variables //////////////////////////////////////////
    int TFT_Reset = 24; // tft reset pin
    int StartDeg = 45; // gauge start degrees
    int EndDeg = 315; // gauge end degrees
    int Ltickdegrees = 45; // long tick mark degrees
    int line_OD = 120; //OD of outside radius in pixels
    int tll = 15; //length of the large tick marks
    int longtickcolorS = ILI9341_WHITE; // color of long tick mark
    int textcolorS = ILI9341_WHITE; // color of gauge text values
    int textcolorG = ILI9341_BLUE; // color of gauge name text
    int Xstart = 160; // start of X line start in pixels
    int Ystart = 120; // start of Y line start in pixels
    int gts = 2; // gauge name text size
    int ts = 2; //gauge values text size
    String gname = "GAUGE"; //gauge name
    
    
    
    void setup() {
    
    	//////////////////////////////////////////////////////////////////// Display 1 Start up ////////////////////////////
    	pinMode(TFT_Reset, OUTPUT);
    	digitalWrite(TFT_Reset, HIGH);
    	delay(500);
    	tft1.begin();
    	tft1.setRotation(1);
    	tft1.fillScreen(ILI9341_BLACK);
    
    	//////////////////////////////////////////////////////////////////// Draw numbers or names on degrees ////////////////////////////
    	for (int i = StartDeg; i < (EndDeg + 1); i += Ltickdegrees)
    	{
    		// start drawing the gauge tick marks
    		float sx = cos((i - 270) * 0.0174532925); // Coodinates of X tick line to draw
    		float sy = sin((i - 270) * 0.0174532925); // Coodinates of Y tick line to draw
    		float x0 = sx * (line_OD - tll) + Xstart; // tick mark start in pixels
    		float y0 = sy * (line_OD - tll) + Ystart; // tick mark start in pixels
    		float x1 = sx * line_OD + Xstart; // tick mark end in pixels
    		float y1 = sy * line_OD + Ystart; // tick mark end in pixels
    		tft1.drawLine(x0, y0, x1, y1, longtickcolorS); // Draw tick marks
    		// start drawing the gauge numbers
    		float x2 = sx * ((line_OD - tll) - 25) + Xstart; // text start in pixels
    		float y2 = sy * ((line_OD - tll) - 25) + Ystart; // text mark start in pixels
    		tft1.setTextColor(textcolorS); // standard tick mark colors
    		tft1.setTextSize(ts); // set gauge number text size
    		tft1.setCursor((x2 - 10), y2 - 10); // place cursor for writing text
    		tft1.println(i - 45); // -45 is the offset for the displayed value of tick mark
    		delay(250); // delay to slow disply startup drawing
    	}
    
    	//////////////////////////////////////////////////////////////////// Draw Gauge Name ////////////////////////////
    	tft1.setTextColor(textcolorG); // Gauge text color
    	tft1.setTextSize(gts); // gauge text size
    	int length = gname.length(); // place gauge "string" name into variable
    	length = ((length * 6) * gts); //length of text in pixels
    	length = length / 2; //divide the length of pixels by two to find center offset value
    	tft1.setCursor((Xstart - length), 200); //place cursor for writing text
    	tft1.print(gname); //print gauge name
    }
    
    void loop()
    {
    }
    Can you please enclose any posted code between CODE tags using the # button at the top of the post form.
    It presents your work in a much more readable and understandable manner making it much easier for people to help you.

  14. #664
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,781
    Note: there is additional stuff in my version of the library: https://github.com/KurtE/ILI9341_t3n

    The code has the concept of center,
    Where you can output a string and have it centered at the center of the screen:
    or specific X and center y, or center x and specific y...

    Also it has an extra parameter on setCursor which says center the text here:

    like:
    Code:
      tft.setCursor(width / 2, height - 30, true);
      tft.print("Center");
    The true says to center. Note the centering only works for one output, after that the text cursor will be at the end of that output.

    The example ILI_Ada_fontTest4 in my library shows exampls of this in function: displayStuff1

    Note: Several of the display libraries that ship with Teensydunio I believe we added this stuff... But I don't think it made it back into the ILI9341_t3 library.

    But to do it manual:
    With ILI9341_t3, I believe the functions are as thebigg mentioned:
    Did you try calling measureTextWidth() / measureTextHeight() to retrieve the bounds of the rendered text?
    If you want the text centered at some location: x, y
    then something like:

    int text_width = tft.measureTextWidth("45");
    int text_height = tft.measureTextHeight("45");
    tft.setCursor(x - (text_width/2), y - (text_height / 2));
    tft.print("45");

    Assuming you want it centered at that spot... May have to fudge

    With ILI9341_t3n and some of the others we have:
    Code:
      void getTextBounds(const uint8_t *buffer, uint16_t len, int16_t x, int16_t y,
                         int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
      void getTextBounds(const char *string, int16_t x, int16_t y, int16_t *x1,
                         int16_t *y1, uint16_t *w, uint16_t *h);
      void getTextBounds(const String &str, int16_t x, int16_t y, int16_t *x1,
                         int16_t *y1, uint16_t *w, uint16_t *h);
      int16_t strPixelLen(const char *str, uint16_t cb=0xffff);  // optional number of characters...
    Looks like the only example showing that is in the Kurts_ILI9341_t3n_FB_and_clip_test.ino.
    Or like in the main libary .cpp file and see how it is used in the Centering code mentioned above.

    The idea of these functions, is you pass in your string as well as where maybe you would be drawing it, or 0, 0 if you will compute that from this data.
    And you pass in pointers to x, y, w, h to retrieve the bounding rectangle for where the text would output. Note, there are some characters in some fonts, that
    may bias the text t0 actually output some pixels offset in the negative direction...

  15. #665
    Junior Member
    Join Date
    Nov 2022
    Posts
    3
    Thanks for all the help. I have it working now.

  16. #666
    Hey everyone, since i´m an absolute noob when it gets to programming, i´m wondering if there was a super easy example for a DMA approach?!
    I dont even know if its possible since i could not find an example for my needs
    What i would like to have is
    one framebuffer to work with (dont know if thats possible)
    and a simple sketch, where i dont know, the display shows the integers from 0-9 or so, so really super simple
    Maybe someone can explain, when to update the screen or other important details i have to look at

    Since i´m completly out of any insights to DMA i really would love to get some tipps from you

    TIA Stefan

  17. #667
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,781
    Try looking at my ILI9341_t3n https://github.com/kurte/ili9341_t3n
    There is also: https://github.com/vindar/ILI9341_T4

  18. #668
    Hello Kurt,

    thank you for your answer. Yes i know your libs, but somehow i was not able to find an easy example how to use one dma framebuffer.
    Maybe you can point to an example you´ve done, that would be very cool
    danke aus wien
    cheers stefan

  19. #669
    I am using ILI9488_t3.h and it works.

    However tft.print(); wont delete the old value.
    ChatGTP always provides examples with tft.fillScreen(BACKGROUND_COLOR); to delete the old value but what would be a more elegant way to show e.g an ADC value or other fast changing values?
    Filling the background also makes the TFT flickering.

  20. #670
    Senior Member
    Join Date
    Sep 2021
    Posts
    239
    Write the same value with color = background-color

  21. #671
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,781
    There are several ways to do it.
    With out flickering:

    1) You can use the frame buffer.
    With this you could erase the whole screen, draw everything and then do an updateScreen() call which will then do a redraw of the whole screen...

    2) Use Opaque text output, this will overwrite the things in the text rectangle that are not in the character with the selected background color.

    That is something like:

    Code:
    tft.setTextColor(WHITE, BLACK); // set the text color to white and the Background to black. 
    tft.setCursor(20, 20); // set the cursor
    tft.print(val, DEC);
    Warning, typing on the fly and not worrying about being fully correct, like WHITE or BLACK need to be whatever the colors are for the display you are using...

    Now this should in most cases cover up the bits and pieces of the characters it overwrote.

    But if for example your Analog value was 325 and dropped to 50, the code above would only overwrite the 32 and not the 5..

    A couple ways to handle this.

    a) Cheat, if nothing is going to display directly to the right of this, simply add something like:
    Code:
    tft.print("   ");
    After the tft.print of the value. and hopefully cover up everything from previous output, without flicker.

    b) blank out after text output, until end of field..

    Code:
    uint16_t cx = tft.getCursorX();
    fillRect(cx, 20, FIELD_SIZE - cx, 10, BLACK); // might have to play with these values, like the 10 for height, depends on font size...
    c) like b, except remember the last cx_ and only blank from new cx to last cx...
    Code:
    uint16_t last_cx = 0;
    ...
    uint16_t cx = tft.getCursorX();
    
    if (cx < last_cx) fillRect(cx, 20, last_cx - cx, 10, BLACK); // might have to play with these values, like the 10 for height, depends on font size...
    last_cx = cx;
    Probably lots of other ways as well.

  22. #672
    Hello
    thank you for your answers, i know the trick of writing the old value with the background color, but since i have to draw a lot of different stuff, i think framebuffer will do the job best for me.

    the question is, is there an easy to follow example for one framebuffer or do i have to use 2 buffers?

  23. #673
    I used the framebuffer option with tft.updateScreenAsync(false); and It works fine. Thanks for your help!

    However if I try to update the screen with a higher rate than ~7hz horizontal lines appear on the screen. Is this normal or a limitation by the LCD hardware?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •