Arduino'dan sonra...

Arduino'dan sonra...

Bugün neler yaptığımı anlatayım...

Önce nette bolca bulunan sayfalardan birinden aldığım bağlantı şemasını Arduino Uno ve bir adet ATTiny85 ile uyguladım. ( )
Sonra Arduino IDE üzerinden gerekli ayarlamaları yaparak ATTiny85'e 8 MHz internal clock ile çalışması için gereken bootloaderi yazdırdım (ki bu aslında sadece bir registeri değiştiriyor).
Sonra daha önce ATMega328 üzerinde test etmiş ve ATTiny85'e uyarlamış olduğum servo programını Arduino'yu ISP (In System Programmer) olarak kullanıp ATTiny85'e yükledim.
Breadboard üzerinde hemen ekteki şemayı uyguladım ve pili taktım.
Bir butona bastıkça servo bir yöne diğerine bastıkça diğer yöne dönüyor. İkisine birden basarsam hiçbir şey olmuyor. Basit bir servo tester kısaca. Ama bence en önemli nokta interrupt kullanıyor oluşu.

ATTiny85'in TIMER1'ini kullanıyorum. Gerekli ayarlar setup'tan çağrılan initTimerCounter() işlevinde gerekli register bitleri ayarlanarak yapılıyor. 8 MHz sistem saati 1024'e bölüncek şekilde ayarlı. Timer bunu sayıp 156 olduğunda bir interrupt oluşturuyor. Yani ana loopta ne yapıyorsak yapalım (interruptları kapatmadığımız sürece) her 20 milisaniyede bir interrupt geliyor ve bu interrupt sonrası sistem hazırda bekleyen pwm değeri boyutunda bir darbeyi servoya gönderiyor.
Ana loopta ise tuşlar kontrol edilip pwm değeri değiştiriliyor. Interruptta kullanılan tüm değişkenler volatile olarak tanımlı.

Breadboard şeması bu:

[attachimg=1]

Kullanılan kod da bu:

Kod:
const int servopin = 0;
const int uppin = 3;
const int downpin = 4;
int up = 1;
int down = 1;
volatile unsigned int x = 0;
volatile unsigned long timer;
volatile unsigned int pwm = 1500;


void setup()
{
  pinMode(servopin, OUTPUT);
  initTimerCounter();
}

void loop()
{
  up = digitalRead(uppin);
  down = digitalRead(downpin);
  if (up != down)
  {
    delay(1);
    up = digitalRead(uppin);
    down = digitalRead(downpin);
    if (up != down)
    {
      if (up == 0)
      {
        pwm = pwm + 1;
      }
      else
      {
        pwm = pwm - 1;
      }
      if (pwm < 1000)
      {
        pwm = 1000;
      }
      if (pwm > 2000)
      {
        pwm = 2000;
      }
    }
  }
}



ISR(TIMER1_COMPA_vect)
{
  timer = micros();
  digitalWrite(servopin, HIGH);
  while ((micros() - timer) < pwm)
  {
  }
  digitalWrite(servopin, LOW);
}


void initTimerCounter() {    // initialize Timer1
  noInterrupts();  // disable global interrupts

  PLLCSR = 0; //

  TCCR1 = 0;  // set all bits in TCCR1 register to 0

  TCCR1 |= (1 << CTC1); //CTC Mode enabled

  // prescaler 1024
  TCCR1 |= (1 << CS10);
  TCCR1 |= (1 << CS11);
  TCCR1 |= (0 << CS12);
  TCCR1 |= (1 << CS13);

  GTCCR |= (1 << PSR1); // reset Timer/Counter prescaler

  TCNT1 = 0; // Zero (Reset) Timer1 8-bit up counter value

  OCR1A = 156; //156 periyot * 128 us = 20 mS

  TIMSK |= (1 << OCIE1A); // enable Timer1 compare A interrupt

  interrupts(); // enable global interrupts
}

Anlatmaya çalıştığım şey, "bakın ben ne acayip programlar yazıyomm" değil. TCNT1, OCR1A, TIMSK, ACIE1A... Önce Mars dili gibi gelen bu ifadeleri, okuyup deneyerek anlayabiliyor olmanın verdiği keyfi anlatmak istiyorum. Muhtemelen Servo Library benzer bir iş yapıyordur ama bunu kendi ürettiğim çözüm ve kodla başarınca sistemi çok daha yakından tanımış oluyorum. Bütün derdim de bu işte. :D
 

Ekli dosyalar

  • pic0001_001.jpg
    pic0001_001.jpg
    41.1 KB · Görülme: 57
Arduino'dan sonra...

Valla Ben hazir library bile uzak durmaya calisirken sen masallah abi aldin yolu gidiyorsun. Seni cok net anliyoruz Abi. Dedigin gibi hedefe varmak degil esas zevk, yolda yurumek :bravo: %p her ne kadar bu yolda Sana eslik edemesekte sahsen senin yuruyusunu seyretmek benim icin buyuk bir keyf :halay:
 
Arduino'dan sonra...

Sümer Yamaner' Alıntı:
Sizi de fişekleyebilsem... :)
Abi başımızda yeterince bela olmasa hic durmayıp ben de dalacağım ama buna da bulasirsam, hanim kesin kovacak beni :) :) :)


Sent from my iPhone using Tapatalk
 
Arduino'dan sonra...


Sümer Yamaner' Alıntı:
Hanımlar bu tür risksiz uğraşılara bişii demez.
Doğru diyorsun da abi saatlerce Pc başında oturmaktan da cok haz etmiyorlar :) :)


Sent from my iPhone using Tapatalk
 
Arduino'dan sonra...

Sümer Yamaner' Alıntı:
Abi bari delay komutunu değiştirip frekansı ile oyna. :D :p

Örneğin 5V ile 0V arasına bir potansiyometre bağla. Orta ucu bir analog girişten okut. Oradan elde edeceğin 0 - 1023 arasındaki değeri scale ederek delay komutunun parametresi olarak kullan. Böylece potansiyometre ile yanıp sönme hızını değiştirebileceğin bir ileri aşama sistemin olsun. Ondan sonra zaten kendiliğinden gelir gerisi. Örneğin potansiyometre ile frekansı değil duty cycle'ı yani yanık kalma oranını değiştirebilirsin. Sonra bunu çok hızlandırıp software pwm yapmış olursun. Her bir adımda aklına binbir yeni şey gelir. Onları yaparsın.

Valla Sümer bey, şu sıralar başımda başka dertler olduğundan pek kafa yoramıyorum. :( Yoksa arkasının geleceğini biliyorum!

Mehmet Kucuksari' Alıntı:
Abi başımızda yeterince bela olmasa hic durmayıp ben de dalacağım ama buna da bulasirsam, hanim kesin kovacak beni :) :) :)

Nihayet ilk geri bildirim geldi! Ben de bu sözü ne zaman duyacağım bakalım diyordum! Hani, ismi lazım değil, bazılarının hanımı anlayışlıymış ya!... :lollol: