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

PulsePin.cpp

Committer:
Bobty
Date:
2015-10-16
Revision:
23:fd5a5a9f30bc
Parent:
10:72eb217def1f

File content as of revision 23:fd5a5a9f30bc:

// Handles a pin that has a slow pulse applied
// Written for a gas meter monitor
// Rob Dobson, 2015

#include "PulsePin.h"

PulsePin::PulsePin(DigitalIn& pin, bool detectRisingEdge, int waitForPinStabilisationMs) :
    _pin(pin)
{
    _detectRisingEdge = detectRisingEdge;
    _waitForPinStabilisationMs = waitForPinStabilisationMs;
    _pinTimer.start();
    _curPinState = _pin;
    _lastStableTimeMs = _pinTimer.read_ms();
    _firstEdgeDetected = false;
    _timeBetweenEdgesMs = 0;
    _pulseCount = 0;
    _pinTimerMinutes = 0;
}

bool PulsePin::Service()
{
    // Check time since last edge - looking for stability
    int timeNowMs = _pinTimer.read_ms();
    
    // Check if over 1 minute (as the timer wraps around after 30 mins)
    if (timeNowMs > 60000)
    {
        _pinTimerMinutes++;
        _pinTimer.reset();
        timeNowMs -= 60000;
    }
    
    // Get the real time elapsed (still wraps but now only after about 500 hours)
    timeNowMs = _pinTimerMinutes*60000 + timeNowMs;
    
    // Check for pin stabilization    
    if (timeNowMs < _lastStableTimeMs + _waitForPinStabilisationMs)
        return false;

    // Check for a change of state
    bool pinState = _pin;
    if (pinState == _curPinState)
        return false;
        
    _curPinState = pinState;
    _lastStableTimeMs = timeNowMs;
    
    // Check if this is the direction of edge we're looking for
    if (pinState != _detectRisingEdge)
        return false;
        
    // Reset the timer to avoid wrap around problems
    bool firstEdgeDetected = _firstEdgeDetected;
    _pinTimerMinutes = 0;
    _pinTimer.reset();
    _firstEdgeDetected = true;
    _lastStableTimeMs = 0;
    
    // Check if this should be returned
    if (!firstEdgeDetected)
        return false;
    _timeBetweenEdgesMs = timeNowMs;
    _pulseCount++;
    return true;
}

int PulsePin::GetPulseRateMs()
{
    return _timeBetweenEdgesMs;
}

int PulsePin::GetPulseCount()
{
    return _pulseCount;
}

void PulsePin::SetPulseCount(int pulseCount)
{
    _pulseCount = pulseCount;
}