Git Product home page Git Product logo

lsm303-arduino's Introduction

Arduino library for Pololu LSM303 boards

Version: 3.0.1
Release date: 2016-08-17
www.pololu.com

Summary

This is a library for an Arduino-compatible controller that interfaces with LSM303D, LSM303DLHC, LSM303DLM, and LSM303DLH 3D compass and accelerometer ICs on Pololu boards. It makes it simple to read the raw accelerometer and magnetometer data from these boards:

The library also includes a function for computing the tilt-compensated heading for those looking to use the LSM303 as a tilt-compensated compass.

Getting started

Hardware

A LSM303 carrier can be purchased from Pololu's website. Before continuing, careful reading of the product page as well as the chip datasheet is recommended.

Make the following connections with wires between the Arduino and the LSM303 board:

5V Arduino boards

(including Arduino Uno, Leonardo, Mega; Pololu A-Star 32U4)

Arduino   LSM303 board
-------   ------------
     5V - VIN
    GND - GND
    SDA - SDA
    SCL - SCL

3.3V Arduino boards

(including Arduino Due)

Arduino   LSM303 board
-------   ------------
    3V3 - VIN
    GND - GND
    SDA - SDA
    SCL - SCL

Software

If you are using version 1.6.2 or later of the Arduino software (IDE), you can use the Library Manager to install this library:

  1. In the Arduino IDE, open the "Sketch" menu, select "Include Library", then "Manage Libraries...".
  2. Search for "LSM303".
  3. Click the LSM303 entry in the list.
  4. Click "Install".

If this does not work, you can manually install the library:

  1. Download the latest release archive from GitHub and decompress it.
  2. Rename the folder "lps-arduino-xxxx" to "LSM303".
  3. Drag the "LSM303" folder into the "libraries" directory inside your Arduino sketchbook directory. You can view your sketchbook location by opening the "File" menu and selecting "Preferences" in the Arduino IDE. If there is not already a "libraries" folder in that location, you should make the folder yourself.
  4. After installing the library, restart the Arduino IDE.

Examples

Several example sketches are available that show how to use the library. You can access them from the Arduino IDE by opening the "File" menu, selecting "Examples", and then selecting "LSM303". If you cannot find these examples, the library was probably installed incorrectly and you should retry the installation instructions above.

Serial

This program continuously reads the accelerometer and magnetometer, communicating the readings over the serial interface. You can display the readings with the Arduino Serial Monitor.

Example output:

A:    192  -1040 -17168    M:   -512     27    144
A:    288  -1040 -17232    M:   -511     26    143
A:     16  -1104 -17216    M:   -511     27    144

See the comments in this sketch for some notes on how to convert the raw sensor values to units of g and gauss.

Calibrate

This program is similar to the Serial example, but instead of printing the most recent readings, it prints a running minimum and maximum of the readings from each magnetometer axis. These values can be used to calibrate the heading() functions and the Heading example after moving the LSM303 through every possible orientation.

Heading

This program uses readings from the accelerometer and magnetometer to calculate a tilt-compensated compass heading (in degrees relative to a default vector), which is communicated serially and can be displayed with the Arduino Serial Monitor. The default vector is chosen to point along the surface of the PCB, in the direction of the top of the text on the silkscreen. (This is the +X axis on the Pololu LSM303D carrier and the -Y axis on the Pololu LSM303DLHC, LSM303DLM, and LSM303DLH carriers.) See the comments if you want to use a different reference vector.

For the most accurate results, you should replace the values of m_min and m_max assigned in the setup() function with your own values obtained from the Calibrate example.

Other library applications

These programs make use of the LSM303 library but are not included in the library archive or repository.

  • MinIMU-9 + Arduino AHRS
    This sketch allows an Arduino connected to a MinIMU-9 or AltIMU-10 to function as an attitude and heading reference system, calculating estimated roll, pitch, and yaw angles from sensor readings that can be visualized with a 3D test program on a PC. It is based on the work of Jordi Munoz, William Premerlani, Jose Julio, and Doug Weibel.
  • Pololu_Open_IMU by mikeshub
    This is an alternative AHRS implementation that uses the Madgwick algorithm.
  • ascii_graph by drewtm
    This sketch outputs a text-based graph of LSM303 accelerometer and L3G gyro data, providing a quick way to check whether the sensors are working as expected.

