Pulse measurement to know signal occupancy

Dependents:   PwmReaderTest

Committer:
abouillot
Date:
Thu Jan 26 08:26:22 2017 +0000
Revision:
1:ebc39fb22351
Parent:
0:15aa9d3aeb2e
Fixed few bugs and added inline documentation. It is now possible to retrieve the time spent in a state in us, ms and seconds.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
abouillot 0:15aa9d3aeb2e 1 /*!
abouillot 0:15aa9d3aeb2e 2 * PwmReader.cpp
abouillot 0:15aa9d3aeb2e 3 *
abouillot 0:15aa9d3aeb2e 4 * Read signal occupacy on a pin in a non blocking way using timer and interrupt
abouillot 0:15aa9d3aeb2e 5 *
abouillot 0:15aa9d3aeb2e 6 * Copyright (c) 2017 - Alexandre Bouillot github.com/abouillot
abouillot 0:15aa9d3aeb2e 7 *
abouillot 0:15aa9d3aeb2e 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
abouillot 0:15aa9d3aeb2e 9 * of this software and associated documnetation files (the "Software"), to deal
abouillot 0:15aa9d3aeb2e 10 * in the Software without restriction, including without limitation the rights
abouillot 0:15aa9d3aeb2e 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
abouillot 0:15aa9d3aeb2e 12 * copies of the Software, and to permit persons to whom the Software is
abouillot 0:15aa9d3aeb2e 13 * furished to do so, subject to the following conditions:
abouillot 0:15aa9d3aeb2e 14 *
abouillot 0:15aa9d3aeb2e 15 * The above copyright notice and this permission notice shall be included in
abouillot 0:15aa9d3aeb2e 16 * all copies or substantial portions of the Software.
abouillot 0:15aa9d3aeb2e 17 *
abouillot 0:15aa9d3aeb2e 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
abouillot 0:15aa9d3aeb2e 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
abouillot 0:15aa9d3aeb2e 20 * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
abouillot 0:15aa9d3aeb2e 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
abouillot 0:15aa9d3aeb2e 22 * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
abouillot 0:15aa9d3aeb2e 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
abouillot 0:15aa9d3aeb2e 24 * THE SOFTWARE.
abouillot 0:15aa9d3aeb2e 25 */
abouillot 1:ebc39fb22351 26
abouillot 0:15aa9d3aeb2e 27 #include "PwmReader.h"
abouillot 0:15aa9d3aeb2e 28
abouillot 1:ebc39fb22351 29 /// #define TRACE to enable TRACEs using printf #undef to disable
abouillot 1:ebc39fb22351 30 #undef TRACE
abouillot 1:ebc39fb22351 31
abouillot 0:15aa9d3aeb2e 32
abouillot 0:15aa9d3aeb2e 33 void PwmReader::pressedInt()
abouillot 0:15aa9d3aeb2e 34 {
abouillot 1:ebc39fb22351 35 long now = _timer.read_us();
abouillot 1:ebc39fb22351 36 // signal moved from high to low, record the time spent in this state
abouillot 0:15aa9d3aeb2e 37 _high += _timer.read_us() - _last_toggle;
abouillot 1:ebc39fb22351 38 // record the new timestamp
abouillot 0:15aa9d3aeb2e 39 _last_toggle = _timer.read_us();
abouillot 1:ebc39fb22351 40 #ifdef TRACE
abouillot 1:ebc39fb22351 41 printf("p %ld ", _high);
abouillot 1:ebc39fb22351 42 #endif
abouillot 0:15aa9d3aeb2e 43 // sleep();
abouillot 0:15aa9d3aeb2e 44 }
abouillot 0:15aa9d3aeb2e 45
abouillot 0:15aa9d3aeb2e 46 void PwmReader::releasedInt()
abouillot 0:15aa9d3aeb2e 47 {
abouillot 1:ebc39fb22351 48 long now = _timer.read_us();
abouillot 1:ebc39fb22351 49 // signal moved from down to high, record the time spent in this state
abouillot 1:ebc39fb22351 50 _down += now - _last_toggle;
abouillot 1:ebc39fb22351 51 // record the new timestamp
abouillot 1:ebc39fb22351 52 _last_toggle = now;
abouillot 1:ebc39fb22351 53 #ifdef TRACE
abouillot 1:ebc39fb22351 54 printf("r %ld", _down);
abouillot 1:ebc39fb22351 55 #endif
abouillot 0:15aa9d3aeb2e 56 // sleep();
abouillot 0:15aa9d3aeb2e 57 }
abouillot 0:15aa9d3aeb2e 58
abouillot 0:15aa9d3aeb2e 59 void PwmReader::init()
abouillot 0:15aa9d3aeb2e 60 {
abouillot 1:ebc39fb22351 61 // register the interupt attached with the levels changes
abouillot 0:15aa9d3aeb2e 62 _pin.fall(callback(this, &PwmReader::pressedInt));
abouillot 0:15aa9d3aeb2e 63 _pin.rise(callback(this, &PwmReader::releasedInt));
abouillot 0:15aa9d3aeb2e 64 }
abouillot 0:15aa9d3aeb2e 65
abouillot 0:15aa9d3aeb2e 66 void PwmReader::start()
abouillot 0:15aa9d3aeb2e 67 {
abouillot 1:ebc39fb22351 68 // reset the storing variable
abouillot 0:15aa9d3aeb2e 69 _high = 0;
abouillot 0:15aa9d3aeb2e 70 _down = 0;
abouillot 1:ebc39fb22351 71 _last_toggle = 0;
abouillot 1:ebc39fb22351 72
abouillot 1:ebc39fb22351 73 // store the inital state
abouillot 0:15aa9d3aeb2e 74 _start_state = _pin.read();
abouillot 1:ebc39fb22351 75
abouillot 1:ebc39fb22351 76 // start the timer at 0
abouillot 1:ebc39fb22351 77 _timer.reset();
abouillot 1:ebc39fb22351 78 _timer.start();
abouillot 1:ebc39fb22351 79
abouillot 1:ebc39fb22351 80 // enable the IRQ requests
abouillot 0:15aa9d3aeb2e 81 _pin.enable_irq();
abouillot 1:ebc39fb22351 82
abouillot 1:ebc39fb22351 83 #ifdef TRACE
abouillot 1:ebc39fb22351 84 if (_pin.read() != _start_state) {
abouillot 1:ebc39fb22351 85 printf("toggle ");
abouillot 1:ebc39fb22351 86 }
abouillot 1:ebc39fb22351 87 if (_pin.read() == 0) {
abouillot 1:ebc39fb22351 88 printf("low ");
abouillot 1:ebc39fb22351 89 }
abouillot 1:ebc39fb22351 90 if (_pin.read() == 1) {
abouillot 1:ebc39fb22351 91 printf("high ");
abouillot 1:ebc39fb22351 92 }
abouillot 1:ebc39fb22351 93 #endif
abouillot 0:15aa9d3aeb2e 94 }
abouillot 0:15aa9d3aeb2e 95
abouillot 0:15aa9d3aeb2e 96 void PwmReader::stop()
abouillot 0:15aa9d3aeb2e 97 {
abouillot 1:ebc39fb22351 98 // disable the IRQ request, to avoid code call
abouillot 0:15aa9d3aeb2e 99 _pin.disable_irq();
abouillot 0:15aa9d3aeb2e 100
abouillot 1:ebc39fb22351 101 // no time has been recorded. The signal stayed at the same level from the start of measurment
abouillot 0:15aa9d3aeb2e 102 if (_high == 0 && _down == 0)
abouillot 1:ebc39fb22351 103 // retrieve the duration of the measurment to assign it to the right state
abouillot 1:ebc39fb22351 104 if (_start_state == 1)
abouillot 0:15aa9d3aeb2e 105 _high = _timer.read_us();
abouillot 1:ebc39fb22351 106 else if (_start_state == 0)
abouillot 0:15aa9d3aeb2e 107 _down = _timer.read_us();
abouillot 1:ebc39fb22351 108
abouillot 1:ebc39fb22351 109 // stop the running timer
abouillot 0:15aa9d3aeb2e 110 _timer.stop();
abouillot 0:15aa9d3aeb2e 111 }