ana sayfa > ARM, STM32, Yazılım > STM32 ile LIS302DL ivme ölçer kullanımı

STM32 ile LIS302DL ivme ölçer kullanımı

Cumartesi, 16 Mar 2013 yorum ekle yorumlara git
STM32 ile LIS302DL ivme ölçer kullanımı

Arkadaşlar Merhaba

C ve ARM ile tanıştıktan sonra artık Pic leri gözüm görmez oldu :) Bende hazır ARM ye  ısınmışken bir proje daha yapayım dedim.

Bu Yazımda LIS302DL 3 eksen ivme ölçer kullanımına biraz göz attım. Kısaca kullanımından bahsedeceğim.

Bu uygulamamda LIS302DL ‘den eksen bilgilerini okuyup TFT ekranda Bargraph olarak olarak gösterip ardından Bilgisayar Arayüzünde Ve X, Y, Z eksenlerinin değişimini grafik olarak gösterip ayrıca açılarını hesapladım.

LIS302DL Sensörü ST firmasının ürettiği, 3 eksen bir ivme ölçerdir. 2.3g ve9.2g olmak üzere iki adet çalışma modu vardır. Ayrıca SPI ve I2C ile haberleşebilmektedir. Benim elimdeki MCBSTM32C board üzerindeki ivme sensörü STM32F107 ye I2C hattı üzerinden bağlanmış. Dolayısıyla bende STM32F107 nin I2C donanımını kullanarak sensörle haberleştim.

Sensörün Datasheetine Buradan ulaşabilirsiniz.

LIS302DL nin kullanımı gerçekten çok basit. Kendi içerisinde çok fazla register yok. Biz sadece CONTROL_REG1 registeri üzerinde ayarlamalar yaparak sensörü kullanıma hazır hale getiriyoruz.

CONTROL_REG1 Registerinin içeriği aşağıdaki tabloda gösterilmiş.
LIS302DL
Burada ;

DR biti, veri hızı seçim bitidir. “1” Olursa 400Hz, “0” olursa 100Hz Modunda çalışır. Biz 100Hz modunda kullanıyoruz.

PD biti, Power Down Control diye adlandırılmış. Anladığım kadarıyla Gerektiğinde sensörün ölçüm işlemi durdurulmak istendiğinde Bu bit “0” yapılarak Sensör Power Down Moduna sokuluyor. Normade biz bu biti “1” Yapmamız gerekiyor.

FS biti “Full Scale Select” bitidir. Bu bit “0” Olursa sensör 2.3g modunda, “1” olursa 9.2g modunda çalışıyor. Ben çıkıştaki değişimleri daha rahat görebilmem için sensörü 2.3g modunda çalıştırıyorum. 

STP, STM Bitleri Self Test Enable olarak geçiyor. Normal çalışmada bu iki bit “0” olması gerekiyor

Xen, Yen, Zen Bitleri X, Y, Z eksenlerinin Enable Bitleridir “1” olursa Aktif, “0”olursa Pasif olur.

Sensörü kullanıma hazır hale getirmek için min. yapılması gereken ayarlar bunlardır.

Şimdi işin yazılım kısmına bakalım

Sensör yukarıda Bahsettiğim gibi MCBSTM32C Deney board’ın da  STM32F107 nin I2C1 (PB8, PB9) Donanımına Bağlandığı için  bende I2C donanımını kullanmak zorunda kaldım. Bu vesileyle Favori işlemcim olan STM32F10X serisinde I2C haberleşmesi üzerinede tecrübe sahibi olmuş oldum.

STM32F10X serisinde I2C donanımını çalıştırmak açıkçası çok uğraştırdı. İlk başta ST kütüphanesiyle yapayım dedim. Nerden baksanız 3-4 gün ST kütüphanesi kullanılarak yazılmış Farklı I2C rutinlerini çalıştırmak için uğraştım. ST kütüphanesini çalıştıramayınca bende kütüphane kullanılmadan yazılmış olan(Bu Arada bunun adı Low Level miş. :) ) I2C Rutinlerini buldum. Bu kodlar sayesinde işlemcinin I2C donanımını çalıştırıp sensör ile haberleşebildim.

Şuan kullandığım I2C koları aşağıdaki gibi.

I2C.h

Kütüphanenin kullanımı çok basit zaten.

Şimdi Main programına bakalım

main.c

Burada işlemciyi 8Mhz Dahili osilatörü ile çalıştırıyorum. Bu OSC değeri girişte 2’ye bölünüp ardında PLLMUL çarpanıyla 16 ya katlanıyor. Dolayısıyla işlemci 64Mhz de çalışıyor.

