4
\$\begingroup\$

I have a LIS3MDL outputting what seem to be reasonable magnetic field strength values (see second image). However, I am confused why the temperature reading seems to be dependent on the orientation of the magnetometer when I performed the "figure 8" motions. As far as I understand, the temperature value I am reading is used as an input to a compensation algorithm in the magnetometer, so it should be independent of the field itself.

Concerning acquisition of the value, I am reading out the 16-bit, 2's complement value and then dividing by 2^8 and offsetting to 25 degC. I believe this is justified by the application note AN4602 (http://www.st.com/resource/en/application_note/dm00136626.pdf):

Serial.print((((int16_t)((buf[8] << 8) | buf[7])) / 256.0) + 25.0); // temp

Temperature Readings

Magnetometer values "Figure 8"

\$\endgroup\$
  • 1
    \$\begingroup\$ Is the board equipped with decoupling capacitors? Is the voltage filtered and stable? What about computing cross-correlation between two signals to make sure the temperature is correlated with angle? \$\endgroup\$ – Marko Buršič Mar 17 '17 at 0:10
  • 1
    \$\begingroup\$ I seriously doubt the temperature is going up and down 7 degrees celcius every second... so it's either reading it wrong or more likely you are somehow. Are you sure you are actually reading the temperature? \$\endgroup\$ – Trevor_G Mar 17 '17 at 1:16
  • 1
    \$\begingroup\$ You could also leave it sitting and warm it up with a heat gun or hair drier and see if it changes as much you expect. If it doesn't then you are not reading the temperature. Though bare in mind the magnetic values will change a bit too. \$\endgroup\$ – Trevor_G Mar 17 '17 at 1:44
  • 1
    \$\begingroup\$ @abc - I suggest going back to basics, cut down your code to the minimum, analyse raw data bytes from the sensor (X, Y, Z and temperature) not the computed values, and look for patterns. As Trevor mentioned, I wonder if your code is actually using the correct bytes from the sensor, to compute the "temperature" value. Looking at calculated values can hide problems visible in the underlying raw data. Also, please perform the "gently heat the stationary sensor" test suggested by Trevor and see what happens to the raw data from the sensor. Do only the expected raw bytes change? \$\endgroup\$ – SamGibson Mar 17 '17 at 4:19
  • 1
    \$\begingroup\$ If that is the MATLAB plot, then use XCORR (signal processing toolbox) : temperature VS. X-axis, temperature VS. Y-axis, temperature VS. Z-axis. It will show and confirm//reject your hypothesis. I gave you an upvote for preparation. \$\endgroup\$ – Marko Buršič Mar 17 '17 at 9:31
2
\$\begingroup\$

I recaptured data and plotted the temperature individually against each magnetometer axis. From the plots below, its apparent that the temperature data was actually the x-axis data.

enter image description here

enter image description here

enter image description here

I believe this is due to the SPI address auto-increment not working as expected. It seems to 'wrap around' only within the mag x/y/z registers, and does not go to the adjacent temperature registers. My original code was:

#define OUT_X_L 0x28
#define OUT_X_H 0x29
#define OUT_Y_L 0x2A
#define OUT_Y_H 0x2B
#define OUT_Z_L 0x2C
#define OUT_Z_H 0x2D
#define TEMP_OUT_L 0x2E
#define TEMP_OUT_H 0x2F
#define SPI_READ_BURST_START OUT_X_L

uint8_t buf[8]; // xyz, temp

...

  spiReadBurstLIS3MDL(SPI_READ_BURST_START, buf, sizeof(buf));
  Serial.print(micros());
  Serial.print("\t");
  Serial.print((int16_t)((buf[1] << 8) | buf[0])); // x
  Serial.print("\t");
  Serial.print((int16_t)((buf[3] << 8) | buf[2])); // y
  Serial.print("\t");
  Serial.print((int16_t)((buf[5] << 8) | buf[4])); // z
  Serial.print("\t");
  Serial.print((((int16_t)((buf[7] << 8) | buf[6])) / 256.0) + 25.0); // temp
  Serial.print("\n");

But after changing to the following, the temperature output is as expected:

...

uint8_t buf[6]; // xyz
int16_t temp;

...

  spiReadBurstLIS3MDL(SPI_READ_BURST_START, buf, sizeof(buf));
  temp = 0xFF & spiReadLIS3MDL(TEMP_OUT_L);
  temp |= spiReadLIS3MDL(TEMP_OUT_H) << 8;
  Serial.print(micros());
  Serial.print("\t");
  Serial.print((int16_t)((buf[1] << 8) | buf[0])); // x
  Serial.print("\t");
  Serial.print((int16_t)((buf[3] << 8) | buf[2])); // y
  Serial.print("\t");
  Serial.print((int16_t)((buf[5] << 8) | buf[4])); // z
  Serial.print("\t");
  Serial.print((temp / 256.0) + 25.0); // temp
  Serial.print("\n");

enter image description here

Thanks for all the input. It was a silly issue with serial comms after all, nothing to do with the sensor.

\$\endgroup\$
  • 1
    \$\begingroup\$ :) Glad you found it. As I suspected. When the data seems too weird to be true.. it usually is. \$\endgroup\$ – Trevor_G Mar 17 '17 at 20:59
  • 1
    \$\begingroup\$ Happy end story.:) \$\endgroup\$ – Marko Buršič Mar 18 '17 at 0:06
0
\$\begingroup\$

You and your face are a heat source. Approximately 1/4 watt/cm^2. Your hands are cooler, but you use your hands to hold the PCB.

Simply by being near, by closely examining the PCB, you are injecting heat and causing temperature gradients.

PCB foil, the default 1ounce/foot^2 CU foil, has thermal resistance of 70 degree Centigrade per watt.

Is that a problem?

\$\endgroup\$
  • 1
    \$\begingroup\$ Again, I want to reiterate that the only thing appearing to cause this is a change in orientation. My grip on the board and distance from heat sources is constant. \$\endgroup\$ – abc Mar 17 '17 at 3:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.