Difference between revisions of "Sparkfun: HMC5883L Magnetometer"

From eLinux.org
Jump to: navigation, search
(Connecting to the Bone)
(Communicating with the HMC5883L Using the Shell)
 
(8 intermediate revisions by 2 users not shown)
Line 3: Line 3:
  
 
<pre style="color:red">
 
<pre style="color:red">
Overview:  1, show a picture of the device that shows what pins it has.
+
Overview:  2
Wiring:   1, Give a diagram that shows how the pull up resistors are used.
+
Wiring:   2, a bit fuzzy, but I can figure it out.
Code:     0,  i2cget can get 16bit values.  Check out the 'w' option.
+
Code:     1,  i2cget can get 16bit values.  Check out the 'w' option.
git:   0 put in git
+
git:       2
Demo:     0
+
Demo:     2
Total:   2/10
+
Total:     9/10
 
Comments:  More details are needed.  I think someone else in the class would have trouble
 
Comments:  More details are needed.  I think someone else in the class would have trouble
 
reproducing what you have done.  I'd like to see a C code version working.  I'm not sure
 
reproducing what you have done.  I'd like to see a C code version working.  I'm not sure
Line 102: Line 102:
 
|}
 
|}
  
The sensor values for each axis are 16-bit and are stored across 2 registers each.
+
The sensor values for each axis are 16-bit and are stored across 2 registers each assuming the devise is connected to I2C bus 3.
  
 
beagle$ '''i2cget -y 3 0x1e 3'''
 
beagle$ '''i2cget -y 3 0x1e 3'''
Line 110: Line 110:
 
will get the two halves of the 16-bit signed measurement along the +x axis.
 
will get the two halves of the 16-bit signed measurement along the +x axis.
  
By default the magnetometer takes a single sample and enters idle mode.The lowest two bits of the mode register control the measurement mode. Setting these to 0x01 will cause the device to take one measurement and then enter idle mode again. Setting to 0x00 should cause the device to enter continuous measurement mode,  
+
'''Note:''' '''i2cget -y 3 0x1e 3 w''' gets both bytes of the X-Axis, but the bytes are flipped so the less significant byte is first.
 +
 
 +
 
 +
By default the magnetometer takes a single sample and enters idle mode.The lowest two bits of the mode register (register 02) control the measurement mode. Setting these to 0x01 will cause the device to take one measurement and then enter idle mode again. Setting to 0x00 should cause the device to enter continuous measurement mode where measurements are taken periodically at a sampling rate set by configuration register A (register 00),  
  
 
beagle$ '''i2cset -y 3 0x1e 2 1'''
 
beagle$ '''i2cset -y 3 0x1e 2 1'''
will cause a single measurement to be taken.
+
writes a 1 to register 02 and this will cause a single measurement to be taken.
  
 
The new values for each axis can be read from registers 03-08 as shown above. By default the measurements correspond to 1090 LSB/Gauss, but this can be changed by modifying the gain in Configuration Register B.
 
The new values for each axis can be read from registers 03-08 as shown above. By default the measurements correspond to 1090 LSB/Gauss, but this can be changed by modifying the gain in Configuration Register B.
Line 119: Line 122:
 
Note: reading a value of 0xF000 (-4096) in a data output register indicates an overflow or underflow error in the ADC or a math error.
 
Note: reading a value of 0xF000 (-4096) in a data output register indicates an overflow or underflow error in the ADC or a math error.
  
==Using C==
+
==C Example Code==
 +
 
 +
the [http://elinux.org/EBC_Exercise_12_I2C I2C code] from exercise 12 can be used to communicate with the magnetometer. I modified myi2cget.c from this exercise to create a [https://github.com/duganje/ECE497_duganje/tree/master/MiniProject02 program] that puts the magnetometer into continuous measurement mode and reads and prints the values measured along each axis in an infinite loop.
 +
 
 +
==Graphical Display using Node.js==
  
the [http://elinux.org/EBC_Exercise_12_I2C I2C code] from exercise 12 should work for the magnetometer, but it produces an error trying to read from or write to the device. This is probably because the magnetometer I2C operates at 400Khz and the bone uses 100kHz, so anything other than the simple shell commands produces corrupted data due to timing errors.
+
Starting with the [https://github.com/MarkAYoder/BeagleBoard-exercises/tree/master/node.js/realtime node.js code] provided as a starting point for [http://elinux.org/EBC_Mini_Project_04 Miniproject04], I wrote a [https://github.com/duganje/ECE497_duganje/tree/master/MiniProject04 program] that creates a web-based graphical display of the magnetometer measurements. The program requires the nodejs package to be installed
 +
beagle$ '''opkg update'''
 +
beagle$ '''opkg install nodejs'''
  
==Example Code==
+
To run the code on the Bone:
The following shell script sets the magnetometer to continuous measurement mode and then reads and displays the sensor values every half seconds assuming the sensor is connected to I2C bus 3.
+
beagle$ '''node buttonBox.js'''
  
# read the sensor value of a magnetometer
+
Then point you web browser to '''bone:8081''' where bone is the ip address of you Bone
+
This is what the display should look like
cleanup() { # Release the GPIO port
+
[[File:Nodejs.jpg]]
  echo ""
 
  exit
 
}
 
 
trap cleanup SIGINT # call cleanup on Ctrl-C
 
 
XM=0
 
XL=0
 
YM=0
 
YL=0
 
ZM=0
 
ZL=0
 
 
#set to continuous measurement mode
 
i2cset -y 3 0x1e 2 0
 
 
# Read forever
 
 
while [ "1" = "1" ]; do
 
 
#read sensor values
 
  XM=`i2cget -y 3 0x1e 3`
 
  XL=`i2cget -y 3 0x1e 4`
 
  ZM=`i2cget -y 3 0x1e 5`
 
  ZL=`i2cget -y 3 0x1e 6`
 
  YM=`i2cget -y 3 0x1e 7`
 
  YL=`i2cget -y 3 0x1e 8`
 
 
  echo -n -e "X_MSB=${XM} X_LSB=${XL} Y_MSB=${YM} Y_LSB=${YL} Z_MSB=${ZM} Z_LSB=${ZL}\r"
 
  # sleep for a while
 
  sleep 0.5
 
done
 
 
 
cleanup # call the cleanup routine
 

Latest revision as of 10:35, 6 November 2012


Overview:  2
Wiring:    2, a bit fuzzy, but I can figure it out.
Code:      1,  i2cget can get 16bit values.  Check out the 'w' option.
git:       2
Demo:      2
Total:     9/10
Comments:  More details are needed.  I think someone else in the class would have trouble
reproducing what you have done.   I'd like to see a C code version working.  I'm not sure
the clock difference is the problem.

Overview

The HMC5883L Magnetometer is a sensor that measures the magnetic field vector in three dimensions. the Magnetometer uses a 400KHz I2C bus to communicate. The breakout board comes with filtering capacitors and four pins: Vcc, ground, and the two I2C pins (clock and data).

Magnetometer.jpg

Connecting to the Bone

The Beagle Bone can be connected to the magnetometer via the I2C bus. Ground and Vcc on the breakout board should be connected to pins 1 and 2 respectively on the bone's P9 header, and the SCL and SDA pins should be connected to one of the I2C pairs on the bone. I used I2C bus 3 (pin 19 on header P9 connected to SCL and pin 20 on P9 to SDA) because it is configured out of reset. 4.7kΩ pullup resistors should be connected between SCL and Vcc and between SDA and Vcc.

Miniproject2.JPG

The address of the magnetometer can be found by using the i2cdetect command from the shell. I get:

beagle$ i2cdetect -y -r 3
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- UU -- -- 1e -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

The address should be 0x1e

Communicating with the HMC5883L Using the Shell

the HMC5883L has 13 8-bit registers:

Address Name Access
00 Configuration Register A Read/Write
01 Configuration Register B Read/Write
02 Mode Register Read/Write
03 Data Output X MSB Register Read
04 Data Output X LSB Register Read
05 Data Output Z MSB Register Read
06 Data Output Z LSB Register Read
07 Data Output Y MSB Register Read
08 Data Output Y LSB Register Read
09 Status Register Read
10 Identification register A Read
11 Identification register B Read
12 Identification register C Read

The sensor values for each axis are 16-bit and are stored across 2 registers each assuming the devise is connected to I2C bus 3.

beagle$ i2cget -y 3 0x1e 3

beagle$ i2cget -y 3 0x1e 4

will get the two halves of the 16-bit signed measurement along the +x axis.

Note: i2cget -y 3 0x1e 3 w gets both bytes of the X-Axis, but the bytes are flipped so the less significant byte is first.


By default the magnetometer takes a single sample and enters idle mode.The lowest two bits of the mode register (register 02) control the measurement mode. Setting these to 0x01 will cause the device to take one measurement and then enter idle mode again. Setting to 0x00 should cause the device to enter continuous measurement mode where measurements are taken periodically at a sampling rate set by configuration register A (register 00),

beagle$ i2cset -y 3 0x1e 2 1 writes a 1 to register 02 and this will cause a single measurement to be taken.

The new values for each axis can be read from registers 03-08 as shown above. By default the measurements correspond to 1090 LSB/Gauss, but this can be changed by modifying the gain in Configuration Register B.

Note: reading a value of 0xF000 (-4096) in a data output register indicates an overflow or underflow error in the ADC or a math error.

C Example Code

the I2C code from exercise 12 can be used to communicate with the magnetometer. I modified myi2cget.c from this exercise to create a program that puts the magnetometer into continuous measurement mode and reads and prints the values measured along each axis in an infinite loop.

Graphical Display using Node.js

Starting with the node.js code provided as a starting point for Miniproject04, I wrote a program that creates a web-based graphical display of the magnetometer measurements. The program requires the nodejs package to be installed

beagle$ opkg update
beagle$ opkg install nodejs

To run the code on the Bone:

beagle$ node buttonBox.js

Then point you web browser to bone:8081 where bone is the ip address of you Bone This is what the display should look like Nodejs.jpg