Skip to content

Commit 4594835

Browse files
committed
Allow custom device interval for callbacks
1 parent 8179ad9 commit 4594835

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

buildhat/devices.py

+27-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def __init__(self, port):
5858
self._simplemode = -1
5959
self._combimode = -1
6060
self._typeid = self._conn.typeid
61+
self._interval = 100
6162
if (
6263
self._typeid in Device._device_names
6364
and Device._device_names[self._typeid][0] != type(self).__name__ # noqa: W503
@@ -239,7 +240,7 @@ def select(self):
239240
idx = self._combimode
240241
else:
241242
raise DeviceError("Not in simple or combimode")
242-
self._write(f"port {self.port} ; select {idx}\r")
243+
self._write(f"port {self.port} ; select {idx} ; selrate {self._interval}\r")
243244

244245
def on(self):
245246
"""Turn on sensor"""
@@ -274,3 +275,28 @@ def callback(self, func):
274275
self._conn.callit = None
275276
else:
276277
self._conn.callit = weakref.WeakMethod(func)
278+
279+
@property
280+
def interval(self):
281+
"""Interval between data points in milliseconds
282+
283+
:getter: Gets interval
284+
:setter: Sets interval
285+
:return: Device interval
286+
:rtype: int
287+
"""
288+
return self._interval
289+
290+
@interval.setter
291+
def interval(self, value):
292+
"""Interval between data points in milliseconds
293+
294+
:param value: Interval
295+
:type value: int
296+
:raises DeviceError: Occurs if invalid interval passed
297+
"""
298+
if isinstance(value, int) and value >= 0 and value <= 1000000000:
299+
self._interval = value
300+
self._write(f"port {self.port} ; selrate {self._interval}\r")
301+
else:
302+
raise DeviceError("Invalid interval")

buildhat/motors.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ def _run_positional_ramp(self, pos, newpos, speed):
202202
# Collapse speed range to -5 to 5
203203
speed *= 0.05
204204
dur = abs((newpos - pos) / speed)
205-
cmd = (f"port {self.port}; combi 0 {self._combi} ; select 0 ; pid {self.port} 0 1 s4 0.0027777778 0 5 0 .1 3 ; "
205+
cmd = (f"port {self.port}; combi 0 {self._combi} ; select 0 ; selrate {self._interval}; "
206+
f"pid {self.port} 0 1 s4 0.0027777778 0 5 0 .1 3; "
206207
f"set ramp {pos} {newpos} {dur} 0\r")
207208
self._write(cmd)
208209
with self._hat.rampcond[self.port]:
@@ -258,7 +259,8 @@ def run_to_position(self, degrees, speed=None, blocking=True, direction="shortes
258259

259260
def _run_for_seconds(self, seconds, speed):
260261
self._runmode = MotorRunmode.SECONDS
261-
cmd = (f"port {self.port} ; combi 0 {self._combi} ; select 0 ; pid {self.port} 0 0 s1 1 0 0.003 0.01 0 100; "
262+
cmd = (f"port {self.port} ; combi 0 {self._combi} ; select 0 ; selrate {self._interval}; "
263+
f"pid {self.port} 0 0 s1 1 0 0.003 0.01 0 100; "
262264
f"set pulse {speed} 0.0 {seconds} 0\r")
263265
self._write(cmd)
264266
with self._hat.pulsecond[self.port]:
@@ -308,7 +310,8 @@ def start(self, speed=None):
308310
raise MotorError("Invalid Speed")
309311
cmd = f"port {self.port} ; set {speed}\r"
310312
if self._runmode == MotorRunmode.NONE:
311-
cmd = (f"port {self.port} ; combi 0 {self._combi} ; select 0 ; pid {self.port} 0 0 s1 1 0 0.003 0.01 0 100; "
313+
cmd = (f"port {self.port} ; combi 0 {self._combi} ; select 0 ; selrate {self._interval}; "
314+
f"pid {self.port} 0 0 s1 1 0 0.003 0.01 0 100; "
312315
f"set {speed}\r")
313316
self._runmode = MotorRunmode.FREE
314317
self._currentspeed = speed

test/motors.py

+17
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,23 @@ def handle_motor(speed, pos, apos):
8181
m.run_for_seconds(1)
8282
self.assertGreater(handle_motor.evt, 0)
8383

84+
def test_callback_interval(self):
85+
"""Test setting callback and interval"""
86+
m = Motor('A')
87+
m.interval = 10
88+
89+
def handle_motor(speed, pos, apos):
90+
handle_motor.evt += 1
91+
handle_motor.evt = 0
92+
m.when_rotated = handle_motor
93+
m.run_for_seconds(5)
94+
self.assertGreater(handle_motor.evt, 0.8 * ((1 / ((m.interval) * 1e-3)) * 5))
95+
96+
handle_motor.evt = 0
97+
m.interval = 5
98+
m.run_for_seconds(5)
99+
self.assertGreater(handle_motor.evt, 0.8 * ((1 / ((m.interval) * 1e-3)) * 5))
100+
84101
def test_none_callback(self):
85102
"""Test setting empty callback"""
86103
m = Motor('A')

0 commit comments

Comments
 (0)