Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
December 06, 2016, 01:46:53 01:46


Login with username, password and session length


Pages: [1]
Print
Author Topic: HMC5883L Digital Compass with Pic 16f877A CCS C Picbasic Pro and Proton Code  (Read 4069 times)
0 Members and 1 Guest are viewing this topic.
intel
Senior Member
****
Offline Offline

Posts: 266

Thank You
-Given: 9
-Receive: 1074



« on: March 20, 2015, 05:45:03 17:45 »

HMC5883L Digital Compass with Pic 16f877A CCS C 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.




https://www.youtube.com/watch?v=NBi1IHufEGk




This codes works fine for me.


Main Code:

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:

Code:
// 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 Offline

Posts: 2403

Thank You
-Given: 405
-Receive: 544


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
Senior Member
****
Offline Offline

Posts: 266

Thank You
-Given: 9
-Receive: 1074



« 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 Offline

Posts: 2403

Thank You
-Given: 405
-Receive: 544


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  Cheesy
Logged

Ever wonder why Kamikaze pilot's wore helmet's ?
intel
Senior Member
****
Offline Offline

Posts: 266

Thank You
-Given: 9
-Receive: 1074



« 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 Offline

Posts: 2403

Thank You
-Given: 405
-Receive: 544


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
Senior Member
****
Offline Offline

Posts: 266

Thank You
-Given: 9
-Receive: 1074



« 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

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
V.I.P
Active Member
*****
Offline Offline

Posts: 136

Thank You
-Given: 282
-Receive: 48

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 x86 SP1 on HP6910p
intel
Senior Member
****
Offline Offline

Posts: 266

Thank You
-Given: 9
-Receive: 1074



« 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
V.I.P
Active Member
*****
Offline Offline

Posts: 136

Thank You
-Given: 282
-Receive: 48

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 x86 SP1 on HP6910p
intel
Senior Member
****
Offline Offline

Posts: 266

Thank You
-Given: 9
-Receive: 1074



« 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=17

I 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
**
 Warned
Offline Offline

Posts: 85

Thank You
-Given: 98
-Receive: 25


« 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
Senior Member
****
Offline Offline

Posts: 266

Thank You
-Given: 9
-Receive: 1074



« Reply #12 on: March 28, 2015, 08:23:42 08:23 »



Proton Basic Code for HMC5883L:

Code:
'****************************************************************
'*  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.
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC