CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

HMC5883L Digital Compass Library
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
sshahryiar



Joined: 05 May 2010
Posts: 94
Location: Dhaka, Bangladesh

View user's profile Send private message Send e-mail Visit poster's website

HMC5883L Digital Compass Library
PostPosted: Sat Sep 14, 2013 1:20 am     Reply with quote

HMC5883L.h

Code:

#define HMC5883L_READ_ADDR       0x3D
#define HMC5883L_WRITE_ADDR      0x3C
                           
#define Config_Reg_A             0x00
#define Config_Reg_B             0x01
#define Mode_Reg                 0x02
#define X_MSB_Reg                0x03
#define X_LSB_Reg                0x04
#define Z_MSB_Reg                0x05
#define Z_LSB_Reg                0x06
#define Y_MSB_Reg                0x07
#define Y_LSB_Reg                0x08
#define Status_Reg               0x09
#define ID_Reg_A                 0x0A             
#define ID_Reg_B                 0x0B
#define ID_Reg_C                 0x0C
       
#define declination_angle     -0.5167   // For Uttara, Dhaka, Bangladesh   

                                   
#use I2C(MASTER, SDA = pin_B7, SCL = pin_B6)   
                                             
                                   
register signed long X_axis = 0;
register signed long Y_axis = 0;                                 
register signed long Z_axis = 0;
float m_scale = 1.0;
       

unsigned long make_word(unsigned char HB, unsigned char LB);
void HMC5883L_init(); 
unsigned char HMC5883L_read(unsigned char reg);
void HMC5883L_write(unsigned char reg_address, unsigned char value);
void HMC5883L_read_data();
void HMC5883L_scale_axes();
void HMC5883L_set_scale(float gauss);
float HMC5883L_heading();



HMC5883L.c

Code:

#include "HMC5883L.h"

                         
unsigned long make_word(unsigned char HB, unsigned char LB)
{                                     
   register unsigned long val = 0;
                              
   val = HB;
   val <<= 8;                         
   val |= LB;         
   return val;
}                                 

                               
void HMC5883L_init()
{                                       
   HMC5883L_write(Config_Reg_A, 0x70);
   HMC5883L_write(Config_Reg_B, 0xA0);
   HMC5883L_write(Mode_Reg, 0x00); 
   HMC5883L_set_scale(1.3);
}
                                   

unsigned char HMC5883L_read(unsigned char reg)
{                                         
   unsigned char val = 0;
   
   I2C_Start();
   I2C_Write(HMC5883L_WRITE_ADDR);
   I2C_Write(reg);
   I2C_Start();
   I2C_Write(HMC5883L_READ_ADDR);
   val = I2C_Read(0);                       
   I2C_Stop();
   return(val);   
}

                                 
void HMC5883L_write(unsigned char reg_address, unsigned char value)
{
   I2C_Start();
   I2C_Write(HMC5883L_WRITE_ADDR);
   I2C_Write(reg_address);
   I2C_Write(value);
   I2C_Stop();
}                                           
     
void HMC5883L_read_data()
{                         
   unsigned char lsb = 0;
   unsigned char msb = 0;
   
   I2C_Start();
   I2C_Write(HMC5883L_WRITE_ADDR);
   I2C_Write(X_MSB_Reg);           
   I2C_Start();
   I2C_Write(HMC5883L_READ_ADDR);
   
   msb = I2C_Read();
   lsb = I2C_Read();
   X_axis = make_word(msb, lsb);
                          
   msb = I2C_Read();
   lsb = I2C_Read();
   Z_axis = make_word(msb, lsb);
                  
   msb = I2C_Read();
   lsb = I2C_Read(0);
   Y_axis = make_word(msb, lsb);           
                      
   I2C_Stop();   
}


void HMC5883L_scale_axes()
{   
         
   X_axis *= m_scale;
   Z_axis *= m_scale;                           
   Y_Axis *= m_scale;
}


void HMC5883L_set_scale(float gauss)                     
{
   unsigned char value = 0;   
   
    if(gauss == 0.88)       
    {                                           
      value = 0x00;                     
      m_scale = 0.73;
   } 
   
   else if(gauss == 1.3)   
   {
      value = 0x01;
      m_scale = 0.92;     
   } 
   
   else if(gauss == 1.9)
   {
      value = 0x02;
      m_scale = 1.22;
   }
   
   else if(gauss == 2.5)
   {
      value = 0x03;
      m_scale = 1.52;
   } 
   
   else if(gauss == 4.0)
   {
      value = 0x04;
      m_scale = 2.27;
   }
   
   else if(gauss == 4.7)
   {
      value = 0x05;
      m_scale = 2.56;
   } 
   
   else if(gauss == 5.6)
   {
      value = 0x06;
      m_scale = 3.03;
   }   
   
   else if(gauss == 8.1)                                 
   {
      value = 0x07;
      m_scale = 4.35;         
   }       
                                               
   value <<= 5;
   HMC5883L_write(Config_Reg_B, value);
}     

                               
float HMC5883L_heading()         
{
   register float heading = 0.0;
   
   HMC5883L_read_data();
   HMC5883L_scale_axes();
   heading = atan2(Y_axis, X_axis);
    heading += declination_angle;   
                 
    if(heading < 0.0)
    {
      heading += (2.0 * PI);
    }
   
    if(heading > (2.0 * PI))               
    {                           
      heading -= (2.0 * PI);
    }                   
                   
   heading *= (180.0 / PI);
                  
   return heading;
}             



