Skip to content

Commit 331776c

Browse files
authored
Merge pull request #11 from process1183/sequence_property
Indexable waveform sequence property
2 parents 0429b55 + f978a65 commit 331776c

File tree

2 files changed

+121
-10
lines changed

2 files changed

+121
-10
lines changed

adafruit_drv2605.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ def __init__(self, i2c, address=_DRV2605_ADDR):
122122
# Default to internal trigger mode and TS2200 A library.
123123
self.mode = MODE_INTTRIG
124124
self.library = LIBRARY_TS2200A
125+
self._sequence = _DRV2605_Sequence(self)
125126

126127
def _read_u8(self, address):
127128
# Read an 8-bit unsigned value from the specified 8-bit address.
@@ -196,6 +197,18 @@ def library(self, val):
196197
raise ValueError('Library must be a value within 0-6!')
197198
self._write_u8(_DRV2605_REG_LIBRARY, val)
198199

200+
@property
201+
def sequence(self):
202+
"""List-like sequence of waveform effects.
203+
Get or set an effect waveform for slot 0-6 by indexing the sequence
204+
property with the slot number. A slot must be set to either an Effect()
205+
or Pause() class. See the datasheet for a complete table of effect ID
206+
values and the associated waveform / effect.
207+
208+
E.g. 'slot_0_effect = drv.sequence[0]', 'drv.sequence[0] = Effect(88)'
209+
"""
210+
return self._sequence
211+
199212
def set_waveform(self, effect_id, slot=0):
200213
"""Select an effect waveform for the specified slot (default is slot 0,
201214
but up to 7 effects can be combined with slot values 0 to 6). See the
@@ -219,3 +232,100 @@ def use_LRM(self):
219232
"""Use a linear resonance actuator motor."""
220233
feedback = self._read_u8(_DRV2605_REG_FEEDBACK)
221234
self._write_u8(_DRV2605_REG_FEEDBACK, feedback | 0x80)
235+
236+
237+
238+
class Effect:
239+
"""DRV2605 waveform sequence effect."""
240+
def __init__(self, effect_id):
241+
self._effect_id = 0
242+
# pylint: disable=invalid-name
243+
self.id = effect_id
244+
245+
@property
246+
def raw_value(self):
247+
"""Raw effect ID."""
248+
return self._effect_id
249+
250+
@property
251+
# pylint: disable=invalid-name
252+
def id(self):
253+
"""Effect ID."""
254+
return self._effect_id
255+
256+
@id.setter
257+
# pylint: disable=invalid-name
258+
def id(self, effect_id):
259+
"""Set the effect ID."""
260+
if not 0 <= effect_id <= 123:
261+
raise ValueError('Effect ID must be a value within 0-123!')
262+
self._effect_id = effect_id
263+
264+
def __repr__(self):
265+
return "{}({})".format(type(self).__qualname__, self.id)
266+
267+
268+
269+
class Pause:
270+
"""DRV2605 waveform sequence timed delay."""
271+
def __init__(self, duration):
272+
# Bit 7 must be set for a slot to be interpreted as a delay
273+
self._duration = 0x80
274+
self.duration = duration
275+
276+
@property
277+
def raw_value(self):
278+
"""Raw pause duration."""
279+
return self._duration
280+
281+
@property
282+
def duration(self):
283+
"""Pause duration in seconds."""
284+
# Remove wait time flag bit and convert duration to seconds
285+
return (self._duration & 0x7f) / 100.0
286+
287+
@duration.setter
288+
def duration(self, duration):
289+
"""Set the pause duration in seconds."""
290+
if not 0.0 <= duration <= 1.27:
291+
raise ValueError('Pause duration must be a value within 0.0-1.27!')
292+
# Add wait time flag bit and convert duration to centiseconds
293+
self._duration = 0x80 | round(duration * 100.0)
294+
295+
def __repr__(self):
296+
return "{}({})".format(type(self).__qualname__, self.duration)
297+
298+
299+
300+
class _DRV2605_Sequence:
301+
"""Class to enable List-like indexing of the waveform sequence slots."""
302+
def __init__(self, DRV2605_instance):
303+
self._drv2605 = DRV2605_instance
304+
305+
def __setitem__(self, slot, effect):
306+
"""Write an Effect or Pause to a slot."""
307+
if not 0 <= slot <= 6:
308+
raise IndexError('Slot must be a value within 0-6!')
309+
if not isinstance(effect, (Effect, Pause)):
310+
raise TypeError('Effect must be either an Effect() or Pause()!')
311+
# pylint: disable=protected-access
312+
self._drv2605._write_u8(_DRV2605_REG_WAVESEQ1 + slot, effect.raw_value)
313+
314+
def __getitem__(self, slot):
315+
"""Read an effect ID from a slot. Returns either a Pause or Effect class."""
316+
if not 0 <= slot <= 6:
317+
raise IndexError('Slot must be a value within 0-6!')
318+
# pylint: disable=protected-access
319+
slot_contents = self._drv2605._read_u8(_DRV2605_REG_WAVESEQ1 + slot)
320+
if slot_contents & 0x80:
321+
return Pause((slot_contents & 0x7f) / 100.0)
322+
return Effect(slot_contents)
323+
324+
def __iter__(self):
325+
"""Return an iterator over the waveform sequence slots."""
326+
for slot in range(0, 7):
327+
yield self[slot]
328+
329+
def __repr__(self):
330+
"""Return a string representation of all slot's effects."""
331+
return repr([effect for effect in self])

examples/drv2605_simpletest.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,18 @@
1616
# Main loop runs forever trying each effect (1-117).
1717
# See table 11.2 in the datasheet for a list of all the effect names and IDs.
1818
# http://www.ti.com/lit/ds/symlink/drv2605.pdf
19-
effect = 1
19+
effect_id = 1
2020
while True:
21-
print('Playing effect #{0}'.format(effect))
22-
drv.set_waveform(effect) # Select the effect on slot 0.
23-
# Optionally you can assign effects to up to 7 different slots to combine
24-
# them in interesting ways. Use the slot keyword and specify a slot 0 to 6
25-
# (0 is the default).
26-
#drv.set_waveform(effect, slot=1)
21+
print('Playing effect #{0}'.format(effect_id))
22+
drv.sequence[0] = adafruit_drv2605.Effect(effect_id) # Set the effect on slot 0.
23+
# You can assign effects to up to 7 different slots to combine
24+
# them in interesting ways. Index the sequence property with a
25+
# slot number 0 to 6.
26+
# Optionally, you can assign a pause to a slot. E.g.
27+
# drv.sequence[1] = adafruit_drv2605.Pause(0.5) # Pause for half a second
2728
drv.play() # Play the effect.
2829
time.sleep(0.5)
2930
# Increment effect ID and wrap back around to 1.
30-
effect += 1
31-
if effect > 117:
32-
effect = 1
31+
effect_id += 1
32+
if effect_id > 117:
33+
effect_id = 1

0 commit comments

Comments
 (0)