T c bileciK Şeyh edebali ÜNİversitesi MÜhendiSLİk faküLtesi BİLGİsayar mühendiSLİĞİ BÖLÜMÜ MİkroiŞlemci uygulamalari sunum konusu



Yüklə 0,89 Mb.
tarix29.09.2018
ölçüsü0,89 Mb.
#71080



T.C BİLECİK ŞEYH EDEBALİ ÜNİVERSİTESİ MÜHENDİSLİK FAKÜLTESİ

BİLGİSAYAR MÜHENDİSLİĞİ BÖLÜMÜ

MİKROİŞLEMCİ UYGULAMALARI

SUNUM KONUSU

İVME SENSÖRÜ ve UYGULAMASI

Öğrencilerin :

Adı : RABİA Adı : SABRİ

Soyadı : YILDIRIM Soyadı : GÜLTEKİN

Numara : 47803523978 Numara : 25820504286

E-posta : yildirimrabiace@gmail.com

E-posta : gultekinsabrice@gmail.com

ADXL345 İVME SENSÖRÜ

Kullandığımız Stellaris M3 kitimizde ADXL345 ivme ölçer sensörü bulunmaktadır.

ADXL345 ; küçük, düşük güç tüketimine sahip 3 eksende çıkış verebilen bir açısal ivme ölçer sensördür. ±16g’lik bir algılama alanına sahip olup, I²C hattı üzerinden ve SPI hattı üzerinden çıkış alınabilir.

Kart üzerinde dahili voltaj regülatörü bulunduğundan 3-5V arası bir giriş gerilimi ile beslenebilir.

Kart üzerinde bununla beraber iki adet kesme pinide bulunmaktadır. Bu pinler, serbest düşüş, dokunma veya çift dokunma için ayarlanarak çıkış vermesi sağlanabilir. [5]

Özellikleri :



  • Giriş Voltajı : 3-5V

  • Düşük güç tüketimi(40uA)

  • Serbest düşüş algılama

  • SPI ve I²C arayüzü



Şekil : Stellaris M3 kiti

İvme sensörümüz Şekil 1’de kutu içerisinde gösterilen kısımda bulunmaktadır.

Kullanılan ivme sensörümüz Şekil 2’ de gösterilmektedir.



Şekil : İvme sensörü

İVME SENSÖRÜ PİN KONFİGÜRASYONU VE FONKSİYON TANIMLAMALARI



Şekil : İvme sensörü pin konfügürasyonu ve fonksiyon tanımlamaları [1]

İVME SENSÖRÜNÜN ÖZELİKLERİ



Şekil : İvme sensörünün çalışma özellikleri [1]

İVME SENSÖRÜNÜN REGİSTER HARİTASI



Şekil : Register haritası [1]

İVME SENSÖRÜNÜN ÇALIŞMASINI SAĞLAYAN REGISTERI

Register 0x00 – DEVID ( Read Only) :



Şekil : Register 0x00 -Devid

DEVID kaydı i 0xE5 sabit bir aygıt kimlik kodu tutar. Şekil 6’da DEVID kaydı için gerekli değerler yazılmıştır. Bu değer 8’lik sayı tabanında 345’ e denk gelir. Bu registerin tanımlanması sensörün çalışması için çok önemlidir. [1]



İVME SENSÖRÜNÜN İLERİ HASSASİYET DÜZEYLERİ

Şekil : Hassasiyet düzeyleri [1]



I²C HABERLEŞMESİ

  I²C (Inter-Integrated Circuit), seri haberleşme türlerinden senkron haberleşmeye bir örnektir. Haberleşme için toprak hattı dışında SDA ve SCL olmak üzere iki hatta ihtiyaç duyulmaktadır. Hat sayısının fazla olması nedeniyle, uzun mesafeli haberleşmelerde tercih edilmez. Genellikle kısa mesafeli ve düşük veri aktarım hızının yeterli olduğu yerlerde kullanılır.

I²C haberleşmesinde, haberleşmeyi kontrol eden master cihazı bulunur. Her haberleşmede bir tane master bulunmalıdır. Haberleşmenin sağlanabilmesi için haberleşme hattına en az bir adet slave (köle) cihaz bağlanmalıdır. Hatta bağlanan birden fazla slave cihazlardan hangisinin veri aktaracağına, master cihaz karar verir. Böylece hat sayısında bir değişiklik olmadan birden fazla cihazla haberleşme sağlanır.

ÖRNEK :




Şekil : I2C Örneği

Şekil 8’de ki örnek çizim için ; Master ve slave cihazların aynı besleme hattına bağlanmasına gerek yoktur. Fakat iletişimin sağlanması için toprak hatlarının aynı olması gerekir. Bunun yanında veri aktarımı için SDA (Serial Data Line) ve SCL (Serial Clock) olmak üzere iki adet haberleşme hattı bulunur. Bu hatlardan SDA, cihazlar arasındaki veri aktarımının sağlandığı hattır. Bu hatta çift yönlü veri aktarımı olur. Hatta aktarılan verilerin senkronizasyonu, SCL hattı tarafından gerçekleştirilir. SCL hattında master cihaz tarafından üretilen saat sinyali bulunur. SDA hattındaki haberleşme, bu sinyale göre düzenlenir.

Haberleşmenin tüm hat boyunca hatasız bir şekilde sağlanabilmesi için SDA ve SCL hatları, pull-up dirençlerle VCC hattına bağlanmalıdır. SDA ve SCL pinleri, kullanılan Arduino türüne göre değişiklik göstermektedir. Arduino türlerine göre SDA ve SCL pinleri Tablo1’de gösterilmiştir. [2]



Tablo : Türe göre değer tablosu

BUFFER (Tampon Saha) :

Verilerin I/O işlemlerinden sonra belleğe yazılmadan önce uğradıkları bir sahadır. Bufferlar I/O işlemi sırasında kullanıcının beklemesini engellemek için kullanılırlar. Bellekten okumak ve belleğe yazmak maliyetli bir işlemdir. Sistemi yorar ve hız olarak yavaştır.  I/O aygıtlarından gelen veriler bu sebeple önce bir havuzda toplanır. Böylece bu havuz belirli miktarlarda dolduktan sonra toplu olarak belleğe yazılır. Bu sisteme performans kazandıran bir harekettir. [4]

UYGULAMA :

İVME SENSÖRÜ İLE TOP HAREKETİ

Uygulama ne yapmakta ?

İvme sensörü kullanılarak alınan x-y değerleri ile oluşturulan topun herketi sağlanmakta aynı zamanda topun hızıda kontrol edilmektedir. Yani kitimizin eğim değerlerini bir anda (hızlıca eğersek) değiştirirsek daha hızlı hareket edecektir.Top bulunduğu çerçeve alanının dışına çıkmamaktadır. Şekil 9 ‘da tasarım gösterilmektedir.

Uygulamamızda

Label2’ de X yazmakta.

Label3’te ölçülen X değeri yazılacaktır.

Label’1de Y yazmakta.

Label4’te ölçülen Y değeri yazacaktır.

Top olarak kullanılan Circle1’dir.



Şekil : İvme sensörü uygulamasının görünümü

UYGULAMAMIZIN KODLARI :

Tüm kodlar ivme_main.c ‘de yazılmaktadır.

#include "ivme_objects.h"

#include "built_in.h"

//ivme sensörünün verilerini tanımladık.

// ADXL345 Register Definition

#define _POWER_CTL 0x2D

#define _DATA_FORMAT 0x31

#define _BW_RATE 0x2C

#define _DATAX0 0x32

#define _DATAX1 0x33

#define _DATAY0 0x34

#define _DATAY1 0x35

#define _DATAZ0 0x36

#define _DATAZ1 0x37

#define _FIFO_CTL 0x38

#define _SPEED 0x0F // Buffer Speed - 3200Hz
#define _ACCEL_ERROR 0x02
//değişkenler

char out[16];

int readings[2] = {0, 0};

char cACCEL_test_status;


//İvme sensörü fonksiyonları

void ADXL345_Write(unsigned short address, unsigned short data1) {

I2C0_Enable(); // issue I2C start signal

I2C0_Master_Slave_Addr_Set(0x1D, _I2C_DIR_MASTER_TRANSMIT);

I2C0_Write(address,_I2C_MASTER_MODE_BURST_SEND_START); // send byte (address of the location)

I2C0_Write(data1,_I2C_MASTER_MODE_BURST_SEND_FINISH); // send data (data to be written)

I2C0_Disable(); // issue I2C stop signal

}

unsigned short ADXL345_Read(unsigned short address) {



unsigned short tmp = 0;

I2C0_Enable(); // issue I2C start signal

I2C0_Master_Slave_Addr_Set(0x1D, _I2C_DIR_MASTER_TRANSMIT); // issue I2C start signal

I2C0_Write(address, _I2C_MASTER_MODE_SINGLE_SEND);

I2C0_Master_Slave_Addr_Set(0x1D, _I2C_DIR_MASTER_RECEIVE);

I2C0_Read(&tmp, _I2C_MASTER_MODE_SINGLE_RECEIVE);

I2C0_Disable(); // issue I2C stop signal

return tmp;

}
char ADXL345_Init(void) {

char id = 0x00;

// Go into standby mode to configure the device.

ADXL345_Write(0x2D, 0x00);

id = ADXL345_Read(0x00);

if (id != 0xE5) {

return _ACCEL_ERROR;

}

else {



ADXL345_Write(_DATA_FORMAT, 0x08); // Full resolution, +/-2g, 4mg/LSB, right justified

ADXL345_Write(_BW_RATE, 0x0A); // Set 100 Hz data rate

ADXL345_Write(_FIFO_CTL, 0x80); // stream mode

ADXL345_Write(_POWER_CTL, 0x08); // POWER_CTL reg: measurement mode

return 0x00;

}

}


int Accel_ReadX(void) {

int Out_x;


Hi(Out_x) = ADXL345_Read(_DATAX1);

Lo(Out_x) = ADXL345_Read(_DATAX0);


return Out_x;

}
int Accel_ReadY(void)

{

int Out_y;


Hi(Out_y) = ADXL345_Read(_DATAY1);

Lo(Out_y) = ADXL345_Read(_DATAY0);


return Out_y;

}

void ACCEL_Start(char *test)



{

// Reset error flag

*test = 0;
// Initialize I2C communication

I2C0_Init_Advanced(100000, &_GPIO_MODULE_I2C0_B23);


TFT_Set_Font(TFT_defaultFont, CL_YELLOW, FO_HORIZONTAL);

TFT_Set_Pen(CL_TEAL, 1);

TFT_Set_Brush(1, CL_TEAL, 0, 0, 0, 0);

TFT_Rectangle(0, 0, 320, 22);

TFT_Write_Text("Hosgeldiniz. Ivme Modulu Test Ediliyor.", 5, 6);

Delay_ms(2000);

TFT_Rectangle(0, 0, 320, 22);
// Initialize ADXL345 accelerometer

if (ADXL345_Init() == 0)

{

TFT_Write_Text("Ivme Modulu Basariyla Kuruldu.", 5, 6);



*test = 1;

Delay_ms(2000);

}

else


{

TFT_Write_Text("Ivme Modulunde Bir Hata Meydana Geldi.", 5, 6);

*test = 2;

Delay_ms(2000);

}
TFT_Rectangle(0, 0, 320, 22);

}
void Accel_Average(void) {

int i, sx, sy;
// sum

sx = sy = 0;


// average accelerometer reading over last 16 samples

for (i=0; i<16; i++) {

sx += Accel_ReadX();

sy += Accel_ReadY();

}

// average



readings[0] = sx >> 4;

readings[1] = sy >> 4;

}
void Display_X_Value(void)

{

TFT_Rectangle(25, 6, 155, 22);



IntToStr(readings[0], out);

Label3.Caption=out;

DrawLabel(&Label3);

Delay_ms(10);

}
void Display_Y_Value(void)

{

TFT_Rectangle(180, 6, 320, 22);



IntToStr(readings[1], out);

Label4.Caption=out;

DrawLabel(&Label4);

Delay_ms(10);

}
void ACCEL_Test(void)

{

Accel_Average(); // Calculate average X, Y and Z reads



Display_X_Value(); // Display average X value read

Display_Y_Value(); // Display average Y value read

Delay_ms(10);

}
int CposX=150,CposY=110;


void UpdateCirclePosition(void){
int diffX=0,diffY=0;

bit directionX,directionY;


if(!(readings[0]<50 && readings[0]>-50)){

if(readings[0]<0)

{

DiffX=-readings[0]/15-3;



directionX=1;

}

else



{

DiffX=readings[0]/15-3;

directionX=0;

}

}



if(!(readings[1]<50 && readings[1]>-50)){

if(readings[1]<0)

{

DiffY=-readings[1]/15-3;



directionY=1;

}

else



{

DiffY=readings[1]/15-3;

directionY=0;

}

}


TFT_Set_Pen(CL_TEAL, 1);

TFT_Set_Brush(1, CL_TEAL, 0, 0, 0, 0);

TFT_Circle(Circle1.Left+Circle1.Radius,Circle1.Top+Circle1.Radius,Circle1.Radius);
if(directionX && directionY){

Circle1.Left=Circle1.Left+diffX;

Circle1.Top=Circle1.Top+diffY;

if(Circle1.Left>300)

Circle1.Left=300;

if(Circle1.Top>220)

Circle1.Top=220;

}else if(directionX && !directionY){

Circle1.Left=Circle1.Left+diffX;

Circle1.Top=Circle1.Top-diffY;

if(Circle1.Left>300)

Circle1.Left=300;

if(Circle1.Top<26)

Circle1.Top=26;

}else if(!directionX && directionY){

Circle1.Left=Circle1.Left-diffX;

Circle1.Top=Circle1.Top+diffY;

if(Circle1.Left<20)

Circle1.Left=20;

if(Circle1.Top>220)

Circle1.Top=220;

}else if(!directionX && !directionY){

Circle1.Left=Circle1.Left-diffX;

Circle1.Top=Circle1.Top-diffY;

if(Circle1.Left<20)

Circle1.Left=20;

if(Circle1.Top<26)

Circle1.Top=26;

}

DrawCircle(&Circle1);



TFT_Set_Pen(CL_TEAL, 1);

TFT_Set_Brush(1, CL_TEAL, 0, 0, 0, 0);

}
void main() {
Start_TP();

TFT_Set_Font(TFT_defaultFont, CL_YELLOW, FO_VERTICAL);

TFT_Write_Text("IVME MODUL UYGULAMASI", 2, 225);

ACCEL_Start(&cACCEL_test_status);

DrawLabel(&Label2);

DrawLabel(&Label1);

while (1) {

Check_TP();

ACCEL_Test();

UpdateCirclePosition();

}

}
SUNUMDA YAPILAN UYGULAMA :



Uygulamamızda kare cisini ivme sensöründen okunan x-y verilerine göre hareketi sağlanmıştır. Şekil 10’da tasarım gösterilmektedir.

Label1’ de X yazmakta.

Label4’ te ölçülen X değeri yazılacaktır.

Label2’ de Y yazmakta.

Label3’ te ölçülen Y değeri yazılacaktır.

Label5’ te Z yazmakta.

Label6’ da ölçülen Z değeri yazılacaktır.



Şekil : Sunumda yapılan uygulamanın tasarımı
UYGULAMAMIZIN KODLARI :

Tüm kodlar ivmeprojesi2_main.c ‘de yazılmaktadır.

#include "ivmeprojesi2_objects.h"

#include "built_in.h"


//ivme sensörünün verilerini tanımladık.

// ADXL345 Register Definition

#define _POWER_CTL 0x2D

#define _DATA_FORMAT 0x31

#define _BW_RATE 0x2C

#define _DATAX0 0x32

#define _DATAX1 0x33

#define _DATAY0 0x34

#define _DATAY1 0x35

