Skip to content

Commit ab19bce

Browse files
committed
Merge branch 'master' of https://github.com/adafruit/Adafruit_CircuitPython_Debouncer into use-monotonic-ns
2 parents 5e099ac + a533c4b commit ab19bce

File tree

7 files changed

+172
-85
lines changed

7 files changed

+172
-85
lines changed

.github/workflows/build.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Build CI
2+
3+
on: [pull_request, push]
4+
5+
jobs:
6+
test:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- name: Dump GitHub context
10+
env:
11+
GITHUB_CONTEXT: ${{ toJson(github) }}
12+
run: echo "$GITHUB_CONTEXT"
13+
- name: Translate Repo Name For Build Tools filename_prefix
14+
id: repo-name
15+
run: |
16+
echo ::set-output name=repo-name::$(
17+
echo ${{ github.repository }} |
18+
awk -F '\/' '{ print tolower($2) }' |
19+
tr '_' '-'
20+
)
21+
- name: Set up Python 3.6
22+
uses: actions/setup-python@v1
23+
with:
24+
python-version: 3.6
25+
- name: Versions
26+
run: |
27+
python3 --version
28+
- name: Checkout Current Repo
29+
uses: actions/checkout@v1
30+
with:
31+
submodules: true
32+
- name: Checkout tools repo
33+
uses: actions/checkout@v2
34+
with:
35+
repository: adafruit/actions-ci-circuitpython-libs
36+
path: actions-ci
37+
- name: Install deps
38+
run: |
39+
source actions-ci/install.sh
40+
- name: Library version
41+
run: git describe --dirty --always --tags
42+
- name: PyLint
43+
run: |
44+
pylint $( find . -path './adafruit*.py' )
45+
([[ ! -d "examples" ]] || pylint --disable=missing-docstring,invalid-name,bad-whitespace examples/*.py)
46+
- name: Build assets
47+
run: circuitpython-build-bundles --filename_prefix ${{ steps.repo-name.outputs.repo-name }} --library_location .
48+
- name: Build docs
49+
working-directory: docs
50+
run: sphinx-build -E -W -b html . _build/html

.github/workflows/release.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: Release Actions
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
upload-release-assets:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Dump GitHub context
12+
env:
13+
GITHUB_CONTEXT: ${{ toJson(github) }}
14+
run: echo "$GITHUB_CONTEXT"
15+
- name: Translate Repo Name For Build Tools filename_prefix
16+
id: repo-name
17+
run: |
18+
echo ::set-output name=repo-name::$(
19+
echo ${{ github.repository }} |
20+
awk -F '\/' '{ print tolower($2) }' |
21+
tr '_' '-'
22+
)
23+
- name: Set up Python 3.6
24+
uses: actions/setup-python@v1
25+
with:
26+
python-version: 3.6
27+
- name: Versions
28+
run: |
29+
python3 --version
30+
- name: Checkout Current Repo
31+
uses: actions/checkout@v1
32+
with:
33+
submodules: true
34+
- name: Checkout tools repo
35+
uses: actions/checkout@v2
36+
with:
37+
repository: adafruit/actions-ci-circuitpython-libs
38+
path: actions-ci
39+
- name: Install deps
40+
run: |
41+
source actions-ci/install.sh
42+
- name: Build assets
43+
run: circuitpython-build-bundles --filename_prefix ${{ steps.repo-name.outputs.repo-name }} --library_location .
44+
- name: Upload Release Assets
45+
# the 'official' actions version does not yet support dynamically
46+
# supplying asset names to upload. @csexton's version chosen based on
47+
# discussion in the issue below, as its the simplest to implement and
48+
# allows for selecting files with a pattern.
49+
# https://github.com/actions/upload-release-asset/issues/4
50+
#uses: actions/upload-release-asset@v1.0.1
51+
uses: csexton/release-asset-action@master
52+
with:
53+
pattern: "bundles/*"
54+
github-token: ${{ secrets.GITHUB_TOKEN }}
55+
56+
upload-pypi:
57+
runs-on: ubuntu-latest
58+
steps:
59+
- uses: actions/checkout@v1
60+
- name: Check For setup.py
61+
id: need-pypi
62+
run: |
63+
echo ::set-output name=setup-py::$( find . -wholename './setup.py' )
64+
- name: Set up Python
65+
if: contains(steps.need-pypi.outputs.setup-py, 'setup.py')
66+
uses: actions/setup-python@v1
67+
with:
68+
python-version: '3.x'
69+
- name: Install dependencies
70+
if: contains(steps.need-pypi.outputs.setup-py, 'setup.py')
71+
run: |
72+
python -m pip install --upgrade pip
73+
pip install setuptools wheel twine
74+
- name: Build and publish
75+
if: contains(steps.need-pypi.outputs.setup-py, 'setup.py')
76+
env:
77+
TWINE_USERNAME: ${{ secrets.pypi_username }}
78+
TWINE_PASSWORD: ${{ secrets.pypi_password }}
79+
run: |
80+
python setup.py sdist
81+
twine upload dist/*

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
21
*.mpy

.travis.yml

Lines changed: 0 additions & 33 deletions
This file was deleted.

README.rst

Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ Introduction
99
:target: https://discord.gg/nBQh6qu
1010
:alt: Discord
1111

12-
.. image:: https://travis-ci.com/adafruit/Adafruit_CircuitPython_Debouncer.svg?branch=master
13-
:target: https://travis-ci.com/adafruit/Adafruit_CircuitPython_Debouncer
12+
.. image:: https://github.com/adafruit/Adafruit_CircuitPython_Debouncer/workflows/Build%20CI/badge.svg
13+
:target: https://github.com/adafruit/Adafruit_CircuitPython_Debouncer/actions/
1414
:alt: Build Status
1515

1616
Debounces an arbitrary predicate function (typically created as a lambda) of 0 arguments.
@@ -61,52 +61,7 @@ Contributions are welcome! Please read our `Code of Conduct
6161
<https://github.com/adafruit/Adafruit_CircuitPython_debouncer/blob/master/CODE_OF_CONDUCT.md>`_
6262
before contributing to help this project stay welcoming.
6363

64-
Building locally
65-
================
66-
67-
Zip release files
68-
-----------------
69-
70-
To build this library locally you'll need to install the
71-
`circuitpython-build-tools <https://github.com/adafruit/circuitpython-build-tools>`_ package.
72-
73-
.. code-block:: shell
74-
75-
python3 -m venv .env
76-
source .env/bin/activate
77-
pip install circuitpython-build-tools
78-
79-
Once installed, make sure you are in the virtual environment:
80-
81-
.. code-block:: shell
82-
83-
source .env/bin/activate
84-
85-
Then run the build:
86-
87-
.. code-block:: shell
88-
89-
circuitpython-build-bundles --filename_prefix adafruit-circuitpython-debouncer --library_location .
90-
91-
Sphinx documentation
92-
-----------------------
93-
94-
Sphinx is used to build the documentation based on rST files and comments in the code. First,
95-
install dependencies (feel free to reuse the virtual environment from above):
96-
97-
.. code-block:: shell
98-
99-
python3 -m venv .env
100-
source .env/bin/activate
101-
pip install Sphinx sphinx-rtd-theme
102-
103-
Now, once you have the virtual environment activated:
104-
105-
.. code-block:: shell
106-
107-
cd docs
108-
sphinx-build -E -W -b html . _build/html
64+
Documentation
65+
=============
10966

110-
This will output the documentation to ``docs/_build/html``. Open the index.html in your browser to
111-
view them. It will also (due to -W) error out on any warning like Travis will. This is a good way to
112-
locally verify it will pass.
67+
For information on building library documentation, please check out `this guide <https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/sharing-our-docs-on-readthedocs#sphinx-5-1>`_.

adafruit_debouncer.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class Debouncer(object):
7979

8080
def __init__(self, io_or_predicate, interval=0.010):
8181
"""Make am instance.
82-
:param DigitalInOut/function io_or_predicate: the pin (from board) to debounce
82+
:param DigitalInOut/function io_or_predicate: the DigitalIO or function to debounce
8383
:param int interval: bounce threshold in seconds (default is 0.010, i.e. 10 milliseconds)
8484
"""
8585
self.state = 0x00
@@ -91,6 +91,8 @@ def __init__(self, io_or_predicate, interval=0.010):
9191
self._set_state(_DEBOUNCED_STATE | _UNSTABLE_STATE)
9292
self.previous_time = 0
9393
self.interval = interval
94+
self._previous_state_duration = 0
95+
self._state_changed_time = 0
9496

9597

9698
def _set_state(self, bits):
@@ -123,6 +125,8 @@ def update(self):
123125
self.previous_time = now
124126
self._toggle_state(_DEBOUNCED_STATE)
125127
self._set_state(_CHANGED_STATE)
128+
self._previous_state_duration = now - self._state_changed_time
129+
self._state_changed_time = now
126130

127131
@property
128132
def interval(self):
@@ -151,3 +155,13 @@ def rose(self):
151155
def fell(self):
152156
"""Return whether the debounced value went from high to low at the most recent update."""
153157
return (not self._get_state(_DEBOUNCED_STATE)) and self._get_state(_CHANGED_STATE)
158+
159+
@property
160+
def last_duration(self):
161+
"""Return the amount of time the state was stable prior to the most recent transition."""
162+
return self._previous_state_duration
163+
164+
@property
165+
def current_duration(self):
166+
"""Return the time since the most recent transition."""
167+
return time.monotonic() - self._state_changed_time

examples/debouncer_timing_test.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import time
2+
import board
3+
from digitalio import DigitalInOut, Direction, Pull
4+
from adafruit_debouncer import Debouncer
5+
6+
button = DigitalInOut(board.D4)
7+
button.direction = Direction.INPUT
8+
button.pull = Pull.UP
9+
switch = Debouncer(button)
10+
11+
while True:
12+
switch.update()
13+
if switch.fell:
14+
print('pressed')
15+
print('was released for ', switch.last_duration)
16+
elif switch.rose:
17+
print('released')
18+
print('was pressed for ', switch.last_duration)
19+
else:
20+
print('Stable for ', switch.current_duration)
21+
time.sleep(0.1)

0 commit comments

Comments
 (0)