diff --git a/docs/images/ultrasonic.jpg b/docs/images/ultrasonic.jpg new file mode 100644 index 00000000..2e6e39d3 Binary files /dev/null and b/docs/images/ultrasonic.jpg differ diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index 85b40b85..76774c33 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -245,6 +245,7 @@ add_example (bma220) add_example (dfrph) add_example (mcp9808) add_example (groveultrasonic) +add_example (ultrasonic) add_example (sx1276-lora) add_example (sx1276-fsk) add_example (ili9341) diff --git a/examples/c++/ultrasonic.cxx b/examples/c++/ultrasonic.cxx new file mode 100644 index 00000000..7bdecd65 --- /dev/null +++ b/examples/c++/ultrasonic.cxx @@ -0,0 +1,60 @@ +/* + * Author: Jun Kato + * Copyright (c) 2015 Jun Kato. + * + * Thanks to Seeed Studio for a working arduino sketch + * + * 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 "ultrasonic.hpp" +#include +#include +#include + +upm::UltraSonic *sonar = NULL; +bool running = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + running = false; +} + +int main(int argc, char **argv) +{ + signal(SIGINT, sig_handler); + //! [Interesting] + // upm::UltraSonic *sonar = NULL; + sonar = new upm::UltraSonic(2); + while(running) + { + int width = sonar->getDistance(); + printf("Echo width = %d\n", width); + printf("Distance inches = %f.2\n\n", width/148.0); + sleep(3); + } + //! [Interesting] + printf("exiting application\n"); + delete sonar; + return 0; +} diff --git a/examples/javascript/ultrasonic.js b/examples/javascript/ultrasonic.js new file mode 100644 index 00000000..49b63af3 --- /dev/null +++ b/examples/javascript/ultrasonic.js @@ -0,0 +1,45 @@ +/* + * Author: Jun Kato + * Copyright (c) 2015 Jun Kato. + * + * Thanks to Seeed Studio for a working arduino sketch + * + * 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 ultrasonic = require("jsupm_ultrasonic"); +var sensor = new ultrasonic.UltraSonic(2); + +var myInterval = setInterval(function() +{ + var travelTime = sensor.getDistance(); + if (travelTime > 0) { + var distance = (travelTime / 29 / 2).toFixed(3); + console.log("distance: " + distance + " [cm]"); + } +}, 200); + +// When exiting: clear interval and print message +process.on('SIGINT', function() +{ + clearInterval(myInterval); + console.log("Exiting..."); + process.exit(0); +}); diff --git a/src/ultrasonic/CMakeLists.txt b/src/ultrasonic/CMakeLists.txt new file mode 100644 index 00000000..2614a5f9 --- /dev/null +++ b/src/ultrasonic/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "ultrasonic") +set (libdescription "upm grove ultrasonic proximity sensor") +set (module_src ${libname}.cxx) +set (module_hpp ${libname}.hpp) +upm_module_init() diff --git a/src/ultrasonic/javaupm_ultrasonic.i b/src/ultrasonic/javaupm_ultrasonic.i new file mode 100644 index 00000000..bece5af0 --- /dev/null +++ b/src/ultrasonic/javaupm_ultrasonic.i @@ -0,0 +1,21 @@ +%module javaupm_ultrasonic +%include "../upm.i" + +%ignore signalISR; + +%{ + #include "ultrasonic.hpp" +%} + +%include "ultrasonic.hpp" + +%pragma(java) jniclasscode=%{ + static { + try { + System.loadLibrary("javaupm_ultrasonic"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. \n" + e); + System.exit(1); + } + } +%} diff --git a/src/ultrasonic/jsupm_ultrasonic.i b/src/ultrasonic/jsupm_ultrasonic.i new file mode 100644 index 00000000..f2a87a5d --- /dev/null +++ b/src/ultrasonic/jsupm_ultrasonic.i @@ -0,0 +1,8 @@ +%module jsupm_ultrasonic +%include "../upm.i" + +%{ + #include "ultrasonic.hpp" +%} + +%include "ultrasonic.hpp" diff --git a/src/ultrasonic/pyupm_ultrasonic.i b/src/ultrasonic/pyupm_ultrasonic.i new file mode 100644 index 00000000..613fb380 --- /dev/null +++ b/src/ultrasonic/pyupm_ultrasonic.i @@ -0,0 +1,11 @@ +// Include doxygen-generated documentation +%include "pyupm_doxy2swig.i" +%module pyupm_ultrasonic +%include "../upm.i" + +%feature("autodoc", "3"); + +%include "ultrasonic.hpp" +%{ + #include "ultrasonic.hpp" +%} diff --git a/src/ultrasonic/ultrasonic.cxx b/src/ultrasonic/ultrasonic.cxx new file mode 100644 index 00000000..9af925b0 --- /dev/null +++ b/src/ultrasonic/ultrasonic.cxx @@ -0,0 +1,104 @@ +/* + * Author: Jun Kato + * Copyright (c) 2015 Jun Kato. + * + * Thanks to Seeed Studio for a working arduino sketch + * + * 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 "ultrasonic.hpp" + +using namespace upm; + +UltraSonic::UltraSonic (uint8_t pin) { + mraa_result_t error = MRAA_SUCCESS; + m_name = "UltraSonic"; + + mraa_init(); + + // setup pin + m_pinCtx = mraa_gpio_init(pin); + if (m_pinCtx == NULL) { + fprintf (stderr, "Are you sure that pin%d you requested is valid on your platform?", pin); + exit (1); + } + mraa_gpio_use_mmaped(m_pinCtx, 1); + mraa_gpio_isr (m_pinCtx, MRAA_GPIO_EDGE_BOTH, + &signalISR, this); +} + +UltraSonic::~UltraSonic () { + + // close pin + mraa_gpio_isr_exit(m_pinCtx); + mraa_gpio_close (m_pinCtx); +} + +int +UltraSonic::getDistance () { + + // output trigger signal + mraa_gpio_dir(m_pinCtx, MRAA_GPIO_OUT); + mraa_gpio_write(m_pinCtx, LOW); + usleep(2); + mraa_gpio_write(m_pinCtx, HIGH); + usleep(5); + mraa_gpio_write(m_pinCtx, LOW); + + // wait for the pulse, + m_doWork = true; + m_InterruptCounter = 0; + mraa_gpio_dir(m_pinCtx, MRAA_GPIO_IN); + + // though do not wait over 25 [ms]. + int timer = 0; + while (m_doWork && timer++ < 5) { + // in 25 [ms], sound travels 25000 / 29 / 2 = 431 [cm], + // which is more than 400 [cm], the max distance measurable with this sensor. + usleep(5 * 1000); // 5 [ms] + } + + // calc diff + long diff = m_FallingTimeStamp.tv_usec - m_RisingTimeStamp.tv_usec; + diff += (m_FallingTimeStamp.tv_sec - m_RisingTimeStamp.tv_sec) * 1000000; + return timer >= 5 ? 0 : diff; +} + +void +UltraSonic::signalISR(void *ctx) { + upm::UltraSonic *This = (upm::UltraSonic *)ctx; + This->ackEdgeDetected(); +} + +void +UltraSonic::ackEdgeDetected () { + if (++m_InterruptCounter % 2 == 0) { + gettimeofday(&m_FallingTimeStamp, NULL); + m_doWork = false; + } else { + gettimeofday(&m_RisingTimeStamp, NULL); + } +} diff --git a/src/ultrasonic/ultrasonic.hpp b/src/ultrasonic/ultrasonic.hpp new file mode 100644 index 00000000..bd703313 --- /dev/null +++ b/src/ultrasonic/ultrasonic.hpp @@ -0,0 +1,121 @@ +/* + * Author: Jun Kato + * Copyright (c) 2015 Jun Kato. + * + * Thanks to Seeed Studio for a working arduino sketch + * + * 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 + +#define HIGH 1 +#define LOW 0 + +namespace upm { + +/** + * @brief Grove ultrasonic sensor library + * @defgroup ultrasonic libupm-ultrasonic + * @ingroup seeed gpio sound + */ + +/** + * @library ultrasonic + * @sensor ultrasonic + * @comname Grove Ultrasonic Ranger + * @type sound + * @man seeed + * @con gpio + * + * @brief API for Grove Ultrasonic Ranger + * + * This Grove Ultrasonic sensor is a non-contact distance measurement module + * which is compatible with the Grove system. It is designed for easy modular + * project usage with industrial performance. Detection ranges from 3 cm (1.2") + * to 4 m (13'1.5") and works best when the object is within a 30 degree angle + * relative to the sensor. + * + * @image html ultrasonic.jpg + * @snippet ultrasonic.cxx Interesting + */ +class UltraSonic { + public: + /** + * Instantiates a UltraSonic object + * + * @param pin pin for triggering the sensor for distance and for receiving pulse response + */ + UltraSonic (uint8_t pin); + + /** + * UltraSonic object destructor. + */ + ~UltraSonic (); + + /** + * Returns the echo's pulse width from the sensor in microseconds. + * Divide by 58 to convert distance to centimetres. + * Divide by 148 to convert distance to inches. + */ + int getDistance (); + + /** + * Return name of the component + */ + std::string name() + { + return m_name; + } + + /** + * Returns true while the sensor is busy waiting for the echo pulse + */ + bool working() + { + return m_doWork; + } + + private: + bool m_doWork; /* Flag to control blocking function while waiting for falling edge interrupt */ + mraa_gpio_context m_pinCtx; + uint8_t m_InterruptCounter; + struct timeval m_RisingTimeStamp; + struct timeval m_FallingTimeStamp; + std::string m_name; + + /** + * ISR for the pulse signal + */ + static void signalISR(void *ctx); + + /** + * On each interrupt this function will detect if the interrupt + * was falling edge or rising. + * Should be called from the interrupt handler. + */ + void ackEdgeDetected (); +}; + +}