#define _DATAZ0 0x36

#define _DATAZ1 0x37

#define _FIFO_CTL 0x38

#define _SPEED 0x0F // Buffer Speed - 3200Hz
#define _ACCEL_ERROR 0x02
//değişkenler

char out[16];

int Xvalue,Yvalue,Zvalue;

char cACCEL_test_status;


//İvme sensörü fonksiyonları

void ADXL345_Write(unsigned short address, unsigned short data1) {

I2C0_Enable(); // issue I2C start signal

I2C0_Master_Slave_Addr_Set(0x1D, _I2C_DIR_MASTER_TRANSMIT);

I2C0_Write(address,_I2C_MASTER_MODE_BURST_SEND_START); // send byte (address of the location)

I2C0_Write(data1,_I2C_MASTER_MODE_BURST_SEND_FINISH); // send data (data to be written)

I2C0_Disable(); // issue I2C stop signal

}

unsigned short ADXL345_Read(unsigned short address) {



unsigned short tmp = 0;

I2C0_Enable(); // issue I2C start signal

I2C0_Master_Slave_Addr_Set(0x1D, _I2C_DIR_MASTER_TRANSMIT); // issue I2C start signal

I2C0_Write(address, _I2C_MASTER_MODE_SINGLE_SEND);

I2C0_Master_Slave_Addr_Set(0x1D, _I2C_DIR_MASTER_RECEIVE);

I2C0_Read(&tmp, _I2C_MASTER_MODE_SINGLE_RECEIVE);

I2C0_Disable(); // issue I2C stop signal

return tmp;

}
//ivme sensörünün tanımlanması.

char ADXL345_Init(void) {

char id = 0x00;

// Go into standby mode to configure the device.

ADXL345_Write(0x2D, 0x00);

id = ADXL345_Read(0x00);

if (id != 0xE5) {

return _ACCEL_ERROR;

}

else {


ADXL345_Write(_DATA_FORMAT, 0x08); // Full resolution, +/-2g, 4mg/LSB, right justified

ADXL345_Write(_BW_RATE, 0x0A); // Set 100 Hz data rate

ADXL345_Write(_FIFO_CTL, 0x80); // stream mode

ADXL345_Write(_POWER_CTL, 0x08); // POWER_CTL reg: measurement mode

return 0x00;

}

}


//ivme sensörünün X değerini okuma

int Accel_ReadX(void) {

int Out_x;
Hi(Out_x) = ADXL345_Read(_DATAX1);

Lo(Out_x) = ADXL345_Read(_DATAX0);


return Out_x;

}

//ivme sensörünün Y değerini okuma



int Accel_ReadY(void)

{

int Out_y;


Hi(Out_y) = ADXL345_Read(_DATAY1);

Lo(Out_y) = ADXL345_Read(_DATAY0);


return Out_y;

}

//ivme sensörünün Z değerini okuma



int Accel_ReadZ(void)

{

int Out_z;


Hi(Out_z) = ADXL345_Read(_DATAZ1);

Lo(Out_z) = ADXL345_Read(_DATAZ0);


return Out_z;

}
//ivme sensörünü başlatma

void ACCEL_Start(char *test)

{

// Reset error flag



*test = 0;
// Initialize I2C communication

I2C0_Init_Advanced(100000, &_GPIO_MODULE_I2C0_B23);


TFT_Set_Font(TFT_defaultFont, CL_YELLOW, FO_HORIZONTAL);

TFT_Set_Pen(CL_PURPLE, 1);

TFT_Set_Brush(1, CL_PURPLE, 0, 0, 0, 0);

TFT_Rectangle(0, 0, 320, 22);


TFT_Write_Text("Hosgeldiniz. Ivme Modulu Test Ediliyor.", 5, 6);

Delay_ms(2000);

TFT_Rectangle(0, 0, 320, 22);
// Initialize ADXL345 accelerometer

if (ADXL345_Init() == 0) // _ACCEL_ERROR kodu gelmediyse, 0x00 geldiyse.

{

TFT_Write_Text("Ivme Modulu Basariyla Kuruldu.", 5, 6);



*test = 1;

Delay_ms(2000);

}

else


{

TFT_Write_Text("Ivme Modulunde Bir Hata Meydana Geldi.", 5, 6);

*test = 2;

Delay_ms(2000);

}
TFT_Rectangle(0, 0, 320, 30);

}
//X,Y,Z Verilerini okuyup ortalamasını alma

void Accel_Average(void) {

int i, sx, sy, sz;


// sum

sx = sy = sz = 0;


// average accelerometer reading over last 16 samples

for (i=0; i<16; i++) {

sx += Accel_ReadX();

sy += Accel_ReadY();

sz += Accel_ReadZ();

}

// average



Xvalue = sx >> 4; //4 bit sağa kaydır.

Yvalue = sy >> 4;

Zvalue = sz >> 4;

}
//X değerini Ekranda gösterme

void Display_X_Value(void)

{

TFT_Rectangle(270, 60, 320, 75);



IntToStr(Xvalue, out);

Label4.Caption=out;

DrawLabel(&Label4);

Delay_ms(10);

}
//Y değerini Ekranda gösterme

void Display_Y_Value(void)

{

TFT_Rectangle(270, 120, 320, 135);



IntToStr(Yvalue, out);

Label3.Caption=out;

DrawLabel(&Label3);

Delay_ms(10);

}
//Z değerini Ekranda gösterme

void Display_Z_Value(void)

{

TFT_Rectangle(270, 180, 320, 195);



IntToStr(Zvalue, out);

Label6.Caption=out;

DrawLabel(&Label6);

Delay_ms(10);

}
//ivme sensörünü test etme.

void ACCEL_Test(void)

{

Accel_Average(); // İvme sensörünün X,Y,Z verileri hesaplandı



Display_X_Value(); // Ekranda ortalama X değeri yazıldı.

Display_Y_Value(); // Ekranda ortalama Y değeri yazıldı.

Display_Z_Value(); // Ekranda ortalama Z değeri yazıldı.

Delay_ms(10);

}

//Dikdörtgenin Pozisyonu Güncellendi.



void UpdateRectanglePosition(void)

{

if( Xvalue < 0 )//eğer okunan ortalama x değeri 0'dan küçükse



{

Box1.Left=-Xvalue;

}

else


{

Box1.Left=Xvalue;

}

if( Yvalue < 0 ) //eğer okunan ortalama y değeri 0'dan küçükse



{

Box1.Top=-Yvalue;

}

else


{

Box1.Top=Yvalue;

}

DrawBox(&Box1); //Dikdörtgeni(Kutucuğu) ekranda çizdir.



TFT_Set_Pen(CL_PURPLE, 1); //Kalemi mor renge ayarla, kalınlık 1

TFT_Set_Brush(1, CL_PURPLE, 0, 0, 0, 0); //Fırçayı mor renge ayarla.

}
void main() {
Start_TP(); //touchpanelin tanımlandığı ve kalibrasyon yapılan kısım.

ACCEL_Start(&cACCEL_test_status);//ivme sensörünü başlattık.


//fırça ve kalem rengi ayarladık.

TFT_Set_Pen(CL_PURPLE, 1);

TFT_Set_Brush(1, CL_PURPLE, 0, 0, 0, 0);

while (1) {

Check_TP();

//sonsuza kadar ivmenin değerini ölç kutunun pozisyonunu güncelle

ACCEL_Test();

UpdateRectanglePosition();

}

}

KAYNAKLAR :



1. https://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXL345.pdf

2. https://gelecegiyazanlar.turkcell.com.tr/konu/arduino/egitim/arduino-401/i2c-protokolu

3. http://libstock.mikroe.com/projects/view/236/mikromedia-for-stellaris-examples

4. http://www.mehmetcemyucel.com/2009/05/buffer-nedirnicin-kullanlr.html



5. http://www.robotistan.com/adxl345-3-eksen-ivme-olcer-triple-axis-accelerometer- breakout-adxl345
Yüklə 0,89 Mb.

Dostları ilə paylaş:




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə