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