Monitor for central heating system (e.g. 2zones+hw) Supports up to 15 temp probes (DS18B20/DS18S20) 3 valve monitors Gas pulse meter recording Use stand-alone or with nodeEnergyServer See http://robdobson.com/2015/09/central-heating-monitor

Dependencies:   EthernetInterfacePlusHostname NTPClient Onewire RdWebServer SDFileSystem-RTOS mbed-rtos mbed-src

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PulsePin.cpp Source File

PulsePin.cpp

00001 // Handles a pin that has a slow pulse applied
00002 // Written for a gas meter monitor
00003 // Rob Dobson, 2015
00004 
00005 #include "PulsePin.h"
00006 
00007 PulsePin::PulsePin(DigitalIn& pin, bool detectRisingEdge, int waitForPinStabilisationMs) :
00008     _pin(pin)
00009 {
00010     _detectRisingEdge = detectRisingEdge;
00011     _waitForPinStabilisationMs = waitForPinStabilisationMs;
00012     _pinTimer.start();
00013     _curPinState = _pin;
00014     _lastStableTimeMs = _pinTimer.read_ms();
00015     _firstEdgeDetected = false;
00016     _timeBetweenEdgesMs = 0;
00017     _pulseCount = 0;
00018     _pinTimerMinutes = 0;
00019 }
00020 
00021 bool PulsePin::Service()
00022 {
00023     // Check time since last edge - looking for stability
00024     int timeNowMs = _pinTimer.read_ms();
00025     
00026     // Check if over 1 minute (as the timer wraps around after 30 mins)
00027     if (timeNowMs > 60000)
00028     {
00029         _pinTimerMinutes++;
00030         _pinTimer.reset();
00031         timeNowMs -= 60000;
00032     }
00033     
00034     // Get the real time elapsed (still wraps but now only after about 500 hours)
00035     timeNowMs = _pinTimerMinutes*60000 + timeNowMs;
00036     
00037     // Check for pin stabilization    
00038     if (timeNowMs < _lastStableTimeMs + _waitForPinStabilisationMs)
00039         return false;
00040 
00041     // Check for a change of state
00042     bool pinState = _pin;
00043     if (pinState == _curPinState)
00044         return false;
00045         
00046     _curPinState = pinState;
00047     _lastStableTimeMs = timeNowMs;
00048     
00049     // Check if this is the direction of edge we're looking for
00050     if (pinState != _detectRisingEdge)
00051         return false;
00052         
00053     // Reset the timer to avoid wrap around problems
00054     bool firstEdgeDetected = _firstEdgeDetected;
00055     _pinTimerMinutes = 0;
00056     _pinTimer.reset();
00057     _firstEdgeDetected = true;
00058     _lastStableTimeMs = 0;
00059     
00060     // Check if this should be returned
00061     if (!firstEdgeDetected)
00062         return false;
00063     _timeBetweenEdgesMs = timeNowMs;
00064     _pulseCount++;
00065     return true;
00066 }
00067 
00068 int PulsePin::GetPulseRateMs()
00069 {
00070     return _timeBetweenEdgesMs;
00071 }
00072 
00073 int PulsePin::GetPulseCount()
00074 {
00075     return _pulseCount;
00076 }
00077 
00078 void PulsePin::SetPulseCount(int pulseCount)
00079 {
00080     _pulseCount = pulseCount;
00081 }