Library reference

  • vector<int16_t> a
    The last values read from the accelerometer.
  • vector<int16_t> m
    The last values read from the magnetometer.
  • vector<int16_t> m_min
    Lower bounds (minimum values) for the magnetometer readings on each axis; set this appropriately to calibrate heading().
  • vector<int16_t> m_max
    Upper bounds (maximum values) for the magnetometer readings on each axis; set this appropriately to calibrate heading().
  • byte last_status
    The status of the last I2C transmission. See the Wire.endTransmission() documentation for return values.
  • LSM303(void)
    Constructor; initializes m_min and m_max with placeholder values.
  • bool init(deviceType device, sa0State sa0)
    Initializes the library with the device being used (device_DLH, device_DLM, device_DLHC, device_D, or device_auto) and the state of the SA0 pin (sa0_low, sa0_high, or sa0_auto), which determines the least significant bit(s) of the I²C slave address (on some devices, and only for the accelerometer in some cases). Constants for these arguments are defined in LSM303.h. Both of these arguments are optional; if they are not specified, the library will try to automatically detect the device and accelerometer address[1]. A boolean is returned indicating whether the type of LSM303 device was successfully determined (if necessary).
  • byte getDeviceType(void)
    Returns the device type specified to or detected by init().
  • void enableDefault(void)
    Turns on the accelerometer and magnetometer and enables a consistent set of default settings. This function will set the accelerometer's full scale to be +/-2 g, which means that a reading of 16384 corresponds to approximately 1 g. The magnetometer's full scale is set to +/-4 gauss for the LSM303D or +/-1.3 gauss on all other devices. See the comments in LSM303.cpp for a full explanation of these settings.
  • void writeReg(byte reg, byte value)
    Writes an accelerometer or magnetometer register with the given value. Register addresses are defined by the regAddr enumeration type in LSM303.h. Example use: compass.writeReg(LSM303::CTRL_REG1_A, 0x57);
  • void readReg(int reg)
    Reads an accelerometer or magnetometer register and returns the value read.[2][3]
  • void writeAccReg(byte reg, byte value)
    Writes an accelerometer register with the given value.
  • byte readAccReg(byte reg)
    Reads an accelerometer register and returns the value read.
  • void writeMagReg(byte reg, byte value)
    Writes a magnetometer register with the given value.
  • byte readMagReg(int reg)
    Reads a magnetometer register and returns the value read.[3]
  • void readAcc(void)
    Takes a reading from the accelerometer and stores the values in the vector a. Conversion of the readings to units of g depends on the accelerometer's selected gain (full scale setting). Note that in the LSM303DLHC, LSM303DLM, and LSM303DLH, the acceleration data registers actually contain a left-aligned 12-bit number, so the lowest 4 bits are always 0, and the values in a should be shifted right by 4 bits (divided by 16) to be consistent with the conversion factors specified in the datasheets.
  • void readMag(void)
    Takes a reading from the magnetometer and stores the values in the vector m. Conversion of the readings to units of gauss depends on the magnetometer's selected gain (full scale setting).
  • void read(void)
    Takes a reading from both the accelerometer and magnetometer and stores the values in the vectors a and m.
  • void setTimeout(unsigned int timeout)
    Sets a timeout period for readAcc() and readMag(), in milliseconds, after which they will abort if no data is received. A value of 0 disables the timeout.
  • unsigned int getTimeout(void)
    Returns the current timeout period setting.
  • bool timeoutOccurred(void)
    Returns a boolean indicating whether a call to readAcc() or readMag() has timed out since the last call to timeoutOccurred().
  • float heading(void)
    Returns the tilt-compensated heading of a default vector in degrees (the angular difference in the horizontal plane between the default vector and north). The default vector is chosen to point along the surface of the PCB, in the direction of the top of the text on the silkscreen. This is the +X axis on the Pololu LSM303D carrier and the -Y axis on the Pololu LSM303DLHC, LSM303DLM, and LSM303DLH carriers.
  • float heading(vector from)
    Returns the tilt-compensated heading of the given vector in degrees (the angular difference in the horizontal plane between from and north).

1 The automatic detection might fail if you do not use the Pololu boards' default accelerometer address, so you should specify your particular device if you change the state of the SA0 pin.

2 This function will not work for reading TEMP_OUT_H_M and TEMP_OUT_L_M on the LSM303DLHC. To read those two registers, use readMagReg() instead.

