Help needed with magnetometer coding.

I am trying to make a sensor with the HMC5883L magnetometer to detect a change in the magnetic field and send a serial message when it does change. I'm trying to go about it by tracking the first reading of the sensor and then compare it to the most recent reading. My problem is I can not figure out how to save the first variable to compare to the new readings. Any help would be appreciated.

Typically you would, in setup(), call the function to get a reading and save that reading in a global variable. Give that a try and if you can't get it to work, post your code.

#include <Wire.h> 
#define address 0x1E


void setup(){

  Serial.begin(9600);
  Wire.begin();
  

  Wire.beginTransmission(address); 
  Wire.write(0x02); 
  Wire.write(0x00); 
  Wire.endTransmission();
}

void loop(){
  
  int x;

 
  Wire.beginTransmission(address);
  Wire.write(0x03);
  Wire.endTransmission();
  
 

  Wire.requestFrom(address, 6);
  if(6<=Wire.available()){
    x = Wire.read()<<8;
    x |= Wire.read();
  }
  
  Serial.print("x: ");
  Serial.print(x);
  Serial.print("  ");
  delay(250);
}

Thank you for the reply. my problem is when i set it to a variable i can not get it to stay the first reading of the sensor it is constantly changing with the sensor.

You can use a library to read the sensor. I use the Adafruit library and until now I had no problems: https://learn.adafruit.com/adafruit-hmc5883l-breakout-triple-axis-magnetometer-compass-sensor/wiring-and-test

Thank you for the link. i have been able to read the sensor. my problem now is saving the first output of the sensor and then using it to compare to the new sensor readings coming in.

As John suggested, read the first value in setup() and save it for comparison. It will need to be a global variable so that both setup() and loop() can access it. For example (your code would greatly benefit from some comments):

#include <Wire.h> 
#define address 0x1E

int firstx;   //global variable.

void setup(){

  Serial.begin(9600);
  Wire.begin();
  

  Wire.beginTransmission(address); 
  Wire.write(0x02); 
  Wire.write(0x00); 
  Wire.endTransmission();

  Wire.beginTransmission(address);
  Wire.write(0x03);
  Wire.endTransmission();
  
  Wire.requestFrom(address, 6);
  if(6<=Wire.available()){  //get and save first reading
    firstx = Wire.read()<<8;
    firstx|= Wire.read();
}

void loop(){
  
  int x;

 
  Wire.beginTransmission(address);
  Wire.write(0x03);
  Wire.endTransmission();
  
 

  Wire.requestFrom(address, 6);
  if(6<=Wire.available()){
    x = Wire.read()<<8;
    x |= Wire.read();
  }
  
  Serial.print("x: ");
  Serial.print(x);
  Serial.print("  ");
  delay(250);

// compare x and firstx here, and do something.

// then if you wish, update firstx here as follows:

  firstx = x;

}

The reading does constantly change.

If you expect two consecutive readings to be the same, you will be waiting a long time.

  Wire.requestFrom(address, 6);
  if(6<=Wire.available()){
    x = Wire.read()<<8;
    x |= Wire.read();
  }

I find it really hard to read ass-backwards logic statements like that. But, if you are asking for 6 bytes, and expecting 6 bytes to be available, why are you only reading two?

Thank you for the great code jremington. Your help is greatly appreciated, it is working wonderfully now.

PaulS has a good point. According to the datasheet, the magnetometer will not update the readings until all six data bytes are read, so who knows what you are getting.

You should modify the code to read y and z in the same way that you read x, but do not do anything with the values.