mirror of
https://github.com/eclipse/upm.git
synced 2025-03-15 04:57:30 +03:00
lsm9ds0: Initial implementation
This module implements support for the LSM9DS0 accelerometer, magnetometer, and gyroscope. It was developed on the Sparkfun 9DOF sensor block for Intel Edison. https://www.sparkfun.com/products/13033 Commonly used capabilities are supported, and methods/register definitions exist to easily implement any desired functionality that is missing. Interrupt support has also been added. Signed-off-by: Jon Trulson <jtrulson@ics.com> Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
parent
03e72e02f8
commit
36b0e1dce0
@ -131,6 +131,7 @@ add_executable (pn532-writeurl-example pn532-writeurl.cxx)
|
||||
add_executable (sainsmartks-example sainsmartks.cxx)
|
||||
add_executable (mpu60x0-example mpu60x0.cxx)
|
||||
add_executable (ak8975-example ak8975.cxx)
|
||||
add_executable (lsm9ds0-example lsm9ds0.cxx)
|
||||
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/grove)
|
||||
@ -236,6 +237,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/grovecircularled)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/rgbringcoder)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/hp20x)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/pn532)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/lsm9ds0)
|
||||
|
||||
target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT})
|
||||
@ -368,3 +370,4 @@ target_link_libraries (pn532-writeurl-example pn532 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (sainsmartks-example i2clcd ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (mpu60x0-example mpu9150 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (ak8975-example mpu9150 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (lsm9ds0-example lsm9ds0 ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
83
examples/c++/lsm9ds0.cxx
Normal file
83
examples/c++/lsm9ds0.cxx
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* 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 <unistd.h>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include "lsm9ds0.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int shouldRun = true;
|
||||
|
||||
void sig_handler(int signo)
|
||||
{
|
||||
if (signo == SIGINT)
|
||||
shouldRun = false;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
signal(SIGINT, sig_handler);
|
||||
//! [Interesting]
|
||||
|
||||
// Instantiate an LSM9DS0 using default parameters (bus 1, gyro addr 6b,
|
||||
// xm addr 1d)
|
||||
upm::LSM9DS0 *sensor = new upm::LSM9DS0();
|
||||
|
||||
sensor->init();
|
||||
|
||||
while (shouldRun)
|
||||
{
|
||||
sensor->update();
|
||||
|
||||
float x, y, z;
|
||||
|
||||
sensor->getAccelerometer(&x, &y, &z);
|
||||
cout << "Accelerometer: ";
|
||||
cout << "AX: " << x << " AY: " << y << " AZ: " << z << endl;
|
||||
|
||||
sensor->getGyroscope(&x, &y, &z);
|
||||
cout << "Gryoscope: ";
|
||||
cout << "GX: " << x << " GY: " << y << " GZ: " << z << endl;
|
||||
|
||||
sensor->getMagnetometer(&x, &y, &z);
|
||||
cout << "Magnetometer: ";
|
||||
cout << "MX = " << x << " MY = " << y << " MZ = " << z << endl;
|
||||
|
||||
cout << "Temperature: " << sensor->getTemperature() << endl;
|
||||
cout << endl;
|
||||
|
||||
usleep(500000);
|
||||
}
|
||||
|
||||
//! [Interesting]
|
||||
|
||||
cout << "Exiting..." << endl;
|
||||
|
||||
delete sensor;
|
||||
|
||||
return 0;
|
||||
}
|
77
examples/javascript/lsm9ds0.js
Normal file
77
examples/javascript/lsm9ds0.js
Normal file
@ -0,0 +1,77 @@
|
||||
/*jslint node:true, vars:true, bitwise:true, unparam:true */
|
||||
/*jshint unused:true */
|
||||
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* 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 sensorObj = require('jsupm_lsm9ds0');
|
||||
|
||||
// Instantiate an LSM9DS0 using default parameters (bus 1, gyro addr 6b,
|
||||
// xm addr 1d)
|
||||
var sensor = new sensorObj.LSM9DS0();
|
||||
|
||||
// Initialize the device with default values
|
||||
sensor.init();
|
||||
|
||||
var x = new sensorObj.new_floatp();
|
||||
var y = new sensorObj.new_floatp();
|
||||
var z = new sensorObj.new_floatp();
|
||||
|
||||
// Output data every half second until interrupted
|
||||
setInterval(function()
|
||||
{
|
||||
sensor.update();
|
||||
|
||||
sensor.getAccelerometer(x, y, z);
|
||||
console.log("Accelerometer: AX: " + sensorObj.floatp_value(x) +
|
||||
" AY: " + sensorObj.floatp_value(y) +
|
||||
" AZ: " + sensorObj.floatp_value(z));
|
||||
|
||||
sensor.getGyroscope(x, y, z);
|
||||
console.log("Gyroscope: GX: " + sensorObj.floatp_value(x) +
|
||||
" AY: " + sensorObj.floatp_value(y) +
|
||||
" AZ: " + sensorObj.floatp_value(z));
|
||||
|
||||
sensor.getMagnetometer(x, y, z);
|
||||
console.log("Magnetometer: MX: " + sensorObj.floatp_value(x) +
|
||||
" MY: " + sensorObj.floatp_value(y) +
|
||||
" MZ: " + sensorObj.floatp_value(z));
|
||||
|
||||
console.log("Temperature: " + sensor.getTemperature());
|
||||
|
||||
console.log();
|
||||
|
||||
}, 500);
|
||||
|
||||
// exit on ^C
|
||||
process.on('SIGINT', function()
|
||||
{
|
||||
sensor = null;
|
||||
sensorObj.cleanUp();
|
||||
sensorObj = null;
|
||||
console.log("Exiting.");
|
||||
process.exit(0);
|
||||
});
|
||||
|
71
examples/python/lsm9ds0.py
Normal file
71
examples/python/lsm9ds0.py
Normal file
@ -0,0 +1,71 @@
|
||||
#!/usr/bin/python
|
||||
# Author: Jon Trulson <jtrulson@ics.com>
|
||||
# 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.
|
||||
|
||||
import time, sys, signal, atexit
|
||||
import pyupm_lsm9ds0 as sensorObj
|
||||
|
||||
# Instantiate an LSM9DS0 using default parameters (bus 1, gyro addr 6b,
|
||||
# xm addr 1d)
|
||||
sensor = sensorObj.LSM9DS0()
|
||||
|
||||
## 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)
|
||||
|
||||
sensor.init()
|
||||
|
||||
x = sensorObj.new_floatp()
|
||||
y = sensorObj.new_floatp()
|
||||
z = sensorObj.new_floatp()
|
||||
|
||||
while (1):
|
||||
sensor.update()
|
||||
sensor.getAccelerometer(x, y, z)
|
||||
print "Accelerometer: AX: ", sensorObj.floatp_value(x),
|
||||
print " AY: ", sensorObj.floatp_value(y),
|
||||
print " AZ: ", sensorObj.floatp_value(z)
|
||||
|
||||
sensor.getGyroscope(x, y, z)
|
||||
print "Gyroscope: GX: ", sensorObj.floatp_value(x),
|
||||
print " GY: ", sensorObj.floatp_value(y),
|
||||
print " GZ: ", sensorObj.floatp_value(z)
|
||||
|
||||
sensor.getMagnetometer(x, y, z)
|
||||
print "Magnetometer: MX: ", sensorObj.floatp_value(x),
|
||||
print " MY: ", sensorObj.floatp_value(y),
|
||||
print " MZ: ", sensorObj.floatp_value(z)
|
||||
|
||||
print "Temperature: ", sensor.getTemperature()
|
||||
print
|
||||
|
||||
time.sleep(.5)
|
5
src/lsm9ds0/CMakeLists.txt
Normal file
5
src/lsm9ds0/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
set (libname "lsm9ds0")
|
||||
set (libdescription "gyro, accelerometer and magnometer sensor based on lsm9ds0")
|
||||
set (module_src ${libname}.cxx)
|
||||
set (module_h ${libname}.h)
|
||||
upm_module_init()
|
11
src/lsm9ds0/jsupm_lsm9ds0.i
Normal file
11
src/lsm9ds0/jsupm_lsm9ds0.i
Normal file
@ -0,0 +1,11 @@
|
||||
%module jsupm_lsm9ds0
|
||||
%include "../upm.i"
|
||||
%include "cpointer.i"
|
||||
|
||||
%pointer_functions(float, floatp);
|
||||
|
||||
%include "lsm9ds0.h"
|
||||
%{
|
||||
#include "lsm9ds0.h"
|
||||
%}
|
||||
|
751
src/lsm9ds0/lsm9ds0.cxx
Normal file
751
src/lsm9ds0/lsm9ds0.cxx
Normal file
@ -0,0 +1,751 @@
|
||||
/*
|
||||
* Author: Jon Trulson <jtrulson@ics.com>
|
||||
* 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 <unistd.h>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <string.h>
|
||||
|
||||
#include "lsm9ds0.h"
|
||||
|
||||
using namespace upm;
|
||||
using namespace std;
|
||||
|
||||
|
||||
LSM9DS0::LSM9DS0(int bus, uint8_t gAddress, uint8_t xmAddress) :
|
||||
m_i2cG(bus), m_i2cXM(bus), m_gpioG_INT(0), m_gpioG_DRDY(0),
|
||||
m_gpioXM_GEN1(0), m_gpioXM_GEN2(0)
|
||||
{
|
||||
m_gAddr = gAddress;
|
||||
m_xmAddr = xmAddress;
|
||||
|
||||
m_accelX = 0.0;
|
||||
m_accelY = 0.0;
|
||||
m_accelZ = 0.0;
|
||||
|
||||
m_gyroX = 0.0;
|
||||
m_gyroY = 0.0;
|
||||
m_gyroZ = 0.0;
|
||||
|
||||
m_magX = 0.0;
|
||||
m_magY = 0.0;
|
||||
m_magZ = 0.0;
|
||||
|
||||
m_temp = 0.0;
|
||||
|
||||
m_accelScale = 0.0;
|
||||
m_gyroScale = 0.0;
|
||||
m_magScale = 0.0;
|
||||
|
||||
mraa_result_t rv;
|
||||
if ( (rv = m_i2cG.address(m_gAddr)) != MRAA_SUCCESS)
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Could not initialize Gyro i2c address."
|
||||
<< endl;
|
||||
mraa_result_print(rv);
|
||||
throw std::runtime_error(string(__FUNCTION__) +
|
||||
": Could not initialize Gyro i2c address");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (rv = m_i2cXM.address(m_xmAddr)) != MRAA_SUCCESS)
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Could not initialize XM i2c address. " << endl;
|
||||
mraa_result_print(rv);
|
||||
throw std::runtime_error(string(__FUNCTION__) +
|
||||
": Could not initialize XM i2c address");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LSM9DS0::~LSM9DS0()
|
||||
{
|
||||
uninstallISR(INTERRUPT_G_INT);
|
||||
uninstallISR(INTERRUPT_G_DRDY);
|
||||
uninstallISR(INTERRUPT_XM_GEN1);
|
||||
uninstallISR(INTERRUPT_XM_GEN2);
|
||||
}
|
||||
|
||||
bool LSM9DS0::init()
|
||||
{
|
||||
// Init the gyroscope
|
||||
|
||||
// power up
|
||||
if (!setGyroscopePowerDown(false))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to wake up gyro" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// enable all axes
|
||||
if (!setGyroscopeEnableAxes(CTRL_REG1_G_YEN |CTRL_REG1_G_XEN |
|
||||
CTRL_REG1_G_ZEN))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to enable gyro axes" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// set gyro ODR
|
||||
if (!setGyroscopeODR(G_ODR_95_25))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to set gyro ODR" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// set gyro scale
|
||||
if (!setGyroscopeScale(G_FS_245))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to set gyro scale" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Init the accelerometer
|
||||
|
||||
// power up and set ODR
|
||||
if (!setAccelerometerODR(XM_AODR_100))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to set accel ODR" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// enable all axes
|
||||
if (!setAccelerometerEnableAxes(CTRL_REG1_XM_AXEN |CTRL_REG1_XM_AYEN |
|
||||
CTRL_REG1_XM_AZEN))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to enable accel axes" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// set scaling rate
|
||||
if (!setAccelerometerScale(XM_AFS_2))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to set accel scale" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// temperature sensor
|
||||
|
||||
// enable the temperature sensor
|
||||
if (!enableTemperatureSensor(true))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to enable temp sensor" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Init the magnetometer
|
||||
|
||||
// set mode (this also powers it up if not XM_MD_POWERDOWN)
|
||||
if (!setMagnetometerMode(XM_MD_CONTINUOUS))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to set mag scale" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// turn LPM off
|
||||
if (!setMagnetometerLPM(false))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to disable mag LPM" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// set resolution
|
||||
if (!setMagnetometerResolution(XM_RES_LOW))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to set mag res" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// set ODR
|
||||
if (!setMagnetometerODR(XM_ODR_12_5))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to set mag ODR" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// set scale
|
||||
if (!setMagnetometerScale(XM_MFS_2))
|
||||
{
|
||||
cerr << __FUNCTION__ << ": Unable to set mag scale" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LSM9DS0::update()
|
||||
{
|
||||
updateGyroscope();
|
||||
updateAccelerometer();
|
||||
updateMagnetometer();
|
||||
updateTemperature();
|
||||
}
|
||||
|
||||
void LSM9DS0::updateGyroscope()
|
||||
{
|
||||
uint8_t buffer[6];
|
||||
|
||||
memset(buffer, 0, 6);
|
||||
readRegs(DEV_GYRO, REG_OUT_X_L_G, buffer, 6);
|
||||
|
||||
int16_t x, y, z;
|
||||
|
||||
x = ( (buffer[1] << 8) | buffer[0] );
|
||||
y = ( (buffer[3] << 8) | buffer[2] );
|
||||
z = ( (buffer[5] << 8) | buffer[4] );
|
||||
|
||||
m_gyroX = float(x);
|
||||
m_gyroY = float(y);
|
||||
m_gyroZ = float(z);
|
||||
}
|
||||
|
||||
void LSM9DS0::updateAccelerometer()
|
||||
{
|
||||
uint8_t buffer[6];
|
||||
|
||||
memset(buffer, 0, 6);
|
||||
readRegs(DEV_XM, REG_OUT_X_L_A, buffer, 6);
|
||||
|
||||
int16_t x, y, z;
|
||||
|
||||
x = ( (buffer[1] << 8) | buffer[0] );
|
||||
y = ( (buffer[3] << 8) | buffer[2] );
|
||||
z = ( (buffer[5] << 8) | buffer[4] );
|
||||
|
||||
m_accelX = float(x);
|
||||
m_accelY = float(y);
|
||||
m_accelZ = float(z);
|
||||
}
|
||||
|
||||
void LSM9DS0::updateMagnetometer()
|
||||
{
|
||||
uint8_t buffer[6];
|
||||
|
||||
memset(buffer, 0, 6);
|
||||
readRegs(DEV_XM, REG_OUT_X_L_M, buffer, 6);
|
||||
|
||||
int16_t x, y, z;
|
||||
|
||||
x = ( (buffer[1] << 8) | buffer[0] );
|
||||
y = ( (buffer[3] << 8) | buffer[2] );
|
||||
z = ( (buffer[5] << 8) | buffer[4] );
|
||||
|
||||
m_magX = float(x);
|
||||
m_magY = float(y);
|
||||
m_magZ = float(z);
|
||||
}
|
||||
|
||||
void LSM9DS0::updateTemperature()
|
||||
{
|
||||
uint8_t buffer[2];
|
||||
|
||||
memset(buffer, 0, 2);
|
||||
readRegs(DEV_XM, REG_OUT_TEMP_L_XM, buffer, 2);
|
||||
|
||||
// cerr << "HIGH: " << int(buffer[1]) << " LOW: " << int(buffer[0]) << endl;
|
||||
|
||||
// 12b signed
|
||||
int16_t temp = ( (buffer[1] << 8) | (buffer[0] ) );
|
||||
if (temp & 0x0800)
|
||||
{
|
||||
temp &= ~0x0800;
|
||||
temp *= -1;
|
||||
}
|
||||
|
||||
m_temp = float(temp);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::readReg(DEVICE_T dev, uint8_t reg)
|
||||
{
|
||||
mraa::I2c *device;
|
||||
|
||||
switch(dev)
|
||||
{
|
||||
case DEV_GYRO: device = &m_i2cG; break;
|
||||
case DEV_XM: device = &m_i2cXM; break;
|
||||
default:
|
||||
cerr << __FUNCTION__ << ": Internal error, invalid device" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return device->readReg(reg);
|
||||
}
|
||||
|
||||
void LSM9DS0::readRegs(DEVICE_T dev, uint8_t reg, uint8_t *buf, int len)
|
||||
{
|
||||
mraa::I2c *device;
|
||||
|
||||
switch(dev)
|
||||
{
|
||||
case DEV_GYRO: device = &m_i2cG; break;
|
||||
case DEV_XM: device = &m_i2cXM; break;
|
||||
default:
|
||||
cerr << __FUNCTION__ << ": Internal error, invalid device" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to set the high bit of the register to enable
|
||||
// auto-increment mode for reading multiple registers in one go.
|
||||
device->readBytesReg(reg | m_autoIncrementMode, buf, len);
|
||||
}
|
||||
|
||||
bool LSM9DS0::writeReg(DEVICE_T dev, uint8_t reg, uint8_t val)
|
||||
{
|
||||
mraa::I2c *device;
|
||||
|
||||
switch(dev)
|
||||
{
|
||||
case DEV_GYRO: device = &m_i2cG; break;
|
||||
case DEV_XM: device = &m_i2cXM; break;
|
||||
default:
|
||||
cerr << __FUNCTION__ << ": Internal error, invalid device" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
mraa_result_t rv;
|
||||
if ((rv = device->writeReg(reg, val)) != MRAA_SUCCESS)
|
||||
{
|
||||
cerr << __FUNCTION__ << ": failed:" << endl;
|
||||
mraa_result_print(rv);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LSM9DS0::setGyroscopePowerDown(bool enable)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG1_G);
|
||||
|
||||
if (enable)
|
||||
reg &= ~CTRL_REG1_G_PD;
|
||||
else
|
||||
reg |= CTRL_REG1_G_PD;
|
||||
|
||||
return writeReg(DEV_GYRO, REG_CTRL_REG1_G, reg);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setGyroscopeEnableAxes(uint8_t axes)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG1_G);
|
||||
|
||||
// filter out any non-axis related data from arg
|
||||
axes &= (CTRL_REG1_G_YEN | CTRL_REG1_G_XEN | CTRL_REG1_G_ZEN);
|
||||
|
||||
// clear them in the register
|
||||
reg &= ~(CTRL_REG1_G_YEN | CTRL_REG1_G_XEN | CTRL_REG1_G_ZEN);
|
||||
|
||||
// now add them
|
||||
reg |= axes;
|
||||
|
||||
return writeReg(DEV_GYRO, REG_CTRL_REG1_G, reg);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setGyroscopeODR(G_ODR_T odr)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG1_G);
|
||||
|
||||
reg &= ~(_CTRL_REG1_G_ODR_MASK << _CTRL_REG1_G_ODR_SHIFT);
|
||||
|
||||
reg |= (odr << _CTRL_REG1_G_ODR_SHIFT);
|
||||
|
||||
return writeReg(DEV_GYRO, REG_CTRL_REG1_G, reg);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setGyroscopeScale(G_FS_T scale)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_GYRO, REG_CTRL_REG4_G);
|
||||
|
||||
reg &= ~(_CTRL_REG4_G_FS_MASK << _CTRL_REG4_G_FS_SHIFT);
|
||||
|
||||
reg |= (scale << _CTRL_REG4_G_FS_SHIFT);
|
||||
|
||||
if (!writeReg(DEV_GYRO, REG_CTRL_REG4_G, reg))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// store scaling factor (mDeg/s/LSB)
|
||||
|
||||
switch (scale)
|
||||
{
|
||||
case G_FS_245:
|
||||
m_gyroScale = 8.75;
|
||||
break;
|
||||
|
||||
case G_FS_500:
|
||||
m_gyroScale = 17.5;
|
||||
break;
|
||||
|
||||
case G_FS_2000:
|
||||
m_gyroScale = 70.0;
|
||||
break;
|
||||
|
||||
default: // should never occur, but...
|
||||
m_gyroScale = 0.0; // set a safe, though incorrect value
|
||||
cerr << __FUNCTION__ << ": internal error, unsupported scale" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LSM9DS0::setAccelerometerEnableAxes(uint8_t axes)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG1_XM);
|
||||
|
||||
// filter out any non-axis related data from arg
|
||||
axes &= (CTRL_REG1_XM_AXEN | CTRL_REG1_XM_AYEN | CTRL_REG1_XM_AZEN);
|
||||
|
||||
// clear them in the register
|
||||
reg &= ~(CTRL_REG1_XM_AXEN | CTRL_REG1_XM_AYEN | CTRL_REG1_XM_AZEN);
|
||||
|
||||
// now add them
|
||||
reg |= axes;
|
||||
|
||||
return writeReg(DEV_XM, REG_CTRL_REG1_XM, reg);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setAccelerometerODR(XM_AODR_T odr)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG1_XM);
|
||||
|
||||
reg &= ~(_CTRL_REG1_XM_AODR_MASK << _CTRL_REG1_XM_AODR_SHIFT);
|
||||
|
||||
reg |= (odr << _CTRL_REG1_XM_AODR_SHIFT);
|
||||
|
||||
return writeReg(DEV_XM, REG_CTRL_REG1_XM, reg);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setAccelerometerScale(XM_AFS_T scale)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG2_XM);
|
||||
|
||||
reg &= ~(_CTRL_REG2_XM_AFS_MASK << _CTRL_REG2_XM_AFS_SHIFT);
|
||||
|
||||
reg |= (scale << _CTRL_REG2_XM_AFS_SHIFT);
|
||||
|
||||
if (!writeReg(DEV_XM, REG_CTRL_REG2_XM, reg))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// store scaling factor
|
||||
|
||||
switch (scale)
|
||||
{
|
||||
case XM_AFS_2:
|
||||
m_accelScale = 0.061;
|
||||
break;
|
||||
|
||||
case XM_AFS_4:
|
||||
m_accelScale = 0.122 ;
|
||||
break;
|
||||
|
||||
case XM_AFS_6:
|
||||
m_accelScale = 0.183 ;
|
||||
break;
|
||||
|
||||
case XM_AFS_8:
|
||||
m_accelScale = 0.244 ;
|
||||
break;
|
||||
|
||||
case XM_AFS_16:
|
||||
m_accelScale = 0.732 ;
|
||||
break;
|
||||
|
||||
default: // should never occur, but...
|
||||
m_accelScale = 0.0; // set a safe, though incorrect value
|
||||
cerr << __FUNCTION__ << ": internal error, unsupported scale" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LSM9DS0::setMagnetometerResolution(XM_RES_T res)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG5_XM);
|
||||
|
||||
reg &= ~(_CTRL_REG5_XM_RES_MASK << _CTRL_REG5_XM_RES_SHIFT);
|
||||
|
||||
reg |= (res << _CTRL_REG5_XM_RES_SHIFT);
|
||||
|
||||
return writeReg(DEV_XM, REG_CTRL_REG5_XM, reg);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setMagnetometerODR(XM_ODR_T odr)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG5_XM);
|
||||
|
||||
reg &= ~(_CTRL_REG5_XM_ODR_MASK << _CTRL_REG5_XM_ODR_SHIFT);
|
||||
|
||||
reg |= (odr << _CTRL_REG5_XM_ODR_SHIFT);
|
||||
|
||||
return writeReg(DEV_XM, REG_CTRL_REG5_XM, reg);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setMagnetometerMode(XM_MD_T mode)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG7_XM);
|
||||
|
||||
reg &= ~(_CTRL_REG7_XM_MD_MASK << _CTRL_REG7_XM_MD_SHIFT);
|
||||
|
||||
reg |= (mode << _CTRL_REG7_XM_MD_SHIFT);
|
||||
|
||||
return writeReg(DEV_XM, REG_CTRL_REG7_XM, reg);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setMagnetometerLPM(bool enable)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG7_XM);
|
||||
|
||||
if (enable)
|
||||
reg |= CTRL_REG7_XM_MLP;
|
||||
else
|
||||
reg &= ~CTRL_REG7_XM_MLP;
|
||||
|
||||
return writeReg(DEV_XM, REG_CTRL_REG7_XM, reg);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setMagnetometerScale(XM_MFS_T scale)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG6_XM);
|
||||
|
||||
reg &= ~(_CTRL_REG6_XM_MFS_MASK << _CTRL_REG6_XM_MFS_SHIFT);
|
||||
|
||||
reg |= (scale << _CTRL_REG6_XM_MFS_SHIFT);
|
||||
|
||||
if (!writeReg(DEV_XM, REG_CTRL_REG6_XM, reg))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// store scaling factor
|
||||
|
||||
switch (scale)
|
||||
{
|
||||
case XM_MFS_2:
|
||||
m_magScale = 0.08;
|
||||
break;
|
||||
|
||||
case XM_MFS_4:
|
||||
m_magScale = 0.16;
|
||||
break;
|
||||
|
||||
case XM_MFS_8:
|
||||
m_magScale = 0.32;
|
||||
break;
|
||||
|
||||
case XM_MFS_12:
|
||||
m_magScale = 0.48;
|
||||
break;
|
||||
|
||||
default: // should never occur, but...
|
||||
m_magScale = 0.0; // set a safe, though incorrect value
|
||||
cerr << __FUNCTION__ << ": internal error, unsupported scale" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LSM9DS0::getAccelerometer(float *x, float *y, float *z)
|
||||
{
|
||||
if (x)
|
||||
*x = (m_accelX * m_accelScale) / 1000.0;
|
||||
|
||||
if (y)
|
||||
*y = (m_accelY * m_accelScale) / 1000.0;
|
||||
|
||||
if (z)
|
||||
*z = (m_accelZ * m_accelScale) / 1000.0;
|
||||
}
|
||||
|
||||
void LSM9DS0::getGyroscope(float *x, float *y, float *z)
|
||||
{
|
||||
if (x)
|
||||
*x = (m_gyroX * m_gyroScale) / 1000.0;
|
||||
|
||||
if (y)
|
||||
*y = (m_gyroY * m_gyroScale) / 1000.0;
|
||||
|
||||
if (z)
|
||||
*z = (m_gyroZ * m_gyroScale) / 1000.0;
|
||||
}
|
||||
|
||||
void LSM9DS0::getMagnetometer(float *x, float *y, float *z)
|
||||
{
|
||||
if (x)
|
||||
*x = (m_magX * m_magScale) / 1000.0;
|
||||
|
||||
if (y)
|
||||
*y = (m_magY * m_magScale) / 1000.0;
|
||||
|
||||
if (z)
|
||||
*z = (m_magZ * m_magScale) / 1000.0;
|
||||
}
|
||||
|
||||
float LSM9DS0::getTemperature()
|
||||
{
|
||||
// This might be wrong... The datasheet does not provide enough info
|
||||
// to calculate the temperature given a specific sensor reading. So
|
||||
// - with 12b resolution, signed, and 8 degrees/per LSB, we come up
|
||||
// with the following. Then scale up and we get a number that seems
|
||||
// pretty close.
|
||||
return (((m_temp / 2048.0) * 8.0) * 100.0);
|
||||
}
|
||||
|
||||
bool LSM9DS0::enableTemperatureSensor(bool enable)
|
||||
{
|
||||
uint8_t reg = readReg(DEV_XM, REG_CTRL_REG5_XM);
|
||||
|
||||
if (enable)
|
||||
reg |= CTRL_REG5_XM_TEMP_EN;
|
||||
else
|
||||
reg &= ~CTRL_REG5_XM_TEMP_EN;
|
||||
|
||||
return writeReg(DEV_XM, REG_CTRL_REG5_XM, reg);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::getGyroscopeStatus()
|
||||
{
|
||||
return readReg(DEV_GYRO, REG_STATUS_REG_G);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::getMagnetometerStatus()
|
||||
{
|
||||
return readReg(DEV_XM, REG_STATUS_REG_M);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::getAccelerometerStatus()
|
||||
{
|
||||
return readReg(DEV_XM, REG_STATUS_REG_A);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::getGyroscopeInterruptConfig()
|
||||
{
|
||||
return readReg(DEV_GYRO, REG_INT1_CFG_G);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setGyroscopeInterruptConfig(uint8_t enables)
|
||||
{
|
||||
return writeReg(DEV_GYRO, REG_INT1_CFG_G, enables);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::getGyroscopeInterruptSrc()
|
||||
{
|
||||
return readReg(DEV_GYRO, REG_INT1_SRC_G);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::getMagnetometerInterruptControl()
|
||||
{
|
||||
return readReg(DEV_XM, REG_INT_CTRL_REG_M);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setMagnetometerInterruptControl(uint8_t enables)
|
||||
{
|
||||
return writeReg(DEV_XM, REG_INT_CTRL_REG_M, enables);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::getMagnetometerInterruptSrc()
|
||||
{
|
||||
return readReg(DEV_XM, REG_INT_SRC_REG_M);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::getInterruptGen1()
|
||||
{
|
||||
return readReg(DEV_XM, REG_INT_GEN_1_REG);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setInterruptGen1(uint8_t enables)
|
||||
{
|
||||
return writeReg(DEV_XM, REG_INT_GEN_1_REG, enables);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::getInterruptGen1Src()
|
||||
{
|
||||
return readReg(DEV_XM, REG_INT_GEN_1_SRC);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::getInterruptGen2()
|
||||
{
|
||||
return readReg(DEV_XM, REG_INT_GEN_2_REG);
|
||||
}
|
||||
|
||||
bool LSM9DS0::setInterruptGen2(uint8_t enables)
|
||||
{
|
||||
return writeReg(DEV_XM, REG_INT_GEN_2_REG, enables);
|
||||
}
|
||||
|
||||
uint8_t LSM9DS0::getInterruptGen2Src()
|
||||
{
|
||||
return readReg(DEV_XM, REG_INT_GEN_2_SRC);
|
||||
}
|
||||
|
||||
void LSM9DS0::installISR(INTERRUPT_PINS_T intr, int gpio, mraa::Edge level,
|
||||
void (*isr)(void *), void *arg)
|
||||
{
|
||||
// delete any existing ISR and GPIO context
|
||||
uninstallISR(intr);
|
||||
|
||||
// greate gpio context
|
||||
getPin(intr) = new mraa::Gpio(gpio);
|
||||
|
||||
getPin(intr)->dir(mraa::DIR_IN);
|
||||
getPin(intr)->isr(level, isr, arg);
|
||||
}
|
||||
|
||||
void LSM9DS0::uninstallISR(INTERRUPT_PINS_T intr)
|
||||
{
|
||||
if (getPin(intr))
|
||||
{
|
||||
getPin(intr)->isrExit();
|
||||
delete getPin(intr);
|
||||
|
||||
getPin(intr) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mraa::Gpio*& LSM9DS0::getPin(INTERRUPT_PINS_T intr)
|
||||
{
|
||||
switch(intr)
|
||||
{
|
||||
case INTERRUPT_G_INT:
|
||||
return m_gpioG_INT;
|
||||
break;
|
||||
case INTERRUPT_G_DRDY:
|
||||
return m_gpioG_DRDY;
|
||||
break;
|
||||
case INTERRUPT_XM_GEN1:
|
||||
return m_gpioXM_GEN1;
|
||||
break;
|
||||
case INTERRUPT_XM_GEN2:
|
||||
return m_gpioXM_GEN2;
|
||||
break;
|
||||
default:
|
||||
throw std::logic_error(string(__FUNCTION__) +
|
||||
": Invalid interrupt enum passed");
|
||||
}
|
||||
}
|
1452
src/lsm9ds0/lsm9ds0.h
Normal file
1452
src/lsm9ds0/lsm9ds0.h
Normal file
File diff suppressed because it is too large
Load Diff
15
src/lsm9ds0/pyupm_lsm9ds0.i
Normal file
15
src/lsm9ds0/pyupm_lsm9ds0.i
Normal file
@ -0,0 +1,15 @@
|
||||
%module pyupm_lsm9ds0
|
||||
%include "../upm.i"
|
||||
%include "cpointer.i"
|
||||
|
||||
%include "stdint.i"
|
||||
|
||||
%feature("autodoc", "3");
|
||||
|
||||
%pointer_functions(float, floatp);
|
||||
|
||||
%include "lsm9ds0.h"
|
||||
%{
|
||||
#include "lsm9ds0.h"
|
||||
%}
|
||||
|
Loading…
x
Reference in New Issue
Block a user