Compass

From Noisebridge
(Difference between revisions)
Jump to: navigation, search
(Components)
m (Components)
 
(11 intermediate revisions by one user not shown)
Line 1: Line 1:
 
[[File:CompassBreadboard.jpg|600px]]
 
[[File:CompassBreadboard.jpg|600px]]
  
''Breadboard with Compass module and Boarduino, calibration button with indicator, FTDI serial out connected.''
+
''Breadboard with Compass module, ShiftBrite, Boarduino, calibration button with indicator, & FTDI serial out connected.''
  
 
== Components ==
 
== Components ==
 
[[File:CMPS03.jpg|thumb]]
 
[[File:CMPS03.jpg|thumb]]
 
[[File:DC-Boarduino.jpg|thumb]]
 
[[File:DC-Boarduino.jpg|thumb]]
[[File:OLED-96x64.jpg|thumb]]
+
[[File:ShiftBrite.jpg|thumb]]
 
[[File:FTDI-USB.jpg|thumb]]
 
[[File:FTDI-USB.jpg|thumb]]
  
Line 12: Line 12:
 
* DC Boarduino http://learn.adafruit.com/boarduino-kits/dc-parts-list
 
* DC Boarduino http://learn.adafruit.com/boarduino-kits/dc-parts-list
 
* FTDI Friend http://www.adafruit.com/products/284
 
* FTDI Friend http://www.adafruit.com/products/284
 +
* [[ShiftBrite]] http://macetech.com/blog/node/54
  
 
Other potential components
 
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
 
* 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
 
* 0.96" OLED Display https://www.adafruit.com/products/684
 
* FTDI/USB http://www.parallax.com/catalog/integrated-circuits/ftdi
 
* 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
 
Future potential SMD components
 
* MAG3110FCR1 http://www.digikey.com/product-detail/en/MAG3110FCR1/MAG3110FCR1CT-ND/3524267
 
* MAG3110FCR1 http://www.digikey.com/product-detail/en/MAG3110FCR1/MAG3110FCR1CT-ND/3524267
 +
 +
Other products
 +
* http://www.alibaba.com/product-gs/298165096/3D_electronic_compass_inclinometer_heading_sensor.html
 +
 +
== Schematic ==
 +
[[File:CompassSchematic.jpg|600px]]
 +
 +
''Indicates wiring for [[RGBpixel]] LEDs, as opposed to [[ShiftBrite]]''
  
 
== 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 64: Line 75:
 
}
 
}
 
</pre>
 
</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>
 +
 +
 +
See also: [[Compass_Vibro_Anklet]]
 +
 +
 +
[[Category:Fort]]

Latest revision as of 02:44, 24 December 2013

CompassBreadboard.jpg

Breadboard with Compass module, ShiftBrite, Boarduino, calibration button with indicator, & FTDI serial out connected.

[edit] Components

CMPS03.jpg
DC-Boarduino.jpg
ShiftBrite.jpg
FTDI-USB.jpg

Other potential components

Future potential SMD components

Other products

[edit] Schematic

CompassSchematic.jpg

Indicates wiring for RGBpixel LEDs, as opposed to ShiftBrite

[edit] 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

Personal tools