| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| sshahryiar 
 
 
 Joined: 05 May 2010
 Posts: 94
 Location: Dhaka, Bangladesh
 
 
			        
 
 | 
			
				| HMC5883L Digital Compass Library |  
				|  Posted: Sat Sep 14, 2013 1:20 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				| please help |  
				|  Posted: Sun Feb 09, 2014 3:56 pm |   |  
				| 
 |  
				| How code to use in codevision.. please help.. thank you
 |  |  
		|  |  
		| sshahryiar 
 
 
 Joined: 05 May 2010
 Posts: 94
 Location: Dhaka, Bangladesh
 
 
			        
 
 | 
			
				|  |  
				|  Posted: Sun Feb 09, 2014 11:00 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Feb 11, 2014 7:03 am |   |  
				| 
 |  
				| oke.. thank you |  |  
		|  |  
		| hamid9543 
 
 
 Joined: 31 Jan 2013
 Posts: 63
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Mar 26, 2014 5:21 am |   |  
				| 
 |  
				|  	  | 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
 
 
			      
 
 | 
			
				| Help me: HMC5883L |  
				|  Posted: Wed Apr 16, 2014 10:33 am |   |  
				| 
 |  
				| 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
 
 
			        
 
 |  |  
		|  |  
		| sshahryiar 
 
 
 Joined: 05 May 2010
 Posts: 94
 Location: Dhaka, Bangladesh
 
 
			        
 
 | 
			
				| SDA SCL Changed |  
				|  Posted: Wed Apr 16, 2014 10:36 am |   |  
				| 
 |  
				| 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
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Apr 16, 2014 10:48 am |   |  
				| 
 |  
				| I pull up pin SCL, SDA with R 4k7 to 3V3... My project will use it. Now, it's very hard...   your code working well?
 Thanks
 _________________
 Ryan
 |  |  
		|  |  
		| phamduy2807 
 
 
 Joined: 16 Apr 2014
 Posts: 5
 Location: Vietnam
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Apr 16, 2014 10:56 am |   |  
				| 
 |  
				| 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
 
 
			        
 
 |  |  
		|  |  
		| phamduy2807 
 
 
 Joined: 16 Apr 2014
 Posts: 5
 Location: Vietnam
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Apr 16, 2014 11:19 am |   |  
				| 
 |  
				| Thanks so much _________________
 Ryan
 |  |  
		|  |  
		| phamduy2807 
 
 
 Joined: 16 Apr 2014
 Posts: 5
 Location: Vietnam
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Apr 16, 2014 11:27 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Feb 05, 2015 12:56 am |   |  
				| 
 |  
				| 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
 
 
			        
 
 | 
			
				| Digital Compass |  
				|  Posted: Thu Feb 05, 2015 12:59 am |   |  
				| 
 |  
				| Did you check this part "#define declination_angle     -0.5167   // For Uttara, Dhaka, Bangladesh" ? _________________
 https://www.facebook.com/MicroArena
 
 SShahryiar
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |