Skip to content
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

DigitalReader last_pressed and last_triggered #62

Merged
merged 17 commits into from Feb 1, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/publish_docs.yml
Expand Up @@ -6,7 +6,6 @@ on:
push:
branches:
- main
- mjj/more_docs

jobs:
deploy:
Expand Down
2 changes: 1 addition & 1 deletion contrib/polyrhythmic_sequencer.py
Expand Up @@ -149,7 +149,7 @@ def _trigger_seq(self, step):
return int(status[1]) == 1, int(status[0]) == 1

def show_menu_header(self):
if ticks_diff(ticks_ms(), b1.last_pressed) < MENU_DURATION:
if ticks_diff(ticks_ms(), b1.last_pressed()) < MENU_DURATION:
oled.fill_rect(0, 0, OLED_WIDTH, CHAR_HEIGHT, 1)
oled.text(f"{self.pages[self.page]}", 0, 0, 0)

Expand Down
1 change: 1 addition & 0 deletions docs/.gitignore
@@ -1 +1,2 @@
generated
_build
20 changes: 14 additions & 6 deletions software/README.md
Expand Up @@ -49,26 +49,34 @@ If you really want to avoid 'noise' which would present as a flickering value de
The ADCs used to read the knob position are only 12 bit, which means that any read_position value above 4096 (2^12) will not actually be any finer resolution, but will instead just go up in steps. For example using 8192 would only return values which go up in steps of 2.


## Digital Input and Buttons
## Digital Input

It may seem a little strange to see the digital input and buttons grouped together, but if you think about it, all the button is doing is create an internal digital input when you press it. For this reason, the method for handling the event that should happen when either a button is pressed or a digital input detected is the same.

A class is used named 'DigitalInput' in the europi.py library, which handles both the debounce (only used for buttons) and the handler (what happens when a press/input is detected).
The Digital Input jack can detect a HIGH signal when recieving voltage > 0.8v and will be LOW when below.

| Method | Usage | Parameter(s) |
| ------------- | ----------- | ----------- |
|value|Reads the current value of the input, HIGH (1) or LOW (0).|
|handler|Assign a new function to be used as the handler|function
|reset_handler|Detach the handler method from the Pin IRQ|
|last_trigger|Return the time in milliseconds of the last trigger.|

It should be noted that the value will be 0 when the input is 'high', and 1 when 'low'. This is simply a hardware technicality, but will not affect the use of the handler, only the .value() mathod.
awonak marked this conversation as resolved.
Show resolved Hide resolved

To use the handler method, you simply define whatever you want to happen when a button or the digital input is triggered, and then use x.handler(new_function). Do not include the brackets for the function, and replace the 'x' in the example with the name of your input, either b1, b2, or din.

Button instances have an attribute `last_pressed` which can be used to perform some action or behavior relative to when the button was last pressed. For example, if you want to display that a button was pressed, you could add the following code to your main script loop:
## Button

| Method | Usage | Parameter(s) |
| ------------- | ----------- | ----------- |
|value|Reads the current value of the input, HIGH (1) or LOW (0).|
|handler|Assign a new function to be used as the handler|function
|reset_handler|Detach the handler methods from the Pin IRQ|
|last_pressed|Return the time in milliseconds when the button was last pressed.|

Button instances have a method `last_pressed()` which can be used to perform some action or behavior relative to when the button was last pressed. For example, if you want to display that a button was pressed, you could add the following code to your main script loop:

```python
if ticks_diff(ticks_ms(), b1.last_pressed) < 2000:
if ticks_diff(ticks_ms(), b1.last_pressed()) < 2000:
# Do something for two seconds after button press.
display_button_pressed()
```
Expand Down
14 changes: 11 additions & 3 deletions software/firmware/europi.py
Expand Up @@ -171,7 +171,7 @@ class DigitalReader:
def __init__(self, pin, debounce_delay=500):
self.pin = Pin(pin, Pin.IN)
self.debounce_delay = debounce_delay
self.last_pressed = 0
self.last_rising_ms = 0

def value(self):
"""The current binary value, HIGH (1) or LOW (0)."""
Expand All @@ -183,8 +183,8 @@ def value(self):
def handler(self, func):
"""Define the callback func to call when rising edge detected."""
def bounce_wrapper(pin):
if (time.ticks_ms() - self.last_pressed) > self.debounce_delay:
self.last_pressed = time.ticks_ms()
if time.ticks_diff(time.ticks_ms(), self.last_rising_ms) > self.debounce_delay:
self.last_rising_ms = time.ticks_ms()
func()
# Both the digital input and buttons are normally high, and 'pulled'
# low when on, so here we use IRQ_FALLING to detect rising edge.
Expand All @@ -198,12 +198,20 @@ class DigitalInput(DigitalReader):
"""A class for handling reading of the digital input."""
def __init__(self, pin, debounce_delay=0):
super().__init__(pin, debounce_delay)

def last_trigger(self):
"""Return the time in milliseconds of the last trigger."""
return self.last_rising_ms


class Button(DigitalReader):
"""A class for handling push button behavior."""
def __init__(self, pin, debounce_delay=200):
super().__init__(pin, debounce_delay)

def last_pressed(self):
"""Return the time in milliseconds when the button was last pressed."""
return self.last_rising_ms


class Display(SSD1306_I2C):
Expand Down