Gömülü Sistem ve Programlama ile ilgili yazılar yazıyorum. Umarım faydalı olur.

19 Eylül 2016 Pazartesi

MSP430 DC Motor Hız ve Yön Kontrolü

15:13:00 Posted by Erencan Tayanç , , , , , , No comments

MSP430 DC Motor Hız ve Yön Kontrolü

   Bu yazımızda MSP430G2553 ile DC motor kontrölü yapacağız. Bunun için öncelikle motor sürücüsüne ihtiyacımız var. Bunun için H-bridge (Köprüsü) olarak adlandırılan devreyi kurmamız lazım. Yada bununla uğraşmak istemiyorsanız hazır olarak motor sürücüsü alabilirsiniz.
H-Köprüsü Devresi (Motor Sürücü)

  Devrenin çalışma mantığına gelirsek; A girişi logic 1, B girişi logic 0 seviyesindeyken NPN transistörün çalışma prensibinden dolayı Q1 ve Q4 iletimdeyken Q2 ve Q3 transistörleri kesimdedir. Bu nedenle akım Q1 transistörü üzerinden DC motora akar ve buradan da Q4 üzerinden toprağa ulaşıp devreyi tamamlamış olur. Böylece motor bir yöne dönmüş olur. A girişi logic 0, B girişi logic 1 iken yukarıda anlattığımız durumun tam tersi gerçekleşip akım ters yönden akar ve Q2 transistörü üzerinden toprağa akar. Böylece motor ters yönde dönmüş olur. 

          A                           B                                     MOTOR      
                0                        0                                    HAREKET YOK
                  1                        0                                    İLERİ HAREKET
                  0                        1                                     GERİ HAREKET
                  1                        1                                      HAREKET YOK
   Devrede bulunan 1N4148 diyotunu piyasada bulamazsanız 1N4007 de kullanabilirsiniz. Bu diyotlar devreden akım ani akımları kesmek için kullanılmıştır. Girişlerdeki dirençler olmasa da olur. Yine de koruma amaçlı kullanmanızda fayda var. 150 ohm direnç bulamazsanız 120 ohm gibi yakın direnç değerleri de kullanabilirsiniz.
   Motor sürücünü hazır olarak almak isterseniz buradan ulaşabilirsiniz. Bu devrenin üzerinde bir adet 5V'lik regülatörde bulunmaktadır. Bu sayede mikrodenetleyicimizi buradaki kaynaktan da besleyebiliriz. Enable girişlerine logic 1 seviyesi verdiğimizde bu entegre aktif olur diğer türlü girişleri hangi logic seviyeye çekerseniz çekin çalışmaz. Bu kartın üstündeki entegre 2 adet H-Köprüsü barındırmaktadır. Bu nedenle aynı anda 2 adet DC motor da sürebilirsiniz bu devreyle. Giriş voltajı olarak motorunuz kaç volt ile çalışıyorsa o voltajı verin. Bu entegre maksimum 30 Volt girişe dayanabiliyor bu nedenle daha yüksek bir voltaj uygulamayın. Zaten elektronikçilerde bulunan motorlar 6-12 volt arası çalıştığından bu herhangi bir sorun teşkil etmeyecektir sizin için.
L298 Motor Sürücü Devresi
   Motorun yön kontrolünün nasıl yapacağını anlattık şimdi sıra geldi hız kontrölüne. Hız kontrölü için PWM (Pulse With Modulation) yöntemi kullanılır. Bu yöntemi kısaca anlatmak gerekirse, mikrodenetleyiciler için logic 1 seviyesi 5 yada 3,3 volttur. Logic 0 seviyesi ise 0 volttur. Eğer ki biz yukarıdaki devrenin girişlerine logic 1 seviyesi verirsek motor yüksek hızda dönecektir. Motorun hızını azaltmak istiyorsak mikrodenetleyiciden logic 1'in daha altında bir voltaj uygulamamız gerekli fakat bu direkt olarak mümkün değil. Bunun yerine belli bir süre logic 1 belli bir süre 0 verilirse bu iki seviyenin ortalama değeri devreye verilmiş gibi olacaktır.
PWM (Pulse With Modulation)
   Yukarıdaki dalga animasyonunu inceleyecek olursak ilk örnekte doluluk oranı %10'dur. Logic 1 seviyesini 5 Volt kabul edersek birim zamanda devreye 0,5 Volt eşdeğer voltaj uygulanır. İkinci örnekte 1,5 Volt, üçüncü örnekte 2,5 volt ve son örnekte 4,5 volt eşdeğere gerilim oluşturulmuştur. Bir periyottaki doluluk oranı ne kadar fazla ise uygulanan eşdeğer voltaj o kadar yüksek olur. MSP430'un pinlerindeki çıkış gerilimi 3,3 volt olduğundan yukarıdaki grafiği tekrar inceleyecek olursak;

  1. Dalga  0,33 Volt
  2. Dalga  0,99 Volt
  3. Dalga  1,65 Volt
  4. Dalga  2,97 Volt  olur.
   Bu mantıkla aşağıdaki kodda gecikme fonksiyonu hız kontrolü için kullanılmıştır. Bu fonksiyon yerine __delay_cycles() metodu da kullanılabilir. Ben bunun yerine ayrı bir metot yazmak istediğim.
 Aşağıda kodumuzu görüyorsunuz. Aşağıda gördüğünüz kodu açıklamayacağım çünkü yanına gerekli açıklamaları yaptım. Aklınızdaki soruları ve görüşlerinizi yorum olarak yazabilirsiniz ve kodu istediğiniz gibi değiştirerek farklı uygulamalarda kullanabilirsiniz.


#include "io430.h"
#include "in430.h"
void gecikme(void); //Fonksiyon için prototip oluşturuldu
int k;

P2DIR = 0xF0; //Port2' nin  1. 2. 3. 4. pinleri çıkış gerisi giriş
P2REN = 0x0F; //Girişlerin pull up direnci aktif
P2OUT = 0X00; //P2 çıkışı temizleniyor
P2IE  = 0x0F; //Port2, 1 2 3 4 kesme olsun
P2IES = 0x00; //Yükselen kenarda kesme olucak
P2IFG = 0x00; //P2 portu kesme bayragı temızlenıyor

P1OUT = 0x00; //P1 port cıkısları temızlenyor
P1DIR = 0x0F; //1 2 3 4 giriş gerisi cıkıs

_BIS_SR(GIE); //Tüm kesmeler aktif
for(;;);
}

#pragma vector=PORT2_VECTOR     //Port2 kesme vektöru tanımlandı
__interrupt void P1_ISR(void)
{
if(P2IFG_bit.P0) //İleri
P1OUT_bit.P0 = 1;
P1OUT_bit.P1 = 0;
gecikme(k);

else if(P2IFG_bit.P1) //Geri
P1OUT_bit.P0 = 0;
P1OUT_bit.P1 = 1;
gecikme(k);

else if(P2IFG_bit.P2)   //Hızlan
k-=500;

else if(P2IFG_bit.P3)   //Yavaşla
k+=500;

P2IFG = 0x00;   //Bayrak temizlendi
}


void gecikme(void)
{
volatile unsigned int i;
for(i=0 ; i < 50000 ; i ++);
}

28 Ağustos 2016 Pazar

MSP430 ile Vumetre Uygulaması

04:17:00 Posted by Erencan Tayanç , , , , , , , , , 1 comment

MSP430 ile Vumetre Uygulaması



   16 bitlik RISC mimarisine sahip MSP430 ailesi düşük güç tüketimi için Texas Instruments (TI) şirketi tarafından tasarlanmıştır. Bu tasarıma bağlı olarak azaltılmış komut kümesi sayesinde daha hızlı çalışır, işlemcilerin komut kümeleri basitleştirildiklerinden çok az yonga kullanır ve CISC işlemcilere göre daha çabuk tasarlanabilirler. USB, RF, LCD kontrollerinin yanı sıra I2C, SPI, USART, ADC dâhil olmak üzere yüksek performanslı çevre birimleri bulundururlar. MSP430/16x serileri halinde ailelere sahiptir.


