Compare commits
51 commits
pi_bitbang
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4f66fa039 | ||
|
|
7e5c1b807e | ||
|
|
d8f4d092c1 | ||
|
|
04854c340b | ||
|
|
21310b27f8 | ||
|
|
694fdecb7e | ||
|
|
0e9a311e73 | ||
|
|
8b01d1057d | ||
|
|
1f3b0053f7 | ||
|
|
62e645efd9 | ||
|
|
11e10957a7 | ||
|
|
d8ccc5a0b8 | ||
|
|
0ea1ce9a55 | ||
|
|
de73bcbeb1 | ||
|
|
171e8e980d | ||
|
|
f5bf2cb94a | ||
|
|
84eadeafa9 | ||
|
|
a9c8fbbd8f | ||
|
|
010e691868 | ||
|
|
d8a8fb1fbd | ||
|
|
e24d6f5335 | ||
|
|
290c2cf771 | ||
|
|
49f57d3cdf | ||
|
|
0509ac9cc9 | ||
|
|
ba06384b47 | ||
|
|
99d89ae70c | ||
|
|
84f138f99d | ||
|
|
dd29815841 | ||
|
|
6efcd0193e | ||
|
|
01e89a8437 | ||
|
|
4397b48299 | ||
|
|
e708de0a64 | ||
|
|
be5b20480c | ||
|
|
9715821e2a | ||
|
|
b726925ac2 | ||
|
|
198e70d33d | ||
|
|
294502c624 | ||
|
|
02758607e2 | ||
|
|
d17f1179af | ||
|
|
045d6f8bc7 | ||
|
|
409e90902a | ||
|
|
0ad0510dd1 | ||
|
|
73e4fe8fff | ||
|
|
2886aeaf51 | ||
|
|
2d4f5469bc | ||
|
|
91b53dd5a7 | ||
|
|
f7279ea4ec | ||
|
|
8c184d4051 | ||
|
|
03c24157d4 | ||
|
|
2165d38129 | ||
|
|
242f7ab2d4 |
15 changed files with 519 additions and 343 deletions
57
.github/workflows/build.yml
vendored
Normal file
57
.github/workflows/build.yml
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
name: Build CI
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- name: Translate Repo Name For Build Tools filename_prefix
|
||||
id: repo-name
|
||||
run: |
|
||||
echo ::set-output name=repo-name::$(
|
||||
echo ${{ github.repository }} |
|
||||
awk -F '\/' '{ print tolower($2) }' |
|
||||
tr '_' '-'
|
||||
)
|
||||
- name: Set up Python 3.6
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.6
|
||||
- name: Versions
|
||||
run: |
|
||||
python3 --version
|
||||
- name: Checkout Current Repo
|
||||
uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: true
|
||||
- name: Checkout tools repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: adafruit/actions-ci-circuitpython-libs
|
||||
path: actions-ci
|
||||
- name: Install dependencies
|
||||
# (e.g. - apt-get: gettext, etc; pip: circuitpython-build-tools, requirements.txt; etc.)
|
||||
run: |
|
||||
source actions-ci/install.sh
|
||||
- name: Pip install pylint, black, & Sphinx
|
||||
run: |
|
||||
pip install pylint black==19.10b0 Sphinx sphinx-rtd-theme
|
||||
- name: Library version
|
||||
run: git describe --dirty --always --tags
|
||||
- name: Check formatting
|
||||
run: |
|
||||
black --check --target-version=py35 .
|
||||
- name: PyLint
|
||||
run: |
|
||||
pylint $( find . -path './adafruit*.py' )
|
||||
([[ ! -d "examples" ]] || pylint --disable=missing-docstring,invalid-name,bad-whitespace $( find . -path "./examples/*.py" ))
|
||||
- name: Build assets
|
||||
run: circuitpython-build-bundles --filename_prefix ${{ steps.repo-name.outputs.repo-name }} --library_location .
|
||||
- name: Build docs
|
||||
working-directory: docs
|
||||
run: sphinx-build -E -W -b html . _build/html
|
||||
81
.github/workflows/release.yml
vendored
Normal file
81
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
name: Release Actions
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
upload-release-assets:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- name: Translate Repo Name For Build Tools filename_prefix
|
||||
id: repo-name
|
||||
run: |
|
||||
echo ::set-output name=repo-name::$(
|
||||
echo ${{ github.repository }} |
|
||||
awk -F '\/' '{ print tolower($2) }' |
|
||||
tr '_' '-'
|
||||
)
|
||||
- name: Set up Python 3.6
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.6
|
||||
- name: Versions
|
||||
run: |
|
||||
python3 --version
|
||||
- name: Checkout Current Repo
|
||||
uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: true
|
||||
- name: Checkout tools repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: adafruit/actions-ci-circuitpython-libs
|
||||
path: actions-ci
|
||||
- name: Install deps
|
||||
run: |
|
||||
source actions-ci/install.sh
|
||||
- name: Build assets
|
||||
run: circuitpython-build-bundles --filename_prefix ${{ steps.repo-name.outputs.repo-name }} --library_location .
|
||||
- name: Upload Release Assets
|
||||
# the 'official' actions version does not yet support dynamically
|
||||
# supplying asset names to upload. @csexton's version chosen based on
|
||||
# discussion in the issue below, as its the simplest to implement and
|
||||
# allows for selecting files with a pattern.
|
||||
# https://github.com/actions/upload-release-asset/issues/4
|
||||
#uses: actions/upload-release-asset@v1.0.1
|
||||
uses: csexton/release-asset-action@master
|
||||
with:
|
||||
pattern: "bundles/*"
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
upload-pypi:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Check For setup.py
|
||||
id: need-pypi
|
||||
run: |
|
||||
echo ::set-output name=setup-py::$( find . -wholename './setup.py' )
|
||||
- name: Set up Python
|
||||
if: contains(steps.need-pypi.outputs.setup-py, 'setup.py')
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install dependencies
|
||||
if: contains(steps.need-pypi.outputs.setup-py, 'setup.py')
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install setuptools wheel twine
|
||||
- name: Build and publish
|
||||
if: contains(steps.need-pypi.outputs.setup-py, 'setup.py')
|
||||
env:
|
||||
TWINE_USERNAME: ${{ secrets.pypi_username }}
|
||||
TWINE_PASSWORD: ${{ secrets.pypi_password }}
|
||||
run: |
|
||||
python setup.py sdist
|
||||
twine upload dist/*
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -4,7 +4,6 @@ __pycache__
|
|||
_build
|
||||
*.pyc
|
||||
.env
|
||||
build*
|
||||
bundles
|
||||
*.DS_Store
|
||||
.eggs
|
||||
|
|
|
|||
16
.pylintrc
16
.pylintrc
|
|
@ -18,6 +18,7 @@ ignore-patterns=
|
|||
#init-hook=
|
||||
|
||||
# Use multiple processes to speed up Pylint.
|
||||
# jobs=1
|
||||
jobs=2
|
||||
|
||||
# List of plugins (as comma separated values of python modules names) to load,
|
||||
|
|
@ -50,7 +51,8 @@ confidence=
|
|||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||
# --disable=W"
|
||||
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error
|
||||
# disable=import-error,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
|
||||
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,bad-continuation
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
|
|
@ -117,7 +119,8 @@ spelling-store-unknown-words=no
|
|||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=FIXME,XXX,TODO
|
||||
# notes=FIXME,XXX,TODO
|
||||
notes=FIXME,XXX
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
|
@ -200,6 +203,7 @@ redefining-builtins-modules=six.moves,future.builtins
|
|||
[FORMAT]
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
# expected-line-ending-format=
|
||||
expected-line-ending-format=LF
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
|
|
@ -272,9 +276,11 @@ class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
|||
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
||||
|
||||
# Naming hint for class names
|
||||
# class-name-hint=[A-Z_][a-zA-Z0-9]+$
|
||||
class-name-hint=[A-Z_][a-zA-Z0-9_]+$
|
||||
|
||||
# Regular expression matching correct class names
|
||||
# class-rgx=[A-Z_][a-zA-Z0-9]+$
|
||||
class-rgx=[A-Z_][a-zA-Z0-9_]+$
|
||||
|
||||
# Naming hint for constant names
|
||||
|
|
@ -294,7 +300,8 @@ function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
|||
function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma
|
||||
good-names=r,g,b,i,j,k,n,ex,Run,_
|
||||
# good-names=i,j,k,ex,Run,_
|
||||
good-names=r,g,b,w,i,j,k,n,x,y,z,ex,ok,Run,_
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name
|
||||
include-naming-hint=no
|
||||
|
|
@ -391,6 +398,7 @@ valid-metaclass-classmethod-first-arg=mcs
|
|||
max-args=5
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
# max-attributes=7
|
||||
max-attributes=11
|
||||
|
||||
# Maximum number of boolean expressions in a if statement
|
||||
|
|
@ -415,7 +423,7 @@ max-returns=6
|
|||
max-statements=50
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=2
|
||||
min-public-methods=1
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
|
|
|||
32
.travis.yml
32
.travis.yml
|
|
@ -1,32 +0,0 @@
|
|||
dist: trusty
|
||||
sudo: false
|
||||
language: python
|
||||
python:
|
||||
- '3.6'
|
||||
cache:
|
||||
pip: true
|
||||
deploy:
|
||||
- provider: releases
|
||||
api_key: "$GITHUB_TOKEN"
|
||||
file_glob: true
|
||||
file: "$TRAVIS_BUILD_DIR/bundles/*"
|
||||
skip_cleanup: true
|
||||
overwrite: true
|
||||
on:
|
||||
tags: true
|
||||
- provider: pypi
|
||||
user: adafruit-travis
|
||||
on:
|
||||
tags: true
|
||||
password:
|
||||
secure: uLzy5y4iRH61pHF6yRKKii+JmWHLu8VDrSHsrHz3ofRTCr6EPEnvj+8kpo7QHTDAsc4ylg0S7PB2nmIS5LJ9tTJw2w8bAK+7BV2sdcabuZbzKh+CNb2SwFBX6LxzwxLBNyfVPOh5Zd+Tk04EePUGC/aIuSQ0UiEDbuUEA5FGHtj3czjMOZs1VkGt3dTZjlnkDimJtUDDvaYzGQp4cy2+hc/m4J2a7KgNkSbKJ4PCfiU2K6tnGPbz1q28oYYHfdWHcEP1Dy9JrA3dtXiudmDAVb4S2viTQdaUddZ1sOkRdri2Q93vVOVMdG0x1sCmn5IYDTw6FIInyL+2Rt9TjqgdH4WT94gYJof79nTBTDcGvYhxOybC0+16uZcfCjx5HKLTry38Du81vUEEBGXl8M+rH3p5wZpUr21q933jR18yNlkai9IGtQIR0xgUl2wi+dzxD/XHNCM7DdRB/oCo7pUurw/s5XVi4lhnoByK39H9aA/cZmlwCaUdYc04ADK9WSaHVUDr6/A6Gjp3LykVBVUzrdpyozKFXDdvW2Q8KaA3XyTcfKO92e0EihAr6dJdcYp1STUck4wNQLBefqAVVEUUeTruFTyVoIu5P0b1qMtK69dxAzVJpJ64l8hETZ8kLH3YkG1ergg5pYHPs8KNxhIcG8DfFNyccpjuP1uMwm4F6EY=
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
- pip install pylint circuitpython-build-tools Sphinx sphinx-rtd-theme
|
||||
- pip install --force-reinstall pylint==1.9.2
|
||||
script:
|
||||
- pylint adafruit_dotstar.py
|
||||
- ([[ ! -d "examples" ]] || pylint --disable=missing-docstring,invalid-name examples/*.py)
|
||||
- circuitpython-build-bundles --filename_prefix adafruit-circuitpython-dotstar --library_location
|
||||
.
|
||||
- cd docs && sphinx-build -E -W -b html . _build/html && cd ..
|
||||
|
|
@ -34,13 +34,15 @@ Examples of unacceptable behavior by participants include:
|
|||
* Excessive or unwelcome helping; answering outside the scope of the question
|
||||
asked
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Promoting or spreading disinformation, lies, or conspiracy theories against
|
||||
a person, group, organisation, project, or community
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate
|
||||
|
||||
The goal of the standards and moderation guidelines outlined here is to build
|
||||
and maintain a respectful community. We ask that you don’t just aim to be
|
||||
and maintain a respectful community. We ask that you don’t just aim to be
|
||||
"technically unimpeachable", but rather try to be your best self.
|
||||
|
||||
We value many things beyond technical expertise, including collaboration and
|
||||
|
|
@ -72,10 +74,10 @@ You may report in the following ways:
|
|||
In any situation, you may send an email to <support@adafruit.com>.
|
||||
|
||||
On the Adafruit Discord, you may send an open message from any channel
|
||||
to all Community Helpers by tagging @community helpers. You may also send an
|
||||
open message from any channel, or a direct message to @kattni#1507,
|
||||
@tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, or
|
||||
@Andon#8175.
|
||||
to all Community Moderators by tagging @community moderators. You may
|
||||
also send an open message from any channel, or a direct message to
|
||||
@kattni#1507, @tannewt#4653, @Dan Halbert#1614, @cater#2442,
|
||||
@sommersoft#0222, @Mr. Certainly#0472 or @Andon#8175.
|
||||
|
||||
Email and direct message reports will be kept confidential.
|
||||
|
||||
|
|
@ -83,7 +85,7 @@ In situations on Discord where the issue is particularly egregious, possibly
|
|||
illegal, requires immediate action, or violates the Discord terms of service,
|
||||
you should also report the message directly to Discord.
|
||||
|
||||
These are the steps for upholding our community’s standards of conduct.
|
||||
These are the steps for upholding our community’s standards of conduct.
|
||||
|
||||
1. Any member of the community may report any situation that violates the
|
||||
Adafruit Community Code of Conduct. All reports will be reviewed and
|
||||
|
|
@ -124,4 +126,4 @@ For other projects adopting the Adafruit Community Code of
|
|||
Conduct, please contact the maintainers of those projects for enforcement.
|
||||
If you wish to use this code of conduct for your own project, consider
|
||||
explicitly mentioning your moderation policy or making a copy with your
|
||||
own moderation policy so as to avoid confusion.
|
||||
own moderation policy so as to avoid confusion.
|
||||
|
|
|
|||
79
README.rst
79
README.rst
|
|
@ -10,8 +10,8 @@ Adafruit CircuitPython DotStar
|
|||
:target: https://adafru.it/discord
|
||||
:alt: Discord
|
||||
|
||||
.. image:: https://travis-ci.org/adafruit/Adafruit_CircuitPython_DotStar.svg?branch=master
|
||||
:target: https://travis-ci.org/adafruit/Adafruit_CircuitPython_DotStar
|
||||
.. image:: https://github.com/adafruit/Adafruit_CircuitPython_DotStar/workflows/Build%20CI/badge.svg
|
||||
:target: https://github.com/adafruit/Adafruit_CircuitPython_DotStar/actions/
|
||||
:alt: Build Status
|
||||
|
||||
Higher level DotStar driver that presents the strip as a sequence. It is the
|
||||
|
|
@ -26,7 +26,7 @@ It should be a float. For example, (0xFF,0,0, 1.0) is the brightest red possible
|
|||
|
||||
.. note:: The int hex API represents the brightness of the white pixel when
|
||||
present by setting the RGB channels to identical values. For example, full
|
||||
white is 0xffffff but is actually (0xff, 0xff, 0xff) in the tuple syntax.
|
||||
white is 0xffffff but is actually (0xff, 0xff, 0xff) in the tuple syntax.
|
||||
|
||||
Dependencies
|
||||
=============
|
||||
|
|
@ -38,6 +38,31 @@ Please ensure all dependencies are available on the CircuitPython filesystem.
|
|||
This is easily achieved by downloading
|
||||
`the Adafruit library and driver bundle <https://github.com/adafruit/Adafruit_CircuitPython_Bundle>`_.
|
||||
|
||||
Installing from PyPI
|
||||
====================
|
||||
|
||||
On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from
|
||||
PyPI <https://pypi.org/project/adafruit-circuitpython-dotstar/>`_. To install for current user:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
pip3 install adafruit-circuitpython-dotstar
|
||||
|
||||
To install system-wide (this may be required in some cases):
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo pip3 install adafruit-circuitpython-dotstar
|
||||
|
||||
To install in a virtual environment in your current project:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
mkdir project-name && cd project-name
|
||||
python3 -m venv .env
|
||||
source .env/bin/activate
|
||||
pip3 install adafruit-circuitpython-dotstar
|
||||
|
||||
Usage Example
|
||||
=============
|
||||
|
||||
|
|
@ -60,49 +85,7 @@ Contributions are welcome! Please read our `Code of Conduct
|
|||
<https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel/blob/master/CODE_OF_CONDUCT.md>`_
|
||||
before contributing to help this project stay welcoming.
|
||||
|
||||
Building locally
|
||||
================
|
||||
Documentation
|
||||
=============
|
||||
|
||||
To build this library locally you'll need to install the
|
||||
`circuitpython-build-tools <https://github.com/adafruit/circuitpython-build-tools>`_ package.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python3 -m venv .env
|
||||
source .env/bin/activate
|
||||
pip install circuitpython-build-tools
|
||||
|
||||
Once installed, make sure you are in the virtual environment:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
source .env/bin/activate
|
||||
|
||||
Then run the build:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
circuitpython-build-bundles --filename_prefix adafruit-circuitpython-dotstar --library_location .
|
||||
|
||||
Sphinx documentation
|
||||
-----------------------
|
||||
|
||||
Sphinx is used to build the documentation based on rST files and comments in the code. First,
|
||||
install dependencies (feel free to reuse the virtual environment from above):
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python3 -m venv .env
|
||||
source .env/bin/activate
|
||||
pip install Sphinx sphinx-rtd-theme
|
||||
|
||||
Now, once you have the virtual environment activated:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cd docs
|
||||
sphinx-build -E -W -b html . _build/html
|
||||
|
||||
This will output the documentation to ``docs/_build/html``. Open the index.html in your browser to
|
||||
view them. It will also (due to -W) error out on any warning like Travis will. This is a good way to
|
||||
locally verify it will pass.
|
||||
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>`_.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
# Copyright (c) 2016 Damien P. George (original Neopixel object)
|
||||
# Copyright (c) 2017 Ladyada
|
||||
# Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
# Copyright (c) 2019 Roy Hooper
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -23,30 +24,46 @@
|
|||
# THE SOFTWARE.
|
||||
|
||||
"""
|
||||
`adafruit_dotstar` - DotStar strip driver
|
||||
====================================================
|
||||
`adafruit_dotstar` - DotStar strip driver (for CircuitPython 5.0+ with _pixelbuf)
|
||||
=================================================================================
|
||||
|
||||
* Author(s): Damien P. George, Limor Fried & Scott Shawcroft
|
||||
* Author(s): Damien P. George, Limor Fried, Scott Shawcroft & Roy Hooper
|
||||
"""
|
||||
|
||||
# pylint: disable=ungrouped-imports
|
||||
import sys
|
||||
import busio
|
||||
import digitalio
|
||||
|
||||
if sys.implementation.version[0] < 5:
|
||||
import adafruit_pypixelbuf as _pixelbuf
|
||||
else:
|
||||
try:
|
||||
import _pixelbuf
|
||||
except ImportError:
|
||||
import adafruit_pypixelbuf as _pixelbuf
|
||||
|
||||
__version__ = "0.0.0-auto.0"
|
||||
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DotStar.git"
|
||||
|
||||
START_HEADER_SIZE = 4
|
||||
LED_START = 0b11100000 # Three "1" bits, followed by 5 brightness bits
|
||||
|
||||
# Pixel color order constants
|
||||
RGB = (0, 1, 2)
|
||||
RBG = (0, 2, 1)
|
||||
GRB = (1, 0, 2)
|
||||
GBR = (1, 2, 0)
|
||||
BRG = (2, 0, 1)
|
||||
BGR = (2, 1, 0)
|
||||
RBG = "PRBG"
|
||||
"""Red Blue Green"""
|
||||
RGB = "PRGB"
|
||||
"""Red Green Blue"""
|
||||
GRB = "PGRB"
|
||||
"""Green Red Blue"""
|
||||
GBR = "PGBR"
|
||||
"""Green Blue Red"""
|
||||
BRG = "PBRG"
|
||||
"""Blue Red Green"""
|
||||
BGR = "PBGR"
|
||||
"""Blue Green Red"""
|
||||
|
||||
|
||||
class DotStar:
|
||||
class DotStar(_pixelbuf.PixelBuf):
|
||||
"""
|
||||
A sequence of dotstars.
|
||||
|
||||
|
|
@ -56,10 +73,13 @@ class DotStar:
|
|||
:param float brightness: Brightness of the pixels between 0.0 and 1.0
|
||||
:param bool auto_write: True if the dotstars should immediately change when
|
||||
set. If False, `show` must be called explicitly.
|
||||
:param tuple pixel_order: Set the pixel order on the strip - different
|
||||
:param str pixel_order: Set the pixel order on the strip - different
|
||||
strips implement this differently. If you send red, and it looks blue
|
||||
or green on the strip, modify this! It should be one of the values above
|
||||
|
||||
or green on the strip, modify this! It should be one of the values above.
|
||||
:param int baudrate: Desired clock rate if using hardware SPI (ignored if
|
||||
using 'soft' SPI). This is only a recommendation; the actual clock
|
||||
rate may be slightly different depending on what the system hardware
|
||||
can provide.
|
||||
|
||||
Example for Gemma M0:
|
||||
|
||||
|
|
@ -74,15 +94,41 @@ class DotStar:
|
|||
with adafruit_dotstar.DotStar(APA102_SCK, APA102_MOSI, 1) as pixels:
|
||||
pixels[0] = RED
|
||||
time.sleep(2)
|
||||
|
||||
.. py:method:: DotStar.show()
|
||||
|
||||
Shows the new colors on the dotstars themselves if they haven't already
|
||||
been autowritten.
|
||||
|
||||
The colors may or may not be showing after this function returns because
|
||||
it may be done asynchronously.
|
||||
|
||||
.. py:method:: DotStar.fill(color)
|
||||
|
||||
Colors all dotstars the given ***color***.
|
||||
|
||||
.. py:attribute:: brightness
|
||||
|
||||
Overall brightness of all dotstars (0 to 1.0)
|
||||
"""
|
||||
|
||||
def __init__(self, clock, data, n, *, brightness=1.0, auto_write=True, pixel_order=BGR):
|
||||
def __init__(
|
||||
self,
|
||||
clock,
|
||||
data,
|
||||
n,
|
||||
*,
|
||||
brightness=1.0,
|
||||
auto_write=True,
|
||||
pixel_order=BGR,
|
||||
baudrate=4000000
|
||||
):
|
||||
self._spi = None
|
||||
try:
|
||||
self._spi = busio.SPI(clock, MOSI=data)
|
||||
while not self._spi.try_lock():
|
||||
pass
|
||||
self._spi.configure(baudrate=4000000)
|
||||
self._spi.configure(baudrate=baudrate)
|
||||
|
||||
except (NotImplementedError, ValueError):
|
||||
self.dpin = digitalio.DigitalInOut(data)
|
||||
|
|
@ -90,36 +136,29 @@ class DotStar:
|
|||
self.dpin.direction = digitalio.Direction.OUTPUT
|
||||
self.cpin.direction = digitalio.Direction.OUTPUT
|
||||
self.cpin.value = False
|
||||
self._n = n
|
||||
|
||||
# Supply one extra clock cycle for each two pixels in the strip.
|
||||
self.end_header_size = n // 16
|
||||
trailer_size = n // 16
|
||||
if n % 16 != 0:
|
||||
self.end_header_size += 1
|
||||
self._buf = bytearray(n * 4 + START_HEADER_SIZE + self.end_header_size)
|
||||
self.end_header_index = len(self._buf) - self.end_header_size
|
||||
self.pixel_order = pixel_order
|
||||
# Four empty bytes to start.
|
||||
for i in range(START_HEADER_SIZE):
|
||||
self._buf[i] = 0x00
|
||||
# Mark the beginnings of each pixel.
|
||||
for i in range(START_HEADER_SIZE, self.end_header_index, 4):
|
||||
self._buf[i] = 0xff
|
||||
# 0xff bytes at the end.
|
||||
for i in range(self.end_header_index, len(self._buf)):
|
||||
self._buf[i] = 0xff
|
||||
self._brightness = 1.0
|
||||
# Set auto_write to False temporarily so brightness setter does _not_
|
||||
# call show() while in __init__.
|
||||
self.auto_write = False
|
||||
self.brightness = brightness
|
||||
self.auto_write = auto_write
|
||||
trailer_size += 1
|
||||
|
||||
# Four empty bytes for the header.
|
||||
header = bytearray(START_HEADER_SIZE)
|
||||
# 0xff bytes for the trailer.
|
||||
trailer = bytearray(b"\xff") * trailer_size
|
||||
|
||||
super().__init__(
|
||||
n,
|
||||
byteorder=pixel_order,
|
||||
brightness=brightness,
|
||||
auto_write=auto_write,
|
||||
header=header,
|
||||
trailer=trailer,
|
||||
)
|
||||
|
||||
def deinit(self):
|
||||
"""Blank out the DotStars and release the resources."""
|
||||
self.auto_write = False
|
||||
for i in range(START_HEADER_SIZE, self.end_header_index):
|
||||
if i % 4 != 0:
|
||||
self._buf[i] = 0
|
||||
self.fill(0)
|
||||
self.show()
|
||||
if self._spi:
|
||||
self._spi.deinit()
|
||||
|
|
@ -136,131 +175,24 @@ class DotStar:
|
|||
def __repr__(self):
|
||||
return "[" + ", ".join([str(x) for x in self]) + "]"
|
||||
|
||||
def _set_item(self, index, value):
|
||||
"""
|
||||
value can be one of three things:
|
||||
a (r,g,b) list/tuple
|
||||
a (r,g,b, brightness) list/tuple
|
||||
a single, longer int that contains RGB values, like 0xFFFFFF
|
||||
brightness, if specified should be a float 0-1
|
||||
|
||||
Set a pixel value. You can set per-pixel brightness here, if it's not passed it
|
||||
will use the max value for pixel brightness value, which is a good default.
|
||||
|
||||
Important notes about the per-pixel brightness - it's accomplished by
|
||||
PWMing the entire output of the LED, and that PWM is at a much
|
||||
slower clock than the rest of the LEDs. This can cause problems in
|
||||
Persistence of Vision Applications
|
||||
"""
|
||||
|
||||
offset = index * 4 + START_HEADER_SIZE
|
||||
rgb = value
|
||||
if isinstance(value, int):
|
||||
rgb = (value >> 16, (value >> 8) & 0xff, value & 0xff)
|
||||
|
||||
if len(rgb) == 4:
|
||||
brightness = value[3]
|
||||
# Ignore value[3] below.
|
||||
else:
|
||||
brightness = 1
|
||||
|
||||
# LED startframe is three "1" bits, followed by 5 brightness bits
|
||||
# then 8 bits for each of R, G, and B. The order of those 3 are configurable and
|
||||
# vary based on hardware
|
||||
# same as math.ceil(brightness * 31) & 0b00011111
|
||||
# Idea from https://www.codeproject.com/Tips/700780/Fast-floor-ceiling-functions
|
||||
brightness_byte = 32 - int(32 - brightness * 31) & 0b00011111
|
||||
self._buf[offset] = brightness_byte | LED_START
|
||||
self._buf[offset + 1] = rgb[self.pixel_order[0]]
|
||||
self._buf[offset + 2] = rgb[self.pixel_order[1]]
|
||||
self._buf[offset + 3] = rgb[self.pixel_order[2]]
|
||||
|
||||
def __setitem__(self, index, val):
|
||||
if isinstance(index, slice):
|
||||
start, stop, step = index.indices(self._n)
|
||||
length = stop - start
|
||||
if step != 0:
|
||||
# same as math.ceil(length / step)
|
||||
# Idea from https://fizzbuzzer.com/implement-a-ceil-function/
|
||||
length = (length + step - 1) // step
|
||||
if len(val) != length:
|
||||
raise ValueError("Slice and input sequence size do not match.")
|
||||
for val_i, in_i in enumerate(range(start, stop, step)):
|
||||
self._set_item(in_i, val[val_i])
|
||||
else:
|
||||
self._set_item(index, val)
|
||||
|
||||
if self.auto_write:
|
||||
self.show()
|
||||
|
||||
def __getitem__(self, index):
|
||||
if isinstance(index, slice):
|
||||
out = []
|
||||
for in_i in range(*index.indices(self._n)):
|
||||
out.append(
|
||||
tuple(self._buf[in_i * 4 + (3 - i) + START_HEADER_SIZE] for i in range(3)))
|
||||
return out
|
||||
if index < 0:
|
||||
index += len(self)
|
||||
if index >= self._n or index < 0:
|
||||
raise IndexError
|
||||
offset = index * 4
|
||||
return tuple(self._buf[offset + (3 - i) + START_HEADER_SIZE]
|
||||
for i in range(3))
|
||||
|
||||
def __len__(self):
|
||||
return self._n
|
||||
|
||||
@property
|
||||
def brightness(self):
|
||||
"""Overall brightness of the pixel"""
|
||||
return self._brightness
|
||||
def n(self):
|
||||
"""
|
||||
The number of dotstars in the chain (read-only)
|
||||
"""
|
||||
return len(self)
|
||||
|
||||
@brightness.setter
|
||||
def brightness(self, brightness):
|
||||
self._brightness = min(max(brightness, 0.0), 1.0)
|
||||
if self.auto_write:
|
||||
self.show()
|
||||
def _transmit(self, buffer):
|
||||
if self._spi:
|
||||
self._spi.write(buffer)
|
||||
else:
|
||||
self._ds_writebytes(buffer)
|
||||
|
||||
def fill(self, color):
|
||||
"""Colors all pixels the given ***color***."""
|
||||
auto_write = self.auto_write
|
||||
self.auto_write = False
|
||||
for i in range(self._n):
|
||||
self[i] = color
|
||||
if auto_write:
|
||||
self.show()
|
||||
self.auto_write = auto_write
|
||||
|
||||
def _ds_writebytes(self, buf):
|
||||
for b in buf:
|
||||
def _ds_writebytes(self, buffer):
|
||||
for b in buffer:
|
||||
for _ in range(8):
|
||||
self.dpin.value = b & 0x80
|
||||
self.cpin.value = True
|
||||
self.dpin.value = (b & 0x80)
|
||||
self.cpin.value = False
|
||||
b = b << 1
|
||||
|
||||
def show(self):
|
||||
"""Shows the new colors on the pixels themselves if they haven't already
|
||||
been autowritten.
|
||||
|
||||
The colors may or may not be showing after this function returns because
|
||||
it may be done asynchronously."""
|
||||
# Create a second output buffer if we need to compute brightness
|
||||
buf = self._buf
|
||||
if self.brightness < 1.0:
|
||||
buf = bytearray(self._buf)
|
||||
# Four empty bytes to start.
|
||||
for i in range(START_HEADER_SIZE):
|
||||
buf[i] = 0x00
|
||||
for i in range(START_HEADER_SIZE, self.end_header_index):
|
||||
buf[i] = self._buf[i] if i % 4 == 0 else int(self._buf[i] * self._brightness)
|
||||
# Four 0xff bytes at the end.
|
||||
for i in range(self.end_header_index, len(buf)):
|
||||
buf[i] = 0xff
|
||||
|
||||
if self._spi:
|
||||
self._spi.write(buf)
|
||||
else:
|
||||
self._ds_writebytes(buf)
|
||||
self.cpin.value = False
|
||||
self.cpin.value = False
|
||||
|
|
|
|||
111
docs/conf.py
111
docs/conf.py
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
|
||||
sys.path.insert(0, os.path.abspath(".."))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
|
|
@ -10,37 +11,39 @@ sys.path.insert(0, os.path.abspath('..'))
|
|||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.viewcode',
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx.ext.viewcode",
|
||||
]
|
||||
|
||||
# autodoc_mock_imports = ["digitalio", "busio"]
|
||||
|
||||
intersphinx_mapping = {'python': ('https://docs.python.org/3.4', None),
|
||||
'CircuitPython': ('https://circuitpython.readthedocs.io/en/latest/', None)}
|
||||
intersphinx_mapping = {
|
||||
"python": ("https://docs.python.org/3.4", None),
|
||||
"CircuitPython": ("https://circuitpython.readthedocs.io/en/latest/", None),
|
||||
}
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
templates_path = ["_templates"]
|
||||
|
||||
source_suffix = '.rst'
|
||||
source_suffix = ".rst"
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
master_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = u'Adafruit CircuitPython DotStar Library'
|
||||
copyright = u'2017 Scott Shawcroft, Limor Fried & Damien P. George'
|
||||
author = u'Scott Shawcroft, Limor Fried & Damien P. George'
|
||||
project = "Adafruit CircuitPython DotStar Library"
|
||||
copyright = "2017 Scott Shawcroft, Limor Fried & Damien P. George"
|
||||
author = "Scott Shawcroft, Limor Fried & Damien P. George"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = u'1.0'
|
||||
version = "1.0"
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = u'1.0'
|
||||
release = "1.0"
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
|
@ -52,7 +55,7 @@ language = None
|
|||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.env', 'CODE_OF_CONDUCT.md']
|
||||
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", ".env", "CODE_OF_CONDUCT.md"]
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
|
|
@ -64,7 +67,7 @@ default_role = "any"
|
|||
add_function_parentheses = True
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
pygments_style = "sphinx"
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
|
@ -78,59 +81,62 @@ todo_emit_warnings = True
|
|||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
|
||||
|
||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
||||
try:
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
|
||||
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), "."]
|
||||
except:
|
||||
html_theme = 'default'
|
||||
html_theme_path = ['.']
|
||||
html_theme = "default"
|
||||
html_theme_path = ["."]
|
||||
else:
|
||||
html_theme_path = ['.']
|
||||
html_theme_path = ["."]
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
html_static_path = ["_static"]
|
||||
|
||||
# The name of an image file (relative to this directory) to use as a favicon of
|
||||
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#
|
||||
html_favicon = '_static/favicon.ico'
|
||||
html_favicon = "_static/favicon.ico"
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'AdafruitDotStarLibrarydoc'
|
||||
htmlhelp_basename = "AdafruitDotStarLibrarydoc"
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'AdafruitDotStarLibrary.tex', u'Adafruit DotStar Library Documentation',
|
||||
author, 'manual'),
|
||||
(
|
||||
master_doc,
|
||||
"AdafruitDotStarLibrary.tex",
|
||||
"Adafruit DotStar Library Documentation",
|
||||
author,
|
||||
"manual",
|
||||
),
|
||||
]
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
|
@ -138,8 +144,13 @@ latex_documents = [
|
|||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'adafruitDotStarlibrary', u'Adafruit DotStar Library Documentation',
|
||||
[author], 1)
|
||||
(
|
||||
master_doc,
|
||||
"adafruitDotStarlibrary",
|
||||
"Adafruit DotStar Library Documentation",
|
||||
[author],
|
||||
1,
|
||||
)
|
||||
]
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
|
@ -148,7 +159,13 @@ man_pages = [
|
|||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'AdafruitDotStarLibrary', u'Adafruit DotStar Library Documentation',
|
||||
author, 'AdafruitDotStarLibrary', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
(
|
||||
master_doc,
|
||||
"AdafruitDotStarLibrary",
|
||||
"Adafruit DotStar Library Documentation",
|
||||
author,
|
||||
"AdafruitDotStarLibrary",
|
||||
"One line description of project.",
|
||||
"Miscellaneous",
|
||||
),
|
||||
]
|
||||
|
|
|
|||
61
examples/dotstar_image_paint.py
Normal file
61
examples/dotstar_image_paint.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
# Light-painting example for Adafruit DotStar RGB LED strip.
|
||||
# Loads image, displays column-at-a-time on LEDs at a reasonable
|
||||
# speed for long exposure photography.
|
||||
# See dotstar_simpletest.py for a much simpler example script.
|
||||
# See dotstar_image_pov.py for a faster persistence-of-vision example.
|
||||
|
||||
import time
|
||||
import board
|
||||
from PIL import Image
|
||||
import adafruit_dotstar as dotstar
|
||||
|
||||
NUMPIXELS = 30 # Number of LEDs in strip
|
||||
FILENAME = "hello.png" # Image file to load
|
||||
|
||||
# First two arguments in strip declaration identify the clock and data pins
|
||||
# (here we're using the hardware SPI pins). Last argument identifies the
|
||||
# color order -- older DotStar strips use GBR instead of BRG.
|
||||
DOTS = dotstar.DotStar(
|
||||
board.SCK,
|
||||
board.MOSI,
|
||||
NUMPIXELS,
|
||||
brightness=0.25,
|
||||
auto_write=False,
|
||||
pixel_order=dotstar.BGR,
|
||||
)
|
||||
|
||||
# Load image in RGB format and get dimensions:
|
||||
print("Loading...")
|
||||
IMG = Image.open(FILENAME).convert("RGB")
|
||||
PIXELS = IMG.load()
|
||||
WIDTH = IMG.size[0]
|
||||
HEIGHT = IMG.size[1]
|
||||
print("%dx%d pixels" % IMG.size)
|
||||
|
||||
if HEIGHT > NUMPIXELS:
|
||||
HEIGHT = NUMPIXELS
|
||||
|
||||
# Calculate gamma correction table, makes mid-range colors look 'right':
|
||||
GAMMA = bytearray(256)
|
||||
for i in range(256):
|
||||
GAMMA[i] = int(pow(float(i) / 255.0, 2.7) * 255.0 + 0.5)
|
||||
|
||||
print("Displaying...")
|
||||
while True: # Loop forever
|
||||
|
||||
for x in range(WIDTH): # For each column of image...
|
||||
for y in range(HEIGHT): # For each pixel in column...
|
||||
value = PIXELS[x, y] # Read pixel in image
|
||||
DOTS[y] = ( # Set pixel #y in strip
|
||||
GAMMA[value[0]], # Gamma-corrected red
|
||||
GAMMA[value[1]], # Gamma-corrected green
|
||||
GAMMA[value[2]], # Gamma-corrected blue
|
||||
)
|
||||
DOTS.show() # Refresh LED strip
|
||||
time.sleep(0.01) # Pause 1/100 sec.
|
||||
|
||||
DOTS.fill(0) # Clear strip and pause 1/4 sec.
|
||||
DOTS.show()
|
||||
time.sleep(0.25)
|
||||
71
examples/dotstar_image_pov.py
Normal file
71
examples/dotstar_image_pov.py
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
# Persistence-of-vision (POV) example for Adafruit DotStar RGB LED strip.
|
||||
# Loads image, displays column-at-a-time on LEDs at very high speed,
|
||||
# suitable for naked-eye illusions.
|
||||
# See dotstar_simpletest.py for a much simpler example script.
|
||||
# See dotstar_image_paint.py for a slightly simpler light painting example.
|
||||
# This code accesses some elements of the dotstar object directly rather
|
||||
# than through function calls or setters/getters...this is poor form as it
|
||||
# could break easily with future library changes, but is the only way right
|
||||
# now to do the POV as quickly as possible.
|
||||
# May require installing separate libraries.
|
||||
|
||||
import board
|
||||
from PIL import Image
|
||||
import adafruit_dotstar as dotstar
|
||||
|
||||
NUMPIXELS = 30 # Length of DotStar strip
|
||||
FILENAME = "hello.png" # Image file to load
|
||||
ORDER = dotstar.BGR # Change to GBR for older DotStar strips
|
||||
|
||||
# First two arguments in strip declaration identify the clock and data pins
|
||||
# (here we're using the hardware SPI pins).
|
||||
DOTS = dotstar.DotStar(
|
||||
board.SCK,
|
||||
board.MOSI,
|
||||
NUMPIXELS,
|
||||
auto_write=False,
|
||||
brightness=1.0,
|
||||
pixel_order=ORDER,
|
||||
)
|
||||
|
||||
# Load image in RGB format and get dimensions:
|
||||
print("Loading...")
|
||||
IMG = Image.open(FILENAME).convert("RGB")
|
||||
PIXELS = IMG.load()
|
||||
WIDTH = IMG.size[0]
|
||||
HEIGHT = IMG.size[1]
|
||||
print("%dx%d pixels" % IMG.size)
|
||||
|
||||
if HEIGHT > NUMPIXELS:
|
||||
HEIGHT = NUMPIXELS
|
||||
|
||||
# Calculate gamma correction table, makes mid-range colors look 'right':
|
||||
GAMMA = bytearray(256)
|
||||
brightness = 0.25
|
||||
for i in range(256):
|
||||
GAMMA[i] = int(pow(float(i) / 255.0, 2.7) * brightness * 255.0 + 0.5)
|
||||
|
||||
# Allocate list of lists, one for each column of image.
|
||||
print("Allocating...")
|
||||
COLUMN = [0 for x in range(WIDTH)]
|
||||
for x in range(WIDTH):
|
||||
COLUMN[x] = [[0, 0, 0, 0] for _ in range(HEIGHT)]
|
||||
|
||||
# Convert entire RGB image into columnxrow 2D list.
|
||||
print("Converting...")
|
||||
for x in range(WIDTH): # For each column of image
|
||||
for y in range(HEIGHT): # For each pixel in column
|
||||
value = PIXELS[x, y] # Read RGB pixel in image
|
||||
COLUMN[x][y][0] = GAMMA[value[0]] # Gamma-corrected R
|
||||
COLUMN[x][y][1] = GAMMA[value[1]] # Gamma-corrected G
|
||||
COLUMN[x][y][2] = GAMMA[value[2]] # Gamma-corrected B
|
||||
COLUMN[x][y][3] = 1.0 # Brightness
|
||||
|
||||
print("Displaying...")
|
||||
while True: # Loop forever
|
||||
|
||||
for x in range(WIDTH): # For each column of image...
|
||||
DOTS[0 : DOTS.n] = COLUMN[x] # Copy column to DotStar buffer
|
||||
DOTS.show() # Send data to strip
|
||||
|
|
@ -3,27 +3,27 @@ import random
|
|||
import board
|
||||
import adafruit_dotstar as dotstar
|
||||
|
||||
# One pixel connected internally on a GEMMA M0
|
||||
# pylint: disable=no-member
|
||||
# On-board DotStar for boards including Gemma, Trinket, and ItsyBitsy
|
||||
dots = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)
|
||||
|
||||
# With a Dotstar Digital LEB Strip with 30 lights
|
||||
#dots = dotstar.DotStar(board.SCK, board.MOSI, 30, brightness=0.2)
|
||||
# Using a DotStar Digital LED Strip with 30 LEDs connected to hardware SPI
|
||||
# dots = dotstar.DotStar(board.SCK, board.MOSI, 30, brightness=0.2)
|
||||
|
||||
######################### HELPERS ##############################
|
||||
# Using a DotStar Digital LED Strip with 30 LEDs connected to digital pins
|
||||
# dots = dotstar.DotStar(board.D6, board.D5, 30, brightness=0.2)
|
||||
|
||||
# a random color 0 -> 224
|
||||
|
||||
# HELPERS
|
||||
# a random color 0 -> 192
|
||||
def random_color():
|
||||
return random.randrange(0, 7) * 32
|
||||
|
||||
######################### MAIN LOOP ##############################
|
||||
|
||||
# MAIN LOOP
|
||||
n_dots = len(dots)
|
||||
while True:
|
||||
#fill each dot with a random color
|
||||
# Fill each dot with a random color
|
||||
for dot in range(n_dots):
|
||||
dots[dot] = (random_color(), random_color(), random_color())
|
||||
|
||||
# show all dots in strip
|
||||
dots.show()
|
||||
|
||||
time.sleep(.25)
|
||||
time.sleep(0.25)
|
||||
|
|
|
|||
BIN
examples/hello.png
Normal file
BIN
examples/hello.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
|
|
@ -1,2 +1,3 @@
|
|||
Adafruit-Blinka
|
||||
adafruit-circuitpython-busdevice
|
||||
adafruit-circuitpython-pypixelbuf>=2.0.0
|
||||
|
|
|
|||
56
setup.py
56
setup.py
|
|
@ -7,6 +7,7 @@ https://github.com/pypa/sampleproject
|
|||
|
||||
# Always prefer setuptools over distutils
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
# To use a consistent encoding
|
||||
from codecs import open
|
||||
from os import path
|
||||
|
|
@ -14,47 +15,42 @@ from os import path
|
|||
here = path.abspath(path.dirname(__file__))
|
||||
|
||||
# Get the long description from the README file
|
||||
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
|
||||
with open(path.join(here, "README.rst"), encoding="utf-8") as f:
|
||||
long_description = f.read()
|
||||
|
||||
setup(
|
||||
name='adafruit-circuitpython-dotstar',
|
||||
|
||||
name="adafruit-circuitpython-dotstar",
|
||||
use_scm_version=True,
|
||||
setup_requires=['setuptools_scm'],
|
||||
|
||||
description='CircuitPython library for DotStar LEDs.',
|
||||
setup_requires=["setuptools_scm"],
|
||||
description="CircuitPython library for DotStar LEDs.",
|
||||
long_description=long_description,
|
||||
long_description_content_type='text/x-rst',
|
||||
|
||||
long_description_content_type="text/x-rst",
|
||||
# The project's main homepage.
|
||||
url='https://github.com/adafruit/Adafruit_CircuitPython_DotStar',
|
||||
|
||||
url="https://github.com/adafruit/Adafruit_CircuitPython_DotStar",
|
||||
# Author details
|
||||
author='Adafruit Industries',
|
||||
author_email='circuitpython@adafruit.com',
|
||||
|
||||
install_requires=['Adafruit-Blinka', 'adafruit-circuitpython-busdevice'],
|
||||
|
||||
author="Adafruit Industries",
|
||||
author_email="circuitpython@adafruit.com",
|
||||
install_requires=[
|
||||
"Adafruit-Blinka",
|
||||
"adafruit-circuitpython-busdevice",
|
||||
"adafruit-circuitpython-pypixelbuf>=2.0.0",
|
||||
],
|
||||
# Choose your license
|
||||
license='MIT',
|
||||
|
||||
license="MIT",
|
||||
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
classifiers=[
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Intended Audience :: Developers',
|
||||
'Topic :: Software Development :: Libraries',
|
||||
'Topic :: System :: Hardware',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
"Development Status :: 3 - Alpha",
|
||||
"Intended Audience :: Developers",
|
||||
"Topic :: Software Development :: Libraries",
|
||||
"Topic :: System :: Hardware",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.4",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
],
|
||||
|
||||
# What does your project relate to?
|
||||
keywords='adafruit dotstar leds rgb spi addressable hardware micropython circuitpython',
|
||||
|
||||
keywords="adafruit dotstar leds rgb spi addressable hardware micropython circuitpython",
|
||||
# You can just specify the packages manually here if your project is
|
||||
# simple. Or you can use find_packages().
|
||||
py_modules=['adafruit_dotstar'],
|
||||
)
|
||||
py_modules=["adafruit_dotstar"],
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue