diff --git a/docs/images/itg3200.jpeg b/docs/images/itg3200.jpeg new file mode 100644 index 00000000..ed5a435f Binary files /dev/null and b/docs/images/itg3200.jpeg differ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 6d0aa2f0..74f2cc1b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -48,6 +48,7 @@ add_executable (htu21d-example htu21d.cxx) add_executable (mpl3115a2-example mpl3115a2.cxx) add_executable (ldt0028-example ldt0028.cxx) add_executable (am2315-example am2315.cxx) +add_executable (itg3200-example itg3200.cxx) include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l) include_directories (${PROJECT_SOURCE_DIR}/src/grove) @@ -85,6 +86,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/htu21d) include_directories (${PROJECT_SOURCE_DIR}/src/mpl3115a2) include_directories (${PROJECT_SOURCE_DIR}/src/ldt0028) include_directories (${PROJECT_SOURCE_DIR}/src/am2315) +include_directories (${PROJECT_SOURCE_DIR}/src/itg3200) target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT}) @@ -136,3 +138,4 @@ target_link_libraries (htu21d-example htu21d ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (mpl3115a2-example mpl3115a2 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (ldt0028-example ldt0028 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (am2315-example am2315 ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (itg3200-example itg3200 ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/itg3200.cxx b/examples/itg3200.cxx new file mode 100644 index 00000000..7a70e094 --- /dev/null +++ b/examples/itg3200.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 "itg3200.h" + +int +main(int argc, char **argv) +{ +//! [Interesting] + int16_t *rot; + float *ang; + + // Note: Sensor not supported on Intel Edison with Arduino breakout + upm::Itg3200* gyro = new upm::Itg3200(0); + + while(true){ + gyro->update(); // Update the data + rot = gyro->getRawValues(); // Read raw sensor data + ang = gyro->getRotation(); // Read rotational speed (deg/sec) + fprintf(stdout, "Raw: %6d %6d %6d\n", rot[0], rot[1], rot[2]); + fprintf(stdout, "AngX: %5.2f\n", ang[0]); + fprintf(stdout, "AngY: %5.2f\n", ang[1]); + fprintf(stdout, "AngZ: %5.2f\n", ang[2]); + fprintf(stdout, "Temp: %5.2f Raw: %6d\n", gyro->getTemperature(), gyro->getRawTemp()); + sleep(1); + } +//! [Interesting] + return 0; +} diff --git a/src/itg3200/CMakeLists.txt b/src/itg3200/CMakeLists.txt new file mode 100644 index 00000000..5be008b8 --- /dev/null +++ b/src/itg3200/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "itg3200") +set (libdescription "libupm Digital Gyro") +set (module_src ${libname}.cxx) +set (module_h ${libname}.h) +upm_module_init() diff --git a/src/itg3200/itg3200.cxx b/src/itg3200/itg3200.cxx new file mode 100644 index 00000000..b60789ae --- /dev/null +++ b/src/itg3200/itg3200.cxx @@ -0,0 +1,155 @@ +/* + * 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 "itg3200.h" + +#define READ_BUFFER_LENGTH 8 + +//address and id +#define ITG3200_I2C_ADDR 0x68 +#define ITG3200_ID 0x00 + +//configuration registers +#define ITG3200_SMPLRT_DIV 0x15 +#define ITG3200_DLPF_FS 0x16 + +//interrupt registers +#define ITG3200_INT_CFG 0x17 +#define ITG3200_INT_STATUS 0x1A + +//data registers (read only) +#define ITG3200_TEMP_H 0x1B +#define ITG3200_TEMP_L 0x1C +#define ITG3200_XOUT_H 0x1D +#define ITG3200_XOUT_L 0x1E +#define ITG3200_YOUT_H 0x1F +#define ITG3200_YOUT_L 0x20 +#define ITG3200_ZOUT_H 0x21 +#define ITG3200_ZOUT_L 0x22 +#define DATA_REG_SIZE 8 + +//power management +#define ITG3200_PWR_MGM 0x3E + +//useful values +#define ITG3200_RESET 0x80 +#define ITG3200_SLEEP 0x40 +#define ITG3200_WAKEUP 0x00 + +using namespace upm; + +Itg3200::Itg3200(int bus) +{ + //init bus and reset chip + m_i2c = mraa_i2c_init(bus); + + mraa_i2c_address(m_i2c, ITG3200_I2C_ADDR); + m_buffer[0] = ITG3200_PWR_MGM; + m_buffer[1] = ITG3200_RESET; + mraa_i2c_write(m_i2c, m_buffer, 2); + + Itg3200::calibrate(); + Itg3200::update(); +} + +Itg3200::~Itg3200() +{ + mraa_i2c_stop(m_i2c); +} + +mraa_result_t +Itg3200::calibrate(void) +{ + int reads = 600; + int delay = 4000; // 4 milliseconds + int skip = 5; // initial samples to skip + int temp[3] = {0}; + + for(int i = 0; i < reads; i++){ + + Itg3200::update(); + if (i > skip){ + for (int j = 0; j < 3; j++){ + temp[j] += m_rotation[j]; + } + } + usleep(delay); + } + + for(int i = 0; i < 3; i++){ + m_offsets[i] = (-1) * temp[i] / (reads - skip); + } +} + +float +Itg3200::getTemperature() +{ + return 35.0 + (m_temperature + 13200.0) / 280.0; +} + +float* +Itg3200::getRotation() +{ + for(int i = 0; i < 3; i++){ + m_angle[i] = m_rotation[i]/14.375; + } + return &m_angle[0]; +} + +int16_t* +Itg3200::getRawValues() +{ + return &m_rotation[0]; +} + +int16_t +Itg3200::getRawTemp() +{ + return m_temperature; +} + +mraa_result_t +Itg3200::update(void) +{ + mraa_i2c_address(m_i2c, ITG3200_I2C_ADDR); + mraa_i2c_write_byte(m_i2c, ITG3200_TEMP_H); + + mraa_i2c_address(m_i2c, ITG3200_I2C_ADDR); + mraa_i2c_read(m_i2c, m_buffer, DATA_REG_SIZE); + + //temp + // + m_temperature = (m_buffer[0] << 8 ) | m_buffer[1]; + // x + m_rotation[0] = ((m_buffer[2] << 8 ) | m_buffer[3]) + m_offsets[0]; + // y + m_rotation[1] = ((m_buffer[4] << 8 ) | m_buffer[5]) + m_offsets[1]; + // z + m_rotation[2] = ((m_buffer[6] << 8 ) | m_buffer[7]) + m_offsets[2]; + + return MRAA_SUCCESS; +} diff --git a/src/itg3200/itg3200.h b/src/itg3200/itg3200.h new file mode 100644 index 00000000..c6cf641c --- /dev/null +++ b/src/itg3200/itg3200.h @@ -0,0 +1,115 @@ +/* + * 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 8 + +namespace upm { + +/** + * @brief Itg3200 gyroscope library + * @defgroup itg3200 libupm-itg3200 + */ + +/** + * @brief C++ API for Itg3200 (3-axis digital gyroscope) + * + * The InvenSense Itg3200 is a 3-axis digital gyroscope. + * (https://www.sparkfun.com/datasheets/Sensors/Gyro/PS-ITG-3200-00-01.4.pdf) + * This sensor has been tested and can run at either 3V3 or 5V on the Intel Galileo.
+ * However, it is incompatible and will not be detected on the I2C bus + * by the Intel Edison using the Arduino breakout board. + * + * @ingroup itg3200 i2c + * @snippet itg3200.cxx Interesting + * @image html itg3200.jpeg + */ +class Itg3200 { +public: + /** + * Creates an Itg3200 object + * + * @param bus number of used i2c bus + */ + Itg3200(int bus); + + /** + * Itg3200 object destructor + */ + ~Itg3200(); + + /** + * Calibrates the sensor to 0 on all axes. Sensor needs to be resting for accurate calibration. + * Takes about 3 seconds and is also called by constructor on object creation. + * + * @return 0 for successful calibration + */ + mraa_result_t calibrate(); + + /** + * Returns the temperature reading from the integrated temperature sensor in Celsius degrees + * + * @return float temperature in Celsius degrees + */ + float getTemperature(); + + /** + * Returns a pointer to an float[3] that contains computed rotational speeds (angular velocities) + * + * @return float* to an float[3] + */ + float* getRotation(); + + /** + * 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 an int that contains the raw register value for the temperature + * + * @return int raw temperature + */ + int16_t getRawTemp(); + + /** + * Updates the rotational values and temperature by reading from i2c bus + * + * @return 0 for success + */ + mraa_result_t update(); +private: + float m_angle[3]; + int16_t m_rotation[3]; + int16_t m_offsets[3]; + int16_t m_temperature; + uint8_t m_buffer[READ_BUFFER_LENGTH]; + mraa_i2c_context m_i2c; +}; + +} diff --git a/src/itg3200/jsupm_itg3200.i b/src/itg3200/jsupm_itg3200.i new file mode 100644 index 00000000..528c4dca --- /dev/null +++ b/src/itg3200/jsupm_itg3200.i @@ -0,0 +1,10 @@ +%module jsupm_itg3200 +%include "../upm.i" + +%{ + #include "itg3200.h" +%} + +%include "itg3200.h" + +%include diff --git a/src/itg3200/pyupm_itg3200.i b/src/itg3200/pyupm_itg3200.i new file mode 100644 index 00000000..08aff43c --- /dev/null +++ b/src/itg3200/pyupm_itg3200.i @@ -0,0 +1,13 @@ +%module pyupm_itg3200 +%include "../upm.i" + +%feature("autodoc", "3"); + +#ifdef DOXYGEN +%include "itg3200_doc.i" +#endif + +%include "itg3200.h" +%{ + #include "itg3200.h" +%}