Files
2024-07-20 22:09:06 +08:00

938 lines
27 KiB
C++

/**************************************************************************/
/*!
@file MSA300.cpp
@mainpage MSA300 14-bit digital accelometer library
@section author Author
Joel Lavikainen
@section license License
BSD
@section intro_sec Introduction
Based on Adafruit Accelerometer library code
*/
/**************************************************************************/
#include "Arduino.h"
#include <Wire.h>
#include <limits.h>
#include "MSA300.h"
/**************************************************************************/
/*!
@brief Writes 8-bits to the specified destination register.
@param reg
Register address
@param value
Byte value to be written
*/
/**************************************************************************/
void MSA300::writeRegister(uint8_t reg, uint8_t value)
{
Wire.beginTransmission(MSA300_I2C_ADDRESS);
Wire.write((uint8_t)reg);
Wire.write((uint8_t)(value));
Wire.endTransmission();
}
/**************************************************************************/
/*!
@brief Reads 8-bits from the specified register
@param reg
Address of register
@return Reply byte
*/
/**************************************************************************/
uint8_t MSA300::readRegister(uint8_t reg)
{
Wire.beginTransmission(MSA300_I2C_ADDRESS);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(MSA300_I2C_ADDRESS, 1);
uint8_t data =Wire.read();
return data;
}
/**************************************************************************/
/*!
@brief Reads 16-bits from the specified register
@param reg
Register address
@return 16-bits of data
*/
/**************************************************************************/
int16_t MSA300::read16(uint8_t reg)
{
Wire.beginTransmission(MSA300_I2C_ADDRESS);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(MSA300_I2C_ADDRESS, 2);
return (uint16_t)(((Wire.read()&0xff) | (uint16_t)(Wire.read()&0xff) << 8));
}
/**************************************************************************/
/*!
@brief Read the part ID (can be used to check connection)
@return Part ID
*/
/**************************************************************************/
uint8_t MSA300::getPartID(void)
{
// Check device ID register
return readRegister(MSA300_REG_PARTID);
}
/**************************************************************************/
/*!
@brief Gets the most recent X axis value
@return X-axis acceleration data
*/
/**************************************************************************/
int16_t MSA300::getX(void)
{
int16_t temp = (readRegister(MSA300_REG_ACC_X_LSB) + (int8_t)(readRegister(MSA300_REG_ACC_X_MSB))*256)/4;
return temp;
}
/**************************************************************************/
/*!
@brief Gets the most recent Y axis value
@return Y-axis acceleration data
*/
/**************************************************************************/
int16_t MSA300::getY(void)
{
int16_t temp = (readRegister(MSA300_REG_ACC_Y_LSB) + (int8_t)(readRegister(MSA300_REG_ACC_Y_MSB))*256)/4;
return temp;
}
/**************************************************************************/
/*!
@brief Gets the most recent Z axis value
@return Z-axis acceleration data
*/
/**************************************************************************/
int16_t MSA300::getZ(void)
{
int16_t temp = (readRegister(MSA300_REG_ACC_Z_LSB) + (int8_t)(readRegister(MSA300_REG_ACC_Z_MSB))*256)/4;
return temp;
}
/**************************************************************************/
/*!
@brief Instantiates a new MSA300 class
@param sensorID
ID for identifying different sensors
*/
/**************************************************************************/
MSA300::MSA300(int32_t sensorID)
{
_sensorID = sensorID;
_range = MSA300_RANGE_2_G;
}
/**************************************************************************/
/*!
@brief Setups the HW (reads coefficients values, etc.)
@return True if connection was established, False if no MSA300 was
detected
*/
/**************************************************************************/
bool MSA300::begin()
{
Wire.begin();
/* Check connection */
uint8_t partid = getPartID();
if (partid != 0x13)
{
/* No MSA300 detected ... return false */
Serial.println(partid, HEX);
return false;
}
_multiplier = MSA300_MG2G_MULTIPLIER_4_G;
// Enable measurements
writeRegister(MSA300_REG_PWR_MODE_BW, 0x10); // Normal mode & 500 Hz Bandwidth
writeRegister(MSA300_REG_ODR, MSA300_DATARATE_1000_HZ); // Set Output Data Rate to 1000 Hz
writeRegister(MSA300_REG_RES_RANGE, 0x01);
writeRegister(MSA300_REG_INT_SET_0,0x00);
writeRegister(MSA300_REG_INT_SET_1,0x00);
writeRegister(MSA300_REG_INT_LATCH,0x81);
return true;
}
/**************************************************************************/
/*!
@brief Sets the g range for the accelerometer
@param range
Measurement range
*/
/**************************************************************************/
void MSA300::setRange(range_t range)
{
/* Read the data format register to preserve bits */
uint8_t format = readRegister(MSA300_REG_RES_RANGE);
/* Update the range */
format &= ~0x3; // clear range bits
format |= range;
/* Write the register back to the IC */
writeRegister(MSA300_REG_RES_RANGE, format);
/* Keep track of the current range (to avoid readbacks) */
_range = range;
/* Map correct conversion multiplier */
switch(range) {
case MSA300_RANGE_16_G:
_multiplier = MSA300_MG2G_MULTIPLIER_16_G;
break;
case MSA300_RANGE_8_G:
_multiplier = MSA300_MG2G_MULTIPLIER_8_G;
break;
case MSA300_RANGE_4_G:
_multiplier = MSA300_MG2G_MULTIPLIER_4_G;
break;
case MSA300_RANGE_2_G:
_multiplier = MSA300_MG2G_MULTIPLIER_2_G;
}
}
/**************************************************************************/
/*!
@brief Get the g range for the accelerometer
@return Measurement range
*/
/**************************************************************************/
range_t MSA300::getRange(void)
{
return (range_t)(readRegister(MSA300_REG_RES_RANGE) & 0x3);
}
/**************************************************************************/
/*!
@brief Sets the resolution for the accelerometer
@param resolution
Measurement resolution
*/
/**************************************************************************/
void MSA300::setResolution(res_t resolution)
{
/* Read the data format register to preserve bits */
uint8_t format = readRegister(MSA300_REG_RES_RANGE);
/* Update the resolution */
format &= ~0xC; // clear resolution bits
format |= resolution;
/* Write the register back to the IC */
writeRegister(MSA300_REG_RES_RANGE, format);
/* Keep track of the current resolution (to avoid readbacks) */
_res = resolution;
}
/**************************************************************************/
/*!
@brief Get resolution for the accelerometer
@return Measurement resolution
*/
/**************************************************************************/
res_t MSA300::getResolution(void)
{
return (res_t)(readRegister(MSA300_REG_RES_RANGE) & 0xC);
}
/**************************************************************************/
/*!
@brief Sets the data rate for the MSA300 (controls power consumption)
@param dataRate
Output data rate
*/
/**************************************************************************/
void MSA300::setDataRate(dataRate_t dataRate)
{
/* Note: The LOW_POWER bits are currently ignored and we always keep
the device in 'normal' mode */
writeRegister(MSA300_REG_ODR, dataRate);
}
/**************************************************************************/
/*!
@brief Get the data rate for the MSA300
@return Output data rate
*/
/**************************************************************************/
dataRate_t MSA300::getDataRate(void)
{
return (dataRate_t)(readRegister(MSA300_REG_ODR) & 0x0F);
}
/**************************************************************************/
/*!
@brief Sets the operating mode for MSA300
@param mode
Power mode
*/
/**************************************************************************/
void MSA300::setMode(pwrMode_t mode)
{
/* Read the data format register to preserve bits */
uint8_t format = readRegister(MSA300_REG_PWR_MODE_BW);
/* Update the mode */
format &= ~0xC0; // clear the mode bits
format |= mode;
/* Write the register back to the IC */
writeRegister(MSA300_REG_PWR_MODE_BW, format);
/* Keep track of the current mode (to avoid readbacks) */
_mode = mode;
}
/**************************************************************************/
/*!
@brief Gets the data rate for the MSA300
@return Power mode
*/
/**************************************************************************/
pwrMode_t MSA300::getMode(void)
{
return (pwrMode_t)(readRegister(MSA300_REG_PWR_MODE_BW) & 0xC0);
}
/**************************************************************************/
/*!
@brief Reset all latched interrupts
*/
/**************************************************************************/
void MSA300::resetInterrupt(void)
{
/* Read register to preserve bits */
uint8_t reg = readRegister(MSA300_REG_INT_LATCH);
/* Turn RESET_INT bit on */
reg |= (1 << 7);
/* Write the register back to the IC */
writeRegister(MSA300_REG_INT_LATCH, reg);
}
/**************************************************************************/
/*!
@brief Clear all interrupt registers by setting them to default state.
*/
/**************************************************************************/
void MSA300::clearInterrupts(void)
{
writeRegister(MSA300_REG_INT_SET_0, 0x00);
writeRegister(MSA300_REG_INT_SET_1, 0x00);
writeRegister(MSA300_REG_INT_MAP_0, 0x00);
writeRegister(MSA300_REG_INT_MAP_2_1, 0x00);
writeRegister(MSA300_REG_INT_MAP_2_2, 0x00);
}
/**************************************************************************/
/*!
@brief Check interrupt registers for all occured interrupts. Return
struct with booleans of all triggered interrupts.
@return Struct containing boolean status of interrupts.
*/
/**************************************************************************/
interrupt_t MSA300::checkInterrupts(void)
{
interrupt_t interrupts;
uint8_t motionReg = readRegister(MSA300_REG_MOTION_INT);
uint8_t dataReg = readRegister(MSA300_REG_DATA_INT);
uint8_t tapReg = readRegister(MSA300_REG_TAP_ACTIVE_STATUS);
interrupts.orientInt = (motionReg >> 6) & 1;
interrupts.sTapInt = (motionReg >> 5) & 1;
interrupts.dTapInt = (motionReg >> 4) & 1;
interrupts.activeInt = (motionReg >> 2) & 1;
interrupts.freefallInt = (motionReg >> 0) & 1;
interrupts.newDataInt = (dataReg >> 0) & 1;
/* If there was active or tap interrupts, populate intStatus struct */
if(interrupts.activeInt || interrupts.sTapInt || interrupts.dTapInt) {
interrupts.intStatus.tapSign = (tapReg >> 7) & 1;
interrupts.intStatus.tapFirstX = (tapReg >> 6) & 1;
interrupts.intStatus.tapFirstY = (tapReg >> 5) & 1;
interrupts.intStatus.tapFirstZ = (tapReg >> 4) & 1;
interrupts.intStatus.activeSign = (tapReg >> 3) & 1;
interrupts.intStatus.activeFirstX = (tapReg >> 2) & 1;
interrupts.intStatus.activeFirstY = (tapReg >> 1) & 1;
interrupts.intStatus.activeFirstZ = (tapReg >> 0) & 1;
}
return interrupts;
}
/**************************************************************************/
/*!
@brief Set interrupt latching mode
@param mode
Interrupt mode
*/
/**************************************************************************/
void MSA300::setInterruptLatch(intMode_t mode)
{
/* Read register to preserve bits */
uint8_t reg = readRegister(MSA300_REG_INT_LATCH);
/* Update latching mode */
reg &= ~0xF0;
reg |= mode;
/* Write the register back to the IC */
writeRegister(MSA300_REG_INT_LATCH, reg);
}
/**************************************************************************/
/*!
@brief Turn on active interrupt. Interrupt parameter corresponds to
interrupt pins.
@param axis
Axis to set active interrupt on
@param interrupt
Index of interrupt (1 or 2)
*/
/**************************************************************************/
void MSA300::enableActiveInterrupt(axis_t axis, uint8_t interrupt)
{
uint8_t reg;
switch(interrupt) {
case 1:
reg = readRegister(MSA300_REG_INT_MAP_0);
reg |= (1 << 2);
writeRegister(MSA300_REG_INT_MAP_0, reg);
break;
case 2:
reg = readRegister(MSA300_REG_INT_MAP_2_1);
reg |= (1 << 2);
writeRegister(MSA300_REG_INT_MAP_2_1, reg);
break;
}
reg = readRegister(MSA300_REG_INT_SET_0);
switch(axis) {
case MSA300_AXIS_X:
reg |= (1 << 0);
break;
case MSA300_AXIS_Y:
reg |= (1 << 1);
break;
case MSA300_AXIS_Z:
reg |= (1 << 2);
break;
}
writeRegister(MSA300_REG_INT_SET_0, reg);
}
/**************************************************************************/
/*!
@brief Toggle freefall interrupt. Interrupt parameter corresponds to
interrupt pins.
@param interrupt
Index of interrupt (1 or 2)
*/
/**************************************************************************/
void MSA300::enableFreefallInterrupt(uint8_t interrupt)
{
uint8_t reg;
switch(interrupt) {
case 1:
reg = readRegister(MSA300_REG_INT_MAP_0);
reg |= (1 << 0);
writeRegister(MSA300_REG_INT_MAP_0, reg);
break;
case 2:
reg = readRegister(MSA300_REG_INT_MAP_2_1);
reg |= (1 << 0);
writeRegister(MSA300_REG_INT_MAP_2_1, reg);
break;
}
reg = readRegister(MSA300_REG_INT_SET_1);
reg |= (1 << 3);
writeRegister(MSA300_REG_INT_SET_1, reg);
}
/**************************************************************************/
/*!
@brief Enable freefall interrupt. Interrupt parameter corresponds to
interrupt pins.
@param interrupt
Index of interrupt (1 or 2)
*/
/**************************************************************************/
void MSA300::enableOrientationInterrupt(uint8_t interrupt)
{
uint8_t reg;
switch(interrupt) {
case 1:
reg = readRegister(MSA300_REG_INT_MAP_0);
reg |= (1 << 6);
writeRegister(MSA300_REG_INT_MAP_0, reg);
break;
case 2:
reg = readRegister(MSA300_REG_INT_MAP_2_1);
reg |= (1 << 6);
writeRegister(MSA300_REG_INT_MAP_2_1, reg);
break;
}
reg = readRegister(MSA300_REG_INT_SET_0);
reg |= (1 << 6);
writeRegister(MSA300_REG_INT_SET_0, reg);
}
/**************************************************************************/
/*!
@brief Enable single tap interrupt. Interrupt parameter corresponds to
interrupt pins.
@param interrupt
Index of interrupt (1 or 2)
*/
/**************************************************************************/
void MSA300::enableSingleTapInterrupt(uint8_t interrupt)
{
uint8_t reg;
switch(interrupt) {
case 1:
reg = readRegister(MSA300_REG_INT_MAP_0);
reg |= (1 << 5);
writeRegister(MSA300_REG_INT_MAP_0, reg);
break;
case 2:
reg = readRegister(MSA300_REG_INT_MAP_2_1);
reg |= (1 << 5);
writeRegister(MSA300_REG_INT_MAP_2_1, reg);
break;
}
reg = readRegister(MSA300_REG_INT_SET_0);
reg |= (1 << 5);
writeRegister(MSA300_REG_INT_SET_0, reg);
}
/**************************************************************************/
/*!
@brief Enable double tap interrupt. Interrupt parameter corresponds to
interrupt pins.
@param interrupt
Index of interrupt (1 or 2)
*/
/**************************************************************************/
void MSA300::enableDoubleTapInterrupt(uint8_t interrupt)
{
uint8_t reg;
switch(interrupt) {
case 1:
reg = readRegister(MSA300_REG_INT_MAP_0);
reg |= (1 << 4);
writeRegister(MSA300_REG_INT_MAP_0, reg);
break;
case 2:
reg = readRegister(MSA300_REG_INT_MAP_2_1);
reg |= (1 << 4);
writeRegister(MSA300_REG_INT_MAP_2_1, reg);
break;
}
reg = readRegister(MSA300_REG_INT_SET_0);
reg |= (1 << 4);
writeRegister(MSA300_REG_INT_SET_0, reg);
}
/**************************************************************************/
/*!
@brief Enable new data interrupt. Interrupt parameter corresponds to
interrupt pins.
@param interrupt
Index of interrupt (1 or 2)
*/
/**************************************************************************/
void MSA300::enableNewDataInterrupt(uint8_t interrupt)
{
uint8_t reg;
switch(interrupt) {
case 1:
reg = readRegister(MSA300_REG_INT_MAP_1);
reg |= (1 << 0);
writeRegister(MSA300_REG_INT_MAP_1, reg);
break;
case 2:
reg = readRegister(MSA300_REG_INT_MAP_1);
reg |= (1 << 7);
writeRegister(MSA300_REG_INT_MAP_1, reg);
break;
}
reg = readRegister(MSA300_REG_INT_SET_1);
reg |= (1 << 4);
writeRegister(MSA300_REG_INT_SET_1, reg);
}
/**************************************************************************/
/*!
@brief Check orientation of the chip.
@return Orientation struct containing z and xy-orientations
*/
/**************************************************************************/
orient_t MSA300::checkOrientation(void)
{
orient_t orientation;
uint8_t reg = readRegister(MSA300_REG_ORIENT_STATUS);
orientation.z = (zOrient_t)((reg >> 6) & 1);
orientation.xy = (xyOrient_t)((reg >> 4) & 0x3);
return orientation;
}
/**************************************************************************/
/*!
@brief Set offset compensation value for specific axis. Value can vary
from 0 to 998.4 mg.
Values outside the range will be clamped.
@param axis
Axis to set offset on
@param value
Offset value (0 to 998.4 mg)
*/
/**************************************************************************/
void MSA300::setOffset(axis_t axis, float value)
{
uint8_t offset = value / 3.9f;
uint8_t reg;
offset = clamp<float>(offset, 0, 998.4f);
switch(axis) {
case MSA300_AXIS_X:
reg = readRegister(MSA300_REG_OFFSET_COMP_X);
reg &= ~0xFF;
reg |= offset;
writeRegister(MSA300_REG_OFFSET_COMP_X, reg);
break;
case MSA300_AXIS_Y:
reg = readRegister(MSA300_REG_OFFSET_COMP_Y);
reg &= ~0xFF;
reg |= offset;
writeRegister(MSA300_REG_OFFSET_COMP_Y, reg);
break;
case MSA300_AXIS_Z:
reg = readRegister(MSA300_REG_OFFSET_COMP_Z);
reg &= ~0xFF;
reg |= offset;
writeRegister(MSA300_REG_OFFSET_COMP_Z, reg);
break;
}
}
/**************************************************************************/
/*!
@brief Set threshold of tap interrupt. Value can vary from 0 to full
scale of each range. Values outside the range will be clamped.
@param value
Tap threshold value (0 to full scale)
*/
/**************************************************************************/
void MSA300::setTapThreshold(float value)
{
float offset = 0;
switch(_range) {
case MSA300_RANGE_16_G:
offset = clamp<float>(value / MSA300_MG2G_TAP_TH_16_G, 0, 16000.0);
break;
case MSA300_RANGE_8_G:
offset = clamp<float>(value / MSA300_MG2G_TAP_TH_8_G, 0, 8000.0);
break;
case MSA300_RANGE_4_G:
offset = clamp<float>(value / MSA300_MG2G_TAP_TH_4_G, 0, 4000.0);
break;
case MSA300_RANGE_2_G:
offset = clamp<float>(value / MSA300_MG2G_TAP_TH_2_G, 0, 2000.0);
break;
}
writeRegister(MSA300_REG_TAP_TH, offset);
}
/**************************************************************************/
/*!
@brief Set duration of tap interrupt.
@param duration
Second shock duration: According to tapDuration_t enum.
@param quiet
Quiet duration: 0 -> 30 ms
1 -> 20 ms
@param shock
Shock duration: 0 -> 50 ms
1 -> 70 ms
*/
/**************************************************************************/
void MSA300::setTapDuration(tapDuration_t duration, uint8_t quiet, uint8_t shock)
{
uint8_t reg = 0;
reg |= (quiet << 7);
reg |= (shock << 6);
reg |= duration;
writeRegister(MSA300_REG_TAP_DUR, reg);
}
/**************************************************************************/
/*!
@brief Set threshold of active interrupt. Value can vary from 0 to full
scale of each range. Values outside the range will be clamped.
@param value
Active threshold value (0 to full scale)
*/
/**************************************************************************/
void MSA300::setActiveThreshold(float value)
{
float offset = 0;
switch(_range) {
case MSA300_RANGE_16_G:
offset = clamp<float>(value / MSA300_MG2G_ACTIVE_TH_16_G, 0, 16000.0);
break;
case MSA300_RANGE_8_G:
offset = clamp<float>(value / MSA300_MG2G_ACTIVE_TH_8_G, 0, 8000.0);
break;
case MSA300_RANGE_4_G:
offset = clamp<float>(value / MSA300_MG2G_ACTIVE_TH_4_G, 0, 4000.0);
break;
case MSA300_RANGE_2_G:
offset = clamp<float>(value / MSA300_MG2G_ACTIVE_TH_2_G, 0, 2000.0);
break;
}
writeRegister(MSA300_REG_ACTIVE_TH, offset);
}
/**************************************************************************/
/*!
@brief Set duration of active interrupt.
Value can vary from 1 ms to 5 ms.
@param duration
Active interrupt duration (1 to 5 ms)
*/
/**************************************************************************/
void MSA300::setActiveDuration(uint8_t duration)
{
uint8_t reg = 0;
uint8_t value = clamp<uint8_t>(duration - 1, 0, 4);
reg |= value;
writeRegister(MSA300_REG_ACTIVE_DUR, reg);
}
/**************************************************************************/
/*!
@brief Set duration of freefall interrupt.
Value can vary from 2 ms to 512 ms.
@param duration
Freefall interrupt duration (2 to 512 ms)
*/
/**************************************************************************/
void MSA300::setFreefallDuration(uint16_t duration)
{
uint8_t reg = 0;
float dur_f;
duration = clamp<uint16_t>(duration, 2, 512);
dur_f = clamp<float>((float)(duration)/2.0f - 1, 0, 256); // avoid rounding the result in between
reg |= (uint8_t)dur_f;
writeRegister(MSA300_REG_FREEFALL_DUR, reg);
}
/**************************************************************************/
/*!
@brief Set threshold of freefall interrupt. Value can vary from 0 to full
scale of each range. Values outside the range will be clamped.
@param value
Freefall interrupt threshold (0 to full scale)
*/
/**************************************************************************/
void MSA300::setFreefallThreshold(float value)
{
float threshold = value / 7.81f;
switch(_range) {
case MSA300_RANGE_16_G:
threshold = clamp<float>(threshold, 0, 16000.0);
break;
case MSA300_RANGE_8_G:
threshold = clamp<float>(threshold, 0, 8000.0);
break;
case MSA300_RANGE_4_G:
threshold = clamp<float>(threshold, 0, 4000.0);
break;
case MSA300_RANGE_2_G:
threshold = clamp<float>(threshold, 0, 2000.0);
break;
}
writeRegister(MSA300_REG_FREEFALL_TH, threshold);
}
/**************************************************************************/
/*!
@brief Set hysteresis value and mode of freefall interrupt.
Value can vary from 0 to 500 mg in integers of 125mg.
Values outside the range will be clamped.
@param mode
Mode: 1 -> sum mode |acc_x| + |acc_y| + |acc_z|
0 -> single mode
@param value
Freefall hysteresis value (0 to 500 mg in steps of 125 mg)
*/
/**************************************************************************/
void MSA300::setFreefallHysteresis(uint8_t mode, uint8_t value)
{
uint8_t reg = 0;
uint8_t hysteresis = (uint8_t)clamp<uint16_t>(value / 125, 0, 500);
reg |= (mode << 3);
reg &= ~0x3;
reg |= hysteresis;
writeRegister(MSA300_REG_FREEFALL_HY, reg);
}
/**************************************************************************/
/*!
@brief Swap polarity.
@param polarity
Polarity to be changed
*/
/**************************************************************************/
void MSA300::swapPolarity(pol_t polarity)
{
uint8_t reg = readRegister(MSA300_REG_SWAP_POLARITY);
reg ^= (1 << polarity);
writeRegister(MSA300_REG_SWAP_POLARITY, reg);
}
/**************************************************************************/
/*!
@brief Set orientation mode
@param mode
Orientation mode
*/
/**************************************************************************/
void MSA300::setOrientMode(orientMode_t mode)
{
uint8_t reg = readRegister(MSA300_REG_ORIENT_HY);
reg &= ~0x3;
reg |= mode;
writeRegister(MSA300_REG_ORIENT_HY, reg);
}
/**************************************************************************/
/*!
@brief Set orientation hysteresis. Value can vary from 0 to 500 mg.
@param value
Orientation hysteresis value (0 to 500 mg)
*/
/**************************************************************************/
void MSA300::setOrientHysteresis(float value)
{
uint8_t reg = readRegister(MSA300_REG_ORIENT_HY);
uint8_t hysteresis = (uint8_t)clamp<float>(value / 62.5f, 0, 8);
reg &= ~0x70;
reg |= hysteresis;
writeRegister(MSA300_REG_ORIENT_HY, reg);
}
/**************************************************************************/
/*!
@brief Set z blocking.
@param mode
Orientation blocking mode
@param zBlockValue
Limit value of z-blocking
*/
/**************************************************************************/
void MSA300::setBlocking(orientBlockMode_t mode, float zBlockValue)
{
uint8_t reg = readRegister(MSA300_REG_ORIENT_HY);
reg &= ~0xC;
reg |= mode;
writeRegister(MSA300_REG_ORIENT_HY, reg);
uint8_t value = (uint8_t)clamp<float>(zBlockValue / 62.5f, 0, 15);
writeRegister(MSA300_REG_Z_BLOCK, value);
}
/**************************************************************************/
/*!
@brief Get the acceleration.
@return Acceleration struct containing accelarations of each axis in
m/s^2
*/
/**************************************************************************/
acc_t MSA300::getAcceleration(void)
{
acc_t acceleration;
acceleration.x = getX() * _multiplier * GRAVITY;
acceleration.y = getY() * _multiplier * GRAVITY;
acceleration.z = getZ() * _multiplier * GRAVITY;
return acceleration;
}