Sunday, April 26, 2015

Simple Compass - Arduino Nano + GY-271(HMC5883L) + mini-OLED

Use Arduino Nano + GY-271 Digital Compass Module (with HMC5883L) + 0.96" I2C mini-OLED to implement a simple compass.


For HMC5883L library with calibration, refer LAST POST.
For u8glib library used on 0.96" I2C mini OLED, refer Hello World 0.96 inch 128X64 I2C OLED, on Arduino Uno, using u8glib library.
Connection between Arduino Nano, GY-271 and the mini OLED via I2C, refer to Arduino Nano + GY-271 (Digital Compass module) + OLED.


Nano_Compass.ino
/*
http://arduino-er.blogspot.com/

For HMC5883L_Header_Arduino_Auto_calibration library
ref: http://hobbylogs.me.pn/?p=17

For u8glib Universal Graphics Library for 8 Bit Embedded Systems
ref: https://code.google.com/p/u8glib/
*/

#include "U8glib.h"
#include <Wire.h>
#include "compass.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);

#define Task_t 10          // Task Time in milli seconds

int dt=0;
unsigned long t;
// Main code -----------------------------------------------------------------
void setup(){
  Serial.begin(9600);
  // Serial.print("Setting up I2C ........\n");
  Wire.begin();
  compass_x_offset = -48.23;  //122.17;
  compass_y_offset = 284.69;  //230.08;
  compass_z_offset = 59.87;  //389.85;
  compass_x_gainError = 1.07;  //1.12;
  compass_y_gainError = 1.09;  //1.13;
  compass_z_gainError = 1.01;  //1.03;
  
  compass_init(2);
  //compass_debug = 1;
  //compass_offset_calibration(3);

}

void loop(){
  
  t = millis();
 
  float load;
 
  compass_scalled_reading();
  
  Serial.print("x = ");
  Serial.println(compass_x_scalled);
  Serial.print("y = ");
  Serial.println(compass_y_scalled);
  Serial.print("z = ");
  Serial.println(compass_z_scalled);
  
  compass_heading();
  Serial.print ("Heading angle = ");
  Serial.print (bearing);
  Serial.println(" Degree");
  
  dt = millis()-t;
  load = (float)dt/(Task_t/100);
  Serial.print ("Load on processor = ");
  Serial.print(load);
  Serial.println("%");
  
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );

  delay(100);
}

void draw(void) {
  static int armLength = 20;
  static int cx = 64;
  static int cy = 20;
  int armX, armY;
  
  //convert degree to radian
  float bearingRad = bearing/57.2957795;
  armX = armLength*cos(bearingRad);
  armY = -armLength*sin(bearingRad);

  u8g.setFont(u8g_font_unifont);
  
  u8g.setPrintPos(0, 60);
  u8g.print("bearing: ");
  u8g.setPrintPos(70, 60);
  u8g.print(bearing);
  
  u8g.drawLine(cx, cy, cx-armX, cy-armY);
  u8g.drawCircle(cx, cy, armLength, U8G_DRAW_ALL);

}

14 comments:

  1. where can i find the compass.h file?

    ReplyDelete
    Replies
    1. Read it: http://arduino-er.blogspot.com/2015/04/hmc5883l-library-with-calibration-for.html

      Delete
  2. Hello,this link is dead, can you mail me compass.h file?Thank you very much.

    ReplyDelete
  3. i have uploaded your codes successfully but then display shows a round with pointer positioned near to 6 o clock postion and letters are saying "bearing: 99.62" which is not change with module position

    ReplyDelete
    Replies
    1. I had the same problem. It was due to the metal in the breadboard. Use wires to move the sensor away from other metal.

      Delete
  4. I tried to fix my problems with this tutorial. I cannot find the library compass.h.
    Can you help me?

    ReplyDelete
  5. Where can i find the compass.h file?

    ReplyDelete
  6. Hi Erik,
    where can i find the compass.h file?

    ReplyDelete
  7. me too 99.62 fixed. nothing change by moving module

    ReplyDelete
  8. How can a correction be made to the read out to compensate for declination to give true north?

    ReplyDelete