Elektronik pusula projesi, GY-271 manyetometre modülüyle Dünya'nın manyetik alanını ölçer ve atan2(Y, X) formülüyle yönü 0-360 derece olarak hesaplar. Arduino Uno sonucu OLED ekranda derece, yön harfi ve kuzeyi gösteren bir ibreyle gösterir. GY-271 kartlarında HMC5883L ya da QMC5883L çipi bulunabilir; buradaki kod ikisini de I2C adresinden tanır.
Telefonunuzdaki pusula uygulaması kuzeyi nasıl bulur? Telefonun içinde küçük bir manyetik alan sensörü vardır. Bu projede aynı tür bir sensörü Arduino Uno'ya bağlayıp yönü derece olarak ölçen, OLED ekranda dönen bir ibre gösteren elektronik bir pusula yapıyoruz. Proje fizik dersindeki manyetizma konusunu kodlamayla birleştirir; ortaokul, lise ve TÜBİTAK 4006 projeleri için uygundur.
Elektronik pusula nedir?
Elektronik pusula, Dünya'nın manyetik alanını bir manyetometre sensörüyle ölçüp cihazın baktığı yönü manyetik kuzeye göre derece cinsinden hesaplayan bir yön bulma aracıdır. Klasik pusuladaki mıknatıslı iğnenin yerini, manyetik alanın üç eksendeki büyüklüğünü sayıya çeviren bir çip alır.
Sensör yere paralel tutulduğunda manyetik alanın yatay bileşeni X ve Y eksenlerine paylaşılır. Arduino bu iki değerden atan2(Y, X) açısını hesaplar; sonuç 0° kuzey, 90° doğu, 180° güney ve 270° batı demektir.
Hangi malzemeler gerekir?
Elektronik pusula için Arduino Uno, GY-271 pusula modülü, 0,96 inç I2C OLED ekran ve jumper kablolar yeterlidir. Sensör ve ekran aynı iki I2C hattını paylaşır.
Malzeme listesi
| Malzeme | Adet | Ne işe yarar? |
|---|---|---|
| Arduino Uno R3 (CH340, USB kablolu) | 1 | Açıyı hesaplar, ekranı sürer |
| GY-271 QMC5883L 3 eksen pusula sensörü | 1 | Manyetik alanı ölçer (bu ya da alttaki) |
| GY-271 HMC5883L 3 eksenli manyetometre | 1 | Aynı görev, farklı çip |
| 0,96 inç 128x64 I2C OLED ekran (SSD1306) | 1 | Derece, yön ve ibre |
| Şeffaf breadboard, orta boy | 1 | I2C hattını ortaklamak için |
| 140 parça kutulu jumper kablo seti | 1 | Bağlantılar |
İki pusula modülünden birini almanız yeterlidir. Arduino IDE'de "Adafruit SSD1306" ve "Adafruit GFX" kütüphanelerini kurun; sensör için kütüphane gerekmez, kod çiple doğrudan konuşur.
QMC5883L ile HMC5883L arasındaki fark nedir?
QMC5883L ve HMC5883L aynı işi yapan ama farklı üreticilerin, farklı I2C adresi ve yazmaç düzeni kullanan iki ayrı çipidir; birinin kodu diğerinde çalışmaz. İkisi de "GY-271" adlı aynı görünüşlü kartlara takılır, bu yüzden sık karıştırılır.
| Özellik | HMC5883L | QMC5883L |
|---|---|---|
| Üretici | Honeywell | QST |
| I2C adresi | 0x1E | 0x0D |
| Verinin başladığı yazmaç | 0x03 | 0x00 |
| Eksen sırası | X, Z, Y | X, Y, Z |
| Bayt sırası | Önce yüksek bayt | Önce düşük bayt |
| Çipin üstündeki yazı (genellikle) | L883 | DA5883 |
Honeywell HMC5883L'nin üretimini durdurduğu için piyasadaki pek çok GY-271 kartında artık QMC5883L bulunur. Kartınızdaki çipi bilmiyorsanız sorun değil: aşağıdaki kod açılışta iki adresi de dener ve bulduğu çipe göre çalışır. Ekranın ilk satırında hangi çipin bulunduğu yazar.
Devre nasıl bağlanır?
GY-271 ve OLED ekranın VCC uçları 5V'a, GND uçları GND'ye, SDA uçları A4'e ve SCL uçları A5'e bağlanır; iki modül aynı hattı paylaşır. Bu ortak hattı I2C nedir yazısında anlattık.
- Breadboard'un bir sırasını 5V, bir sırasını GND, iki sırasını da SDA ve SCL için ayırın.
- Arduino 5V → 5V sırası, GND → GND sırası, A4 → SDA sırası, A5 → SCL sırası.
- GY-271: VCC, GND, SDA ve SCL uçlarını ilgili sıralara takın. DRDY ucu boş kalır.
- OLED: VCC, GND, SDA ve SCL uçlarını aynı sıralara takın.
- Sensörü Arduino'dan, USB kablosundan ve buzzer, hoparlör gibi mıknatıslı parçalardan en az 10 cm uzağa yerleştirin.
- Sensörü yere paralel ve sabit tutun; kart üzerindeki X oku cihazın "önü" olur.
Pusula kodu nasıl çalışır?
Kod önce çipi bulur ve ölçüme başlatır, 20 saniye boyunca kalibrasyon değerlerini toplar, sonra her 100 ms'de X ve Y değerlerinden yön açısını hesaplayıp ekrana çizer.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 oled(128, 64, &Wire, -1);
byte adres = 0; // 0x0D = QMC5883L, 0x1E = HMC5883L
const float SAPMA = 6.0; // manyetik sapma, Türkiye'de yaklaşık 5-7° doğu
int xMin = 32767, xMax = -32768, yMin = 32767, yMax = -32768;
const char* YON[8] = {"K", "KD", "D", "GD", "G", "GB", "B", "KB"};
bool var(byte a) {
Wire.beginTransmission(a);
return Wire.endTransmission() == 0;
}
void yaz(byte reg, byte deger) {
Wire.beginTransmission(adres);
Wire.write(reg);
Wire.write(deger);
Wire.endTransmission();
}
void oku(int &x, int &y) {
byte b[6];
Wire.beginTransmission(adres);
Wire.write(adres == 0x0D ? 0x00 : 0x03);
Wire.endTransmission();
Wire.requestFrom(adres, (byte)6);
for (byte i = 0; i < 6; i++) b[i] = Wire.read();
if (adres == 0x0D) { // QMC: X, Y, Z ve önce düşük bayt
x = (int16_t)(b[1] << 8 | b[0]);
y = (int16_t)(b[3] << 8 | b[2]);
} else { // HMC: X, Z, Y ve önce yüksek bayt
x = (int16_t)(b[0] << 8 | b[1]);
y = (int16_t)(b[4] << 8 | b[5]);
}
}
void setup() {
Wire.begin();
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.setTextColor(SSD1306_WHITE);
oled.clearDisplay();
if (var(0x0D)) adres = 0x0D; else if (var(0x1E)) adres = 0x1E;
if (!adres) { oled.print("Sensor yok!"); oled.display(); while (true); }
if (adres == 0x0D) { yaz(0x0B, 0x01); yaz(0x09, 0x1D); } // sürekli ölçüm
else { yaz(0x00, 0x70); yaz(0x01, 0x20); yaz(0x02, 0x00); } // sürekli ölçüm
oled.print(adres == 0x0D ? "QMC5883L" : "HMC5883L");
oled.setCursor(0, 24);
oled.print("Kalibrasyon: 20 sn");
oled.setCursor(0, 36);
oled.print("yavasca 2 tur cevirin");
oled.display();
unsigned long bas = millis();
while (millis() - bas < 20000) { // en küçük/en büyük değerleri topla
int x, y;
oku(x, y);
xMin = min(xMin, x); xMax = max(xMax, x);
yMin = min(yMin, y); yMax = max(yMax, y);
delay(20);
}
}
void loop() {
int x, y;
oku(x, y);
float xd = x - (xMin + xMax) / 2.0; // kalibrasyon: merkezi sıfıra al
float yd = y - (yMin + yMax) / 2.0;
float derece = atan2(yd, xd) * 180.0 / PI + SAPMA;
if (derece < 0) derece += 360;
if (derece >= 360) derece -= 360;
byte bolge = (byte)((derece + 22.5) / 45) % 8;
oled.clearDisplay();
oled.setTextSize(2);
oled.setCursor(0, 8);
oled.print((int)derece);
oled.setCursor(0, 36);
oled.print(YON[bolge]);
oled.setTextSize(1);
oled.drawCircle(96, 32, 30, SSD1306_WHITE);
float r = -derece * PI / 180.0; // ekranda kuzeyin açısı
oled.drawLine(96, 32, 96 + 24 * sin(r), 32 - 24 * cos(r), SSD1306_WHITE);
oled.setCursor(93 + 18 * sin(r), 28 - 18 * cos(r));
oled.print("K");
oled.display();
delay(100);
}
Ekranın solunda yön açısı ve yön harfi (K, KD, D, GD, G, GB, B, KB), sağında ise her zaman manyetik kuzeyi gösteren bir ibre görünür. Cihazı döndürdüğünüzde ibre ters yöne döner; tıpkı gerçek pusuladaki iğne gibi.
Kalibrasyon ve manyetik sapma neden gerekir?
Kalibrasyon, karttaki ve çevredeki sabit mıknatıslanmanın ölçümleri bir yöne kaydırmasını düzeltmek için gerekir. Sensör düz tutulup tam tur döndürülürse X ve Y değerleri bir çember çizer; çemberin merkezi sıfırda olmalıdır. Kod en küçük ve en büyük değerlerin ortasını bulup bu kaymayı çıkarır.
Manyetik sapma ise manyetik kuzey ile coğrafi kuzey arasındaki açıdır. Türkiye'de bu açı bölgeye göre yaklaşık 5-7° doğudur ve yıllar içinde yavaşça değişir. Bulunduğunuz yerin güncel değerini NOAA'nın manyetik sapma hesaplayıcısından öğrenip koddaki SAPMA sabitine yazabilirsiniz.
Hangi güvenlik kurallarına dikkat edilmeli?
Elektronik pusula USB'den 5V ile çalışır ve tehlikeli gerilim içermez; yine de şu kurallara uyun:
- Devreyi bilgisayarın USB çıkışından, USB powerbank'tan ya da en çok 12V'luk bir adaptörden besleyin. 220V şebeke elektriğine hiçbir şey bağlamayın.
- Deney için kullanacağınız güçlü neodimyum mıknatısları birbirine yaklaştırmayın; aniden yapışıp parmak sıkıştırabilir. Telefon ve banka kartlarından uzak tutun.
- Projeyi öğretmen ya da yetişkin gözetiminde kurun.
- Bu bir eğitim maketidir; doğa yürüyüşünde yön bulmak için gerçek bir pusula taşıyın.
Ödevinizi nasıl sunarsınız?
Ödevinizi, elektronik pusulayı gerçek bir pusulanın yanına koyup iki ölçümü karşılaştırarak sunabilirsiniz.
- Problem: "Telefonlar ve akıllı saatler yönü nasıl bulur?"
- Gösteri: Kalibrasyonu jüri önünde yapın; sonra ekrandaki dereceyi gerçek pusulayla karşılaştırın.
- Deney: Sensöre bir tornavida ya da mıknatıs yaklaştırıp yön okumasının nasıl bozulduğunu gösterin.
- Rapor: QMC/HMC karşılaştırma tablosunu, bağlantı şemasını ve kalibrasyon öncesi-sonrası ölçümlerinizi ekleyin.
- Geliştirme: Eğik tutulunca da doğru ölçmek için ivmeölçerle eğim düzeltmesi önerin. Bu konuyu ivme ve jiroskop sensörü yazısında anlattık.
Sık sorulan sorular
Ekranda "Sensor yok!" yazıyorsa ne yapmalıyım?
Bu mesaj, Arduino'nun 0x0D ve 0x1E adreslerinin hiçbirinde çip bulamadığını gösterir. Önce SDA'nın A4'e, SCL'nin A5'e gittiğini ve iki kablonun yer değiştirmediğini kontrol edin. VCC ve GND uçlarının sağlam takıldığına bakın. Hâlâ bulunmuyorsa bir I2C tarayıcı kodu çalıştırıp kartın hangi adreste göründüğünü öğrenin.
Doğu ile batı ters çıkıyorsa ne yapmalıyım?
Doğu ve batı ters çıkıyorsa koddaki atan2(yd, xd) ifadesini atan2(-yd, xd) olarak değiştirin. Bunun nedeni, çipin kart üzerine yerleştirilme yönünün ve eksen tanımının üreticiye göre değişebilmesidir. Değişiklikten sonra cihaz kuzeye bakarken 0°, doğuya bakarken 90° göstermelidir.
Ölçüm neden birkaç derece oynuyor?
Manyetometreler çevredeki her manyetik kaynaktan etkilenir: masa ayağındaki çelik, prizdeki kablolar, telefon ve hoparlör okumayı kaydırabilir. Sensörü bunlardan uzak tutun ve yere paralel tutun; birkaç derecelik eğim bile hata yaratır. Kalibrasyonu da projeyi kullanacağınız yerde yapın.
Pusula modülü 3,3V ile de çalışır mı?
Evet, GY-271 kartları 3-5V aralığında beslenebilir; kartın üzerinde bir gerilim regülatörü bulunur. Arduino Uno ile kullanırken 5V bağlamak en kolay yoldur. ESP32 gibi 3,3V kartlarda VCC'yi 3,3V pinine bağlamanız yeterlidir; I2C bağlantısı aynı mantıkla kurulur.
Özet
- Elektronik pusula, manyetik alanın X ve Y bileşenlerinden
atan2ile yön açısını bulur. - GY-271 kartlarında HMC5883L (0x1E) ya da QMC5883L (0x0D) bulunabilir; kod ikisini de tanır.
- Sensör ve OLED aynı I2C hattına bağlanır: SDA → A4, SCL → A5, VCC → 5V.
- Kalibrasyon sabit mıknatıslanmayı düzeltir; Türkiye'de manyetik sapma yaklaşık 5-7° doğudur.
- Sensörü metal ve mıknatıslardan uzak, yere paralel tutun; devreyi 220V'a bağlamayın.
