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