pimoroni / inky

Combined library for V2/V3 Inky pHAT and Inky wHAT.
https://shop.pimoroni.com/?q=inky
MIT License
590 stars 122 forks source link

exception "Timeout waiting for busy signal to clear." thrown when trying to update display with inky.show (Inky Impressions) #103

Closed jg76379 closed 1 year ago

jg76379 commented 3 years ago

Hello,

I have the Inky Impressions display on a Raspberry Pi Zero W running Raspbian 10. I am using Python 3.7.3

I installed the inky library and all dependencies and was initially able to run a script and display an image on the screen. However, now whenever I try to display a new image the following exception is thrown:

Traceback (most recent call last): File "", line 5, in File "/home/pi/.local/lib/python3.7/site-packages/inky/inky_uc8159.py", line 365, in show self._update(buf.astype('uint8').tolist(), busy_wait=busy_wait) File "/home/pi/.local/lib/python3.7/site-packages/inky/inky_uc8159.py", line 320, in _update self.setup() File "/home/pi/.local/lib/python3.7/site-packages/inky/inky_uc8159.py", line 226, in setup self._busy_wait() File "/home/pi/.local/lib/python3.7/site-packages/inky/inky_uc8159.py", line 309, in _busy_wait raise RuntimeError("Timeout waiting for busy signal to clear.") RuntimeError: Timeout waiting for busy signal to clear.

I tried running the example code to clear the display and got the same error.

Any idea on how to fix this issue?

For reference here is my script to display an image:

from os import listdir
from os.path import isfile, join

from PIL import Image
from inky.inky_uc8159 import Inky

IMAGES_DIR = "/home/pi/scripts/picturesforpi2"
images = [i for i in listdir(IMAGES_DIR) if isfile(join(IMAGES_DIR, i))]
print(images)
pic = Image.open(join(IMAGES_DIR, images[0]))
pic = pic.resize((600,448))
inky = Inky()
saturation = 0.5
inky.set_image(pic, saturation=saturation)
inky.show()
mortentor commented 3 years ago

I had the same issue with an inky7.

The display - initially - worked, but stopped after a few months of sitting stale on the shelf.

I just removed the busy-wait code in the driver inky_uc8159.py line 307 and replaced it with a 1 second sleep. The display then worked.

I also tried replacing it with a test for the pin being LOW. This did NOT work. The busy pin under test seems to be 0 (LOW) at all times (in other words, it doesn't do anything after the board runs the reset sequence).

I also tried with the smalled mono inky display. It worked out of the box.

jg76379 commented 3 years ago

@mortentor Hey thanks for the reply, i finally got a chance to try your hack and it seems to be working!

I'm curious if this will have any adverse effect on the display, but i am just glad that I am at least able to use it!

Gadgetoid commented 3 years ago

An alternative hack would be to discard the RuntimeError like so:

try:
    inky.show()
except RuntimeError:
    pass

Which saves modifying the library, at least for now.

I'm not totally sure the busy wait timeout even needs to be a hard fail like this, though it's there ideally to help you know when the display has finished updating. If the display for some reason doesn't change the pin to indicate this... then I guess baking in a known approximate delay is just as good. The update cycles more or less take the same amount of time.

Right now I don't know why this is happening, but I'm keeping an eye on this issue to see if the problem becomes more pervasive.

jg76379 commented 3 years ago

@Gadgetoid I don't see how catching the exception would help. The RuntimeError causes the inky module to exit before the display is updated. So catching the exception would prevent my script from crashing but it still wouldnt allow for the display to be updated.

Gadgetoid commented 3 years ago

@Gadgetoid I don't see how catching the exception would help. The RuntimeError causes the inky module to exit before the display is updated. So catching the exception would prevent my script from crashing but it still wouldnt allow for the display to be updated.

Oooof, good point. Yeah I guess there's a busy_wait check in the setup that I'd forgotten about.

Are you sure you don't have anything else interfering with GPIO 17 that could be trampling the busy pin state?

jg76379 commented 3 years ago

Are you sure you don't have anything else interfering with GPIO 17 that could be trampling the busy pin state?

I don't think so, I just have the Inky Impression hat attached to the Pi's Gpio pins.

lwild12 commented 3 years ago

I am also getting this error on a freshly imaged Pi with a brand new inky impression and no other GPIO devices connected...

Results of identify script: Found: 7-Colour (UC8159) Display: 600x448 Color: None PCB Variant: 1.2 Display Variant: 14 Time: 2021-05-19 16:17:30.2

PeaceDealer commented 3 years ago

Hey just to chip in, same above.

Tried to run "stripes.py" and "clear.py" getting the exception from that shared libary.

Litterly just unpacked & plugged in display.

Have been using the inky what without issues, and just swapped out the display.

Personally fixed it by going to /usr/local/lib/python3.7/dist-packages/inky/inky_uc8159.py and looking for def _busy_wait and raising the default timeout to 30

jg76379 commented 3 years ago

Hey @PeaceDealer I will give your solution a try. I have been using the solution suggested by @mortentor and that has been working (https://github.com/jg76379/inky/commit/65e03c0e539dec7b53488fcb917ddade97b1ad80) but your solution might be better since it doesn't remove the busy pin call all together.

jg76379 commented 3 years ago

Oops... accidentally hit 'close with comment' on my last comment.

Skyost commented 3 years ago

I'm getting the same exception, but my Inky display is able to refresh. Therefore the hack provided by @Gadgetoid works in my case (at least for now).

dominicpanarello commented 3 years ago

Hi, I have exactly the same issue with a brand new inky impression and pi4b. After the standard installation instructions on https://shop.pimoroni.com/products/inky-impression, then running 7color/clean.py, this returns Traceback (most recent call last): File "clear.py", line 14, in <module> inky.show() File "/usr/local/lib/python3.7/dist-packages/inky/inky_uc8159.py", line 365, in show self._update(buf.astype('uint8').tolist(), busy_wait=busy_wait) File "/usr/local/lib/python3.7/dist-packages/inky/inky_uc8159.py", line 329, in _update self._busy_wait() File "/usr/local/lib/python3.7/dist-packages/inky/inky_uc8159.py", line 309, in _busy_wait raise RuntimeError("Timeout waiting for busy signal to clear.") As @PeaceDealer suggested, raising the default _busy_wait in /usr/local/lib/python3.7/dist-packages/inky/inky_uc8159.py from 15 to 30 resolves the issue and allows the process to complete normally, with no exceptions.

I imagine the other suggested fixes, like catching the Exception, are not a good idea as the requested process is still interrupted.

sakumoil commented 3 years ago

I have the same issue, I have tried to reseat the display multiple times. Sometimes the screen updates properly for a while, but then the error comes up once again. Changing the timeout value does not help.

steamfan commented 3 years ago

I changed to value to 40s for my Raspberry Pi Zero W and have no timeout warnings anymore (see https://forums.pimoroni.com/t/exception-timeout-waiting-for-busy-signal-to-clear-thrown-when-trying-to-update-display-with-inky-show-inky-impressions/16597/4).

Gadgetoid commented 3 years ago

I have as yet been unable tor replicate this, and am wondering if I've made a flawed assumption about how/when the busy signal should be asserted.

Either way if increasing the "busy_wait" timeout fixes the problem, it might be worth adding. Though 15-30 seconds is a heck of a long wait for a chip to come out of reset.

PeaceDealer commented 3 years ago

As far a i can tell physically the display is actually still updating when the 15s timeout expires.