3 If the magnetometer data registers are read using register address constants without a specific device prefix (e.g. OUT_Y_H_M), these functions will automatically use the correct register addresses depending on the device type.

Version history

  • 3.0.1 (2016-08-17): Used PI instead of M_PI because M_PI is not defined for Arduino/Genuino 101.
  • 3.0.0 (2016-08-17): Updated library to work with the Arduino Library Manager.
  • 2.1.0 (2015-02-05): Improved autodetect behavior in init(); reverted argument types in register access functions to allow numeric register addresses; other miscellaneous fixes and optimizations.
  • 2.0.0 (2013-11-27): Major rewrite. List of significant changes:
    • Added support for LSM303D.
    • Lowest 4 bits of accelerometer readings are no longer dropped before being stored in a; this makes the values returned by the library more consistent between the LSM303D and older sensors.
    • enableDefault() behavior changed to be more consistent across devices.
    • heading() now returns a float instead of an int.
    • Library constants converted to enums.
    • Added writeReg() and readReg(), which should be usable in place of writeAccReg(), readAccReg(), writeMagReg(), and readMagReg() in most situations.
    • timeoutOccurred() now reports whether a timeout occurred since it was last called instead of only on the most recent readAcc() or readMag() call.
    • Magnetometer gain functions removed; unfortunately, they would have been hard to update to support the LSM303D.
  • 1.4.4 (2013-07-22): Corrected comments explaining heading() function.
  • 1.4.3 (2013-03-15): Enable high resolution mode for LSM303DLHC accelerometer in enableDefault().
  • 1.4.2 (2012-10-31): Cast sensor readings to 16-bit ints for better portability.
  • 1.4.1 (2012-07-06): Added getDeviceType() function for programs that need to autodetect devices and distinguish between them.
  • 1.4.0 (2012-05-24): Added magnetometer gain functions and reading timeout feature; thanks to Joshua Hogendorn and Eric Brundick for these contributions. Added keywords.txt and changed file extensions of examples to .ino.
  • 1.3.0 (2011-12-12): Arduino 1.0 compatibility.
  • 1.2.0 (2011-11-15): Original release. (numbered to avoid confusion with our earlier LSM303DLH library)
    • Besides the name change, the main difference in this library is that you need to call the init() function before using any of the other library functions, typically from within the Arduino setup() function. While the older library only works with the Pololu boards' default accelerometer slave address of 0011000b, this library allows you to specify the slave address with the init() function.

lsm303-arduino's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lsm303-arduino's Issues

LSM303DLHC heading calculation issue

Hi,

I'm ported this example, in node js(the readings coming from executed python code),
so the pitch and roll calculations are ok, but the heading is a bit weird for me. I set the from vector to (0, -1, 0) as the example said, so in this case the heading should show the angle between the North and the y axis.Correct me if i'm wrong but when i testing, i keep the board paralell to the ground and rotate it.It seems the 0 is in the right direction, but when i'm rotate the board the angle is not correct.
Mainly my heading calculations in this file:
https://github.com/Soulskater/RobotControl/blob/master/services/compass/compassService.js
The raw data comes from this python files:
https://github.com/Soulskater/RobotControl/blob/master/python/Magnetometer.py
https://github.com/Soulskater/RobotControl/blob/master/python/Accelerometer.py

Do you have any idea?
Thanks,
Gabor

writeAccReg(regAddr reg, byte value) Initialization Error

I installed the latest lsm303 lib through the Arduino Lib manager and am receiving a Initialization error on writing to the acc register. Here is the complete error:

..........\Arduino\libraries\LSM303\LSM303.cpp: At global scope:

.......\Arduino\libraries\LSM303\LSM303.cpp:259:6: error: prototype for 'void LSM303::writeAccReg(byte, byte)' does not match any in class 'LSM303'

void LSM303::writeAccReg(byte reg, byte value)
^
In file included from C:\Users\CyberPalin\Documents\Arduino\libraries\LSM303\LSM303.cpp:1:0:

.......\Arduino\libraries\LSM303/LSM303.h:177:10: error: candidate is: void LSM303::writeAccReg(LSM303::regAddr, byte)

 void writeAccReg(regAddr reg, byte value);
      ^

.....\Arduino\libraries\LSM303\LSM303.cpp: In member function 'void LSM303::writeReg(byte, byte)':

