✈️ Adds barometer to imu service
This commit is contained in:
@@ -0,0 +1,262 @@
|
||||
/*!
|
||||
* @file Adafruit_HMC5883_U.cpp
|
||||
*
|
||||
* @mainpage Adafruit HMC5883 Unified Library
|
||||
*
|
||||
* @section intro_sec Introduction
|
||||
*
|
||||
* This is a library for the HMC5883 magnentometer/compass
|
||||
*
|
||||
* Designed specifically to work with the Adafruit HMC5883 Breakout
|
||||
* http://www.adafruit.com/products/1746
|
||||
*
|
||||
* These displays use I2C to communicate, 2 pins are required to interface.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit andopen-source hardware by purchasing products
|
||||
* from Adafruit!
|
||||
*
|
||||
* @section author Author
|
||||
*
|
||||
* Written by Kevin Townsend for Adafruit Industries.
|
||||
*
|
||||
* @section license License
|
||||
*
|
||||
* BSD license, all text above must be included in any redistribution
|
||||
*/
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#ifdef __AVR_ATtiny85__
|
||||
#include "TinyWireM.h"
|
||||
#define Wire TinyWireM
|
||||
#else
|
||||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "Adafruit_HMC5883_U.h"
|
||||
|
||||
static float _hmc5883_Gauss_LSB_XY = 1100.0F; // Varies with gain
|
||||
static float _hmc5883_Gauss_LSB_Z = 980.0F; // Varies with gain
|
||||
|
||||
/***************************************************************************
|
||||
MAGNETOMETER
|
||||
***************************************************************************/
|
||||
/***************************************************************************
|
||||
PRIVATE FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Abstract away platform differences in Arduino wire library
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_HMC5883_Unified::write8(byte address, byte reg, byte value) {
|
||||
Wire.beginTransmission(address);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write((uint8_t)reg);
|
||||
Wire.write((uint8_t)value);
|
||||
#else
|
||||
Wire.send(reg);
|
||||
Wire.send(value);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Abstract away platform differences in Arduino wire library
|
||||
*/
|
||||
/**************************************************************************/
|
||||
byte Adafruit_HMC5883_Unified::read8(byte address, byte reg) {
|
||||
byte value;
|
||||
|
||||
Wire.beginTransmission(address);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write((uint8_t)reg);
|
||||
#else
|
||||
Wire.send(reg);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(address, (byte)1);
|
||||
#if ARDUINO >= 100
|
||||
value = Wire.read();
|
||||
#else
|
||||
value = Wire.receive();
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Reads the raw data from the sensor
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_HMC5883_Unified::read() {
|
||||
// Read the magnetometer
|
||||
Wire.beginTransmission((byte)HMC5883_ADDRESS_MAG);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(HMC5883_REGISTER_MAG_OUT_X_H_M);
|
||||
#else
|
||||
Wire.send(HMC5883_REGISTER_MAG_OUT_X_H_M);
|
||||
#endif
|
||||
Wire.endTransmission(false);
|
||||
Wire.requestFrom((byte)HMC5883_ADDRESS_MAG, (byte)6, true);
|
||||
|
||||
// Note high before low (different than accel)
|
||||
#if ARDUINO >= 100
|
||||
uint8_t xhi = Wire.read();
|
||||
uint8_t xlo = Wire.read();
|
||||
uint8_t zhi = Wire.read();
|
||||
uint8_t zlo = Wire.read();
|
||||
uint8_t yhi = Wire.read();
|
||||
uint8_t ylo = Wire.read();
|
||||
#else
|
||||
uint8_t xhi = Wire.receive();
|
||||
uint8_t xlo = Wire.receive();
|
||||
uint8_t zhi = Wire.receive();
|
||||
uint8_t zlo = Wire.receive();
|
||||
uint8_t yhi = Wire.receive();
|
||||
uint8_t ylo = Wire.receive();
|
||||
#endif
|
||||
|
||||
// Shift values to create properly formed integer (low byte first)
|
||||
_magData.x = (int16_t)(xlo | ((int16_t)xhi << 8));
|
||||
_magData.y = (int16_t)(ylo | ((int16_t)yhi << 8));
|
||||
_magData.z = (int16_t)(zlo | ((int16_t)zhi << 8));
|
||||
|
||||
// ToDo: Calculate orientation
|
||||
_magData.orientation = 0.0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
CONSTRUCTOR
|
||||
***************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Instantiates a new Adafruit_HMC5883 class
|
||||
*/
|
||||
/**************************************************************************/
|
||||
Adafruit_HMC5883_Unified::Adafruit_HMC5883_Unified(int32_t sensorID) {
|
||||
_sensorID = sensorID;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
PUBLIC FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Setups the HW
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_HMC5883_Unified::begin() {
|
||||
// Enable I2C
|
||||
Wire.begin();
|
||||
|
||||
// Enable the magnetometer
|
||||
write8(HMC5883_ADDRESS_MAG, HMC5883_REGISTER_MAG_MR_REG_M, 0x00);
|
||||
|
||||
// Set the gain to a known level
|
||||
setMagGain(HMC5883_MAGGAIN_1_3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Sets the magnetometer's gain
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_HMC5883_Unified::setMagGain(hmc5883MagGain gain) {
|
||||
write8(HMC5883_ADDRESS_MAG, HMC5883_REGISTER_MAG_CRB_REG_M, (byte)gain);
|
||||
|
||||
_magGain = gain;
|
||||
|
||||
switch (gain) {
|
||||
case HMC5883_MAGGAIN_1_3:
|
||||
_hmc5883_Gauss_LSB_XY = 1100;
|
||||
_hmc5883_Gauss_LSB_Z = 980;
|
||||
break;
|
||||
case HMC5883_MAGGAIN_1_9:
|
||||
_hmc5883_Gauss_LSB_XY = 855;
|
||||
_hmc5883_Gauss_LSB_Z = 760;
|
||||
break;
|
||||
case HMC5883_MAGGAIN_2_5:
|
||||
_hmc5883_Gauss_LSB_XY = 670;
|
||||
_hmc5883_Gauss_LSB_Z = 600;
|
||||
break;
|
||||
case HMC5883_MAGGAIN_4_0:
|
||||
_hmc5883_Gauss_LSB_XY = 450;
|
||||
_hmc5883_Gauss_LSB_Z = 400;
|
||||
break;
|
||||
case HMC5883_MAGGAIN_4_7:
|
||||
_hmc5883_Gauss_LSB_XY = 400;
|
||||
_hmc5883_Gauss_LSB_Z = 255;
|
||||
break;
|
||||
case HMC5883_MAGGAIN_5_6:
|
||||
_hmc5883_Gauss_LSB_XY = 330;
|
||||
_hmc5883_Gauss_LSB_Z = 295;
|
||||
break;
|
||||
case HMC5883_MAGGAIN_8_1:
|
||||
_hmc5883_Gauss_LSB_XY = 230;
|
||||
_hmc5883_Gauss_LSB_Z = 205;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the most recent sensor event
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_HMC5883_Unified::getEvent(sensors_event_t *event) {
|
||||
/* Clear the event */
|
||||
memset(event, 0, sizeof(sensors_event_t));
|
||||
|
||||
/* Read new data */
|
||||
read();
|
||||
|
||||
event->version = sizeof(sensors_event_t);
|
||||
event->sensor_id = _sensorID;
|
||||
event->type = SENSOR_TYPE_MAGNETIC_FIELD;
|
||||
event->timestamp = 0;
|
||||
event->magnetic.x =
|
||||
_magData.x / _hmc5883_Gauss_LSB_XY * SENSORS_GAUSS_TO_MICROTESLA;
|
||||
event->magnetic.y =
|
||||
_magData.y / _hmc5883_Gauss_LSB_XY * SENSORS_GAUSS_TO_MICROTESLA;
|
||||
event->magnetic.z =
|
||||
_magData.z / _hmc5883_Gauss_LSB_Z * SENSORS_GAUSS_TO_MICROTESLA;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Gets the sensor_t data
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_HMC5883_Unified::getSensor(adafruit_sensor_t *sensor) {
|
||||
/* Clear the sensor_t object */
|
||||
memset(sensor, 0, sizeof(adafruit_sensor_t));
|
||||
|
||||
/* Insert the sensor name in the fixed length char array */
|
||||
strncpy(sensor->name, "HMC5883", sizeof(sensor->name) - 1);
|
||||
sensor->name[sizeof(sensor->name) - 1] = 0;
|
||||
sensor->version = 1;
|
||||
sensor->sensor_id = _sensorID;
|
||||
sensor->type = SENSOR_TYPE_MAGNETIC_FIELD;
|
||||
sensor->min_delay = 0;
|
||||
sensor->max_value = 800; // 8 gauss == 800 microTesla
|
||||
sensor->min_value = -800; // -8 gauss == -800 microTesla
|
||||
sensor->resolution = 0.2; // 2 milligauss == 0.2 microTesla
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*!
|
||||
* @file Adafruit_HMC5883_U.h
|
||||
*/
|
||||
#ifndef __HMC5883_H__
|
||||
#define __HMC5883_H__
|
||||
|
||||
#if (ARDUINO >= 100)
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include <Adafruit_Sensor.h>
|
||||
|
||||
#ifdef __AVR_ATtiny85__
|
||||
#include "TinyWireM.h"
|
||||
#define Wire TinyWireM
|
||||
#else
|
||||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief I2C address/bits
|
||||
*/
|
||||
#define HMC5883_ADDRESS_MAG (0x3C >> 1) // 0011110x
|
||||
|
||||
/*!
|
||||
@brief Registers
|
||||
*/
|
||||
typedef enum {
|
||||
HMC5883_REGISTER_MAG_CRA_REG_M = 0x00,
|
||||
HMC5883_REGISTER_MAG_CRB_REG_M = 0x01,
|
||||
HMC5883_REGISTER_MAG_MR_REG_M = 0x02,
|
||||
HMC5883_REGISTER_MAG_OUT_X_H_M = 0x03,
|
||||
HMC5883_REGISTER_MAG_OUT_X_L_M = 0x04,
|
||||
HMC5883_REGISTER_MAG_OUT_Z_H_M = 0x05,
|
||||
HMC5883_REGISTER_MAG_OUT_Z_L_M = 0x06,
|
||||
HMC5883_REGISTER_MAG_OUT_Y_H_M = 0x07,
|
||||
HMC5883_REGISTER_MAG_OUT_Y_L_M = 0x08,
|
||||
HMC5883_REGISTER_MAG_SR_REG_Mg = 0x09,
|
||||
HMC5883_REGISTER_MAG_IRA_REG_M = 0x0A,
|
||||
HMC5883_REGISTER_MAG_IRB_REG_M = 0x0B,
|
||||
HMC5883_REGISTER_MAG_IRC_REG_M = 0x0C,
|
||||
HMC5883_REGISTER_MAG_TEMP_OUT_H_M = 0x31,
|
||||
HMC5883_REGISTER_MAG_TEMP_OUT_L_M = 0x32
|
||||
} hmc5883MagRegisters_t;
|
||||
|
||||
/*!
|
||||
* @brief Magnetometer gain settings
|
||||
*/
|
||||
typedef enum {
|
||||
HMC5883_MAGGAIN_1_3 = 0x20, // +/- 1.3
|
||||
HMC5883_MAGGAIN_1_9 = 0x40, // +/- 1.9
|
||||
HMC5883_MAGGAIN_2_5 = 0x60, // +/- 2.5
|
||||
HMC5883_MAGGAIN_4_0 = 0x80, // +/- 4.0
|
||||
HMC5883_MAGGAIN_4_7 = 0xA0, // +/- 4.7
|
||||
HMC5883_MAGGAIN_5_6 = 0xC0, // +/- 5.6
|
||||
HMC5883_MAGGAIN_8_1 = 0xE0 // +/- 8.1
|
||||
} hmc5883MagGain;
|
||||
|
||||
/*!
|
||||
* @brief Internal magnetometer data type
|
||||
*/
|
||||
typedef struct hmc5883MagData_s {
|
||||
float x; //!< Magnetometer x value
|
||||
float y; //!< Magnetometer y value
|
||||
float z; //!< Magnetometer z value
|
||||
float orientation; //!< Magnetometer orientation
|
||||
} hmc5883MagData;
|
||||
|
||||
/*!
|
||||
* @brief Chip ID
|
||||
*/
|
||||
#define HMC5883_ID (0b11010100)
|
||||
|
||||
//! Unified sensor driver for the magnetometer ///
|
||||
class Adafruit_HMC5883_Unified : public Adafruit_Sensor {
|
||||
public:
|
||||
/*!
|
||||
* @param sensorID sensor ID, -1 by default
|
||||
*/
|
||||
Adafruit_HMC5883_Unified(int32_t sensorID = -1);
|
||||
|
||||
bool begin(void); //!< @return Returns whether connection was successful
|
||||
void setMagGain(hmc5883MagGain gain); //!< @param gain Desired magnetic gain
|
||||
bool
|
||||
getEvent(sensors_event_t *); //!< @return Returns the most recent sensor event
|
||||
void getSensor(adafruit_sensor_t *);
|
||||
|
||||
private:
|
||||
hmc5883MagGain _magGain;
|
||||
hmc5883MagData _magData; // Last read magnetometer data will be available here
|
||||
int32_t _sensorID;
|
||||
|
||||
void write8(byte address, byte reg, byte value);
|
||||
byte read8(byte address, byte reg);
|
||||
void read(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
# Adafruit HMC5883L Driver (3-Axis Magnetometer) [](https://github.com/adafruit/Adafruit_HMC5883_Unified/actions)[](http://adafruit.github.io/Adafruit_HMC5883_Unified/html/index.html)
|
||||
|
||||
This driver is for the Adafruit HMC5883L Breakout (http://www.adafruit.com/products/1746), and is based on Adafruit's Unified Sensor Library (Adafruit_Sensor).
|
||||
|
||||
## About the HMC5883 ##
|
||||
|
||||
The HMC5883L is a digital (I2C) compass (magnetometer). The magnetometer measure magnetic force, which is useful to detect magnetic north.
|
||||
|
||||
More information on the HMC5883L can be found in the datasheet: http://www.adafruit.com/datasheets/HMC5883L_3-Axis_Digital_Compass_IC.pdf
|
||||
|
||||
## What is the Adafruit Unified Sensor Library? ##
|
||||
|
||||
The Adafruit Unified Sensor Library (**Adafruit_Sensor**) provides a common interface and data type for any supported sensor. It defines some basic information about the sensor (sensor limits, etc.), and returns standard SI units of a specific type and scale for each supported sensor type.
|
||||
|
||||
It provides a simple abstraction layer between your application and the actual sensor HW, allowing you to drop in any comparable sensor with only one or two lines of code to change in your project (essentially the constructor since the functions to read sensor data and get information about the sensor are defined in the base Adafruit_Sensor class).
|
||||
|
||||
This is imporant useful for two reasons:
|
||||
|
||||
1.) You can use the data right away because it's already converted to SI units that you understand and can compare, rather than meaningless values like 0..1023.
|
||||
|
||||
2.) Because SI units are standardised in the sensor library, you can also do quick sanity checks working with new sensors, or drop in any comparable sensor if you need better sensitivity or if a lower cost unit becomes available, etc.
|
||||
|
||||
Light sensors will always report units in lux, gyroscopes will always report units in rad/s, etc. ... freeing you up to focus on the data, rather than digging through the datasheet to understand what the sensor's raw numbers really mean.
|
||||
|
||||
## About this Driver ##
|
||||
|
||||
Adafruit invests time and resources providing this open source code. Please support Adafruit and open-source hardware by purchasing products from Adafruit!
|
||||
|
||||
Written by Kevin (KTOWN) Townsend for Adafruit Industries.
|
||||
@@ -0,0 +1,108 @@
|
||||
/***************************************************************************
|
||||
This is a library example for the HMC5883 magnentometer/compass
|
||||
|
||||
Designed specifically to work with the Adafruit HMC5883 Breakout
|
||||
http://www.adafruit.com/products/1746
|
||||
|
||||
*** You will also need to install the Adafruit_Sensor library! ***
|
||||
|
||||
These displays use I2C to communicate, 2 pins are required to interface.
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit andopen-source hardware by purchasing products
|
||||
from Adafruit!
|
||||
|
||||
Written by Kevin Townsend for Adafruit Industries with some heading example from
|
||||
Love Electronics (loveelectronics.co.uk)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the version 3 GNU General Public License as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include <Adafruit_HMC5883_U.h>
|
||||
|
||||
/* Assign a unique ID to this sensor at the same time */
|
||||
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
|
||||
|
||||
void displaySensorDetails(void)
|
||||
{
|
||||
sensor_t sensor;
|
||||
mag.getSensor(&sensor);
|
||||
Serial.println("------------------------------------");
|
||||
Serial.print ("Sensor: "); Serial.println(sensor.name);
|
||||
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
|
||||
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
|
||||
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" uT");
|
||||
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" uT");
|
||||
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" uT");
|
||||
Serial.println("------------------------------------");
|
||||
Serial.println("");
|
||||
delay(500);
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(9600);
|
||||
Serial.println("HMC5883 Magnetometer Test"); Serial.println("");
|
||||
|
||||
/* Initialise the sensor */
|
||||
if(!mag.begin())
|
||||
{
|
||||
/* There was a problem detecting the HMC5883 ... check your connections */
|
||||
Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
|
||||
while(1);
|
||||
}
|
||||
|
||||
/* Display some basic information on this sensor */
|
||||
displaySensorDetails();
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
/* Get a new sensor event */
|
||||
sensors_event_t event;
|
||||
mag.getEvent(&event);
|
||||
|
||||
/* Display the results (magnetic vector values are in micro-Tesla (uT)) */
|
||||
Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print(" ");
|
||||
Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print(" ");
|
||||
Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print(" ");Serial.println("uT");
|
||||
|
||||
// Hold the module so that Z is pointing 'up' and you can measure the heading with x&y
|
||||
// Calculate heading when the magnetometer is level, then correct for signs of axis.
|
||||
float heading = atan2(event.magnetic.y, event.magnetic.x);
|
||||
|
||||
// Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
|
||||
// Find yours here: http://www.magnetic-declination.com/
|
||||
// Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
|
||||
// If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
|
||||
float declinationAngle = 0.22;
|
||||
heading += declinationAngle;
|
||||
|
||||
// Correct for when signs are reversed.
|
||||
if(heading < 0)
|
||||
heading += 2*PI;
|
||||
|
||||
// Check for wrap due to addition of declination.
|
||||
if(heading > 2*PI)
|
||||
heading -= 2*PI;
|
||||
|
||||
// Convert radians to degrees for readability.
|
||||
float headingDegrees = heading * 180/M_PI;
|
||||
|
||||
Serial.print("Heading (degrees): "); Serial.println(headingDegrees);
|
||||
|
||||
delay(500);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
name=Adafruit HMC5883 Unified
|
||||
version=1.2.3
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Adafruit HMC5883L 3-Axis Magnetometer Breakout library using Adafruit's Unified Sensor Library.
|
||||
paragraph=Adafruit HMC5883L 3-Axis Magnetometer Breakout library using Adafruit's Unified Sensor Library.
|
||||
category=Sensors
|
||||
url=https://github.com/adafruit/Adafruit_HMC5883_Unified
|
||||
architectures=*
|
||||
depends=Adafruit Unified Sensor
|
||||
Reference in New Issue
Block a user