diff --git a/docs/images/ads1015.jpg b/docs/images/ads1015.jpg new file mode 100644 index 00000000..972a679d Binary files /dev/null and b/docs/images/ads1015.jpg differ diff --git a/docs/images/ads1115.jpg b/docs/images/ads1115.jpg new file mode 100644 index 00000000..27e6a61f Binary files /dev/null and b/docs/images/ads1115.jpg differ diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index d548c779..fb239aa0 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -231,6 +231,7 @@ if (OPENZWAVE_FOUND) add_example (ozw) endif() add_example (nlgpio16) +add_example (ads1x15) # 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++/ads1x15.cxx b/examples/c++/ads1x15.cxx new file mode 100644 index 00000000..3c5da655 --- /dev/null +++ b/examples/c++/ads1x15.cxx @@ -0,0 +1,320 @@ +/* + * Author: Marc Graham + * 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 "mraa.hpp" + +#include +#include +#include "ads1015.h" +#include "ads1115.h" + + + +int main() +{ + + using namespace std; + using namespace upm; + int command; + //Select the device you are testing here and adjust case 6 for the correct sample rates. + //upm::ADS1015 *ads = new upm::ADS1015(1); + upm::ADS1115 *ads = new upm::ADS1115(1, 0x49); + float inputVoltage; + int ans; + + do + { + + cout << endl; + cout << "1 - get Conversion \t" ; + cout << "2 - get last conversion" << endl; + cout << "3 - get Gain \t\t"; + cout << "4 - set Gain" << endl;; + cout << "5 - get Data Rate \t"; + cout << "6 - set Data Rate" << endl; + cout << "7 - Set Upper Threshold \t" ; + cout << "8 - Set Lower Threshold \t"; + cout << "9 - Display Thresholds \t"; + cout << "10 - Set Default Thresholds \t"; + cout << "11 - Set conversion ready" << endl; + cout << "12 - get Comp Que \t" ; + cout << "13 - set Comp Que" << endl; + cout << "14 - get Comp Pol \t"; + cout << "15 - set Comp Pol" << endl; + cout << "16 - get Comp mode \t"; + cout << "17 - set Comp mode " << endl; + cout << "18 - get Comp Latch\t"; + cout << "19 - set Comp Latch " << endl; + cout << "20 - get Continuous \t"; + cout << "21 - set Continuous \t" << endl; + cout << "-1 - exit" << endl; + cout << "Enter a command: "; + cin >> command; + + + switch(command) + { + case 2: + cout << ads->getLastSample() << endl; + break; + case 3: + cout << std::hex << ads->getGain() << endl; + break; + case 5: + cout << std::hex << ads->getSPS() << endl; + break; + case 4: + int gain; + ADS1015::ADSGAIN set_gain; + cout << "select one of the following:" << endl; + cout << "1 -> gain 2/3 \t 2 -> gain1 \t 3 -> gain 2" << endl; + cout << "4 -> gain 4 \t 5 -> gain 8 \t 6 -> gain 15" << endl; + cin >> gain; + switch(gain){ + case 1: + set_gain = ADS1X15::GAIN_TWOTHIRDS; + break; + case 2: + set_gain = ADS1X15::GAIN_ONE; + break; + case 3: + set_gain = ADS1X15::GAIN_TWO; + break; + case 4: + set_gain = ADS1X15::GAIN_FOUR; + break; + case 5: + set_gain = ADS1X15::GAIN_EIGHT; + break; + case 6: + set_gain = ADS1X15::GAIN_SIXTEEN; + break; + default: + set_gain = ADS1X15::GAIN_ONE; + } + ads->setGain(set_gain); + break; + case 6: + int rate; + /*ADS1015::ADSDATARATE set_rate; + cout << "select one of the following:" << endl; + cout << "1 -> SPS_120 \t 2 -> SPS_250 \t 3 -> SPS_490 \t 4 -> SPS_920" << endl; + cout << "5 -> SPS_1600 \t 6 -> SPS_2400 \t 7 -> SPS_3300" << endl; + cin >> rate; + switch(rate){ + case 1: + set_rate = ADS1015::SPS_128; + break; + case 2: + set_rate = ADS1015::SPS_250; + break; + case 3: + set_rate = ADS1015::SPS_490; + break; + case 4: + set_rate = ADS1015::SPS_920; + break; + case 5: + set_rate = ADS1015::SPS_1600; + break; + case 6: + set_rate = ADS1015::SPS_2400; + break; + case 7: + set_rate = ADS1015::SPS_3300; + break; + default: + set_rate = ADS1015::SPS_1600; + } */ + ADS1115::ADSDATARATE set_rate; + cout << "select one of the following:" << endl; + cout << "1 -> SPS_8 \t 2 -> SPS_16 \t 3 -> SPS_32 \t 4 -> SPS_64" << endl; + cout << "5 -> SPS_128 \t 6 -> SPS_250 \t 7 -> SPS_475 \t 8-> SPS_860" << endl; + cin >> rate; + switch(rate){ + case 1: + set_rate = ADS1115::SPS_8; + break; + case 2: + set_rate = ADS1115::SPS_16; + break; + case 3: + set_rate = ADS1115::SPS_32; + break; + case 4: + set_rate = ADS1115::SPS_64; + break; + case 5: + set_rate = ADS1115::SPS_128; + break; + case 6: + set_rate = ADS1115::SPS_250; + break; + case 7: + set_rate = ADS1115::SPS_475; + break; + case 8: + set_rate = ADS1115::SPS_860; + break; + default: + set_rate = ADS1115::SPS_128; + } + + ads->setSPS(set_rate); + break; + case 1: + int mode; + ADS1X15::ADSMUXMODE set_mode; + cout << "select one of the following:" << endl; + cout << "1 -> MUX_0_1 \t 2 -> MUX_0_3 \t 3 -> MUX_1_3 \t 4 -> MUX_2_3" << endl; + cout << "5 -> SINGLE_0 \t 6 -> SINGLE_1 \t 7 -> SINGLE_2 \t 8 -> SINGLE_3" << endl; + cin >> mode; + switch(mode){ + case 1: + set_mode = ADS1X15::DIFF_0_1; + break; + case 2: + set_mode = ADS1X15::DIFF_0_3; + break; + case 3: + set_mode = ADS1X15::DIFF_1_3; + break; + case 4: + set_mode = ADS1X15::DIFF_2_3; + break; + case 5: + set_mode = ADS1X15::SINGLE_0; + break; + case 6: + set_mode = ADS1X15::SINGLE_1; + break; + case 7: + set_mode = ADS1X15::SINGLE_2; + break; + case 8: + set_mode = ADS1X15::SINGLE_3; + break; + default: + set_mode = ADS1X15::DIFF_0_1; + break; + } + cout << ads->getSample(set_mode) << endl; + break; + case 7: + cout << " enter a float value: " ; + cin >> inputVoltage; + ads->setThresh(ADS1115::THRESH_HIGH, inputVoltage); + break; + case 8: + cout << " enter a float value: " ; + cin >> inputVoltage; + ads->setThresh(ADS1115::THRESH_LOW, inputVoltage); + break; + case 9: + cout << "Upper " << ads->getThresh(ADS1X15::THRESH_HIGH) << endl; + cout << "Lower " << ads->getThresh(ADS1X15::THRESH_LOW) << endl; + break; + case 10: + ads->setThresh(ADS1115::THRESH_DEFAULT); + break; + case 11: + ads->setThresh(ADS1015::CONVERSION_RDY); + break; + case 12: + cout << ads->getCompQue() << endl; + break; + case 13: + int que; + cout << "select one of the following:" << endl; + cout << "1 -> CQUE_1CONV \t 2 -> CQUE_2CONV \t 3 -> CQUE_3CONV \t 4 -> CQUE_NONE" << endl; + cin >> que; + switch(que){ + case 1: + ads->setCompQue(ADS1X15::CQUE_1CONV); + break; + case 2: + ads->setCompQue(ADS1X15::CQUE_2CONV); + break; + case 3: + ads->setCompQue(ADS1X15::CQUE_4CONV); + break; + case 4: + default: + ads->setCompQue(ADS1X15::CQUE_NONE); + break; + } + break; + case 14: + cout << ads->getCompPol() << endl; + break; + case 15: + cout << "select one of the following:" << endl; + cout << "1 -> active high \t 2 -> active low" << endl; + cin >> ans; + if(ans == 1) ads->setCompPol(true); + else ads->setCompPol(false); + break; + case 16: + cout << ads->getCompMode() << endl; + break; + case 17: + cout << "select one of the following:" << endl; + cout << "1 -> Window \t 2 -> Traditional (default)" << endl; + cin >> ans; + if(ans == 1) ads->setCompMode(true); + else ads->setCompMode(); + break; + case 18: + cout << ads->getCompLatch() << cout; + break; + case 19: + cout << "select one of the following:" << endl; + cout << "1 -> Latching \t 2 -> Non-latching (default)" << endl; + cin >> ans; + if(ans == 1) ads->setCompLatch(true); + else ads->setCompLatch(); + break; + case 20: + cout << ads->getContinuous() << cout; + break; + case 21: + cout << "select one of the following:" << endl; + cout << "1 -> Power Down (default) \t 2 -> Continuous" << endl; + cin >> ans; + if(ans == 1) ads->setContinuous(true); + else ads->setContinuous(); + break; + case -1: + break; + default: + + break; + } + + }while (command != -1 ); + + delete ads; + + return MRAA_SUCCESS; +} diff --git a/examples/javascript/ads1x15.js b/examples/javascript/ads1x15.js new file mode 100644 index 00000000..d47e795e --- /dev/null +++ b/examples/javascript/ads1x15.js @@ -0,0 +1,46 @@ +/*jslint node:true, vars:true, bitwise:true, unparam:true */ +/*jshint unused:true */ +/* + * Author: Marc Graham + * 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 mraa = require('mraa'); +var version = mraa.getVersion(); + +if (version >= 'v0.6.1') { + console.log('mraa version (' + version + ') ok'); +} +else { + console.log('meaa version(' + version + ') is old - this code may not work'); +} + +var ADS1X15 = require('jsupm_ads1x15'); +var ads1115 = new ADS1X15.ADS1115(1, 0x49); +var ads1015 = new ADS1X15.ADS1015(1, 0x48); + +setInterval(function(){ + console.log(ads1115.getSample()); + console.log(ads1015.getSample()); + console.log("*********************"); +}, 1000); + + diff --git a/src/ads1x15/CMakeLists.txt b/src/ads1x15/CMakeLists.txt new file mode 100644 index 00000000..67c2e857 --- /dev/null +++ b/src/ads1x15/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "ads1x15") +set (libdescription "analog to digital converter") +set (module_src ${libname}.cxx ads1115.cxx ads1015.cxx) +set (module_h ${libname}.h ads1115.h ads1015.h) +upm_module_init() \ No newline at end of file diff --git a/src/ads1x15/ads1015.cxx b/src/ads1x15/ads1015.cxx new file mode 100644 index 00000000..1beef3dc --- /dev/null +++ b/src/ads1x15/ads1015.cxx @@ -0,0 +1,102 @@ +/* + * Author: Marc Graham + * 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 "ads1015.h" + +using namespace upm; + +void +ADS1015::setSPS(ADSSAMPLERATE rate){ + updateConfigRegister((m_config_reg & ~ADS1X15_DR_MASK) | rate); +} + +ADS1015::ADS1015(int bus, uint8_t address) : ADS1X15(bus, address) { + m_name = "ADS1015"; + m_conversionDelay = ADS1015_CONVERSIONDELAY; + m_bitShift = 4; + ADS1X15::getCurrentConfig(); +} + +ADS1015::~ADS1015(){}; + +//Private functions +float +ADS1015::getMultiplier(void){ + float multi = 0.0; + switch((ADSGAIN)m_config_reg & ADS1X15_PGA_MASK){ + case GAIN_TWOTHIRDS: + multi = 0.003; + break; + case GAIN_ONE: + multi = 0.002; + break; + case GAIN_TWO: + multi = 0.001; + break; + case GAIN_FOUR: + multi = 0.0005; + break; + case GAIN_EIGHT: + multi = 0.00025; + break; + case GAIN_SIXTEEN: + multi = 0.000125; + break; + default: + multi = 0.001; + break; + } + return multi; +} + +void +ADS1015::setDelay(){ + switch((int)ADS1X15::getSPS()){ + case 0: + m_conversionDelay = 8000; + break; + case 32: + m_conversionDelay = 4000; + break; + case 64: + m_conversionDelay = 3000; + break; + case 96: + m_conversionDelay = 1100; + break; + case 128: + m_conversionDelay = 700; + break; + case 160: + m_conversionDelay = 500; + break; + case 192: + m_conversionDelay = 400; + break; + default: + m_conversionDelay = 8000; + break; + } +} + + diff --git a/src/ads1x15/ads1015.h b/src/ads1x15/ads1015.h new file mode 100644 index 00000000..d47f2256 --- /dev/null +++ b/src/ads1x15/ads1015.h @@ -0,0 +1,142 @@ +/* + * Author: Marc Graham + * 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 "ads1x15.h" + + + +/*========================================================================= + CONVERSION DELAY (in microS) + -----------------------------------------------------------------------*/ + #define ADS1015_CONVERSIONDELAY (8000) +/*=========================================================================*/ + + +/*========================================================================= + CONFIG REGISTER + + -----------------------------------------------------------------------*/ + +#define ADS1015_DR_MASK (0x00E0) +#define ADS1015_DR_128SPS (0x0000) // 128 samples per second +#define ADS1015_DR_250SPS (0x0020) // 250 samples per second +#define ADS1015_DR_490SPS (0x0040) // 490 samples per second +#define ADS1015_DR_920SPS (0x0060) // 920 samples per second +#define ADS1015_DR_1600SPS (0x0080) // 1600 samples per second (default) +#define ADS1015_DR_2400SPS (0x00A0) // 2400 samples per second +#define ADS1015_DR_3300SPS (0x00C0) // 3300 samples per second + +/*=========================================================================*/ + +namespace upm { + /** + * @library ADS1115 + * @sensor ADS1115 + * @comname ADS1115 + * @type adc + * @man adafruit + * @con i2c + * + * @brief API for ADS1015 + * + * The ADS1013, ADS1014, and ADS1015 are precision analog-to-digital converters (ADCs) with 12 bits of resolution + * offered in an ultra-small, leadless QFN-10 package or an MSOP-10 package. The ADS1013/4/5 are designed with + * precision, power, and ease of implementation in mind. The ADS1013/4/5 feature an onboard reference and oscillator. + * Data are transferred via an I2C-compatible serial interface; four I2C slave addresses can be selected. The ADS1013/4/5 + * operate from a single power supply ranging from 2.0V to 5.5V. + * The ADS1013/4/5 can perform conversions at rates up to 3300 samples per second (SPS). An onboard PGA is available + * on the ADS1014 and ADS1015 that offers input ranges from the supply to as low as ±256mV, allowing both large and small + * signals to be measured with high resolution. The ADS1015 also features an input multiplexer (MUX) that provides two + * differential or four single-ended inputs. + * The ADS1013/4/5 operate either in continuous conversion mode or a single-shot mode that automatically powers down + * after a conversion and greatly reduces current consumption during idle periods. The ADS1013/4/5 are specified from + * –40°C to +125°C. + * + * web https://www.adafruit.com/products/1083 + * web http://www.ti.com/lit/ds/symlink/ads1015.pdf + * + * Tested with Adafriut ADS1015 board. + * + * @image html ADS1015.jpg + * @snippet ADS1015.cxx Interesting + */ + class ADS1015 : public ADS1X15 { + + public: + + /** + * @enum ADSSAMPLERATE + * @brief uint16_t enum containing values + * representing the sample rate of the device. + * + * @var ADSSAMPLERATE::SPS_128 = 0x0000 + * @var ADSSAMPLERATE::SPS_250 = 0x0020 + * @var ADSSAMPLERATE::SPS_490 = 0x0040 + * @var ADSSAMPLERATE::SPS_920 = 0x0060 + * @var ADSSAMPLERATE::SPS_1600 = 0x0080 + * @var ADSSAMPLERATE::SPS_2400 = 0x00A0 + * @var ADSSAMPLERATE::SPS_3300 = 0x00C0 + */ + typedef enum ADSSAMPLERATE { + SPS_128 = ADS1015_DR_128SPS, + SPS_250 = ADS1015_DR_250SPS, + SPS_490 = ADS1015_DR_490SPS, + SPS_920 = ADS1015_DR_920SPS, + SPS_1600 = ADS1015_DR_1600SPS, + SPS_2400 = ADS1015_DR_2400SPS, + SPS_3300 = ADS1015_DR_3300SPS + } ADSSAMPLERATE; + + + /** + * ADS1X15 constructor + * + * @param bus i2c bus the sensor is attached to. + * @param address. Device address. Default is 0x48. + */ + ADS1015 (int bus, uint8_t address = 0x48); + + /** + * ADS1X15 destructor + */ + ~ADS1015 (); + + /** + * Sets the sample rate of the device. This function + * needs to be overridden in subclasses as the ADS1115 and + * ADS1015 have different sample rates. + * + * @param ADSSAMPLERATE enum + */ + void setSPS(ADSSAMPLERATE rate = SPS_1600); + + protected: + float getMultiplier(void); + void setDelay(void); + + }; +} diff --git a/src/ads1x15/ads1115.cxx b/src/ads1x15/ads1115.cxx new file mode 100644 index 00000000..ee0dfdab --- /dev/null +++ b/src/ads1x15/ads1115.cxx @@ -0,0 +1,103 @@ +/* + * Author: Marc Graham + * 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 "ads1115.h" + +using namespace upm; + +ADS1115::ADS1115(int bus, uint8_t address) : ADS1X15(bus, address) { + m_name = "ADS1115"; + m_conversionDelay = ADS1115_CONVERSIONDELAY; + m_bitShift = 0; + ADS1X15::getCurrentConfig(); +} + +ADS1115::~ADS1115(){}; + +void +ADS1115::setSPS(ADSDATARATE rate){ + updateConfigRegister((m_config_reg & ~ADS1X15_DR_MASK) | rate); +} + +//Protected functions +float +ADS1115::getMultiplier(void){ + float multi = 0.0; + switch((ADSGAIN)m_config_reg & ADS1X15_PGA_MASK){ + case GAIN_TWOTHIRDS: + multi = 0.0001875; + break; + case GAIN_ONE: + multi = 0.000125; + break; + case GAIN_TWO: + multi = 0.0000625; + break; + case GAIN_FOUR: + multi = 0.00003125; + break; + case GAIN_EIGHT: + multi = 0.000015625; + break; + case GAIN_SIXTEEN: + multi = 0.0000078125; + break; + default: + multi = 0.0001875; + break; + } + return multi; +} + +void +ADS1115::setDelay(){ + switch((int)ADS1X15::getSPS()){ + case 0: + m_conversionDelay = 126000; + break; + case 32: + m_conversionDelay = 63000; + break; + case 64: + m_conversionDelay = 32000; + break; + case 96: + m_conversionDelay = 16000; + break; + case 128: + m_conversionDelay = 8000; + break; + case 160: + m_conversionDelay = 4500; + break; + case 192: + m_conversionDelay = 2200; + break; + case 224: + m_conversionDelay = 1200; + break; + default: + m_conversionDelay = 126000; + break; + } +} diff --git a/src/ads1x15/ads1115.h b/src/ads1x15/ads1115.h new file mode 100644 index 00000000..5ed2c828 --- /dev/null +++ b/src/ads1x15/ads1115.h @@ -0,0 +1,147 @@ +/* + * Author: Marc Graham + * 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 "ads1x15.h" + + + +/*========================================================================= + CONVERSION DELAY (in microS) + -----------------------------------------------------------------------*/ + #define ADS1115_CONVERSIONDELAY (8000) +/*=========================================================================*/ + + +/*========================================================================= + CONFIG REGISTER + + -----------------------------------------------------------------------*/ + +#define ADS1115_DR_MASK (0x00E0) +#define ADS1115_DR_8SPS (0x0000) // 8 samples per second +#define ADS1115_DR_16SPS (0x0020) // 16 samples per second +#define ADS1115_DR_32SPS (0x0040) // 32 samples per second +#define ADS1115_DR_64SPS (0x0060) // 64 samples per second +#define ADS1115_DR_128SPS (0x0080) // 128 samples per second (default) +#define ADS1115_DR_250SPS (0x00A0) // 250 samples per second +#define ADS1115_DR_475SPS (0x00C0) // 475 samples per second +#define ADS1115_DR_860SPS (0x00E0) // 860 samples per second + +/*=========================================================================*/ + +namespace upm { + /** + * @library ADS1115 + * @sensor ADS1115 + * @comname ADS1115 + * @type adc + * @man adafruit + * @con i2c + * web https://www.adafruit.com/products/1085 + * web http://www.ti.com/lit/ds/symlink/ads1115.pdf + * + * + * @brief API for ADS1115 + * + * The ADS1113, ADS1114, and ADS1115 are precision analog-to-digital converters (ADCs) with 16 bits of resolution offered + * in an ultra-small, leadless QFN-10 package or an MSOP-10 package. The ADS1113/4/5 are designed with precision, power, + * and ease of implementation in mind. The ADS1113/4/5 feature an onboard reference and oscillator. Data are transferred via + * an I2C-compatible serial interface; four I2C slave addresses can be selected. The ADS1113/4/5 operate from a single power + * supply ranging from 2.0V to 5.5V. + * The ADS1113/4/5 can perform conversions at rates up to 860 samples per second (SPS). An onboard PGA is available on + * the ADS1114 and ADS1115 that offers input ranges from the supply to as low as ±256mV, allowing both large and small + * signals to be measured with high resolution. The ADS1115 also features an input multiplexer (MUX) that provides two + * differential or four single-ended inputs. + * The ADS1113/4/5 operate either in continuous conversion mode or a single-shot mode that automatically powers down after + * a conversion and greatly reduces current consumption during idle periods. The ADS1113/4/5 are specified from –40°C to +125°C. + * + * Tested with DIYMall ADS1115 board. + * + * @image html ADS1115.jpg + * @snippet ADS1015.cxx Interesting + */ + class ADS1115 : public ADS1X15 { + + public: + + /** + * @enum ADSSAMPLERATE + * @brief uint16_t enum containing values + * representing the sample rate of the device. + * + * @var ADSSAMPLERATE::SPS_8 = 0x0000 + * @var ADSSAMPLERATE::SPS_16 = 0x0020 + * @var ADSSAMPLERATE::SPS_32 = 0x0040 + * @var ADSSAMPLERATE::SPS_64 = 0x0060 + * @var ADSSAMPLERATE::SPS_128 = 0x0080 + * @var ADSSAMPLERATE::SPS_250 = 0x00A0 + * @var ADSSAMPLERATE::SPS_475 = 0x00C0 + * @var ADSSAMPLERATE::SPS_860 = 0x00E0 + */ + typedef enum ADSDATARATE + { + SPS_8 = ADS1115_DR_8SPS, + SPS_16 = ADS1115_DR_16SPS, + SPS_32 = ADS1115_DR_32SPS, + SPS_64 = ADS1115_DR_64SPS, + SPS_128 = ADS1115_DR_128SPS, + SPS_250 = ADS1115_DR_250SPS, + SPS_475 = ADS1115_DR_475SPS, + SPS_860 = ADS1115_DR_860SPS + } ADSDATARATE; + + + + /** + * ADS1X15 constructor + * + * @param bus i2c bus the sensor is attached to. + * @param address. Device address. Default is 0x48. + */ + ADS1115 (int bus, uint8_t address = 0x48); + + /** + * ADS1X15 destructor + */ + ~ADS1115(); + + /** + * Sets the sample rate of the device. This function + * needs to be overridden in subclasses as the ADS1115 and + * ADS1015 have different sample rates. + * + * @param ADSSAMPLERATE enum + */ + void setSPS(ADSDATARATE rate = ADS1115::SPS_128); + + + protected: + float getMultiplier(void); + void setDelay(void); + + }; +} diff --git a/src/ads1x15/ads1x15.cxx b/src/ads1x15/ads1x15.cxx new file mode 100644 index 00000000..4a1ea9db --- /dev/null +++ b/src/ads1x15/ads1x15.cxx @@ -0,0 +1,187 @@ +/* + * Author: Marc Graham + * 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 "ads1x15.h" + +#include + +using namespace upm; + +ADS1X15::ADS1X15(int bus, uint8_t address){ + + if(!(i2c = new mraa::I2c(bus))){ + throw std::invalid_argument(std::string(__FUNCTION__) +": I2c.init() failed"); + return; + } + + if((i2c->address(address) != mraa::SUCCESS)){ + throw std::invalid_argument(std::string(__FUNCTION__) + ": I2c.address() failed"); + return; + } + + if(i2c->frequency( mraa::I2C_FAST) != mraa::SUCCESS){ + throw std::invalid_argument(std::string(__FUNCTION__) + ": I2c.frequency(I2C_FAST) failed"); + return; + } + //Will be reset by sub class. + m_bitShift = 0; + m_conversionDelay = .001; + m_config_reg = 0x0000; +} + +ADS1X15::~ADS1X15(){} + +float +ADS1X15::getSample(ADSMUXMODE mode){ + updateConfigRegister((m_config_reg & ~ADS1X15_MUX_MASK) | mode, true); + usleep(m_conversionDelay); + return getLastSample(); +} + +float +ADS1X15::getLastSample(int reg){ + uint16_t value = i2c->readWordReg(reg); + bool neg = false; + value = swapWord(value); + if(value & 0x8000){ + neg = true; + value = ~value; + } + if(m_name == "ADS1015") value = value >> m_bitShift; + if(neg) return 0.0 - value * getMultiplier(); + else return value * getMultiplier(); +} + +void +ADS1X15::setGain(ADSGAIN gain){ + updateConfigRegister((m_config_reg & ~ADS1X15_PGA_MASK) | gain); +} + +void +ADS1X15::setSPS(ADSSAMPLERATE rate){ + updateConfigRegister((m_config_reg & ~ADS1X15_DR_MASK) | rate); +} + +void +ADS1X15::setCompMode(bool mode){ + if(mode) updateConfigRegister((m_config_reg & ~ADS1X15_CMODE_MASK)); + else updateConfigRegister((m_config_reg & ~ADS1X15_CMODE_MASK) | ADS1X15_CMODE_WINDOW); +} + +void +ADS1X15::setCompPol(bool mode){ + if(!mode) updateConfigRegister((m_config_reg & ~ADS1X15_CPOL_MASK)); + else updateConfigRegister((m_config_reg & ~ADS1X15_CPOL_MASK) | ADS1X15_CPOL_ACTVHI); +} + +void +ADS1X15::setCompLatch(bool mode){ + if(mode) updateConfigRegister((m_config_reg & ~ADS1X15_CLAT_MASK)); + else updateConfigRegister((m_config_reg & ~ADS1X15_CLAT_MASK) | ADS1X15_CLAT_LATCH); +} + +void +ADS1X15::setCompQue(ADSCOMP mode){ + updateConfigRegister((m_config_reg & ~ADS1X15_CQUE_MASK) | mode); +} + +void +ADS1X15::setContinuous(bool mode){ + if(mode) updateConfigRegister((m_config_reg & ~ADS1X15_MODE_MASK)); + else updateConfigRegister((m_config_reg & ~ADS1X15_MODE_MASK) | ADS1X15_MODE_SINGLE); +} + +float +ADS1X15::getThresh(ADSTHRESH reg){ + if( THRESH_HIGH && THRESH_LOW) return getLastSample(reg); + else return 0.0; +} + +void +ADS1X15::setThresh(ADSTHRESH reg, float value){ + uint16_t set_value; + switch((int)reg){ + case 4: //set conversion_rdy operation + if(i2c->writeWordReg(ADS1X15_REG_POINTER_LOWTHRESH, 0x0000) != mraa::SUCCESS){ + throw std::invalid_argument(std::string(__FUNCTION__) + ": I2c.write() failed"); + return; + } + if(i2c->writeWordReg(ADS1X15_REG_POINTER_HITHRESH, 0x0080) != mraa::SUCCESS){ + throw std::invalid_argument(std::string(__FUNCTION__) + ": I2c.write() failed"); + return; + } + break; + case 2: + case 3: + set_value = value / getMultiplier(); + set_value = set_value << m_bitShift; + if(i2c->writeWordReg(reg, swapWord(set_value)) != mraa::SUCCESS){ + throw std::invalid_argument(std::string(__FUNCTION__) + ": I2c.write() failed"); + return; + } + break; + case 5: //set default + default: + if(i2c->writeWordReg(ADS1X15_REG_POINTER_LOWTHRESH, 0x0080) != mraa::SUCCESS){ + throw std::invalid_argument(std::string(__FUNCTION__) + ": I2c.write() failed"); + return; + } + if(i2c->writeWordReg(ADS1X15_REG_POINTER_HITHRESH, 0xF07F) != mraa::SUCCESS){ + throw std::invalid_argument(std::string(__FUNCTION__) + ": I2c.write() failed"); + return; + } + break; + } +} + + +//Private functions +void +ADS1X15::getCurrentConfig(){ + m_config_reg = i2c->readWordReg(ADS1X15_REG_POINTER_CONFIG); + m_config_reg = swapWord(m_config_reg); + setDelay(); +} + +void +ADS1X15::updateConfigRegister(uint16_t update, bool read){ + uint16_t temp = update; + //Mask out read bit if we are just updating the configuration. + if(!read) temp = update & 0x7FFF; + if(i2c->writeWordReg(ADS1X15_REG_POINTER_CONFIG, swapWord(temp)) != mraa::SUCCESS){ + throw std::invalid_argument(std::string(__FUNCTION__) + ": I2c.write() failed"); + return; + } + //If we update the configuration re-set the in memory copy. + if(!read) getCurrentConfig(); +} + +uint16_t +ADS1X15::swapWord(uint16_t value){ + uint16_t res = value; + return ((res & 0xFF) << 8) | ((res >> 8 ) & 0xFF); +} + + diff --git a/src/ads1x15/ads1x15.h b/src/ads1x15/ads1x15.h new file mode 100644 index 00000000..c08fe46b --- /dev/null +++ b/src/ads1x15/ads1x15.h @@ -0,0 +1,422 @@ +/* + * Author: Marc Graham + * 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 "mraa.hpp" +#include "mraa/i2c.hpp" + +/*========================================================================= + I2C ADDRESS/BITS + -----------------------------------------------------------------------*/ +#define ADS1X15_ADDRESS (0x48) // 1001 000 (ADDR = GND) +/*=========================================================================*/ + + +/*========================================================================= + POINTER REGISTER + -----------------------------------------------------------------------*/ +#define ADS1X15_REG_POINTER_MASK (0x03) +#define ADS1X15_REG_POINTER_CONVERT (0x00) +#define ADS1X15_REG_POINTER_CONFIG (0x01) +#define ADS1X15_REG_POINTER_LOWTHRESH (0x02) +#define ADS1X15_REG_POINTER_HITHRESH (0x03) +/*=========================================================================*/ + +/*========================================================================= + CONFIG REGISTER + + -----------------------------------------------------------------------*/ +#define ADS1X15_OS_MASK (0x8000) +#define ADS1X15_OS_SINGLE (0x8000) // Write: Set to start a single-conversion +#define ADS1X15_OS_BUSY (0x0000) // Read: Bit = 0 when conversion is in progress +#define ADS1X15_OS_NOTBUSY (0x8000) // Read: Bit = 1 when device is not performing a conversion + +#define ADS1X15_MUX_MASK (0x7000) +#define ADS1X15_MUX_DIFF_0_1 (0x0000) // Differential P = AIN0, N = AIN1 (default) +#define ADS1X15_MUX_DIFF_0_3 (0x1000) // Differential P = AIN0, N = AIN3 +#define ADS1X15_MUX_DIFF_1_3 (0x2000) // Differential P = AIN1, N = AIN3 +#define ADS1X15_MUX_DIFF_2_3 (0x3000) // Differential P = AIN2, N = AIN3 +#define ADS1X15_MUX_SINGLE_0 (0x4000) // Single-ended AIN0 +#define ADS1X15_MUX_SINGLE_1 (0x5000) // Single-ended AIN1 +#define ADS1X15_MUX_SINGLE_2 (0x6000) // Single-ended AIN2 +#define ADS1X15_MUX_SINGLE_3 (0x7000) // Single-ended AIN3 + +#define ADS1X15_PGA_MASK (0x0E00) +#define ADS1X15_PGA_6_144V (0x0000) // +/-6.144V range = Gain 2/3 +#define ADS1X15_PGA_4_096V (0x0200) // +/-4.096V range = Gain 1 +#define ADS1X15_PGA_2_048V (0x0400) // +/-2.048V range = Gain 2 (default) +#define ADS1X15_PGA_1_024V (0x0600) // +/-1.024V range = Gain 4 +#define ADS1X15_PGA_0_512V (0x0800) // +/-0.512V range = Gain 8 +#define ADS1X15_PGA_0_256V (0x0A00) // +/-0.256V range = Gain 16 + +#define ADS1X15_MODE_MASK (0x0100) +#define ADS1X15_MODE_CONTIN (0x0000) // Continuous conversion mode +#define ADS1X15_MODE_SINGLE (0x0100) // Power-down single-shot mode (default) + +#define ADS1X15_DR_MASK (0x00E0) + +#define ADS1X15_CMODE_MASK (0x0010) +#define ADS1X15_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default) +#define ADS1X15_CMODE_WINDOW (0x0010) // Window comparator + +#define ADS1X15_CPOL_MASK (0x0008) +#define ADS1X15_CPOL_ACTVLOW (0x0000) // ALERT/RDY pin is low when active (default) +#define ADS1X15_CPOL_ACTVHI (0x0008) // ALERT/RDY pin is high when active + +#define ADS1X15_CLAT_MASK (0x0400) // Determines if ALERT/RDY pin latches once asserted +#define ADS1X15_CLAT_NONLAT (0x0000) // Non-latching comparator (default) +#define ADS1X15_CLAT_LATCH (0x0400) // Latching comparator + +#define ADS1X15_CQUE_MASK (0x0003) +/* This wouldn't compile for the python wrapper. with these in for some reason. +#define ADS1X15_CQUE_1CONV (0x0000) // Assert ALERT/RDY after one conversions +#define ADS1X15_CQUE_2CONV (0x0001) // Assert ALERT/RDY after two conversions +#define ADS1X15_CQUE_4CONV (0x0002) // Assert ALERT/RDY after four conversions +#define ADS1X15_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default) +*/ +/*=========================================================================*/ + +namespace upm { + /** + * @brief ADS1X15 family adc library + * + * Library for TI analog to digital converter ic. Base clase fro ADS1X15 provides all the functionality that + * ADS1115 and ADS1015 ics have in common. + * + */ + class ADS1X15 { + + public: + + /** + * @enum ADSGAIN + * @brief uint16_t enum containing values for + * setting gain for ADS1X15 devices. + * + * @var ADSGAIN::TWOTHIRDS = 0x0000 + * @var ADSGAIN::ONE = 0x0200 + * @var ADSGAIN::TWO = 0x0400 + * @var ADSGAIN::FOUR = 0x0600 + * @var ADSGAIN::EIGHT = 0x0800 + * @var ADSGAIN::SIXTEEN = 0x0A00 + */ + typedef enum ADSGAIN { + GAIN_TWOTHIRDS = ADS1X15_PGA_6_144V, + GAIN_ONE = ADS1X15_PGA_4_096V, + GAIN_TWO = ADS1X15_PGA_2_048V, + GAIN_FOUR = ADS1X15_PGA_1_024V, + GAIN_EIGHT = ADS1X15_PGA_0_512V, + GAIN_SIXTEEN = ADS1X15_PGA_0_256V + } ADSGAIN ; + + /** + * @enum ADSMUXMODE + * @brief uint16_t enum containing values used + * for selecting ADS1X15 read operations. + * + * @var ADSMUXMODE::DIFF_0_1 = 0x0000 + * @var ADSMUXMODE::DIFF_0_2 = 0x1000 + * @var ADSMUXMODE::DIFF_1_3 = 0x2000 + * @var ADSMUXMODE::DIFF_2_3 = 0x3000 + * @var ADSMUXMODE::SINGLE_0 = 0x4000 + * @var ADSMUXMODE::SINGLE_1 = 0x5000 + * @var ADSMUXMODE::SINGLE_2 = 0x6000 + * @var ADSMUXMODE::SINGLE_3 = 0x7000 + */ + typedef enum ADSMUXMODE { + DIFF_0_1 = ADS1X15_MUX_DIFF_0_1, // Differential P = AIN0, N = AIN1 (default) + DIFF_0_3 = ADS1X15_MUX_DIFF_0_3, // Differential P = AIN0, N = AIN3 + DIFF_1_3 = ADS1X15_MUX_DIFF_1_3, // Differential P = AIN1, N = AIN3 + DIFF_2_3 = ADS1X15_MUX_DIFF_2_3, // Differential P = AIN2, N = AIN3 + SINGLE_0 = ADS1X15_MUX_SINGLE_0, // Single-ended AIN0 + SINGLE_1 = ADS1X15_MUX_SINGLE_1, // Single-ended AIN1 + SINGLE_2 = ADS1X15_MUX_SINGLE_2, // Single-ended AIN2 + SINGLE_3 = ADS1X15_MUX_SINGLE_3 // Single-ended AIN3 + } ADSMUXMODE; + + /** + * @enum ADSCOMP + * @brief uint16_t enum containing values + * for setting ADS1X15 comparator queue modes. + * + * @var ADSCOMP::CQUE_1CONV = 0x0000 + * @var ADSCOMP::CQUE_2CONV = 0x0001 + * @var ADSCOMP::CQUE_3CONV = 0x0002 + * @var ADSCOMP::CQUE_NONE = 0x0003 + */ + typedef enum ADSCOMP { + CQUE_1CONV = 0x0000, // Assert ALERT/RDY after one conversions + CQUE_2CONV = 0x0001, // Assert ALERT/RDY after two conversions + CQUE_4CONV = 0x0002, // Assert ALERT/RDY after four conversions + CQUE_NONE = 0x0003 // Disable the comparator and put ALERT/RDY in high state (default) + } ADSCOMP; + + /** + * @enum ADSTHRESH + * @brief uint8_t enum containing register addresses + * used for setting HI and LOW threshold values as + * well as setting conversion ready and set to default. + * + * @var ADSTHRESH::THRESH_LOW = 0x02 + * @var ADSTHRESH::THRESH_HIGH = 0x03 + * @var ADSTHRESH::CONVERSION_RDY = 0x04 + * @var ADSTHRESH::THRESH_DEFAULT = 0x05 + */ + typedef enum ADSTHRESH { + THRESH_LOW = ADS1X15_REG_POINTER_LOWTHRESH, + THRESH_HIGH = ADS1X15_REG_POINTER_HITHRESH, + CONVERSION_RDY = 0x04, + THRESH_DEFAULT = 0x05 + + } ADSTHRESH; + + /** + * @enum ADSSAMPLERATE + * @brief uint16_t enum containing values + * representing the sample rate of the device. + * Will be overridden in subclass + * + * @var ADSSAMPLERATE::SPS_DEFAULT = 0x0080 + */ + typedef enum ADSSAMPLERATE { + SPS_DEFAULT = 0x0080 + } ADSSAMPLERATE; + + /** + * ADS1X15 constructor + * + * @param bus i2c bus the sensor is attached to. + * @param address. Device address. Default is 0x48. + */ + ADS1X15(int bus, uint8_t address); + + /** + * ADS1X15 destructor + */ + virtual ~ADS1X15 (); + + /** + * Returns the name of the sensor + */ + std::string name() + { + return m_name; + } + + /** + * Returns the contents of conversion register without performing + * a conversion operation. Will use a multiplier based on the + * current gain setting to give the voltage as a float. Used + * internally to return the HI and LOW threshold values. + * + * @param reg uint8_t value specifying register to read. + * Should generally be called with no parameter. + */ + float getLastSample(int reg = ADS1X15_REG_POINTER_CONVERT); + + /** + * Performs a read as specified by ADS1X15::ADSMUXMOE and + * returns the value as a float. Uses getLastSample() internally + * to return voltage value. + * + * @pram mode ADSMUXMODE specifying inputs to be sampled. + */ + float getSample(ADSMUXMODE mode = ADS1X15::DIFF_0_1); + + /** + * Returns the current gain setting being used by the device + * as an ADSGAIN value. + */ + ADSGAIN getGain(){ + return (ADSGAIN)(m_config_reg & ADS1X15_PGA_MASK); + } + + /** + * Sets the PGA gain bits to the desired gain. Default + * is +/- 2.094 volts. + * + * @param gain ADSGAIN value reprenting the desired gain. + * See warnings in spec sheet. + */ + void setGain(ADSGAIN gain = ADS1X15::GAIN_TWO); + + /** + * Returns the current device sample rate a an ADSSAMPLERATE + * value. + */ + ADSSAMPLERATE getSPS(void){ + return (ADSSAMPLERATE)(m_config_reg & ADS1X15_DR_MASK); + } + + /** + * Sets the sample rate of the device. This function + * needs to be overrode in subclasses as the ADS1115 and + * ADS1015 have different data rates. + * + * @param ADSSAMPLERATE enum + * SPS_DEFAULT = 0x0080 + */ + virtual void setSPS(ADSSAMPLERATE rate); + + /** + * Returns the comparator mode. + * False = Traditional comparator with Hysteresis (default) + * True = Window Comparator + */ + bool getCompMode(void){ + return (bool)(m_config_reg & ADS1X15_CMODE_MASK); + } + + /** + * Sets the comparator mode of the device. + * + * @param mode bool value denoting mode. + * False = Traditional comparator with Hysteresis (default) + * True = Window Comparator + */ + void setCompMode(bool mode = false); + + /** + * Get comparator polarity. Reports the polarity + * of the ALERT/RDY pin. Returns: + * False = Active Low (default) + * True = Active High + */ + bool getCompPol(void){ + return (bool)(m_config_reg & ADS1X15_CPOL_MASK); + } + + /** + * Sets the comparator polarity. Controls the + * polarity of the ALERT/RDY pin. + * + * @param mode bool. + * False = Active Low (default) + * True = Active High + */ + void setCompPol(bool mode = false); + + /** + * Returns bool representing the state of the + * comparator latching functionality. + * False = Non Latching comparator (default) + * True = Latching Comparator + */ + bool getCompLatch(void){ + return (bool)(m_config_reg & ADS1X15_CLAT_MASK); + } + + /** + * Sets bit controlling comparator operation. + * + * @param mode bool + * False = Non Latching comparator (default) + * True = Latching Comparator + */ + void setCompLatch(bool mode = false); + + /** + * Returns ADSCOMP value representing the state of + * comparator queue. + * + * CQUE_1CONV = Assert after one conversion + * CQUE_2CONV = Assert after two conversions + * CQUE_2CONV = Assert after four conversions + * CQUE_NONE = Disable comparator (default) + */ + ADSCOMP getCompQue(void){ + return (ADSCOMP)(m_config_reg & ADS1X15_CQUE_MASK); + } + + /** + * Sets bits controlling Comparator queue operation. + * + * @param mode ADSCOMP enum. + * CQUE_1CONV = Assert after one conversion + * CQUE_2CONV = Assert after two conversions + * CQUE_2CONV = Assert after four conversions + * CQUE_NONE = Disable comparator (default) + */ + void setCompQue(ADSCOMP mode = ADS1X15::CQUE_NONE); + + /** + * Returns bool reflecting state of device mode bit. + * + * False = Power Down Single shot mode (default) + * True = Continuous conversion mode + */ + bool getContinuous(void){ + return !(bool)(m_config_reg & ADS1X15_MODE_MASK); + } + + /** + * Sets the state of device mode but. + * + * @param mode bool + * False = Power Down Single shot mode (default) + * True = Continuous conversion mode + */ + void setContinuous(bool mode = false); + + /** + * Returns current high or low threshold setting. + * + * @param reg ADSTHRES enum value. + * Returns 0.0 unless THRESH_HIGH or THRESH_LOW requested. + */ + float getThresh(ADSTHRESH reg = THRESH_LOW); + + /** + * Sets threshold levels or configures for conversion ready + * operation of ALERT/RDY output. + * + * @param reg ADSTHRESH enum + * @param value float value to set threshold register to. + * + * THRESH_LOW = Sets low thresh register. + * THRESH_HIGH = Sets high thresh register. + * CONVERSION_RDY = Configures conversion ready operation + * THRESH_DEFAULT = resets high/low registers to startup values. + */ + void setThresh(ADSTHRESH reg = THRESH_DEFAULT , float value = 0.0); + + protected: + std::string m_name; + float m_conversionDelay; + uint8_t m_bitShift; + uint16_t m_config_reg; + //Must be overridden in subclass for proper values. + virtual float getMultiplier(void) = 0; + //Must be overridden in subclass for proper values. + virtual void setDelay(void) = 0; + void getCurrentConfig(); + void updateConfigRegister(uint16_t update, bool read = false); + uint16_t swapWord(uint16_t value); + + mraa::I2c* i2c; + + };} diff --git a/src/ads1x15/javaupm_ads1x15.i b/src/ads1x15/javaupm_ads1x15.i new file mode 100644 index 00000000..88522e3a --- /dev/null +++ b/src/ads1x15/javaupm_ads1x15.i @@ -0,0 +1,26 @@ +%module javaupm_ads1x15 +%include "../upm.i" +%include "typemaps.i" + +%{ + #include "ads1x15.h" + #include "ads1015.h" + #include "ads1115.h" +%} + +%include "ads1x15.h" +%include "ads1015.h" +%include "ads1115.h" + + + +%pragma(java) jniclasscode=%{ + static { + try { + System.loadLibrary("javaupm_ads1x15"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. \n" + e); + System.exit(1); + } + } +%} \ No newline at end of file diff --git a/src/ads1x15/jsupm_ads1x15.i b/src/ads1x15/jsupm_ads1x15.i new file mode 100644 index 00000000..11a00e7c --- /dev/null +++ b/src/ads1x15/jsupm_ads1x15.i @@ -0,0 +1,17 @@ +%module jsupm_ads1x15 +%include "../upm.i" + +%include "ads1x15.h" +%{ + #include "ads1x15.h" +%} + +%include "ads1015.h" +%{ + #include "ads1015.h" +%} + +%include "ads1115.h" +%{ + #include "ads1115.h" +%} \ No newline at end of file diff --git a/src/ads1x15/pyupm_ads1x15.i b/src/ads1x15/pyupm_ads1x15.i new file mode 100644 index 00000000..dddefc1d --- /dev/null +++ b/src/ads1x15/pyupm_ads1x15.i @@ -0,0 +1,20 @@ +%module pyupm_ads1x15 +%include "../upm.i" + + +%feature("autodoc", "3"); + +%include "ads1x15.h" +%{ + #include "ads1x15.h" +%} + +%include "ads1015.h" +%{ + #include "ads1015.h" +%} + +%include "ads1115.h" +%{ + #include "ads1115.h" +%} \ No newline at end of file