Compass
Jump to navigation
Jump to search
This shows the general distribution and strengths of the Earth's magnetic field on teh surface.
Compasses react to magnetic fields, in particular pointing to magnetic North, to find True North, an offset needs to be applied, which will adjust headings to indicate the direction of North Pole.
HMC6352[edit | edit source]
CMPS03[edit | edit source]
Breadboard with Compass module, ShiftBrite, Boarduino, calibration button with indicator, & FTDI serial out connected.
Components[edit | edit source]
- Compass Module CMPS03 http://www.robot-electronics.co.uk/htm/cmps3tech.htm
- DC Boarduino http://learn.adafruit.com/boarduino-kits/dc-parts-list
- FTDI Friend http://www.adafruit.com/products/284
- ShiftBrite http://macetech.com/blog/node/54
Other potential components
- Compass Module HM55B http://www.hobbyengineering.com/specs/PX-29123.pdf
- SCF5740 Siemens (OSRAM) 4 digit display http://catalog.osram-os.com/media/_en/Graphics/00034126_0.pdf
- 0.96" OLED Display https://www.adafruit.com/products/684
- FTDI/USB http://www.parallax.com/catalog/integrated-circuits/ftdi
- RGB LED http://www.taydaelectronics.com/rgb-led-5mm.html
- RGBpixel
Future potential SMD components
Other products
Schematic[edit | edit source]
Indicates wiring for RGBpixel LEDs, as opposed to ShiftBrite
Code[edit | edit source]
The following will give a compass heading via serial monitor with the CMPS03
/*
CMPS03 with arduino I2C example
This will display a value of 0 - 359 for a full rotation of the compass.
The SDA line is on analog pin 4 of the arduino and is connected to pin 3 of the CMPS03.
The SCL line is on analog pin 5 of the arduino and is conected to pin 2 of the CMPS03.
Both SDA and SCL are also connected to the +5v via a couple of 1k8 resistors.
A switch to callibrate the CMPS03 can be connected between pin 6 of the CMPS03 and the ground.
*/
#include <Wire.h>
#define ADDRESS 0x60 //defines address of compass
void setup(){
Wire.begin(); //conects I2C
Serial.begin(9600);
}
void loop(){
byte highByte;
byte lowByte;
Wire.beginTransmission(ADDRESS); //starts communication with cmps03
Wire.write(2); //Sends the register we wish to read
Wire.endTransmission();
Wire.requestFrom(ADDRESS, 2); //requests high byte
while(Wire.available() < 2); //while there is a byte to receive
highByte = Wire.read(); //reads the byte as an integer
lowByte = Wire.read();
int bearing = ((highByte<<8)+lowByte)/10;
Serial.println(bearing);
delay(100);
}
This code will provide x/y magnetic strength and computed angle with the HM55B
/*
/////////////////////////////////
Htachi HM55B Compass
parallax (#)
AUTHOR: kiilo kiilo@kiilo.org
License: http://creativecommons.org/licenses/by-nc-sa/2.5/ch/
http://parallax.com/Store/Microcontrollers/BASICStampModules/tabid/134/txtSearch/hm55b/List/1/ProductID/98/Default.aspx?SortField=ProductName%2cProductName
http://sage.medienkunst.ch/tiki-index.php?page=HowTo_Arduino_Parallax_HM55B_Kompass
http://playground.arduino.cc/HM55B
/////////////////////////////////
*/
#include <math.h> // (no semicolon)
//// VARS
byte CLK_pin = 8;
byte EN_pin = 9;
byte DIO_pin = 10;
int X_Data = 0;
int Y_Data = 0;
int angle;
//// FUNCTIONS
void ShiftOut(int Value, int BitsCount) {
for(int i = BitsCount; i >= 0; i--) {
digitalWrite(CLK_pin, LOW);
if ((Value & 1 << i) == ( 1 << i)) {
digitalWrite(DIO_pin, HIGH);
//Serial.print("1");
}
else {
digitalWrite(DIO_pin, LOW);
//Serial.print("0");
}
digitalWrite(CLK_pin, HIGH);
delayMicroseconds(1);
}
//Serial.print(" ");
}
int ShiftIn(int BitsCount) {
int ShiftIn_result;
ShiftIn_result = 0;
pinMode(DIO_pin, INPUT);
for(int i = BitsCount; i >= 0; i--) {
digitalWrite(CLK_pin, HIGH);
delayMicroseconds(1);
if (digitalRead(DIO_pin) == HIGH) {
ShiftIn_result = (ShiftIn_result << 1) + 1;
//Serial.print("x");
}
else {
ShiftIn_result = (ShiftIn_result << 1) + 0;
//Serial.print("_");
}
digitalWrite(CLK_pin, LOW);
delayMicroseconds(1);
}
//Serial.print(":");
// below is difficult to understand:
// if bit 11 is Set the value is negative
// the representation of negative values you
// have to add B11111000 in the upper Byte of
// the integer.
// see: http://en.wikipedia.org/wiki/Two%27s_complement
if ((ShiftIn_result & 1 << 11) == 1 << 11) {
ShiftIn_result = (B11111000 << 8) | ShiftIn_result;
}
return ShiftIn_result;
}
void HM55B_Reset() {
pinMode(DIO_pin, OUTPUT);
digitalWrite(EN_pin, LOW);
ShiftOut(B0000, 3);
digitalWrite(EN_pin, HIGH);
}
void HM55B_StartMeasurementCommand() {
pinMode(DIO_pin, OUTPUT);
digitalWrite(EN_pin, LOW);
ShiftOut(B1000, 3);
digitalWrite(EN_pin, HIGH);
}
int HM55B_ReadCommand() {
int result = 0;
pinMode(DIO_pin, OUTPUT);
digitalWrite(EN_pin, LOW);
ShiftOut(B1100, 3);
result = ShiftIn(3);
return result;
}
void setup() {
Serial.begin(9600);
pinMode(EN_pin, OUTPUT);
pinMode(CLK_pin, OUTPUT);
pinMode(DIO_pin, INPUT);
HM55B_Reset();
}
void loop() {
HM55B_StartMeasurementCommand(); // necessary!!
delay(40); // the data is 40ms later ready
Serial.print(HM55B_ReadCommand()); // read data and print Status
Serial.print(" ");
X_Data = ShiftIn(11); // Field strength in X
Y_Data = ShiftIn(11); // and Y direction
Serial.print(X_Data); // print X strength
Serial.print(" ");
Serial.print(Y_Data); // print Y strength
Serial.print(" ");
digitalWrite(EN_pin, HIGH); // ok deselect chip
angle = 180 * (atan2(-1 * Y_Data , X_Data) / M_PI); // angle is atan( -y/x) !!!
Serial.print(angle); // print angle
Serial.println("");
}
See also: Compass_Vibro_Anklet

