HMC5883L 3 Eksenli Pusula Modülü ve Arduino
Neden Manyetometreye İhtiyacımız Var?
Robotlar ve insansız hava araçları gibi insansız makineler, insanların aksine hangi yöne gideceklerini algılayamazlar. Bu nedenle, yönleri belirlemek için bir sensöre ihtiyaçları vardır. Bu nedenle manyetometrelere ihtiyacımız var. Manyetik alanı algılarlar ve bu manyetik alana dayanırlar; bu manyetometrenin entegre edildiği bir cihazın yönünü söyler. Bu nedenle, nesnelerin yönünü belirlemek için HMC5883L'yi kullanabiliriz.
HMC5883L IC Pinout Şeması
HMC5883L manyetometre modülü, diğer bileşenlerle birlikte XC6206P332MR IC'den oluşur. Şimdi önce bu IC'nin pin konfigürasyonunu tartışalım ve bundan sonra modülün pinout'unu göreceğiz.
IC Pin Yapılandırması
Bu bölüm, HMC5883L IC'nin tüm pimlerinin ayrıntılarını sağlar. Pin 3, 5, 6, 7 ve 14 NC pinleridir. Herhangi bir işlevi yoktur ve bu yüzden bağlantısız bırakılır.
I2C İletişim Pinleri
Pin1 ve pin16, I2C arayüzü için iletişim pinleridir.
- SCL - Pin1
- SDA - Toplu iğne16
SCL, bir ana cihazdan saat sinyalini alan bir ana / bağımlı saat girişidir. Manyetometre IC, mikrodenetleyici ile arayüz oluşturduğumuzda köle gibi davranır. Bu nedenle, mikro denetleyici IC'ye saat sinyali sağlar. SDA, bir seri veri pinidir.
Güç Kaynağı Pinleri
Pin2 bir güç kaynağı pinidir. Sensörün çalışması için 2,16V ila 3,6V aralığında voltaj gerektirir. İç işlemler için güç sağlar. Pin9 ve Pin11 topraklama pinleridir.
- Pin_4, S1 pinidir. Bu pimi VDDIO'ya bağlayın.
- Pin_8 bir set / reset kayışı pozitif giriş pinidir. Sensörde depolanan geçmiş manyetizmayı ortadan kaldırır.
- Pin_10, bir rezervuar kondansatörü için bir pimdir. Bu pime 4.7 µF'lik bir rezervuar kondansatörü bağlayın.
- Pin_12 SETC, ayarlama / sıfırlama kayışının sürücü tarafındaki bir bağlantıdır.
- Pin_13 VDDIO, IO arayüzüne güç sağlar. VDD'ye 1,71V olmalıdır.
- Pin_15, verilerin ne zaman hazır olduğunu gösteren bir veri Hazır kesme pinidir.
HMC5883L Modül Pin Çıkışı
Gördüğünüz gibi XC6206P332MR IC'nin çok sayıda pimi var ve çalışmasını sağlamak için harici bileşenler kullanmamız gerekiyor. Ancak neyse ki, modül gerekli tüm bileşenlerle birlikte piyasada mevcuttur. Bu şekil manyetometre modülünün pimini göstermektedir.
Özellikleri
- 3V ile 6V arasında değişen DC Voltajı ile çalışır.
- Destekler iletişim protokolü.
- Sensör, 3 Eksenli Manyetoresistif Sensörlere, ASIC, 12-bit ADC'ye ve kayış sürücü devrelerine sahiptir.
- HMC2883L, 1-2 derece hassasiyetle -8 ila +8 gauss aralığında manyetik alan gücünü ölçer.
- Maksimum veri çıkış hızı 160Hz'dir.
Nerede kullanmalı?
HMC5883L, ucuz ve kolayca bulunabilen küçük bir sensördür. Dijital dijital arayüz, diğer mikrodenetleyicilerle birlikte kullanılmasına izin verir. Hatta normal IC'lere bile bağlayabilirsiniz. Bunlar, sektördeki diğer manyetometrelere kıyasla en güvenilir ve hassas sensörlerdir.
Bu sensörü uygulamalarda manyetik alanın gücünü ve büyüklüğünü ölçmek için kullanabilirsiniz. Ayrıca bir malzemenin manyetizasyonunu da ölçebilir. Hassas ölçümler vererek yukarıdaki fonksiyonları yerine getirebilen bir manyetometre arıyorsanız, o zaman bu sensör bu amaca en iyi şekilde hizmet edecektir.
HMC5883L nasıl kullanılır?
Aşağıdaki şekiller, çalışmasını anlamak için HMC5883L sensör modülünün iki referans tasarımını göstermektedir. Tek beslemeli tasarımda, hem VDD hem de VDDIO pinlerine aynı voltaj beslemesini uygulayın. İkili besleme modundayken, her iki pime de ayrı güç kaynakları uyguladık. VDD, IC'nin dahili işlemlerine güç sağlarken, VDDIO, iletişim sağlamak için arayüz. Her iki devredeki diğer tüm bağlantılar aynıdır. Standart ve hızlı mod olmak üzere iki çalışma moduna sahiptir. Bu nedenle, bu modları desteklemek için yukarı çekme dirençleri bağlarız.
Tek Tedarik Tasarımı
Çift Beslemeli tasarım
HMC5883L'nin Arduino Uno ile arayüzlenmesi
HMC5883L, diğer mikrodenetleyicilerle kullanım için uyumlu hale getirmek için ekstra devreden oluşan bir koparma kartına sahiptir. Bu ara kartını ekstra bileşenlere ihtiyaç duymadan doğrudan Arduino Uno ile bağlayabilirsiniz. Bağlantılar basit. Vcc'yi + 5V'ye bağlayın ve Arduino'nun toprak pinine topraklayın. SCL ve SDA iletişim pinlerini analog pin 5 ve 4 veya Arduino'ya bağlayın.
HMC5883 Arduino Kütüphanesi
Bu HMC5883 modülünün programlanması James Sleeman'ın HMC5883L kitaplığı ile çok kolaydır. Öncelikle bu bağlantıya gidin ve kütüphaneyi indirin.
Bundan sonra Arduino kütüphane yöneticisine gidin ve HMC5883 kütüphanesini ekleyin. Veya indirilen klasörü çıkarabilir ve bu dosyayı Arduino kütüphaneleri klasörüne yapıştırabilirsiniz.
Arduino ile Bağlantı Şeması
Bu şematik diyagrama göre manyetometre modülü ve Arduino Uno ile bağlantı kurunuz.
- GY-273 Pusula Modülü -> Arduino
- VCC -> VCC (Aşağıdaki Nota Bakın)
- GND -> GND
- SCL -> A5 / SCL, (Arduino Mega'da Pin 21'i kullanın)
- SDA -> A4 / SDA, (Arduino Mega'da Pin 20'yi kullanın)
- DRDY -> Bağlı Değil (bu örnekte)
Arduino Kodu
Bu kod, HMC5883L modül Arduino Kitaplığının işlevlerini gösterir.
#include <Arduino.h>
// PLEASE NOTE!
// The Arduino IDE is a bit braindead, even though we include Wire.h here, it does nothing
// you must include Wire.h in your main sketch, the Arduino IDE will not include Wire
// in the build process otherwise.
#include <Wire.h>
#include "HMC5883L_Simple.h"
HMC5883L_Simple::HMC5883L_Simple()
{
declination_offset_radians = 0;
mode = COMPASS_SINGLE | COMPASS_SCALE_130 | COMPASS_HORIZONTAL_X_NORTH;
i2c_address = COMPASS_I2C_ADDRESS; // NB: The HMC5883L does not appear to be able to have any different address.
// so this is a bit moot.
}
/** Set declination in degrees, minutes and direction (E/W)
* See http://www.magnetic-declination.com/
*/
void HMC5883L_Simple::SetDeclination( int declination_degs , int declination_mins, char declination_dir )
{
// Convert declination to decimal degrees
switch(declination_dir)
{
// North and East are positive
case 'E':
declination_offset_radians = ( declination_degs + (1/60 * declination_mins)) * (M_PI / 180);
break;
// South and West are negative
case 'W':
declination_offset_radians = 0 - (( declination_degs + (1/60 * declination_mins) ) * (M_PI / 180));
break;
}
}
/** Set the sampling mode to one of COMPASS_CONTINUOUS or COMPASS_SINGLE
*/
void HMC5883L_Simple::SetSamplingMode( uint16_t sampling_mode )
{
// Mode is the bits marked M in mode
// xxxxxxxxxxxSSSMM
mode = (mode & ~0x03) | (sampling_mode & 0x03);
Write(COMPASS_MODE_REGISTER, mode & 0x03);
}
/** Set the scale to one of COMPASS_SCALE_088 through COMPASS_SCALE_810
* Higher scales are less sensitive and less noisy
* Lower scales are more sensitive and more noisy
*/
void HMC5883L_Simple::SetScale( uint16_t scale )
{
// Scale is the bits marked S in mode
// xxxxxxxxxxxSSSMM
mode = (mode & ~0x1C) | (scale & 0x1C);
Write(COMPASS_CONFIG_REGISTER_B, (( mode >> 2 ) & 0x07) << 5);
}
/** Set the orientation to one of COMPASS_HORIZONTAL_X_NORTH
* through COMPASS_VERTICAL_Y_WEST
*
*/
void HMC5883L_Simple::SetOrientation( uint16_t orientation )
{
// Orientation is the bits marked XXXYYYZZZ in mode
// xxXXXYYYZZZxxxxx
mode = (mode & ~0x3FE0) | (orientation & 0x3FE0);
}
/** Get the heading of the compass in degrees. */
float HMC5883L_Simple::GetHeadingDegrees()
{
// Obtain a sample of the magnetic axes
MagnetometerSample sample = ReadAxes();
float heading;
// Determine which of the Axes to use for North and West (when compass is "pointing" north)
float mag_north, mag_west;
// Z = bits 0-2
switch((mode >> 5) & 0x07 )
{
case COMPASS_NORTH: mag_north = sample.Z; break;
case COMPASS_SOUTH: mag_north = 0-sample.Z; break;
case COMPASS_WEST: mag_west = sample.Z; break;
case COMPASS_EAST: mag_west = 0-sample.Z; break;
// Don't care
case COMPASS_UP:
case COMPASS_DOWN:
break;
}
// Y = bits 3 - 5
switch(((mode >> 5) >> 3) & 0x07 )
{
case COMPASS_NORTH: mag_north = sample.Y; break;
case COMPASS_SOUTH: mag_north = 0-sample.Y; ; break;
case COMPASS_WEST: mag_west = sample.Y; break;
case COMPASS_EAST: mag_west = 0-sample.Y; break;
// Don't care
case COMPASS_UP:
case COMPASS_DOWN:
break;
}
// X = bits 6 - 8
switch(((mode >> 5) >> 6) & 0x07 )
{
case COMPASS_NORTH: mag_north = sample.X; break;
case COMPASS_SOUTH: mag_north = 0-sample.X; break;
case COMPASS_WEST: mag_west = sample.X; break;
case COMPASS_EAST: mag_west = 0-sample.X; break;
// Don't care
case COMPASS_UP:
case COMPASS_DOWN:
break;
}
// calculate heading from the north and west magnetic axes
heading = atan2(mag_west, mag_north);
// Adjust the heading by the declination
heading += declination_offset_radians;
// Correct for when signs are reversed.
if(heading < 0)
heading += 2*M_PI;
// Check for wrap due to addition of declination.
if(heading > 2*M_PI)
heading -= 2*M_PI;
// Convert radians to degrees for readability.
return heading * 180/M_PI;
}
/** Read the axes from the magnetometer.
* In SINGLE mode we take a sample. In CONTINUOUS mode we
* just grab the most recent result in the registers.
*/
HMC5883L_Simple::MagnetometerSample HMC5883L_Simple::ReadAxes()
{
if(mode & COMPASS_SINGLE)
{
Write(COMPASS_MODE_REGISTER, (uint8_t)( mode & 0x03 ));
delay(66); // We could listen to the data ready pin instead of waiting.
}
uint8_t buffer[6];
Read(COMPASS_DATA_REGISTER, buffer, 6);
MagnetometerSample sample;
// NOTE:
// The registers are in the order X Z Y (page 11 of datasheet)
// the datasheet when it describes the registers details then in order X Y Z (page 15)
// stupid datasheet writers
sample.X = (buffer[0] << 8) | buffer[1];
sample.Z = (buffer[2] << 8) | buffer[3];
sample.Y = (buffer[4] << 8) | buffer[5];
return sample;
}
/** Write data to the compass by I2C */
void HMC5883L_Simple::Write(uint8_t register_address, uint8_t data)
{
Wire.beginTransmission(i2c_address);
Wire.write(register_address);
Wire.write(data);
Wire.endTransmission();
}
/** Read data from the compass by I2C
*/
uint8_t HMC5883L_Simple::Read(uint8_t register_address, uint8_t buffer[], uint8_t length)
{
// Write the register address that we will begin the read from, this
// has the effect of "seeking" to that register
Wire.beginTransmission(i2c_address);
Wire.write(register_address);
Wire.endTransmission();
// Read the data starting at that register we seeked
Wire.requestFrom(i2c_address, length);
if(Wire.available() == length)
{
for(uint8_t i = 0; i < length; i++)
{
buffer[i] = Wire.read();
}
return length;
}
return 0;
}
Örnek Kod
Bu örnek taslak, Arduino Seri monitöründe bir HMC5883L üç eksenli manyetometreden bir başlık okumasını gösterir.
#include <Arduino.h> #include <Wire.h> #include <HMC5883L_Simple.h> // Create a compass HMC5883L_Simple Compass; void setup() { Serial.begin(9600); Wire.begin(); // Magnetic Declination is the correction applied according to your present location // in order to get True North from Magnetic North, it varies from place to place. // // The declination for your area can be obtained from http://www.magnetic-declination.com/ // Take the "Magnetic Declination" line that it gives you in the information, // // Examples: // Christchurch, 23° 35' EAST // Wellington , 22° 14' EAST // Dunedin , 25° 8' EAST // Auckland , 19° 30' EAST // Compass.SetDeclination(23, 35, 'E'); // The device can operate in SINGLE (default) or CONTINUOUS mode // SINGLE simply means that it takes a reading when you request one // CONTINUOUS means that it is always taking readings // for most purposes, SINGLE is what you want. Compass.SetSamplingMode(COMPASS_SINGLE); // The scale can be adjusted to one of several levels, you can probably leave it at the default. // Essentially this controls how sensitive the device is. // Options are 088, 130 (default), 190, 250, 400, 470, 560, 810 // Specify the option as COMPASS_SCALE_xxx // Lower values are more sensitive, higher values are less sensitive. // The default is probably just fine, it works for me. If it seems very noisy // (jumping around), incrase the scale to a higher one. Compass.SetScale(COMPASS_SCALE_130); // The compass has 3 axes, but two of them must be close to parallel to the earth's surface to read it, // (we do not compensate for tilt, that's a complicated thing) - just like a real compass has a floating // needle you can imagine the digital compass does too. // // To allow you to mount the compass in different ways you can specify the orientation: // COMPASS_HORIZONTAL_X_NORTH (default), the compass is oriented horizontally, top-side up. when pointing North the X silkscreen arrow will point North // COMPASS_HORIZONTAL_Y_NORTH, top-side up, Y is the needle,when pointing North the Y silkscreen arrow will point North // COMPASS_VERTICAL_X_EAST, vertically mounted (tall) looking at the top side, when facing North the X silkscreen arrow will point East // COMPASS_VERTICAL_Y_WEST, vertically mounted (wide) looking at the top side, when facing North the Y silkscreen arrow will point West Compass.SetOrientation(COMPASS_HORIZONTAL_X_NORTH); } // Our main program loop. void loop() { float heading = Compass.GetHeadingDegrees(); Serial.print("Heading: \t"); Serial.println( heading ); delay(1000); }
Yapılan Uygulamalar
- GPS tabanlı kablosuz telefonlar
- bilgisayar oyunları
- kablosuz işaretçiler
- spor saatleri
- taşınabilir GPS alıcıları
Bahadır ÖZGEN Electronic Robotic Coding Research and Development 1975 - ∞ Learn Forever If you want, let's learn together... https://roboticcode2020.blogspot.com/ bahadirozgen1975@gmail.com facebook robotic.code instagram @roboticcode
Sayfalarımı ziyaret ettiğiniz için teşekkür ederim.Bu sitede mevcut olan içerikler kendi oluşturduğum projeler yazı,resim ve videolardan oluşmaktadır.İçerik oluşturmak çok uzun sürdüğü için bazı projelerde yurtdışı kaynaklardan faydalandım.Buradaki amacım ticari değildir.Kaynağı belli olan ve bizim kaynağına ulaşabildiğimiz materyal (yazı, fotoğraf, resim, video v.b.) için ilgili konularda fotoğraflarda logo varsa v.b. not olarak gösterilecektir.Sitemizde yayınlanan tüm içerik, bizim tarafımızdan ve internet üzerinden youtube, facebook ve blog gibi paylaşıma sunulmuş kaynak sitelerden alındığı için, sitemiz yasal yükümlülüğe tabi tutulamaz. Sitemizde telif haklarının size ait olduğu bir içerik varsa ve bunu kaldırmamızı isterseniz, iletişim sayfamızdan bizimle iletişime geçtiğiniz takdirde içerik yayından kaldırılacaktır.Bu konu ve modüller ile uğraşarak, ileride çok güzel makine ve elektronik aletler yapabilirsiniz.