-
Notifications
You must be signed in to change notification settings - Fork 0
/
read_PWM.py
134 lines (99 loc) · 3.01 KB
/
read_PWM.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
124
125
126
127
128
129
130
131
132
# File to aid in reading the PWM from the feedback servo incorporated in this project
# read_PWM.py
# 2015-12-08
# Public Domain
import time
import pigpio
class reader:
"""
A class to read PWM pulses and calculate their frequency
and duty cycle. The frequency is how often the pulse
happens per second. The duty cycle is the percentage of
pulse high time per cycle.
"""
def __init__(self, pi, gpio, weighting=0.0):
"""
Instantiate with the Pi and gpio of the PWM signal
to monitor.
Optionally a weighting may be specified. This is a number
between 0 and 1 and indicates how much the old reading
affects the new reading. It defaults to 0 which means
the old reading has no effect. This may be used to
smooth the data.
"""
self.pi = pi
self.gpio = gpio
if weighting < 0.0:
weighting = 0.0
elif weighting > 0.99:
weighting = 0.99
self._new = 1.0 - weighting # Weighting for new reading.
self._old = weighting # Weighting for old reading.
self._high_tick = None
self._period = None
self._high = None
pi.set_mode(gpio, pigpio.INPUT)
self._cb = pi.callback(gpio, pigpio.EITHER_EDGE, self._cbf)
def _cbf(self, gpio, level, tick):
if level == 1:
if self._high_tick is not None:
t = pigpio.tickDiff(self._high_tick, tick)
if self._period is not None:
self._period = (self._old * self._period) + (self._new * t)
else:
self._period = t
self._high_tick = tick
elif level == 0:
if self._high_tick is not None:
t = pigpio.tickDiff(self._high_tick, tick)
if self._high is not None:
self._high = (self._old * self._high) + (self._new * t)
else:
self._high = t
def frequency(self):
"""
Returns the PWM frequency.
"""
if self._period is not None:
return 1000000.0 / self._period
else:
return 0.0
def pulse_width(self):
"""
Returns the PWM pulse width in microseconds.
"""
if self._high is not None:
return self._high
else:
return 0.0
def duty_cycle(self):
"""
Returns the PWM duty cycle percentage.
"""
if self._high is not None:
return 100.0 * self._high / self._period
else:
return 0.0
def cancel(self):
"""
Cancels the reader and releases resources.
"""
self._cb.cancel()
if __name__ == "__main__":
import time
import pigpio
import read_PWM
PWM_GPIO = 20
RUN_TIME = 60.0
SAMPLE_TIME = 0.1
pi = pigpio.pi()
p = read_PWM.reader(pi, PWM_GPIO)
start = time.time()
while (time.time() - start) < RUN_TIME:
time.sleep(SAMPLE_TIME)
f = p.frequency()
pw = p.pulse_width()
dc = p.duty_cycle()
print("f={:.1f} pw={} dc={:.2f}".format(f, int(pw+0.5), dc))
p.cancel()
pi.stop()