counts digital frequency based on interrupt and timer, triggers on rising edge
FrequencyCounter.cpp@0:91a906dbf731, 2016-08-09 (annotated)
- Committer:
- awmiller
- Date:
- Tue Aug 09 20:03:10 2016 +0000
- Revision:
- 0:91a906dbf731
first edition;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
awmiller | 0:91a906dbf731 | 1 | #include "FrequencyCounter.h" |
awmiller | 0:91a906dbf731 | 2 | #include <mbed.h> |
awmiller | 0:91a906dbf731 | 3 | |
awmiller | 0:91a906dbf731 | 4 | #ifndef INF |
awmiller | 0:91a906dbf731 | 5 | #define INF ((double)(1.0/0.0)) |
awmiller | 0:91a906dbf731 | 6 | #endif |
awmiller | 0:91a906dbf731 | 7 | |
awmiller | 0:91a906dbf731 | 8 | /* |
awmiller | 0:91a906dbf731 | 9 | * Class constructor initializes interrupt and starts rising edge triggering |
awmiller | 0:91a906dbf731 | 10 | */ |
awmiller | 0:91a906dbf731 | 11 | FrequencyCounter::FrequencyCounter(PinName pin) : _cPin(pin){ |
awmiller | 0:91a906dbf731 | 12 | this->_cPin.rise(this,&FrequencyCounter::_irqs); |
awmiller | 0:91a906dbf731 | 13 | this->_cPin.disable_irq(); //justin case |
awmiller | 0:91a906dbf731 | 14 | this->_iircoef = 0.9f; |
awmiller | 0:91a906dbf731 | 15 | this->_lastTime =0; |
awmiller | 0:91a906dbf731 | 16 | this->_fq = 0; |
awmiller | 0:91a906dbf731 | 17 | } |
awmiller | 0:91a906dbf731 | 18 | |
awmiller | 0:91a906dbf731 | 19 | /* |
awmiller | 0:91a906dbf731 | 20 | * Getter method for reading the averaged freqency |
awmiller | 0:91a906dbf731 | 21 | */ |
awmiller | 0:91a906dbf731 | 22 | double FrequencyCounter::getFrequency() { |
awmiller | 0:91a906dbf731 | 23 | return this->_fq; |
awmiller | 0:91a906dbf731 | 24 | } |
awmiller | 0:91a906dbf731 | 25 | |
awmiller | 0:91a906dbf731 | 26 | /* |
awmiller | 0:91a906dbf731 | 27 | * Getter method for reading the averaged freqency |
awmiller | 0:91a906dbf731 | 28 | */ |
awmiller | 0:91a906dbf731 | 29 | double FrequencyCounter::getTime() { |
awmiller | 0:91a906dbf731 | 30 | return this->_lastTime; |
awmiller | 0:91a906dbf731 | 31 | } |
awmiller | 0:91a906dbf731 | 32 | |
awmiller | 0:91a906dbf731 | 33 | /* |
awmiller | 0:91a906dbf731 | 34 | * Setter for modifying the coefficient of the averaging IIR filter |
awmiller | 0:91a906dbf731 | 35 | * the IIR Coefficient is the fraction of old data to keep, typically 0.9 |
awmiller | 0:91a906dbf731 | 36 | * Incoming data is multiplied by (1 - coeff) and added to (coeff * old_data) |
awmiller | 0:91a906dbf731 | 37 | */ |
awmiller | 0:91a906dbf731 | 38 | void FrequencyCounter::setIIRCoeff(double D) { |
awmiller | 0:91a906dbf731 | 39 | this->_iircoef = D; |
awmiller | 0:91a906dbf731 | 40 | } |
awmiller | 0:91a906dbf731 | 41 | |
awmiller | 0:91a906dbf731 | 42 | /* |
awmiller | 0:91a906dbf731 | 43 | * Starts the IRQ service |
awmiller | 0:91a906dbf731 | 44 | */ |
awmiller | 0:91a906dbf731 | 45 | void FrequencyCounter::start() { |
awmiller | 0:91a906dbf731 | 46 | this->_lastTime = 0; |
awmiller | 0:91a906dbf731 | 47 | this->_cPin.enable_irq(); |
awmiller | 0:91a906dbf731 | 48 | this->_fq = 0.0f; |
awmiller | 0:91a906dbf731 | 49 | this->_mtime.start(); |
awmiller | 0:91a906dbf731 | 50 | } |
awmiller | 0:91a906dbf731 | 51 | |
awmiller | 0:91a906dbf731 | 52 | /* |
awmiller | 0:91a906dbf731 | 53 | * Stops the IRQ service |
awmiller | 0:91a906dbf731 | 54 | */ |
awmiller | 0:91a906dbf731 | 55 | void FrequencyCounter::stop() { |
awmiller | 0:91a906dbf731 | 56 | this->_cPin.disable_irq(); //justin case |
awmiller | 0:91a906dbf731 | 57 | this->_mtime.stop(); |
awmiller | 0:91a906dbf731 | 58 | } |
awmiller | 0:91a906dbf731 | 59 | |
awmiller | 0:91a906dbf731 | 60 | /* |
awmiller | 0:91a906dbf731 | 61 | * IRQ service (private) implements a simple IIR LPF |
awmiller | 0:91a906dbf731 | 62 | */ |
awmiller | 0:91a906dbf731 | 63 | void FrequencyCounter::_irqs() { |
awmiller | 0:91a906dbf731 | 64 | //written long-hand for clarity, should get optimized out |
awmiller | 0:91a906dbf731 | 65 | double delta = (double)(this->_mtime.read_us()); |
awmiller | 0:91a906dbf731 | 66 | delta = delta/(10^6); |
awmiller | 0:91a906dbf731 | 67 | double nfq = 1/delta; |
awmiller | 0:91a906dbf731 | 68 | if(nfq == INF){ |
awmiller | 0:91a906dbf731 | 69 | nfq=0; |
awmiller | 0:91a906dbf731 | 70 | }else if(nfq < 0.01){ |
awmiller | 0:91a906dbf731 | 71 | nfq = 0.01; |
awmiller | 0:91a906dbf731 | 72 | } |
awmiller | 0:91a906dbf731 | 73 | this->_fq = this->_fq*this->_iircoef + (1-this->_iircoef)*nfq; // basic LPF |
awmiller | 0:91a906dbf731 | 74 | this->_mtime.reset(); |
awmiller | 0:91a906dbf731 | 75 | this->_lastTime = delta; |
awmiller | 0:91a906dbf731 | 76 | } |