Arduino UNO R3 ile temel projeler

malazgirt

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
118
Atmel'in Atmega 328P işlemcisini kullanan Arduino UNO R3 ve bu karta uygun bir de LCD tuş takımı ve ekran modülünü (LCD Keypad Shield) sipariş etmiştim. Ayrıca daha sonra başlamayı düşündüğüm, alarm sistemleri için darbe sensörü projesi için de bir Adafruit Pro Trinket kartlarını sipariş etmiştim, İkisi de elime ulaştı.

scaled_20180403_230107.jpg


Trinket'i bir kenara koyuyoruz ve UNO R3'e daha yakından bakalım. Bu kartın Çin malı ucuz klonları da var, ama ben orijinalini almayı tercih ettim. Sayısız Çin malı klonlar arasında olabilecek ufak tefek farklardan dolayı yaptığımız deneylerde farklı sonuçlar alınabilir, o yüzden kendi açımdan ne olduğu tam olarak bilinen ve iyi dokümantasyona sahip olan orijinal UNO R3 ile çalışmanın daha mantıklı olduğunu düşünüyorum. Ama bu sizin de mutlaka orijinal UNO R3 kullanmanız gerektiği anlamına gelmez. İstediğiniz çeşidini kullanabilirsiniz, ama orijinal UNO R3'e göre farklılıklarını bilerek yaparsanız herhangi bir sürpriz ile karşılaşmamış olursunuz.

UNO R3'e yakından bakalım:

scaled_20180403_230237.jpg


scaled_20180403_230249.jpg
 
UNO R3 kartının şeması ekte. Arduino'nun en yaygın kullanılış biçimi, Arduino IDE denen ve PC'de çalışan bir yazılımla, küçük program parçaları geliştirmek. Sonra da bu program parçalarını Arduino üzerindeki mikrokontroller'a (Atmega 328P-PU) transfer edip çalıştırmak. Atmega328'in üzerinde, fabrikada programlanmış olan bir firmware var. Bizim yazdığımız program parçaları, bu firmware'in kontrolü altında işlemcinin dahili belleğine transfer edilmektedir ve sonra da bu firmware'in kontrolü altında çalıştırılmaktadır. Yani bizim yazacağımız programlar, %100 olarak Atmega328'e hakim değildir, mevcut firmware'in bir alt programı gibidir.

Eğer Atmega328 işlemcisine %100 hakim bir firmware geliştirmek istersek, Arduino IDE'yi kullanamayız. Onun yerine, "Atmel Studio" yazılımı ile direkt olarak C/C++ veya assembly dilinde firmware geliştirip sonra da bir çip programlayıcı ile Atmega'nın firmware'ini silip bizim yeni firmware'i yerine yazmamız lazım. Bu da ilerisi için planladığım projelerden birisidir.
 

Ekler

  • Arduino_Uno_Rev3-schematic.pdf
    81.4 KB · Görüntüleme: 555
İnternette Arduino programlama ile ilgili araştırma yaptığımızda, en yaygın kullanılan başlangıç projeleri, bir LED'nin blink edilmesi, bir butona basılınca LED'nin yakılması veya durum değiştirmesi gibi şeylerdir. Bu kadar hazır materyal varken, benim de burada tekrar bir blink kodu yazdırmam anlamsız olur diye düşünüyorum. Onun yerine, birçok temel konuyu kapsayan ve pratikte de kullanılabilecek kapsamlı bir proje yapacağız.

Proje, 8 haneli bir kronometre. Çözünürlüğü şimdilik 0.1 saniye olarak belirliyoruz. Sonradan bunu artırmak için de çaba göstereceğiz ve ne tür zorluklar çıkacağını göreceğiz. Bir tane başlat butonu olacak, bir tane durdur butonu, bir tane de sıfırlama butonu. Bu projenin yapımı, hem temel dijital elektronik bilgisi gerektiriyor, hem de programlama ile ilgili bazı temel tekniklerin kullanımını gerektiriyor:

- Arduino'da, 8 tane 7 segment display sürecek kadar port yoktur. Her bir haneye BCD dekoder koymuş olsak bile, bunun için de gene yeterince port yok. O halde, hanelere tek tek, çok hızlı bir şekilde tarayarak rakamları yazdırmamız gerekecek. Eğer yeterince fazla sayıda tarama yapabilirsek, kullanıcı herhangi bir titreme görmeden sayaçtaki rakamı rahatlıkla okuyabilecek.

- Kronometreyi başlatmak/durdurmak için Arduino üzerinde mekanik butonlar kullanacağız. Ama bu butonlara basıldığında oluşan parazitik etkiler nedeniyle, buton birden fazla basılmış gibi bir etki ortaya çıkacak. Bunu uygun bir yazılımla engellememiz gerekecek.

- Kronometrenin doğru sayması için, bizim yazılımın hassas olarak 0.1 saniyede bir kontrolü ele alması lazım ve sayaç değerini güncellemesi lazım. Eğer burada bir değişkenlik varsa, bizim kronometre, gerçek bir kronometreye göre ya yavaş kalacaktır, yada fazla hızlı olacak.
 
Muhtemelen internette araştırırsanız, Arduino için hazır kronometre programları da bulunabilir. Ama burada bizim için önemli olan, başkasının yazdığı hazır kodu alıp körü körüne kullanmak değil. O yazan kişi, yukarıda bahsettiğimiz sorunların hepsine bir çözüm getirmiş ve kodu yazmış, işi öğrenmiş. Bizim de aynı sorunlarla boğuşup, çözümü kendimiz bulmamız lazım. Ancak bu şekilde birşeyler öğrenmiş oluruz.

Diyeceksiniz ki "tekerleği yeniden icat etmeye ne gerek var? Adam yapmış, al kullan!". İşte, bizi millet olarak onlarca yıl böyle uyuttular. Bizler millet olarak ne zaman özgün birşeyler yapmaya kalksak, hemen devreye girdiler: "ya ne gerek var bununla uğraşıyorsunuz. Biz size çok ucuza verelim!". Ve böylelikle de çok az şeyi derinlemesine öğrenebildik, hep onlara muhtaç kaldık. Tekerleği yeniden icat edeceğiz kardeşim! O tekerleğin en ince detayına kadar nasıl çalıştığını öğrenmenin tek yolu bu. Çünkü gün gelecek, o tekerlek bize en çok lazım olduğu anda, adamlar bize satmayacaklar. Biz de o zaman tekerleği çaresiz yeniden icat etmek zorunda kalacağız, ama iş işten geçmiş olacak.
 
Projenin en önemli tarafı, belirlenmiş zaman aralıklarında, aşağıdaki iki işi yapmak:

1) kronometrenin zaman sayaçlarını güncellemek. kronometre çözünürlüğünü daha önce 0.1 saniye olarak belirlemiştik. Yani saniyede 10 defa, kronometrenin zaman sayacını artırmamız lazım.

2) 7 segment displayleri, titreme olmayacak kadar hızlı bir şekilde güncellemek. Bunun için displayleri en az saniyede 50 defa güncellemeyi deneyeceğiz. Eğer titreme oluyorsa, güncelleme frekansını artırmayı deneyeceğiz.

Her iki işi yapmak için arduino'da ayrı ayrı zamanlayıcılar tanımlayabiliriz, ve her bir zamanlayıcı da tanımlanan aralıklarla bizim yazdığımız bir fonksiyonu çağırır. Bu tip fonksiyonlara "kesme" deniyor, çünkü bunlar programın normal akışını "kesip" belli bir işi yapıyor, sonra da program, kesildiği yerden devam ediyor.

Bir kesme, kronometre sayacını artırır, diğer kesme de 7 segment display'leri günceller. Veya, saniyede 50 defa çalışan bir tek kesme tanımlarız ve bu kesme her çağırıldığında 7 segmentleri günceller, 5 çağırmada bir de kronometre sayacını günceller. Sistemin basit olması açısından, tek kesme kullanmak daha iyidir, çünkü bağımsız çalışan birden fazla kesme olması durumunda, bu kesmelerin birbirine göre öncelikleri farklı olacaktır ve yüksek öncelikli bir kesme, düşük öncelikli bir kesmeyi de "kesecektir". Ayrıca program karmaşıklaşacak, problem ayıklamak daha zor olacak, ve her kesmenin de bir işlem zamanı maliyeti olduğundan ekstrem durumlarda zamanlama sorunları yaşayabileceğiz.
 
Öncelikle konsepti kanıtlamak açısından aşağıdaki basit programı yazalım. Bu program, saniyede 100 kere çağırılan bir kesme fonksiyonu tanımlıyor. Tanımlanan kesme fonksiyonu da, arduino'nun 12'nci pininde bir pulse üretiyor:

Kod:
/* tanimladigimiz kesme fonksiyonunun saniyede kac defa
   cagirilacagini belirleyen degisken */
int isr_rate = 100;

void setup()
{
  /* 12 numarali pini cikis olarak tanimliyoruz */
  pinMode(12, OUTPUT);

  /* Atmel 328 in birinci timer'ini kesme kaynagi
     olarak yapilandiriyoruz */
  TCCR1A = 0;
  TCNT1 = 0;
  OCR1A = 16000000 / (isr_rate * 64) - 1;
  TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
}

ISR(TIMER1_COMPA_vect)
{
  /* daha once cikis olarak tanimladigimiz 12 numarali pin'de,
     osiloskop'ta kesmenin olusumunu gozlemlemek icin bir pulse uretiyoruz */
  digitalWrite(12, 1);
  delayMicroseconds(100);
  digitalWrite(12, 0);
}

void loop()
{
  /* ana programda hicbir sey yapmiyoruz, sadece tanimladigimiz
     kesme fonksiyonu belirli araliklarla cagiriliyor */
}
 
Burada Atmel 328'in timer'ini nasıl yapılandırdım? Bunun için bu işlemcinin datasheet'ini inceledim. Burada kullanılan timer, 16 bitlik bir sayaca sahip. Bu sayacın hangi frekanstaki bir clock ile çalıştıracağımızı belirliyoruz. Sonra sayaç hangi değere ulaştığında kesme üretecek onu belirliyoruz. Bunları yaptıktan sonra sayacı aktif hale getiriyoruz.

Konu ile ilgili epey detay var, o yüzden datasheet'i incelemenizi tavsiye ederim:

https://playground.arduino.cc/Main/ArduinoCoreHardware

Ama netice itibarı ile, timer'i yapılandırdıktan sonra, bizim tanımladığımız kesme fonksiyonu, belirlediğimiz sıklıkta (saniyede 100 defa) çağırılmaya başlıyor. Sonraki aşama, saniyede 100 defa çağırılan bu kesme fonksiyonunda, hem 7 segment displayleri güncellemek, hem de 10 kesmede bir, kronometre sayacını artırmak.
 
Kesme tarafından üretilen pulse'ları osiloskop ile doğruluyoruz

scaled_20180608_235759.jpg


isr_calling.png
 
Arduino İle Max7219 ikilisini kullanmaya çalıştım ama netteki projeleri görüntüleyemiyorum. Çünkü önüne gelen arduinoya özel hazırlanmış 8 digit hazır entegreleri kullanmış. Ben ise 4 digit kullandım. Kodları biraz kurcaladım ama ortaya birşey çıkaramadım.
20200610_163722.jpg
 
İlk önce portlara direkt olarak yazarak ekrana birşey çıkarmaya çalış, bu sana entegrenin çalışma mantığını öğretecek. Sonra seri veri yazmaya yarayan bazı kütüphaneler vardır (spesifik kütüphane bilmiyorum, kullanmadım), onlardan birisi ile yazma işini yapabilirsin.
 
Selamlar,
Simdi entegreyi inceledim. SPI yani shift register sureceksin aslinda cok basit.
Shift register surmek icin 74HC595 surme mantigini incelersen hemen anlayacabilecegini dusunuyorum.
Eger sifirdan yazmak istemiyorsan arduinoda shiftout diye bir sey olmasi lazim onu kullanabilirsin.
Bu arada duzgun calisan bir MAX7219 kutuphanesi bulamadin mi ?

1591826314841.png
 
Selamlar,
Simdi entegreyi inceledim. SPI yani shift register sureceksin aslinda cok basit.
Shift register surmek icin 74HC595 surme mantigini incelersen hemen anlayacabilecegini dusunuyorum.
Eger sifirdan yazmak istemiyorsan arduinoda shiftout diye bir sey olmasi lazim onu kullanabilirsin.
Bu arada duzgun calisan bir MAX7219 kutuphanesi bulamadin mi ?

4145 eklentisine bak
Yarın inceleyeyim.
Arduino kütüphane yöneticisi içinde Max7219 için 3 tane örnek devre var. Ama sanırım benim beceriksizliğimden (yada displayin 8 digit olmamasından) kayda değer bir görüntü alamadım. Sadece Segmentler abuk subuk şekillerde yanıp yanıp söndü. Nettede bir kaçkod buldum ama onlardan da sonuç alamadım. Tamamen benim bilgisizliğimden kaynaklanıyor. biraz kurcalarsam doğru yolu bulurum diye düşünüyorum.
arduino led.png


arduino led1.png
 

Çevrimiçi personel

Forum istatistikleri

Konular
6,955
Mesajlar
118,793
Üyeler
2,824
Son üye
selocan32

Son kaynaklar

Son profil mesajları

hakan8470 wrote on Dede's profile.
1717172721760.png
Dedecim bu gul mu karanfil mi? Gerci ne farkeder onu da anlamam. Gerci bunun anlamini da bilmem :gulus2:
Lyewor_ wrote on hakan8470's profile.
Takip edilmeye başlanmışım :D ❤️
Merhaba elektronik tutsakları...
Lyewor_ wrote on taydin's profile.
Merhabalar. Elektrik laboratuvarınız varsa bunun hakkında bir konunuz var mı acaba? Sizin laboratuvarınızı merak ettim de :)
Lyewor_ wrote on taydin's profile.
Merhabalar forumda yeniyim! Bir sorum olacaktı lcr meterler hakkında. Hem bobini ölçen hemde bobin direnci ölçen bir lcr meter var mı acaba?
Back
Top