-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpicomotodash_rpm.py
123 lines (88 loc) · 2.82 KB
/
picomotodash_rpm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# -*- coding: utf-8 -*-
"""Pico Motorcycle Dashboard RPM
"""
__author__ = "Salvatore La Bua"
from machine import Pin, Timer
from utime import ticks_us
pin = 22
PWM2RPM_FACTOR = 10
class RPM:
def __init__(self, pin=pin, factor=PWM2RPM_FACTOR, autostart=False):
self.pwm = Pin(pin, Pin.IN, Pin.PULL_DOWN) # RPM pwm
self.curr_interrupt = ticks_us()
self.prev_interrupt = ticks_us()
self.durations = []
self.RPM_ESTIMATE = 0
self.factor = factor
self.n_repeats = 1
self.duty = 50
self.timeout = False
self.timeout_max = 1000
self.timer = Timer()
if autostart:
self.start()
def start(self):
self.pwm.irq(
trigger=Pin.IRQ_FALLING,
handler=self.estimate,
# priority=2,
# hard=True,
)
self.timer.init(
freq=(1 / 1),
mode=Timer.PERIODIC,
callback=self.set_timeout,
)
def stop(self):
self.pwm.irq(handler=None)
self.timer.deinit()
def reset(self):
self.curr_interrupt = ticks_us()
self.prev_interrupt = ticks_us()
self.durations = []
self.RPM_ESTIMATE = 0
self.duty = 50
self.n_repeats = 1
self.timeout = False
self.start()
def estimate(self, _):
self.curr_interrupt = ticks_us()
cycle_duration = self.curr_interrupt - self.prev_interrupt
self.prev_interrupt = self.curr_interrupt
if len(self.durations) > self.n_repeats:
self.durations.pop(0)
self.durations.append(cycle_duration)
duration_avg = sum(self.durations) / len(self.durations)
freq = 1000000 / duration_avg
repeat_factor = ((50 - 20) / (1500 - 150)) * freq + ( # y = mx + q
50 - ((50 - 20) / (1500 - 150) * 1500) # magic numbers
)
self.n_repeats = (
int(freq / repeat_factor) if int(freq / repeat_factor) != 0 else 1
)
self.RPM_ESTIMATE = freq * self.factor
def set_timeout(self, _):
if ticks_us() - self.curr_interrupt > self.timeout_max:
self.stop()
self.timeout = True
def __enter__(self):
return self
def __exit__(self, exception_type, exception_value, traceback):
pass
if __name__ == "__main__":
from machine import PWM
from utime import sleep
pwm2 = PWM(Pin(2))
pwm2.freq(802)
pwm2.duty_u16(32768)
rpm = RPM(pin=pin, factor=PWM2RPM_FACTOR, autostart=True)
while True:
if not rpm.timeout and rpm.RPM_ESTIMATE > 0:
print(rpm.n_repeats, rpm.RPM_ESTIMATE)
else:
# rpm.stop()
print("TIMEOUT", rpm.RPM_ESTIMATE)
sleep(0.5)
rpm.reset()
# rpm.start()
sleep(0.02)