Arduino İle Dijital Pusula Yapımı

24 6.903

Bu projemizde MHC5883L 3 eksenli dijital pusula kullanarak arduino ile kendi pusulamızı yapacağız.

Malzemeler:

  1. Arduino
  2. HMC5883L 3 eksenli dijital pusula
  3. Nokia 5110 ekran (pcb versiyon)
  4. 2x Buton
  5. 1x Açma / kapama anahtarı

Projeyi Satın Al

Kütüphane Dosyalarını İndir

Elektronik Devre Şeması:

Pusula sensörü scl sda ve enerji pinlerini arduino karta takıyoruz.Uno ve nano kullanıyorsanız scl analog 5, sda analog 4. pine takınız.Megada pinler üzerinde yazıyor.Nokia ekran pinlerini de şekildeki gibi soldan sağa 5v , gnd , 7,6,5,4,,3 nolu pinlere takıyoruz.

Yazılım Kısmı:

#include <SPI.h>
#include <Wire.h>
#include <Button.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <Adafruit_HMC5883_U.h>
#include <Adafruit_Sensor.h>

//Init Display (SCLK, DIN, D/C, CS, RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);
//Init HMC5883L sensor
Adafruit_HMC5883_Unified compass = Adafruit_HMC5883_Unified(12345);

//Constants
const int lcdLight = 13; //BL pin of LCD to arduino pin 13 (BL = Back Light)
Button buttonA = Button(2,PULLUP); //Button to turn on/off display light
Button buttonB = Button(8,PULLUP); //Button for changing display mode
// For 1st display mode:
static unsigned char Leters[] = { 'N' , 'E' , 'S' , 'W' };
const static unsigned char PROGMEM arrow_bmp[] =
{B00100000, B00100000, B01110000, B01110000, B11111000};
// For 2nd display mode:
int r = 24; // radius of compass rose
int x0= 60; // x-origin
int y0= 24; // y-origin

//Variables
int flag=0;
int i=1;

void setup() {
pinMode(lcdLight, OUTPUT); // lcd led
compass.begin();
Wire.begin();
display.begin();
display.setContrast(60);
//Print a welcome message in startup for 6sec.//////////
digitalWrite(lcdLight,HIGH);
display.clearDisplay(); // clears the screen and buffer
display.setTextColor(BLACK);
display.setCursor(0,2);
display.print(" ARDUMOTIVE ");
display.setCursor(0,13);
display.print(" ArduinoBased ");
display.setCursor(0,23);
display.print(" compassn.Compass ");
display.setCursor(0,33);
display.print(" Michalis Vas.");
display.display(); // show splashscreen
digitalWrite(lcdLight,LOW);
delay(6000);
display.clearDisplay(); // clears the screen and buffer
}

void loop() {

//if buttonB is pressed, 'flag' will change between 0 and 1
if(buttonB.isPressed()){
delay(100);//small delay
if(flag==0){ flag=1; }
else{ flag=0; }
}
//if buttonA is pressed, 'i' will change between 0 and 1
if(buttonA.isPressed()){
if(i==0){ i=1; }
else{ i=0; }
}
if (i==0){
digitalWrite(lcdLight,HIGH);}
else{
digitalWrite(lcdLight,LOW);
}
sensors_event_t event;
compass.getEvent(&event);
float heading = atan2(event.magnetic.y, event.magnetic.x);

float declinationAngle = 0.22; // heading += declinationAngle;
if(heading < 0) heading += 2*PI; if(heading > 2*PI)heading -= 2*PI;
float headingDegrees = heading * 180/M_PI;
//Convert float to int
int angle=(int)headingDegrees;
display.clearDisplay();

if (flag==0){
DrawRow(angle);
display.drawBitmap(40, 24, arrow_bmp, 5, 5, 1);
display.drawLine(42, 0, 42, 24, BLACK);
display.setCursor(32,34);
display.print(angle);
display.setTextSize(1);
display.print("o");
display.display();
delay(500);
}
if (flag==1){
DrawCircle(angle);
display.setTextSize(2);
display.setTextColor(BLACK);
display.setCursor(0,0);
display.println(angle);

display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(x0-2,0);
display.println("N");

display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor((x0+r)-5,y0-3);
display.println("E");

display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(x0-2,y0+r-8);
display.println("S");

display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor((x0-r)+5,y0-3);
display.println("W");

// Triangle for direction
display.drawTriangle(0, 46, 20, 46, 10, 18, BLACK);
display.fillTriangle (0, 46, 20, 46, 10, 18, BLACK);
display.display();
delay(500); //print new value every 0.5sec
}
}/// end of program

//////////// Functions ////////////

//Draw rows and print letters to display - 1st Display Mode
void DrawRow(int angle) {

display.drawLine(0, 0, 84, 0, BLACK);
display.drawLine(0, 1, 84, 1, BLACK);

display.drawLine(0, 22, 91, 22, BLACK);
display.drawLine(0, 23, 95, 23, BLACK);

display.setTextSize(2);
display.setTextColor(BLACK);

int start = 42 - angle / 3 ;
if (start > 120) start += -120 ;

int x = 0 ;
int y = 18 ;
for (int i=0; i<4; i++) { x = start + (i*30) -1; if (x>119) x += -120;
display.drawPixel(x+1, y-2, 1);
display.drawPixel(x, y, 1);
display.drawPixel(x+1, y, 1);
display.drawPixel(x+2, y, 1);
display.drawPixel(x, y-1, 1);
display.drawPixel(x+1, y-1, 1);
display.drawPixel(x+2, y-1, 1);
display.setCursor((x-4),(y-16));
display.write(Leters[i]);
}
for (int i=0; i<24; i++) { x = start + (i*5) -1; if (x>119) x += -120;
display.drawPixel(x+1, y+1, 1);
display.drawPixel(x, y+2, 1);
display.drawPixel(x+1, y+2, 1);
display.drawPixel(x+2, y+2, 1);
display.drawPixel(x, y+3, 1);
display.drawPixel(x+1, y+3, 1);
display.drawPixel(x+2, y+3, 1);
};

for (int i=0; i<8; i++) { x = start + (i*15)-1; if (x>119) x += -120;
display.drawPixel(x+1, y-1, 1);

display.drawPixel(x, y, 1);
display.drawPixel(x+1, y, 1);
display.drawPixel(x+2, y, 1);
display.drawPixel(x, y+1, 1);
display.drawPixel(x+1, y+1, 1);
display.drawPixel(x+2, y+1, 1);

};
}

////Draw circle and print letters to display - 1st Display Mode
void DrawCircle(int angle) {
if (angle >= 0 && angle <=45) { int angle = angle/2; display.drawLine(x0, y0, x0+angle, y0-r, BLACK); } else if (angle >45 && angle <=90) { int angle = (angle-44)/2 ; display.drawLine(x0, y0, x0+r, (y0-r)+angle, BLACK); } else if (angle >90 && angle <=135) { int angle = (angle-90)/2; display.drawLine(x0, y0, x0+r, y0+angle, BLACK); } else if (angle >135 && angle <=180){ int angle = (angle-134)/2; display.drawLine(x0, y0, (x0+r)-angle, y0+r, BLACK); } else if (angle >180 && angle <=225){ int angle = (angle-178)/2; display.drawLine(x0, y0, x0-angle, y0+r, BLACK); } else if (angle >225 && angle <=270){ int angle = (angle-222)/2; display.drawLine(x0, y0, x0-r, (y0+r)-angle, BLACK); } else if (angle >270 && angle <=315){ int angle = (angle-270)/2; display.drawLine(x0, y0, x0-r, y0-angle, BLACK); } else if (angle >315 && angle <=360){
int angle = (angle-312)/2;
display.drawLine(x0, y0, (x0-r)+angle, y0-r, BLACK);
}
}
Bunlar da İlgini Çekebilir
Cevap bırakın

E-posta hesabınız yayımlanmayacak.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

