counts digital frequency based on interrupt and timer, triggers on rising edge

Files at this revision

API Documentation at this revision

Comitter:
awmiller
Date:
Tue Aug 09 20:03:10 2016 +0000
Commit message:
first edition;

Changed in this revision

FrequencyCounter.cpp Show annotated file Show diff for this revision Revisions of this file
FrequencyCounter.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FrequencyCounter.cpp	Tue Aug 09 20:03:10 2016 +0000
@@ -0,0 +1,76 @@
+#include "FrequencyCounter.h"
+#include <mbed.h>
+
+#ifndef INF
+#define INF ((double)(1.0/0.0))
+#endif
+
+/*
+ * Class constructor initializes interrupt and starts rising edge triggering
+ */
+FrequencyCounter::FrequencyCounter(PinName pin) : _cPin(pin){  
+    this->_cPin.rise(this,&FrequencyCounter::_irqs);
+    this->_cPin.disable_irq(); //justin case
+    this->_iircoef = 0.9f;
+    this->_lastTime =0;
+    this->_fq = 0;
+}
+
+/*
+ *  Getter method for reading the averaged freqency
+ */
+double FrequencyCounter::getFrequency() {
+    return this->_fq;
+}
+
+/*
+ *  Getter method for reading the averaged freqency
+ */
+double FrequencyCounter::getTime() {
+    return this->_lastTime;
+}
+
+/*
+ * Setter for modifying the coefficient of the averaging IIR filter
+ * the IIR Coefficient is the fraction of old data to keep, typically 0.9
+ * Incoming data is multiplied by (1 - coeff) and added to (coeff * old_data)
+ */    
+void FrequencyCounter::setIIRCoeff(double D) {
+    this->_iircoef = D;
+}
+
+/*
+ * Starts the IRQ service
+ */
+void FrequencyCounter::start() {
+    this->_lastTime = 0;
+    this->_cPin.enable_irq();  
+    this->_fq = 0.0f;
+    this->_mtime.start();
+}
+
+/*
+ * Stops the IRQ service
+ */
+void FrequencyCounter::stop() {
+    this->_cPin.disable_irq(); //justin case
+    this->_mtime.stop();
+}
+
+/*
+ * IRQ service (private) implements a simple IIR LPF
+ */
+void FrequencyCounter::_irqs() {
+    //written long-hand for clarity, should get optimized out
+    double delta = (double)(this->_mtime.read_us());
+    delta = delta/(10^6);
+    double nfq = 1/delta;
+    if(nfq == INF){
+        nfq=0;
+    }else if(nfq < 0.01){
+        nfq = 0.01;
+    }
+    this->_fq = this->_fq*this->_iircoef + (1-this->_iircoef)*nfq; // basic LPF    
+    this->_mtime.reset();
+    this->_lastTime = delta;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FrequencyCounter.h	Tue Aug 09 20:03:10 2016 +0000
@@ -0,0 +1,26 @@
+#ifndef FREQUENCY_COUNTER_H_DECL
+#define FREQUENCY_COUNTER_H_DECL
+
+#include <mbed.h>
+
+class FrequencyCounter {
+    //mbed classes
+    Timer _mtime;
+    InterruptIn _cPin;
+    
+    double _lastTime;
+    double _fq;
+    double _iircoef;
+    void _irqs(void);
+    
+public:
+    
+    FrequencyCounter(PinName);    
+    double getFrequency();
+    double getTime();
+    void setIIRCoeff(double);
+    void start();
+    void stop();
+};
+#endif
+