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 support@ccsinfo.com

HMC5883L Help

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 05, 2013 11:38 pm     Reply with quote

Here is a sample driver. I don't have a HMC5883L to test, so I can't
guarantee this code will work, but at least it has a chance to work.

I don't have the PCD compiler, but I do have PCH. That's why I did it for
the 18F4520. If you convert this code to PCD, remember that in PCD
most data types are signed by default, whereas in PCH they are unsigned
by default. Also, in PCD you use "%x" to display a 16-bit value, but
in PCH you use "%lx".
Code:

#include <18F4520.h>
#fuses INTRC_IO, NOWDT, PUT, BROWNOUT
#use delay(clock=4M)   
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, UART1, ERRORS)

// i2c slave addresses
#define HMC5883L_WRT_ADDR  0x3C
#define HMC5883L_READ_ADDR 0x3D

// Register addresses
#define HMC5883L_CFG_A_REG 0x00
#define HMC5883L_CFG_B_REG 0x01
#define HMC5883L_MODE_REG  0x02
#define HMC5883L_X_MSB_REG 0x03

//------------------------------
// Low level routines
//------------------------------
void hmc5883l_write_reg(int8 reg, int8 data)
{
i2c_start();
i2c_write(HMC5883L_WRT_ADDR);
i2c_write(reg);
i2c_write(data);
i2c_stop();
}

//------------------------------
int8 hmc5883l_read_reg(int8 reg)
{
int8 retval;

i2c_start();
i2c_write(HMC5883L_WRT_ADDR);
i2c_write(reg);
i2c_start();
i2c_write(HMC5883L_READ_ADDR);
retval = i2c_read(0);
i2c_stop();

return(retval);
}

//------------------------------
typedef struct
{
int16 x;
int16 y;
int16 z;
}hmc5883l_result;

// This global structure holds the values read
// from the HMC5883L x,y,z registers.
hmc5883l_result compass = {0,0,0};

//------------------------------
void hmc5883l_read_data(void)
{
int8 x_lsb;
int8 x_msb;

int8 y_lsb;
int8 y_msb;

int8 z_lsb;
int8 z_msb;

i2c_start();
i2c_write(HMC5883L_WRT_ADDR);
i2c_write(HMC5883L_X_MSB_REG);  // Point to X-msb register
i2c_start();
i2c_write(HMC5883L_READ_ADDR);

x_msb = i2c_read();
x_lsb = i2c_read();

y_msb = i2c_read();
y_lsb = i2c_read();

z_msb = i2c_read();
z_lsb = i2c_read(0);   // do a NACK on last read

i2c_stop();
 
// Combine high and low bytes into 16-bit values.
compass.x = make16(x_msb, x_lsb);
compass.y = make16(y_msb, y_lsb);
compass.z = make16(z_msb, z_lsb);
}


//==========================================
void main()
{
delay_ms(500);  // A power-on init delay may be needed 

printf("\n\rStart:\n\r");

// Init the HMC5883L.  Set Mode register for
// continuous measurements.
hmc5883l_write_reg(HMC5883L_CFG_A_REG, 0x70);
hmc5883l_write_reg(HMC5883L_CFG_B_REG, 0xA0);
hmc5883l_write_reg(HMC5883L_MODE_REG, 0x00);

// Continuously read and display the x,y,z results.
// Wait at least 67 ms between reads, re the HMC5883L data sheet.
while(1)
  {
   delay_ms(100); 
   hmc5883l_read_data();   
   printf("%lx, %lx, %lx \n\r", compass.x, compass.y, compass.z);
  }   
   
}
Tom1234



Joined: 06 Jan 2013
Posts: 39

View user's profile Send private message

HMC5883L Help
PostPosted: Sun Apr 07, 2013 6:02 pm     Reply with quote

Thanks PCM Programmer.

I test this code and is look like that is working. (I will further study and i will ask some things).

But firstly there is any way to check if the sensor is give me correct data??

