- CON
- _clkmode = xtal1 + pll16x
- _xinfreq = 5_000_000
- servoPin = 19
- ping_pin = 0
- datapin = 4 'SDA
- clockPin = 5 'SCL
- WRITE_DATA = $3C 'Used to perform a Write operation
- READ_DATA = $3D 'Used to perform a Read operation
- CNFG_A = $00 'Read/Write Register, Sets Data Output Rate. Default = 15Hz & 8 samples per measurement
- '160Hz can be achieved by monitoring DRDY pin in single measurement mode.
- CNFG_B = $01 'Read/Write Register, Sets the Device Gain(230-1370 Gauss). Default = 1090 Gauss
- MODE = $02 'Read/Write Register, Selects the operating mode. Default = Single measurement
- 'Send $3C $02 $00 on power up to change to continuous measurement mode.
- OUTPUT_X_MSB = $03 'Read Register, Output of X MSB 8-bit value. (Will read -4096 if math overflow during bias measurement)
- OUTPUT_X_LSB = $04 'Read Register, Output of X LSB 8-bit value. (Will read -4096 if math overflow during bias measurement)
- OUTPUT_Z_MSB = $05 'Read Register, Output of Z MSB 8-bit value. (Will read -4096 if math overflow during bias measurement)
- OUTPUT_Z_LSB = $06 'Read Register, Output of Z LSB 8-bit value. (Will read -4096 if math overflow during bias measurement)
- OUTPUT_Y_MSB = $07 'Read Register, Output of Y MSB 8-bit value. (Will read -4096 if math overflow during bias measurement)
- OUTPUT_Y_LSB = $08 'Read Register, Output of Y LSB 8-bit value. (Will read -4096 if math overflow during bias measurement)
- STATUS = $09 'Read Register, indicates device status.
- ID_A = $0A 'Read Register, (ASCII value H)
- ID_B = $0B 'Read Register, (ASCII value 4)
- ID_C = $0C 'Read Register, (ASCII value 3)
- OBJ
- ping : "Ping"
- Term : "FullDuplexSerial"
- math : "SL32_INTEngine_2"
- VAR
- long ServoStack[32]
- long PingCompassStack[32]
- long range
- long x
- long y
- long z
- byte NE
- byte SE
- byte SW
- byte NW
- Pub Main
- term.start(31, 30, 0, 9600)
- cognew(Servo1, @ServoStack)
- cognew(PingCompass, @PingCompassStack)
- PUB Servo1 | tInc, tC, tCtr, tCw, tCcw, t, b
- ctra[30..26] := %00100
- ctra[8..0] := servoPin
- frqa := 1
- dira[servoPin]~~
- tInc := clkfreq/1_000_000
- tC := tInc * 20_000
- tCtr := tInc * 1510
- tCw := tInc * 1300
- tCcw := tInc * 1700
- t := cnt
- repeat
- repeat b from tCtr to tCw step (tInc * 4)
- repeat 1
- phsa := -b
- t += tC
- waitcnt(t)
- repeat b from tCw to tCtr step (tInc * 4)
- repeat 1
- phsa := -b
- t += tC
- waitcnt(t)
- repeat b from tCtr to tCcw step (tInc * 4)
- repeat 1
- phsa := -b
- t += tC
- waitcnt (t)
- repeat b from tCcw to tCtr step (tInc * 4)
- repeat 1
- phsa := -b
- t += tC
- waitcnt (t)
- PUB PingCompass
- waitcnt(clkfreq/100_000 + cnt) 'Wait while compass has time to startup.
- setcont 'sets measurements to go continuously
- repeat 'Repeat indefinitely
- setpointer(OUTPUT_X_MSB) 'Start with Register OUT_X_MSB
- getRaw 'Gather raw data from compass
- range := ping.Inches(ping_pin) ' Get range in inches
- term.str(string("Ping Range:", 32))
- term.dec(range) ' Display result
- term.tx(13)
- RawTerm 'Terminal window display X,Y,Z Raw Data
- term.tx(13)
- term.str(string("Heading in Degrees:", 32))
- term.dec(aziadjust)
- term.tx(13)
- waitcnt(clkfreq + cnt)
- PUB AzimuthTerm
- ''Terminal window display of calculated arcTan(y/x)
- term.str(string("This is the calculated azimuth:",11))
- term.tx(13)
- term.tx(13)
- term.str(@Azm)
- term.dec(azimuth)
- term.tx(13)
- term.tx(13)
- PUB RawTerm
- '' Terminal window display X,Y,Z Raw Data
- term.str(string("Raw Compass Data:", 32))
- term.str(@XRaw)
- term.dec(x)
- term.tx(32)
- term.str(@YRaw)
- term.dec(y)
- term.tx(32)
- term.str(@ZRaw)
- term.dec(z)
- term.tx(13)
- PUB aziadjust : value
- {{ Converts the Azimuth to Degrees from 0 - 360. }}
- NW~
- NE~
- SE~
- SW~
- if x =< 0
- if azimuth =< 0
- value := AZ_A
- NW := 1
- else
- NW~
- if azimuth > 0
- value := AZ_D
- SW := 1
- else
- SW~
- if x > 0
- if azimuth =< 0
- value := AZ_B
- NE := 1
- else
- NE~
- if azimuth > 0
- value := AZ_C
- SE := 1
- else
- SE~
- value := 1 #> value <# 360
- value := (value + 270) // 360
- PUB SetCont
- {{ Sets the Compass to Continuous output mode.}}
- start
- send(WRITE_DATA)
- send(MODE)
- send($00)
- stop
- PUB SetPointer(Register)
- {{ Start pointer at user specified Register. }}
- start
- send(WRITE_DATA)
- send(Register)
- stop
- PUB GetRaw
- {{ Get raw data from continous output.}}
- start
- send(READ_DATA)
- x := ((receive(true) << 8) | receive(true)) 'RegisterA and RegisterB
- z := ((receive(true) << 8) | receive(true))
- y := ((receive(true) << 8) | receive(false))
- stop
- ~~x
- ~~z
- ~~y
- x := x
- z := z
- y := y
- PRI Azimuth
- 'Azimuth = arcTan(y/x)
- result := math.arctan(y,x)
- PRI AZ_A 'NE
- result := ||azimuth
- PRI AZ_B 'SE
- result := azimuth + 180
- PRI AZ_C 'SW
- result := azimuth + 180
- PRI AZ_D 'NW
- result := -azimuth + 360
- PRI send(value) ' I²C Send data - 4 Stack Longs
- value := ((!value) >< 8)
- repeat 8
- dira[dataPin] := value
- dira[clockPin] := false
- dira[clockPin] := true
- value >>= 1
- dira[dataPin] := false
- dira[clockPin] := false
- result := !(ina[dataPin])
- dira[clockPin] := true
- dira[dataPin] := true
- PRI receive(aknowledge) ' I²C receive data - 4 Stack Longs
- dira[dataPin] := false
- repeat 8
- result <<= 1
- dira[clockPin] := false
- result |= ina[dataPin]
- dira[clockPin] := true
- dira[dataPin] := aknowledge
- dira[clockPin] := false
- dira[clockPin] := true
- dira[dataPin] := true
- PRI start ' 3 Stack Longs
- outa[dataPin] := false
- outa[clockPin] := false
- dira[dataPin] := true
- dira[clockPin] := true
- PRI stop ' 3 Stack Longs
- dira[clockPin] := false
- dira[dataPin] := false
- DAT
- Azm byte "Azimuth = ",0
- XRaw byte "X = ",0
- YRaw byte "Y = ",0
- ZRaw byte "Z = ",0