lcd.c (SPI LCD based on CD4094B)
Code:

#define data         PIN_C0
#define clock        PIN_C1
#define strobe       PIN_C2   
         
#define LCD_DB4          5
#define LCD_DB5          6
#define LCD_DB6          7         
#define LCD_DB7          8         
                           
#define LCD_E            4
#define LCD_RS           3         

#define lcd_type          2         
#define lcd_line_two     0x40     


byte d0 = 0;
byte d1 = 0;
byte d2 = 0;
byte d3 = 0;
byte d4 = 0;
byte d5 = 0;
byte d6 = 0;
byte d7 = 0;
 
 
void set_shift(unsigned char value)
{
   unsigned char location = 0;
   unsigned char n = 0;
   location = 128;
   for(n = 1; n <= 8; n++)
   {   
       if((value & location)>0)
       {
         output_bit(data,1);
       }
       else
       {
         output_bit(data, 0);
       }
       output_bit(clock,1);
       location >>= 1;
       output_bit(clock,0);
   }
   output_bit(strobe, 1);
   output_bit(strobe, 0);
}
                 

void f_output(byte value)
{
   set_shift(value);
}

void fatport()
{
   unsigned char value = 0;
   if(d0==1)
   {       
      value += 1;
   }
   if(d1 == 1)
   {
      value += 2;
   }           
   if(d2 == 1)
   {
      value += 4;
   }   
   if(d3 == 1)
   {
      value += 8;
   }
   if(d4 == 1)
   {
      value += 16;
   }
   if(d5 == 1)
   {
      value += 32;
   }   
   if(d6 == 1)
   {
      value += 64;
   }           
   if(d7 == 1)
   {
      value += 128;
   }
   f_output(value); 
}


void dg0(unsigned char value)
{
   d0 = value;
   fatport(); 
}

void dg1(unsigned char value)
{
   d1 = value;
   fatport();
}

void dg2(unsigned char value)
{
   d2 = value;
   fatport();
}

void dg3(unsigned char value)
{
   d3 = value;
   fatport();
}

void dg4(unsigned char value)
{
   d4 = value;
   fatport();
}
         
void dg5(unsigned char value)
{
   d5 = value;
   fatport();
}

void dg6(unsigned char value)
{
   d6 = value;
   fatport();
}

void dg7(unsigned char value)
{
   d7 = value;
   fatport();
}

void f_output_bit(byte pin, value)
{
   switch(pin)
   {
      case 1:
      {
         dg0(value);
            break;
      }
      case 2:
      {
            dg1(value);
            break;
      }
      case 3:
      {
         dg2(value);
            break;
      }
      case 4:
      {
            dg3(value);
            break;
      }
      case 5:
      {
         dg4(value);
            break;
      }
      case 6:
      {
         dg5(value);
            break;
      }
      case 7:
      {
         dg6(value);
            break;
      }
      case 8:
      {
         dg7(value);
            break;
      }
   }
}


void f_output_high(byte pin)
{
   switch(pin)
   {
      case 1:
      {
      dg0(1);
            break;
      }
      case 2:
      {
            dg1(1);
            break;
      }         
      case 3:
      {
      dg2(1);
            break;
      }
      case 4:
      {
            dg3(1);
            break;
      }
      case 5:
      {
      dg4(1);
            break;
      }
      case 6:
      {
      dg5(1);
            break;
      }
      case 7:
      {
      dg6(1);
            break;
      }
      case 8:
      {
      dg7(1);
            break;
      }
   } 
}


void f_output_low(byte pin)
{
   switch(pin)
   {
      case 1:
      {
      dg0(0);
            break;
      }
      case 2:
      {
            dg1(0);
            break;
      }
      case 3:
      {
      dg2(0);
            break;
      }
      case 4:
      {
            dg3(0);
            break;
      }
      case 5:
      {
      dg4(0);
            break;
      }
      case 6:
      {
      dg5(0);
            break;
      }
      case 7:
      {
      dg6(0);
            break;
      }
      case 8:
      {
      dg7(0);
            break;
      }
   }
}


