Compass Sensor
 
1. Earth's magnetic field

As everyone knows, the earth's magnetic field can be respresented as a dipole situated about 440 km off center and inclined 11 degrees to the planet's rotation axis. The strength of the field is 0,5 Gauss, which is quite small. There exist only a few kinds of magnetometers able to read such a weak magnetic field strength:

The last categorie is the one we try to realize using the magnetoresistive sensor K MZ51 from Philips.

2. K MZ 51

This electronic device is a high sensitive magnetic field sensor released in 1996. It employs the magnetoresistive effect of thin-film permalloy. The sensor contains a magnetoresistive Wheatsone bridge and integrated compensation and set/reset coils. Simplified circuit diagram:

Some typical data:

Symbol Parameter Min Typ. Max Unit
Vcc bridge power voltage - 5 8 V
V(offset) offset voltage -1.5 - +1.5 mV/V
R(bridge) bridge resistance 1   3 kOhm
R(comp) compensation coil resitance 100 170 300 Ohm
R(flip) flip coil resistance 1 3 5 Ohm
I(flip) recommended flipping current 800 1000 1200 mA (!)
t(flip) flip pulse duration 1 3 100 micro-sec

A short current pulse on the flip coil is necessary to recover the sensor after exposure to strong disturbing magnetic fields. Note: The package is held in SMD-technic. The difference between +Vo and -Vo can be expressed as:

dV = Vmax*cos(Theta).

3. Electronics

 

This is our first proto-type. The KM Z51 is powered with 5.1V through the 420 Ohm-resistor and stabilized by the means of the Z-diode. The 1 microFarad Capacitor is discharged through R1 and the KM Z51 internal flip coil whenever the switch is operated. This produces a high and short current pulse. R1=(5 - flip coil resistance). The 100k potentiometer is used for offset-regulation. Use a screw-potentiometer and be patient ! The LM 324 is used in a first stage as differential-amplifier and comparator. The last stage is an inverting amplifier. The signal is sent to the RCX through the 1 kOhm resistor. Remember to set the sensortype to light-type. This will cause the RCX to send alternatively a 3 ms power-supply followed by a 0.1 ms-sensor-reading. The 22 microFarad capacitor acts as the power-supply during the reading-phase. The extreme sensitivity of the sensor causes a remarkable drift of the returned values. If the sensor-mode is set to percent-mode, the values will variate from 0 to 95.

This is not the end of our research! We stay on stand-by for any suggestion.

If the sensor is fixed on a mobile robot, the device will demonstrate the influences of earth's magnetic field, iron objects and other magnetic sources on the returned values. There will be variations of V(max), so that it will not be possible to use absolute values. Therefore the sensor should be placed on a support that allows it to rotate and find the maximum value by comparison. While doing so, the support may rotate but not translate. (Perhaps rapid rotation would minimize variations of V(max) caused by translation, but we are not sure about this.) This compass-sensor as it is designed mustn't present perfect linearity. Nevertheless we tried a smaller gain on the last stage. So the original 100k resistor is replaced by 47k.

4. Sensor-support

1 2
3 4
5 6
7 8
9 10

This design works with a 1/24 transmission for rotation of the sensor's platform and a 3/1 transmission for the turning of the rotation-sensor. So one turn of the platform correspond to 72 revolutions of the rotation-sensor e.a. 72*16=1152 impulses which provide a good accuracy. Experiments showed deviation errors up to 15 impulses = 5 degrees due to unprecision of the gearing. Quite accurate for such a design, isn't it!

5. Program

The following RCX-Code lines command the sensor support in order to find the true magnetic north. The particularity of this program is that it doesn't search the maximum of the sensor values. Instead it uses the trick first to find the east-sided direction where the sensor's value passes to 0 (we took the value 3), then to do so on the west-side. The Lego-rotation-sensor does well the job to provide the exact value of the angle between both directions. After this the program divides this angle by two and moves the sensor to the given direction which will be the true north.

{...variables...}

#define(Last_rotation_position,1)

#define(angle,2)

{...motors...}

#define(compass_motor,0) {connect to output A}

{...sensor_type...}

#define(compass_type,3)

#define(Lego_rotation_type,4)

{...subroutines...}

#define(check_declination,1)

{...tasks...}

#define(time_manager,1)

{...sensors...}

#define(compass_sensor,0) {connect to sensor input 1}

#define(Lego_rotation_sensor,1) {connect to sensor input 2}

{.........................................................................................}

selectprgm(slot_4)

beginoftask(main)

setsensortype(compass_sensor,compass_type)

setsensormode(compass_sensor,percent_mode,0)

setsensortype(Lego_rotation_sensor,Lego_rotation_type)

setsensormode(Lego_rotation_sensor,angle_mode,0)

setpower(compass_motor,con,4)

starttask(time_manager)

endoftask()

{-------------------------------------------------------------------------------------------}

beginoftask(time_manager)

loop(con,forever)

gosub(check_declination)

wait(con,2000)

endloop()

endoftask()

{----------------------subroutine...------------------------------------}

beginofsub(check_declination)

setfwd(compass_motor)

while(senval,compass_sensor,LT,con,15) {wait until value >=15}

on(compass_motor)

endwhile()

while(senval,compass_sensor,GT,con,3) {wait until value <=3}

on(compass_motor)

endwhile()

setvar(Last_rotation_position,senval,Lego_rotation_sensor)

setrwd(compass_motor)

on(compass_motor) {return a little bit}

wait(con,30)

off(compass_motor)

while(senval,compass_sensor,GT,con,3) {wait until value <=3, but this time other direction}

on(compass_motor)

endwhile()

setvar(angle,senval,Lego_rotation_sensor)

sumvar(angle,var,Last_rotation_position) {use subvar if motor turns differently due to connection}

off(compass_motor)

divvar(angle,con,2) {search the midth}

setfwd(compass_motor)

while(senval,Lego_rotation_sensor,LT,var,angle)

on(compass_motor)

endwhile()

off(compass_motor)

endofsub()


  RetourMain page