HMC5883L HMC5983 pusula devresi proton basic
Proton basic compass code |
Bir süredir HMC5883L pusula modülü ile çalışmalar yapıyorum, bunları paylaşmamın doğru olacağını düşündüm.
Öncelikle piyasada FAKE olarak adlandırabileceğimiz modüller mevcut. Bu modüllerin chip üzerinde hmc önünde DB veya DA ibaresi mevcut. Bu db ve da ile üretilen modellerin kalibre ve bir takım işlemlerle çalıştığı söyleniyor ama çalışan sağlam modül varken kimse bu işle uğraşmak istemez.
Paylaştığım kod hem HMC5883 hem de HMC5983 ile çalıştığını da belirteyim. Daha önce aynı modül için CCS C kodu paylaşmıştım. Onu da kullanabilirsiniz. Eğer orjinal HMC5883L bulamazsanız HMC5983L veya basınç sensörü barındıran HMC5983L+BMP180 kullanabilirsiniz.
Ayrıca manyetik sapma koda ilave edilmeli. Dünyadaki her yerin manyetik sapma değeri farklı oluyor. Ve bu değere her yıl 6 dakika eklemek gerekiyor. Manyetik sapma değerlerini aşağıdaki linkten öğrenebilirsiniz:
http://www.magnetic-declination.com/
Not: Pusula sensörü 45 derece altı eğimde hatalı ölçüm yapar. Bunu dikkate alınız. Yapmış olduğunuz devre kerteriz değerini doğrudan etkiler. Pusula sensörünü ferro manyetik malzemelerden uzak tutunuz. Ölçüm değerinin doğru olup olmadığını analog pusula ve pusula sensörü içeren telefon ile teyit ediniz. Hata payı varsa kerteriz değerine +- değer kadar ekleyiniz veya çıkarınız.
Ben pic18f2550 ile test ettim siz diğer işlemcileri de kullanabilirsiniz.
Proton Kodu: Proton derleyicisine kopyalayıp kaydediniz.
Device = 18F2550
Declare Xtal = 20
Config_Start
FOSC = HS
MCLRE = On
PWRT = On
FCMEN = Off
IESO = Off
BOR = Off
VREGEN = Off
WDT = Off
PBADEN = Off
CCP2MX = Off
STVREN = Off
LVP = Off
XINST = Off
Debug = Off
Cp0 = Off
Cp1 = Off
Cp2 = Off
Cp3 = Off
CPB = Off
CPD = Off
WRT0 = Off
WRT1 = Off
WRT2 = Off
WRT3 = Off
WRTB = Off
WRTC = Off
WRTD = Off
EBTR0 = Off
EBTR1 = Off
EBTR2 = Off
EBTR3 = Off
EBTRB = Off
Config_End
Include "AtnFc.inc"
Declare LCD_DTPin PORTB.4
Declare LCD_RSPin PORTB.2
Declare LCD_ENPin PORTB.3
Declare LCD_Interface 4
Declare LCD_Lines 4
Declare LCD_Type 0
Declare LCD_CommandUs = 2000
Declare LCD_DataUs =50 ' YADA 255
'Declare Optimiser_Level = 2
'Declare Dead_Code_Remove = On
'Declare Float_Display_Type = Fast
Declare Hserial_Baud = 9600
Declare Hserial_RCSTA = %10010000
Declare Hserial_TXSTA = 100100
Declare Hserial_Clear = On
'Declare PORTB_Pullups true
Symbol SCL = PORTB.1
Symbol SDA = PORTB.0
Symbol X_MSB = $03 'Read Register, Output of X MSB 8-bit value.
Symbol X_LSB = $04 'Read Register, Output of X LSB 8-bit value.
Symbol Z_MSB = $05 'Read Register, Output of Z MSB 8-bit value.
Symbol Z_LSB = $06 'Read Register, Output of Z LSB 8-bit value.
Symbol Y_MSB = $07 'Read Register, Output of Y MSB 8-bit value.
Symbol Y_LSB = $08 'Read Register, Output of Y LSB 8-bit value.
Symbol WRITE_ADDRESS = $3C ' Requests Write operation
Symbol READ_ADDRESS = $3D ' Requests Read operation
Symbol MODE = $02 ' Mode setting register
Symbol I2C_VAL = $0
Dim X As SWord 'x sensor measured value
Dim Y As SWord 'y sensor measured value
Dim Z As SWord 'z sensor measured value
Dim XC As Float
Dim YC As Float
Dim Heading As Float
Dim DeclinationAngle As Float
Dim Pi As Float
Dim Pi2 As Float
Pi = 3.141592654
Pi2 = 6.283185307 ; 2*pi
DelayMS 100
I2COut SDA,SCL, 0x3c, 0x00, [0x70] '(8-average, 15 Hz default, normal measurement)
I2COut SDA,SCL, 0x3c, 0x01, [0xA0] ' (Gain=5)
I2COut SDA,SCL, 0x3c, 0x02, [0x00] ' Send continuous output command
Cls
Main:
I2CIn SDA, SCL, $3D, $03,[X.HighByte ,X.LowByte,Z.HighByte,Z.LowByte,Y.HighByte,Y.LowByte]
XC = X ;Convert the numbers to Float
YC = Y ;Either Result will come garbage
ATan2(YC, XC, Heading) ;Calculate the ATaan2
'DeclinationAngle = 0.0457; ;DeclinationAngle is different in every place
DeclinationAngle = 5.38; ;eskişehir manyetik sapma değeri
Heading = Heading + DeclinationAngle;
If Heading < 0 Then Heading = Heading + Pi2 ;Add 2*Pi
If Heading > Pi2 Then Heading = Heading - Pi2 ;Subtract 2*Pi
Heading = Heading * 57.295779 ;Convert radians to degrees
Print At 1,1,"Head : ",Dec2 Heading," N "
DelayMS 200
GoTo Main
INC Dosyası: Aşağıdaki satırları txt dosyasına kaydedip daha sonra uzantısını inc yapmalısınız. Dosya adı şu şekilde olmalıdır: AtnFc.inc
'-------------------------------------------------------------------------------------------------------------------------------------
' Name : Atan2
' Purpose : Computes the principal value of arc tangent of Y/X, using the
' : signs of both the arguments to determine the quadrant of the return value
' Input : PP_AARG holds the Y input
' : PP_BARG holds the X input
' Output : PP_AARG holds the arc tangent of Y/X.
' Notes : All values are in Radians
'
'
' Bring two of the compiler's floating point system variables into the program for the Atan2 macro
'
$ifndef __Atan2__
Dim PP_AARG As Float System
Dim PP_BARG As Float System
'-----------------------------------------------------------------------------------------------
GoTo _Atan2_Main ' Jump over the subroutines
'-----------------------------------------------------------------------------------------------
$define ATan2(pYin, pXin, pResult) '
PP_AARG = pYin '
PP_BARG = pXin '
_Atan2 '
pResult = PP_AARG
_Atan2 Macro-
GoSub __Atan2
Endm
#ifMacro- _Atan2
__Atan2:
Dim fYin As PP_AARG
Dim fXin As PP_BARG
Dim bQuadrant As Byte System
Dim tSign As bQuadrant.7
tSign = 0
bQuadrant = 0
If fYin <= 0.0 Then
If fXin <= 0.0 Then
bQuadrant = 3
Else
bQuadrant = 4
EndIf
ElseIf fXin < 0.0 Then
bQuadrant = 2
Else
bQuadrant = 1
EndIf
If fYin < 0.0 Then
tSign = 1
fYin = Abs fYin
EndIf
fXin = Abs fXin
If fXin = 0.0 Then
PP_AARG = 1.570796325
If tSign = 1 Then
PP_AARG = -PP_AARG
EndIf
Else
PP_AARG = fYin / fXin
PP_AARG = ATan(PP_AARG)
bQuadrant = bQuadrant & %01111111 ' Mask out the Sign bit
Select bQuadrant
Case 2
PP_BARG = PP_AARG
PP_AARG = 3.14159265 - PP_BARG
Case 3
PP_AARG = PP_AARG - 3.14159265
Case 4
PP_AARG = -PP_AARG
EndSelect
EndIf
Return
#endIfMacro-
_Atan2_Main:
$endif
teşekkürler paylaşım için
YanıtlaSil