const unsigned char LCD_INIT_STRING[4] =
{                                       
    0x20 | (lcd_type << 2),                 
    0xc,                   
    1,                           
    6                       
};                   
                             
                             
void lcd_send_nibble(int8 nibble)
{
    f_output_bit(LCD_DB4, !!(nibble & 1));
    f_output_bit(LCD_DB5, !!(nibble & 2)); 
    f_output_bit(LCD_DB6, !!(nibble & 4));   
    f_output_bit(LCD_DB7, !!(nibble & 8));   
    delay_cycles(1);
    f_output_high(LCD_E);
    delay_us(2);
    f_output_low(LCD_E);   
}


//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(unsigned char address, unsigned char n)
{
   f_output_low(LCD_RS);
   delay_us(60); 
   
   
   if(address)
   {
      f_output_high(LCD_RS);
   }   
   else
   {
      f_output_low(LCD_RS);
   }     
   delay_cycles(1);
   
   f_output_low(LCD_E);                              
   lcd_send_nibble(n >> 4);
   lcd_send_nibble(n & 0x0F);   
}


void lcd_init()
{
   unsigned char i = 0;
   
   f_output_low(LCD_RS);
   f_output_low(LCD_E);
   delay_ms(15);
   
   for(i = 0 ;i < 3; i++)
   {
       lcd_send_nibble(0x03);
       delay_ms(5);
   }
   
   lcd_send_nibble(0x02);
   
   for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {   
      lcd_send_byte(0, LCD_INIT_STRING[i]);
   }     
          
}         


void lcd_gotoxy(unsigned char x, unsigned char y)
{
   unsigned char address = 0;
   
   if(y != 1)
   {
      address = lcd_line_two;
   }
   else
   {
      address=0;
   }   
   address += x - 1;
   lcd_send_byte(0, 0x80 | address);   
}


void lcd_putc(char c)
{
   switch(c)
   {
       case '\f':
       {
         lcd_send_byte(0, 1);
         delay_ms(2);
         break;
       }   
       case '\n':
       {
          lcd_gotoxy(1, 2);
          break;
       }         
       case '\b':
       {                 
          lcd_send_byte(0, 0x10);
          break;
       }   
       default:
       {
          lcd_send_byte(1, c);
          break;
       }
   }
}                     


Example:

Code:

#include <16F690.h>


#device *= 16
                   
                                               
#fuses INTRC_IO, PROTECT, PUT, BROWNOUT ,CPD, NOWDT, NOFCMEN, NOMCLR, NOIESO
     
     
#use delay(internal = 4MHz)                               
                               
                                           
#include "lcd.c"   
#include <math.h>
#include "HMC5883L.c"

   
const unsigned char symbol[8] = {0x04, 0x0A, 0x0A, 0x04, 0x00, 0x00, 0x00, 0x00};                               
                       
 
void setup();                                                   
void lcd_symbol();                             
                     
                                       
void main()
{                                                                                       
    float h = 0.0;
    setup();
    while(TRUE)                                   
    {                           
      h = HMC5883L_heading();
      lcd_gotoxy(4, 1);
      lcd_putc("Heading  N");
      lcd_gotoxy(12, 1);                         
      lcd_putc(0);
      lcd_gotoxy(6, 2);
      printf(lcd_putc, "%03.2f  ", h);
      delay_ms(100);
    }                         
}                                     
 
                                       
void setup()                   
{                                                   
    setup_WDT(WDT_off);
    setup_oscillator(osc_4MHz);
    setup_comparator(NC_NC_NC_NC);
    setup_adc(ADC_off);
    setup_adc_ports(no_analogs);   
    setup_timer_0(T0_internal | T0_8_BIT);       
    setup_timer_1(T1_disabled);   
    setup_timer_2(T2_disabled, 255, 1);
    port_B_pullups(FALSE);             
    set_RTCC(0);                   
    set_timer1(0);   
    set_timer1(0);   
    set_timer2(0);
    setup_CCP1(CCP_off); 
    setup_SPI(SPI_disabled | SPI_SS_disabled);   
    lcd_init();
    HMC5883L_init();
    lcd_symbol();
}   
 

void lcd_symbol()                   
{
   unsigned char i=0;
   lcd_send_byte(0, 0x40);
   for(i = 0; i < 8; i += 1)
   {
       lcd_send_byte(1, symbol[i]);
   }
   lcd_send_byte(0, 0x80);   
}

_________________
https://www.facebook.com/MicroArena

SShahryiar
helmiyanwahyudi



Joined: 02 Feb 2014
Posts: 2

View user's profile Send private message

please help
PostPosted: Sun Feb 09, 2014 3:56 pm     Reply with quote

How code to use in codevision.. please help..
thank you
sshahryiar



