Tag Archives: HMC5883L

Jarum Penunjuk Kompas Digital HMC5883L + TFT LCD 2.2″

Jarum Penunjuk Kompas Digital HMC5883L + TFT LCD 2.2″

Pada tutorial kali ini, saya akan berbagi pengalaman membuat  kompas digital dengan tampilan berupa jarum penunjuk yang ditampilkan pada LCD. LCD yang digunakan bukanlah LCD  (16×2) yang umum digunakan pada proyek elektronika, melainkan menggunakan TFT LCD 2.2″. Jarum penunjuk ditampilkan dalam bentuk animasi yang nantinya akan selalu menunjuk ke arah utara layaknya jarum pada kompas analog, sehingga kemanapun sensor kompas (pengguna) berputar maka jarum akan selalu menunjuk ke arah utara.

Sekilas tentang kompas
Pada dasarnya jarum penunjuk pada kompas akan selalu menunjuk ke arah kutub utara magnetis bumi. Oleh karena itu, untuk membuat kompas digital yang selalu menunjuk ke arah utara layaknya kompas konvensional adalah dengan membuat suatu algoritma. Algoritma tersebut sebagai berikut: berapapun heading sensor kompas maka heading penunjuk arah utara akan memiliki nilai yang sama dengan heading sensor namun arahnya berkebalikan. Algoritma tersebut dibuat menggunakan circular function atau yang biasa disebut dengan fungsi trigonometri.

sincos-75

Circular Function (mathdemos.org)

Pergerakan heading oleh sensor merupakan representasi dari unit lingkaran dengan koordinat (sin θ, cos θ) yang pergerakannya searah dengan jarum jam (CW). Untuk membuat jarum (animasi) bergerak berlawanan dengan arah jarum jam (CCW) adalah dengan menggunakan hubungan koordinat kartesius terhadap koordinat kutub, yakni (cos θ, sin θ).

Dengan menggunakan koordinat (cos θ, sin θ) maka jarum bergerak sebesar heading sensor namun arahnya berkebalikan.

Dengan demikian, berapapun besar heading sensor kompas maka pergerakan jarum akan selalu menunjuk ke arah utara magnetis bumi yang secara definitif menunjuk ke arah 0°. Sebagai contoh, ketika sensor menghadap (heading) sebesar 30° maka jarum akan melakukan heading yang sama namun arahnya berkebalikan, hal inilah yang membuat tampilan jarum selalu menunjuk ke arah 0° alias arah utara.

K3

Heading sensor kompas sebesar 30°

Komponen
[1] Arduino Pro Mini 5V
[1] Sensor Kompas HMC5883L
[1] TFT LCD 2.2″ ILI9340
[~] Komponen penunjang (breadboard, kabel jumper, dll)

Koneksi Pin

Arduino (Pro Mini, Uno) HMC5883L (GY-271 breakout) LCD TFT 2.2″ (ILI9340)
5V (VCC) VCC VIN
GND GND GND
A4 (SDA) SDA
A5 (SCL) SCL
D8 RST
D9 DC
D10 CS
D11 MOSI
D13 SCK

Rangkaian

Rangkaian Kompas Digital HMC5883L + TFT LCD 2.2″ + Arduino Pro Mini 5V

Kode Program

/******************************************************************************
  This is an sketch for the project below
  ----> http://engine-near.com

  Check out the links below to download specific library used in this project
  ----> https://github.com/platisd/HMC5883L
  ----> https://github.com/adafruit/Adafruit_ILI9340
  ----> https://github.com/adafruit/Adafruit-GFX-Library
 
  All library works with Arduino IDE 1.6.5 version. If using the above version
  please click 'tools' and select 'fix encoding & reload'

  Written by Fathur Miftahudin for http://engine-near.com
 *****************************************************************************/


#include <Wire.h>      // Library for I2C Communication
#include <HMC5883L.h>  // Library for Compass HMC5883L
#include "SPI.h"
#include "Adafruit_GFX.h"    // Library for all our adafruit displays
#include "Adafruit_ILI9340.h" // Library for Adafruit TFT LCD 2.2"
#include <SPI.h>
 
#if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
#endif

// These are the pins used for the Pro Mini & UNO
// for Due/Mega/Leonardo use the hardware SPI pins (which are different)
#define _sclk 13
#define _miso 12
#define _mosi 11
#define _cs 10
#define _dc 9
#define _rst 8


// Using software SPI is really not suggested, its incredibly slow
Adafruit_ILI9340 tft = Adafruit_ILI9340(_cs, _dc, _rst);
// Use hardware SPI
int error = 0;
 
HMC5883L compass; // HMC5883L
 
void setup(void){
 
 Serial.begin(9600);
 Wire.begin();
 
 // HMC5883L
 compass = HMC5883L();  
 error=compass.SetScale(1.3);
 if(error!=0)Serial.println(compass.GetErrorText(error));
 Serial.println("Setting measurement mode to continous.");
 error=compass.SetMeasurementMode(Measurement_Continuous); 
 if(error != 0)Serial.println(compass.GetErrorText(error));
 
 tft.begin(); // TFTdisplay
 display_show(); // Show display such as battery, time & circle
 
}
 
