First Arduino default I²c address is 7-bit address, the manual is described, 7-bit address is 0x1e, read address is 0x3d = (7-bit address <<1 + 1), write address is 0x3c (7-bit address << 1)
If you want to communicate with the hmc5883l, you need to hmc5883l power on the 5ms. Therefore, the general write configuration requires a delay of 5ms before communication.
After connecting the device to test the sensor, identify the operation and identify register a, identify register B, identify register C is related, so want to know whether the sensor is working properly read their values to verify, because they are three read-only registers, technology static test
Identify register a address 0x0A default value is 0x48
Identify register B address 0x0B default value is 0x34
Recognition Register C address 0x0C default value is 0x33
Read the value of the Register to ensure that the device communicates properly.
What we care about most about the sensor is how to read its value and how to handle the Read value.
The measured value of the sensor is placed in X, Y, z 16-bit registers, there are two continuous and one-time measurements on the measurement mode, single measurement I used a bit, not very good, so the following main introduction of continuous measurement.
Configuration as a continuous measurement is simple, is the above mode register, address 0x02
As you can see, configuring a continuous measurement mode requires only writing the mode register to 0x00.
Configuration to continuous, configured as sequential read mode there is a very important place to remember: read XYZ, must read 6 bytes at a time, that is, all read, otherwise the data is not updated! the manual does not give a specific explanation, but I guess it should be a write address and read address common an address caused this phenomenon .
Data processing :
x, y, Z 16 bits of data after reading the need to use the conversion angle, just start to convert the angle has been wrong, and very puzzled because see the online ready code is that set of formulas, atan2 (y,x) *180/pi+180 But his calculation is wrong.
It turns out that the X, Y, Z registers on the manual don't refer to actual x, Y, z
In fact, X, Y, Z is x,z,y stored in the data region, and pseudo-code is represented as
Requestfrom (0x3d,6);
x = Wire.read () <<8 | Wire.read ()
z = wire.read () <<8 | Wire.read ()
y = wire.read () <<8 | Wire.read ()
double degree=atan2 (y,x) *180/pi+180
the degree is the angle between hmc5883l and magnetic north direction. My test results are basically the same as the iphone's own sensor values, the error is between 3-5 degrees, which may be interference or my artificial error caused, so the effect is satisfactory.
The following is the test code;
#include <math.h> #include <Wire.h> #define ADDRESS 0x1econst int led_pin=13;const int rady=22;void setup () { Pinmode (Rady, INPUT);p Inmode (Led_pin, OUTPUT); Serial.begin (115200);d Elay (5); Wire.begin (); Wire.begintransmission (ADDRESS); Wire.write (0x02); Wire.write (0x00); Wire.endtransmission (); Wire.begintransmission (ADDRESS); Wire.write (10); Wire.endtransmission (); Wire.requestfrom (address,1); if (Wire.available () ==1&&wire.read () ==0x48) {serial.println ("Connect Success" );} ELSESERIAL.PRINTLN ("Connect failure"); Wire.begintransmission (ADDRESS); Wire.write (0x02); Wire.endtransmission (); Wire.requestfrom (address,1); if (wire.available () ==1) {switch (Wire.read ()) {case 00:serial.println ("sequence measure "); Break;case 01:serial.println ("single measure"); BREAK;DEFAULT:SERIAL.PRINTLN ("other measure"); Break;}}} void Loop () {wire.begintransmission (ADDRESS); Wire.write (0x03); Wire.endtransmission (); Wire.requestfrom (address,6);//delay, if (wire.available () ==6&&digitalread (Rady)) {Serial.print("Receive:"); int x=wire.read (); x=x<<8| (Wire.read ()); int z=wire.read (); z=z<<8| (Wire.read ()); int y= Wire.read (); y=y<<8| (Wire.read ()); float rot=atan2 (y,x) *180/pi+180; SERIAL.PRINTLN (ROT);} Else{serial.print ("Rady is"); Serial.println (Digitalread (rady)? " High ":" Low ");} Delay (1000);}
Arduino and Compass sensor hmc5883l