Joined: 05 May 2010
Posts: 94
Location: Dhaka, Bangladesh

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sun Feb 09, 2014 11:00 pm     Reply with quote

This forum is not for Codevision AVR. It's only for CCS PIC C. I'm sure Codevision AVR has either I2C or TWI library equivalent to I2C library in CCS. The rest of the code will be similar then.
_________________
https://www.facebook.com/MicroArena

SShahryiar
helmiyanwahyudi



Joined: 02 Feb 2014
Posts: 2

View user's profile Send private message

PostPosted: Tue Feb 11, 2014 7:03 am     Reply with quote

oke.. thank you
hamid9543



Joined: 31 Jan 2013
Posts: 63

View user's profile Send private message

PostPosted: Wed Mar 26, 2014 5:21 am     Reply with quote

Code:

#define declination_angle     -0.5167   // For Uttara, Dhaka, Bangladesh



how find coefficient for other city or country?
phamduy2807



Joined: 16 Apr 2014
Posts: 5
Location: Vietnam

View user's profile Send private message Send e-mail

Help me: HMC5883L
PostPosted: Wed Apr 16, 2014 10:33 am     Reply with quote

I use pic16f877a + CD4094 + LCD 16x2 + HMC5883 and your code. I change pin SCL and SDA for my pic, but it's not working. Can you help me???
Thanks
_________________
Ryan
sshahryiar



Joined: 05 May 2010
Posts: 94
Location: Dhaka, Bangladesh

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Apr 16, 2014 10:35 am     Reply with quote

This should do:

http://www.ngdc.noaa.gov/geomag-web/#declination
_________________
https://www.facebook.com/MicroArena

SShahryiar
sshahryiar



Joined: 05 May 2010
Posts: 94
Location: Dhaka, Bangladesh

View user's profile Send private message Send e-mail Visit poster's website

SDA SCL Changed
PostPosted: Wed Apr 16, 2014 10:36 am     Reply with quote

Did you use pull ups for those pins? Are you using a ready-made module or just the chip itself?
_________________
https://www.facebook.com/MicroArena

SShahryiar
phamduy2807



Joined: 16 Apr 2014
Posts: 5
Location: Vietnam

View user's profile Send private message Send e-mail

PostPosted: Wed Apr 16, 2014 10:48 am     Reply with quote

I pull up pin SCL, SDA with R 4k7 to 3V3... My project will use it. Now, it's very hard... Sad
your code working well?
Thanks
_________________
Ryan
phamduy2807



Joined: 16 Apr 2014
Posts: 5
Location: Vietnam

View user's profile Send private message Send e-mail

PostPosted: Wed Apr 16, 2014 10:56 am     Reply with quote

i connect all pin like pic on http://www.electronics-lab.com/blog/?p=2086.
It use pin 10 11 12 of Arduino to connect with pin 1 2 3 of 4094 but I use pin c0 c1 c2 connect with 4094 like you.
Help me!!! Thanks
_________________
Ryan
sshahryiar



Joined: 05 May 2010
Posts: 94
Location: Dhaka, Bangladesh

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Apr 16, 2014 11:06 am     Reply with quote

If it Arduino then this is not the right forum for discussion....

BTW it works perfectly and so see it for yourself:

https://www.facebook.com/MicroArena/photos/pb.113572212076237.-2207520000.1397667803./408027482630707/?type=3&theater
_________________
https://www.facebook.com/MicroArena

SShahryiar
phamduy2807



Joined: 16 Apr 2014
Posts: 5
Location: Vietnam

View user's profile Send private message Send e-mail

PostPosted: Wed Apr 16, 2014 11:19 am     Reply with quote

Thanks so much
_________________
Ryan
phamduy2807



Joined: 16 Apr 2014
Posts: 5
Location: Vietnam

View user's profile Send private message Send e-mail

PostPosted: Wed Apr 16, 2014 11:27 am     Reply with quote

Hi SShahryiar
Can you send for me your circuit? I want to know more your connect them.
my email: phamduy2807@gmail.com
Thanks
_________________
Ryan
nuwanw



Joined: 16 Jan 2015
Posts: 7

View user's profile Send private message

PostPosted: Thu Feb 05, 2015 12:56 am     Reply with quote

Hi Sshahryair,

The code works fine, but not accurate as per the true angle, could you please explain this code please
HMC5883L_set_scale(1.3);

Why did you put 1.3 specifically?

Thank you
sshahryiar



Joined: 05 May 2010
Posts: 94
Location: Dhaka, Bangladesh

View user's profile Send private message Send e-mail Visit poster's website

Digital Compass
PostPosted: Thu Feb 05, 2015 12:59 am     Reply with quote

Did you check this part "#define declination_angle -0.5167 // For Uttara, Dhaka, Bangladesh" ?
_________________
https://www.facebook.com/MicroArena

SShahryiar
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group