From b0625e11f18d904fb14988b19fea4e5adc9d276a Mon Sep 17 00:00:00 2001 From: Jon Trulson Date: Thu, 27 Aug 2015 16:57:16 -0600 Subject: [PATCH] wheelencoder: Initial implementation This driver was developed for the DFRobot Wheel Encoder, though it could be used for any counting time-based task using a digital i/o pin to generate interrupts. http://www.dfrobot.com/index.php?route=product/product&product_id=98 If you want to use more than one encoder, simply create a class instance for each one. Signed-off-by: Jon Trulson Signed-off-by: sisinty sasmita patra --- examples/c++/CMakeLists.txt | 3 + examples/c++/wheelencoder.cxx | 69 +++++++++++++ examples/javascript/wheelencoder.js | 54 ++++++++++ examples/python/wheelencoder.py | 50 +++++++++ src/wheelencoder/CMakeLists.txt | 5 + src/wheelencoder/javaupm_wheelencoder.i | 8 ++ src/wheelencoder/jsupm_wheelencoder.i | 8 ++ src/wheelencoder/pyupm_wheelencoder.i | 9 ++ src/wheelencoder/wheelencoder.cxx | 106 +++++++++++++++++++ src/wheelencoder/wheelencoder.h | 131 ++++++++++++++++++++++++ 10 files changed, 443 insertions(+) create mode 100644 examples/c++/wheelencoder.cxx create mode 100644 examples/javascript/wheelencoder.js create mode 100644 examples/python/wheelencoder.py create mode 100644 src/wheelencoder/CMakeLists.txt create mode 100644 src/wheelencoder/javaupm_wheelencoder.i create mode 100644 src/wheelencoder/jsupm_wheelencoder.i create mode 100644 src/wheelencoder/pyupm_wheelencoder.i create mode 100644 src/wheelencoder/wheelencoder.cxx create mode 100644 src/wheelencoder/wheelencoder.h diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index 71350e70..353bf69d 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -135,6 +135,7 @@ add_executable (lsm9ds0-example lsm9ds0.cxx) add_executable (eboled-example eboled.cxx) add_executable (hyld9767-example hyld9767.cxx) add_executable (mg811-example mg811.cxx) +add_executable (wheelencoder-example wheelencoder.cxx) include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l) include_directories (${PROJECT_SOURCE_DIR}/src/grove) @@ -243,6 +244,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/pn532) include_directories (${PROJECT_SOURCE_DIR}/src/lsm9ds0) include_directories (${PROJECT_SOURCE_DIR}/src/hyld9767) include_directories (${PROJECT_SOURCE_DIR}/src/mg811) +include_directories (${PROJECT_SOURCE_DIR}/src/wheelencoder) target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT}) @@ -379,3 +381,4 @@ target_link_libraries (lsm9ds0-example lsm9ds0 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (eboled-example i2clcd ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (hyld9767-example hyld9767 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (mg811-example mg811 ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (wheelencoder-example wheelencoder ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/c++/wheelencoder.cxx b/examples/c++/wheelencoder.cxx new file mode 100644 index 00000000..08a7825b --- /dev/null +++ b/examples/c++/wheelencoder.cxx @@ -0,0 +1,69 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include "wheelencoder.h" + +using namespace std; + +int shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + + +int main() +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + // Instantiate a DFRobot Wheel Encoder on digital pin D2 + upm::WheelEncoder* sensor = new upm::WheelEncoder(2); + + // set the counter to 0 and start counting + sensor->clearCounter(); + sensor->startCounter(); + + while (shouldRun) + { + // output milliseconds passed and current sensor count + cout << "Millis: " << sensor->getMillis() << " Count: " + << sensor->counter() << endl; + + sleep(1); + } + + sensor->stopCounter(); +//! [Interesting] + + cout << "Exiting..." << endl; + + delete sensor; + return 0; +} diff --git a/examples/javascript/wheelencoder.js b/examples/javascript/wheelencoder.js new file mode 100644 index 00000000..532ea029 --- /dev/null +++ b/examples/javascript/wheelencoder.js @@ -0,0 +1,54 @@ +/*jslint node:true, vars:true, bitwise:true, unparam:true */ +/*jshint unused:true */ + +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +var sensorObj = require('jsupm_wheelencoder'); + +// Instantiate a DFRobot Wheel Encoder on digital pin D2 +var sensor = new sensorObj.WheelEncoder(2); + +// set the counter to 0 and start counting +sensor.clearCounter(); +sensor.startCounter(); + +setInterval(function() +{ + // output milliseconds passed and current sensor count + console.log("Millis: " + sensor.getMillis() + " Count: " + + sensor.counter()); +}, 1000); + +// exit on ^C +process.on('SIGINT', function() +{ + sensor = null; + sensorObj.cleanUp(); + sensorObj = null; + console.log("Exiting."); + process.exit(0); +}); + diff --git a/examples/python/wheelencoder.py b/examples/python/wheelencoder.py new file mode 100644 index 00000000..b61cc872 --- /dev/null +++ b/examples/python/wheelencoder.py @@ -0,0 +1,50 @@ +#!/usr/bin/python +# Author: Jon Trulson +# Copyright (c) 2015 Intel Corporation. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import time, sys, signal, atexit +import pyupm_wheelencoder as sensorObj + +# Instantiate a DFRobot Wheel Encoder on digital pin D2 +sensor = sensorObj.WheelEncoder(2) + +## Exit handlers ## +# This function stops python from printing a stacktrace when you hit control-C +def SIGINTHandler(signum, frame): + raise SystemExit + +# This function lets you run code on exit +def exitHandler(): + print "Exiting" + sys.exit(0) + +# Register exit handlers +atexit.register(exitHandler) +signal.signal(signal.SIGINT, SIGINTHandler) + +# set the counter to 0 and start counting +sensor.clearCounter(); +sensor.startCounter(); + +while (1): + print "Millis:", sensor.getMillis(), "Count:", sensor.counter() + time.sleep(1) diff --git a/src/wheelencoder/CMakeLists.txt b/src/wheelencoder/CMakeLists.txt new file mode 100644 index 00000000..9528920a --- /dev/null +++ b/src/wheelencoder/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "wheelencoder") +set (libdescription "upm DFRobot wheelencoder") +set (module_src ${libname}.cxx) +set (module_h ${libname}.h) +upm_module_init() diff --git a/src/wheelencoder/javaupm_wheelencoder.i b/src/wheelencoder/javaupm_wheelencoder.i new file mode 100644 index 00000000..92aae94b --- /dev/null +++ b/src/wheelencoder/javaupm_wheelencoder.i @@ -0,0 +1,8 @@ +%module javaupm_wheelencoder +%include "../upm.i" + +%{ + #include "wheelencoder.h" +%} + +%include "wheelencoder.h" diff --git a/src/wheelencoder/jsupm_wheelencoder.i b/src/wheelencoder/jsupm_wheelencoder.i new file mode 100644 index 00000000..ded5481b --- /dev/null +++ b/src/wheelencoder/jsupm_wheelencoder.i @@ -0,0 +1,8 @@ +%module jsupm_wheelencoder +%include "../upm.i" + +%{ + #include "wheelencoder.h" +%} + +%include "wheelencoder.h" diff --git a/src/wheelencoder/pyupm_wheelencoder.i b/src/wheelencoder/pyupm_wheelencoder.i new file mode 100644 index 00000000..72705b4c --- /dev/null +++ b/src/wheelencoder/pyupm_wheelencoder.i @@ -0,0 +1,9 @@ +%module pyupm_wheelencoder +%include "../upm.i" + +%feature("autodoc", "3"); + +%include "wheelencoder.h" +%{ + #include "wheelencoder.h" +%} diff --git a/src/wheelencoder/wheelencoder.cxx b/src/wheelencoder/wheelencoder.cxx new file mode 100644 index 00000000..7964ca72 --- /dev/null +++ b/src/wheelencoder/wheelencoder.cxx @@ -0,0 +1,106 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "wheelencoder.h" + +using namespace upm; +using namespace std; + +WheelEncoder::WheelEncoder(int pin) : + m_gpio(pin) +{ + m_gpio.dir(mraa::DIR_IN); + + initClock(); + m_counter = 0; + m_isrInstalled = false; +} + +WheelEncoder::~WheelEncoder() +{ + stopCounter(); +} + +void WheelEncoder::initClock() +{ + gettimeofday(&m_startTime, NULL); +} + +uint32_t WheelEncoder::getMillis() +{ + struct timeval elapsed, now; + uint32_t elapse; + + // get current time + gettimeofday(&now, NULL); + + // compute the delta since m_startTime + if( (elapsed.tv_usec = now.tv_usec - m_startTime.tv_usec) < 0 ) + { + elapsed.tv_usec += 1000000; + elapsed.tv_sec = now.tv_sec - m_startTime.tv_sec - 1; + } + else + { + elapsed.tv_sec = now.tv_sec - m_startTime.tv_sec; + } + + elapse = (uint32_t)((elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000)); + + // never return 0 + if (elapse == 0) + elapse = 1; + + return elapse; +} + +void WheelEncoder::startCounter() +{ + initClock(); + m_counter = 0; + + // install our interrupt handler + if (!m_isrInstalled) + m_gpio.isr(mraa::EDGE_RISING, &wheelISR, this); + + m_isrInstalled = true; +} + +void WheelEncoder::stopCounter() +{ + // remove the interrupt handler + if (m_isrInstalled) + m_gpio.isrExit(); + + m_isrInstalled = false; +} + +void WheelEncoder::wheelISR(void *ctx) +{ + upm::WheelEncoder *This = (upm::WheelEncoder *)ctx; + This->m_counter++; +} + diff --git a/src/wheelencoder/wheelencoder.h b/src/wheelencoder/wheelencoder.h new file mode 100644 index 00000000..68e9f182 --- /dev/null +++ b/src/wheelencoder/wheelencoder.h @@ -0,0 +1,131 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#include +#include +#include +#include + +namespace upm { + + /** + * @brief DFRobot Wheel Encoder library + * @defgroup wheelencoder libupm-wheelencoder + * @ingroup dfrobot gpio other + */ + + /** + * @library libupm-wheelencoder + * @sensor wheelencoder + * @comname DFRobot Wheel Encoder + * @type other + * @man dfrobot + * @web http://www.dfrobot.com/index.php?route=product/product&product_id=98 + * @con gpio + + * @brief API for the DFRobot Wheel Encoder + * + * This sensor was developed for the DFRobot Wheel Encoder, though + * it could be used for any counting time-based task. + * + * When you instantiate a class of this type, the gpio pin specified + * is connected to an interrupt. Whenever a low to high transition + * occurs on the gpio pin, the internal counter is incremented by + * one. + * + * This class also includes a millisecond counter, so that you can + * correlate the number of counts to a time period for calculating + * an RPM or other value as needed. + * + * @snippet wheelencoder.cxx Interesting + */ + class WheelEncoder { + public: + + /** + * DFRobot Wheel Encoder sensor constructor + * + * @param pin Digital pin to use + */ + WheelEncoder(int pin); + + /** + * WheelEncoder destructor + */ + ~WheelEncoder(); + + /** + * Returns the number of milliseconds elapsed since initClock() + * was last called. + * + * @return Elapsed milliseconds + */ + uint32_t getMillis(); + + /** + * Resets the clock + * + */ + void initClock(); + + /** + * Resets the counter to 0. The counter should be + * stopped via stopCounter() prior to calling this function. + * + */ + void clearCounter() { m_counter = 0; }; + + /** + * Starts the counter. This function will also clear the current + * count and reset the clock. + * + */ + void startCounter(); + + /** + * Stops the counter + * + */ + void stopCounter(); + + /** + * Gets the current counter value + * + * @return counter value + */ + uint32_t counter() { return m_counter; }; + + protected: + mraa::Gpio m_gpio; + static void wheelISR(void *ctx); + + private: + volatile uint32_t m_counter; + struct timeval m_startTime; + bool m_isrInstalled; + }; +} + +