diff --git a/examples/c++/hcsr04.cxx b/examples/c++/hcsr04.cxx index 472c293f..4c1dbed9 100644 --- a/examples/c++/hcsr04.cxx +++ b/examples/c++/hcsr04.cxx @@ -29,15 +29,13 @@ #include #include -upm::HCSR04 *sonar = NULL; +int shouldRun = true; void sig_handler(int signo) { - printf("got signal\n"); if (signo == SIGINT) { - printf("exiting application\n"); - sonar->m_doWork = 1; + shouldRun = false; } } @@ -45,20 +43,20 @@ sig_handler(int signo) int main(int argc, char **argv) { - sonar = new upm::HCSR04(5, 6); + upm::HCSR04 *sonar = new upm::HCSR04(2, 4); signal(SIGINT, sig_handler); sleep(1); - for(;;){ + while(shouldRun){ std::cout << "get distance" << std::endl; - double distance = sonar->getDistance(CM); + double distance = sonar->getDistance(HCSR04_CM); std::cout << "distance " << distance << std::endl; - sleep(5); + sleep(2); } + std::cout << "Exiting... " << std::endl; delete sonar; - return 0; } //! [Interesting] diff --git a/examples/c/hcsr04.c b/examples/c/hcsr04.c new file mode 100644 index 00000000..8bc100db --- /dev/null +++ b/examples/c/hcsr04.c @@ -0,0 +1,48 @@ +/* + * Author: Abhishek Malik + * Copyright (c) 2017 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 +#include + +#include "upm_utilities.h" +#include "hcsr04.h" + +int main() { + hcsr04_context dev = hcsr04_init(2,4); + if(dev == NULL) { + printf("Unable to intialize the sensor\n"); + return 0; + } + + double distance; + while(1) { + distance = hcsr04_get_distance(dev, HCSR04_CM); + printf("Distance detected: %f\n", distance); + upm_delay(1); + } + + return 0; +} diff --git a/examples/java/HCSR04Sample.java b/examples/java/HCSR04Sample.java index ee90773a..5b02b677 100644 --- a/examples/java/HCSR04Sample.java +++ b/examples/java/HCSR04Sample.java @@ -23,17 +23,19 @@ */ //NOT TESTED!!! +import upm_hcsr04.*; + public class HCSR04Sample { // ! [Interesting] public static void main(String[] args) throws InterruptedException { - upm_hcsr04.HCSR04 sonar = new upm_hcsr04.HCSR04((short) 5, (short) 6); + HCSR04 sonar = new HCSR04((short) 2, (short) 4); Thread.sleep(1000); while (true) { System.out.println("Get distance"); - double distance = sonar.getDistance(upm_hcsr04.javaupm_hcsr04Constants.CM); + double distance = sonar.getDistance(HCSR04_U.swigToEnum(0)); System.out.println("Distance: " + distance); Thread.sleep(5000); diff --git a/examples/javascript/hcsr04.js b/examples/javascript/hcsr04.js new file mode 100644 index 00000000..cfd91576 --- /dev/null +++ b/examples/javascript/hcsr04.js @@ -0,0 +1,41 @@ +/* +* Author: Abhishek Malik +* Copyright (c) 2017 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 HCSR04 = require('jsupm_hcsr04'); + +// Instantiate a HCSR04 ultrasonic distance sensor on digital pins D2 and D4 +var myHCSR04 = new HCSR04.HCSR04(2, 4); + +// Check every second for the presence of a magnetic field (south polarity) +setInterval(function() +{ + console.log("Distance: " + myHCSR04.getDistance(0)); +}, 1000); + +// Print message when exiting +process.on('SIGINT', function() +{ + console.log("Exiting..."); + process.exit(0); +}); diff --git a/examples/python/hcsr04.py b/examples/python/hcsr04.py new file mode 100644 index 00000000..28ca8ab8 --- /dev/null +++ b/examples/python/hcsr04.py @@ -0,0 +1,52 @@ +#!/usr/bin/python +# Author: Abhishek Malik +# Copyright (c) 2017 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. + +from __future__ import print_function +import time, sys, signal, atexit +from upm import pyupm_hcsr04 as hcsr04 + +def main(): + # Instantiate a HCSR04 Distance sensor on digital pins 2 and 4 + hcsr04_sensor = hcsr04.HCSR04(2, 4); + + ## 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) + + # Read the value every second and detect the pressure + while(1): + print("Distance: {0}".format(hcsr04_sensor.getDistance(hcsr04.HCSR04_CM))) + time.sleep(1) + +if __name__ == '__main__': + main() diff --git a/src/hcsr04/CMakeLists.txt b/src/hcsr04/CMakeLists.txt index e60401f6..48c0c2ad 100644 --- a/src/hcsr04/CMakeLists.txt +++ b/src/hcsr04/CMakeLists.txt @@ -1,5 +1,8 @@ -set (libname "hcsr04") -set (libdescription "Ultrasonic Distance Measuring Sensor") -set (module_src ${libname}.cxx) -set (module_hpp ${libname}.hpp) -upm_module_init(mraa) +upm_mixed_module_init (NAME hcsr04 + DESCRIPTION "Micropik HCSR04" + C_HDR hcsr04.h + C_SRC hcsr04.c + CPP_HDR hcsr04.hpp + CPP_SRC hcsr04.cxx + CPP_WRAPS_C + REQUIRES mraa utilities-c) diff --git a/src/hcsr04/hcsr04.c b/src/hcsr04/hcsr04.c new file mode 100644 index 00000000..4ef44733 --- /dev/null +++ b/src/hcsr04/hcsr04.c @@ -0,0 +1,121 @@ +/* + * Author: Yevgeniy Kiveisha + * Author: Rafael Neri + * Author: Jun Kato + * Contributions by: Abhishek Malik + * Copyright (c) 2014-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 "upm_utilities.h" +#include "hcsr04.h" + +hcsr04_context hcsr04_init(int triggerPin, int echoPin) { + // make sure MRAA is initialized + int mraa_rv; + if ((mraa_rv = mraa_init()) != MRAA_SUCCESS) + { + printf("%s: mraa_init() failed (%d).\n", __FUNCTION__, mraa_rv); + return NULL; + } + + hcsr04_context dev = (hcsr04_context) malloc(sizeof(struct _hcsr04_context)); + + if(!dev) { + return NULL; + } + + // initialize the GPIO pins + dev->trigPin = mraa_gpio_init(triggerPin); + if(!dev->trigPin) { + printf("Unable to initialize the trigger pin\n"); + return NULL; + } + + dev->echoPin = mraa_gpio_init(echoPin); + if(!dev->echoPin) { + printf("Unable to initialize the echo pin\n"); + return NULL; + } + + // Setting direction for the GPIO pins + if(mraa_gpio_dir(dev->trigPin, MRAA_GPIO_OUT) != MRAA_SUCCESS) { + printf("Unable to set the direction of the trigger Pin\n"); + return NULL; + } + + if(mraa_gpio_dir(dev->echoPin, MRAA_GPIO_IN) != MRAA_SUCCESS) { + printf("Unable to set the direction of the echo Pin\n"); + return NULL; + } + + // Setting the trigger pin to logic level 0 + if(mraa_gpio_write(dev->trigPin, 0) != MRAA_SUCCESS) + return NULL; + + // initialize the interrupt counter + dev->interruptCounter = 0; + + return dev; +} + +void hcsr04_close(hcsr04_context dev) { + mraa_gpio_close(dev->trigPin); + mraa_gpio_close(dev->echoPin); + free(dev); +} + +double hcsr04_get_distance(hcsr04_context dev, HCSR04_U unit) { + // set value to start cycle right after trigger + long cycleLength = 0, sampleTime = 0; + struct timeval tv; + int reading = 0; + + dev->interruptCounter = 0; + gettimeofday(&tv, NULL); + + // The datasheet suggests using cycles of upto 60 ms + // being a little libteral and using 70 ms, though a limit + // should not be necessary at all + cycleLength = (1000000 * tv.tv_sec) + tv.tv_usec + 70000; + mraa_gpio_write(dev->trigPin, 1); + upm_delay_us(10); + mraa_gpio_write(dev->trigPin, 0); + + while(sampleTime < cycleLength) { + reading = mraa_gpio_read(dev->echoPin); + if(reading == 1 && dev->interruptCounter == 0) { + gettimeofday(&tv, NULL); + dev->startTime = (1000000 * tv.tv_sec) + tv.tv_usec; + dev->interruptCounter++; + } else if(reading == 0 && dev->interruptCounter == 1) { + gettimeofday(&tv, NULL); + dev->endTime = (1000000 * tv.tv_sec) + tv.tv_usec; + break; + } else { + sampleTime = (1000000 * tv.tv_sec) + tv.tv_usec; + } + } + + if(unit == HCSR04_CM) + return ((dev->endTime - dev->startTime)/2)/29.1; + else + return ((dev->endTime - dev->startTime)/2)/74.1; +} diff --git a/src/hcsr04/hcsr04.cxx b/src/hcsr04/hcsr04.cxx index 03f1acad..0f7c1cec 100644 --- a/src/hcsr04/hcsr04.cxx +++ b/src/hcsr04/hcsr04.cxx @@ -26,94 +26,26 @@ #include #include #include -#include -#include -#include - -#ifdef JAVACALLBACK -#undef JAVACALLBACK -#endif #include "hcsr04.hpp" using namespace upm; -HCSR04::HCSR04 (int triggerPin, int echoPin) { - m_name = "HCSR04"; - - m_triggerPinCtx = mraa_gpio_init (triggerPin); - if (m_triggerPinCtx == NULL) { - throw std::invalid_argument(std::string(__FUNCTION__) + - ": mraa_pwm_init() failed, invalid pin?"); - return; - } - - mraa_gpio_dir(m_triggerPinCtx, MRAA_GPIO_OUT); - mraa_gpio_write (m_triggerPinCtx, 0); - - m_echoPinCtx = mraa_gpio_init(echoPin); - if (m_echoPinCtx == NULL) { - throw std::invalid_argument(std::string(__FUNCTION__) + - ": mraa_gpio_init() failed, invalid pin?"); - return; - } - - mraa_gpio_dir(m_echoPinCtx, MRAA_GPIO_IN); - mraa_gpio_isr(m_echoPinCtx, MRAA_GPIO_EDGE_BOTH, &ackEdgeDetected, (void*)this); -} - -HCSR04::~HCSR04 () { - mraa_result_t error = MRAA_SUCCESS; - - error = mraa_gpio_close (m_triggerPinCtx); - if (error != MRAA_SUCCESS) { - mraa_result_print (error); - } - - error = mraa_gpio_close (m_echoPinCtx); - if (error != MRAA_SUCCESS) { - mraa_result_print (error); - } -} - -double -HCSR04::timing() { - mraa_gpio_write (m_triggerPinCtx, 1); - usleep(10); - mraa_gpio_write (m_triggerPinCtx, 0); - - m_doWork = 0; - m_InterruptCounter = 0; - while (!m_doWork) { - usleep (5); - } - - return m_FallingTimeStamp - m_RisingTimeStamp; -} - -void -HCSR04::ackEdgeDetected (void *ctx) { - upm::HCSR04 *This = (upm::HCSR04 *)ctx; - struct timeval timer; - gettimeofday(&timer, NULL); - - This->m_InterruptCounter++; - if (!(This->m_InterruptCounter % 2)) { - This->m_FallingTimeStamp = 1000000 * timer.tv_sec + timer.tv_usec; - This->m_doWork = 1; - } else { - This->m_RisingTimeStamp = 1000000 * timer.tv_sec + timer.tv_usec; - } -} - -double -HCSR04::getDistance(int sys) +HCSR04::HCSR04 (int triggerPin, int echoPin) : + m_hcsr04(hcsr04_init(triggerPin, echoPin)) { - double _timing = timing(); - if (sys) - { - return (_timing/2) / 29.1; - } else { - return (_timing/2) / 74.1; - } + if(!m_hcsr04) + throw std::runtime_error(std::string(__FUNCTION__) + + ": hcsr04_init failed"); +} + +HCSR04::~HCSR04 () +{ + hcsr04_close(m_hcsr04); +} + +double +HCSR04::getDistance(HCSR04_U unit) +{ + return hcsr04_get_distance(m_hcsr04, unit); } diff --git a/src/hcsr04/hcsr04.h b/src/hcsr04/hcsr04.h new file mode 100644 index 00000000..41532771 --- /dev/null +++ b/src/hcsr04/hcsr04.h @@ -0,0 +1,84 @@ +/* + * Author: Yevgeniy Kiveisha + * Author: Rafael Neri + * Author: Jun Kato + * Contributions by: Abhishek Malik + * Copyright (c) 2014-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 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + HCSR04_CM = 0, + HCSR04_INCH } HCSR04_U; + +/** + * @file hcsr04.h + * @library hcsr04 + * @brief C API for the HCSR04 Ultrasonic Ranger sensor + * + * @include hcsr04.c + */ + +typedef struct _hcsr04_context { + mraa_gpio_context trigPin; + mraa_gpio_context echoPin; + int interruptCounter; + long startTime; + long endTime; +} *hcsr04_context; + +/** + * HCSR04 Initialization function + * + * @param triggerPin GPIO pin for trigger + * @param echoPin GPIO pin used for output from sensor + * @return hcsr04_context + */ +hcsr04_context hcsr04_init(int triggerPin, int echoPin); + +/** + * HCSR04 Close function + * + * @param dev hcsr04_context pointer + */ +void hcsr04_close(hcsr04_context dev); + +/** + * Function to get the distance from the HCSR04 sensor + * + * @param unit cm/inches + * @return distance in specified unit + */ +double hcsr04_get_distance(hcsr04_context dev, HCSR04_U unit); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/hcsr04/hcsr04.hpp b/src/hcsr04/hcsr04.hpp index 7b3fbab6..7fa5e3c0 100644 --- a/src/hcsr04/hcsr04.hpp +++ b/src/hcsr04/hcsr04.hpp @@ -24,14 +24,7 @@ */ #pragma once -#include -#include -#include -#include -#include - -#define CM 1 -#define INC 0 +#include "hcsr04.h" namespace upm { /** @@ -73,37 +66,13 @@ class HCSR04 { /** * Gets the distance from the sensor * - * @param sys Selects units for measurement: 0 = inch, 1 = cm + * @param unit Selects units for measurement */ - double getDistance (int sys); - - - uint8_t m_doWork; /**< Flag to control blocking function while waiting for a falling-edge interrupt */ - - /** - * Returns the name of the sensor - */ - std::string name() - { - return m_name; - } + double getDistance (HCSR04_U unit); private: - /** - * On each interrupt, this function detects if the interrupt - * was falling-edge or rising-edge. - */ - static void ackEdgeDetected (void *ctx); - - double timing(); - mraa_gpio_context m_triggerPinCtx; - mraa_gpio_context m_echoPinCtx; - - long m_RisingTimeStamp; - long m_FallingTimeStamp; - uint8_t m_InterruptCounter; - - std::string m_name; -}; - + hcsr04_context m_hcsr04; + HCSR04(const HCSR04& src) { /* do not create copied constructor */ } + HCSR04& operator=(const HCSR04&) {return *this;} + }; } diff --git a/src/hcsr04/javaupm_hcsr04.i b/src/hcsr04/javaupm_hcsr04.i index a92d6f0c..dd7d104d 100644 --- a/src/hcsr04/javaupm_hcsr04.i +++ b/src/hcsr04/javaupm_hcsr04.i @@ -5,6 +5,7 @@ #include "hcsr04.hpp" %} +%include "hcsr04.h" %include "hcsr04.hpp" %pragma(java) jniclasscode=%{ diff --git a/src/hcsr04/jsupm_hcsr04.i b/src/hcsr04/jsupm_hcsr04.i index 0b5aa52d..5bcd753a 100644 --- a/src/hcsr04/jsupm_hcsr04.i +++ b/src/hcsr04/jsupm_hcsr04.i @@ -5,4 +5,5 @@ #include "hcsr04.hpp" %} +%include "hcsr04.h" %include "hcsr04.hpp" diff --git a/src/hcsr04/pyupm_hcsr04.i b/src/hcsr04/pyupm_hcsr04.i index 87c4e9d0..db788c08 100644 --- a/src/hcsr04/pyupm_hcsr04.i +++ b/src/hcsr04/pyupm_hcsr04.i @@ -5,6 +5,7 @@ %feature("autodoc", "3"); +%include "hcsr04.h" %include "hcsr04.hpp" %{ #include "hcsr04.hpp"