LSM303D Value Jumps/Offsets

I’m recording data from the Pololu LSM303D carrier and from a BME280 breakout. The end idea is see if we can see the Earth’s diurnal variations or at least large magnetic storms. It’s right at the edge of the sensor resolution, but we’ll give it a shot. The temperature data recorded is to help us do a valid temperature correction, but that’s another story.

My setup is an Arduino Uno, the LSM303D, and the BME280 with a level shifter. I’m recording using the OpenLog. After recording, I change things to absolute time stamps, re-interpolate to a fixed timebase, etc. For now I’m just going to show the raw data coming back from the sensor using the recommended driver for the Arduino.

Offset Issue

I’ve included two plots of the total field data (vector magnitude) below. The second is just zoomed in on the center of the first. You can see a sudden offset in the readings. These occur throughout the data. After trying to correlate them with everything (heating system, time of day, etc) nothing works out and they appear pretty much random. Any ideas what could be causing such offsets? They make doing time domain filtering impossible.

#include <BME280_MOD-1022.h>
#include <LSM303.h>
#include <Wire.h>



const int NUM_AVG = 5000;
const int WX_AVG = 5;

LSM303 compass;

void setup()
{

  Serial.begin(9600); 
  Wire.begin();
  compass.init();
  compass.enableDefault();
  
  
  // Setup BME280
  BME280.writeStandbyTime(tsb_0p5ms);        // tsb = 0.5ms
  BME280.writeFilterCoefficient(fc_16);      // IIR Filter coefficient 16
  BME280.writeOversamplingPressure(os16x);    // pressure x16
  BME280.writeOversamplingTemperature(os2x);  // temperature x2
  BME280.writeOversamplingHumidity(os1x);     // humidity x1
  BME280.writeMode(smNormal);
  
}


void loop()
{
  log_wx();
  log_mag();
}

void log_wx()
{
    float temperature = 0;
    float humidity = 0;
    float pressure = 0;
    
    for(int i = 0; i<WX_AVG; i++){
        BME280.readCompensationParams();  
        while (BME280.isMeasuring()) {}
        BME280.readMeasurements();
        temperature += BME280.getTemperatureMostAccurate();
        humidity += BME280.getHumidityMostAccurate();
        pressure += BME280.getPressureMostAccurate();
    }
    
  temperature = temperature/WX_AVG;
  humidity = humidity/WX_AVG;
  pressure = pressure/WX_AVG;
 
  Serial.print(millis());
  Serial.print(",");
  Serial.print(temperature);
  Serial.print(",");
  Serial.print(humidity);
  Serial.print(",");
  Serial.print(pressure);
  Serial.print(",");
    
}

void log_mag()
{
 int i;
 long lx,ly,lz;
 double x,y,z;
 int n = 1000;
 // Average n measurements
 lx = 0; ly = 0; lz = 0;
 for(i=0;i<n;i++)
 {
   compass.read();
   lx += (long) compass.m.x;
   ly += (long) compass.m.y;
   lz += (long) compass.m.z;
 }
 x = (double) lx / (double) n;
 y = (double) ly / (double) n;
 z = (double) lz / (double) n;
 
 Serial.print(x); 
 Serial.print(",");
 Serial.print(y); 
 Serial.print(",");
 Serial.println(z);
}

Please post a few examples of the raw readings (numbers) immediately around the discontinuity, not a plot of the vector magnitude. It could be that only one axis is causing the problem.

I’ve got a few jumps in mine. A friend across town is trying the same experiment so we can compare. I’ve found a chunk of his data with several transitions (attached). Format ms_stamp, temperature, mx, my, mz. I think we’ll try running on batteries instead of wall-warts and drop all averaging to see if the jumps are still there. Would be interesting if you can reproduce. I just got a second breakout delivered and will try with it as well.

jumps.txt (22.0 KB)

Hmmm. In that case the discontinuities are on all three axes. The latter column is the vector magnitude. Could be a power supply problem.

2324716.25 17.19 461.1 2151.08  -3849.3  4433.606756
2324738.25 17.19 483.64 2194.21 -3868.52 4473.691112

2328812.5 17.12	487.34	2192	-3869.91 4474.211404
2328834.5 17.19	476.31	2158.13	-3858.09 4446.263011

Will give it a try with a USB battery powering things for a few days and see what happens. Stay tuned!

After a long hiatus, we plugged up the unit with a USB battery powering the Arduino, sensor, and an OpenLog. The attached plot shows the offsets are still present. Any ideas? We’ve tried and can’t find anything that it correlates with. Plot includes temperature, Bx, By, Bz.

Hi.

We are also not sure why you are seeing those jumps. Have you tried using other magnetometers to see if you observe the same effects? If you haven’t, but would like to, email us at support@pololu.com and we might be able to help you with a discount on some more sensors.

Also, if you would like, we can try to reproduce your results to see if it is an issue with your setup or the magnetometer. If so, could you post the latest code you are using and tell us how you processed and graphed the data?

Kevin

I’ll have to look back - I think we also saw this on the MAG3110, but it is also much less sensitive.

It would be great to see if you see the same thing. You could just use the example code and log the serial output. We had an MCP9808 temperature sensor as well. The data were read into Mathematica by a coworker for the posted plot, no real processing done, just plotted. I generally use Python and have a similar plotting setup there.

`

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

LSM303 compass;

// Create the MCP9808 temperature sensor object
Adafruit_MCP9808 tempsensor = Adafruit_MCP9808();

char report[128];
int numberAveraged;
boolean includeTime;
/*============================================================================*/
void setup()
{
  Serial.begin(9600);
  Wire.begin();
  
  compass.init();
  compass.enableDefault();

  if (!tempsensor.begin()) {
    Serial.println("Couldn't find MCP9808!");
    while (1);
  }
  Serial.println("#Time Temperature mx my mz");
}
/*============================================================================*/
void loop()
{
  includeTime = true;
  numberAveraged = 1000;
  print_values(includeTime, numberAveraged);
  delay(20000);
}
/*============================================================================*/
void print_values(boolean includeTime, int n)
{
  int i;
  long lx,ly,lz;
  double x,y,z;
  // Average n measurements
  lx = 0; ly = 0; lz = 0;
  for(i=0;i<n;i++)
  {
    compass.read();
    lx += (long) compass.m.x;
    ly += (long) compass.m.y;
    lz += (long) compass.m.z;
  }
  x = (double) lx / (double) n;
  y = (double) ly / (double) n;
  z = (double) lz / (double) n;
  //
  // print the values
  if(includeTime)
  {
    Serial.print(millis()*0.001); 
    Serial.print(", ");
  }
  // Read and print out the temperature, then convert to *F
  float c = tempsensor.readTempC();
  //float f = c * 9.0 / 5.0 + 32;
  Serial.print(c);Serial.print(", ");
  
  Serial.print(x); Serial.print(", ");
  Serial.print(y); Serial.print(", ");
  Serial.println(z);
}
/*============================================================================*/`

I tried running a slightly changed version of your code over the weekend; I’ve attached my plots below. I’m not seeing anything that looks obviously discontinuous, so if your results seemed very different, I’d suspect a problem with either your particular sensor or something else in your system.

For comparison, I also tried getting readings from a different magnetometer (LIS3MDL), and those plots are also below. Those results seem like they might be too noisy to be useful for you, although I’m not sure at this point whether that is the limit of the LIS3MDL’s performance or if it is not configured optimally.

Kevin

What do you suppose causes the prominent dips, exactly 24 hours apart?

Did you record temperature as well? My best guess is those mark the building AC schedule?

I didn’t have a record of the temperature, but given that the spikes were at the same time every day and that they showed up on both magnetometers, I’m inclined to think there was something actually happening and it wasn’t just the sensors acting up.

Edited to add - I had the setup near a window, so that was probably the time each day when sunlight was coming through the window and heating up the sensors.

Interesting… I have another LSM303 - I’ll try a multi-unit comparison next week.

Was your setup battery powered and logged on an SD card, or were you powered for a wall-powered computer? Trying to replicate as well as I can.

I was plugged into the wall via a USB adapter but logging onto an SD card (so that I could put it out of the way where I’d be less likely to disturb it).

Did you find the source of the problem?
I am using the LSM303D and I see these jumps when I cycle the power, and that makes the calibration useless.
It looks like the magnetometer has two different states to initialize.
Thanks

Hi, @Marfil. I don’t know if @geo_leeman reached a conclusion, but I don’t really have anything new to add. If you tell us more about your setup and results, and explain when you see the jumps (including if you’ve found a way to consistently trigger them), I might be able to look some more into reproducing the problem and trying to understand it.

Kevin

Kevin:

I am not using a commercial board.

It looks like the problem happens at power cycling, I wait 10 sec
between power OFF and ON.

The magnetometer is mounted on a board that is power 1 sec after the
main system, then the problem is not because of fast power cycling.

It looks like the magnetometer starts with different offsets, and these
offsets are not random, they are A or B.

I read the OFFSET registers to be sure I was not writing on them by mistake.

I am powering my unit with a small power supply , if I unplug the power
supply from the wall the “jump” does not happen, if I switch the power
between the power supply and the unit the “jump” happens approx 20% of
the time. After the “jump” if I cycle power from the wall the
magnetometer does not “jump” stays in the state A or B.

I am using the magnetometer at 2 Gauss scale, and the “jumps” I see are
about 250 bits.

Thanks

Hi all,

I haven’t resolved the issue. The project got buried under some pressing jobs and I haven’t had a chance to get back to it. @Marfil - do you have some plots that we could compare?