O Watch
Published © GPL3+

Compass

3 Axis Compass Sensor O Watch Sensor Kit.

BeginnerShowcase (no instructions)15 minutes959
Compass

Things used in this project

Hardware components

O Watch Sensor Kit
O Watch Sensor Kit
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

O Watch Compass Sensor Demo

Arduino
/*
 * Compass demo for O Watch
 * This demo shows the heading or magnetic direction your are pointing O Watch
 * O Watch needs to be help parallel to the ground and away from any magnetic materials
 * 
 * Based on TinyCompass demo by Tony Batey 
 * https://www.hackster.io/tbatey_tiny-circuits/tinycompass-32de65
 * 
 * This example is in the public domain
 * http://theowatch.com
 * 
 */

#include <TinyScreen.h> //TinyScreen Library
#include <Wire.h> //Communication with sensor board via I2C
#include <SPI.h>  //Communication with OLED 

TinyScreen display = TinyScreen(TinyScreenPlus);

//Declare the variables for use in the program

int x, y, z;
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;

#define HMC5883_I2CADDR     0x1E //Set the address for the compass

void setup()
{ 
  Wire.begin();
  display.begin();
  display.setFlip(1);
  display.setFont(liberationSans_10ptFontInfo);
  display.fontColor(TS_8b_White,TS_8b_Black);
      display.setFont(liberationSans_12ptFontInfo);
  display.setCursor(20,15); 
  HMC5883nit(); //initialize the compass

      //Draw an arrow pointing top
    display.drawLine(5,20,10,10,TS_8b_White);
    display.drawLine(10,40,10,10,TS_8b_White);      
    display.drawLine(15,20,10,10,TS_8b_White); 
}
     
     
     
void loop()
{


      ReadMyCompass();
      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;
      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; 
      display.setCursor(25,10);

      Degrees = Degrees-90; //Adjust 90 degrees because the sensor is pointing right
      if (Degrees < 0) Degrees=Degrees+360;
      if(Degrees<30 || Degrees> 330) display.print("N  ");
      if(Degrees >= 30 && Degrees< 60) display.print("NE "); 
      if(Degrees >= 60 && Degrees< 120) display.print("E  "); //East and West flipped here because the compass is upside down
      if(Degrees >= 120 && Degrees< 150) display.print("SE ");
      if(Degrees >= 150 && Degrees< 210) display.print("S ");
      if(Degrees >= 210 && Degrees< 240) display.print("SW ");
      if(Degrees >= 240 && Degrees< 300) display.print("W  "); //East and West flipped here because the compass is upside down
      if(Degrees >= 300 && Degrees< 330) display.print("NW ");
    
      display.setCursor(25,30);
      display.print(Degrees); //Display the heading in degrees
      display.print("  ");
      delay(100); 
      display.clearWindow(25,10,55,50);
 

}

void HMC5883nit()
{
  //Put the HMC5883 into operating mode
  Wire.beginTransmission(HMC5883_I2CADDR);
  Wire.write(byte(0x02));     // Mode register
  Wire.write(byte(0x00));     // Continuous measurement mode
  Wire.endTransmission();
}

void ReadMyCompass()
{
    Wire.beginTransmission(HMC5883_I2CADDR);
      Wire.write(byte(0x03));       // Send request to X MSB register
      Wire.endTransmission();
      Wire.requestFrom(HMC5883_I2CADDR, 6);    // Request 6 bytes; 2 bytes per axis
      if(Wire.available() <=6) // If 6 bytes available
      {    
        x = (int16_t)(Wire.read() << 8 | Wire.read());
        z = (int16_t)(Wire.read() << 8 | Wire.read());
        y = (int16_t)(Wire.read() << 8 | Wire.read());
      }
}

Credits

O Watch

O Watch

9 projects • 15 followers
Make your own smartwatch. Learn 3D design and Arduino coding.

Comments