adafruit / Adafruit_CircuitPython_HT16K33

Adafruit CircuitPython driver for the HT16K33, a LED matrix driver IC.
MIT License
41 stars 29 forks source link

In internal functions _auto_write should be touched after input validation #90

Closed Docteh closed 2 years ago

Docteh commented 2 years ago

I've got a 7 segment display on my desk at the moment, and I noticed that display.autowrite gets set to False if the _number function is unhappy

from adafruit_ht16k33.segments import Seg7x4
display = Seg7x4(i2c)
>>> display.auto_write=True
>>> display.auto_write
True
>>> display.fill(0)
>>> display.print(1234)
>>> display.print(12345)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "adafruit_ht16k33/segments.py", line 146, in print
  File "adafruit_ht16k33/segments.py", line 220, in _number
ValueError: Input overflow - 12345 is too large for the display!
>>> display.auto_write
False
>>>

Noting this down for later. I see that under certain circumstances the _number function will do a fill but I'm not clear on the logic

https://github.com/adafruit/Adafruit_CircuitPython_HT16K33/blame/97937addac8fb392b8e5074acfaf69dc7efec58f/adafruit_ht16k33/segments.py#L214-L227

Seems like print()ing a number used to print to a cleared display, and now it doesn't.

https://github.com/adafruit/Adafruit_CircuitPython_HT16K33/blob/9fc3ecdb49064de0cb8d3aed4531f672931d0a08/adafruit_ht16k33/segments.py#L229

tannewt commented 2 years ago

Nice find! The line throwing the exception should be wrapped in try: finally: to make sure auto_write is re-enabled. Want to make a PR?

makermelissa commented 2 years ago

A good fix would be to set self._auto_write = auto_write right before the error is thrown in line 219. This should fix the behavior.

Docteh commented 2 years ago

@makermelissa It looks like self._auto_write is set to False such that if the self.fill(False) on line 230 fires it doesn't write to the screen. The call to _text avoids any need to look at auto_write

if places <= 0 < decimal: to trigger this code right now I'd need to pass an integer that somehow doesn't have any digits on either side of the decimal point, but is still a number. So zero is out as it has 1 digit on the left side of the decimal point. -1 is considered two digits on the left

From what I can tell looking at the original import of micropython-adafruit-ht16k33 if a user would display.print(1) a few times the display would be cleared and display 1 every time

Right now if a user does a few calls to display.print(1) in a row the display fills with 1's so 1111