Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 29

Thread: ILI9341 Display Issue

  1. #1
    Member
    Join Date
    Jan 2016
    Location
    Tx
    Posts
    48

    ILI9341 Display Issue

    Working on a small project that is outputting data to a ILI9341 display from Paul wired per the instructions. The data is updating pretty fast (reading it off CAN bus @500k). The screen does not seem to clear data on fields that are constantly changing. I am not sure how to address this in the code. I tried doing a simple screen fill, but it just makes the screen flicker.

    I am pulling 3.3v for the display and CAN transceiver from the Teensy's 3.3v pin if that matters. Also I do have a 100ohm resistor on LED to VIN as well.

    Project is a Teensy 3.2 reading data off a CAN bus using a WaveShare SN65HVD230 transceiver. Attached is the sketch I am using.

    Here is a picture, notice the issue at the bottom for the TPS value




    RB_CAN_Logging.ino

  2. #2
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    7,490
    That's normal behavior. Try to delete only the text that need to be rewitten. And rewrite this part only.

    tft.fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
    Last edited by Frank B; 01-30-2016 at 07:58 PM.

  3. #3
    Member
    Join Date
    Jan 2016
    Location
    Tx
    Posts
    48
    Quote Originally Posted by Frank B View Post
    That's normal behavior. Try to delete only the text that need to be rewitten. And rewrite this part only.

    tft.fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
    Thank you, I noticed all that does is isolate the flicker to the area specified. Is that simply a limitation of the LCD panel?

    On edit: I introduced a small delay off 500ms, that combined with the above seems to work well. It still has a "blink" affect, but not too bad.
    Last edited by Raymond_B; 01-30-2016 at 08:35 PM.

  4. #4
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    7,490
    Yep, and only re-draw if the text has changed.

  5. #5
    Member
    Join Date
    Jan 2016
    Location
    Tx
    Posts
    48
    Quote Originally Posted by Frank B View Post
    Yep, and only re-draw if the text has changed.
    OK thank you, this display is not the final one I'd like to use, but I wanted something inexpensive to test and learn with. A delay of 150ms looks to be the "smoothest" I can make it. When I do get to the point of looking for a larger (~7") display are there any you'd recommend for data that will be updated quite often? This is all engine data, which I hope to display in a nice digital dash eventually so there are a lot of items that will change quickly.

    Maybe that is a better question for the project guidance section?

  6. #6
    Senior Member
    Join Date
    Nov 2015
    Location
    Wales
    Posts
    579
    only re-draw if the text has changed.
    If you do this per character your flicker will be incredibly isolated.

    Either that or change the drawText to draw a black background behind it when it's called. This may already exist, I haven't actually used this library or screen

  7. #7
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    7,490
    Quote Originally Posted by Raymond_B View Post
    OK thank you, this display is not the final one I'd like to use, but I wanted something inexpensive to test and learn with. A delay of 150ms looks to be the "smoothest" I can make it. When I do get to the point of looking for a larger (~7") display are there any you'd recommend for data that will be updated quite often? This is all engine data, which I hope to display in a nice digital dash eventually so there are a lot of items that will change quickly.

    Maybe that is a better question for the project guidance section?
    You'll have this kind of problem with every Display.
    The common technique to prevent flickering is double-buffering. That means you have two RAM-Buffers on the Display,
    when the 1st is diplayed, you write the second, and vice-versa. This way, the whole content is displayed at once.
    But i don't know which displays with SPI support a second buffer.
    Another, additional techniqe, is to wait for the vertial-sync.
    Or, re-write only the PIXELS that are changed.
    Maybe there are more tricks.

    But perhaps it's better to display bar-graphs, or another kind of "analogue" display ! They are better readable.

    https://www.youtube.com/watch?v=iWcqSE_yjT4
    Last edited by Frank B; 01-30-2016 at 09:08 PM.

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,367
    Quote Originally Posted by Frank B View Post
    Maybe there are more tricks.
    Maybe we could do something creative here....

    Unfortunately we don't have access to the vertical sync signal and we don't have a lot of RAM to buffer all the pixels. But we could dedicate a moderate amount of RAM to remembering several strings and the coordinately where they were written. Then we could create a function which draws two strings at the same time, rendering each line of the old string in black or whatever the background color is, and the new string in the foreground color. Done line by line, maybe this would minimize flicker?

  9. #9
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,117
    I did a function for that in my last touch sample with the scroll areas. That would be cool, so much to track you'd want a structure /handle to x, y, fgc, bgc , font, Last_txt? Without that controlled, the overlay would be lossy.

    User code to:set font , fgc=bgc, locate, print,fgc&bgc, locate, print, update text is tedious/repetitive but effective. Also given font and area extent a .clear(bgc) rectangle could be done
    Last edited by defragster; 01-31-2016 at 12:43 AM.

  10. #10
    Member
    Join Date
    Jan 2016
    Location
    Tx
    Posts
    48
    Here's what it looks like so far with a 150ms delay.

    https://youtu.be/EME9iuKZJFQ

  11. #11
    Senior Member pictographer's Avatar
    Join Date
    May 2013
    Location
    San Jose, CA
    Posts
    681
    Quote Originally Posted by PaulStoffregen View Post
    Maybe we could do something creative here....

    Unfortunately we don't have access to the vertical sync signal and we don't have a lot of RAM to buffer all the pixels. But we could dedicate a moderate amount of RAM to remembering several strings and the coordinately where they were written. Then we could create a function which draws two strings at the same time, rendering each line of the old string in black or whatever the background color is, and the new string in the foreground color. Done line by line, maybe this would minimize flicker?
    Ages ago, I suggested the string drawing function could be modified to take two strings, old and new. For each pixel, there are three cases:

    • No need to update
    • Needs to be updated with the background color
    • Needs to be updated with the foreground color

    Someone posted the code to do this and claimed it worked.

    I'll try to find the posts I'm referring to... Here they are:

    https://forum.pjrc.com/threads/26305...ll=1#post83639

    https://forum.pjrc.com/threads/26305...ll=1#post83887
    Last edited by pictographer; 01-31-2016 at 06:24 AM. Reason: Added links.

  12. #12
    Member
    Join Date
    Jan 2016
    Location
    Tx
    Posts
    48
    I also meant to ask, an LED display would not have this issue correct?

  13. #13
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    7,490
    @Paul, there is a command 0x45 get_scanline.
    Maybe this can be used as "sync".
    A function "waitforscanline(y)" could be useful.
    Then, we could simply wait and update displaycontents near that line only when that line just passed the area we're updating - or when it is "far away".
    A bit tricky but it might be useful for some users.

    Edit: A function "int getscanline(void)" would be better/more flexible
    Last edited by Frank B; 01-31-2016 at 10:23 AM.

  14. #14
    Member
    Join Date
    Jan 2016
    Location
    Tx
    Posts
    48
    I must be making a rookie mistake somewhere, but I am unable to find it. Here is the sketch I have created, basically the way I formatted the data I am simply re-drawing the rightmost part of the display where the data values are. Everything works great until I try to call gauge_display(); (line 69) when I do that from within the void loop output slows down greatly. What am I doing wrong?

    I put in the serial part so I could see if the output was only slow to the LCD, but it is slow in Serial Monitor too.

    RB_CAN_Logging_Extended_No_Flicker.ino
    Last edited by Raymond_B; 01-31-2016 at 08:19 PM. Reason: Clarify

  15. #15
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    7,490
    Quote Originally Posted by Raymond_B View Post
    I must be making a rookie mistake somewhere, but I am unable to find it. Here is the sketch I have created, basically the way I formatted the data I am simply re-drawing the rightmost part of the display where the data values are. Everything works great until I try to call gauge_display(); (line 69) when I do that from within the void loop output slows down greatly. What am I doing wrong?

    I put in the serial part so I could see if the output was only slow to the LCD, but it is slow in Serial Monitor too.

    RB_CAN_Logging_Extended_No_Flicker.ino
    Try smaller "fillRect"s for the values only, and print the fixed texts like "Air-Fuel:" once in setup() only, not again and again in loop().

    All that data transmitting over SPI takes too much time.

  16. #16
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,117
    This is stopping you dead : delay(150);

    Here's where I'd start . . . .


    Do a global : elapsedMillis DisplayTime;

    in gauge_display() remove the delay() and do ::

    Code:
    elapsedMillis DisplayTime;
    void gauge_display() {  //Prints captured data from above to display
    if ( DisplayTime < 150 ) return;
    DisplayTime = 0;
    
    ...
    }
    This : tft.fillRect( 235, 0, 160, 240, ILI9341_BLACK );
    is killing your screen appearance and update speed


    Lots of rewriting of STATIC screen bits it looks like:

    There are seven items like this:
    Code:
      tft.setCursor(10, 210);
      tft.print("Air-Fuel:");
      tft.setCursor(235, 210);
      tft.print(AFR / 10);
    Split them into two functions with changes to how the update is done:

    Code:
      tft.setCursor(10, 210);    // DO ONCE per clear screen
      tft.print("Air-Fuel:");    // DO ONCE per clear screen
    
    //  tft.setCursor(235, 210);    // Do each loop when changed and then do something like this instead
    //  tft.print(AFR / 10);
    oldAFR = tftSCprint( oldAFR, (AFR / 10), uint16_t fgc, uint16_t bgc,   235, 210 );
    Since Each of the "label" fields like "Air-Fuel:" never changes you [ Don't ] need to rewrite them if you stop clearing the screen, you can split your gauge code into two and just call the half that does the static strings ONCE in setup and any time you might do a clear_screen.


    Also - If you record the 7 prior updated numbers strings - then reprint the OLD in background Color - then the new value and update the 'prior' printed - make this work:

    Code:
    //Self Cleaning String print
    //Self Cleaning number print
    uint32_t tftSCprint( uint32_t oldV, uint32_t newV, uint16_t fgc, uint16_t bgc,   int xxt, int yyt ) {
    
      tft.setCursor(xxt, yyt);
      tft.setTextColor(bgc);
      tft.print(oldV);
      tft.setCursor(xxt, yyt);
      tft.setTextColor(fgc);
      tft.print(newV);
      return newV;
    }
    Last edited by defragster; 01-31-2016 at 08:48 PM.

  17. #17
    Member
    Join Date
    Jan 2016
    Location
    Tx
    Posts
    48
    Thank you both! It makes such obvious sense to move the data labels to setup.

    @defragster, I follow along with what you are saying, but the last two items have me confused code-wise. For example, I am not sure how to format the item below;

    Code:
    uint32_t tftSCprint( uint32_t oldV, uint32_t newV, uint16_t fgc, uint16_t bgc,   int xxt, int yyt )
    oldV is simply one of my 7 values correct? so oldV could be oldAFR, or oldTPS, etc.? Also uint16_t fgc simply means foreground color correct? If so I am not sure how to fill in that value. Should I decare a variable in setup or simply enter it in this part of the code?

    I've tried several different things to no avail.

  18. #18
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,117
    Raymond_B : see the code just above - I coded a suggestive sample:

    Code:
    oldAFR = tftSCprint( oldAFR, (AFR / 10), uint16_t fgc, uint16_t bgc,   235, 210 );
    You need to provide data for colors : fgc, bgc

    You pass in ( an INT ) for OLD and one for NEW

    The NEW int passed in is returned and shown as stored in OLD for that value.

    You could also do this:

    Code:
    newAFR = AFR / 10;
    if ( newAFR != oldAFR )
    oldAFR = tftSCprint( oldAFR, newAFR, uint16_t fgc, uint16_t bgc,   235, 210 );
    oldAFR MUST BE STATIC/GLOBAL.

    The last two params are x,y coordinates taken by replacing the SetCursor in the sample code above

    You could get FANCY and put all this into an 7 deep array of everything you need.

  19. #19
    Member
    Join Date
    Jan 2016
    Location
    Tx
    Posts
    48
    I really appreciate your help on this.

    I am getting the following errors with this sketch.

    C:\Users\R\AppData\Local\Temp\arduino_3465ee788ead 1997e3f3bddfebcd1d2e\RB_CAN_Logging_Extended_No_Fl icker.ino: In function 'void gauge_display()':
    RB_CAN_Logging_Extended_No_Flicker:181: error: too many arguments to function 'uint32_t tftSCprint()'
    uint32_t oldTPS= tftSCprint(oldTPS, TPS/10,ILI9341_GREEN,ILI9341_GREEN,235,35);
    ^
    C:\Users\R\AppData\Local\Temp\arduino_3465ee788ead 1997e3f3bddfebcd1d2e\RB_CAN_Logging_Extended_No_Fl icker.ino:162:10: note: declared here
    uint32_t tftSCprint() {
    ^
    exit status 1
    too many arguments to function 'uint32_t tftSCprint()'

    RB_CAN_Logging_Extended_No_Flicker_2.ino
    Last edited by Raymond_B; 02-01-2016 at 02:21 AM.

  20. #20
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,117
    Raymond_B - hopefully you got through that. I cut and pasted with edits to two params. That is a normal compiler error telling you the number of parameters expected by the function definition does not match the number proved when you call the function. I've been busy powering up a new onehorse ESP8266 unit to working and couldn't get back. I'll give your code a look now.

    <edit> : I see you did some of my suggestions - but didn't put my name in the credit comments ...

    You sketch calls stuff not provided so I will try to use this "//notgot " to make it run

    <edit> : you've made some fundamental errors putting in my suggestions - particularly where you took a generic function and hardcoded the values into it taking off the 'variable' parameters. Hopefully in a few minutes I can show you working code.
    Last edited by defragster; 02-01-2016 at 09:14 AM.

  21. #21
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,117
    Raymond_B - I completed three of the displayed values for you - that leaves 4 - one of which is missing (Air-Fuel).

    I left a DEBUG increment section for testing since I had one of these on my desk - you can remove this.

    I fixed the errors in tftSCprint() and added a float version tftSCprintF().

    I also added the update limiter for 150 ms using an elapsedMillis as originally shown.

    It seems this should solve most of your problems and work for you. You may need to initialize the oldXYZ values to something over a possible value, as if they match it won't do the first update.

    Raymond_B_feb01a.ino

  22. #22
    Senior Member
    Join Date
    Nov 2015
    Location
    Wales
    Posts
    579
    A bit of an off the wall suggestion but you could try one of the following:

    Moving average your value so it changes more smoothly. Not really a fix though as numbers don't lend very well to rapid reading or redrawing
    OR
    Create a VU graphical reading. As you'll be filling in solid blocks this should eliminate any flicker. Personally I find these a lot easier to interpret at a glance
    Click image for larger version. 

Name:	vu-meter_21083265.jpg 
Views:	171 
Size:	28.3 KB 
ID:	6260

  23. #23
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,117
    I didn't have Raymond_B's large font - but the over write BLACK the old and write the new is pretty smooth - much better than any rectangle fill over a large area as it was before.

  24. #24
    Member
    Join Date
    Jan 2016
    Location
    Tx
    Posts
    48
    Thank you so much!! I really appreciate it, now I just need to get home to test.

    EDIT: OK, looking through the sketch now it makes sense what I was doing wrong and what you originally meant. The function accepts the values, somehow that was lost on me the first time around

    Again thank you very much!
    Last edited by Raymond_B; 02-01-2016 at 05:39 PM.

  25. #25
    Member
    Join Date
    Jan 2016
    Location
    Tx
    Posts
    48
    Quote Originally Posted by Xenoamor View Post
    A bit of an off the wall suggestion but you could try one of the following:

    Moving average your value so it changes more smoothly. Not really a fix though as numbers don't lend very well to rapid reading or redrawing
    OR
    Create a VU graphical reading. As you'll be filling in solid blocks this should eliminate any flicker. Personally I find these a lot easier to interpret at a glance
    Click image for larger version. 

Name:	vu-meter_21083265.jpg 
Views:	171 
Size:	28.3 KB 
ID:	6260
    Thanks for the suggestion, and you're right for some types of data it makes sense to display in that format, especially for at a glance type stuff. But for others the value is what you're looking for, e.g. gear position indicator, am I in 1st, second, etc. In a larger display I'd have a combination of both.

    I had two goals with this, to just learn the code and display CAN data from my fuel injection/transmission setup. Secondly once I had that part figured out I was going to use a large LCD display, something along the lines of 7" or so. It will be a "digital dash" for my vehicle using something like this https://www.itead.cc/display/nextion...splay_size=747

    But for now the little 12.00 2.8" display is fine

Posting Permissions

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