Non-blocking (Inky Impression)

Does anyone have a mechanism to call in a non-blocking way? I’m using asyncio to run a variety of components simultaneously, and the 30 second display draw time is throwing a really unfortunate delay into my event loop. I can probably live with it if I have to, but it’d be super if there was a way to let other functions continue while the display draws…

To be clear, I tried to await the function, but it doesn’t seem to support it :-(. Hope I’m missing something here…

Internally, the waits in a tight loop until the busy-pin of the display signals it is finished. So without changing the driver, you cannot do a lot.

BTW: the InkyFrame, which uses the same display (at least the 5.7" variant), exposes the busy-pin only on a shift-register. And the CircuitPython driver does not wait for it. So theoretically you can change this in the driver if you take care not to send new commands to the display while it is busy. You could e.g. check manually.

The method accepts the busy_wait keyword argument which can be False, so just pass that and it shouldn’t block.

You may need some way to check when the update is finished, so take a look at the Inky._busy_wait method to see how that can be done.

1 Like

@davidb - thanks for the suggestion. If I’m right, the following should result in the two print statements being output one after the other (with the display commencing updating, but not finishing before the second print). That’s not happening (it’s still waiting for the screen to complete the update before the second print), so any idea what I’m doing wrong?

    print("Writing clean image to display...")
    print("Done cleaning display.")

I think your expectations are wrong: the busy-wait functionality is executed after setup (which uses an unconditional busy-wait) and after sending all data to the display and starting the update. So you will have delays.

As I already mentioned above, CircuitPython does not wait and as far as I remember I always have something around 15 seconds before the screen-refresh returns.

BTW: CircuitPython has the cleaning builtin. And the driver waits after clean (but not after the actual display update). I currently have an issue open with the maintainers discussing if it makes sense to wait after the clean but not after the data-update. The good thing is I can configure the waiting, so I can keep the delay after clean short.

@bablokb I’m using this with a full Python implementation on a Raspberry Pi with the impression 7.3". Didn’t ignore what you said about it not being possible, I just saw the comment from @davidb and thought it would be something to try…

I’m just not sure what busy_wait=False is intended to achieve if not allowing processing to continue in a shorter time after starting a screen update. Having timed it when True and False, it’s the same 40 second delay either way, so figured maybe I was doing it wrong…?

I’m not so much “cleaning” the display here because I need to, I just pinched the screen update code out of the example as an example of writing something to the display. Could equally well be a black screen/red/green etc screen here…I’m just setting it up with some content and then sending that to the display…then I realised I had this big delay in my separate code loops (which run LEDs, get data updates and handle input through a keypad) and wondered if I could do anything about it…

I don’t think you are doing anything wrong. The inky-code is generic, maybe this flag has more impact with other displays.

If you are running full Python, then I would recommend to switch to threads and do the update in a dedicated thread. ayncio is fine, but it is not as powerful. Even threads might not solve your problem, but I tend to use them anyhow because it makes the code clean. And as a final option you would also have multiprocessing.

@caeci11ius If you can show some of the code you are using, that would be helpful.