esp-idf-ssd1306 icon indicating copy to clipboard operation
esp-idf-ssd1306 copied to clipboard

_ssd1306_bitmaps is slow due to vTaskDelay

Open drewbharris opened this issue 8 months ago • 8 comments

Hi, just curious what the function of this line is: https://github.com/nopnop2002/esp-idf-ssd1306/blob/f0770f10b5d4ed037118f41a39a5f8a23d19113a/components/ssd1306/ssd1306.c#L575C3-L575C17

I took that out and _ssd1306_bitmaps runs about 4x faster - in the BDF demo a string draw takes 24ms instead of 115ms for me.

drewbharris avatar Mar 18 '25 16:03 drewbharris

This is to avoid TWDT alerts. If you comment it out and run it, you will get a WDT alert with some SoC.

You can disable the Task Watchdog Timer by defining the following in sdkconfig: CONFIG_ESP_TASK_WDT_EN=n

in the BDF demo a string draw takes 24ms instead of 115ms for me.

Is it i2c or spi?

nopnop2002 avatar Mar 18 '25 22:03 nopnop2002

I'm using an I2C SSD1306. No issues with watchdog timeout when commenting out the vTaskDelay. I've modified the BdfFontDemo like so

while (1) {
  ssd1306_clear_screen(&dev, false);
  ssd1306_contrast(&dev, 0xff);

  int64_t start = esp_timer_get_time();
  show_bdf_font_text(&dev, __timR12_bitmap__, "Hello World", 0, 32);
  ESP_LOGI("", "elapsed: %llu us", esp_timer_get_time() - start);
  vTaskDelay(10);

  ssd1306_clear_screen(&dev, false);
  ssd1306_contrast(&dev, 0xff);
  vTaskDelay(10);
}

and it works great. ~26ms to draw a single line of text with vTaskDelay commented out. The watchdog timer is enabled - the only way I could see this being an issue is if someone is calling _ssd1306_bitmaps in a loop without delaying, but that should be solved in the consuming code I think - I can't see a reason to have a sleep inside a loop inside _ssd1306_bitmaps.

drewbharris avatar Mar 18 '25 22:03 drewbharris

Try displaying a 128x64 image without delay. You'll probably see TWDT.

Changing this will make it few faster.

Image

nopnop2002 avatar Mar 18 '25 22:03 nopnop2002

I guess it just surprises me that this function would ever take long enough to trigger watchdog timeout (I know I can change tickrate, but in my situation I can't afford extra delay) - I will just fork and remove the timeout I think, though it might be an improvement to the API to make that optional

drewbharris avatar Mar 19 '25 03:03 drewbharris

You can eliminate the delay in _ssd1306_bitmaps by changing the following in sdkconfig:

CONFIG_ESP_TASK_WDT_EN=n

However, disabling TWDT can be risky.

This might improve it a bit.

        //vTaskDelay(1); // To avoid TWDT alerts
        offset = offset + _width;
        dstBits++;
        _seg = xpos;
        if (dstBits == 8) {
            vTaskDelay(1); // To avoid TWDT alerts
            page++;
            dstBits=0;
        }

nopnop2002 avatar Mar 19 '25 04:03 nopnop2002

Thanks, yeah, I know that I can disabled the watchdog but definitely don't want to do that!

I'm having no issues removing the sleep altogether, but if I run into issues I'll try your solution, thanks!

drewbharris avatar Mar 19 '25 14:03 drewbharris

Just seeing this comment thread. I didn't know why vTaskDelay was in there either and just submitted a PR removing it. However I also updated ssd1306_bitmaps to only re-draw the pages/segments that are updated by the bitmap. This makes it much faster to draw any bitmap smaller than the entire screen. I'm showing a bubble-pop animation on keypress that is crazy responsive. Really appreciate this library as it's perfect for my project after this small change.

DennisCRM avatar Apr 04 '25 00:04 DennisCRM

I tested DennisCRM's PR for a week and merged this PR.

As a result, vTaskDelay(1) in _ssd1306_bitmaps is gone.

https://github.com/nopnop2002/esp-idf-ssd1306/blob/master/components/ssd1306/ssd1306.c#L575

nopnop2002 avatar Apr 12 '25 08:04 nopnop2002