Deney bordu ile birlikte gelen TFT nin üzerinde SPDF5408 sürücü çipi bulunuyor. SPDF5408 sürücü kütüphanesini keilin örnek kodlarından aldım. Bu uygulamada görsellik açısından çok iyi oldu :)

Ayrıca TFT kütüphanesinde BarGraph rutuni çok iyi hazırlanmış. Bargraph için açılan pencerenin boyutu ne olursa olsun. Bargraph 0-1023 arası değer alıyor. Dolayısıyla Bar boyutu değiştiğinde Bar’ın max değeriyle uğraşmak gerekmiyor.

Sensör çıkışı +-0-127 arasında bir çıkış değeri verir. Normalde sensörden 60dan yukarı değerler almak için bayağı bir kuvvet uygulamak gerekiyor. Bu yüzden bende Sensörden 60 değeri gelince Bar değeri 1024 olacak şekilde ayarladım. Bunun için Aşağıdaki işlemi yapmak gerekiyor.

xbar_value=(xaxis*256)/15;

Normalde dünya üzerinde yer çekim ivmesi bulunan coğrafi bölgeye göre g =9,8065 m/s² (Tübitak) civarındadır. Bu sebebden ötürü sensör düz bir zeminde olmasına rağmen sürekli olarak 55-60 Arasında bir değer alınıyor. Aşağıdaki resimde yaptığım uygulamanın görüntüsünü görebilirsiniz. Buradan daha net anlaşılıyor.
LIS302DL
Aldığım eksen bilgilerini bilgisayara göndermek için STM32 nin Usart2 modülünü kullandım. Elimdeki boardda ki Com bağlantı noktası PortD ye bağlandığı için Usart2 nin Remap Modunu aktif etmek gerekiyor. Aksi hale PortA da ki Rx ve TX pinleri aktif olur.

Ayrıca Timer1 kesmesi ile Usart Rx bufferine sürekli bakarak Bilgisayar programından gelen Dataları alıyorum. Aslında Timer1 Kesmesi bu iş için kulanılmaz Usart Recieve kesmesi daha uygun olurdu. Timer donanımım hazır olduğu için açıkçası kolaya kaçtım biraz 😀

Kullandığım Usart kütüphanesi aşağıdaki gibidir. Usart konfigürasyonu, Seri Data alım ve gönderim rutinleri bu kütüphane içerisinde gerçekleştiriliyor.

Bilgisayar ile haberleşme çift yönlü olarak gerçekleşiyor. C# programı ile bağlantı gerçekleştiği zaman hemen veriler bilgisayar tarafına aktarılmaya başlanıyor. Ayrıca ekran güncelleme hızını da ayarlanabilir yaptım. Bilgisayar ile bağlantı kurulduğu zaman hemen 10 ile 200ms arasında ekran güncellemesi ayarlanabiliyor.

Son olarak biraz C# programından bahsedeceğim.

C#da seri port kullanımı çok basit.

ilk önce toolbox içerisinden serial port nesnesini formumuza sürüklüyoruz.

Ardından seri portun ayarları yapılması gerekiyor. Bizi ilgilendiren 2 ayar var. Bunların kullanımı aşağıdaki gibidir.

serialPort1.PortName =”COM1″
serialPort1.BaudRate = 9600;

Bu ayarları yaptıktan sonra Portu Kullanıma açıyoruz. Bu iş için serialPort1.Open(); komutunu kullanıyoruz.

Tabi Ben bu işlemleri programda biraz daha işlevsel yaptım. Mesela Programı ilk çalıştırdığınızda Program bilgisayara bağlı olan com portları tarayıp otomatikmen ComboBox içerisinde listeler.

Tasarlamış olduğum Formun görüntüsü aşağıdaki gibidir.
LIS302DL
Program üzerinde Sağ üst Tarafta İvme ölçerden okunan değerler Gösterilir. Hemen Altında ise Bu okunan değerlerin açısal karşılığı yazılır. Okunan X, Y ve Z eksenlerinin açıya dönüştürmek için Aşağıdaki formülü kullanıyorum.
LIS302DL
Fakat bu formül Bilgisayar tarafında koşuyor. Fakat bilgisayar üzerindeki Arctan ve Sqrt fonksiyonları radyan cinsinden çıkış verdiği için birde bu değerleri Dereceye çevirmek gerekiyor. Sonuç Yukarıdaki resmin koda dönüşmüş hali aşağıdaki gibidir.

Elde edilen değerler çok küsüratlı oluyor.(Tahminimce virgülden sonra en az 10 hane :) ) Bu yüzden alınan değerleri yuvarlamak gerekiyor. C# da Math.Round fonksiyonu bu işi yapıyor. İçeriğindeki birinci parametre Yuvarlanacak olan değer, ikinci parametre virgülden sonra kaç hanenin yuvarlanacığını belirtiyor. Sonuç olarak bize yuvarlanmış halini geri getiriyor.

Karttan gelen Eksen bilgilerini Grafiğe basmak için aşağıdaki kodları kullanıyorum.

Grafiğin sola kayması için Her eksene 100 boyutlu bir dizi belirledim
Karttan her veri geldiğinde ilk başta bu dizinin elemanlarını bir birim sola kaydırıp dizinin en son elemanına yeni gelen datayı ekliyorum. Sonra grafikteki eski noktaları silip yeni noktaları basıyorum. Bu işlem her yeni bir bilgi geldiğinde yaptığım için grafiğin kayma hızı veri akış hızıyla doğru orantılıdır.

Örneğin X ekseninden gelen verileri grafiğe basmak için aşağıdaki kodları kullandım.

Görüldüğü gibi mantığı çok basit.

Birkaç video çektim.

http://www.youtube.com/watch?v=OrmMO1VVk1Q&width=600&height=360

 

Buradaki videoda C# programında kartın hareketiyle birlikte grafikteki değişimi görebilirsiniz.

 

http://www.youtube.com/watch?v=S9n7DrwivMs&feature=youtu.be&width=600&height=360

Şimdilik yazacaklarım bu kadar. Umarım faydalı bir örnek olmuştur.

Proje Dosyalarını Buradan İndirebilirsiniz.

İyi çalışmalar..

Categories: ARM, STM32, Yazılım Tags:
  1. Çarşamba, 20 Mar 2013 zamanında 10:57 | #1

    Ellerine Sağlık. Neden SPI değilde I2C kullandın Hocam ?

    • Ferhat YOL
      Cuma, 22 Mar 2013 zamanında 00:54 | #2

      Merhaba

      Hocam Mecburiyet.
      Elimdeki Board üzerinde sensör bağlantısı I2C üzerinden yapılmış

  2. Ferudun GÖKCEGÖZ
    Perşembe, 24 Eki 2013 zamanında 23:52 | #3

    Merhabalar hocam. Elinize sağlık, uygulamanız çok hoş olmuş. Birşey sormak istiyorum. C# uygulamanızda, grafik kısmını zedgraph library leri ile mi yaptınız. Yoksa kendiniz mi yazdınız o kısmı ?

  3. Ferhat YOL
    Cuma, 25 Eki 2013 zamanında 10:32 | #4

    Ferudun GÖKCEGÖZ :

    Merhabalar hocam. Elinize sağlık, uygulamanız çok hoş olmuş. Birşey sormak istiyorum. C# uygulamanızda, grafik kısmını zedgraph library leri ile mi yaptınız. Yoksa kendiniz mi yazdınız o kısmı ?

    Hocam Tam hatırlamıyorum ama galiba devexpress ‘in grafiklerini kullanmıştım. Epeyce bir vakit geçti

  4. Kaan
    Pazar, 03 Ağu 2014 zamanında 11:57 | #5

    Merhaba Hocam
    Benim takıldığım bir nokta var hocam. LIS302DL sensöründen aldığım üç eksen bilgisini visual c# arayüzüne bastırdım fakat sürekli negatif eksen bilgileri gelmekte pozitif eksen bilgileri alamıyorum. Minimum -1 Maksimum -127 görüyorum bunlar üç eksen içinde gecerli.

  5. Ferhat YOL
    Pazar, 03 Ağu 2014 zamanında 18:33 | #6

    @Kaan
    Normalde gelen değerler Signed int8 türünde olması lazımdı. Yani +127 ile -127 arasında değer alıyor. Verileri sakladığınız değişkenin bu türde olmasına dikkat edin.

    Diğer bir yandan verileri bilgisayar ortamına aktarmadan önce okuduğunuz ham değerleri göremeye çalışın. Dediğim gibi +127 ile -127 arasında değişmesi gerekir.

  6. Gözde
    Salı, 13 Ara 2016 zamanında 01:38 | #7

    STM32F107 üzerinde dahili ivme ölçer bulunuyor mu acaba? Eğer bulunuyorsa ivmeölçerden aldığım bilgileri sadece ekranda göstermek için haberleşme (I2C) kullanmama gerek var mı?

  1. şimdilik geri bağlantı yok