Skip to content

Commit 91cea1c

Browse files
authored
New Sensor Module: Frequency Counter (#378)
* Add generic Frequency Counter Module
1 parent e040590 commit 91cea1c

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ Hardware support is provided by specific GPIO, Sensor and Stream modules. It's e
4646
- PMS5003 particulate sensor (`pms5003`)
4747
- SHT40/SHT41/SHT45 temperature and humidity sensors (`sht4x`)
4848
- YF-S201 flow rate sensor (`yfs201`)
49+
- FREQUENCYCOUNTER Counts pulses from GPIOs and return the frequency in Hz (frequencycounter)
4950
- FLOWSENSOR generic flow rate sensor like YF-S201 or YF-DN50 (`flowsensor`)
5051

52+
5153
### Streams
5254

5355
- Serial port (`serial`)
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
"""
2+
3+
Frequencycounter: Generic Frequency Counter
4+
5+
Example configuration:
6+
7+
sensor_modules:
8+
- name: frequency
9+
module: frequencycounter
10+
11+
sensor_inputs:
12+
- name: flow_rate1
13+
module: frequency
14+
pin: 0
15+
digits: 0
16+
interval: 10
17+
18+
"""
19+
20+
from typing import Dict
21+
from ...types import CerberusSchemaType, ConfigType, SensorValueType
22+
from . import GenericSensor
23+
24+
REQUIREMENTS = ("gpiozero",)
25+
26+
27+
class FREQUENCYCOUNTER:
28+
"""
29+
Frequency Counter class
30+
Multiple instances support multiple sensors on different pins
31+
"""
32+
33+
def __init__(self, gpiozero, name: str, pin: int) -> None: # type: ignore[no-untyped-def]
34+
self.name = name
35+
self.pin = gpiozero.DigitalInputDevice(pin)
36+
self.pin.when_activated = self.count_pulse
37+
self.count = 0
38+
39+
def count_pulse(self) -> None:
40+
"""Increment pulse count."""
41+
self.count += 1
42+
43+
def reset_count(self) -> None:
44+
"""Reset pulse count."""
45+
self.count = 0
46+
47+
def frequency(self, sample_window: int) -> float:
48+
"""
49+
sample_window is in seconds, so hz is pulse_count / sample_window
50+
"""
51+
hertz = self.count / sample_window
52+
return hertz
53+
54+
def get_value(self, interval: int) -> float:
55+
"""Return frequency over interval seconds and reset count."""
56+
frequency = self.frequency(interval)
57+
self.reset_count()
58+
return frequency
59+
60+
61+
class Sensor(GenericSensor):
62+
"""
63+
Frequency Counter
64+
"""
65+
66+
SENSOR_SCHEMA: CerberusSchemaType = {
67+
"pin": {
68+
"type": 'integer',
69+
"required": True,
70+
"empty": False,
71+
},
72+
"interval": {
73+
"type": 'integer',
74+
"required": True,
75+
"empty": False,
76+
}
77+
}
78+
79+
def setup_module(self) -> None:
80+
# pylint: disable=import-outside-toplevel,import-error
81+
import gpiozero # type: ignore
82+
83+
self.gpiozero = gpiozero
84+
self.sensors: Dict[str, FREQUENCYCOUNTER] = {}
85+
86+
def setup_sensor(self, sens_conf: ConfigType) -> None:
87+
sensor = FREQUENCYCOUNTER(
88+
gpiozero=self.gpiozero, name=sens_conf["name"], pin=sens_conf["pin"]
89+
)
90+
self.sensors[sensor.name] = sensor
91+
92+
def get_value(self, sens_conf: ConfigType) -> SensorValueType:
93+
return self.sensors[sens_conf["name"]].get_value(sens_conf["interval"])

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy