diff --git a/docs/images/adxl345.jpeg b/docs/images/adxl345.jpeg new file mode 100644 index 00000000..66262a8f Binary files /dev/null and b/docs/images/adxl345.jpeg differ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9a2bb67f..43cab59e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -77,6 +77,7 @@ add_executable (biss0001-example biss0001.cxx) add_executable (my9221-example my9221.cxx) add_executable (grove_mcfled-example grove_mcfled.cxx) add_executable (rotaryencoder-example rotaryencoder.cxx) +add_executable (adxl345-example adxl345.cxx) include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l) include_directories (${PROJECT_SOURCE_DIR}/src/grove) @@ -140,6 +141,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/rfr359f) include_directories (${PROJECT_SOURCE_DIR}/src/biss0001) include_directories (${PROJECT_SOURCE_DIR}/src/my9221) include_directories (${PROJECT_SOURCE_DIR}/src/rotaryencoder) +include_directories (${PROJECT_SOURCE_DIR}/src/adxl345) target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT}) @@ -220,3 +222,4 @@ target_link_libraries (biss0001-example biss0001 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (my9221-example my9221 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (grove_mcfled-example grove ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (rotaryencoder-example rotaryencoder ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (adxl345-example adxl345 ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/adxl345.cxx b/examples/adxl345.cxx new file mode 100644 index 00000000..a5bc2cc5 --- /dev/null +++ b/examples/adxl345.cxx @@ -0,0 +1,51 @@ +/* + * Author: Mihai Tudor Panu + * Copyright (c) 2014 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 "adxl345.h" + +int +main(int argc, char **argv) +{ +//! [Interesting] + int16_t *raw; + float *acc; + + // Note: Sensor only works at 3.3V on the Intel Edison with Arduino breakout + upm::Adxl345* accel = new upm::Adxl345(0); + + while(true){ + accel->update(); // Update the data + raw = accel->getRawValues(); // Read raw sensor data + acc = accel->getAcceleration(); // Read acceleration (g) + fprintf(stdout, "Current scale: 0x%2xg\n", accel->getScale()); + fprintf(stdout, "Raw: %6d %6d %6d\n", raw[0], raw[1], raw[2]); + fprintf(stdout, "AccX: %5.2f g\n", acc[0]); + fprintf(stdout, "AccY: %5.2f g\n", acc[1]); + fprintf(stdout, "AccZ: %5.2f g\n", acc[2]); + sleep(1); + } +//! [Interesting] + return 0; +} diff --git a/examples/javascript/adxl345.js b/examples/javascript/adxl345.js new file mode 100644 index 00000000..d03d1f43 --- /dev/null +++ b/examples/javascript/adxl345.js @@ -0,0 +1,41 @@ +/* +* Author: Mihai Tudor Panu +* 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. +*/ + +// Load accelerometer +var adxl345 = require('jsupm_adxl345'); + +// Instantiate on I2C bus +var adxl = new adxl345.Adxl345(0); + +setInterval(function() +{ + adxl.update(); // Update the data + var raw = adxl.getRawValues(); // Read raw sensor data + var force = adxl.getAcceleration(); // Read acceleration force (g) + var rawvalues = raw.getitem(0) + " " + raw.getitem(1) + " " + raw.getitem(2); + console.log("Raw Values: " + rawvalues); + console.log("ForceX: " + force.getitem(0).toFixed(2) + " g"); + console.log("ForceY: " + force.getitem(1).toFixed(2) + " g"); + console.log("ForceZ: " + force.getitem(2).toFixed(2) + " g"); +}, 1000); diff --git a/examples/python/adxl345.py b/examples/python/adxl345.py new file mode 100644 index 00000000..d19110ad --- /dev/null +++ b/examples/python/adxl345.py @@ -0,0 +1,41 @@ +# Author: Mihai Tudor Panu +# Copyright (c) 2014 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. + +from time import sleep +import pyupm_adxl345 as adxl345 + +# Create an I2C accelerometer object +adxl = adxl345.Adxl345(0) + +# Loop indefinitely +while True: + + adxl.update() # Update the data + raw = adxl.getRawValues() # Read raw sensor data + force = adxl.getAcceleration() # Read acceleration force (g) + print "Raw: %6d %6d %6d" % (raw[0], raw[1], raw[2]) + print "ForceX: %5.2f g" % (force[0]) + print "ForceY: %5.2f g" % (force[1]) + print "ForceZ: %5.2f g\n" % (force[2]) + + # Sleep for 1 s + sleep(1) diff --git a/src/adxl345/CMakeLists.txt b/src/adxl345/CMakeLists.txt new file mode 100644 index 00000000..9f192281 --- /dev/null +++ b/src/adxl345/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "adxl345") +set (libdescription "libupm Digital Accelerometer") +set (module_src ${libname}.cxx) +set (module_h ${libname}.h) +upm_module_init() diff --git a/src/adxl345/adxl345.cxx b/src/adxl345/adxl345.cxx new file mode 100644 index 00000000..4ebddcae --- /dev/null +++ b/src/adxl345/adxl345.cxx @@ -0,0 +1,164 @@ +/* + * Author: Mihai Tudor Panu + * Copyright (c) 2014 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 "math.h" +#include "adxl345.h" + +#define READ_BUFFER_LENGTH 6 + +//address and id +#define ADXL345_I2C_ADDR 0x53 +#define ADXL345_ID 0x00 + +//control registers +#define ADXL345_OFSX 0x1E +#define ADXL345_OFSY 0x1F +#define ADXL345_OFSZ 0x20 +#define ADXL345_TAP_THRESH 0x1D +#define ADXL345_TAP_DUR 0x21 +#define ADXL345_TAP_LATENCY 0x22 +#define ADXL345_ACT_THRESH 0x24 +#define ADXL345_INACT_THRESH 0x25 +#define ADXL345_INACT_TIME 0x26 +#define ADXL345_INACT_ACT_CTL 0x27 +#define ADXL345_FALL_THRESH 0x28 +#define ADXL345_FALL_TIME 0x29 +#define ADXL345_TAP_AXES 0x2A +#define ADXL345_ACT_TAP_STATUS 0x2B + +//interrupt registers +#define ADXL345_INT_ENABLE 0x2E +#define ADXL345_INT_MAP 0x2F +#define ADXL345_INT_SOURCE 0x30 + +//data registers (read only) +#define ADXL345_XOUT_L 0x32 +#define ADXL345_XOUT_H 0x33 +#define ADXL345_YOUT_L 0x34 +#define ADXL345_YOUT_H 0x35 +#define ADXL345_ZOUT_L 0x36 +#define ADXL345_ZOUT_H 0x37 +#define DATA_REG_SIZE 6 + +//data and power management +#define ADXL345_BW_RATE 0x2C +#define ADXL345_POWER_CTL 0x2D +#define ADXL345_DATA_FORMAT 0x31 +#define ADXL345_FIFO_CTL 0x38 +#define ADXL345_FIFO_STATUS 0x39 + +//useful values +#define ADXL345_POWER_ON 0x08 +#define ADXL345_AUTO_SLP 0x30 +#define ADXL345_STANDBY 0x00 + +//scales and resolution +#define ADXL345_FULL_RES 0x08 +#define ADXL345_10BIT 0x00 +#define ADXL345_2G 0x00 +#define ADXL345_4G 0x01 +#define ADXL345_8G 0x02 +#define ADXL345_16G 0x03 + +using namespace upm; + +Adxl345::Adxl345(int bus) +{ + //init bus and reset chip + m_i2c = mraa_i2c_init(bus); + + mraa_i2c_address(m_i2c, ADXL345_I2C_ADDR); + m_buffer[0] = ADXL345_POWER_CTL; + m_buffer[1] = ADXL345_POWER_ON; + mraa_i2c_write(m_i2c, m_buffer, 2); + + mraa_i2c_address(m_i2c, ADXL345_I2C_ADDR); + m_buffer[0] = ADXL345_DATA_FORMAT; + m_buffer[1] = ADXL345_16G | ADXL345_FULL_RES; + mraa_i2c_write(m_i2c, m_buffer, 2); + + //2.5V sensitivity is 256 LSB/g = 0.00390625 g/bit + //3.3V x and y sensitivity is 265 LSB/g = 0.003773584 g/bit, z is the same + + m_offsets[0] = 0.003773584; + m_offsets[1] = 0.003773584; + m_offsets[2] = 0.00390625; + + Adxl345::update(); +} + +Adxl345::~Adxl345() +{ + mraa_i2c_stop(m_i2c); +} + +float* +Adxl345::getAcceleration() +{ + for(int i = 0; i < 3; i++){ + m_accel[i] = m_rawaccel[i] * m_offsets[i]; + } + return &m_accel[0]; +} + +int16_t* +Adxl345::getRawValues() +{ + return &m_rawaccel[0]; +} + +uint8_t +Adxl345::getScale(){ + + uint8_t result; + + mraa_i2c_address(m_i2c, ADXL345_I2C_ADDR); + mraa_i2c_write_byte(m_i2c, ADXL345_DATA_FORMAT); + + mraa_i2c_address(m_i2c, ADXL345_I2C_ADDR); + result = mraa_i2c_read_byte(m_i2c); + + return pow(2, (result & 0x03) + 1); +} + +mraa_result_t +Adxl345::update(void) +{ + mraa_i2c_address(m_i2c, ADXL345_I2C_ADDR); + mraa_i2c_write_byte(m_i2c, ADXL345_XOUT_L); + + mraa_i2c_address(m_i2c, ADXL345_I2C_ADDR); + mraa_i2c_read(m_i2c, m_buffer, DATA_REG_SIZE); + + // x + m_rawaccel[0] = ((m_buffer[1] << 8 ) | m_buffer[0]); + // y + m_rawaccel[1] = ((m_buffer[3] << 8 ) | m_buffer[2]); + // z + m_rawaccel[2] = ((m_buffer[5] << 8 ) | m_buffer[4]); + + return MRAA_SUCCESS; +} diff --git a/src/adxl345/adxl345.h b/src/adxl345/adxl345.h new file mode 100644 index 00000000..6a6d60b6 --- /dev/null +++ b/src/adxl345/adxl345.h @@ -0,0 +1,99 @@ +/* + * Author: Mihai Tudor Panu + * Copyright (c) 2014 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 + +#define READ_BUFFER_LENGTH 6 + +namespace upm { + +/** + * @brief Adxl345 accelerometer library + * @defgroup adxl345 libupm-adxl345 + */ + +/** + * @brief C++ API for Adxl345 (3-axis digital accelerometer) + * + * The Adxl345 is a 3-axis digital accelerometer. + * (http://www.seeedstudio.com/wiki/images/2/2c/ADXL345_datasheet.pdf) + * The sensor has configurable resolutions for measuring ±2g, ±4g, ±8g or ±16g. + * Note that the sensor it is incompatible and will not be detected on the I2C bus + * by the Intel Edison using the Arduino breakout board at 5V (3V3 will work fine). + * + * @ingroup adxl345 i2c + * @snippet adxl345.cxx Interesting + * @image html adxl345.jpeg + */ +class Adxl345 { +public: + /** + * Creates an Adxl345 object + * + * @param bus number of used i2c bus + */ + Adxl345(int bus); + + /** + * Adxl345 object destructor + */ + ~Adxl345(); + + /** + * Returns a pointer to a float[3] that contains acceleration (g) forces + * + * @return float* to a float[3] + */ + float* getAcceleration(); + + /** + * Returns a pointer to an int[3] that contains the raw register values for X, Y and Z + * + * @return int* to an int[3] + */ + int16_t* getRawValues(); + + /** + * Returns the scale the accelerometer is currently set up to: 2, 4, 8 or 16 + * + * @return uint with current scale value + */ + uint8_t getScale(); + + /** + * Updates the acceleration values from i2c bus + * + * @return 0 for success + */ + mraa_result_t update(); +private: + float m_accel[3]; + float m_offsets[3]; + int16_t m_rawaccel[3]; + uint8_t m_buffer[READ_BUFFER_LENGTH]; + mraa_i2c_context m_i2c; +}; + +} diff --git a/src/adxl345/jsupm_adxl345.i b/src/adxl345/jsupm_adxl345.i new file mode 100644 index 00000000..6f72b795 --- /dev/null +++ b/src/adxl345/jsupm_adxl345.i @@ -0,0 +1,20 @@ +%module jsupm_adxl345 +%include "../upm.i" +%include "../carrays_int16_t.i" +%include "../carrays_float.i" + +%{ + #include "adxl345.h" +%} + +%typemap(out) int16_t * { + $result = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int16Array, 0 | 0 ); +} + +%typemap(out) float * { + $result = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_floatArray, 0 | 0 ); +} + +%include "adxl345.h" + +%include diff --git a/src/adxl345/pyupm_adxl345.i b/src/adxl345/pyupm_adxl345.i new file mode 100644 index 00000000..033a8d30 --- /dev/null +++ b/src/adxl345/pyupm_adxl345.i @@ -0,0 +1,23 @@ +%module pyupm_adxl345 +%include "../upm.i" +%include "../carrays_int16_t.i" +%include "../carrays_float.i" + +%typemap(out) int16_t * { + $result = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int16Array, 0 | 0 ); +} + +%typemap(out) float * { + $result = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_floatArray, 0 | 0 ); +} + +%feature("autodoc", "3"); + +#ifdef DOXYGEN +%include "adxl345_doc.i" +#endif + +%include "adxl345.h" +%{ + #include "adxl345.h" +%}