Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 14 of 14

Thread: How to have fast text with ILI9340 LCD?

  1. #1

    How to have fast text with ILI9340 LCD?

    Hello:

    I am using a 2.2" LCD (ILI9340). I have a simple sketch which I use to display very fast text. However, all I see are white squares. Is this a limitation of this display? This works on a character LCD.

    Here is my code:


    void loop() {
    count = count + 1;
    tft.setCursor(0, 0);
    tft.setTextColor(ILI9340_WHITE); tft.setTextSize(3);
    tft.print(count);
    delay (3);
    }
    I realize I can use a longer delay but that would be unacceptable in my full sketch.

    Thanks.

  2. #2
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,558
    The time consuming and always identical setTextColor and setTextSize can be done in setup(), no need to re-iterate these each loop().
    But still then, you’ll get all numbers printed one above the other, you’ll have always to clear the affected screen area before printing the next value.
    Even if there are understandable reasons for actualizing the display often and quickly, don’t forget that the human eye does not catch up with refresh rates > 25Hz, which means that it is sufficient to update the display every 40ms. To not waist CPU time by using the blocking delay(), I’d rather use an intervalTimer object to trigger the display update at these regular intervals, while the loop() might continue doing more important work in the meantime.

  3. #3
    Thank you @ Theremingenieur. Certainly good advice.

    I changed the code to the one below, but I am still getting numbers written on top of one another even with a long delay. I guess I do not know how does one clear the "...clear the affected screen area"?

    Here is my current code:

    void loop() {
    tft.setCursor(0, 0);
    tft.println(" ");
    tft.setCursor(0, 0);
    count = count + 1;
    tft.print(count);
    delay (2000);
    }

  4. #4
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,564
    Quote Originally Posted by Theremingenieur View Post
    Even if there are understandable reasons for actualizing the display often and quickly, donít forget that the human eye does not catch up with refresh rates > 25Hz, which means that it is sufficient to update the display every 40ms. To not waist CPU time by using the blocking delay(), Iíd rather use an intervalTimer object to trigger the display update at these regular intervals, while the loop() might continue doing more important work in the meantime.
    Alternatively to interval timer one could use


    Code:
    void loop() {
      count = count + 1;
    
      // update TFT
      static uint32_t t0=0;
      uint32_t t1=milis();
      if(t1-t0>40) // maybe 20 (50 Hz update rate)?
      {
        tft.print(count);
        t0=t1;
      }
      // do other stuff
    }

  5. #5
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,558
    Quote Originally Posted by jimmie View Post
    Thank you @ Theremingenieur. Certainly good advice.

    I changed the code to the one below, but I am still getting numbers written on top of one another even with a long delay. I guess I do not know how does one clear the "...clear the affected screen area"?
    Two possible variants:
    a) "Gross": Draw a filled rectangle of appropriate size but not larger than needed to save time and CPU cycles in the background color (I guess black) just before printing the next numeric value.
    b) "Delicate": Print the old numeric value again at the same coordinates, but in background color, just before printing the new value.

    Understand that in opposite to a lcd matrix, the tft is pixel based and not character based. Thus you have basically to "kill" every drawn pixel before drawing something new in the same area.

    symbolic example code for solution b)
    Code:
    void loop() {
    tft.setTextColor(backgroundColor);
    tft.setCursor(0,0);
    tft.print(count);
    tft.setTextColor(foregroundColor);
    tft.setCursor(0,0);
    count +=1;
    tft.print(count);
    delay(whatever);
    }
    Last edited by Theremingenieur; 06-21-2017 at 06:36 AM.

  6. #6
    Thank you @WMXZ. Certainly using millis will avoid using delay but the problem remains, namely the numbers are written on top of one another. In other words, the first line is not cleared prior to writing new data (and I do not know how to do it).

    Here is my current code:

    void loop() {
    tft.setCursor(0, 0);
    count = count + 1;

    // update TFT
    static uint32_t t0=0;
    uint32_t t1=millis();
    if(t1-t0>40) // maybe 20 (50 Hz update rate)?
    {
    tft.print(count);
    t0=t1;
    }
    // do other stuff
    }

  7. #7
    Thank you again @Theremingenieur.

    Indeed, you did remind me. A few years ago, I used successfully drawing a filled rectangle. I will try your "delicate" method now.

  8. #8
    Thank you again @Theremingenieur.

    Your "Delicate" method worked the best. I appreciate it.

  9. #9
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,564
    Quote Originally Posted by jimmie View Post
    Thank you @WMXZ. Certainly using millis will avoid using delay but the problem remains, namely the numbers are written on top of one another. In other words, the first line is not cleared prior to writing new data (and I do not know how to do it).
    I did not address the overwrite but suggested a 'timed' version that does not need a timer object.
    If in setup you clear the whole screen, or at least the areas where you plan to write continuously, then you are fine.
    Also you could the write field initialize with some values (e.g. 0) then you can use the 'delicate' method.

  10. #10
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,324
    I won't mention about how often you update or the like as that was mentioned earlier...

    @Theremingenieur solution should work as would a simple fillrect/fillscreen - But potentially the user will see flashes as first the text is erased (drawn in background color) and then redrawn in FG color with new number.

    Another solution might be to use drawing the text in Opaque mode. That is something like:

    Code:
    void loop() {
        count = count + 1;
        tft.setCursor(0, 0);
        tft.setTextColor(ILI9340_WHITE, ILI0340_BLACK);   // set text color for FG and BG color
        tft.setTextSize(3);
        tft.print(count);
        delay (3);
    }
    Note: the above may be sufficient for you, but if your text output is shorter than previous ones than text to the right is not overwritten... I have solved this a couple of different ways.
    a) If you know that there is nothing to the right of your field and lets say you know the number will take 1-3 digits to output, then simply output a couple of spaces after the
    number to possibly overwrite any previous digits.

    b) Use fill rect to clear out anything to the right of your new output. That is if you know your text will draw inside a rectangle likes say (0,0) - (100, 50), you can
    after you do your tft.print, you can then do something like:

    Code:
    void loop() {
        count = count + 1;
        tft.setCursor(0, 0);
        tft.setTextColor(ILI9340_WHITE, ILI0340_BLACK);   // set text color for FG and BG color
        tft.setTextSize(3);
        tft.print(count);
        int16_t cursor_x = tft.getCursorX();
        tft.fillRect(cursor_x, 0, 100 - cursor_x, 50);  // note the 0, 100, 50 are your field y1, field width, field height... 
        delay (3);
    }
    This can be easily be modified to handle fields where you pass in either: x, y, w, h or x1, y1, x2, y2

  11. #11
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,558
    I like the first, opaque variant. The width problem could be solved by using a formatted printf(), left-padding the number with zeros.
    And, BTW, no need to put the line

    tft.setTextColor(ILI9340_WHITE, ILI0340_BLACK); // set text color for FG and BG color

    into the loop, since these values won't change and could be set once in setup().

  12. #12
    Thank you.

  13. #13
    Thank you very much @KurtE for the detailed response. I appreciate it.

  14. #14
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,324
    I agree with Michael, that in your current code base you could put some of the settings like color and size into setup.

    However it was unclear to me from the text in the original posting:
    I realize I can use a longer delay but that would be unacceptable in my full sketch
    If there will be additional text being output and if all of the text fields will use the same font/colors.... If so move to setup, else
    may need it where the text is output...

Posting Permissions

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