Last active
March 21, 2019 16:21
-
-
Save Shadow6363/8473080 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
add this at top
#include <Wire.h> //I2C Library