24 Yorum
  1. Atahan

    Merhabalar kodu arduinoya yazdığımda PULLUP was not declared in this scope hatası aldım nasıl çözerim

  2. KEMAL

    BU PROJENDEKİ DEVREYİ SORUNSUZ YAPTIM AMA EKRANDA GRAFİK DEGERLERİ GELMİYOR PUSULA OKUMUYOR GALİBA CALİBRE FİLANMI ETMEM LAZIM PUSULANIN SAGLAMLIGINDANDA EMINIM BASKA BIR DEVREDE CALISIYOR AMA BU PROJEDE EKRANA SADECE

    “ARDUMOTIVE
    ArduinoBased
    compassn.Compass
    Michalis Vas”

    BU YAZI GÖRZUKUYOR 5110 EKRANINDA

  3. batuhan

    hocam 4 eksende kodu değiştirmeye gerek varmı ?

  4. Vepa

    Kardeşim ben bu kütüphaneleri yükledim ama kodu derlerken hata veriyor nedense yardamcı olursanız sevinirim

  5. İbrahim

    Kolay gelsin usta. Bir sorum olacak kütüphaneleri ekliyorum ama turuncu yerine siyah oluyor yazılar #include<'den sonrası neden acaba?

  6. kamuran yiğittekin

    dostum bana da yardımcı olur musun kütüphane işinde yükleyemiyorum bir türlü

  7. gökhan

    Sezgin bey, aşağıdaki kodlarla ilgili sorularım olacak, 1-) MPU6050 ile sizin kullandığınız sensör arasında fark varmı. 2-) 90 derece dönüş için &z bilgisini kullanabilir miyim. 3-) map komutunun içindeki 17000 değeri neyi ifade ediyor. komutu şöyle yazarsam olurmu map(&z,0,17000,0,90);
    4-)
    motor_value=abs(gyro_value); kodu ne ifade ediyor abs ne anlama geliyor. ve ben burda bu komut satırı ile ne yapıyorum. Özür dilerim biraz uzun oldu ama cevapları çok uzun değil zannedersem.

    #include “MPU6050.h”
    .
    .
    .void loop()
    {
    mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
    gyro_value = map(ax, 0, 17000, 0,255);
    motor_value=abs(gyro_value);

  8. gökhan

    Sezgin bey ultrasonik ses sensörü ile labirentten çıkacak robot yapmaya çalışıyorum. Ancak 90 derece dönüş problemim var. Bu sensörle veya piyasada kolay bulunan önereceğiniz hangi sensörle 90 derece dönüş yapmam mümkün.

  9. kamuran yiğittekin

    error in opening zip file
    bu şekilde hata veriyor

    1. Sezgin GÜL

      zipten çıkarıp kütüphane klasörüne atmalısın

  10. kamuran yiğittekin

    ayrıca kütüphane dosyalarını zip olarak indirdim ve arduino ya yüklerken hata veriyor yüklemiyor
    yazılan programı ekranda hiç bir şey çıkmıyor yardımcı olun lütfen varsa bu konu ile ilgili bir video yayınlayın teşekkürler.

  11. emre

    devreyi kaç volt ile çalıştırmalıyım

  12. kamuran yiğittekin

    merhaba dosyaları arduino kütüphanesine ekledim ve bağlantıyı gösterildiği gibi yaptım ama 5110 ekranı hiç açılmıyor bende yardımcı olur musunuz teşekkürler.

  13. oktay

    kolay gelsinn..sensör bacakları takıldığı pim A5 İLE A4, ben acaba programda hangi satırdan bacakların yerini değiştirebilirim yardımcı olursanız sevinirim 🙂

    1. Sezgin GÜL

      Pusula sensörü ı2c haberleşme protokolü üzerinden çalışır. Her arduino modelinde de ı2c iletişim pinleri önceden belirlenmiş standart pin numaralarıdır. Yani kodda bu pinlere tanım yapılmaz zaten bellidir.

  14. vahit ünsal

    ben arduino uno r3 ile yapmayı denedim pil kullanmadan bilgisayardan gücünü aldım ama ekranda hiç bişey gözükmüyor ve arduinonun üzerindeki L harfinin bulunduğu ışık yanıp söndüğünde ekranın ışığıda yanıp sönüyor lütfen bir yardım

    1. Sezgin GÜL

      ekran bağlantılarında sorun vardır. bir de sensörün verilerin serial ekrana yazdırmayı deneyin sensörde de sorun olup olmadığına bakın.

  15. EMİR

    iyi akşamlar sezgin bey.. ben prjenızi yapıcam da ama okla kıbleyı gosteren saat şeklindeki modu iptal etmek istiyorum.sadece yatay çizelge ile gosteren diğer modda yapmak ıstıyorum bunu nasıl yapabılır yazılımda nereleri silmem gerekıyor yada sız bana düzenleyıp atarmısınız rica etsem lutfen yardımcı olurmusunuz şimdiden teşekkur ederım iyi çalışmalar.. 🙂

    1. Sezgin GÜL

      DrawRow fonksiyonundaki algoritmaları değiştirmen lazım. Yani lcd nin piksel noktalarının koordinatlarına göre şekil noktalarını girip bunlara black yazarak siyah piksel olmasını sağlarsın.O şekilde istediğin şekli ekleyebilirsin.

  16. pusat berk

    Teşekkürler esen kalın takipteyim.

  17. pusat berk

    Bu pic le yapacağım bu uygulamaya jiroskob sensörü ekleyebilirmiyim?Nasıl bir yol izlemeliyim?
    Hem manyetik hemde jiroskob sensörlü kit varmı?

    1. Sezgin GÜL

      İlla PIC ile yapacaksanız arduino gibi pic geliştirme kartları var öyle yapabilirsiniz Daha kolay programlanabilir. Gyro sensör var manyetikli olanı da var. 10 Gyro pusula ivmeölçer ve yukseklık sensör unitesi var işine yarayabilir. Aynı şekil I2C pinlerine bağlayarak haberleştirme yapabilirsin.

  18. pusat berk

    Kolay gelsin gerçekten güzel bir uygulama.Benim için biraz ayrıntısından bahsedermisiniz.Bu projeyi uno yerine pic kullanarak ta yapabilirmiyiz.Sensör nasıl haberleşiyor? vb soruların yanıtını bekliyorum,takipteyim.Aslında bu projeden faydalanarak 3 boyutta yönünü ve derinliğini görebildiğim robot geliştirmek istiyorum.
    Ayrıca bu ülkenin yeni zihinlerine teknolojik girişim ve gelişimi aşılıyorsunuz.Bu anlamda inanılmaz işler başarıyorsunuz,teşekkürler.

    1. Sezgin GÜL

      Merhaba Pusat, öncelikle olumlu düşünceleriniz için teşekkürler. PIC ile de yapabilirsiniz. Fakat yazılımı tamamen değiştirmeniz gerekir. Modül I2C haberleşme protokolü ile veri işliyor. Yani kullanacağınız işlemcinin I2C pinlerine takmanız gerekecek. Bu pinler scl ve sda pinleridir. Her işlemcinin kendine ait pin numaraları farklıdır. İyi çalışmalar.