// Magnetic declination in Jakarta 0.64° = 0.0111 rad
float declinationAngle=0.0111;
 
int heading_degrees=0;
int heading_degrees_old=360;
int heading_degrees_correction=-90;
 
void loop(void){
 
  MagnetometerScaled scaled=compass.ReadScaledAxis();
  
  float heading=atan2(scaled.YAxis,scaled.XAxis);
  
  heading+=declinationAngle;
  if(heading<0)heading+=2*PI;
  if(heading>=2*PI)heading-=2*PI;
 
  heading_degrees=heading*180/M_PI; //+heading_degrees_correction;
  if(heading_degrees<0)heading_degrees+=360;
  if(heading_degrees>=360)heading_degrees-=360;
 
  if(heading_degrees!=heading_degrees_old){
  
    display_info(); // Show compass heading
    display_graphic(); // Show animation (North direction)
    heading_degrees_old=heading_degrees;
 }
   delay(250);
}
 
// Determine coordinate of the circle
#define cx 120 // X coordinate
#define cy 160 // Y coordinate
#define cr 85 // Diameter of circle
 
void display_show(){
 
 tft.fillScreen(ILI9340_BLACK); 
 // Compass circle
 tft.fillCircle(120, 160, 97, ILI9340_WHITE);
 tft.fillCircle(120, 160, 84, ILI9340_BLACK);
    
 tft.fillCircle(120, 69, 5, ILI9340_BLACK);
 tft.fillCircle(120, 251, 5, ILI9340_BLACK);
    
 tft.fillCircle(29, 160, 5, ILI9340_BLACK);
 tft.fillCircle(211, 160, 5, ILI9340_BLACK);

 // Battery icon
 tft.fillRect(193, 6, 35, 17, ILI9340_WHITE);
 tft.fillRect(196, 9, 29, 11, ILI9340_BLACK); 
 tft.fillRect(198, 11, 18, 7, ILI9340_WHITE);
 tft.fillRect(228, 11, 4, 7, ILI9340_WHITE);

 // Time
 tft.setTextSize(2);
 tft.setCursor(5,8);
 tft.print("12:12");
 
}

void display_graphic(){

    // Animation of North direction
    int h=heading_degrees_old+90;
    int h2 = h - 90 ;
    int k2 = h + 90;

    tft.fillTriangle((int)(cx+(cr-70)*cos(M_PI/180*h2)),(int)(cy-(cr-70)*sin(M_PI/180*h2)), (int)(cx+(cr-12)*cos(M_PI/180*h)),(int)(cy-(cr-12)*sin(M_PI/180*h))
    ,(int)(cx+(cr-70)*cos(M_PI/180*k2)),(int)(cy-(cr-70)*sin(M_PI/180*k2)),ILI9340_BLACK);
    

    h=heading_degrees+90;
    h2 = h - 90 ;
    k2 = h + 90;

    tft.fillTriangle((int)(cx+(cr-70)*cos(M_PI/180*h2)),(int)(cy-(cr-70)*sin(M_PI/180*h2)), (int)(cx+(cr-12)*cos(M_PI/180*h)),(int)(cy-(cr-12)*sin(M_PI/180*h))
    ,(int)(cx+(cr-70)*cos(M_PI/180*k2)),(int)(cy-(cr-70)*sin(M_PI/180*k2)),ILI9340_WHITE);
 
    tft.fillCircle(120, 160, 15, ILI9340_WHITE); 
    tft.fillCircle(120, 160, 10, ILI9340_BLACK); 

}
 
void display_info(){

 tft.setTextSize(3);
 tft.fillRect(90,280,73,22,ILI9340_BLACK);
 tft.setTextColor(ILI9340_WHITE);
 tft.setCursor(95,280);
 tft.print(heading_degrees); // Print compass heading 

 tft.setTextSize(2);
 tft.write(247); // Print degree symbol
 delay(100);

}

Hasil Pengujian
Secara pemrograman arah utara magnetis yang dibentuk jarum akan selalu tepat, namun mungkin karena sensor kompas HMC5883L mengalami interferensi medan magnet maka arah utara yang ditunjuk oleh animasi jarum dapat menjadi kurang tepat sesuai dengan defleksi yang terjadi pada sensor.

Perlu diketahui bahwa utara magnetis bumi bukanlah utara 0° sehingga nanti dalam penggunaannya harus disesuaikan dengan deklinasi atau pergeseran medan magnet di lokasi dimana anda berada. Untuk mengetahui berapa besar deklinasi yang terjadi di lokasi anda maka dapat mengunjungi http://www.magnetic-declination.com/

Jika anda ingin lebih memaksimalkan tampilan jarum penunjuk kompas pada LCD, tentunya anda dapat menggunakan imajinasi atau kreatifitas anda sendiri untuk membuat tampilan yang lebih menarik seperti pada video dibawah ini.

Referensi:
[1] https://processing.org/tutorials/trig/
[2] http://mathdemos.org/mathdemos/sincos-demo1/
[3] https://en.wikipedia.org/wiki/Magnetic_declination