Compass: Difference between revisions

From Noisebridge
Jump to navigation Jump to search
(9 intermediate revisions by the same 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
* [[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
Line 26: Line 27:
Other products
Other products
* http://www.alibaba.com/product-gs/298165096/3D_electronic_compass_inclinometer_heading_sensor.html
* 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 69: 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]]

Revision as of 02:44, 24 December 2013

CompassBreadboard.jpg

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

Components

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

Other potential components

Future potential SMD components

Other products

Schematic

CompassSchematic.jpg

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