From dcb4e83251c642695f807376589bae6501a7ccfc Mon Sep 17 00:00:00 2001 From: Jon Trulson Date: Wed, 31 Aug 2016 18:22:24 -0600 Subject: [PATCH] dfrorp: Initial implementation This module implements support for the DFRobot Analog ORP (Oxidation/Reduction Potential) Meter. It requires 5.0 volts, but the more accurate the voltage specified (to the constructor), the more accurate the meter (paraphrased from the wiki). Signed-off-by: Jon Trulson --- examples/c++/CMakeLists.txt | 1 + examples/c++/dfrorp.cxx | 87 ++++++++++++++ examples/c/CMakeLists.txt | 1 + examples/c/dfrorp.c | 86 ++++++++++++++ examples/java/CMakeLists.txt | 1 + examples/java/DFRORP_Example.java | 68 +++++++++++ examples/javascript/dfrorp.js | 70 ++++++++++++ examples/python/dfrorp.py | 68 +++++++++++ include/fti/upm_orp.h | 48 ++++++++ include/upm_fti.h | 4 +- src/dfrorp/CMakeLists.txt | 9 ++ src/dfrorp/dfrorp.c | 165 +++++++++++++++++++++++++++ src/dfrorp/dfrorp.cxx | 86 ++++++++++++++ src/dfrorp/dfrorp.h | 181 ++++++++++++++++++++++++++++++ src/dfrorp/dfrorp.hpp | 162 ++++++++++++++++++++++++++ src/dfrorp/dfrorp_fti.c | 99 ++++++++++++++++ src/dfrorp/javaupm_dfrorp.i | 21 ++++ src/dfrorp/jsupm_dfrorp.i | 13 +++ src/dfrorp/pyupm_dfrorp.i | 17 +++ 19 files changed, 1186 insertions(+), 1 deletion(-) create mode 100644 examples/c++/dfrorp.cxx create mode 100644 examples/c/dfrorp.c create mode 100644 examples/java/DFRORP_Example.java create mode 100644 examples/javascript/dfrorp.js create mode 100644 examples/python/dfrorp.py create mode 100644 include/fti/upm_orp.h create mode 100644 src/dfrorp/CMakeLists.txt create mode 100644 src/dfrorp/dfrorp.c create mode 100644 src/dfrorp/dfrorp.cxx create mode 100644 src/dfrorp/dfrorp.h create mode 100644 src/dfrorp/dfrorp.hpp create mode 100644 src/dfrorp/dfrorp_fti.c create mode 100644 src/dfrorp/javaupm_dfrorp.i create mode 100644 src/dfrorp/jsupm_dfrorp.i create mode 100644 src/dfrorp/pyupm_dfrorp.i diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index bf7387eb..eee1b27c 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -277,6 +277,7 @@ add_example (nmea_gps) add_example (mma7361) add_example (bh1750) add_example (hka5) +add_example (dfrorp) # These are special cases where you specify example binary, source file and module(s) include_directories (${PROJECT_SOURCE_DIR}/src) diff --git a/examples/c++/dfrorp.cxx b/examples/c++/dfrorp.cxx new file mode 100644 index 00000000..f24dc296 --- /dev/null +++ b/examples/c++/dfrorp.cxx @@ -0,0 +1,87 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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 "dfrorp.hpp" + +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 DFRobot ORP sensor on analog pin A0 with an analog + // reference voltage of 5.0. + upm::DFRORP *sensor = new upm::DFRORP(0, 5.0); + + // To calibrate: + // + // Disconnect the sensor probe (but leave the sensor interface board + // connected). Then run one of the examples while holding down the + // 'calibrate' button on the device. Read the ORP value reported + // (it should be fairly small). + // + // This value is what you should supply to setCalibrationOffset(). + // Then reconnect the probe to the interface board and you should be + // ready to go. + // + // DO NOT press the calibrate button on the interface board while + // the probe is attached or you can permanently damage the probe. + sensor->setCalibrationOffset(0.97); + + // Every second, update and print values + while (shouldRun) + { + sensor->update(); + + cout << "ORP: " + << sensor->getORP() + << " mV" + << endl; + + cout << endl; + + sleep(1); + } + +//! [Interesting] + + cout << "Exiting" << endl; + + delete sensor; + return 0; +} diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index d4c89c0a..035be1b3 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -93,6 +93,7 @@ add_example (bh1750) add_example (urm37) add_example (urm37-uart) add_example (hka5) +add_example (dfrorp) # Custom examples add_custom_example (nmea_gps_i2c-example-c nmea_gps_i2c.c nmea_gps) diff --git a/examples/c/dfrorp.c b/examples/c/dfrorp.c new file mode 100644 index 00000000..6a3e4734 --- /dev/null +++ b/examples/c/dfrorp.c @@ -0,0 +1,86 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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 "dfrorp.h" + +bool shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + +int main() +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + + // Instantiate a DFRobot ORP sensor on analog pin A0 with an analog + // reference voltage of 5.0. + dfrorp_context sensor = dfrorp_init(0, 5.0); + + if (!sensor) + { + printf("dfrorp_init() failed.\n"); + return(1); + } + + // To calibrate: + // + // Disconnect the sensor probe (but leave the sensor interface board + // connected). Then run one of the examples while holding down the + // 'calibrate' button on the device. Read the ORP value reported + // (it should be fairly small). + // + // This value is what you should supply to + // dfrorp_set_orp_cal_offset(). Then reconnect the probe to the + // interface board and you should be ready to go. + // + // DO NOT press the calibrate button on the interface board while + // the probe is attached or you can permanently damage the probe. + dfrorp_set_calibration_offset(sensor, 0.97); + + // Every second, update and print values + while (shouldRun) + { + dfrorp_update(sensor); + + printf("ORP = %f mV\n", dfrorp_get_orp(sensor)); + + sleep(1); + } + +//! [Interesting] + + printf("Exiting...\n"); + + dfrorp_close(sensor); + + return 0; +} diff --git a/examples/java/CMakeLists.txt b/examples/java/CMakeLists.txt index 5ed9e8cb..a5c6afed 100644 --- a/examples/java/CMakeLists.txt +++ b/examples/java/CMakeLists.txt @@ -134,6 +134,7 @@ add_example(NMEAGPS_Example nmea_gps) add_example(MMA7361_Example mma7361) add_example(BH1750_Example bh1750) add_example(HKA5_Example hka5) +add_example(DFRORP_Example dfrorp) add_example_with_path(Jhd1313m1_lcdSample lcd i2clcd) add_example_with_path(Jhd1313m1Sample lcd i2clcd) diff --git a/examples/java/DFRORP_Example.java b/examples/java/DFRORP_Example.java new file mode 100644 index 00000000..1a8c388c --- /dev/null +++ b/examples/java/DFRORP_Example.java @@ -0,0 +1,68 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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 upm_dfrorp.DFRORP; + +public class DFRORP_Example +{ + public static void main(String[] args) throws InterruptedException + { +// ! [Interesting] + + // Instantiate a DFRobot ORP sensor on analog pin A0 with an + // analog reference voltage of 5.0. + DFRORP sensor = new DFRORP(0, 5.0f); + + // To calibrate: + // + // Disconnect the sensor probe (but leave the sensor interface + // board connected). Then run one of the examples while + // holding down the 'calibrate' button on the device. Read + // the ORP value reported (it should be fairly small). + // + // This value is what you should supply to + // setCalibrationOffset(). Then reconnect the probe to the + // interface board and you should be ready to go. + // + // DO NOT press the calibrate button on the interface board + // while the probe is attached or you can permanently damage + // the probe. + sensor.setCalibrationOffset(0.97f); + + // Every second, update and print values + while (true) + { + sensor.update(); + + System.out.println("ORP: " + + sensor.getORP() + + " mV"); + + System.out.println(); + Thread.sleep(1000); + } + +// ! [Interesting] + } +} diff --git a/examples/javascript/dfrorp.js b/examples/javascript/dfrorp.js new file mode 100644 index 00000000..d24dacfc --- /dev/null +++ b/examples/javascript/dfrorp.js @@ -0,0 +1,70 @@ +/*jslint node:true, vars:true, bitwise:true, unparam:true */ +/*jshint unused:true */ + +/* + * Author: Jon Trulson + * Copyright (c) 2016 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_dfrorp'); + +// Instantiate a DFRobot ORP sensor on analog pin A0 with an analog +// reference voltage of 5.0. +var sensor = new sensorObj.DFRORP(0, 5.0); + +// To calibrate: +// +// Disconnect the sensor probe (but leave the sensor interface board +// connected). Then run one of the examples while holding down the +// 'calibrate' button on the device. Read the ORP value reported +// (it should be fairly small). +// +// This value is what you should supply to setCalibrationOffset(). +// Then reconnect the probe to the interface board and you should be +// ready to go. +// +// DO NOT press the calibrate button on the interface board while +// the probe is attached or you can permanently damage the probe. +sensor.setCalibrationOffset(0.97); + +// Every second, update and print values +setInterval(function() +{ + sensor.update(); + + console.log("ORP: " + + sensor.getORP() + + " mV"); + + console.log(); + +}, 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/dfrorp.py b/examples/python/dfrorp.py new file mode 100644 index 00000000..89d0a12e --- /dev/null +++ b/examples/python/dfrorp.py @@ -0,0 +1,68 @@ +#!/usr/bin/python +# Author: Jon Trulson +# Copyright (c) 2016 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_dfrorp as sensorObj + +# Instantiate a DFRobot ORP sensor on analog pin A0 with an analog +# reference voltage of 5.0. +sensor = sensorObj.DFRORP(0, 5.0) + +# To calibrate: +# +# Disconnect the sensor probe (but leave the sensor interface board +# connected). Then run one of the examples while holding down the +# 'calibrate' button on the device. Read the ORP value reported +# (it should be fairly small). +# +# This value is what you should supply to setCalibrationOffset(). +# Then reconnect the probe to the interface board and you should be +# ready to go. +# +# DO NOT press the calibrate button on the interface board while +# the probe is attached or you can permanently damage the probe. +sensor.setCalibrationOffset(0.97); + +## 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) + +# Every second, update and print values +while (True): + sensor.update() + + print "ORP:", sensor.getORP(), "mV" + + print + + time.sleep(1) diff --git a/include/fti/upm_orp.h b/include/fti/upm_orp.h new file mode 100644 index 00000000..1e03f78b --- /dev/null +++ b/include/fti/upm_orp.h @@ -0,0 +1,48 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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. + */ +#ifndef UPM_ORP_H_ +#define UPM_ORP_H_ + +#include "upm_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ORP (Oxidation/Reduction Potential) function table */ +typedef struct _upm_orp_ft +{ + /* Set sensor offset */ + upm_result_t (*upm_orp_set_offset) (const void* dev, float offset); + /* Set sensor scale */ + upm_result_t (*upm_orp_set_scale) (const void* dev, float scale); + /* Read sensor value */ + upm_result_t (*upm_orp_get_value) (const void* dev, float *value); +} upm_orp_ft; + +#ifdef __cplusplus +} +#endif + +#endif /* UPM_ORP_H_ */ diff --git a/include/upm_fti.h b/include/upm_fti.h index 41abba6f..25a74891 100644 --- a/include/upm_fti.h +++ b/include/upm_fti.h @@ -70,7 +70,8 @@ typedef enum { UPM_VIDEO, UPM_VOLTAGE, UPM_WIRELESS, - UPM_STREAM + UPM_STREAM, + UPM_ORP } upm_sensor_t; /* Supported IO protocols via MRAA */ @@ -114,6 +115,7 @@ typedef struct _upm_sensor_ft* (*func_get_upm_sensor_ft)(upm_sensor_t sensor_typ #include #include #include +#include #ifdef __cplusplus } diff --git a/src/dfrorp/CMakeLists.txt b/src/dfrorp/CMakeLists.txt new file mode 100644 index 00000000..c3e8e556 --- /dev/null +++ b/src/dfrorp/CMakeLists.txt @@ -0,0 +1,9 @@ +upm_mixed_module_init (NAME dfrorp + DESCRIPTION "upm dfrobot analog ORP sensor" + C_HDR dfrorp.h + C_SRC dfrorp.c + CPP_HDR dfrorp.hpp + CPP_SRC dfrorp.cxx + FTI_SRC dfrorp_fti.c + CPP_WRAPS_C + REQUIRES upmc-utilities mraa) diff --git a/src/dfrorp/dfrorp.c b/src/dfrorp/dfrorp.c new file mode 100644 index 00000000..4cb6640d --- /dev/null +++ b/src/dfrorp/dfrorp.c @@ -0,0 +1,165 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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 "dfrorp.h" + +#include "upm_utilities.h" + +#define DFRORP_NUM_SAMPLES 10 +// Resistor R2 value in schematic, in KOhms +#define DFRORP_R2 30.0 +// Resistor R3 value in schematic, in KOhms +#define DFRORP_R3 75.0 + +static float average(const dfrorp_context dev, int samples) +{ + int sum = 0; + + if (samples < 1) + samples = 1; + + int i; + for (i=0; i< samples; i++) + { + int j = mraa_aio_read(dev->aio); + if (j < 0) + { + printf("%s: mraa_aio_read() failed.\n", __FUNCTION__); + return -1.0; + } + sum += j; + upm_delay_ms(20); + } + + return (float)(sum / samples); +} + +dfrorp_context dfrorp_init(unsigned int apin, float a_ref) +{ + dfrorp_context dev = + (dfrorp_context)malloc(sizeof(struct _dfrorp_context)); + + if (!dev) + return NULL; + + // zero out context + memset((void *)dev, 0, sizeof(struct _dfrorp_context)); + + dev->aio = NULL; + + dev->a_ref = a_ref; + + dev->offset = 0.0; + dev->scale = 1.0; + + // initialize the MRAA context + + if (!(dev->aio = mraa_aio_init(apin))) + { + printf("%s: mraa_aio_init() failed.\n", __FUNCTION__); + dfrorp_close(dev); + return NULL; + } + + // set our analog resolution + dev->a_res = (float)(1 << mraa_aio_get_bit(dev->aio)) - 1; + + return dev; +} + +void dfrorp_close(dfrorp_context dev) +{ + assert(dev != NULL); + + if (dev->aio) + mraa_aio_close(dev->aio); + + free(dev); +} + +void dfrorp_set_offset(const dfrorp_context dev, float offset) +{ + assert(dev != NULL); + + dev->offset = offset; +} + +void dfrorp_set_scale(const dfrorp_context dev, float scale) +{ + assert(dev != NULL); + + dev->scale = scale; +} + +upm_result_t dfrorp_update(const dfrorp_context dev) +{ + assert(dev != NULL); + + float sample = average(dev, DFRORP_NUM_SAMPLES); + if (sample == -1.0) + return UPM_ERROR_OPERATION_FAILED; + + dev->normalized = sample / dev->a_res; + dev->volts = dev->normalized * dev->a_ref; + + float volts = dev->volts + dev->orp_cal_offset; + + // From the DFRobot site + dev->orp = ( (DFRORP_R2 * dev->a_ref * 1000.0) - + (DFRORP_R3 * sample * dev->a_ref * 1000.0 / dev->a_res) ) / + DFRORP_R3 - dev->orp_cal_offset; + + return UPM_SUCCESS; +} + +float dfrorp_get_orp(const dfrorp_context dev) +{ + assert(dev != NULL); + + return dev->orp * dev->scale + (dev->offset * dev->scale); +} + +float dfrorp_get_volts(const dfrorp_context dev) +{ + assert(dev != NULL); + + return dev->volts; +} + +float dfrorp_get_normalized(const dfrorp_context dev) +{ + assert(dev != NULL); + + return dev->normalized; +} + +void dfrorp_set_calibration_offset(const dfrorp_context dev, float offset) +{ + assert(dev != NULL); + + dev->orp_cal_offset = offset; +} diff --git a/src/dfrorp/dfrorp.cxx b/src/dfrorp/dfrorp.cxx new file mode 100644 index 00000000..c41b76a0 --- /dev/null +++ b/src/dfrorp/dfrorp.cxx @@ -0,0 +1,86 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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 "dfrorp.hpp" + +using namespace upm; +using namespace std; + +DFRORP::DFRORP(int apin, float a_ref) : + m_dfrorp(dfrorp_init(apin, a_ref)) +{ + if (!m_dfrorp) + throw std::runtime_error(string(__FUNCTION__) + + ": dfrorp_init() failed"); +} + +DFRORP::~DFRORP() +{ + dfrorp_close(m_dfrorp); +} + +void DFRORP::update() +{ + upm_result_t rv; + + if ((rv = dfrorp_update(m_dfrorp))) + { + throw std::runtime_error(string(__FUNCTION__) + + ": dfrorp_update() failed with UPM error " + + std::to_string(int(rv)) ); + } +} + +void DFRORP::setOffset(float offset) +{ + dfrorp_set_offset(m_dfrorp, offset); +} + +void DFRORP::setScale(float scale) +{ + dfrorp_set_scale(m_dfrorp, scale); +} + +void DFRORP::setCalibrationOffset(float offset) +{ + dfrorp_set_calibration_offset(m_dfrorp, offset); +} + +float DFRORP::getORP() +{ + return dfrorp_get_orp(m_dfrorp); +} + +float DFRORP::getVolts() +{ + return dfrorp_get_volts(m_dfrorp); +} + +float DFRORP::getNormalized() +{ + return dfrorp_get_normalized(m_dfrorp); +} diff --git a/src/dfrorp/dfrorp.h b/src/dfrorp/dfrorp.h new file mode 100644 index 00000000..da15252f --- /dev/null +++ b/src/dfrorp/dfrorp.h @@ -0,0 +1,181 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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 "upm.h" +#include "mraa/aio.h" +#include "mraa/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * @brief UPM C API for the DFRobot ORP (Oxidation/Reduction + * Potential) Sensor + * + * The driver was tested with the DFRobot ORP Analog Sensor. + * + * To calibrate: + * + * Disconnect the sensor probe (but leave the sensor interface board + * connected). Then run one of the examples while holding down the + * 'calibrate' button on the device. Read the ORP value reported + * (it should be fairly small). + * + * This value is what you should supply to + * dfrorp_set_orp_cal_offset(). Then reconnect the probe to the + * interface board and you should be ready to go. + * + * DO NOT press the calibrate button on the interface board while + * the probe is attached or you can permanently damage the probe. + * + * @snippet dfrorp.c Interesting + */ + + /** + * Device context + */ + typedef struct _dfrorp_context { + mraa_aio_context aio; + + // analog ADC resolution + float a_res; + + // analog reference voltage + float a_ref; + + // for external offset and scaling of the results + float offset; + float scale; + + // For sensor interface board calibration + float orp_cal_offset; + + // our measurements + + // ORP measurement (mV) + float orp; + + // volts + float volts; + + // normalized ADC + float normalized; + } *dfrorp_context; + + /** + * DFRORP Initializer + * + * @param apin Analog pin to use. + * @param a_ref The analog reference voltage in use + */ + dfrorp_context dfrorp_init(unsigned int apin, float a_ref); + + /** + * DFRORP sensor close function + */ + void dfrorp_close(dfrorp_context dev); + + /** + * Read the sensor status and update internal state. dfrorp_update() + * must have been called before calling dfrorp_get_orp(), + * dfrorp_get_normalized(), or dfrorp_get_volts(). + * + * @param dev sensor context + * @return UPM result + */ + upm_result_t dfrorp_update(const dfrorp_context dev); + + /** + * Set sensor offset. This offset is applied to the ORP value + * before scaling. Default is 0.0. + * + * @param dev sensor context pointer + * @param offset Offset to apply to the computed ORP value + */ + void dfrorp_set_offset(const dfrorp_context dev, float offset); + + /** + * Set sensor scale. The ORP return value is scaled by this value + * before the offset is applied. Default is 1.0. + * + * @param dev sensor context pointer + * @param scale The scale to apply to the computed ORP value + */ + void dfrorp_set_scale(const dfrorp_context dev, float scale); + + /** + * Get computed ORP (in millivolts) value from the + * sensor. dfrorp_update() must have been called prior to calling + * this function. + * + * @param dev sensor context pointer + * @return ORP value in millivolts + */ + float dfrorp_get_orp(const dfrorp_context dev); + + /** + * Set the calibration offset for the device. This is + * determined by disconnecting the sensor probe (but leaving the + * sensor interface board connected). Then run one of the examples + * while holding down the 'calibrate' button on the device. Read + * the ORP value reported. + * + * This (low) ORP value is what you should supply to this function. + * Then reconnect the probe to the interface board and you should be + * ready to go. + * + * DO NOT press the calibrate button on the interface board while + * the probe is attached or you can permanently damage the probe. + * + * @param dev sensor context pointer + * @param offset The ORP offset obtained during calibration. + */ + void dfrorp_set_calibration_offset(const dfrorp_context dev, float offset); + + /** + * Get the raw measured volts from the sensor. dfrorp_update() must + * have been called prior to calling this function. + * + * @param dev sensor context pointer + * @return voltage read from the sensor + */ + float dfrorp_get_volts(const dfrorp_context dev); + + /** + * Get the raw normalized ADC values from the sensor. + * dfrorp_update() must have been called prior to calling this + * function. + * + * @param dev sensor context pointer + * @return normalized ADC value read from the sensor + */ + float dfrorp_get_normalized(const dfrorp_context dev); + +#ifdef __cplusplus +} +#endif diff --git a/src/dfrorp/dfrorp.hpp b/src/dfrorp/dfrorp.hpp new file mode 100644 index 00000000..35df83a3 --- /dev/null +++ b/src/dfrorp/dfrorp.hpp @@ -0,0 +1,162 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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 +#include + +#include "dfrorp.h" + +namespace upm { + /** + * @brief UPM C++ API for the DFRobot ORP (Oxidation/Reduction + * Potential) Sensor + * @defgroup dfrorp libupm-dfrorp + * @ingroup dfrobot ainput liquid + */ + + /** + * @library dfrorp + * @sensor dfrorp + * @comname DFRobot ORP (Oxidation/Reduction Potential) Sensor + * @type liquid + * @man dfrobot + * @con ainput + * @web http://www.dfrobot.com/index.php?route=product/product&path=36&product_id=1071#.V8Wywt9ytNJ + * + * @brief API for the DFRobot ORP (Oxidation/Reduction Potential) Sensor + * + * The driver was tested with the DFRobot ORP (Oxidation/Reduction + * Potential) Sensor. + * + * To calibrate: + * + * Disconnect the sensor probe (but leave the sensor interface board + * connected). Then run one of the examples while holding down the + * 'calibrate' button on the device. Read the ORP value reported + * (it should be fairly small). + * + * This value is what you should supply to + * setCalibrationOffset(). Then reconnect the probe to the + * interface board and you should be ready to go. + * + * DO NOT press the calibrate button on the interface board while + * the probe is attached or you can permanently damage the probe. + * + * @snippet dfrorp.cxx Interesting + */ + + class DFRORP { + public: + + /** + * DFRORP object constructor + * + * @param apin Analog pin to use + * @param a_ref The analog reference voltage in use. Default 5.0. + */ + DFRORP(int apin, float a_ref=5.0); + + /** + * DFRORP object destructor + */ + ~DFRORP(); + + /** + * Read the sensor status an update internal state. + * update() must have been called before calling + * getORP(), getNormalized(), or getVolts(). + */ + void update(); + + /** + * Set sensor offset. This offset is applied to the return ORP + * value before scaling. Default is 0.0. + * + * @param offset The offset to apply. + */ + void setOffset(float offset); + + /** + * Set sensor scale. The return ORP value is scaled by this value + * before the offset is applied. Default is 1.0. + * + * @param scale The scale to apply. + */ + void setScale(float scale); + + /** + * Get computed ORP (in millivolts) value from the + * sensor. update() must have been called prior to calling this + * function. + * + * @return ORP value in millivolts + */ + float getORP(); + + /** + * Set the calibration offset for the device. This is + * determined by disconnecting the sensor probe (but leaving the + * sensor interface board connected). Then run one of the examples + * while holding down the 'calibrate' button on the device. Read + * the ORP value reported. + * + * This (low) ORP value is what you should supply to this function. + * Then reconnect the probe to the interface board and you should be + * ready to go. + * + * DO NOT press the calibrate button on the interface board while + * the probe is attached or you can permanently damage the probe. + * + * @param offset The ORP offset obtained during calibration. + */ + void setCalibrationOffset(float offset); + + /** + * Get the measured volts from the sensor. update() must have been + * called prior to calling this function. + * + * @return The voltage measurement. + */ + float getVolts(); + + /** + * Get the normalized ADC value from the sensor. update() must have + * been called prior to calling this function. + * + * @return The normalized ADC value. + */ + float getNormalized(); + + protected: + // dfrorp device context + dfrorp_context m_dfrorp; + + private: + }; +} diff --git a/src/dfrorp/dfrorp_fti.c b/src/dfrorp/dfrorp_fti.c new file mode 100644 index 00000000..be88415f --- /dev/null +++ b/src/dfrorp/dfrorp_fti.c @@ -0,0 +1,99 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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 "dfrorp.h" +#include "upm_fti.h" + +/** + * This file implements the Function Table Interface (FTI) for this sensor + */ + +const char upm_dfrorp_name[] = "DFRORP"; +const char upm_dfrorp_description[] = "DFRobot Analog ORP Sensor"; +const upm_protocol_t upm_dfrorp_protocol[] = {UPM_ANALOG}; +const upm_sensor_t upm_dfrorp_category[] = {UPM_ORP}; + +// forward declarations +const void* upm_dfrorp_get_ft(upm_sensor_t sensor_type); +void* upm_dfrorp_init_name(); +void upm_dfrorp_close(void *dev); +upm_result_t upm_dfrorp_get_value(const void *dev, float *value); +upm_result_t upm_dfrorp_set_scale(const void *dev, float scale); +upm_result_t upm_dfrorp_set_offset(const void *dev, float offset); + +static const upm_sensor_ft ft = +{ + .upm_sensor_init_name = &upm_dfrorp_init_name, + .upm_sensor_close = &upm_dfrorp_close, +}; + +static const upm_orp_ft orpft = +{ + .upm_orp_set_offset = upm_dfrorp_set_offset, + .upm_orp_set_scale = upm_dfrorp_set_scale, + .upm_orp_get_value = upm_dfrorp_get_value +}; + +const void* upm_dfrorp_get_ft(upm_sensor_t sensor_type) +{ + switch(sensor_type) + { + case UPM_SENSOR: + return &ft; + + case UPM_ORP: + return &orpft; + + default: + return NULL; + } +} + +void* upm_dfrorp_init_name() +{ + return NULL; +} + +void upm_dfrorp_close(void *dev) +{ + dfrorp_close((dfrorp_context)dev); +} + +upm_result_t upm_dfrorp_set_scale(const void *dev, float scale) +{ + dfrorp_set_scale((dfrorp_context)dev, scale); + return UPM_SUCCESS; +} + +upm_result_t upm_dfrorp_set_offset(const void *dev, float offset) +{ + dfrorp_set_offset((dfrorp_context)dev, offset); + return UPM_SUCCESS; +} + +upm_result_t upm_dfrorp_get_value(const void *dev, float *value) +{ + *value = dfrorp_get_orp((dfrorp_context)dev); + return UPM_SUCCESS; +} diff --git a/src/dfrorp/javaupm_dfrorp.i b/src/dfrorp/javaupm_dfrorp.i new file mode 100644 index 00000000..6215fc3a --- /dev/null +++ b/src/dfrorp/javaupm_dfrorp.i @@ -0,0 +1,21 @@ +%module javaupm_dfrorp +%include "../upm.i" +%include "std_string.i" +%include "cpointer.i" +%include "typemaps.i" + +%include "dfrorp.hpp" +%{ + #include "dfrorp.hpp" +%} + +%pragma(java) jniclasscode=%{ + static { + try { + System.loadLibrary("javaupm_dfrorp"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. \n" + e); + System.exit(1); + } + } +%} diff --git a/src/dfrorp/jsupm_dfrorp.i b/src/dfrorp/jsupm_dfrorp.i new file mode 100644 index 00000000..ae3448b0 --- /dev/null +++ b/src/dfrorp/jsupm_dfrorp.i @@ -0,0 +1,13 @@ +%module jsupm_dfrorp +%include "../upm.i" +%include "std_string.i" +%include "cpointer.i" + +/* Send "int *" and "float *" to JavaScript as intp and floatp */ +%pointer_functions(int, intp); +%pointer_functions(float, floatp); + +%include "dfrorp.hpp" +%{ + #include "dfrorp.hpp" +%} diff --git a/src/dfrorp/pyupm_dfrorp.i b/src/dfrorp/pyupm_dfrorp.i new file mode 100644 index 00000000..79e1f2fb --- /dev/null +++ b/src/dfrorp/pyupm_dfrorp.i @@ -0,0 +1,17 @@ +// Include doxygen-generated documentation +%include "pyupm_doxy2swig.i" +%module pyupm_dfrorp +%include "../upm.i" +%include "std_string.i" +%include "cpointer.i" + +/* Send "int *" and "float *" to python as intp and floatp */ +%pointer_functions(int, intp); +%pointer_functions(float, floatp); + +%feature("autodoc", "3"); + +%include "dfrorp.hpp" +%{ + #include "dfrorp.hpp" +%}