Skip to content

Commit d6bb5cf

Browse files
committed
Added rollover to Counter.
1 parent f74408a commit d6bb5cf

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

inputs.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,14 @@ class Counter(DigitalBase):
210210
ONE_EDGE = 1
211211
BOTH_EDGES = 2
212212

213-
def __init__(self, pin_name, stable_read_count=4, edges=ONE_EDGE, reset_on_read=False, **kwargs):
213+
def __init__(self, pin_name, stable_read_count=4, edges=ONE_EDGE, reset_on_read=False,
214+
rollover=2**32, **kwargs):
214215
'''Arguments not in the inheritance chain:
215216
edges: Either ONE_EDGE or BOTH_EDGES indicating which transitions of the pulse to
216217
count.
217218
reset_on_read: if True, the counter value will be reset to 0 after the count
218219
is read via a call to the value() method.
220+
rollover: count will roll to 0 when it hits this value.
219221
Note that the default 'stable_read_count' value is set to 4 reads. With the
220222
default 2.1 ms read interval, this requires stability for 8.4 ms. Counters are
221223
often reed switches or electronic pulse trains, both of which have little to no
@@ -225,10 +227,15 @@ def __init__(self, pin_name, stable_read_count=4, edges=ONE_EDGE, reset_on_read=
225227
DigitalBase.__init__(self, pin_name, stable_read_count=stable_read_count, **kwargs)
226228
self.edges = edges
227229
self.reset_on_read = reset_on_read
228-
self._low_to_high_count = 0
229-
self._high_to_low_count = 0
230+
self._rollover = rollover
231+
self._count = 0
230232
self._new_val = None # need to allocate memory here, not in interrupt routine
231233

234+
def incr_counter(self):
235+
'''Increments the count accounting for rollover.
236+
'''
237+
self._count = (self._count + 1) % self._rollover
238+
232239
def service_input(self):
233240
# shift the prior readings over one bit, and put the new reading
234241
# in the LSb position.
@@ -241,29 +248,28 @@ def service_input(self):
241248
if self._new_val == self._cur_val:
242249
# no change in value
243250
return
244-
if self._new_val > self._cur_val:
245-
# transition from low to high occurred.
246-
self._low_to_high_count += 1
247-
else:
248-
# transition from high to low occurred.
249-
self._high_to_low_count += 1
251+
if self._new_val < self._cur_val:
252+
# transition from high to low occurred. Always count these
253+
# transitions.
254+
self.incr_counter()
255+
elif self.edges == Counter.BOTH_EDGES:
256+
# A low to high transition occurred and counting both edges
257+
# was requested, so increment counter.
258+
self.incr_counter()
250259
self._cur_val = self._new_val
251260

252261
def _compute_value(self):
253-
if self.edges == Counter.ONE_EDGE:
254-
ct = self._high_to_low_count
255-
else:
256-
ct = self._high_to_low_count + self._low_to_high_count
262+
ct = self._count
257263
if self.reset_on_read:
258-
self._high_to_low_count = self._low_to_high_count = 0
264+
self._count = 0
259265
return ct
260266

261267
def reset_count(self):
262268
'''Resets the counts and protects the processs form being
263269
interrupted.
264270
'''
265271
irq_state = pyb.disable_irq()
266-
self._high_to_low_count = self._low_to_high_count = 0
272+
self._count = 0
267273
pyb.enable_irq(irq_state)
268274

269275

0 commit comments

Comments
 (0)