Code: Alles auswählen
#!/usr/bin/env python
import time
import pigpio
class reader:
"""
A class to read speedometer pulses and calculate the RPM.
"""
def __init__(self, pi, gpio, pulses_per_rev=1.0, weighting=0, min_RPM=5):
"""
Instantiate with the Pi and gpio of the RPM signal
to monitor.
Optionally the number of pulses for a complete revolution
may be specified. It defaults to 1.
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.
Optionally the minimum RPM may be specified. This is a
number between 1 and 1000. It defaults to 5. An RPM
less than the minimum RPM returns 0.0.
"""
self.pi = pi
self.gpio = gpio
self.pulses_per_rev = pulses_per_rev
if min_RPM > 1000:
min_RPM = 1000
elif min_RPM < 1:
min_RPM = 1
self.min_RPM = min_RPM
self._watchdog = 200 # Milliseconds.
if weighting < 0:
weighting = 0
elif weighting > 0:
weighting = 0
self._new = 1 - weighting # Weighting for new reading.
self._old = weighting # Weighting for old reading.
self._high_tick = None
self._period = None
pi.set_mode(gpio, pigpio.INPUT)
self._cb = pi.callback(gpio, pigpio.RISING_EDGE, self._cbf)
pi.set_watchdog(gpio, self._watchdog)
def _cbf(self, gpio, level, tick):
if level == 1: # Rising edge.
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 == 2: # Watchdog timeout.
if self._period is not None:
if self._period < 2000000000:
self._period += (self._watchdog * 1000)
def RPM(self):
"""
Returns the RPM.
"""
RPM = 0
if self._period is not None:
RPM = 60000000 / (self._period * self.pulses_per_rev)
if RPM < self.min_RPM:
RPM = 0
return RPM
def cancel(self):
"""
Cancels the reader and releases resources.
"""
self.pi.set_watchdog(self.gpio, 0) # cancel watchdog
self._cb.cancel()
if __name__ == "__main__":
import time
import pigpio
import readRPM
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(20, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
count = 5
RPM_GPIO = 4
RUN_TIME = 9600.0
SAMPLE_TIME = 2.0
RPM_LOWER_LIMIT = 15
RPM_HIGHER_LIMIT = 320
LEVEL_TO_POWER = {
1: [6,12,20,29,40,53,69,79,92,106,121],
2: [8,16,26,38,53,68,88,103,120,138,152],
3: [9,20,32,47,66,84,107,125,148,172,186],
4: [11,23,39,56,79,101,126,150,173,206,219],
5: [13,27,45,65,92,117,145,175,202,238,254],
6: [15,31,52,75,105,135,166,202,231,275,289],
7: [16,35,58,85,118,152,185,226,260,305,332],
8: [18,39,65,96,131,169,208,249,289,333,375],
9: [19,42,71,104,144,184,227,272,318,361,408],
10:[21,46,77,113,157,199,245,295,345,386,442],
11:[23,50,84,123,170,216,262,318,372,413,480],
12:[24,53,89,131,183,230,279,342,398,441,512],
13:[26,56,94,139,196,245,296,365,424,468,548],
14:[28,60,101,148,209,261,318,389,449,494,585],
15:[30,64,108,158,222,277,337,415,476,518,620],
16:[32,68,115,168,235,296,355,439,503,548,658],
17:[33,72,122,177,248,312,373,463,530,576,694],
18:[35,76,129,187,261,328,390,484,556,606,727],
19:[37,79,134,195,274,342,407,507,572,632,763],
20:[39,83,140,204,287,354,424,528,598,659,790],
21:[40,87,146,213,300,368,442,551,616,689,812],
22:[42,91,153,223,313,385,461,574,645,720,840],
23:[44,95,160,234,326,401,479,598,673,752,872],
24:[47,101,171,246,340,418,501,625,706,788,908],
}
def calculate_power(LEVEL, RPM):
if RPM < RPM_LOWER_LIMIT:
return 0
return LEVEL_TO_POWER[LEVEL][(RPM - RPM_LOWER_LIMIT) //10]
if RPM > RPM_HIGHER_LIMIT:
return 0
return LEVEL_TO_POWER[LEVEL][(RPM + RPM_HIGHER_LIMIT) //10]
def main():
for LEVEL, RPM in [(1, 6), (2, 8), (3, 9)]:
print(calculate_power(LEVEL, RPM))
pi = pigpio.pi()
p = readRPM.reader(pi, RPM_GPIO)
start = time.time()
while (time.time() - start) < RUN_TIME:
input_state = GPIO.input(20)
if input_state == False:
if count < 24:
count = count + 1
RPM = (int(RPM+1))
LEVEL = count
print('Power',calculate_power(LEVEL, RPM),'Level', count, 'RPM={}'.format(int(RPM+1)))
print(calculate_power(LEVEL, RPM))
time.sleep(SAMPLE_TIME)
input_state = GPIO.input(21)
if input_state == False:
if count > 1:
count = count - 1
RPM = (int(RPM+1))
LEVEL = count
print('Power',calculate_power(LEVEL, RPM),'Level', count, 'RPM={}'.format(int(RPM+1)))
time.sleep(SAMPLE_TIME)
LEVEL = count
RPM = p.RPM()
RPM = (int(RPM+1))
time.sleep(SAMPLE_TIME)
print('Power',calculate_power(LEVEL, RPM),'Level', count, "RPM={}".format(int(RPM+1)))
p.cancel()
pi.stop()
if __name__ == '__main__':
main()