This PicBasic Pro code reads a Parallax HM55B Compass module.
'Parallax / Hitachi Compass Module code
' John Schimmel October 2005
' http://itp.nyu.edu/physcomp/sensors/
'
include "modedefs.bas"
DinDout var portc.3
Clk var portc.2
En var portc.1
output clk
output en
Reset con %0000
Measure Con %1000
Report CON %1100
Ready CON %1100
NegMask Con %1111100000000000
x Var word
y var word
newX var byte
newY var byte
stats var byte
angle var word
product var byte
'serial variables
TX var portc.6
RX var portc.7
serialSet CON 16468
main:
gosub Compass_Get_Axes
Serout2 TX,serialSet,[SDEC x," | "]
serout2 tx,serialSet,[Sdec y," | "]
if x.bit10 = 1 then
serout2 tx, serialSet, ["-x | "]
else
serout2 tx, serialSet, ["+x | "]
endif
if y.bit10 = 1 then
serout2 tx, serialSet, ["-y | "]
else
serout2 tx, serialSet, ["+y | "]
endif
serout2 tx,serialSet,[dec abs(y.lowbyte),"/",DEC abs(x.lowbyte)," | "]
serout2 tx,serialSet,[DEC (abs(y.lowbyte)/abs(x.lowbyte)*10)," | "]
gosub get_direction
goto main
'-----------------------------------------------
' Get_Directions subroutine is a hack
' It was made from observing the compass's output
' when pointed in the 4 main directions: N, S, E, W
'
' The data was aligned with the directions and
' conditional IF statements were made to fit.
' Again, this is a hack, but a decent one.
'
' The compass returns both positive and negative numbers
' check for x.BIT10 = 1 or y.BIT10=1 to see if the number is
' negative. Use the negative numbers like this:
' +X = NORTH, -X = SOUTH
' +Y = WEST, -Y = EAST
'
' The compass is not really calibrated, and the magenetic fields
' of the circuit could even throw the data off. Please review your
' compass data then calibrate the PRODUCT values in the IF statements below
'-----------------------------------------------
Get_Direction:
product = abs(y.lowbyte)/abs(x.lowbyte) * 10 'get absolute value of (y/x) * 10 to lose the decimal problem
if NOT x.bit10 and (product <= 10) then 'IF X is positive and the product <= 10 then NORTH
serout2 tx,serialSet,["NORTH!",13,10]
return
endif
if x.Bit10 and y.bit10 and (product>=0) and (product<=40) then 'if X is negative and y is negative and product is between 0 and 40 then EAST
serout2 tx,serialSet,["EAST!",13,10]
return
endif
if x.Bit10 and NOT y.bit10 and (product=0) then ' if X is negative and Y is positive and product=0 then SOUTH
serout2 tx,serialSet,["SOUTH!",13,10]
return
endif
if x.Bit10 and not y.bit10 and (product>=10) and (product<=40) then ' if X is negative and Y is positive and product is between 10 and 40.
serout2 tx,serialSet,["WEST!",13,10]
return
endif
serout2 tx,serialSet,[13,10]
return
'-------------------------------------------------------
' Compass_Get_Axes was originally written by Parallax for
' the BASIC STAMP 2. The code is identical for PICBasic Pro.
'
' From parallax:
' "The polling is a combination of SHIFTOUT commands that request the status,
' and SHIFTIN commands that acquire the status. When the SHIFTIN receives
' status flags indicating that the measurement is complete, a second and third
' SHIFTIN command can then store the 11-bit x and y axis measurements in variables."
'-------------------------------------------------------
Compass_Get_Axes:
High En:Low En ' Turn the enable pin high then low to prepare compass for message
Shiftout DinDout,clk,MSBFIRST,[Reset\4] ' SHIFTOUT the first 4 bits of Reset (i.e. 0000)
High En:Low En ' Again,Turn the enable pin high then low to prepare compass for message
Shiftout DinDout,Clk,MSBFIRST,[Measure\4] ' SHIFTOUT the first 4 bits of Measure (i.e 1000)
stats = 0
While Ready != stats 'Loop until the SHIFTIN command receives stats AND stats = ready
high en:low en ' prepare for message
shiftout dindout,clk,MSBFIRST,[Report\4] ' shiftout out command for compass reading
shiftin DinDout,CLk,MSBPOST,[stats\4] 'shiftin the status of the reading
WEND
'when the status of the compass is ready, SHIFTIN the X and Y values
Shiftin DinDout,clk,MSBPOST,[x\11,y\11]
high en ' turn off compass
'deal with negative numbers
if (y.10 = 1) then y=y | negmask
if (x.10 = 1) then x=x | negmask
return