intel
Hero Member
Offline
Posts: 520
Thank You
-Given: 53
-Receive: 2142
|
|
« on: March 20, 2015, 05:45:03 17:45 » |
|
HMC5883L Digital Compass with Pic 16f877A CCS C CodeRelated to the acceleration sensors, many questions unanswered in the forums and saw the unfinished work. Codes associated with acceleration sensors, I'll be posting the help of the codes used in the forums. Some mathematical formulas taken from their pdf files of the acceleration sensor. Some numbers, because it does not allow the processor bits I wrote using the appropriate numbers. CCS C is very efficient in this regard. 8-bit inefficiency is able to absorb ("math.h"). Proton and Picbasic Pro may be errors. I'm glad you publish corrections. We may in the future use of these codes to balance the robot and share code. Good work everyone. https://www.youtube.com/watch?v=NBi1IHufEGkThis codes works fine for me. Main Code:#include <16f877A.h> #FUSES NOWDT //No Watch Dog Timer #FUSES NOBROWNOUT //No brownout reset #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O #FUSES HS //Dont change #use delay(clock=20MHz) #use I2C(master, sda=PIN_d0, scl=PIN_d1, slow) //You can change, according your board ports #include "EXLCD.C" //You can change, according your board ports #include "HMC5883.C" #include "math.h" int8 M_data[6]; //6 units 8 bit Measured datas int16 Xm=0,Ym=0,Zm=0; //16 bit X,Y,Z variables
void main() { delay_ms(2); lcd_init(); hmc5883_init(); printf(lcd_putc,"\f"); lcd_gotoxy(1,1); printf(lcd_putc," HMC5883L "); lcd_gotoxy(1,2); printf(lcd_putc,"Digital Compass "); delay_ms(1000); printf(lcd_putc,"\f");
while(TRUE) { M_data[0]=hmc5883_read(0x04); //Read X (LSB) M_data[1]=hmc5883_read(0x03); //Read X (MSB) M_data[2]=hmc5883_read(0x08); //Read Y (LSB) M_data[3]=hmc5883_read(0x07); //Read Y (MSB) M_data[4]=hmc5883_read(0x06); //Read Z (LSB) M_data[5]=hmc5883_read(0x05); //Read Z (MSB)
Xm=make16(M_data[1],M_data[0]); Ym=make16(M_data[3],M_data[2]); Zm=make16(M_data[5],M_data[4]);
float Heading = atan2((signed int16)Ym,(signed int16)Xm)* 180 / pi + 180; lcd_gotoxy(1,1); printf(lcd_putc,"X=%ld ",Xm); lcd_gotoxy(9,1); printf(lcd_putc,"Y=%ld ",Ym); lcd_gotoxy(1,2); printf(lcd_putc,"Z=%ld ",Zm); lcd_gotoxy(9,2); printf(lcd_putc,"H=%f ",Heading); delay_ms(100);
} }
Library:// HMC5883 required Registers
#define W_DATA 0x3C //'Used to perform a Write operation #define R_DATA 0x3D //'Used to perform a Read operation #define CON_A 0x00 #define CON_B 0x01 //'Send continuous MeVARurement mode. #define MOD_R 0x02 //'Read/Write Register, Selects the operating mode. Default = Single meVARurement #define X_MSB 0x03 //'Read Register, Output of X MSB 8-bit value. #define X_LSB 0x04 //'Read Register, Output of X LSB 8-bit value. #define Z_MSB 0x05 //'Read Register, Output of Z MSB 8-bit value. #define Z_LSB 0x06 //'Read Register, Output of Z LSB 8-bit value. #define Y_MSB 0x07 //'Read Register, Output of Y MSB 8-bit value. #define Y_LSB 0x08 //'Read Register, Output of Y LSB 8-bit value.
void hmc5883_write(int add, int data) { i2c_start(); i2c_write(W_DATA); i2c_write(add); i2c_write(data); i2c_stop(); } int16 hmc5883_read(int add){ int retval; i2c_start(); i2c_write(W_DATA); i2c_write(add); i2c_start(); i2c_write(R_DATA); retval=i2c_read(0); i2c_stop(); return retval; } void hmc5883_init(){ hmc5883_write(MOD_R, 0x00); delay_ms(100); hmc5883_write(CON_A, 0x10); delay_ms(100); hmc5883_write(CON_B, 0x20); delay_ms(100); }
|
|
« Last Edit: March 28, 2015, 08:26:13 08:26 by intel »
|
Logged
|
In life, most genuine mentor is science.
|
|
|
bbarney
Moderator
Hero Member
Offline
Posts: 2429
Thank You
-Given: 405
-Receive: 545
Uhm? where did pickit put my mute button
|
|
« Reply #1 on: March 21, 2015, 05:25:24 05:25 » |
|
Intel Here is some proton code for a 18f4550 and the HMC5883L Digital Compass - not my code but supposed to work well
|
|
|
Logged
|
Ever wonder why Kamikaze pilot's wore helmet's ?
|
|
|
intel
Hero Member
Offline
Posts: 520
Thank You
-Given: 53
-Receive: 2142
|
|
« Reply #2 on: March 21, 2015, 08:58:32 08:58 » |
|
Thank you for your interest bbarney. My goal is to grasp the fact that the use of I2C communication. However, the unanswered many questions about electronic forum. People do not want to share information base. Here it is the difference of this website. No money waiting to share. Very nice code that you send. I started from 16F877. You know, cheaper and more accessible. After struggling with the limitations of 8-bit, 16 and I think switching to 32-bit code. But it did not happen I expect questions and concerns. I'll share my Picbasic and proton code I prepared for this chip. I'm curious to be useful.
|
|
|
Logged
|
In life, most genuine mentor is science.
|
|
|
bbarney
Moderator
Hero Member
Offline
Posts: 2429
Thank You
-Given: 405
-Receive: 545
Uhm? where did pickit put my mute button
|
|
« Reply #3 on: March 21, 2015, 03:04:07 15:04 » |
|
Let me know if it helps you out I don't have a HMC5883L chip so never tried the code but I remembered seeing it a few years ago and thought it might be useful for you the person that wrote it was a member here ,don't remember his nickname here or if he is still active here so your on your own again
|
|
|
Logged
|
Ever wonder why Kamikaze pilot's wore helmet's ?
|
|
|
intel
Hero Member
Offline
Posts: 520
Thank You
-Given: 53
-Receive: 2142
|
|
« Reply #4 on: March 21, 2015, 03:33:23 15:33 » |
|
I tried the code you sent. Works well.
|
|
|
Logged
|
In life, most genuine mentor is science.
|
|
|
bbarney
Moderator
Hero Member
Offline
Posts: 2429
Thank You
-Given: 405
-Receive: 545
Uhm? where did pickit put my mute button
|
|
« Reply #5 on: March 21, 2015, 07:44:38 19:44 » |
|
Great Thanks for letting us all know, was it any help to you with your conversion to proton code ? These modules are pretty cheap on e-bay may pick one up myself $1.73 us
|
|
|
Logged
|
Ever wonder why Kamikaze pilot's wore helmet's ?
|
|
|
intel
Hero Member
Offline
Posts: 520
Thank You
-Given: 53
-Receive: 2142
|
|
« Reply #6 on: March 22, 2015, 08:18:49 08:18 » |
|
For now, I can not make the preparation of Proton code. As you know 16F877 8-bit compiler to do arctangent operation to have an architecture that does not allow on Proton Basic. I will continue on the same plane with the code I made before. If you prepared for an 8-bit architecture, inc file you have, I'm glad you shared. However, when trying CCS C 8-bit architecture arctangent operations, Picbasic Pro account can be made in a very limited, and Proton Basic not to have never tried, very confusing. Posted on: 22 March 2015, 09:10:22 - Automerged
HMC5883L Digital Compass with Pic 16f877A Picbasic Code Related to the acceleration sensors, many questions unanswered in the forums and saw the unfinished work. Codes associated with acceleration sensors, I'll be posting the help of the codes used in the forums. Some mathematical formulas taken from their pdf files of the acceleration sensor. Some numbers, because it does not allow the processor bits I wrote using the appropriate numbers. CCS C is very efficient in this regard. 8-bit inefficiency is able to absorb ("math.h"). Proton and Picbasic Pro may be errors. I'm glad you publish corrections. We may in the future use of these codes to balance the robot and share code. Good work everyone. This codes works fine for me. But I left as a side note to never trust the accuracy of the arctangent operation. I would be glad if you share that ensure the accuracy or improvement of. Picbasic Code'**************************************************************** '* Name : HMC5883 PBP 16F877A.BAS * '* Author : YUKSEL * '* Notice : Copyright (c) 2015 YUKSEL * '* : All Rights Reserved * '* Date : 15.3.2015 * '* Version : 1.0 * '* Notes : * '* : * '**************************************************************** adcon1 = 7 ' Turns Analogs off 'For 20 MHz config #config __config _HS_OSC & _LVP_OFF #ENDCONFIG
DEFINE OSC 20
TRISA = %00000000 TRISB = %00000000 PORTC = %01000000 PORTD = %00000011 PORTE = %00000000
DEFINE LCD_DREG PORTB DEFINE LCD_DBIT 0 DEFINE LCD_EREG PORTB DEFINE LCD_EBIT 5 DEFINE LCD_RSREG PORTB DEFINE LCD_RSBIT 4 DEFINE LCD_BITS 4 DEFINE LCD_LINES 2
Symbol SDA = PORTD.0 'I2C data pin. Pullup connection is required. Symbol SCL = PORTD.1 'I2C clock pin. Pullup connection is required. Symbol W_DAT = $3C 'Used to perform a Write operation Symbol R_DAT = $3D 'Used to perform a Read operation Symbol CON_A = $00 Symbol CON_B = $01 'Send continuous MeVARurement mode. Symbol MOD_R = $02 'Read/Write Register, Selects the operating mode. Default = Single meVARurement 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.
READX VAR Word READY VAR Word READZ VAR Word 'X VAR BYTE 'Y VAR BYTE 'AZ VAR WORD PAUSE 100 ' Give sensor needed power up time
I2CWRITE SDA,SCL,W_DAT,MOD_R,[$00] '00 PAUSE 70 I2CWRITE SDA,SCL,W_DAT,CON_A,[$10] '70 PAUSE 2 I2CWRITE SDA,SCL,W_DAt,CON_B,[$60] 'A0 PAUSE 100
READI2C: I2CREAD SDA,SCL,R_DAT,X_MSB,[READX.HighByte] 'Read the data starting at x_msb 3 I2CREAD SDA,SCL,R_DAT,X_LSB,[READX.LowByte] I2CREAD SDA,SCL,R_DAT,Z_MSB,[READZ.HighByte] I2CREAD SDA,SCL,R_DAT,Z_LSB,[READZ.LowByte] I2CREAD SDA,SCL,R_DAT,Y_MSB,[READY.HighByte] I2CREAD SDA,SCL,R_DAT,Y_LSB,[READY.LowByte] PAUSE 100
'X = READX>>2 'Y = READY>>2 'AZ = (-y ATN x)
LCDOUT $FE,1, "X=",SDec READX,$FE,2,$FE,$14,$FE,$14,$FE,$14,$FE,$14,$FE,$14,$FE,$14,$FE,$14,$FE,$14,"Y=",SDec READY," " LCDOUT $FE,$C0,"Z=",sDec READZ," "',$FE,$C0+7,$FE,$C0+8,"AZ=",dec3 (AZ * 141)/100 ', " " GoTo READI2C:
End
|
|
« Last Edit: March 22, 2015, 08:22:09 08:22 by intel »
|
Logged
|
In life, most genuine mentor is science.
|
|
|
towlerg
Senior Member
Offline
Posts: 263
Thank You
-Given: 474
-Receive: 104
What is this for?
|
|
« Reply #7 on: March 22, 2015, 03:18:56 15:18 » |
|
Have you ever tried the approximation of Atan here http://www.ccsinfo.com/forum/viewtopic.php?t=50920 post #3 ? George
|
|
|
Logged
|
Win 7 Ult x64 SP1 on HP2570p
|
|
|
intel
Hero Member
Offline
Posts: 520
Thank You
-Given: 53
-Receive: 2142
|
|
« Reply #8 on: March 22, 2015, 04:32:50 16:32 » |
|
Yes. But I think the results were not accurate. Errors may be me. If I have time I'll try again. Thanks...
|
|
|
Logged
|
In life, most genuine mentor is science.
|
|
|
towlerg
Senior Member
Offline
Posts: 263
Thank You
-Given: 474
-Receive: 104
What is this for?
|
|
« Reply #9 on: March 23, 2015, 03:53:25 15:53 » |
|
I've played with these devices and got some very odd results. If I plot the reported direction of the the four points of the compass I do not get two lines at right angles (as you should). I get a variety of odd lines, some at right angles to each other, although pointing generally in the correct direction (very generally, within 45 deg. ish) . I've tried several devices on both types of breakout board and have gotten similar results.
What sort of results to you get, relative and absolute ie is reported South opposite reported North and how accurately does reported North point to actual North?
I started reading about calibration but glazed over. Of the people who report good results with these devices none seem to mention calibration.
Thanks in advance
George
|
|
« Last Edit: March 24, 2015, 05:58:05 05:58 by towlerg »
|
Logged
|
Win 7 Ult x64 SP1 on HP2570p
|
|
|
intel
Hero Member
Offline
Posts: 520
Thank You
-Given: 53
-Receive: 2142
|
|
« Reply #10 on: March 23, 2015, 06:28:18 18:28 » |
|
Results of these sensors for my little strange. 180 North correct but not in the opposite side, where it should be 270. Values approaching 360 degrees rise logarithmically. This is beyond what I prepare codes in the code that I found was the case. (I'll upload them as well.) I think the problem with the sensor. Another model will write the results when you receive a digital compass sensor. Have been made with the Arduino program related to calibration. (I will add your link.) Symmetry problem in digital compass, not in accelerometer. But they also show the wrong value during acceleration. Let's see if we can find a solution. Arduino and HMC5883L (With Auto Calibration): http://hobbylogs.me.pn/?p=17I tried the new code. This link. I attach below.: http://www.ccsinfo.com/forum/viewtopic.php?t=51156
|
|
|
Logged
|
In life, most genuine mentor is science.
|
|
|
gan_canny
Junior Member
Offline
Posts: 89
Thank You
-Given: 101
-Receive: 26
|
|
« Reply #11 on: March 23, 2015, 07:05:26 19:05 » |
|
I use the COORDIC for this type of trigonometry. You might want to try feeding in values first using atan since atan2 uses it. Values fed into atan between -1 and 1 are stable ( inside the unit circle). Don't bring in the actual HMC5883L values until the atan or atan2 function works with your satisfaction to your known values.
|
|
|
Logged
|
|
|
|
intel
Hero Member
Offline
Posts: 520
Thank You
-Given: 53
-Receive: 2142
|
|
« Reply #12 on: March 28, 2015, 08:23:42 08:23 » |
|
Proton Basic Code for HMC5883L: '**************************************************************** '* Name : HMC5883L PROTON 16F877A.BAS * '* Author : YUKSEL * '* Notice : Copyright (c) 2015 YUKSEL * '* : All Rights Reserved * '* Date : 5.3.2015 * '* Version : 1.0 * '* Notes : * '* : * '**************************************************************** Device = 16F877A Declare Xtal = 20 ' Kristal frekansı: 20 MHz CMCON = 7 ' Tüm komparatörler devre dışı Declare All_Digital = True ' 16f877A nın tüm uçları Dijital TRISA = %00000000 TRISB = %00000000 TRISC = %00000000 TRISD = %00000011 TRISE = %00000000
Declare LCD_Type 0 ' Standart 2x16 LCD Declare LCD_DTPort PORTB ' LCD data portu Declare LCD_DTPin PORTB.0 ' DATA girişi PORTB'nin B0 ucundan başlayacak Declare LCD_ENPin PORTB.5 ' Enable (EN) pini E2 Declare LCD_RSPin PORTB.4 ' Register Select (RS) pini B4 Declare LCD_Interface 4 ' 4 bit LCD arayüzü Declare LCD_Lines 2 ' 2 satırlık LCD
Symbol SDA = PORTD.0 'I2C data pin. Pullup connection is required. You can change, according your board ports Symbol SCL = PORTD.1 'I2C clock pin. Pullup connection is required. You can change, according your board ports Symbol W_DAT = $3C 'Used to perform a Write operation Symbol R_DAT = $3D 'Used to perform a Read operation Symbol CON_A = $00 'Send Configuration A Register Symbol CON_B = $01 'Send Configuration B Register Symbol MOD_R = $02 'Send Operating Mode. Default = Single measurement. Must be in Continuous measurement mode. 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.
Dim READX As Word Dim READY As Word Dim READZ As Word DelayMS 100 ' Give sensor needed power up time
I2COut SDA,SCL,W_DAT,MOD_R,[$00] '00 DelayMS 70 I2COut SDA,SCL,W_DAT,CON_A,[$10] '70 DelayMS 2 I2COut SDA,SCL,W_DAT,CON_B,[$60] 'A0 DelayMS 100
READI2C: I2CIn SDA,SCL,R_DAT, X_MSB,[READX.HighByte] 'The first 8 bits of 16-bit X Axis I2CIn SDA,SCL,R_DAT ,X_LSB,[READX.LowByte] 'The second 8 bits of 16-bit X Axis I2CIn SDA,SCL,R_DAT, Z_MSB,[READZ.HighByte] I2CIn SDA,SCL,R_DAT ,Z_LSB,[READZ.LowByte] I2CIn SDA,SCL,R_DAT, Y_MSB,[READY.HighByte] I2CIn SDA,SCL,R_DAT ,Y_LSB,[READY.LowByte] Print At 1,1, "X=",SDec READX," " Print At 1,9, "Y=",SDec READY," " Print At 2,1, "Z=",SDec READZ," " DelayMS 100 GoTo READI2C:
End
|
|
|
Logged
|
In life, most genuine mentor is science.
|
|
|
|