Bardağın yarısı dolu (yada PWM)

Bu yazının başlığı elektronik açısından garip te gelse ifade ettiği şey bakımından gözümüzün önüne somut bir şey getirmektedir -bardağın yarısı dolu (yada boş).

Bir büyüklüğü, potansiyeli, doluluğu elektronikte oluşturabilmek için PWM yöntemi geliştirilmiştir. Eğer bardak tam dolu olsaydı %100 dolu derdik, yarısı dolu ise %50 dolu diyebileceğimiz gibi yarısının yarısı için de %25 dolu diyebilirdik. Bardağın içindeki suyun yüksekliğini de ölçsek yada bardaktaki suyu tartsak ta oransal olarak tamamına göre hep aynı oranları bulacağız. Bu oransal yaklaşım bize elektronik olarak bir potansiyeli (yada voltajı) ifade etmemizi sağlar.

Bardak örneğimizdeki gibi bardağı azar azar doldurarak bir çok oransal/ölçülebilir değer oluşturabiliriz. Daha önceki LED yakıp söndürdüğümüz yazımızda aslında oransal olarak ledi tam dolduruyorduk. Ama gerçek dünya gıcıklıklarla doludur kimseyi memnun edemezsiniz birisi çıkıp bu ledin böyle birden yanıp sönmesini beğenmez şöyle yavaş yavaş parlaklığı artsın sonra yavaş yavaş sönsün filan gibi ukalaca isteklerde bulunacaktır yani şu bardağı yavaş yavaş doldur yavaş yavaş boşalt demek istiyor aslında (bana göre bildiğin gıcık bulmuşun yanıp sönen ledi birde yavaş yavaş yananı arıyor).

Biz şimdi şu arduino borda o kadar para verdik ve topu topu bir adet led koymuş adamlar ve marifetmiş gibi birde yanıp sönen led programı örneği vererek kendinizi bir şey sanmanızı sağlarlar. Ama demezlerki etraf gıcık dolu. Arduinoda bu ledin bağlı olduğu bacak (pin 13) dijital bir çıkıştır (yani durumu “1” veya “0” olabilir) ve arduinonun sağladığı pwm komutu analaogWrite() ancak analog çıkışlarda işe yarar(tüh vede yuh). Ama üzülmeye gerek yok biz yine de bu ledin gayet güzel istediğimiz gibi parlaklığını değiştirebilirz.

Ne demiştik bardak tam dolu olduğunda %100 oluyor o zaman bunun voltaj karşılığı 5v olsun, yanıp sönen led programımızda lede aralıklarla 5v verip duruyorduk. Ledin parlaklığını etkilemek için bu voltajı ne kadar düşürürsek o kadar daha az parlayacak. Bu voltaj etkisini yaratmak için %100 doluk için bir birim zaman içinde ne kadar 5v verdik ona bakarız, birim zamanın tamamında 5v verirsek led tam yanacak ama birim zamanın yarısı kadar 5v verip(bardağın yarısını doldurduk) ve kalan yarısı içinde birşey yapmadan beklersek (bardağın boş kısmı) güzel bişey yapmış oluruz (gerçekten).

Aşağıda Arduinoda yazdığım sketch ile topu topu bordun üstündeki bir adet led yavaşça parlar sonra yavaşça söner. Siz aşağıdaki programı kopyalayın çalıştırın nasılsa anlarsınız cin gibisiniz vesselam.

Her yazımda adet oldu kod yapısı hakkında bilgi vereyim, kodlarda  “do { kodlar;komutlar;} while -şartlar-;” kısmı bir döngüyü ifade eder while kısmındaki şart sağlanana kadar do-while arasındaki her komut çalıştırılır while kısmındaki şart kontrol edilir sağlamıyorsa do kısmından itibaren kod yeniden çalışır, döner durur. delay(milisaniyeOlarakSure) komutu bildiğin bekletme işini yapar. delayMicroseconds(mikrosaniyeSüre) da bekletir ama çok daha küçük süre olan micro saniye bazında beklersiniz.

/*
  yanar donerli bir sketch
 
  This example code is in the public domain.
 */

void setup() {
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(13, OUTPUT);  

}

void loop() {

  int i=1;
  do {                      // led yavas yavas parlasin bolumu
  digitalWrite(13, HIGH);   // bardağın dolu kısmı -set the LED on
  delayMicroseconds(i);     // dolu kısım kadar bekle -wait for a second
  digitalWrite(13, LOW);    // bardağın boş kısmı -set the LED off
  delayMicroseconds(999-i); // boş kısım kadar bekle -wait for a second
  i++;                      // ledin daha hızlı parlaklığa ulaşması için i=i+2 deneyin
  } while (i < 999);        // ledin parlaklığına ulaşması 1 sn=1000mili sn sürecek

  digitalWrite(13, HIGH); 

  delay(2000);              // 2 saniye parlak dur

  i=1;
  do {                      // led yavaş yavaş sönsün bölümü
  digitalWrite(13, HIGH);   // set the LED on
  delayMicroseconds(999-i); // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delayMicroseconds(i);     // wait for a second
  i++;
  } while (i < 999);  

   delay(2000);             // 2 saniye sönük bekle 
}                           // loop başına dön

Görsel olarak nasıl bir şey olduğunu anlatmak istersek aşağıdaki çizim pin 13 üzerinde neler yaptığımızı gösterir.

ben her ne kadar elimizdeki tek ledi çakma bir şekilde pwm yaparak  parlaklığını ayarladıysam da şu yazıda bu işlemi arduinoya otomatik olarak da yaptırabiliyorsunuz (önce bir led bulun sonra denersiniz)

Şimdilik bu kadar, değişik örnek kodlarınızı mesela mum taklidi yapan bir sketch koyarsanız yorumlara, 1 tane tadelle ısmarlayabilirim 🙂

Ömer Koman

Elektronik hakkında ilk hatırladığım şey 5-6 yaşlarımdayken babamın arkadaşı radyocunun tezgahına burnumu dayayıp lambalı radyoları tamir edişini izlemekti...

55 comments

  1. Kenan SATIR dedi ki:

    PWM için örnek uygulama olarak bir de basit bir fotoğraflı servo uygulaması yapılsa güzel olur.

  2. […] Detaylı PWM  hakkında detaylı bilgiyi daha önce  Ömer Koman tarafından yazılmış olan bu yazıdan bulabilrsiniz. […]

  3. Emre G dedi ki:

    Bazı çalışmalarda PWM yerine I2C ile motor sürülüyor. Bu konuda deneyiminiz var mı, nasıl yapılır bilemiyorum. saygılar.

    • Ömer Koman dedi ki:

      i2c protokolü iki(bazı durumlarda 3) data hattının kullanıldığı bir iletişim protokoludur data hatları Clock ve Data dan (ve Enable) oluşur komutları yollarken her komutun bitleri sırası ile bit bit her clock darbesinde iletilir ve cevap da yine her clock darbesi ile bit bit okunur, data hattı çift yönlüdür(i2c de 3. hat karşı cihazı aktif hale getirmek için enable kontrolüdür birden fazla i2c cihaz kontrol edilecekse enable hattı her motor için ayrı ayrı kullanmak gerekir). pwm mi üstün i2c mi diye soracak olursanız, bu tamamen bir seçim ve ihtiyaç meselesi. pwm de sadece bir pin gerekirken, i2c de 2 veya 3 pin gerekir ağer bir robot yapacak ve 13 tane servo motoru yöneteceksek 13 pini yönetmek daha kolay olabilir. i2c çift yönlü bir protokol olduğu için motor tarafında çeşitli verileri okumak gerekiyorsa tercih edilebilir. motor tarafında okunabilecek veriler de ise motorun çektiği akımlar, motor sıcaklığı, motorun besleme voltajı, motorun pozisyonu gibi bir çok veri alınabilir. zaten mühendislik ihtiyaçlara göre çözüm üretmek değil mi? i2c için şu linki inceleyin derim http://www.seeedstudio.com/wiki/Grove_-_I2C_Motor_Driver_V1.1

  4. Emre G dedi ki:

    teşekkürler yorumunuz için.
    Peki örnek bir arduino koduna nasıl erişebilirim. I2C bağlantısı ile sürmek hedefim.

  5. Ömer Koman dedi ki:

    yukarıdaki yorumumun sonunda verdiğim linki incelerseniz arduino ile ilgili kod var(linki tekrar paylaşıyorum http://www.seeedstudio.com/wiki/Grove_-_I2C_Motor_Driver_V1.1 ). i2c kodlarını kullanmak için linkteki gibi bir “i2c motor driver controller shield” almanız gerekir. 2 adet 2A lik DC motor sürebilmekte devre. linkini verdiğim sistemi ben kullanmadım, denemedim seedstudio kaliteli ürünler yapan bir firma seedstudio forumlarına girerek ilgili ürünün kullanıcı yorumlarını da takip edin derim. daha önce motor sürme tecrübeniz olmadı ise pwm çok kolay ve eğlenceli gelecektir. eğer i2c protokolu tecrübeniz yoksa çoşkun taşdemirin arduino kitabında harici eprom örneğinde i2c protokolu ile eproma bilgi yazmayı ve okumayı deneyebilirsiniz.

  6. Emre G dedi ki:

    Evet, aynen bahsettiğiniz gibi Coşkun beyin kitabını bitirdim, PWM konusunda deneyim kazandım. Daha açık söylemem gerekirse: http://www.robotshop.com/content/PDF/md49-documentation.pdf sitesinde mevcut olan motor kontrolörim var. Bu I2C ile mi sürülüyor çözebilmiş değilim, ayrıca PWM gibi de gelmedi. Aynı kontrolörü http://www.robot-electronics.co.uk/htm/arduino_examples.htm#MD49 24v Motor Driver sitesindeki gibi arduino kartına bağlayıp sürmeyi deneyeceğim. Kodunu iliştirmiş oraya. Tam durumu anlayamadım, aklıma yatmadı kontrolü nasıl yaptıgı konusunda. Tekrar teşekkürler.

  7. Ömer Koman dedi ki:

    md49 pdf dökümanına baktım gayet açık anlatılmış serial motor kontrol modülü diyor.(i2c veya pwm değil ama modul kendi içinde motoru kendi başına sürüyor) resimde modülün alt tarafta gördüğünüz serial rx, serial tx bağlantılarını arduinonun serial uçlarına çapraz rx->tx e rx->tx e bağlanacak. arduino üzerinden 2. sayfadaki komutlardan gerekenleri yollayacaksınız tek byte lık komutları yollayarak devrenin durumu hakkında bilgi alabiliyorsunuz veya motorları hareket ettiriyorsunuz. diğer örnek sayfalarında ise serial lcd ve motor modulu ile motorun bağlantı şemaları var. bu modül özel bir motoru sürmek için tasarlanmış her motor uyarmı bilemiyorum. hbridge motor kontrolu ile ilgili araştırma yapmanızı öneririm.

  8. Emre G dedi ki:

    teşekkürler, gerçi çok danıştım kusura bakmayın, ama bir durum daha var. MD22 adlı bir motor kontrolörü de elimde mevcut.
    http://www.robot-electronics.co.uk/htm/md22tech.htm
    Bu I2C protokoluna sahip gözüküyor. Şimdi devre şemasını şu şekilde yaptım:
    http://www.robot-electronics.co.uk/htm/arduino_examples.htm#MD22 Dual 50V 5A Motor Driver

    Buradaki Yazılmış olan örnek kodu uygulayacam.
    – Başlangıçta #define yaparak bazı tanımlamalar yapmış. Onu neye göre ve niçin yapıyor?

    – 2 motor sürülmüş, sürekli durdurulmuş hızlandırılmış gibi. Bu PWM tekniğine benziyor ama neden bu yola başvuruyor anlamadım. “Set first motor to a speed of 255” yapıyor sonra ikinci motoru durduruyor. Sonrasında tam tersini uyguluyor. Sürekli loop içinde böyle bir durum var. Bunu anlamadım amaç ne?
    – Bir de dökümanda switch mode denen bir kısım var, burayı da anlayamadım?

    Lütfen sorularımı mazur görünüz, saygılarımla.

  9. Ömer Koman dedi ki:

    sorduğunuz sorulardan i2c protokolünü hiç anlamadığınızı anlıyorum bu konuda çok çalışmanızı öneririm. örneklerde geçen
    #define SCL TRISB4 // I2C bus
    #define SDA TRISB1 //
    #define SCL_IN RB4 //
    #define SDA_IN RB1 //

    tanımları i2c protolunde kullanılan scl sda pinlerinin arduinoda fiziksel olarak hangi pinlere denk geldiğini tanımlamak için bir yöntemdir. örnek verdiğini bord hem i2c hem pwm hem analog olarak sürülebildiğinden kod örneğinin ne ile ilgili olduğuna bakın. Motor sürüş devrelerinde ilk etapta full ileri geri yapılarak çalışma alanının sınırları belirlenmeye çalışılabilir. switch mode konusunu göremedim verdiğiniz linklerde ya kodun içinde belli bir konum belirliyor yada motor güç beslemelerinin switch mode olmasını tavsiye etmiş olabilirler. Neyse bu yazı fazlasıyla amacını aştı pwm dışında şeylere kaydı bundan sonra soruları forumdan sorarsanız daha geniş alanda cevap alabilirsiniz.

  10. mahmut beşirli dedi ki:

    pwm sinyalinin aynı zamanda başka bir pot ile frkansını da değiştirmek mümkün mü.

  11. Ömer Koman dedi ki:

    /*
    yanar donerli bir sketch
    pin 3 ten alınan analog değere göre pwm frekansı değişir.

    This example code is in the public domain.
    */

    void setup() {
    // initialize the digital pin as an output.
    // Pin 13 has an LED connected on most Arduino boards:
    pinMode(13, OUTPUT);

    int analogPin = 3; // potans orta bacaktan gelen kablo giriş pin 3 e bağlanmış
    int Aval = 0; // analog değer 0-1023
    int pwmF = 1023 // yaklaşık pwm frekansı
    }

    void loop() {

    int i=1;
    do { // led yavas yavas parlasin bolumu
    digitalWrite(13, HIGH); // bardağın dolu kısmı -set the LED on
    delayMicroseconds(i); // dolu kısım kadar bekle -wait for a second
    digitalWrite(13, LOW); // bardağın boş kısmı -set the LED off
    delayMicroseconds(pwmF-i); // boş kısım kadar bekle -wait for a second
    i++; // ledin daha hızlı parlaklığa ulaşması için i=i+2 deneyin
    } while (i < pwmF); // ledin parlaklığına ulaşması 1 sn=1000mili sn sürecek digitalWrite(13, HIGH); delay(2000); // 2 saniye parlak dur Aval = analogRead(analogPin); // pot oku pwmF=Aval; i=1; do { // led yavaş yavaş sönsün bölümü digitalWrite(13, HIGH); // set the LED on delayMicroseconds(pwmF-i); // wait for a second digitalWrite(13, LOW); // set the LED off delayMicroseconds(i); // wait for a second i++; } while (i < pwmF); delay(2000); // 2 saniye sönük bekle Aval = analogRead(analogPin); // pot oku pwmF=Aval; } analog okuma ile ilgili referans bilgi http://arduino.cc/en/Reference/AnalogRead

  12. Ömer Koman dedi ki:

    yukarıda yorumda verdiğim kod soft pwm uygulamasının frekans değiştirme yöntemidir. arduino.cc resmi sitesinde analowrite komutunun anlatıldığı örnek analog girişten aldığı değeri pwm çıkışına uygular kod aşağıdaki gibidir.

    int ledPin = 9; // LED connected to digital pin 9
    int analogPin = 3; // potentiometer connected to analog pin 3
    int val = 0; // variable to store the read value

    void setup()
    {
    pinMode(ledPin, OUTPUT); // sets the pin as output
    }

    void loop()
    {
    val = analogRead(analogPin); // read the input pin
    analogWrite(ledPin, val / 4); // analogRead values go from 0 to 1023, analogWrite values from 0 to 255
    }

    kodun alındığı yer : http://arduino.cc/en/Reference/AnalogWrite

  13. mahmut beşirli dedi ki:

    verdiğiniz bilgi için teşekkür ederim

  14. murat dedi ki:

    ömer bey öncelikle vermiş olduğunuz bilgiler için sonsuz teşekkürler. bir şey sormak istiyorum ama korkuyorum da 🙂 azar yemekten 🙂 ama araştırdım cidden bulabilseydim sormazdım. elimde leadshine dm422c step motor sürücü kiti mevcut bunun pul ucuna palse uyguluyorum opto veya ena ucuna 5 v bağlıyorum, besleme 24v, motor sürücü ile uyumlu 42bygh218 1.8 derece ve 1.5 A….

    şimdi normalde bir ledin parlaklığını artırıp azaltabiliyorum analogWrite() komutu ile…benzer yazılımı step motor sürücü kitine uyguluyorum, 0-255 arası palse almam gerekiyor değil mi? yani motor bu aralıklarda 0 min 255 max dönmesi gerekiyor mu?…ama istediğim gibi dönüşler elde edemiyorum.microstep ayarı var onu 6400 yapınca hızlı dönüyor ama default ya da 1600-3200 yapınca zırlıyor motor.şöyle yalandan bir kod yazdım ama bilmem ne derece mantıklı, dönme var, deneye deneye yazarak ancak bu kadar oldu. kafamda stop etti doğrusu 🙂

    int palsePin = 13;

    void setup()
    {
    }
    void loop()
    {

    for( int donme = 0 ; donme <= 255; donme +=255)
    {
    analogWrite(palsePin,donme);

    }
    }

    mantıksız bir şey yapıyorum sanırım. şimdiden teşekkür ederim.

    • Ömer Koman dedi ki:

      Analogwrite komutunu pin11,10,9,4,5,3 pinlerinde kullanabilirsiniz, yazımda soft pwm i anlatıp bord üzerindeki tek ledden faydalanmak için örnek verdim, soft pwm de dijital pin olan 13 ü kullanabildim bu nedenle.

      servo motorları pwm le sürüyoruz sizin sürücünüz step motor olduğu için pwm le sürmenize gerek yok. datasheete göre http://www.leadshine.com/UploadFile/Down/DM422Cm.pdf 10. Sequence Chart of Control Signals bölümünde 5us den uzun pulse dizisi verdiğiniz sürece motor DIR portunun durumuna göre saat yönünde veya tersinde ilerler. örnek kod aşağıda yazdım(deneyemedim ama çalışması lazım)

      int palsePin = 13;
      int DIRPin=12;// sürücüde DIR pinine bağlı
      int palseSay=0;

      void setup()
      {
      pinMode(palsePin, OUTPUT);
      pinMode(DIRPin, OUTPUT);
      digitalWrite(palsePin, LOW);
      digitalWrite(DIRPin, HIGH); //duruma göre başlangıçta LOW da olabilir.
      }
      void loop()
      {

      //manuel pulse yaratma
      digitalWrite(palsePin, HIGH); // Pulse on
      delay(1); //1 ms bekle
      digitalWrite(palsePin, LOW); // Pulse off
      delay(1); //1 ms bekle
      //manuel pulse son

      inc(palseSay);
      if (palseSay > 500) // konfigurasyona göre pulse sayısını ayarla
      {
      if (digitalRead(DIRPin)==LOW )
      {
      digitalWrite(DIRPin,HIGH );
      }
      else
      {
      digitalWrite(DIRPin,LOW );
      }
      palseSay=0;
      }
      }

      illa analogwrite kullanacam dersen yukarıdaki “// manuel…” yazan satırların arasındaki kodları kaldırıp (yada // ile rem leyip) yerine
      analogwrite(palsePin,128); // palsePin 11 olarak değiştir tanımlarda pwm için
      delay(1); //1 ms bekle
      yazarsanız kare dalga pulse elde edersiniz.

  15. onur dedi ki:

    arduino kontrollü şarj aleti yapıyoruz.buck converter ın anahtarlamasını arduinodan aldığımız pwm le sağlıyoruz.pwm in duty cycle ını da akülerin doluluk durumuna göre arduino ayarlıyor. ancak bi sorunumuz var. pwm in frekansını değiştiremiyoruz. hep 500 hz. bunla ilgili birşeyler buldum. ancak arduinoyla daha sadece 1 ay önce çalışmaya başladığım için tam anlayamadım. frekansı nasıl değiştirebiliriz? basitçe açıklayabilirmisiniz?
    teşekkürler…

  16. Ömer Koman dedi ki:

    şuradaki dökümana göre http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM yapabilirsiniz.

    bit banging metheodu zaten yukarıda anlatmıştım. atmeganın timer ve pwm registerlerine değerler vererek değişiklik yapmak mümkün. yazıda 690hz ve 1300 hz civarlarına göre ayarlar var bir deneyin uygun mu sizin için. bir ara bu pwm yazısının gelişmişini yazayım bari çok soran olmaya başladı…

  17. iclal dedi ki:

    Merhaba Ömer Bey,

    Öncelikle verdiğiniz bilgiler için çok ama çok teşekkür ederim.
    Gördüğüm,incelediğim ve yapmaya çalıştıgım örnek kodlar genellikle dc servolar içindi. Biz projemizde AC SERVO kontrol edeceğiz. üç faz motor da pwm olayını nasıl yapacağım bilemiyorum,bu konuda ve sürücü ile arduino arasındaki bağlantı konusunda yardımcı olursanız çok sevinirim.

  18. murat polat dedi ki:

    Ömer Bey Merhaba; Arduino ile 24 Hz % 25 doluluk oranında bir kare dalga nasıl elde edilebilir.Arduino mega ile duty değeri 0-255 arasında istenildiği gibi ayarlanabiliyor. Fakat bu frekans 1 Khz sanırım değil mi? Frekansı ve duty değerini istediğim gibi nasıl ayarlayabilirim. Örnek bir kod yazar mısınız? İllaki 555 entegre mi kullanmam gerekecek. Teşekkür ederim.

    • Ömer Koman dedi ki:

      murat polat 24hz ve %25 doluluk için zamanları hesaplayalım 24hz zaman olarak 1/24=0,0416 saniyede bir pals demek. mikrosaniyeye çevirirsek 0,0416 x 1000=41.66 mikrosaniye bir peryot etmesi lazım, %25 doluluk istiyorsunuz, (41.66 * 100) / 25= 10,41 mikrosaniye uzunluğunda 1 ve (41,66-10,41) 31,25 mikrosaniye boş 0 uzunlukta pals oluşturmak gerekiyor. siz yukarıdaki örnekde 10mikrosaniye 1 ve 30 mikrosaniye 0 olarak pwm sinyali oluşturusanız yaklaşık 24hz çıkış alırsınız.
      void loop(){
      digitalWrite(13, HIGH);
      delayMicroseconds(10);
      digitalWrite(13, LOW);
      delayMicroseconds(30);
      }

      //Edit: yukarıdaki kodu hatalı yazmışım, saniyeden zamana dönüşürken milisaniye hesapladık ama microsaniye olarak kullandık kodun içinde delayMicroseconds(x) yerine delay(x) kullanırsak doğru zamanlamayı elde etmiş oluyoruz. hata için kusura bakmayın oldu bir kere 😉

  19. murat polat dedi ki:

    Arduino megada 4 tane timer var sanırım.
    timer0=> pin 13,4
    timer1=> pin 12,11
    timer2=> pin 10,9
    timer3 => pin 5,3,2
    timer4 => pin 8,7,6

    TCCRnA , TCCRnB, WGM, CS, COMnA, COMnB ne anlama geliyor?
    hangi pinin yani timer adreslerinin min-max ne kadar frekans desteklediğini yazabilir misiniz?
    Kart üstünde 16 Mhz osilatör olduğundan bütün formüller sanırım buna göre yapılıyor.
    PWM frekansı = (16 000 000)/(Prescale_factor*256)
    prescale factor 1,8,64,256,1024 sanırım.Farklı değer alamıyor mu?

    Setting Prescale_factor
    TCCR0B = _BV(CS00); 1
    TCCR0B = _BV(CS01); 8
    TCCR0B = _BV(CS00) | _BV(CS01); 64
    TCCR0B = _BV(CS02); 256
    TCCR0B = _BV(CS00) | _BV(CS02); 1024

    yukarda TCCR0B demiş bu timer 0 kullanıldığını söylüyor sanırım.
    BV(CS00), BV(CS01) 1 ve 8 e bölüyor. Set Clock

    bir örnek vererek bu formülleri ve komutların ne işe yaradığını açıklayabilir misiniz?

  20. murat polat dedi ki:

    Ömer bey verdiğiniz örnek ile hesaplamalar doğru olsa bile gerçekte; 18.83 Khz ve %30 dolulukta bir sinyal alınıyor.
    http://playground.arduino.cc/Main/TimerPWMCheatsheet#.UxMOCM63vdY

    adresi incelemiştim ama yaptığım hesaplamalar bir şekilde tam uyumlu olmuyor. Diğer programlama dilleri ve programlayıcılar ile yapabiliyordum fakat arduino ile sıkıntı yaşadım. Arduinonun içine girdikçe kaynak bilgisi azalıyor sanırım 🙂 Yine de çok teşekkür ederim yardımlarınız için

    • Ömer Koman dedi ki:

      benim yöntem soft pwm anlatımı, arduinonun kendi pwm modülü ile deneme yapmam lazım. ama bu rutinde zamanlamaları ayarlamak çok kolay zaten, istediğin frekans çok zor değil biraz daha uzatırsan mikroseniyeleri istedğin değeri alırsın. arduinoda debuging olmaması kötü, böyle durumlarda kod performansı ve zamanlamaları kolay hesaplayamıyorsun.

  21. murat polat dedi ki:

    void loop(){
    digitalWrite(13, HIGH);
    delay(10);
    digitalWrite(13, LOW);
    delay(30);
    }

    mikroseconds cinsinden olmayacak. Bu şekilde yaptığım zaman 25 Hz %25 doluluk oranı elde edebildim. Fakat benim buradaki asıl amacım, yukarıda yazmış olduğum şekilde frekansın nasıl değiştirileceği, hangi kanal ne kadar frekans destekler nasıl ayarlanır onu yapmaktı. TCCRnA , TCCRnB, WGM, CS, COMnA, COMnB ne anlama geliyor? Burada TCCRnA demiş A kanalı için ama A kanalı dediğini çözemedim. Timerlarla yapılan CCP pwm olayını anlasaydım istediğimi kontrol ediyor olacaktım. Hazır modülde hiç bir ayar yapmadan sadece belli frekansları veriyor sanıyorum. Biz sadece delay() ya da delayMicroseconds ile bir yere kadar bunu yapabiliyoruz. PİC ile bunu yapabiliyordum fakat arduino ile nasıl yapıldığını anlayamadım. Aslında eminim çok kolaydır. Bütün mesele
    TCCR0B = _BV(CS00); 1
    TCCR0B = _BV(CS01); 8
    TCCR0B = _BV(CS00) | _BV(CS01); 64
    TCCR0B = _BV(CS02); 256
    TCCR0B = _BV(CS00) | _BV(CS02); 1024
    bu yazılanları anlamakta.

    • Ömer Koman dedi ki:

      murat benim yukarıdaki hesaplamamda hata vardı duzeltmeye vaktım olmadı bır edıt yapacağım, en başta saniyeden milisaniye dönerken sorun yok ama kodun içinde mikrosaniye kullanmışım kusura bakamayın. pic i iyi biliyorum pic de timerlara yuklenen öndeğerlerle istediğin frekansı ve interruptu yaptırmak mümkündü. atmelde bu işler daha iyi aslında biraz çalışıp örnek kod yazayım diyorum ezberden sallamayı sevmem biraz zaman alır ama. sen de birşeyler bulursan paylaş… kolay gelsin.

  22. murat polat dedi ki:

    Ömer Bey Çok Teşekkür ederim kendi adıma ve herkes adına, merakla bekliyor olacağım. Bende araştırıyor olacağım kendi halimde 🙂 Kolay gelsin size de duyarlılığınız için ve yardımlarınız için sağolun tekrardan.

  23. Kadir Şener dedi ki:

    Yazıyı okudum, elinizi gördüm ve gıcıklık konusunu 1 artırıyorum.
    Şakası bir yana DC motor hızını (yazıdaki LED ışık seviyesini) PC den verdiğim değişkenlere göre artırmak istiyorum. DK Electronics V1 kontrol kartım var. DC motor hız kontrolünü başardım fakat USB ile PC den canlı olarak yapamadım. İlacım nedir? hangi yazılara makalelere bakmalıyım?

  24. Ömer Koman dedi ki:

    ürünle ilgili kütüphaneleri kullanın ürünü aldığıunız yerde örnek isteyin yada test programları vardır oradan başlayın. bu yazıda pwm konusu anlatılmaya çalışıldı arduino içindeki pwm modülü kullanılmadı burada.

  25. abdullah dedi ki:

    hocam niçin 0-255 arası değer atıyoruz. 0-100 arası, 0-50 arası atasak olurmuydu bunu nedim led parlaklığı azalıyor, aralığı azalttığımızda

  26. Ömer Koman dedi ki:

    hem parlaklık suresini hem aydınlık suresini oranlamanız lazım sadece parlaklık suresini oynamak yetmez. toplam pals uzunluğu 100 (veya 50) olacaksa bunun içindeki kkaranlık ve aydınlık ksımların surelerini toplamı 100( veya 50) olmak zorunda.

  27. suat tuncer dedi ki:

    hocam merhabalar. ben arduino uno ile kare dalga yapmaya çalışıyorum da yaznız ben nekare dalganın neatif alternansını üretemiyorum. Bilindiği gibi arduino da -5 v veremiyoruz.bunu nasıl yapabilirim bununla ilgili bilgilerinizi paylaşabilir misiniz? Ya da varsa bir devresi yardımcı olabilir misiniz?

    • Ömer Koman dedi ki:

      +5v ve -5v veren bir powersuply yapman lazım yada sorduğuna göre biryerlerde -v olan bir kaynak olması lazım onları kullanacaksın kaynak yoksa eğer 10v luk bir trafodan diyotla doğrultup 2 tane kondansatör ve lm7805 ve lm7905 ile dual besleme yapacaksın. arduinoyu gnd +5v kısmından süreceksin, opamp beslemesinde +v kısmını 7805 kısmına ve -v kısmını ise 7905 e bağlayacaksın. arduino ile opampda gndler ortak olacak opamp buffer olarak bağlarsın opampın 2 girişi olur çeviren giriş ve çevirmeyen giriş opamp çıkışını çevirmeyen girişine bağlayacaksın. arduino pwm çıkışını da opamp çeviren kısmından bağlayacaksın opamp çıkışında gnd ile -5v arasında sinyalin belirdiğini göreceksin.

  28. yılmaz dedi ki:

    Ömer Bey bana yardımcı olurmusunzu benim hocam bana ödev verdi PWM ilgili soru :38 KHz ve duty cyclesi %65 PWM üreten arduino programı istiyor.
    13 nolu pinden çıkış verecek.
    Program satırını yazın dedi hoca kart olarak arduino mega 2560 olarak kullanılaçak yardımcı olursanız sevinirim….

  29. yusuf daşdemir dedi ki:

    ömer bey arduino ile asenkron motor sürücü yapmam gerekiyorda bu konuyla ilgilide fazla bir bilgiye sahip degilim bu konuda bana yardımcı olabilir misiniz?

  30. Ömer ERSOY dedi ki:

    Ömer Bey,
    Arduino Nano ve nRF24L01 kullanıyorum. nrf 3 pwm pinini, L298N sürücü ile 2 motor 2 pwm pinini ve geriye kalan 1 pwm pininede 1 adet servo ile kullanıyorum. Ama artı 4 servo daha eklemem gerekiyor. servolarda veya motorlarda(L298N) pwm işlevini görebilecek analog pinlerde kullanma imkanı var mı?
    Cevap verebilirsen çok sevinirim.

  31. Ergin dedi ki:

    iyi günler ömer bey yukarıdaki pot ile pwm sinyalinin frekansını ayarlama kodunu inceledim ben pwm sinyali uretmek istiyorum yuksek frekaslı en fazla kac mhz da çalışabilirim yukarıdaki pot ile ilğili kodu yazıp 0 ili 10 mhz arasında frekansı değişen bir pwm sinyal elde edebilirmiyim hangi ardunio kullanmam lazım kolay gelsin cok teşekkürler.

  32. Ömer Koman dedi ki:

    iki yontem var yazımdaki gibi arduino pinlerinden birini hi lo yaparak bir frekansa elde edilebilir 16mhz clockda yaklaşık 2mhz kod işleme hızı elde edilir ama arduno core bu kadarına izin vermez 1mhz hıza ancak çıkar.

    dahili pwm le değişik modları deneyerek 32khz veya 62.5khz civarı çıkış alabılırsın. daha fazlasını denemedim.

    şu linklere bir bakın
    https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM
    http://playground.arduino.cc/Code/PwmFrequency

  33. QeuS dedi ki:

    Ömer hocam öncelikle paylaşımlarınız için teşekkür ederim. Size bir sorum olacak bu noktada. Piyasada bulunan freescale işlemcilere de bu yöntem uygulanabilir mi? yani digital output olan bir pini pwm çıkışı olarak bu şekilde yazılım olarak çözebilir miyiz? Teşekkürler…

    • Ömer Koman dedi ki:

      mantık olarak uygulayabilirsiniz evet kod olarak biraz değişik olabilir. softpwm diye aratın kullandığınız işlemci için birşeyler bulabilirsiniz.
      genelde bir frekans ve sinyalin doluluk oranıdır söz konusu olan, frekanstan kasıt %50 high ve %50 low durumda çıkıştaki frekans kastedilir, bunu elde etikten sonra bu toplam sureyi bozmadan high low oranlarını ayarlayarak pwm sinyali elde edersiniz. frekans için işlemcinin adım hızını bilmeniz lazım. birde işlemcide timer kurup kesme anlarında high low durumunu kontrol edebilirsiniz, o konuyu burada anlatmadım daha…

  34. ece dedi ki:

    Merhaba.
    Stajda yapmam için bir proje verildi. arduino kullanarak butonla motoru kontrol etmem gerek. Bunun için üç butuna ihtiyacım var. Birisi ileri birisi geri birisi de stop butonu. Motorun butonuna bastığımda yol alması lazım. Bu motor mekanik bir kolu hareket ettirecek. Bu mekanik kol motorla ileri yönde sürülürken ileri noktaya bi switch konumlandırılacak ve switch e değen kol duracak. Aynısı geri konumunda da olacak. stop butonu ise kolu istediğim noktada durdurabilmek için. Yani switchlere gelmeden durmasını sağlamak.
    Arduino da çok yeniyim ve pek işin altından kalkamıyorum. Yaardımcı olabilir misiniz acaba? Teşekkürler.

    • Ömer Koman dedi ki:

      foruma gelin daha hızlı ve fazla kişi size yönlendirme yapabilir, hazır kodu pek bulamayacaksınız ama siz başlayın takıldığınız yerlerde hatanızı duzeltirler.

  35. sefa dedi ki:

    ömer bey kolay gelsin biz balık yemleme makinesi yapıyoruzda programda keypadla bir sayı girilecek farzedelim ben 10 dakikada bir yemleme yapmasını istiyorum bu dakikaya göre servo motoru çalıştırıp yemlemeyi yapacak bu projenin yazılımını bir türlü yapamadık bize yardımcı olursanız çok sevinirim…

    • Ömer Koman dedi ki:

      milis fonksiyonu işinizi görmesi lazım.
      milis fonkisyonu arduino ilk açıldıgından ıtıbaren geçen zamanı sayar.
      ilk başta zaman1=milis değerini setup kısmında saklayın
      daha sonra loop ıcınde zaman1 değerini milis fonkiyonundan gelen değerle devamlı karşılaştırın 10dk içinde 100bin milisaniye var milis-zaman1>= 100bin oldugunda motoru çalıştırın ve zaman1=milis değerini yeniden saklayın bu şekilde bir çok zamanlama işlemi yapabilirsiniz. foruma da gelin…

  36. sefa dedi ki:

    sagolun hocam bu konuyu anladım ama bnim bu degeri keypadla girmem lazım onun için ne yapmalıyım

  37. erdinç dedi ki:

    ömer bey benim elimde 12 dc girişle çalışan 10 amperlik güç kartım var, üzerindeki potansiyometerle çıkış değerini 0 dan 12 volta kadar manuel ayar yapıyorum sorunum şu bu kart oransal bir bobini çalıştırıyor bobinde 6 7 amper civarı güç çekiyor kart çıkışımı 2.8 volt üzerindne çalıştırıyorumki bobin belli bi noktaya çekirdeği çeksin ve orda kalsın valfi kısmak amaçlı yani sonrası 1.2 saniye sonra zaman rolesi vasıtasıyla 12 volt direk bobine veriyorum valf tam kapatıyor ben nasıl kendi kartımıda kullanıp arduin kartıyla manuel potansiyometre yerine saniye/volt yapabilirmiyim yazılımsal kısaca 2 volt başlangıçım olacak 12 volta ulaşana kadar otomatik 1.2 saniyeye bölebilirm rampalı olarak

    • Ömer Koman dedi ki:

      arduino standart pwm ile 0-255 arasında değerleri vererek 0-5v uretebilirsiniz ama bunu bir transitorle surmenız gerekır gerekli akımı cekecek uygun bir malzeme seçmenız lazım. bu değişimi yazlımla veya adc pinine bağlı bir potla ayarlayabilirsiniz. diğer teknık konular yazının konusunu bozacak foruma gelin.

E-posta adresiniz gösterilmeyecek. Gerekli alanlar * ile işaretlidir.

*



Sosyal Ağlar