Skip to content

Mini Color TFT with Joystick FeatherWing #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Apr 12, 2019

Conversation

makermelissa
Copy link
Collaborator

Here's my take on a Mini TFT with Joystick FeatherWing Library. This one is complete with simpletest and documentation changes.

@makermelissa makermelissa requested a review from a team April 10, 2019 05:40
if spi is None:
spi = board.SPI()
self._ss = Seesaw(i2c, address)
self._button_mask = const((1 << BUTTON_RIGHT) |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this const() does nothing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be a class attribute, not an object attribute

if spi is None:
spi = board.SPI()
self._ss = Seesaw(i2c, address)
self._button_mask = const((1 << BUTTON_RIGHT) |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be a class attribute, not an object attribute


@property
def _buttons(self):
return self._ss.digital_read_bulk(self._button_mask)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there could be some caching here, so that if we want to check 5 different buttons, we don't make 5 separate calls to the seesaw.

Copy link
Contributor

@deshipu deshipu Apr 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if there was just a buttons property, that would return a named tuple of True/False values for all the buttons at once? Then you could do:

buttons = wing.buttons
if buttons.right:
    ...
elif buttons.left:
    ...

"""
Returns the display object for doing fun displayio stuff on
"""
return self._display
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason for this to be a property and not a straightforward attribute?


@property
def _buttons(self):
return self._ss.digital_read_bulk(self._button_mask)
Copy link
Contributor

@deshipu deshipu Apr 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if there was just a buttons property, that would return a named tuple of True/False values for all the buttons at once? Then you could do:

buttons = wing.buttons
if buttons.right:
    ...
elif buttons.left:
    ...

@hexthat
Copy link
Contributor

hexthat commented Apr 10, 2019

with this how do you adjust the brightness?

@makermelissa
Copy link
Collaborator Author

Good point @hexthat. I’ll add that.

@makermelissa
Copy link
Collaborator Author

Thanks @deshipu for reviewing this. I’ll make some changes tonight.

@deshipu
Copy link
Contributor

deshipu commented Apr 10, 2019

I'm playing with PyBadge now, and I came up with this code for the buttons for it:

import board
import digitalio
import bitbangio
import time
import collections


Buttons = collections.namedtuple('Buttons',
                                 'left up down right select start a b')


class PyBadgeButtons:
    def __init__(self):
        self._bus = bitbangio.SPI(clock=board.BUTTON_CLOCK,
                                  MISO=board.BUTTON_OUT)
        while not self._bus.try_lock():
            pass
        self._bus.configure(polarity=1, phase=1)
        self._latch = digitalio.DigitalInOut(board.BUTTON_LATCH)
        self._latch.switch_to_output(value=0)
        self._buffer = bytearray(1)

    @property
    def pressed(self):
        self._latch.value = 1
        self._bus.readinto(self._buffer)
        self._latch.value = 0
        pressed = self._buffer[0]
        return Buttons(*[bool(pressed & (1 << button)) for button in range(8)])


buttons = PyBadgeButtons()
while True:
    print(buttons.pressed)
    time.sleep(1)

I think we could use something very similar here.

@makermelissa makermelissa requested a review from deshipu April 11, 2019 05:02
@makermelissa
Copy link
Collaborator Author

Ok, backlight added, unnecessary const() removed, display is an attribute, and buttons returned as named tuple so they are only read once per loop instead of 7 times.

Copy link
Contributor

@deshipu deshipu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, some nit-picks.

(1 << BUTTON_UP) |
(1 << BUTTON_SEL) |
(1 << BUTTON_A) |
(1 << BUTTON_B))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can you put this on the class, like this:

class MiniTFTFeatherWing:
    _button_mask = ((1 << BUTTON_RIGHT) |
                 (1 << BUTTON_DOWN) |
                 (1 << BUTTON_LEFT) |
                 (1 << BUTTON_UP) |
                 (1 << BUTTON_SEL) |
                 (1 << BUTTON_A) |
                 (1 << BUTTON_B))

    def __init_(self, ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you do this as well? I think making it a property is wasteful.

"""
Return a set of buttons with current push values
"""
buttons = namedtuple("Buttons", "up down left right a b select")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this outside the class, where the constants are, so that users have access to it? Also, since it's a type, it should start with upper case letter.

right=(not button_values & (1 << BUTTON_RIGHT)),
a=(not button_values & (1 << BUTTON_A)),
b=(not button_values & (1 << BUTTON_B)),
select=(not button_values & (1 << BUTTON_SEL)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can write this as:

return Buttons(*[not button_values & (1 << button) for button in
                 (BUTTON_UP, BUTTON_DOWN, BUTTON_LEFT, BUTTON_RIGHT, BUTTON_A, BUTTON_B,BUTTON_SEL)])

@makermelissa makermelissa requested a review from deshipu April 12, 2019 00:52
@makermelissa
Copy link
Collaborator Author

Ok, requested changes implemented.

@deshipu deshipu merged commit d047cf8 into adafruit:master Apr 12, 2019
@deshipu
Copy link
Contributor

deshipu commented Apr 12, 2019

Thank you, it looks great!

adafruit-adabot added a commit to adafruit/Adafruit_CircuitPython_Bundle that referenced this pull request Apr 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants