Skip to content

Instantly share code, notes, and snippets.

@murilopontes
Created March 25, 2014 04:17
Show Gist options
  • Save murilopontes/9755203 to your computer and use it in GitHub Desktop.
Save murilopontes/9755203 to your computer and use it in GitHub Desktop.
/*
Arduino Nano V3
SDA ---> A4
SCL ---> A5
*/
//I2C lib
#include <Wire.h>
////////////////////////////////////
// address
#define hmc5883_addr_read 0x3d
#define hmc5883_addr_write 0x3c
#define hmc5883_addr_rw 0x1e
/////////////////////////////////////
// regs
#define hmc5883_reg_config_a 0
#define hmc5883_reg_config_b 1
#define hmc5883_reg_mode 2
#define hmc5883_reg_x_msb 3
#define hmc5883_reg_x_lsb 4
#define hmc5883_reg_z_msb 5
#define hmc5883_reg_z_lsb 6
#define hmc5883_reg_y_msb 7
#define hmc5883_reg_y_msb 8
#define hmc5883_reg_status 9
#define hmc5883_reg_id_a 10
#define hmc5883_reg_id_b 11
#define hmc5883_reg_id_c 12
///////////////////////////////////////
// reg configure A
#define hmc5883_avg_1 1<<5
#define hmc5883_avg_2 2<<5
#define hmc5883_avg_4 3<<5
#define hmc5883_avg_8 4<<5
#define hmc5883_hz_0_75 0<<2
#define hmc5883_hz_1_5 1<<2
#define hmc5883_hz_3 2<<2
#define hmc5883_hz_7_5 3<<2
#define hmc5883_hz_15 4<<2
#define hmc5883_hz_30 5<<2
#define hmc5883_hz_75 6<<2
#define hmc5883_ms_normal 0
#define hmc5883_ms_positive 1
#define hmc5883_ms_negative 2
///////////////////////////////////////
// reg configure B
#define hmc5883_gain_0_88 0<<4
#define hmc5883_gain_1_33 1<<4
#define hmc5883_gain_1_9 2<<4
#define hmc5883_gain_2_5 3<<4
#define hmc5883_gain_4 4<<4
#define hmc5883_gain_4_7 5<<4
#define hmc5883_gain_5_6 6<<4
#define hmc5883_gain_8_1 7<<4
////////////////////////////////////////
// reg configure mode
#define hmc5883_md_continuous 0
#define hmc5883_md_single 1
/////////////////////////////////////////
void setup()
{
//usart debug
Serial.begin(115200);
//i2c start
Wire.begin();
//configure hmc5883l
Wire.beginTransmission(hmc5883_addr_rw);
Wire.write( hmc5883_reg_config_a );
Wire.write( hmc5883_avg_8 | hmc5883_hz_15 | hmc5883_ms_normal);
Wire.endTransmission( );
Wire.beginTransmission(hmc5883_addr_rw);
Wire.write( hmc5883_reg_config_b );
Wire.write( hmc5883_gain_5_6 );
Wire.endTransmission();
Wire.beginTransmission(hmc5883_addr_rw);
Wire.write( hmc5883_reg_mode );
Wire.write( hmc5883_md_continuous);
Wire.endTransmission();
}
//format buffer
char buf[100];
void loop()
{
//point to first data register
Wire.beginTransmission(hmc5883_addr_rw);
Wire.write(hmc5883_reg_x_msb);
Wire.endTransmission();
int rxmax=6;
int rxc = 0;
int rxdata[6];
Wire.requestFrom(hmc5883_addr_rw, rxmax);
while(Wire.available() && rxc<rxmax)
{
rxdata[rxc]=Wire.read();
rxc++;
}
uint16_t x,y,z; //triple axis data
x = rxdata[1] | rxdata[0] <<8;
z = rxdata[3] | rxdata[2] <<8;
y = rxdata[5] | rxdata[4] <<8;
sprintf(buf,"(X)%02x%02x (Z)%02x%02x (Y)%02x%02x (array)",rxdata[0],rxdata[1],rxdata[2],rxdata[3],rxdata[4],rxdata[5],rxdata[6]);
Serial.println(buf);
sprintf(buf,"(X)%04x (Z)%04x (Y)%04x (value)",x,z,y);
Serial.print(buf);
///////////////////////////////////////////////////////////
int status;
Wire.beginTransmission(hmc5883_addr_rw);
Wire.write(hmc5883_reg_status);
Wire.endTransmission();
Wire.requestFrom(hmc5883_addr_rw, 1);
status=Wire.read();
sprintf(buf," status=%02x",status);
Serial.print(buf);
///////////////////////////////////////////////
int a,b,c;
Wire.beginTransmission(hmc5883_addr_rw);
Wire.write(hmc5883_reg_id_a);
Wire.endTransmission();
Wire.requestFrom(hmc5883_addr_rw, 1);
a=Wire.read();
Wire.beginTransmission(hmc5883_addr_rw);
Wire.write(hmc5883_reg_id_b);
Wire.endTransmission();
Wire.requestFrom(hmc5883_addr_rw, 1);
b=Wire.read();
Wire.beginTransmission(hmc5883_addr_rw);
Wire.write(hmc5883_reg_id_c);
Wire.endTransmission();
Wire.requestFrom(hmc5883_addr_rw, 1);
c=Wire.read();
sprintf(buf," ID=%c%c%c ",a,b,c);
Serial.print(buf);
///////////////////////////////////////////////
float angle= atan2((float)y,(float)x) * (180 / 3.14159265) + 180; // angle in degrees
Serial.print(" angle=");
Serial.print((int) angle);
Serial.print(" You are heading ");
if((angle < 22.5) || (angle > 337.5 ))
Serial.print("South");
if((angle > 22.5) && (angle < 67.5 ))
Serial.print("South-West");
if((angle > 67.5) && (angle < 112.5 ))
Serial.print("West");
if((angle > 112.5) && (angle < 157.5 ))
Serial.print("North-West");
if((angle > 157.5) && (angle < 202.5 ))
Serial.print("North");
if((angle > 202.5) && (angle < 247.5 ))
Serial.print("NorthEast");
if((angle > 247.5) && (angle < 292.5 ))
Serial.print("East");
if((angle > 292.5) && (angle < 337.5 ))
Serial.print("SouthEast");
Serial.println("");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment