BDPotentiometer 0.0.1__tar.gz → 0.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- BDPotentiometer-0.0.3/LICENSE +21 -0
- BDPotentiometer-0.0.3/PKG-INFO +79 -0
- BDPotentiometer-0.0.3/README.md +33 -0
- BDPotentiometer-0.0.3/pyproject.toml +42 -0
- BDPotentiometer-0.0.3/setup.cfg +4 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer/__gpiozero_helpers.py +83 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer/__helpers.py +160 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer/__init__.py +16 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer/digital_potentiometer.py +522 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer/digital_wiper.py +291 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer/mcp4xxx/__init__.py +24 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer/mcp4xxx/mcp4xx1.py +74 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer/mcp4xxx/mcp4xx2.py +74 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer/mcp4xxx/mcp4xxx.py +214 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer/potentiometer.py +260 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer.egg-info/PKG-INFO +79 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer.egg-info/SOURCES.txt +19 -0
- BDPotentiometer-0.0.3/src/BDPotentiometer.egg-info/requires.txt +13 -0
- BDPotentiometer-0.0.3/tests/test_version.py +51 -0
- BDPotentiometer-0.0.1/BDPotentiometer/DigitalPotentiometer.py +0 -283
- BDPotentiometer-0.0.1/BDPotentiometer/MCP4xx1.py +0 -126
- BDPotentiometer-0.0.1/BDPotentiometer/MCP4xx2.py +0 -44
- BDPotentiometer-0.0.1/BDPotentiometer/MCP4xxx.py +0 -123
- BDPotentiometer-0.0.1/BDPotentiometer/__gpiozero_helpers.py +0 -33
- BDPotentiometer-0.0.1/BDPotentiometer/__helpers.py +0 -80
- BDPotentiometer-0.0.1/BDPotentiometer/__init__.py +0 -6
- BDPotentiometer-0.0.1/BDPotentiometer/_version.py +0 -1
- BDPotentiometer-0.0.1/BDPotentiometer.egg-info/PKG-INFO +0 -47
- BDPotentiometer-0.0.1/BDPotentiometer.egg-info/SOURCES.txt +0 -19
- BDPotentiometer-0.0.1/LICENSE.txt +0 -202
- BDPotentiometer-0.0.1/MANIFEST.in +0 -15
- BDPotentiometer-0.0.1/NOTICE.txt +0 -2
- BDPotentiometer-0.0.1/PKG-INFO +0 -47
- BDPotentiometer-0.0.1/README.md +0 -25
- BDPotentiometer-0.0.1/pyproject.toml +0 -3
- BDPotentiometer-0.0.1/setup.cfg +0 -7
- BDPotentiometer-0.0.1/setup.py +0 -56
- {BDPotentiometer-0.0.1 → BDPotentiometer-0.0.3/src}/BDPotentiometer.egg-info/dependency_links.txt +0 -0
- {BDPotentiometer-0.0.1 → BDPotentiometer-0.0.3/src}/BDPotentiometer.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Anton Bondarenko
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: BDPotentiometer
|
|
3
|
+
Version: 0.0.3
|
|
4
|
+
Summary: BD Digital Potentiometer
|
|
5
|
+
Author-email: Anton Bondarenko <bond.anton@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2023 Anton Bondarenko
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
Project-URL: Homepage, https://github.com/bond-anton/BDPotentiometer
|
|
28
|
+
Project-URL: Bug Tracker, https://github.com/bond-anton/BDPotentiometer/issues
|
|
29
|
+
Project-URL: Documentation, https://bdpotentiometer.readthedocs.io
|
|
30
|
+
Classifier: Programming Language :: Python :: 3
|
|
31
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
32
|
+
Classifier: Operating System :: OS Independent
|
|
33
|
+
Requires-Python: >=3.9
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
License-File: LICENSE
|
|
36
|
+
Requires-Dist: gpiozero>=1.6.2
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: gpiozero>=1.6.2; extra == "dev"
|
|
39
|
+
Requires-Dist: numpy; extra == "dev"
|
|
40
|
+
Provides-Extra: test
|
|
41
|
+
Requires-Dist: flake8; extra == "test"
|
|
42
|
+
Requires-Dist: pytest; extra == "test"
|
|
43
|
+
Requires-Dist: numpy; extra == "test"
|
|
44
|
+
Provides-Extra: lint
|
|
45
|
+
Requires-Dist: pylint; extra == "lint"
|
|
46
|
+
|
|
47
|
+
# BDPotentiometer
|
|
48
|
+
|
|
49
|
+

|
|
50
|
+
[](https://bdpotentiometer.readthedocs.io/en/latest/?badge=latest)
|
|
51
|
+
|
|
52
|
+
Module to operate Digital Potentiometer over SPI bus. Extends gpiozero SPIDev class.
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
To install BDPotentiometer use pip
|
|
57
|
+
```shell
|
|
58
|
+
$ pip install BDPotentiometer
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
Just import the correct potentiometer class, for example MCP4231, and start operating your pot.
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from BDPotentiometer.mcp4xxx import MCP4231
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
my_pot = MCP4231(r_ab=10e3, device=0)
|
|
70
|
+
my_pot.channels[0].value = 43
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Please see the [examples](examples) directory for more usage examples.
|
|
74
|
+
|
|
75
|
+
Detailed documentation is available at https://bdpotentiometer.readthedocs.io
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
BDPotentiometer is free open source software licensed under MIT License
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# BDPotentiometer
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
[](https://bdpotentiometer.readthedocs.io/en/latest/?badge=latest)
|
|
5
|
+
|
|
6
|
+
Module to operate Digital Potentiometer over SPI bus. Extends gpiozero SPIDev class.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
To install BDPotentiometer use pip
|
|
11
|
+
```shell
|
|
12
|
+
$ pip install BDPotentiometer
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
Just import the correct potentiometer class, for example MCP4231, and start operating your pot.
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from BDPotentiometer.mcp4xxx import MCP4231
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
my_pot = MCP4231(r_ab=10e3, device=0)
|
|
24
|
+
my_pot.channels[0].value = 43
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Please see the [examples](examples) directory for more usage examples.
|
|
28
|
+
|
|
29
|
+
Detailed documentation is available at https://bdpotentiometer.readthedocs.io
|
|
30
|
+
|
|
31
|
+
## License
|
|
32
|
+
|
|
33
|
+
BDPotentiometer is free open source software licensed under MIT License
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "BDPotentiometer"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "BD Digital Potentiometer"
|
|
9
|
+
authors = [
|
|
10
|
+
{ name = "Anton Bondarenko", email = "bond.anton@gmail.com" },
|
|
11
|
+
]
|
|
12
|
+
license = { file = "LICENSE" }
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
]
|
|
19
|
+
requires-python = ">=3.9"
|
|
20
|
+
dependencies = [
|
|
21
|
+
"gpiozero>=1.6.2",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
"Homepage" = "https://github.com/bond-anton/BDPotentiometer"
|
|
26
|
+
"Bug Tracker" = "https://github.com/bond-anton/BDPotentiometer/issues"
|
|
27
|
+
"Documentation" = "https://bdpotentiometer.readthedocs.io"
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
dev = ["gpiozero>=1.6.2", "numpy"]
|
|
31
|
+
test = ["flake8", "pytest", "numpy"]
|
|
32
|
+
lint = ["pylint"]
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.dynamic]
|
|
35
|
+
version = {attr = "BDPotentiometer.__version__"}
|
|
36
|
+
|
|
37
|
+
[tool.mypy]
|
|
38
|
+
python_version = "3.9"
|
|
39
|
+
|
|
40
|
+
[[tool.mypy.overrides]]
|
|
41
|
+
module = ["gpiozero.*"]
|
|
42
|
+
ignore_missing_imports = true
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""Some helpers for gpiozero."""
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
from gpiozero import Device
|
|
5
|
+
from gpiozero.pins.local import LocalPiHardwareSPI, LocalPiHardwareSPIShared
|
|
6
|
+
from gpiozero.pins.rpigpio import RPiGPIOFactory
|
|
7
|
+
except ModuleNotFoundError:
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def fix_gpiozero_dual_cs_spi() -> None:
|
|
12
|
+
"""
|
|
13
|
+
A workaround written by slghb GitHub user to use two spi devices with hardware spi.
|
|
14
|
+
Taken from https://github.com/gpiozero/gpiozero/issues/1015
|
|
15
|
+
|
|
16
|
+
:return: None.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
class LocalPiHardwareSPIFixed(LocalPiHardwareSPI):
|
|
20
|
+
"""Custom conflict checker"""
|
|
21
|
+
|
|
22
|
+
# pylint: disable=too-few-public-methods
|
|
23
|
+
def _conflicts_with(self, other):
|
|
24
|
+
# pylint: disable=protected-access
|
|
25
|
+
return not (
|
|
26
|
+
isinstance(other, LocalPiHardwareSPI)
|
|
27
|
+
and (self._port, self._device) != (other._port, other._device)
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def value(self):
|
|
32
|
+
"""
|
|
33
|
+
Returns a value representing the device's state. Frequently, this is a
|
|
34
|
+
boolean value, or a number between 0 and 1 but some devices use larger
|
|
35
|
+
ranges (e.g. -1 to +1) and composite devices usually use tuples to
|
|
36
|
+
return the states of all their subordinate components.
|
|
37
|
+
"""
|
|
38
|
+
raise NotImplementedError
|
|
39
|
+
|
|
40
|
+
class LocalPiHardwareSPISharedFixed(LocalPiHardwareSPIShared):
|
|
41
|
+
"""Custom Shared SPI hardware class inheriting from fixed Hardware SPI class above"""
|
|
42
|
+
|
|
43
|
+
def _conflicts_with(self, other):
|
|
44
|
+
# pylint: disable=protected-access
|
|
45
|
+
return not (
|
|
46
|
+
isinstance(other, LocalPiHardwareSPI)
|
|
47
|
+
and (self._port, self._device) != (other._port, other._device)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def value(self):
|
|
52
|
+
"""
|
|
53
|
+
Returns a value representing the device's state. Frequently, this is a
|
|
54
|
+
boolean value, or a number between 0 and 1 but some devices use larger
|
|
55
|
+
ranges (e.g. -1 to +1) and composite devices usually use tuples to
|
|
56
|
+
return the states of all their subordinate components.
|
|
57
|
+
"""
|
|
58
|
+
raise NotImplementedError
|
|
59
|
+
|
|
60
|
+
class FixedRPiGPIOFactory(RPiGPIOFactory):
|
|
61
|
+
"""Fixed RPiGPIOFactory"""
|
|
62
|
+
|
|
63
|
+
def _get_spi_class(self, shared, hardware):
|
|
64
|
+
"""
|
|
65
|
+
Return a Fixed SPI class if shared hardware SPI port between two devices
|
|
66
|
+
|
|
67
|
+
:param shared: Flag for shared usage of SPI port.
|
|
68
|
+
:param hardware: Flag for hardware SPI usage.
|
|
69
|
+
:return:
|
|
70
|
+
"""
|
|
71
|
+
if hardware:
|
|
72
|
+
if shared:
|
|
73
|
+
return LocalPiHardwareSPISharedFixed
|
|
74
|
+
return LocalPiHardwareSPIFixed
|
|
75
|
+
return super()._get_spi_class(shared, hardware)
|
|
76
|
+
|
|
77
|
+
Device.pin_factory = FixedRPiGPIOFactory()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def fix_gpiozero_dual_cs_spi_dummy() -> None:
|
|
81
|
+
"""
|
|
82
|
+
A stub function if there will be problems importing above function
|
|
83
|
+
"""
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""This module contains internal helper functions and not supposed to be used outside."""
|
|
2
|
+
|
|
3
|
+
from numbers import Real, Integral
|
|
4
|
+
from math import isnan
|
|
5
|
+
from typing import Union, Callable
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def check_number(num: Union[float, int, Real]) -> Union[float, int]:
|
|
9
|
+
"""
|
|
10
|
+
Checks if argument is a real number.
|
|
11
|
+
check_number does not allow argument to be `+inf` or `-inf`, or `NaN`.
|
|
12
|
+
Special float numbers `+0.0` and `-0.0` will be converted to just 0.0
|
|
13
|
+
|
|
14
|
+
:param num: variable to check.
|
|
15
|
+
:return: Unchanged `num` as float or int or raises ValueError if num is not a real number.
|
|
16
|
+
"""
|
|
17
|
+
if not isinstance(num, Real):
|
|
18
|
+
raise TypeError(f"Expected integer or float number, got {type(num)}")
|
|
19
|
+
if isinstance(num, Integral):
|
|
20
|
+
return int(num)
|
|
21
|
+
if num in [float("inf"), float("-inf")]:
|
|
22
|
+
raise ValueError(f"Expected integer or float number, got {num}")
|
|
23
|
+
if isnan(num):
|
|
24
|
+
raise ValueError("Expected integer or float number, not NaN")
|
|
25
|
+
if num == 0:
|
|
26
|
+
return 0.0
|
|
27
|
+
return float(num)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def check_integer(num: Union[float, int, Real]) -> int:
|
|
31
|
+
"""
|
|
32
|
+
Checks if `num` is an integer and converts it to int, otherwise raises ValueError.
|
|
33
|
+
|
|
34
|
+
:param num: Number (either int or float) to be checked.
|
|
35
|
+
:return: int representation of `num` or rises ValueError.
|
|
36
|
+
"""
|
|
37
|
+
num = check_number(num)
|
|
38
|
+
if isinstance(num, float):
|
|
39
|
+
if not num.is_integer():
|
|
40
|
+
raise ValueError("Argument should be integer number")
|
|
41
|
+
return int(num)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def check_not_negative(num: Union[float, int]) -> Union[float, int]:
|
|
45
|
+
"""
|
|
46
|
+
Checks if `num` is a not negative number, otherwise rises ValueError.
|
|
47
|
+
|
|
48
|
+
:param num: Either float or int number.
|
|
49
|
+
:return: `num` if it is not negative or rises ValueError.
|
|
50
|
+
"""
|
|
51
|
+
num = check_number(num)
|
|
52
|
+
if num < 0:
|
|
53
|
+
raise ValueError("Argument should be not negative number")
|
|
54
|
+
return num
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def check_positive(num: Union[float, int]) -> Union[float, int]:
|
|
58
|
+
"""
|
|
59
|
+
Checks if `num` is a positive number, otherwise rises ValueError.
|
|
60
|
+
|
|
61
|
+
:param num: Either float or int number.
|
|
62
|
+
:return: `num` if it is positive or rises ValueError.
|
|
63
|
+
"""
|
|
64
|
+
num = check_number(num)
|
|
65
|
+
if num <= 0:
|
|
66
|
+
raise ValueError("Argument should be a positive number")
|
|
67
|
+
return num
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def clamp(
|
|
71
|
+
value: Union[float, int], min_value: Union[float, int], max_value: Union[float, int]
|
|
72
|
+
) -> Union[float, int]:
|
|
73
|
+
"""
|
|
74
|
+
Clamp `value` to given range between `min_value` and `max_value`.
|
|
75
|
+
|
|
76
|
+
:param value: Either float or int number to be coerced.
|
|
77
|
+
:param min_value: Lower coerce range boundary.
|
|
78
|
+
:param max_value: Upper coerce range boundary.
|
|
79
|
+
:return: Value coerced to given range.
|
|
80
|
+
"""
|
|
81
|
+
value = check_number(value)
|
|
82
|
+
min_value = check_number(min_value)
|
|
83
|
+
max_value = check_number(max_value)
|
|
84
|
+
if min_value > max_value:
|
|
85
|
+
min_value, max_value = max_value, min_value
|
|
86
|
+
if value < min_value:
|
|
87
|
+
if isinstance(value, float):
|
|
88
|
+
return float(min_value)
|
|
89
|
+
return min_value
|
|
90
|
+
if value > max_value:
|
|
91
|
+
if isinstance(value, float):
|
|
92
|
+
return float(max_value)
|
|
93
|
+
return max_value
|
|
94
|
+
return value
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def build_tuple(
|
|
98
|
+
value: Union[float, int, tuple[float, ...], list[float, ...]],
|
|
99
|
+
num: Union[int, float],
|
|
100
|
+
func: Union[Callable, None] = None,
|
|
101
|
+
) -> tuple[float, ...]:
|
|
102
|
+
"""
|
|
103
|
+
Builds tuple of floats of given length by applying a callable `func` to value.
|
|
104
|
+
If `value` is an iterable (either list or tuple) its length must be equal to `num`.
|
|
105
|
+
The `func` will be applied to each element of the iterable.
|
|
106
|
+
If `value` is a number the resulting tuple of length `num` will be built of same `func(value)`
|
|
107
|
+
elements converted to float.
|
|
108
|
+
If `func` is None the `value` will enter resulting tuple unchanged.
|
|
109
|
+
|
|
110
|
+
:param value: Iterable (either list or tuple) or a number.
|
|
111
|
+
:param num: A number of elements in a tuple.
|
|
112
|
+
:param func: Callable to be applied to `value` or None for identity function.
|
|
113
|
+
:return: A tuple of floats of length `num` produced by application of `func` to `value`.
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
def identity(val: float) -> float:
|
|
117
|
+
return val
|
|
118
|
+
|
|
119
|
+
if not isinstance(value, (float, int, tuple, list)):
|
|
120
|
+
raise TypeError("Argument should be a number or list or tuple of numbers")
|
|
121
|
+
num = check_integer(check_positive(num))
|
|
122
|
+
if func is not None:
|
|
123
|
+
if not callable(func):
|
|
124
|
+
raise TypeError("function must be callable or None")
|
|
125
|
+
else:
|
|
126
|
+
func = identity
|
|
127
|
+
|
|
128
|
+
if isinstance(value, (list, tuple)):
|
|
129
|
+
if len(value) != num:
|
|
130
|
+
raise ValueError(f"A tuple or list of length {num} expected")
|
|
131
|
+
return tuple(float(func(check_number(value_i))) for value_i in value)
|
|
132
|
+
value = check_number(value)
|
|
133
|
+
return tuple(float(func(value)) for _ in range(num))
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def adjust_tuple(
|
|
137
|
+
value: Union[tuple[float, ...], list[float, ...]], num: int, default_value: float
|
|
138
|
+
) -> tuple[float, ...]:
|
|
139
|
+
"""
|
|
140
|
+
Adjusts tuple or list of floats to a given length `num` and returns a tuple.
|
|
141
|
+
if `num` is less than initial length of the tuple it will be truncated to first `num` elements,
|
|
142
|
+
otherwise it will be appended using `default_value` parameter.
|
|
143
|
+
|
|
144
|
+
:param value: Initial iterable (either tuple or list) of float values.
|
|
145
|
+
:param num: Final length of the tuple.
|
|
146
|
+
:param default_value: Default value to populate the tuple if it needs to be grown.
|
|
147
|
+
:return: A tuple of floats of length `num`.
|
|
148
|
+
"""
|
|
149
|
+
if not isinstance(value, (tuple, list)):
|
|
150
|
+
raise TypeError("Argument should be a list or a tuple of numbers")
|
|
151
|
+
num = check_integer(check_positive(num))
|
|
152
|
+
default_value = float(check_number(default_value))
|
|
153
|
+
if len(value) < num:
|
|
154
|
+
return tuple(
|
|
155
|
+
[float(check_number(value_i)) for value_i in value]
|
|
156
|
+
+ [default_value] * (num - len(value))
|
|
157
|
+
)
|
|
158
|
+
if len(value) > num:
|
|
159
|
+
return tuple(float(check_number(value[i])) for i in range(num))
|
|
160
|
+
return tuple(float(check_number(value_i)) for value_i in value)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
""" Module to operate SPI digital potentiometer devices """
|
|
2
|
+
|
|
3
|
+
# pylint: disable=invalid-name
|
|
4
|
+
|
|
5
|
+
__version__ = "0.0.3"
|
|
6
|
+
|
|
7
|
+
from .potentiometer import Potentiometer
|
|
8
|
+
from .digital_wiper import DigitalWiper, SpiDigitalWiper
|
|
9
|
+
from .digital_potentiometer import DigitalPotentiometerDevice
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
from .__gpiozero_helpers import fix_gpiozero_dual_cs_spi
|
|
13
|
+
except ModuleNotFoundError:
|
|
14
|
+
from .__gpiozero_helpers import (
|
|
15
|
+
fix_gpiozero_dual_cs_spi_dummy as fix_gpiozero_dual_cs_spi,
|
|
16
|
+
)
|