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
diff -r 000000000000 -r 91a906dbf731 FrequencyCounter.cpp
--- /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;
+}
diff -r 000000000000 -r 91a906dbf731 FrequencyCounter.h
--- /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
+