Qmk_firmware: [Bug] oled_task_user runs to often

Created on 11 Jun 2020  Â·  4Comments  Â·  Source: qmk/qmk_firmware


Describe the Bug

I had problems with my OLED display. Normal rendering would work, but creating animations using proofed very troublesome. I found, that oled_clear wasn't able to clear the screen completely, but only small parts of it. I also looked into its definition but couldn't find anything meaningful.
Out of curiosity I slowed down the rendering method by triggering it only every few iterations and latter by using a timer_elapsed with 30fps. Now oled_clear works as expected.

As such my proposed solution would be using the timer_elpased function in the render cycle to trigger oled_task_user only in a predefined interval.

System Information

  • Keyboard: Lily58

    • Revision (if applicable): From keycapsss

  • Operating system: Unix
  • AVR GCC version: 5.4.0
  • ARM GCC version: 9.2.1
  • QMK Firmware version: 0.8.147

Additional Context

bug help wanted

Most helpful comment

I'm using a timer in oled_task_user, resetting when it expires.

// time for the next frame?
if (timer_elapsed(anim_timer) > FRAME_TIMEOUT) {
    anim_timer = timer_read();
    render_frame();
}

In context, see https://github.com/drcforbin/keyboards/blob/fe672b9c264cbcd958f4b5ddc48d75764674a3e3/crkbd/oled.c#L208 . I'm using 40fps, but 30's no problem (see FRAME_TIMEOUT in there).

All 4 comments

I ran into something like this too, because I was trying to update the OLED display on every call and it wasn't finished communicating or displaying (not sure which) before the next time it was called, and ended up displaying incompletely and eventually displaying garbage. Your bug report helped me work out what my problem was and a solution. I'm now using a timer, checking timer_elpased in the call to oled_task_user to call a second function regularly.

I think checking your own timer(s) in oled_task_user makes more sense than throttling calls to the oled_task_user function, as it allows for more flexibility, like updating multiple things at different intervals...if oled_task_user were running at a fixed rate, those updates would be limited to multiples of that rate.

Yeah. I would consider that a task for a rewritten OLED driver. Implementation of it is easy. But I think updating it at 30fps would enough. One could define a constant if one wants to limit fps or let the constant be undefined or so. It's an easy solution and I'm happy that my issue report helped you.

Would you like provide your codes to manually trigger the oled_task_user by 30fps? I ran into this issue too, which I want to show a logo for 3s and after that, remove the logo and show the keyboard status (layer, lock keys, etc.). Thanks.

I'm using a timer in oled_task_user, resetting when it expires.

// time for the next frame?
if (timer_elapsed(anim_timer) > FRAME_TIMEOUT) {
    anim_timer = timer_read();
    render_frame();
}

In context, see https://github.com/drcforbin/keyboards/blob/fe672b9c264cbcd958f4b5ddc48d75764674a3e3/crkbd/oled.c#L208 . I'm using 40fps, but 30's no problem (see FRAME_TIMEOUT in there).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jetpacktuxedo picture jetpacktuxedo  Â·  3Comments

mrceephax picture mrceephax  Â·  4Comments

jacwib picture jacwib  Â·  3Comments

vokeio picture vokeio  Â·  3Comments

kb3dow picture kb3dow  Â·  3Comments