Closed martinohanlon closed 8 years ago
See also #357 I haven't got round to looking through the sample code posted there myself yet.
Thanks, I did a search for 'seg' on the issues too and didnt find any.
7SegmentDisplay
is not a valid class name in Python, and 7seg
is not a valid object name :P
I'm not sure about seg.value = "a"
because .value
should be boolean or float to be compatible with the rest of the library.
Other than that, sounds good. Do various 7seg displays tend to work the same way?
I'm not sure about seg.value = "a" because .value should be boolean or float to be compatible with the rest of the library.
Yeah, that was my gut reaction too - glad to see I wasn't alone ;-)
But it then begs the question, how do we map the LEDs illuminated on a 7-segment display (or 8-segment if it also contains a decimal-point) to a single .value
between 0 and 1 (or -1 and +1)? There doesn't seem to be any obvious solution...
The only thing I can think of is to treat the 8-segments as elements of a bit-field, and than divide by 256.0 to get a floating-point value (so all segments off would be 0.0
; all segments on would be 1.0
; and segments 'a' and 'c' turned on would be ((2**0 + 2**2) / 256.0) = ((1 + 4) / 256.0) = 0.01953125
). So we could then do seg2.source = seg1.values
, and it'd work as expected, provided seg1 and seg2 were initialised with their segments in the same order.
But to maintain ease-of-use, we'd also want some kind of .character
property, where you could do seg.character = 3
(with the int
automatically being converted to str
) or seg.character = "A"
.
Or perhaps seg.number = 3
and seg.hexnumber = 0xa
? shrug
P.S. Another approach would be to treat SevenSegmentDisplay as a CompositeOutputDevice
subclass, and have .value
be a tuple of bool
s (so my earlier segments a and c example would be (False, False, False, False, False, True, False, True)
). double shrug
I'm not sure about seg.value = "a" because .value should be boolean or float to be compatible with the rest of the library.
Yeah I thought it was a bit weird, one of the reasons I asked for comment. Less weird would be an 8 bit field, represented as 0 - 1.
It should definitely have a 'friendly' method for showing a number/character how about .display
?
.display
would work.
It might make sense to have .value
as an n-tuple, like (I assume) LEDCollection
already is.
Thought about it a bit:
Inheriting LEDCollection will bring CompositeOutputDevice and value will be a tuple of booleans.
A couple of methods:
which would obviously set the tuple in the .value property
Just having had another look at the docs, I wonder if it would make more sense to just inherit from LEDBoard, rather than LEDCollection? And then add the display
and decimal_point
methods that you mention. Being a geeky programmer type, I'd love there to be a hexdisplay
function too ;-)
I'll try to have a more in-depth look at #357 this evening, while these ideas are fresh in my mind.
I vote for hex too.
On 17 Oct 2016 17:10, "Andrew Scheller" notifications@github.com wrote:
Just having had another look at the docs http://gpiozero.readthedocs.io/en/v1.3.1/api_boards.html#ledboard, I wonder if it would make more sense to just inherit from LEDBoard, rather than LEDCollection? And then add the display and decimal_point methods that you mention. Being a geeky programmer type, I'd love there to be a hexdisplay function too ;-)
I'll try to have a more in-depth look at #357 https://github.com/RPi-Distro/python-gpiozero/issues/357 this evening, while these ideas are fresh in my mind.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/RPi-Distro/python-gpiozero/issues/485#issuecomment-254236118, or mute the thread https://github.com/notifications/unsubscribe-auth/ASiRnOxKFhG3yehJrxRNx-Bpuy-FKZw4ks5q04__gaJpZM4KYjMj .
First stab in the dark at SevenSegmentDisplay:
It needs a display_hex
function.
Some thoughts:
from gpiozero import LEDCollection, LEDBoard
from time import sleep
class SevenSegmentDisplay(LEDBoard):
layouts = {"1": (False, True, True, False, False, False, False),
"2": (True, True, False, True, True, False, True),
"3": (True, True, True, True, False, False, True),
"4": (False, True, True, False, False, True, True),
"5": (True, False, True, True, False, True, True),
"6": (True, False, True, True, True, True, True),
"7": (True, True, True, False, False, False, False),
"8": (True, True, True, True, True, True, True),
"9": (True, True, True, True, False, True, True),
"0": (True, True, True, True, True, True, False),
" ": (False, False, False, False, False, False, False),
"A": (True, True, True, False, True, True, True),
"B": (True, True, True, True, True, True, True),
"C": (True, False, False, True, True, True, False),
"D": (False, True, True, True, True, False, True),
"E": (True, False, False, True, True, True, True),
"F": (True, False, False, False, True, True, True),
"G": (True, False, True, True, True, True, False),
"H": (False, True, True, False, True, True, True)}
def __init__(self, *pins, **kwargs):
# 7 segment displays must have 8 pins
if len(pins) < 7 or len(pins) > 8:
raise ValueError('7 segment display must have 7 or 8 pins')
# Don't allow 7 segments to contain collections
for pin in pins:
assert not isinstance(pin, LEDCollection)
pwm = kwargs.pop('pwm', False)
active_high = kwargs.pop('active_high', True)
super(SevenSegmentDisplay, self).__init__(*pins, pwm=pwm, active_high=active_high)
def display(self, char):
char = char.upper()
if char in SevenSegmentDisplay.layouts.keys():
layout = SevenSegmentDisplay.layouts[char]
for led in range(0,7):
self[led].value = layout[led]
def decimal_point(self, on):
# does the 7seg display have a decimal point (i.e pin 8)
if len(self) > 7:
self[7].value = on
Looking good...
Some comments: (apologies if there's too much here!)
display
method should throw an exception if you try to show an invalid char, which is easiest to do if you just remove the if char in SevenSegmentDisplay.layouts.keys():
linedisplay
method should clear the decimal point? Perhaps display could have a clear_decimal_point=True
parameter?value
can always be set from a 7-tuple or an 8-tuple, regardless of whether this 7-segment has a dp or not (with the dp being ignored as necessary) ? This woud make it easier to chain source
and values
.for led in range(0,7): self[led].value = layout[led]
could then be replaced by self.value = layout
from time import sleep
;-)range(0,7)
is the same as range(7)
;-)if x in somedict.keys():
is the same as if x in somedict:
char = char.upper()
to char = str(char).upper()
then it'd also work with intschar
to a str
, you should check that it has a len
of 1, and throw a ValueError otherwisedecimal_point
could be made a (gettable and settable) property?Common anode / cathode is supported by the active_high property, this could be changed to common_cathode to make it more descriptive
For consistency, it should remain as active_high
. You could always enhance the active_high docstring to make it clearer, as RGBLED does.
It needs a display_hex function.
That's easy:
def display_hex(self, hexnumber):
self.display(hex(hexnumber)[2:])
Should pins be passed in as a, b, c, d, e, f, g...
There's part of me that still wonders if that's the best approach (see my comments in https://github.com/RPi-Distro/python-gpiozero/issues/357#issuecomment-254356623 ) as that way it'd create a namedtuple, so you could do sevenseg.b.on() in addition to sevenseg[1].on()
@lurch Thanks for the comments, they are really useful.
Closing issue, PR #488 submitted.
Im going to be using a 7 seg display in an upcoming project, so I thought it was time it was added to gpiozero, can I get some comments on my thinking so far:
Next step would be to create a multi digit 7 segment display. The way these work (generally) is that in addition to the 8 pins for the display they have additional pins to state which digit should be turned on. To make each digit show a different number you would use plexing to flash individual digits to give the appearance of a multi digit display.