Forum Rule: Always post complete source code & details to reproduce any issue!
Page 14 of 14 FirstFirst ... 4 12 13 14
Results 326 to 339 of 339

Thread: Playing around with yet another version of ILI9341_t3 library (ILI9341_t3n)

  1. #326
    Junior Member
    Join Date
    Jun 2020
    Posts
    7
    Quote Originally Posted by KurtE View Post
    In itself it would have probably 0% difference in possible speed.
    As for Gauge drawing with flicker and the like. I added code to the ili9341_t3n to help speed things up. In particular the code with each graphic primitive in frame buffer mode, would keep a bounding rectangle of what parts of the image changed since the last updateScreen was called and when you call updateScreen it would only update that portion of the display, which in cases of a needle changing a little bit was only a small fraction of the full pixels of the display.
    I'm curious as to how the automatic bounding box works. Does one need to do any more than just set useFrameBuffer(true)? Is it basically an auto "setClipRect()"? Or is it a more sophisticated routine that tightly bounds what's changed? Wouldn't a clipping rectangle get very large on a gauge when the needle is at 45, negating the benefit?

  2. #327
    Senior Member
    Join Date
    Oct 2019
    Posts
    118
    Quote Originally Posted by Slabshaft View Post
    I'm curious as to how the automatic bounding box works. Does one need to do any more than just set useFrameBuffer(true)? Is it basically an auto "setClipRect()"? Or is it a more sophisticated routine that tightly bounds what's changed? Wouldn't a clipping rectangle get very large on a gauge when the needle is at 45, negating the benefit?
    I wish it was automatic You need to define the X,Y pointers and the W,H of the clipping rectangle. One thing that confuses me is the position it starts at is the opposite of the other graphic primitives eg. drawing a char/string you pointer is at the top left corner, whereas ClipRect pointer starts at the bottom left corner.

    Regarding the clipping rectangle at a 45 angle, the rectangle becomes quite big, but still its much faster than a full display refresh. If I'm not mistaking, Kurt has implemented a mechanism that updates only changed pixels within the clipping rectangle on the ILI9341_t3n library - this obviously contributes to performance improvement, no doubt.

  3. #328
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,884
    Actually if you are using the frame buffer, and your updates are reasonably in the same area, in theory I have code in place that it remember the bounding rectangle of things that changed since you last did an updateScreen.

    Again this does not work with the Async stuff, only the sync stuff (so far).

    But I believe I have it such that you can enable this by a call like: tft.updateChangedAreasOnly();

    It has been awhile since i played with it so...

  4. #329
    Junior Member
    Join Date
    Jun 2020
    Posts
    7
    I found this in the header file and set _updateChangedAreasOnly to true and saved the header file so the default for me is now "true". Maybe this can be called in the code, but I wasn't sure how. I just ran a test by removing all of my millions of setClipRect() commands . . . and everything is rendering great, so the automatic clipping rectangle seems to be working. Nice!! I think this should work with the dial needle.

    Code:
    #ifdef ENABLE_ILI9341_FRAMEBUFFER
        // Add support for optional frame buffer
        uint16_t	*_pfbtft;						// Optional Frame buffer 
        uint8_t		_use_fbtft;						// Are we in frame buffer mode?
        uint16_t	*_we_allocated_buffer;			// We allocated the buffer; 
    	int16_t  	_changed_min_x, _changed_max_x, _changed_min_y, _changed_max_y;
    	bool 		_updateChangedAreasOnly = false;	// current default off set to
    	void		(*_frame_complete_callback)() = nullptr;
    	bool 		_frame_callback_on_HalfDone = false;

  5. #330
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,884
    Again as I mentioned there is a simple member function:
    Code:
    void updateChangedAreasOnly(bool updateChangedOnly) {
    #ifdef ENABLE_ILI9341_FRAMEBUFFER
    		_updateChangedAreasOnly = updateChangedOnly;
    #endif
    	}
    That you can call that sets that variable true or false.

    The interesting thing with needle is if that is all you are changing, then yes can do this automatic. But if you then are updating some text field somewhere else, you may be better off doing them as separate sets of updates to limit just how much of the screen redraws.

  6. #331
    Senior Member
    Join Date
    Oct 2019
    Posts
    118
    Quote Originally Posted by KurtE View Post
    The interesting thing with needle is if that is all you are changing, then yes can do this automatic. But if you then are updating some text field somewhere else, you may be better off doing them as separate sets of updates to limit just how much of the screen redraws.
    I've been thinking, to optimize performance even more, for any text fields that aren't changing, you can compare the current value to its old value and decide if it requires updating. On integers it would be simple enough. But how do you suggest one does this with floats? with a single decimal point, I'm using tft.print(float value,1) to print the values. Do you suggest converting to an integer and multiplying and then comparing?

  7. #332
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,750
    Quote Originally Posted by Rezo View Post
    I've been thinking, to optimize performance even more, for any text fields that aren't changing, you can compare the current value to its old value and decide if it requires updating. On integers it would be simple enough. But how do you suggest one does this with floats? with a single decimal point, I'm using tft.print(float value,1) to print the values. Do you suggest converting to an integer and multiplying and then comparing?
    That sounds reasonable to try - math and multiply is faster (single op) than SPI rewrite of the number and background.

    Wondering how much overhead is in the tft.print(float value,1)? Since doing the *10 anyhow:
    Code:
    // int32_t?  uint32_t?
    static int32_t old_foo=0x7FFF;
    int32_t foo = floatX*10;
    if ( foo != old_foo ) {
      // prep cursor/field for overwrite
      tft.print( foo/10 );
      tft.print( '.' );
      tft.print( foo%10 );
      old_foo = foo;
    }

  8. #333
    Senior Member
    Join Date
    Oct 2019
    Posts
    118
    Quote Originally Posted by defragster View Post
    That sounds reasonable to try - math and multiply is faster (single op) than SPI rewrite of the number and background.

    Wondering how much overhead is in the tft.print(float value,1)? Since doing the *10 anyhow:
    Code:
    // int32_t?  uint32_t?
    static int32_t old_foo=0x7FFF;
    int32_t foo = floatX*10;
    if ( foo != old_foo ) {
      // prep cursor/field for overwrite
      tft.print( foo/10 );
      tft.print( '.' );
      tft.print( foo%10 );
      old_foo = foo;
    }
    I think we need to convert everything back into a float if possible as you need to set the cursor for each print if I'm not mistaking - could be a hell of a headache to code in.
    In my code I move the curser left<>right based on the size of value - that way I'm able to center the string to the decimal point and it doesn't jump back and forth.


    EDIT:
    this could work:
    Code:
    // int32_t?  uint32_t?
    static int32_t old_foo=0x7FFF;
    int32_t foo = floatX*10;
    float floatX_n = 0; // new float for tft.print
    if ( foo != old_foo ) {
      // prep cursor/field for overwrite
      floatX_n = foo * 0.1f;
      tft.print(floatX_n, 1);
      old_foo = foo;
    }
    Last edited by Rezo; 06-17-2020 at 10:45 AM.

  9. #334
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,884
    Again if your goal is to output at 10ths of a unit and only update if it changes, you have multiple ways to do so.

    In many cases I will use fixed point math...

    But you can also do it quick and dirty with floating point...

    Something as simple as:

    Code:
    float last_value = 999999.9999; // some value you won't have.
    
    float new_value = ???
    
    if ((abs(last_value - new_value) >= 0.1) {
        display the new value
        last_value = new_value;
    }
    Obviously there are probably faster ways...

    NOTE: But side note: I just pushed up a minor change to the library, that when you call begin, it sets the pending_rx_count back to zero, in case someone calls
    the begin again and for some reason, the count had not been cleared back to zero...

  10. #335
    Senior Member
    Join Date
    Oct 2019
    Posts
    118
    Quote Originally Posted by KurtE View Post
    Again if your goal is to output at 10ths of a unit and only update if it changes, you have multiple ways to do so.

    In many cases I will use fixed point math...

    But you can also do it quick and dirty with floating point...

    Something as simple as:

    Code:
    float last_value = 999999.9999; // some value you won't have.
    
    float new_value = ???
    
    if ((abs(last_value - new_value) >= 0.1) {
        display the new value
        last_value = new_value;
    }
    Obviously there are probably faster ways...
    That's much cleaner. As mentioned before, I think the speed impact will still be a lot lower than rewriting and unchanged string to the display

  11. #336
    Senior Member
    Join Date
    Oct 2019
    Posts
    118
    I implemented the code above, calculating the absolute value and updating the relevant area of the display if its equal to or greater than 0.1, but it seems to have really slowed down the rate of change, as in, it wasn't updating nearly as fast as it does without the condition set

    Here's an example trying to limit the printout of Boost on the display as it doesn't change much when the car is at idle but as soon as some throttle is applied it will jump up and down quite fast

    Code:
    float intakePressureFinal = 0; // Boost: range is -30 to +30
    float intakePressureFinal_n = 0x7fff0;
    
    if ((abs(intakePressureFinal_n - intakePressureFinal) >= 0.1)) {
          
            if (intakePressureFinal >= 0 && intakePressureFinal < 10){ //Boost is between 0-10
              tft.setCursor(221, 230);
            }
          
            else if (intakePressureFinal > -99 && intakePressureFinal < -10){ // Boost bigger than -10 and smaller than -99
              tft.setCursor(182, 230);
            }
    
            else if (intakePressureFinal >= 10 && intakePressureFinal < 99){ // Boost is bigger than 10 and smaller than 99
              tft.setCursor(193, 230); 
            }
    
            else { // Boost is between -10 and 0
              tft.setCursor(210, 230);
            }
    
            tft.print(intakePressureFinal, 1);
            tft.setClipRect(182, 220, 110, 35);
            tft.updateScreen();
            tft.setClipRect();
            intakePressureFinal_n = intakePressureFinal;
     }
    Perhaps this method is too slow to execute or I ain't doing it right

  12. #337
    Senior Member
    Join Date
    Oct 2019
    Posts
    118
    Been up to some testing on an online C++ complier as I don't have access to a Teensy at the moment - will test the same code later on or tomorrow on a T4/4.1

    Here's the script im using to test the function:
    Code:
    #include <iostream>
    #include "math.h"
    
    using namespace std;
    float intakePressureFinal[5] = {-30.2, -15.2, 1.1, 14.9, 30.0}; // Boost: range is -30 to +30
    float intakePressureFinal_n[5] = {-24.2, -16.2, 1.1, 14.8, 30.2};
    float diff;
    
    
    int main()
    {
        
        for (int i = 0; i < 5 ; i++){
            cout<<"intakePressureFinal: " << intakePressureFinal[i];
            diff = intakePressureFinal_n[i] - intakePressureFinal[i];
            cout<< " || Diff: " << diff;
            if (fabs(diff) >= 0.1) {
                cout<<" || Output: " << intakePressureFinal[i] << "\n";
                intakePressureFinal_n[i] = intakePressureFinal[i];
            }
            else{
                cout<<" || No change \n";
                }
        }
        return 0;
    }
    Output:
    Code:
    intakePressureFinal: -30.2 || Diff: 6 || Output: -30.2                                                                                                                                          
    intakePressureFinal: -15.2 || Diff: -1 || Output: -15.2                                                                                                                                         
    intakePressureFinal: 1.1 || Diff: 0 || No change                                                                                                                                                
    intakePressureFinal: 14.9 || Diff: -0.0999994 || No change                                                                                                                                      
    intakePressureFinal: 30 || Diff: 0.200001 || Output: 30
    If I change intakePressureFinal_n[3] (14.8) to 15.0 I get a different output
    Code:
    intakePressureFinal: -30.2 || Diff: 6 || Output: -30.2                                                                                                                                        
    intakePressureFinal: -15.2 || Diff: -1 || Output: -15.2                                                                                                                                       
    intakePressureFinal: 1.1 || Diff: 0 || No change                                                                                                                                              
    intakePressureFinal: 14.9 || Diff: 0.1 || Output: 14.9                                                                                                                                        
    intakePressureFinal: 30 || Diff: 0.200001 || Output: 30
    But, if I change the value to compare abs to 0.09 from 0.1 it works much better:
    Code:
    if (fabs(intakePressureFinal_n[i]) >= 0.09)
    as I'm not getting a rounded off 0.1 or higher if the old value is smaller than the new value. I believe this is the cause of the "slowness" in updating the numbers on the display - it's just not meeting the conditions when using a difference of 0.1 for a single decimal point of precision.

  13. #338
    Junior Member
    Join Date
    Jan 2019
    Posts
    1
    Has anyone using the Buydisplay 7" with capacitive touch screen. https://www.buydisplay.com/spi-7-inc...h-screen-panel
    I have connected one to a teensy 4.0 Works fine, however the touch screen in showing the touches with x 1024 and y 600 in the top left hand corner. Using the test sketch from https://github.com/mjs513/Ra8876LiteTeensy. When the screen is touched the large dot is opposite of where it is being touched. It is like the touch screen was put on backwards. Please help.
    Tim

  14. #339
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,884
    Probably should ask on ra8876 thread, but probably does not take logical rotation into account. I would probably have simple sketch that prints the touch positions, and use map functions to convert

Posting Permissions

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