MSP430 Geliştirme Kartı
   Kısaca mikrodenetleyicimizi tanımladıktan sonra vumetre nedir ona gelelim. Vumetre sesin şiddetine göre devreye bağlı olan ledlerin yanıp sönmesini görebildiğimiz bir devredir.
Vumetre Devresi Örneği


Devrenin fritzing Çizimi

   
   Yukarıda çizmiş olduğum devrede vumetre devresindeki ses çıkışı yerine pot kullandım. Bunun sebebi kodu basitçe deneyebilmeniz için uygun şartları sağlamaktadır. Potansiyometrenin içindeki ayarlanabilir uç sayesinde içindeki direnç miktarı değişir. bu sayede ise değişen direnç oranına göre üzerine düşen gerilim miktarı değişmektedir. Bu sayede ölçülen gerilim miktarına göre mikrodenetleyici çıkışlarındaki ledler bu voltaj şiddetine göre yanıp sönecektir. Devre ve kod MSP430G2553 mikrodenetleyicisinde denenmiş olup çalıştığı kesindir. Soru, öneri ve görüşlerinizi yorum olarak yazarsanız sevinirim...





/*
Yazar : Erencan TAYANÇ
MSP430 ile Vumetre
*/
#include <msp430.h>
void LedYak(int); // Fonksiyon prototipi.
int ADC_Ham; // Ham  değerlerini tutan değişkenler
void main(void) {
  P1DIR = 0xFE;  // p1.0 hariç hepsi output olarak ayarlandı
  P1OUT = 0x00;
  WDTCTL = WDTPW | WDTHOLD; // Watchdog timeri durdur.
  ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; // ADC ayarları, kesme aktif
  ADC10CTL1 = INCH_0; // A0 girişini seç
  ADC10AE0 |= BIT0; // PA.0 ADC özelliğini aktif et
  _BIS_SR(GIE); // Kesmeleri aç
  for(;;){
    ADC10CTL0 |= ENC + ADC10SC; // AD çevrimi başlat
    _BIS_SR(LPM0_bits); // Uykuya gir (Low Power 0 Moduna)
    ADC_Ham = ADC10MEM; // Çevrim sonucunu ADC_Ham değişkenine at.
    LedYak(ADC_Ham);    //Led Yak fonksiyonuna ADC_Ham'ın değerini yolla.
  }
}
void LedYak(int ham){
  /* Bu fonksiyonun içindeki sayıları en iyi değeri bulmak
  * için deneyerek bulabilirsiniz. ADC' ye bağlanacak devrenin
  * çıkış gerilimine göre bu değerler farklılık gösterir.
  */

  if(ham>=100 && ham <130)
    P1OUT =  0x7E;

  else if(ham>=130 && ham<160)
    P1OUT =  0x3E;

  else if(ham>=160 && ham<190)
    P1OUT =  0x1E;

  else if(ham>=190 && ham<220)
    P1OUT =  0x0E;

  else if(ham>=220 && ham<250)
    P1OUT =  0x06
   
  else if(ham>=250 && ham<280)
    P1OUT =  0x02;
}
// ADC10 kesme vektörü
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
  __bic_SR_register_on_exit(CPUOFF); // İşlemciyi uykudan uyandır.
}

Arduino ile Mors Üreteci

03:17:00 Posted by Erencan Tayanç , , , , , , , , , 1 comment

Arduino ile Mors Üreteci

   Mors alfabesi veya mors kodu, kısa ve uzun işaretler ( ve ) ile bunlara karşılık gelen ışık veya sesleri kullanarak bilgi aktarılmasını sağlayan yöntem. Günümüzde ses işaretleriyle kullanımı pek kalmasa da ışıkla kullanımı hala bulunmaktadır. Askeriyede ve dağcıların bilmesi gerekli olan bu alfabenin Arduino ile nasıl üretildiğini göreceksiniz.

   Yukarıda gösterilen şekildeki gibi basit bir devre kurabilirsiniz. İsterseniz led yerine buzzer bağlayarak Mors Kodunu sesli olarak kullanabilirsiniz.


int ledPin = 12;
char* letters[] =
{ ".-", "-...", "-.-.", "-..", ".", "..-.", "--.",
  "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.",
  "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."
};
char* numbers[] =
{"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."};
int dotDelay = 200;
void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}
void loop() {
  char ch;
  if (Serial.available())
  {
    ch = Serial.read();
    if (ch >= 'a' && ch <= 'z') {
      flashSequence(letters[ch - 'a']);
    }
    else if (ch >= 'A' && ch <= 'Z') {
      flashSequence(letters[ch - 'A']);
    }
    else if (ch >= '0' && ch <= '9') {
      flashSequence(numbers[ch - '0']);
    }
    else if (ch == ' ') {
      flashSequence("-.-.-"); // Boşluğun mors kodu.
    }
  }
}
void flashSequence(char* sequence) {
  int i = 0;
  while (sequence[i] != NULL) {
    flashDotOrDash(sequence[i]);
    i++;
  }
  delay(dotDelay * 3);
}
void flashDotOrDash(char dotOrDash) {
  digitalWrite(ledPin, HIGH);
  if (dotOrDash == '.') {
    delay(dotDelay);
  }
  else {
    delay(dotDelay * 3);
  }
  digitalWrite(ledPin, LOW);
  delay(dotDelay);
}

   Kodu açıklamaya gelirsek ilk olarak harfler ve sonra da numaralar dizisi oluşturulmuş. Buradaki nokta ve çizgiler (.  -) mors alfabesindeki harflerin ve sayıların karşılıklarıdır. Harfler dizisinin ilk elemanı olan ".-" a harfini temsil eder ve "--.." ise son harf olan z'yi temsil eder. Sonrasında nokta için bekleme süresi 200 olarak belirtilmiş. Bunu delay metodunun içine yazacağımızdan bu değer 200 ms'yi temsil etmektedir. Sonrasında 12.pin çıkış olarak ayarlanıp seri haberleşme hızı 9600 baud olarak set ediliyor. Bu satır yazılmazsa da bu değer default olarak 9600'e set edilir.
   Loop metodunun içinde, seri haberleşme aktifken seri porttan okunan değer ch'a atanıyor. İlk if ile bu gelen karakterinin a ile z arasında olup olmadığı kontrol ediliyor. Girilen harf bu harfler arasında ise kod if'in içine giriyor. Burada kontrol ederken a'nın ASCII karşılığı olan 97 ve z'nin karşılığı olan 122 arasında mı diye bakılıyor. Sonra gelen karakterin ASCII karşılığından a'nınki çıkarılıyor. Örneğin d karakteri girildi. Bunun ASCII karşılığı 100. (100-'a') işleminin sonucu 100-97=3 olur. Böylece flashSequence(letters[3]) çıkar sonuç. Letters dizisinin 3.elemanını olan "-.." değerinin karşılığına bakarsanız d harfi olduğunu görürsünüz. Burada if'lerin içinde küçük ve büyük harf ayrımının yapılması ASCII kodlaması yüzündendir. a'nın karşılığı 97 iken, A'nın karşılığı 65'dir.


ASCII Tablosu

   FlashSequence fonksiyonu parametre olarak string alır. Dikkat ederseniz bu fonksiyona gelen değer letters yada numbers dizisinin elemanlarından biri. Örneğin seri porttan A karakterinin yazıdıldığını düşünelim. FlashSequence fonksiyonuna parametre olarak . - gelecek. Burada önce ilk karakteri  flashDotOrDash fonksiyonuna gidiyor.Orada nokta ise 200 ms yanıyor çizgi ise 600 ms. Her bir kısa ve uzun işaretten sonra digitalWrite(ledPin,LOW) metodu ve delay(dotDelay) metodları ile işaret kesiliyor ve 200 ms led sönük kalıyor.
   Mors üretecinin çalışması bu şekilde olup kodda yada başka bir yerde anlamadığınız bir şey olursa yorum bırakabilirsiniz. İlk yazım olduğundan dolayı gözümden kaçan bişeyler olduysa şimdiden özür diliyorum.