Compass: Difference between revisions
Jump to navigation
Jump to search
mNo edit summary |
→Code: added HM55B code |
||
| Line 33: | Line 33: | ||
== Code == | == Code == | ||
The following will give a compass heading via serial monitor | The following will give a compass heading via serial monitor with the CMPS03 | ||
<pre> | <pre> | ||
| Line 72: | Line 72: | ||
Serial.println(bearing); | Serial.println(bearing); | ||
delay(100); | delay(100); | ||
} | |||
</pre> | |||
This code will provide x/y magnetic strength and computed angle with the HM55B | |||
<pre> | |||
/* | |||
///////////////////////////////// | |||
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(""); | |||
} | } | ||
</pre> | </pre> | ||
Revision as of 02:42, 24 December 2013
Breadboard with Compass module, ShiftBrite, Boarduino, calibration button with indicator, & FTDI serial out connected.
Components




- 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
- 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
Indicates wiring for RGBpixel LEDs, as opposed to ShiftBrite
Code
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