and also why you write the function int8 hmc5883l_read_reg(int8 reg) (below) but you never use it !!!

Code:

int8 hmc5883l_read_reg(int8 reg)
{
int8 retval;

i2c_start();
i2c_write(HMC5883L_WRT_ADDR);
i2c_write(reg);
i2c_start();
i2c_write(HMC5883L_READ_ADDR);
retval = i2c_read(0);
i2c_stop();

return(retval);
}

PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 07, 2013 6:24 pm     Reply with quote

You might want to read the Status register or the Identification Registers
sometime.
amjad_alahdal



Joined: 19 Feb 2013
Posts: 50

View user's profile Send private message Yahoo Messenger MSN Messenger

PostPosted: Sat May 11, 2013 1:27 pm     Reply with quote

Question ::

When the x-axis in the sensor points to the North,
what should the output be ?
I Have changed the display type to be :
Code:

fprintf(COM_LCD,"%Lu, %Lu, %Lu ", compass.x, compass.y, compass.z);


TO have integers


I want the value to be 0 at North, and 90 at East
savotech



Joined: 13 Dec 2012
Posts: 12

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

PostPosted: Sun Jan 19, 2014 6:17 pm     Reply with quote

pcm programmer, please thanks for that code, its working very fine. i edited the printf code and make it display on lcd and i saw the the X Y and Z values are changing as i change direction.

Please help me, my challenge now is that i don't know how to interpret those values to get my real north, east, west, south stuff or interpret it to degrees stuff.

I read on net that arctan of Yvalue/Xvalue gives the angle but i tried that but i don't get a tangible result, and again, i don't know what to use the Zvalue for.

So please anybody that can help me modify pcm programmer code to give me the result in degrees, thanks in expectance of favourable reply
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sun Jan 19, 2014 6:40 pm     Reply with quote

The values are often raw magnetometer readings. If you understand geometry and trigonometry you have a chance of succeeding. I don't see you succeeding by asking questions of this forum it is not so far a forum that teaches mathematics. You might find some code for ardruino's. Multiwi is open source and there is c code you might be able to throw at the wall and have something useful stick. Then again without an understanding of the mathematics it will be difficult. As far as the Z axis it has a role since the x and y axis can rotate into the z axis as the platform pitches and rolls. The Earth's magnetic field has a declination that is dependent on latitude and longitude ...the field varies in 3 dimensions so X,Y and Z are needed unless the Z axis is always vertical and fixed as well as the lat and long.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 19, 2014 8:27 pm     Reply with quote

Quote:
So please anybody

How about you learning how to search for the answer.

I typed this into http://www.google.com
Quote:
HMC5883L convert to degrees

Google showed this answer, from Ttelmah on this forum:
http://www.ccsinfo.com/forum/viewtopic.php?t=50920&start=2
savotech



Joined: 13 Dec 2012
Posts: 12

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

PostPosted: Mon Jan 20, 2014 8:02 am     Reply with quote

Thank you all for replying me. I have really gained a lot here

I have successfully converted the the values to degree (sorry i can't paste the code, i am browsing the with my phone).

I have another challenge: i am not getting 0-360 degrees on the x-y axis, i.e. when i put the sensor on a plane table, and rotate, it wont give me a full range, its giving me a value between 21 and 150 degrees. But when i turn it through Z-axis, it gives me a full range.

When i rotate it on a table, it the angle displayed begins to decrease till 21 degrees and begins to increase till 150 degrees and then decreases again, until i rotate it through the zaxis. It gives a full range turning it like a circle going in 3D. What could be the problem, please help me sir.
savotech



Joined: 13 Dec 2012
Posts: 12

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

PostPosted: Mon Jan 20, 2014 8:16 am     Reply with quote

Ooooh! I am sorry guys, i have seen my mistake, i misinterpreted the xyz diagram on the hmc5883l sensor, i laid it down flat instead of making it stand upright. Thats why the system is reading Zaxis variation instead of Yaxis.

I now have a full working digital compass, thanks to God and thanks to you all.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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