40
40
from adafruit_register .i2c_struct_array import StructArray
41
41
from adafruit_bus_device import i2c_device
42
42
43
+ try :
44
+ from typing import Optional , Type
45
+ from types import TracebackType
46
+ from busio import I2C
47
+ except ImportError :
48
+ pass
49
+
43
50
44
51
class PWMChannel :
45
- """A single PCA9685 channel that matches the :py:class:`~pwmio.PWMOut` API."""
52
+ """A single PCA9685 channel that matches the :py:class:`~pwmio.PWMOut` API.
53
+
54
+ :param PCA9685 pca: The PCA9685 object
55
+ :param int index: The index of the channel
56
+ """
46
57
47
- def __init__ (self , pca , index ):
58
+ def __init__ (self , pca : "PCA9685" , index : int ):
48
59
self ._pca = pca
49
60
self ._index = index
50
61
51
62
@property
52
- def frequency (self ):
63
+ def frequency (self ) -> float :
53
64
"""The overall PWM frequency in Hertz (read-only).
54
65
A PWMChannel's frequency cannot be set individually.
55
66
All channels share a common frequency, set by PCA9685.frequency."""
@@ -60,7 +71,7 @@ def frequency(self, _):
60
71
raise NotImplementedError ("frequency cannot be set on individual channels" )
61
72
62
73
@property
63
- def duty_cycle (self ):
74
+ def duty_cycle (self ) -> int :
64
75
"""16 bit value that dictates how much of one cycle is high (1) versus low (0). 0xffff will
65
76
always be high, 0 will always be low and 0x7fff will be half high and then half low."""
66
77
pwm = self ._pca .pwm_regs [self ._index ]
@@ -69,7 +80,7 @@ def duty_cycle(self):
69
80
return pwm [1 ] << 4
70
81
71
82
@duty_cycle .setter
72
- def duty_cycle (self , value ) :
83
+ def duty_cycle (self , value : int ) -> None :
73
84
if not 0 <= value <= 0xFFFF :
74
85
raise ValueError ("Out of range" )
75
86
@@ -82,16 +93,19 @@ def duty_cycle(self, value):
82
93
83
94
84
95
class PCAChannels : # pylint: disable=too-few-public-methods
85
- """Lazily creates and caches channel objects as needed. Treat it like a sequence."""
96
+ """Lazily creates and caches channel objects as needed. Treat it like a sequence.
97
+
98
+ :param PCA9685 pca: The PCA9685 object
99
+ """
86
100
87
- def __init__ (self , pca ) :
101
+ def __init__ (self , pca : "PCA9685" ) -> None :
88
102
self ._pca = pca
89
103
self ._channels = [None ] * len (self )
90
104
91
- def __len__ (self ):
105
+ def __len__ (self ) -> int :
92
106
return 16
93
107
94
- def __getitem__ (self , index ) :
108
+ def __getitem__ (self , index : int ) -> PWMChannel :
95
109
if not self ._channels [index ]:
96
110
self ._channels [index ] = PWMChannel (self ._pca , index )
97
111
return self ._channels [index ]
@@ -117,25 +131,31 @@ class PCA9685:
117
131
prescale_reg = UnaryStruct (0xFE , "<B" )
118
132
pwm_regs = StructArray (0x06 , "<HH" , 16 )
119
133
120
- def __init__ (self , i2c_bus , * , address = 0x40 , reference_clock_speed = 25000000 ):
134
+ def __init__ (
135
+ self ,
136
+ i2c_bus : I2C ,
137
+ * ,
138
+ address : int = 0x40 ,
139
+ reference_clock_speed : int = 25000000
140
+ ) -> None :
121
141
self .i2c_device = i2c_device .I2CDevice (i2c_bus , address )
122
142
self .channels = PCAChannels (self )
123
143
"""Sequence of 16 `PWMChannel` objects. One for each channel."""
124
144
self .reference_clock_speed = reference_clock_speed
125
145
"""The reference clock speed in Hz."""
126
146
self .reset ()
127
147
128
- def reset (self ):
148
+ def reset (self ) -> None :
129
149
"""Reset the chip."""
130
150
self .mode1_reg = 0x00 # Mode1
131
151
132
152
@property
133
- def frequency (self ):
153
+ def frequency (self ) -> float :
134
154
"""The overall PWM frequency in Hertz."""
135
155
return self .reference_clock_speed / 4096 / self .prescale_reg
136
156
137
157
@frequency .setter
138
- def frequency (self , freq ) :
158
+ def frequency (self , freq : float ) -> None :
139
159
prescale = int (self .reference_clock_speed / 4096.0 / freq + 0.5 )
140
160
if prescale < 3 :
141
161
raise ValueError ("PCA9685 cannot output at the given frequency" )
@@ -147,12 +167,17 @@ def frequency(self, freq):
147
167
# Mode 1, autoincrement on, fix to stop pca9685 from accepting commands at all addresses
148
168
self .mode1_reg = old_mode | 0xA0
149
169
150
- def __enter__ (self ):
170
+ def __enter__ (self ) -> "PCA9685" :
151
171
return self
152
172
153
- def __exit__ (self , exception_type , exception_value , traceback ):
173
+ def __exit__ (
174
+ self ,
175
+ exception_type : Optional [Type [type ]],
176
+ exception_value : Optional [BaseException ],
177
+ traceback : Optional [TracebackType ],
178
+ ) -> None :
154
179
self .deinit ()
155
180
156
- def deinit (self ):
181
+ def deinit (self ) -> None :
157
182
"""Stop using the pca9685."""
158
183
self .reset ()
0 commit comments