Forum Rule: Always post complete source code & details to reproduce any issue!
Page 26 of 26 FirstFirst ... 16 24 25 26
Results 626 to 634 of 634

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

  1. #626
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    507
    Hi,

    Thanks to KurtE for adding the setscrollmargins function, this works completely as planned in our TeensyBat project. I am currently looking for an example that uses this library with a framebuffer located in PSRAM.

    Looking through the examples I havent seen one (maybe missed it) but I saw the library now has a function:
    Code:
    void	setFrameBuffer(uint16_t *frame_buffer);
    Would a standard PSRAM on the T4.1 be fast enough for this purpose ? If nobody has tested this I might dive into that and see what comes up.

    regards
    Cor

  2. #627
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,110
    Quote Originally Posted by CorBee View Post
    Hi,

    Thanks to KurtE for adding the setscrollmargins function, this works completely as planned in our TeensyBat project. I am currently looking for an example that uses this library with a framebuffer located in PSRAM.

    Looking through the examples I havent seen one (maybe missed it) but I saw the library now has a function:
    Code:
    void	setFrameBuffer(uint16_t *frame_buffer);
    Would a standard PSRAM on the T4.1 be fast enough for this purpose ? If nobody has tested this I might dive into that and see what comes up.

    regards
    Cor
    KurtE likely to reply in hours ... but it should be worth expecting it to work.

    AFAIK - larger displays needing a buffer that fits only in PSRAM have been tested and designed to work.

    Seems there was testing or a sample on that ... though too long ago to expect to find it in context ... it may have been on MMod or other ...

  3. #628
    Senior Member CorBee's Avatar
    Join Date
    Jun 2018
    Location
    Netherlands
    Posts
    507
    Quote Originally Posted by defragster View Post
    KurtE likely to reply in hours ... but it should be worth expecting it to work.

    AFAIK - larger displays needing a buffer that fits only in PSRAM have been tested and designed to work.

    Seems there was testing or a sample on that ... though too long ago to expect to find it in context ... it may have been on MMod or other ...
    It at least seems to work from code without any problems, since I do use scrolling 1pixel lines in the code I will have to find a good way to do that in memory. The recent
    addition of setscrollmargins was not yet (as KurtE mentions on Github) tested much and scrolling in memory is another "affair". But I am sure that there can be a good
    way to achieve this.

    cheers
    Cor

  4. #629
    My app includes a filled rect which must move left and right one pixel at a time. The simplistic way to move it is to call fillRect with background color and call it again with new coordinates and foreground color. That is slow and causes flicker. A better way is to redraw only the pixels which must change. Call drawFastVLine for the leading edge in foreground color and call it again for the trailing edge in background color. It's efficient and prevents flicker. I call it differential animation.

    I also have a filled circle to move, but that's more complex. You might think to call drawCircleHelper for a semicircle at the trailing edge in background color and call it again for a shifted semicircle in foreground color. But that doesn't quite work because the trailing semicircle removes too many edge pixels in the upper and lower octants. One fix is to draw a shifted full circle in foreground color to restore the edges. That looks good but it really draws about twice as many pixels as needed. An optimal solution is to draw leading and trailing semicircles, but replace the horizontal line segments with only endpoints.

    Here's the code, adapted from drawCircleHelper. I also pulled the first segments out of the loop and combined them to cover the left and right edges completely. I hope someone will find it useful.
    Code:
    // Shift a filled circle left or right by 1 pixel. Draws only leading and trailing edge pixels.
    // Adapted from ILI9341_t3::drawCircleHelper
    void shiftCircle( int16_t x0, int16_t y0, int16_t r, uint16_t lcol, uint16_t rcol) {
      int16_t f = 1 - r;
      int16_t ddFx = 1;
      int16_t ddFy = -2 * r;
      int16_t x = 0;
      int16_t y = r;
      int xold;
    
      xold = x;
      while (f<0) {
        x++;
        ddFx += 2;
        f += ddFx;
      } // draw first line segments
      tft.drawFastVLine(x0+y+1, y0-x, x-xold+x-xold+1, rcol);
      tft.drawPixel(x0+x+1, y0+y, rcol);
      tft.drawPixel(x0+x+1, y0-y, rcol);
      tft.drawPixel(x0-x, y0+y, lcol);
      tft.drawPixel(x0-x, y0-y, lcol);
      tft.drawFastVLine(x0-y, y0-x, x-xold+x-xold+1, lcol);
      xold = x;
      while (x<y) {
        if (f >= 0) {
          y--;
          ddFy += 2;
          f += ddFy;
        }
        x++;
        ddFx += 2;
        f += ddFx;
        if (f >= 0 || x == y) { // time to draw the next line segments
          tft.drawPixel(x0+x+1, y0+y, rcol);
          tft.drawFastVLine(x0+y+1, y0+xold+1, x-xold, rcol);
          tft.drawPixel(x0+x+1, y0-y, rcol);
          tft.drawFastVLine(x0+y+1, y0-x, x-xold, rcol);
          tft.drawFastVLine(x0-y, y0+xold+1, x-xold, lcol);
          tft.drawPixel(x0-x, y0+y, lcol);
          tft.drawFastVLine(x0-y, y0-x, x-xold, lcol);
          tft.drawPixel(x0-x, y0-y, lcol);
          xold = x;
        }
      }
    }

  5. #630
    Member DIYLAB's Avatar
    Join Date
    Jun 2020
    Location
    Germany
    Posts
    64
    Hi,

    is this the right thread to talk about KurtE's ILI9341_t3n?

    I'll make it very short ;o)
    There is a "driver" optimized for the Teensy 4.x that does nothing more than get a framebuffer onto the display as fast as it can, the ILI9341_T4.
    There is an example program which is smoothly impressive at 30MHz SPI, "99 Luftballons".

    Here the test: https://youtu.be/0VGeh5ThRIw
    *It even goes much faster!

    I have now ported the program for the ILI9341_t3n and also used 30MHz SPI clock, here the result: https://youtu.be/0e9oGl-4Ht0

    What am I doing wrong?
    I would like to reach this speed with the ILI9341_t3n.

    Here the used test program for ILI9341_t3n:

    Code:
    #include "SPI.h"
    #include <ILI9341_t3n.h>
    
    // set the pins: here for SPI0 on Teensy 4.0
    // ***  Recall that DC must be on a valid cs pin !!! ***
    #define PIN_SCK         13  // (needed) SCK pin for SPI0 on Teensy 4.0
    #define PIN_MISO        12  // (needed) MISO pin for SPI0 on Teensy 4.0
    #define PIN_MOSI        11  // (needed) MOSI pin for SPI0 on Teensy 4.0
    #define PIN_DC          10  // (needed) CS pin for SPI0 on Teensy 4.0
    #define PIN_RESET        6  // (needed) any pin can be used 
    #define PIN_CS           9  // (needed) any pin can be used
    #define PIN_BACKLIGHT    5  // only required if LED pin from screen is connected to Teensy 
    #define PIN_TOUCH_IRQ  255  // 255 if touch not connected
    #define PIN_TOUCH_CS   255  // 255 if touch not connected
    
    // drawing size in portrait mode
    #define LX  240
    #define LY  320
    
    /** fill a framebuffer with a given color*/
    void clear(uint16_t* fb, uint16_t color = 0) {
        for (int i = 0; i < LX * LY; i++) fb[i] = color;
    }
    
    /** draw a disk centered at (x,y) with radius r and color col on the framebuffer fb */
    void drawDisk(uint16_t* fb, double x, double y, double r, uint16_t col) {
        int xmin = (int)(x - r);
        int xmax = (int)(x + r);
        int ymin = (int)(y - r);
        int ymax = (int)(y + r);
        if (xmin < 0) xmin = 0;
        if (xmax >= LX) xmax = LX - 1;
        if (ymin < 0) ymin = 0;
        if (ymax >= LY) ymax = LY - 1;
        const double r2 = r * r;
        for (int j = ymin; j <= ymax; j++) {
            double dy2 = (y - j) * (y - j);
            for (int i = xmin; i <= xmax; i++) {
                const double dx2 = (x - i) * (x - i);
                if (dx2 + dy2 <= r2) fb[i + (j * LX)] = col;
            }
        }
    }
    
    /** return a uniform in [0,1) */
    double unif() {
        return random(2147483647) / 2147483647.0;
    }
    
    /** a bouncing ball */
    struct Ball {
        double x, y, dirx, diry, r; // position, direction, radius. 
        uint16_t color;
    
        Ball() {
            r = unif() * 25; // random radius
            x = r; // start at the corner
            y = r; //
            dirx = unif() * 5; // direction and speed are random...
            diry = unif() * 5; // ...but not isotropic !
            color = random(65536); // random color
        }
    
        void move() {
            // move
            x += dirx;
            y += diry;
            // and bounce against border
            if (x - r < 0) { x = r;  dirx = -dirx; }
            if (y - r < 0) { y = r;  diry = -diry; }
            if (x > LX - r) { x = LX - r;  dirx = -dirx; }
            if (y > LY - r) { y = LY - r;  diry = -diry; }
        }
    
        void draw(uint16_t* fb) {
            drawDisk(fb, x, y, r, color);
        }
    };
    
    // 99 luftballons
    Ball balls[99];
    
    // Instantiate display object.
    ILI9341_t3n tft = ILI9341_t3n(PIN_CS, PIN_DC, PIN_RESET, PIN_MOSI, PIN_SCK, PIN_MISO);
    
    // Framebuffer
    DMAMEM uint16_t fb[LX * LY];
    
    void setup() {
        tft.begin(30000000);
        tft.setFrameBuffer(fb);
        tft.useFrameBuffer(true);
    
        // make sure backlight is on
        if (PIN_BACKLIGHT != 255) {
            pinMode(PIN_BACKLIGHT, OUTPUT);
            digitalWrite(PIN_BACKLIGHT, HIGH);
        }
    
        tft.setRotation(0);
    }
    
    void loop() {
        tft.fillScreen(ILI9341_BLACK);
    
        // move and then draw all the balls onto the framebuffer
        for (auto& b : balls) {
            b.move();
            b.draw(fb);
        }
    
        tft.updateScreen();
    }

  6. #631
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,558
    @DIYLAB
    Tried your sketch on a T4 and a teensy micro mod and worked with begin(30000000). I did use my arducam config for cs= 10. DC =9. and rat = 8. Still have to try on a t41

  7. #632
    Member DIYLAB's Avatar
    Join Date
    Jun 2020
    Location
    Germany
    Posts
    64
    Quote Originally Posted by mjs513 View Post
    Tried your sketch on a T4 and a teensy micro mod and worked with begin(30000000).
    Nice, then you can now also try the original demo from here: https://github.com/vindar/ILI9341_T4.../99luftballons
    The question is, how do you get the ILI9341_t3n just as fast?
    Please compare the two videos I made of both versions.

  8. #633
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,558
    Quote Originally Posted by DIYLAB View Post
    Nice, then you can now also try the original demo from here: https://github.com/vindar/ILI9341_T4.../99luftballons
    The question is, how do you get the ILI9341_t3n just as fast?
    Please compare the two videos I made of both versions.
    Well I just finished testing the T4.1 up to 50Mhz without an issue - at 60Mhz your screen stays white with your example sketch.

    As to the second part of your question as to how do you get the ILI9341_t3n just as fast that is a whole different question.

    You need to look at what that library is doing and why the author says its optimized for the T4.x only and does not support the T3.x etc. You might be able to realize faster frame rates by only updating the sections of the screen that you are changing or trying double or triple buffering as is done in the library but that will only be good for the t4.1.

  9. #634
    @KurtE @mjs513
    Hi, can someone list the color TFT libraries that use frame buffers? I am currently writing a library for a graphical user interface and would like to increase the compatibility.

    I thank you!

    https://github.com/sepp89117/Teensy_UI

Posting Permissions

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