LSM303DLH setup

Hi All,
I am hoping there's a simple answer to my problem! I have just got a LSM303DLH module and it seems to work, in that a demo program I got from github works and returns a value more or less 0-360 (Degs?).

I am not looking for 100% or even 95% accuracy, it just to get my robot to turn 90/180 Degs etc... So true NORTH is relative and not really important.

I added a few lines that I hoped would indicate North & South, but no it does'nt work! have I got the logic right with &&? it does display the heading and I can get down to <0.4 but it still fails.

Here's the lines I added:

if(heading>358.00 && heading<2.00)
{
Serial.println("North");
}
if(heading <182.00 && heading >178.00)
{
Serial.println("South");

Here's the full code:

#include <Wire.h>
#include <LSM303.h>

LSM303 compass;

void setup() 
{
  Serial.begin(9600);
  Wire.begin();
  compass.init();
  compass.enableDefault();
  
  /*
  Calibration values; the default values of +/-32767 for each axis
  lead to an assumed magnetometer bias of 0. Use the Calibrate example
  program to determine appropriate values for your particular unit.
  */
  compass.m_min = (LSM303::vector<int16_t>){-32767, -32767, -32767};
  compass.m_max = (LSM303::vector<int16_t>){+32767, +32767, +32767};
}

void loop() 
{
  compass.read();
  
  /*
  When given no arguments, the heading() function returns the angular
  difference in the horizontal plane between a default vector and
  north, in degrees.
  
  The default vector is chosen by the library 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.
  
  To use a different vector as a reference, use the version of heading()
  that takes a vector argument; for example, use
  
    compass.heading((LSM303::vector<int>){0, 0, 1});
  
  to use the +Z axis as a reference.
  */
  float heading = compass.heading();
  if(heading>358.00 || heading<2.00)
  {
 Serial.println("North");
  }
  if(heading <182.00 || heading >178.00)
  {
   Serial.println("South");
  }
  Serial.println(heading);
  delay(100);
}

Hope someone can help, I still struggle with C.

Regards

Mel.

In thinking about lines of code like this, where "||" is read as "or", try a few values out in your head to see if it works as you expect. Hint: it doesn't.

if(heading <182.00 || heading >178.00)

It looks like you have not calibrated the compass, so you can't expect accurate or even sensible results.

In any case, you can't expect 1 degree accuracy from these units without very careful calibration and absence of nearby sources of magnetic interference, as described here: Sailboat Instruments: Improved magnetometer calibration (Part 1)

Hi jremington,
I am not as stated looking for accuracy, and I am getting sensible consistant results. My problem is converting them in to "NORTH" etc. I used && and not || Look at the lines I added!! but still can't get any output..

Just point me in the right direction!

Regards

Mel.

The code you POSTED uses "||". Replace this with "&&".

The forum expectations are that users asking for help should post the code that they are actually using, or attempting to use.

Hi JR,
Yes I have replaced || with && (if you read my first post properly) but I still get the same result!! In that I never get NORTH or SOUTH in the serial monitor, but the monitor displays consistant values between >358 and <2. I am thinking that 0 or 360 Degs is North?

Here's the lines I changed/added:

if(heading>358.00 && heading<2.00)
{
Serial.println("North");
}
if(heading <182.00 && heading >178.00)
{
Serial.println("South");
}
Serial.println(heading);
delay(100);
}

Here's a screenshot.....
Sure it's simple and I just can't see the wood for the trees. So give me another clue!!

Regards

Mel.

The problem with "North" is compass wrap-around. If heading = 0.50 then

if(heading>358.00 && heading<2.00)

is not true. "||" would work for this line.

Hi JR,
Yes now NORTH works with if heading <=0.50, but as you say I now need to calibrate the device and will have to take a good look at that link you posted above. I suppose if your going to do it! that's the best way. Who know's might try an electronic compass next with LCD, etc... But then again..

Thanks to all for your replies and advice, Regards.

Mel.

a side remark

These kind of lines I always use extra () to be sure how it is evaluated.
precedence is not always trivial in C/C++..

if ((heading < 182.00) && (heading > 178.00)) ...

had a whole thread a few years ago about converting heading to "wind-rose" names