How to Make The Tiny Compass

Picture of TinyCompassIn this Instructable, we will be building a compass using the TinyShield Compass as well as the Circle Edge Led shield.

Step 1: Materials

Lucky for us there are no downloads for this project, we can simply use the codebender plugin to directly program our TinyDuino.
Materials
  • TinyDuino Processor w/Battery Holder : link
  • TinyShield USB: link
  • TinyShield Compass : link
  • TinyShield Circle Edge LEDs: link
  • CR1632 3V coin cell battery

Step 2: Programming the Tiny Duino

The code below was used for the TinyCompass and has comments throughout to help explain what is going on. The magnetometer used for our compass board is the Honeywell HMC5883L 3-axis compass. This code can be downloaded to your computer or directly uploaded to your TinyDuino processor board.

/*
TinyDuino Compass Demo

This example code is in the public domain.

January 26, 2015 by Tony Batey

https://tiny-circuits.com/

*/
#include <Wire.h>

#define Addr 0x1E               // 7-bit address of HMC5883 compass

void setup() {
  Serial.begin(9600);
  delay(100);                   // Power up delay
  Wire.begin();
 
  // Set operating mode to continuous
  Wire.beginTransmission(Addr);
  Wire.write(byte(0x02));
  Wire.write(byte(0x00));
  Wire.endTransmission();
}
int x_max=-10000;  // Starting values for hard iron calibration
int y_max=-10000;  // We want these values to be extreme in the
int x_min=10000;   // opposite direction so it calibrates nicely
int y_min=10000;

void loop() {
  int x, y, z;

  // Initiate communications with compass
  Wire.beginTransmission(Addr);
  Wire.write(byte(0x03));       // Send request to X MSB register
  Wire.endTransmission();

  Wire.requestFrom(Addr, 6);    // Request 6 bytes; 2 bytes per axis
  if(Wire.available() <=6) {    // If 6 bytes available
    x = Wire.read() << 8 | Wire.read();
    z = Wire.read() << 8 | Wire.read();
    y = Wire.read() << 8 | Wire.read();
  }
 
  // Print raw values
  Serial.print("X=");
  Serial.print(x);
  Serial.print(", Y=");
  Serial.print(y);
  Serial.print(", Z=");
  Serial.print(z);
 
  if(x > x_max) //Find values of hard iron distortion
    x_max = x;  //This will store the max and min values
  if(y >y_max)    //of the magnetic field around you
    y_max = y;
  if(y<y_min)
    y_min = y;
  if(x<x_min)
    x_min = x;
 
  //Print max and min values
  Serial.print(", Xmax=");
  Serial.print(x_max);
  Serial.print(", Ymax=");
  Serial.print(y_max);
  Serial.print(", Xmin=");
  Serial.print(x_min);
  Serial.print(", Ymin=");
  Serial.print(y_min);
 
  int xoffset= (x_max+x_min)/2;
  int yoffset= (y_max+y_min)/2;
 
  int x_scale = x-xoffset; // Math to compensate for hard
  int y_scale = y-yoffset; // iron distortions
 
  // Heading in radians
  float heading = atan2(x_scale,y_scale);
 
  //Heading between 0 and 6.3 radians
  if(heading < 0)
    heading += 2*PI;
   
  if(heading>2*PI)
    heading -= 2*PI;
 
  //Conversion to degrees 
  int Degrees = heading * 180/M_PI;
 
 
  Serial.print("Heading (degrees): "); Serial.print(Degrees);
 
  int LED = Degrees/17; //Led shield has 21 Leds. Dividing 360 by
                          //17 will give us values from 0 to 21
                         
  if (LED==0)             //since there is no Led 0, we will turn   
    LED=21;                //Led 21 on instead
  
  LedOn(LED);
  Serial.print("LED: "); Serial.println(LED);
 
  delay(40);
}

//Function to turn on the led indicated in the main loop
void LedOn(int ledNum)
{
  for(int i=4;i<10;i++)
  {
    pinMode(i, INPUT);
    digitalWrite(i, LOW);
  };
  if(ledNum<1 || ledNum>21) return;
  char highpin[21]={6,7,6,8,5,8,8,7,9,7,9,8,5,9,6,9,9,5,6,5,7};
  char lowpin[21]= {7,6,8,6,8,5,7,8,7,9,8,9,9,5,9,6,4,6,5,7,5};

  ledNum--;
  digitalWrite(highpin[ledNum],HIGH);
  digitalWrite(lowpin[ledNum],LOW);
  pinMode(highpin[ledNum],OUTPUT);
  pinMode(lowpin[ledNum],OUTPUT);
}

Step 3: Calibration

After your TinyDuino has been programmed you can remove the USB Shield. Each time you turn on or restart the processor, you will need to calibrate it. To calibrate, simply rotate it 360 degrees on each axis (the gifs above show exactly what to do). We now have fully functional compass that takes up less than a cubic inch of space! Because of how sensitive the HCM5883L chip is, ferromagnetic materials, magnetized or not, within a 2 inch radius of the chip will cause disturbances
 
Share on Google Plus

About Unknown

    Blogger Comment
    Facebook Comment

0 comments:

Post a Comment

Your Comment is Awaiting Moderation....