diff --git a/docs/images/hx711.jpeg b/docs/images/hx711.jpeg new file mode 100644 index 00000000..feff7840 Binary files /dev/null and b/docs/images/hx711.jpeg differ diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index 53fc1291..0f18545d 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -103,6 +103,7 @@ add_executable (groveeldriver-example groveeldriver.cxx) add_executable (adafruitss-example adafruitss.cxx) add_executable (adafruitms1438-example adafruitms1438.cxx) add_executable (adafruitms1438-stepper-example adafruitms1438-stepper.cxx) +add_executable (hx711-example hx711.cxx) include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l) include_directories (${PROJECT_SOURCE_DIR}/src/grove) @@ -186,6 +187,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/pca9685) include_directories (${PROJECT_SOURCE_DIR}/src/groveeldriver) include_directories (${PROJECT_SOURCE_DIR}/src/adafruitss) include_directories (${PROJECT_SOURCE_DIR}/src/adafruitms1438) +include_directories (${PROJECT_SOURCE_DIR}/src/hx711) target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT}) @@ -290,4 +292,4 @@ target_link_libraries (groveeldriver-example groveeldriver ${CMAKE_THREAD_LIBS_I target_link_libraries (adafruitss-example adafruitss ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (adafruitms1438-example adafruitms1438 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (adafruitms1438-stepper-example adafruitms1438 ${CMAKE_THREAD_LIBS_INIT}) - +target_link_libraries (hx711-example hx711 ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/c++/hx711.cxx b/examples/c++/hx711.cxx new file mode 100644 index 00000000..531734b2 --- /dev/null +++ b/examples/c++/hx711.cxx @@ -0,0 +1,43 @@ +/* +* +* Author: Rafael da Mata Neri +* 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 + +//! [Interesting] +#include "hx711.h" + +int +main(int argc, char **argv) +{ + upm::HX711 *scale = new upm::HX711(3, 2); + + // 2837: value obtained via calibration + scale->setScale(2837); + scale->tare(); + std::cout << scale->getUnits() << std::endl; + + return 0; +} +//! [Interesting] diff --git a/examples/javascript/hx711.js b/examples/javascript/hx711.js new file mode 100644 index 00000000..8393734c --- /dev/null +++ b/examples/javascript/hx711.js @@ -0,0 +1,36 @@ +/* +* +* Author: Rafael da Mata Neri +* 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 hx711 = require('jsupm_hx711'); +// Instantiate a HX711 data on digital pin D3 and clock on digital pin D2 +var scale = new hx711.HX711(3, 2); + +setTimeout(function(){ + // 2837: value obtained via calibration + scale.setScale(2837); + scale.tare(2); + setInterval(function(){ + console.log(scale.getUnits()); + }, 1000); +}, 1000); diff --git a/src/hx711/CMakeLists.txt b/src/hx711/CMakeLists.txt new file mode 100644 index 00000000..8cdf95e7 --- /dev/null +++ b/src/hx711/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "hx711") +set (libdescription "HX711 24bit ADC") +set (module_src ${libname}.cxx) +set (module_h ${libname}.h) +upm_module_init() diff --git a/src/hx711/hx711.cxx b/src/hx711/hx711.cxx new file mode 100644 index 00000000..01fb7893 --- /dev/null +++ b/src/hx711/hx711.cxx @@ -0,0 +1,148 @@ +/* +* +* Author: Rafael da Mata Neri +* 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 +#include +#include "hx711.h" + +using namespace upm; +using namespace std; + +struct HX711Exception : public std::exception { + std::string message; + HX711Exception (std::string msg) : message (msg) { } + ~HX711Exception () throw () { } + const char* what() const throw () { return message.c_str(); } +}; + +HX711::HX711(uint8_t data, uint8_t sck, uint8_t gain) { + mraa_result_t error = MRAA_SUCCESS; + + this->m_dataPinCtx = mraa_gpio_init(data); + if (this->m_dataPinCtx == NULL) { + throw HX711Exception ("Couldn't initilize DATA pin."); + } + + this->m_sckPinCtx = mraa_gpio_init(sck); + if (this->m_sckPinCtx == NULL) { + throw HX711Exception ("Couldn't initilize CLOCK pin."); + } + + error = mraa_gpio_dir (this->m_dataPinCtx, MRAA_GPIO_IN); + if (error != MRAA_SUCCESS) { + throw HX711Exception ("Couldn't set direction for DATA pin."); + } + + error = mraa_gpio_dir (this->m_sckPinCtx, MRAA_GPIO_OUT); + if (error != MRAA_SUCCESS) { + throw HX711Exception ("Couldn't set direction for CLOCK pin."); + } + + this->setGain(gain); +} + +HX711::~HX711() { + mraa_result_t error = MRAA_SUCCESS; + + error = mraa_gpio_close (this->m_dataPinCtx); + if (error != MRAA_SUCCESS) { + mraa_result_print(error); + } + + error = mraa_gpio_close (this->m_sckPinCtx); + if (error != MRAA_SUCCESS) { + mraa_result_print(error); + } +} + +unsigned long HX711::read() { + unsigned long Count = 0; + + while (mraa_gpio_read(this->m_dataPinCtx)); + + for (int i=0; im_sckPinCtx, 1); + Count = Count << 1; + mraa_gpio_write(this->m_sckPinCtx, 0); + if(mraa_gpio_read(this->m_dataPinCtx)) + { + Count++; + } + } + + mraa_gpio_write(this->m_sckPinCtx, 1); + Count = Count ^ 0x800000; + mraa_gpio_write(this->m_sckPinCtx, 0); + + return (Count); +} + +void HX711::setGain(uint8_t gain){ + switch (gain) { + case 128: // channel A, gain factor 128 + GAIN = 24; + break; + case 64: // channel A, gain factor 64 + GAIN = 26; + break; + case 32: // channel B, gain factor 32 + GAIN = 25; + break; + } + + mraa_gpio_write(this->m_sckPinCtx, 0); + read(); +} + +unsigned long HX711::readAverage(uint8_t times){ + unsigned long sum = 0; + for (uint8_t i = 0; i < times; i++) { + sum += read(); + } + return sum / times; +} + +double HX711::getValue(uint8_t times){ + return readAverage(times) - OFFSET; +} + +float HX711::getUnits(uint8_t times){ + return getValue(times) / SCALE; +} + +void HX711::tare(uint8_t times){ + double sum = readAverage(times); + setOffset(sum); +} + +void HX711::setScale(float scale){ + SCALE = scale; +} + +void HX711::setOffset(long offset){ + OFFSET = offset; +} diff --git a/src/hx711/hx711.h b/src/hx711/hx711.h new file mode 100644 index 00000000..e061b073 --- /dev/null +++ b/src/hx711/hx711.h @@ -0,0 +1,135 @@ +/* +* +* Author: Rafael da Mata Neri +* 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 +#include + +namespace upm { + + /** + * @brief HX711 24bit ADC library + * @defgroup hx711 libupm-hx711 + */ + + /** + * @brief C++ API for HX711 + * + * [HX711](http://www.dfrobot.com/image/data/SEN0160/hx711_english.pdf) is + * a precision 24-bit analog- to-digital converter (ADC) designed for weigh + * scales and industrial control applications to interface directly with a + * bridge sensor. This module was tested on the Intel Galileo Gen2. + * + * @ingroup hx711 hx711 + * @snippet hx711.cxx Interesting + * @image html hx711.jpeg + */ + class HX711 { + public: + /** + * HX711 module constructor + * + * @param data define the data pin + * @param sck define the clock pin + * @param gain define the gain factor + * Valid values are 128 or 64 for channel A; channel B works with 32 gain factor only + */ + HX711(uint8_t data, uint8_t sck, uint8_t gain = 128); + + /** + * HX711 module Destructor + */ + ~HX711(); + + + /** + * Waits for the chip to be ready and returns a reading + * + * @return raw adc read + */ + unsigned long read(); + + /** + * Set the gain factor; takes effect only after a call to read() + * channel A can be set for a 128 or 64 gain; channel B has a fixed 32 gain + * depending on the parameter, the channel is also set to either A or B + * @param gain define the gain factor + */ + void setGain(uint8_t gain = 128); + + /** + * Returns an average reading + * @param times define how many times to read + * @return the avarage reading + */ + unsigned long readAverage(uint8_t times = 10); + + /** + * Returns (readAverage() - OFFSET) + * @param times define how many readings to do + * @return the current value without the tare weight + */ + double getValue(uint8_t times = 10); + + /** + * Returns getValue() divided by SCALE + * @param times define how many readings to do + * @return the raw value divided by a value obtained via calibration + */ + float getUnits(uint8_t times = 1); + + /** + * Set the OFFSET value for tare weight + * @param times define how many times to read the tare value + */ + void tare(uint8_t times = 10); + + /** + * Set the SCALE value + * This value is used to convert the raw data to "human readable" data (measure units) + * @param scale value obtained via calibration + */ + void setScale(float scale = 1.f); + private: + mraa_gpio_context m_sckPinCtx; // Power Down and Serial Clock Input Pin + mraa_gpio_context m_dataPinCtx; // Serial Data Output Pin + + uint8_t GAIN; // amplification factor + unsigned long OFFSET; // used for tare weight + float SCALE; // used to return weight in grams, kg, ounces, whatever + + + /** + * Set the OFFSET value + * The value that's subtracted from the actual reading (tare weight) + * @param scale value obtained via calibration + */ + void setOffset(long offset = 0); + }; + +} diff --git a/src/hx711/jsupm_hx711.i b/src/hx711/jsupm_hx711.i new file mode 100644 index 00000000..ff8ec950 --- /dev/null +++ b/src/hx711/jsupm_hx711.i @@ -0,0 +1,10 @@ +//! [Interesting] +%module jsupm_hx711 +%include "../upm.i" + +%{ + #include "hx711.h" +%} + +%include "hx711.h" +//! [Interesting] diff --git a/src/hx711/pyupm_hx711.i b/src/hx711/pyupm_hx711.i new file mode 100644 index 00000000..7d8c7d7e --- /dev/null +++ b/src/hx711/pyupm_hx711.i @@ -0,0 +1,10 @@ +%module pyupm_hx711 +%include "../upm.i" +%include "stdint.i" + +%feature("autodoc", "3"); + +%include "hx711.h" +%{ + #include "hx711.h" +%}