C:\Users\CyberPalin\Documents\Arduino\libraries\LSM303\LSM303.cpp:321:27: error: invalid conversion from 'byte {aka unsigned char}' to 'LSM303::regAddr' [-fpermissive]

 writeAccReg(reg, value);
                       ^

In file included from.......\Arduino\libraries\LSM303\LSM303.cpp:1:0:

......\Arduino\libraries\LSM303/LSM303.h:177:10: error: initializing argument 1 of 'void LSM303::writeAccReg(LSM303::regAddr, byte)' [-fpermissive]

 void writeAccReg(regAddr reg, byte value);

Not sure what the issue is.

thanks for your help
Mike

32 bit ARM Fail.

code compiles fine, but due to right shift operator gives wrong output. on a 32bit arm platform.

Requires type cast, so the desired 16 bit signed integer is always used:
about line 200 in LSM303.cpp
in function
void LSM303::readAcc(void)

change:
a.x = (xha << 8 | xla) >> 4;
a.y = (yha << 8 | yla) >> 4;
a.z = (zha << 8 | zla) >> 4;
to:
a.x = (int16_t)(xha << 8 | xla) >> 4;
a.y = (int16_t)(yha << 8 | yla) >> 4;
a.z = (int16_t)(zha << 8 | zla) >> 4;

can not even verify

After adding library I open example and get
This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.
Arduino: 1.0.6 (Windows 7), Board: "Arduino Uno"
Heading:3: error: 'LSM303' does not name a type
Heading.ino: In function 'void setup()':
Heading:9: error: 'compass' was not declared in this scope
Heading:17: error: 'LSM303' has not been declared
Heading:17: error: expected primary-expression before '>' token
Heading:17: error: expected primary-expression before ')' token
Heading:17: error: expected ;' before '{' token Heading:18: error: 'LSM303' has not been declared Heading:18: error: expected primary-expression before '>' token Heading:18: error: expected primary-expression before ')' token Heading:18: error: expected;' before '{' token
Heading.ino: In function 'void loop()':
Heading:22: error: 'compass' was not declared in this scope

Heading Decimal Values

Is it possible to produce the heading with any decimal values or in binary that can be changed to a decimal? Some applications may desire tenth of degree measurements.

Issue enabling non default behaivor

compass.writeReg(CTRL_REG1_A, 0x57); throws an "invalid conversion from 'byte' to 'LSM303::regAddr'" error.

The Github page lists 'writeReg(byte register, byte value)' as being the correct way to write to registers.

After Wire.requestFrom() there is no need for a timeout and no endTransmission.

In the functions readAccReg() and readMagReg(), there is a Wire.endTransmission() after the Wire.requestFrom(). That should not be there. The Wire.endTransmission() is only used when writing data.
It is not a big problem, but the Wire.endTransmission() will sent the sensor address to the I2C bus and the sensor will aknowledge. It does no harm, but it is unnecessary.

In the functions readAcc() and readMag(), there is a timeout after Wire.requestFrom(). That timeout is not needed. The Wire.requestFrom() waits until the I2C transmission has completely finished. After that, the received data is in a buffer in the Wire library. The Wire.available() shows how many bytes there are in that buffer.
The timeout is not needed, but in case there was a I2C bus error, it does detect that not all bytes are received and it does return with an error.

The return value of Wire.requestFrom() or the Wire.available() could be be used once to check if the correct number of bytes was received or if a bus error did occur.

Add option/example to calibrate accelerometer

Hi! Thanks for making this, finding a way to tilt-compensate compass was a pain, and this just works!

However, my tilt-compensation doesn't work perfectly, and I think that's because of accelerometer is not calibrated well enough - I'm getting X: -960 Y:-176 on perfectly flat surface.
It would be nice if there was just some .calibrateAccel() method to correct this

Default is missing in the switch case.

Hi,

for the switch case in LSM303.cpp from line 126 missing the line
default: break;
at the end.
This is very important when working with a better configured toolchain. Otherwise it will no longer compile.

Failed Sensor Freezes Program

If the compass stops working for any reason (loose VIN in my case), trying to read the compass will cause the program to totally freeze up. This seriously needs to be fixed. One failed sensor should not crash an entire system.

Connecting two LSM303?

I need to connect to two LSM303 using an I2C bus. Creating one LSM303 seems to read data from both devices, and when creating two they both read from both devices. How do I specify two separate devices? I could not find a way to specify the address. Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.