adafruit / Adafruit_CircuitPython_HT16K33

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

Add Multiple Display Support for 7-Segment, Alphanumeric, and Matrix Displays #74

Closed geekguy-wy closed 2 years ago

geekguy-wy commented 4 years ago

Multiple Display Support would essentially "soft-chain" two or more HT16K33 based displays so larger numeric, alphanumeric text, and longer matrix displays could be created. When I say "soft-chain," I mean that the chaining of displays would be done transparently in software because each set of four display units requires a separate HT16K33 controller. It just takes some software magic behind the scenes to make it appear like several of these displays are all one unit.

I would love to add support for multiple 7-segment, alphanumeric, and matrix displays. However, I only have one of the alphanumeric display Feather wings (Green) here. To do this and properly test everything, I would need at least three of each display. I think this would be an awesome feature to add to the library, and it may be possible to make it entirely transparent to the user.

geekguy-wy commented 4 years ago

I have received the displays I need to move forward on this - three 14-Segment and three 7-Segment.

I have been thinking about this and believe I have a way to add this support without so much as impacting the constructor. Everything will be completely transparent to users who do not wish to make use of this. This involves using the address parameter to signal the rest of the library how to handle everything. if the address is a single value, everything proceeds as it does now. However, if the address is a list, this will be checked to make sure each entry is a valid address for the ht16k33 controller, and if so, it will signal this is a call for multiple display support. The addresses will have to be listed in order from right to left in the display set up such that address[0] is the rightmost display which will simplify the library. It could also be listed where address[0] is the left-most display, counting in the same order as the digits of a single display, which might actually make more sense for everything. No additional parameters need to be added to the constructor!

geekguy-wy commented 4 years ago

I have run into a situation where my code refuses to write to any display except the very first one regardless of which one I select. The displays are created with the correct address and kept in a list. That list is used to control which display is being written to at any one time. I have already verified that the addresses stored with each display element are correct. I added an _address variable and property class to the Seg14x4 class so I could expose the address. I have only one idea that might cause this problem, which is in the _set_buffer() and _get_buffer() functions in the HT16K33 class and I am checking this out now. Attached is a short script that demonstrates the current behavior. multi_display_test.zip

Docteh commented 2 years ago

Hi, I ran the test code with two modules and it worked. the test code blinks the first module, and then the second one. Was there further modifications to the HT16K33 class other than the variable with the i2c address?

tannewt commented 2 years ago

I think that'd be enough @Docteh. Want to make a PR?

makermelissa commented 2 years ago

I've been thinking about this issue a lot lately. I think the existing classes could probably be modified with a couple of minor changes (to the function headers at least) without breaking or making new classes. To do multiple displays, we can pass in a tuple or list of I2C headers and have it treat that as one large display. The order they are passed in should match the physical layout. I think #67 could be addressed at the same time with an additional parameter parameter of something like digits_per_display or chars_per_display. Then it would keep an internal maximum size for error handling. I think using #89 as a base at least would be a good start so it doesn't go to waste.