From 517f6c1e88c699da3519e8e1a49f660cabffd0f7 Mon Sep 17 00:00:00 2001 From: Jon Trulson Date: Wed, 20 May 2015 12:07:08 -0600 Subject: [PATCH] ad8232: Initial Implementation This driver implements support for the Sparkfun Single Lead Heart Rate Monitor, based on the AD8232 chip. It simply outputs ADC data that needs to be sent somewhere for plotting. The Sparkfun page has some suggestions. Alternatively, if you have an oscilliscope that supports a 'Roll' mode, you can get an EKG-like display by measuring the OUT pin. https://www.sparkfun.com/products/12650 Signed-off-by: Jon Trulson Signed-off-by: Mihai Tudor Panu --- examples/c++/CMakeLists.txt | 3 + examples/c++/ad8232.cxx | 65 +++++++++++++++++++++ examples/javascript/ad8232.js | 51 +++++++++++++++++ examples/python/ad8232.py | 54 ++++++++++++++++++ src/ad8232/CMakeLists.txt | 5 ++ src/ad8232/ad8232.cxx | 52 +++++++++++++++++ src/ad8232/ad8232.h | 104 ++++++++++++++++++++++++++++++++++ src/ad8232/jsupm_ad8232.i | 8 +++ src/ad8232/pyupm_ad8232.i | 9 +++ 9 files changed, 351 insertions(+) create mode 100644 examples/c++/ad8232.cxx create mode 100644 examples/javascript/ad8232.js create mode 100644 examples/python/ad8232.py create mode 100644 src/ad8232/CMakeLists.txt create mode 100644 src/ad8232/ad8232.cxx create mode 100644 src/ad8232/ad8232.h create mode 100644 src/ad8232/jsupm_ad8232.i create mode 100644 src/ad8232/pyupm_ad8232.i diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index 1072f149..6f0dae26 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -120,6 +120,7 @@ add_executable (maxsonarez-example maxsonarez.cxx) add_executable (hm11-example hm11.cxx) add_executable (ht9170-example ht9170.cxx) add_executable (h3lis331dl-example h3lis331dl.cxx) +add_executable (ad8232-example ad8232.cxx) include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l) include_directories (${PROJECT_SOURCE_DIR}/src/grove) @@ -218,6 +219,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/maxsonarez) include_directories (${PROJECT_SOURCE_DIR}/src/hm11) include_directories (${PROJECT_SOURCE_DIR}/src/ht9170) include_directories (${PROJECT_SOURCE_DIR}/src/h3lis331dl) +include_directories (${PROJECT_SOURCE_DIR}/src/ad8232) target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT}) @@ -339,3 +341,4 @@ target_link_libraries (maxsonarez-example maxsonarez ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (hm11-example hm11 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (ht9170-example ht9170 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (h3lis331dl-example h3lis331dl ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (ad8232-example ad8232 ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/c++/ad8232.cxx b/examples/c++/ad8232.cxx new file mode 100644 index 00000000..5d035275 --- /dev/null +++ b/examples/c++/ad8232.cxx @@ -0,0 +1,65 @@ +/* + * 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 "ad8232.h" + +using namespace std; + +bool shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + +int main() +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + // Instantiate a Ad8232 sensor on digital pins 10 (LO+), 11 (LO-) + // and an analog pin, 0 (OUTPUT) + upm::AD8232 *ad8232 = new upm::AD8232(10, 11, 0); + + // Output the raw numbers from the ADC, for plotting elsewhere. + // A return of 0 indicates a Lead Off (LO) condition. + // In theory, this data could be fed to software like Processing + // (https://www.processing.org/) to plot the data just like an + // EKG you would see in a hospital. + while (shouldRun) + { + cout << ad8232->value() << endl; + usleep(1000); + } +//! [Interesting] + + cout << "Exiting" << endl; + + delete ad8232; + return 0; +} diff --git a/examples/javascript/ad8232.js b/examples/javascript/ad8232.js new file mode 100644 index 00000000..56913fa7 --- /dev/null +++ b/examples/javascript/ad8232.js @@ -0,0 +1,51 @@ +/*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 ad8232Sensor_lib = require('jsupm_ad8232'); + +// Instantiate a AD8232 sensor on digital pins 10 (LO+), 11 (LO-) +// and an analog pin, 0 (OUTPUT) +var myAd8232Sensor_obj = new ad8232Sensor_lib.AD8232(10, 11, 0); + +// Output the raw numbers from the ADC, for plotting elsewhere. +// A return of 0 indicates a Lead Off (LO) condition. +// In theory, this data could be fed to software like Processing +// (https://www.processing.org/) to plot the data just like an +// EKG you would see in a hospital. +var myInterval = setInterval(function() +{ + console.log(myAd8232Sensor_obj.value()); +}, 1); + +// Print message when exiting +process.on('SIGINT', function() +{ + clearInterval(myInterval); + myAd8232Sensor_obj = null; + ad8232Sensor_lib.cleanUp(); + ad8232Sensor_lib = null; + console.log("Exiting"); + process.exit(0); +}); diff --git a/examples/python/ad8232.py b/examples/python/ad8232.py new file mode 100644 index 00000000..97284ada --- /dev/null +++ b/examples/python/ad8232.py @@ -0,0 +1,54 @@ +#!/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_ad8232 as upmAD8232 + +# Instantiate a AD8232 sensor on digital pins 10 (LO+), 11 (LO-) +# and an analog pin, 0 (OUTPUT) +myAD8232 = upmAD8232.AD8232(10, 11, 0) + + +## 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, including functions from myAD8232 +def exitHandler(): + print "Exiting" + sys.exit(0) + +# Register exit handlers +atexit.register(exitHandler) +signal.signal(signal.SIGINT, SIGINTHandler) + + +# Output the raw numbers from the ADC, for plotting elsewhere. +# A return of 0 indicates a Lead Off (LO) condition. +# In theory, this data could be fed to software like Processing +# (https://www.processing.org/) to plot the data just like an +# EKG you would see in a hospital. +while(1): + print myAD8232.value() + time.sleep(.001) diff --git a/src/ad8232/CMakeLists.txt b/src/ad8232/CMakeLists.txt new file mode 100644 index 00000000..0a572409 --- /dev/null +++ b/src/ad8232/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "ad8232") +set (libdescription "upm ad8232 heart rate monitor") +set (module_src ${libname}.cxx) +set (module_h ${libname}.h) +upm_module_init() diff --git a/src/ad8232/ad8232.cxx b/src/ad8232/ad8232.cxx new file mode 100644 index 00000000..35612ae6 --- /dev/null +++ b/src/ad8232/ad8232.cxx @@ -0,0 +1,52 @@ +/* + * 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 "ad8232.h" + +using namespace upm; +using namespace std; + +AD8232::AD8232(int loPlus, int loMinus, int output, float aref) : + m_gpioLOPlus(loPlus), m_gpioLOMinus(loMinus), m_aioOUT(output) +{ + m_gpioLOPlus.dir(mraa::DIR_IN); + m_gpioLOMinus.dir(mraa::DIR_IN); + + m_aref = aref; + m_ares = (1 << m_aioOUT.getBit()); +} + +AD8232::~AD8232() +{ +} + +int AD8232::value() +{ + if (m_gpioLOPlus.read() || m_gpioLOMinus.read()) + return 0; + else + return m_aioOUT.read(); +} diff --git a/src/ad8232/ad8232.h b/src/ad8232/ad8232.h new file mode 100644 index 00000000..beaac59d --- /dev/null +++ b/src/ad8232/ad8232.h @@ -0,0 +1,104 @@ +/* + * 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 + +#define AD8232_DEFAULT_AREF 3.3 + +namespace upm { + + /** + * @brief UPM support for the AD8232 Heart Rate Monitor + * @defgroup ad8232 libupm-ad8232 + * @ingroup sparkfun gpio medical + */ + + /** + * @library ad8232 + * @sensor ad8232 + * @comname AD8232 Heart Rate Monitor + * @type medical + * @man sparkfun + * @web https://www.sparkfun.com/products/12650 + * @con gpio aio + * + * @brief UPM module for the AD8232 Heart Rate Monitor + * + * Note, this sensor must be driven at 3.3v only. + * + * This module will simply spit out the ADC values reported by the + * sensor, with the intent being to send that data somewhere (via + * serial or network port) to another piece of software running on a + * computer that will plot the data for you, like an EKG. + * + * Processing (https://www.processing.org/), is a piece of software + * that should work, using information from the Sparkfun website. + * + * This example just dumps the raw data. + * @snippet ad8232.cxx Interesting + */ + + + class AD8232 { + public: + + /** + * AD8232 constructor + * + * @param loPlus digital pin to use for LO+ + * @param loMinus digital pin to use LO- + * @param output analog pin to use for reading the data + */ + AD8232(int loPlus, int loMinus, int output, float aref=AD8232_DEFAULT_AREF); + + /** + * AD8232 Destructor + */ + ~AD8232(); + + /** + * return the current ADC value for the device output pin. If an + * LO (Leads Off) event is detected, 0 will be returned. + * + * @return ADC value + */ + int value(); + + private: + mraa::Aio m_aioOUT; + mraa::Gpio m_gpioLOPlus; + mraa::Gpio m_gpioLOMinus; + + float m_aref; + int m_ares; + + }; +} + + diff --git a/src/ad8232/jsupm_ad8232.i b/src/ad8232/jsupm_ad8232.i new file mode 100644 index 00000000..e2fe8d8e --- /dev/null +++ b/src/ad8232/jsupm_ad8232.i @@ -0,0 +1,8 @@ +%module jsupm_ad8232 +%include "../upm.i" + +%{ + #include "ad8232.h" +%} + +%include "ad8232.h" diff --git a/src/ad8232/pyupm_ad8232.i b/src/ad8232/pyupm_ad8232.i new file mode 100644 index 00000000..e5688431 --- /dev/null +++ b/src/ad8232/pyupm_ad8232.i @@ -0,0 +1,9 @@ +%module pyupm_ad8232 +%include "../upm.i" + +%feature("autodoc", "3"); + +%include "ad8232.h" +%{ + #include "ad8232.h" +%}