Skip to content

Instantly share code, notes, and snippets.

@Shadow6363
Last active March 21, 2019 16:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Shadow6363/8473080 to your computer and use it in GitHub Desktop.
Save Shadow6363/8473080 to your computer and use it in GitHub Desktop.
#define ARDUINO_H
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <math.h>
#define HMC5883L_Address 0x3C
#define ConfigurationRegisterA 0x00
#define ConfigurationRegisterB 0x01
#define ModeRegister 0x02
#define DataRegisterBegin 0x03
#define Measurement_Continuous 0x00
#define Measurement_SingleShot 0x01
#define Measurement_Idle 0x03
#define ErrorCode_1 "Entered scale was not valid, valid gauss values are: 0.88, 1.3, 1.9, 2.5, 4.0, 4.7, 5.6, 8.1"
#define ErrorCode_1_Num 1
struct MagnetometerScaled
{
float XAxis;
float YAxis;
float ZAxis;
};
struct MagnetometerRaw
{
int XAxis;
int YAxis;
int ZAxis;
} blob;
class HMC5883L
{
public:
HMC5883L();
MagnetometerRaw ReadRawAxis();
MagnetometerScaled ReadScaledAxis();
int SetMeasurementMode(uint8_t mode);
int SetScale(float gauss);
const char* GetErrorText(int errorCode);
protected:
void Write(int address, int byte);
uint8_t* Read(int address, int length);
private:
float m_Scale;
};
HMC5883L::HMC5883L()
{
m_Scale = 1;
}
MagnetometerRaw HMC5883L::ReadRawAxis()
{
uint8_t* buffer = Read(DataRegisterBegin, 6);
MagnetometerRaw raw = MagnetometerRaw();
raw.XAxis = (buffer[0] << 8) | buffer[1];
raw.ZAxis = (buffer[2] << 8) | buffer[3];
raw.YAxis = (buffer[4] << 8) | buffer[5];
return raw;
}
MagnetometerScaled HMC5883L::ReadScaledAxis()
{
MagnetometerRaw raw = ReadRawAxis();
MagnetometerScaled scaled = MagnetometerScaled();
scaled.XAxis = raw.XAxis * m_Scale;
scaled.ZAxis = raw.ZAxis * m_Scale;
scaled.YAxis = raw.YAxis * m_Scale;
return scaled;
}
int HMC5883L::SetScale(float gauss)
{
uint8_t regValue = 0x00;
if(gauss == 0.88)
{
regValue = 0x00;
m_Scale = 0.73;
}
else if(gauss == 1.3)
{
regValue = 0x01;
m_Scale = 0.92;
}
else if(gauss == 1.9)
{
regValue = 0x02;
m_Scale = 1.22;
}
else if(gauss == 2.5)
{
regValue = 0x03;
m_Scale = 1.52;
}
else if(gauss == 4.0)
{
regValue = 0x04;
m_Scale = 2.27;
}
else if(gauss == 4.7)
{
regValue = 0x05;
m_Scale = 2.56;
}
else if(gauss == 5.6)
{
regValue = 0x06;
m_Scale = 3.03;
}
else if(gauss == 8.1)
{
regValue = 0x07;
m_Scale = 4.35;
}
else
return ErrorCode_1_Num;
// Setting is in the top 3 bits of the register.
regValue = regValue << 5;
Write(ConfigurationRegisterB, regValue);
return 0;
}
int HMC5883L::SetMeasurementMode(uint8_t mode)
{
Write(ModeRegister, mode);
return 0;
}
void HMC5883L::Write(int address, int data)
{
Wire.beginTransmission(HMC5883L_Address);
Wire.write(address);
Wire.write(data);
Wire.endTransmission();
}
uint8_t* HMC5883L::Read(int address, int length)
{
Wire.beginTransmission(HMC5883L_Address);
Wire.write(address);
Wire.endTransmission();
Wire.beginTransmission(HMC5883L_Address);
Wire.requestFrom(HMC5883L_Address, length);
uint8_t* buffer = (uint8_t*)malloc(sizeof (uint8_t) * length);
if(Wire.available() == length)
{
for(uint8_t i = 0; i < length; i++)
{
buffer[i] = Wire.read();
}
}
Wire.endTransmission();
return buffer;
}
const char* HMC5883L::GetErrorText(int errorCode)
{
if(ErrorCode_1_Num == 1)
return ErrorCode_1;
return "Error not defined.";
}
// Output the data down the serial port.
void Output(struct MagnetometerRaw raw, struct MagnetometerScaled scaled)
{
Serial.print("Raw:\t");
Serial.print(raw.XAxis);
Serial.print(" ");
Serial.print(raw.YAxis);
Serial.print(" ");
Serial.print(raw.ZAxis);
Serial.print(" \tScaled:\t");
Serial.print(scaled.XAxis);
Serial.print(" ");
Serial.print(scaled.YAxis);
Serial.print(" ");
Serial.print(scaled.ZAxis);
}
// Store our compass as a variable.
HMC5883L compass;
// Record any errors that may occur in the compass.
int error = 0;
// Out setup routine, here we will configure the microcontroller and compass.
void setup()
{
// Initialize the serial port.
Serial.begin(9600);
Serial.println("Starting the I2C interface.");
Wire.begin(); // Start the I2C interface.
Serial.println("Constructing new HMC5883L");
compass = HMC5883L(); // Construct a new HMC5883 compass.
Serial.println("Setting scale to +/- 1.3 Ga");
error = compass.SetScale(1.3); // Set the scale of the compass.
if(error != 0) // If there is an error, print it out.
Serial.println(compass.GetErrorText(error));
Serial.println("Setting measurement mode to continous.");
error = compass.SetMeasurementMode(Measurement_Continuous); // Set the measurement mode to Continuous
if(error != 0) // If there is an error, print it out.
Serial.println(compass.GetErrorText(error));
}
// Our main program loop.
void loop()
{
// Retrive the raw values from the compass (not scaled).
MagnetometerRaw raw = compass.ReadRawAxis();
// Retrived the scaled values from the compass (scaled to the configured scale).
MagnetometerScaled scaled = compass.ReadScaledAxis();
// Values are accessed like so:
//int MilliGauss_OnThe_XAxis = scaled.XAxis;// (or YAxis, or ZAxis)
// Output the data via the serial port.
Output(raw, scaled);
// Normally we would delay the application by 66ms to allow the loop
// to run at 15Hz (default bandwidth for the HMC5883L).
// However since we have a long serial out (104ms at 9600) we will let
// it run at its natural speed.
//delay(66);
}
@shivaadusumilli
Copy link

add this at top
#include <Wire.h> //I2C Library

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment