red etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
red etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

20 Nisan 2018 Cuma

P10 Led Panel ile Real Time Clock Olmadan Gerçek Saat Uygulaması

P10 Led Panel ile Real Time Clock olmadan gerçek saat uygulaması ve bunun yanı sıra ek bazı uygulamalar:

Ofisten bir arkadaşımızın 15 yaşındaki yeğeni haylaz Efe için ufak bir eğlencelik uygulama yapmak istedim.
Efe'nin yaşı küçük ve bu tür işlere de çok meraklı olmadığını düşünerek Visual Studio 2015 Community Edition ile ufak bir C# uygulaması yapmanın daha uygun olacağını düşündüm.

EfeLedPanel isimli bu ufak uygulamanın arayüzü aşağıdaki şekilde. Bu mini uygulama ile arayüzden yapılan seçimlere göre otomatik olarak arka tarafta arduino'nun anlayacağı Ansi C kodlarını oluışturup efeledpanel.ino adında bir arduino proje dosyası oluşturuyoruz. Standart arduino ide kurulumunun komut satırı özelliklerini kullarak ta oluşturduğumuz bu arduino projesini derliyor ve ardından da arduino içine gönderiyoruz.



Aslında konumuz bu proje değil. Bu ufak C# projesi içindeki seçeneklerin en altındaki RTC olmadan saat uygulaması adıyla belirttiğimiz seçeneğin yaptığı işlem. (RTC'nin açılımı bildiğiniz gibi Real Time Clock. Yani Gerçek Zaman Saati. sanırım bunun meali her şartta zaman şaşmadan devam eder anlamında olmalı)

Normal şartlar altında bütün elektronik saatlerde bir pil bağlantısı bulunur:

  • Evinizde kullandığınız desktop bilgisayarınızın içinde bilgisayarınız kapalıyken veya enerji fişi takılı değilken zaman kavramını unutmaması için içindeki RTC devresini besleyen ufak bir pil vardır.
  • Aynı şekilde kullandığınız notebook, laptop, tablet, cep telefonu gibi cihazlarda da kendi ana bataryasının haricinde içinde ilaveten ufacık bir pil (PC, Laptop gibi bilgisayarlarda CR2032 gibi bir pil bağlantısı bulunur. Diğer cihazlarda ise cihazın boyutuna göre bu veya daha küçük bir "düğme pil" denilen ufak pillerden) bulunur.
  • Haricen gördüğünüz duvara asılan, devasa reklam tabelalarında vb. yerlerde kullanılan saat uygulamalarında da aynı şekilde enerji kesilmesi durumunda içindeki ufak RTC devresini besleyerek içindeki saatin ilerlemesini sağlayan bir düğme pil vardır.
Bu bahsettiğimiz pil bulunmazsa ne olur? ilk elektrik kesintisinde saati olan o cihazın saati sıfırlanır. Doğru, güncel saati göstermez hale gelir. Örneğin evde kullandığımız fırının bir saati var. Her elektrik kesintisinde 00:00 şeklinde yanıp sönmeye başlar. Sebebi fırının içindeki saat devresinde muhtemelen maliyeti ucuzlatmak için bir RTC devresi olmaması. (aslında çok ta meşhur bir marka ama sanırım hepsi aynı şeyi yapıyor) :)

Biz de Arduino ile RTC devresi olmadan ve ilave bir pil, batarya desteği olmadan saat nasıl yapabiliriz dersek, onun cevabı da aslında verdiğim son fırın örneğindeki gibi olur. Enerji varken çalışır, enerji kesildiğinde sıfırlanır. Bunun zaten teknik olarak başka bir işleyişi yok. :)

Bizim uygulamamızda arduino PC'ye takılı iken RTC olmadan saat uygulaması seçeneği seçiliyken Metni Panele Gönder butonuna basarak (bu butonun ismi Arduino'ya Gönder olsa daha uygun olacakmış aslında) bilgisayarımızda o andaki aktif saat dakika ve saniye bilgisini alıp o anda otomatik olarak oluşturduğumuz arduino kodunun içine başlangıç saati olarak yazıyoruz.

Oluşturduğumuz bu arduino kodunu Arduino IDE'nin commandline kullanımı ile derleyip arduino içine gönderiyoruz. o andan itibaren arduino cihazımızı çalışmasını istediğimiz yere götürüp enerji verdiğimiz anda set ettiğimiz güncel saatten başlayarak çalışacaktır. Eğer enerjisini hiç kesmezsek yıllarca bu şekilde çalışmaya devam edebilir. Ancak bir şekilde enerjisini kesip tekrar verirsek ilk set ettiğimiz saate geri döner. Enerjisini kesip yeniden vermemiz gereken durumlarda arduino cihazımızı bilgisayarımıza bağlayıp C# programımız ile arduino içindeki başlangıç saatini güncellememiz gerekecektir.

İşleyişimiz nasıl? Tahmin ettiğiniz gibi: arduino'nun loop döngüsü içinde saniye bazlı tuttuğumuz bir zaman sayacını sürekli olarak arttırıp P10 Led panellere basacağımız noktada yeniden saat dakika saniye cinsine cevirip 0 ile padding yaptıktan sonra panele gönderiyoruz. Her loop sonunda da 1000 milisaniyelik bir bekleme ile işleyişin saat kavramına uygun şekilde ilerlemesini sağlamış oluyoruz.

Tam bu noktada ufak bir kalibrasyon ayarı yapmak gerekebilir diye bir not düşmemde fayda olacaktır. Zira loop döngüsünün içindeki kodun işlediği süreyi en sona koyduğumuz 1000 milisaniyelik beklemeden çıkarmak saatimizin geri kalmasını önleyecektir.

Bu yazıda bahsettiğimiz şeylerin hepsini şu linkteki C# kodumuzda bulabilirsiniz:
EfeLedPanel_Arduino_Kodunu_Hazirlayan_C#_Uygulamasi.rar

8 Nisan 2018 Pazar

P10 LED Panelleri Arduino ile Kullanmak

Bismillahirrahmanirrahim.

Her hayırlı işe Besmele ile başlamak gerek malum. Biz de hayr murad ederek geç te olsa başladık bu blog işine. Ne diyelim; bana da, takip edenlere de hayırlı olsun o halde. Yıllardır aklımın bir köşesinde sürekli uğraştığım konularla ilgili böyle bir çalışma yapmak vardı. Artık üşengeçlik mi, tembellik mi dersiniz adına bilmem, fakat baktım da bu blogu bile 9 sene önce, 2009 da register etmişim. Yani niyetim halis, tembelliğim gerçek. :)

8 Nisan 2018 (ürün fiyatları, güncel kalması için bu tarihteki TL fiyatlarından USD'ye çevrilerek yazılmıştır)
Sözü fazla uzatmadan ilk yazımız olan, bugünlerde ilgilendiğim LED tabelalara getireyim konuyu. Son yıllarda oldukça yaygınlaşan led tabelaların yaygınlaşmasında ilerleyen teknoloji, gömülü yazılımlardaki gelişmeler epey etkili olmuş durumda. LEGO tarzı yapılan, istenildiği şekilde genişletilebilen blok panel tabela sistemi ile de sanırım zirveye ulaşmış oldu.

Nedir bu LEGO tarzı blok panel led tabelalar? 16x32, 32x32, 64x64 vb. gibi farklı matris boyutlarında üretilen hazır led panellerdir. En çok kullanılan 16x32 lik paneli örnek olarak ele alacak olursak; bu sayılar şunu ifade etmektedir: 16cm yüksekliğinde, 32cm genişliğinde fiziksel ölçülere sahip bir led paneldir. Led panellerin isimlendirmeleri ise her 1 santimetrekare içine düşen led sayısına orantılanarak verilmiştir. Örneğimizdeki 16x32 led panelin tip ismi P10 olarak geçiyorsa her 10mm de 1 adet led gelecek şekilde yerleşimi olan bir led matris paneldir. Yani 16x32x(10/10)=512 adet led vardır örneğimizdeki P10 panelde. Eğer aynı panelin tip ismi P5 olursa bu da her 5mm de 1 adet led gelecek şekilde yerleşimi olan bir led matris paneldir. Yani 16x32x(10/5)=1024 adet led vardır örneğimizdeki P5 panelde. LED panellerin kırmızı, yeşil, mavi, beyaz, sarı gibi tek renkli modelleri olduğu gibi, RGB led paneller de mevcuttur. Bu tip rgb panelleri şehir meydanlarındaki dev ekranlarda görebilirsiniz. Her bir led bir piksele karşılık gelmektedir. Bu mantıkla oluşturulan görüntü bu panellerin yönetimi için oluşturulmuş özel kontrol kartları veya kendi yapacağımız bir ARM, PIC, Arduino veya benzer bir mikroişlemci devresi ve yazılımı ile de mümkündür.

Pratiğe gelecek olursak... :)
Ankara Konya sokaktan 30 TL'ye, internetten 20-30 TL (4.94$) arasına bulabileceğiniz bir P10 LED Panel başlangıç için doğru bir tercih olacaktır.

Örnek bir çalışma için gerekli temel malzemeler:
  • bir adet P10 kırmızı renk led panel (kırmızı en uygun fiyatlısıdır) [4.94$]
  • bir adet Arduino UNO + USB Kablosu [4.45$]
  • bir adet 5 volt, 5 amper (veya üzeri) DC güç kaynağı [5v 10a için 5.44$]

Practical Arduino kitabının yazarı Jonathan Oxer ve Marc Alexander tarafından oluşturulan ve açık kaynak kod ilkesiyle yayın yapan Freetronics sitesinde bulunan Arduino DMD kütüphanesini kullanacağız:

http://www.freetronics.com/dmd-library
https://github.com/freetronics/dmd
linklerindeki "Clone or download zip" adlı yeşil renkli buton ile DMD-master.zip dosyasi indirilir.
Aynı kütüphanenin 3.parti ek geliştirmeler görmüş hali: https://github.com/cjd/DMD

Arduino IDE'deki Taslak > library ekle > .ZIP Kitaplığı Ekle
menülerinden indirilen zip dosya arduino ide'ye eklenir.

Freetronics'in DMD kütüphanesi içinde kullanılan TimerOne kütüphanesini de indirmek gerekiyor:
https://code.google.com/archive/p/arduino-timerone/downloads
linklerinden TimerOne-r11.zip kutuphanesi indirilir.

Eklediğiniz library dosyalarını Arduino IDE'deki Taslak > library ekle
menusunden kontrol edin. DMD-master ve TimerOne-r11 i görmelisiniz.

https://www.freetronics.com.au/products/dot-matrix-display-32x16-red
https://www.freetronics.com.au/pages/using-your-freetronics-dmd
Linklerinde de ufak örnek uygulamalar mevcut.

P10 panel ile Arduino UNO arasında pratik bağlantı için Freetronics'in geliştirdiği ufak bir PCB var:
https://github.com/freetronics/DMDCon

Aşağıda Freetronics tarafından verilen bağlantı şemasını görebilirsiniz:


Bu şemayı PCB'siz olarak jumper kablolar ile aşağıdaki gibi bağlayarak gerçekleştirebiliriz:




Flat kablolarda pin numaraları 1 ile kırmızı çizgili tel (ve bir ok işareti ile de) gösterilir. 1 numaralı pin ile aynı hizada flat kablonun diğer kenarına doğrıı giden sütun tek sayılı (1-3-5-7-...) pinlerdir. 1 numaralı pine komşu olan diğer pin de 2 numaralı pindir. Çift pinler de aynı şekilde flat kablonun diğer kenarına kadar çift sayılı (2-4-6-...) olarak gider:



Uygulanmış hali aşağıdaki fotoğraflarda görüntüğü gibi olmalıdır:
flat kabloya bağlanan jumper kabloları
arduino pin bağlantıları-1
arduino pin bağlantıları-2
demo uygulaması çalışırken panel arkası, bağlantılar vs.
demo uygulaması çalışırken panel önü-arkası, bağlantılar vs.
demo uygulaması çalışırken panel arkası, bağlantılar vs.




Arduino Nano kullanarak (aynı bacak bağlantılarıyla) yapılmış hali:






Freetronics DMD kütüphanesinden örnek DMD_Demo kodu:

#include <DMD.h>
#include <TimerOne.h>
#include "SystemFont5x7.h"
#include "Arial_black_16.h"

#define DISPLAYS_ACROSS 1
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

void ScanDMD()
{ 
  dmd.scanDisplayBySPI();
}

void setup(void)
{
   Timer1.initialize( 5000 );
   Timer1.attachInterrupt( ScanDMD );
   dmd.clearScreen( true );
}

void loop(void)
{
   byte b;
   
   // yanıp sönen pixel kolonlarının yerleştirilebilmesi için OR ve NOR modlarının demolarını içeren 10 x 14 yazı tipli saat
   dmd.clearScreen( true );
   dmd.selectFont(Arial_Black_16);
   dmd.drawChar(  0,  3, '2', GRAPHICS_NORMAL );
   dmd.drawChar(  7,  3, '3', GRAPHICS_NORMAL );
   dmd.drawChar( 17,  3, '4', GRAPHICS_NORMAL );
   dmd.drawChar( 25,  3, '5', GRAPHICS_NORMAL );
   dmd.drawChar( 15,  3, ':', GRAPHICS_OR     );
   delay( 1000 );
   dmd.drawChar( 15,  3, ':', GRAPHICS_NOR    );
   delay( 1000 );
   dmd.drawChar( 15,  3, ':', GRAPHICS_OR     );
   delay( 1000 );
   dmd.drawChar( 15,  3, ':', GRAPHICS_NOR    );
   delay( 1000 );
   dmd.drawChar( 15,  3, ':', GRAPHICS_OR     );
   delay( 1000 );

   dmd.drawMarquee("   https://ersinkecis.blogspot.com.tr   ",39,(32*DISPLAYS_ACROSS)-1,0);
   long start=millis();
   long timer=start;
   boolean ret=false;
   while(!ret){
     if ((timer+30) < millis()) {
       ret=dmd.stepMarquee(-1,0);
       timer=millis();
     }
   }
   // piksellerin yarısı
   dmd.drawTestPattern( PATTERN_ALT_0 );
   delay( 1000 );

   // diğer yarısı
   dmd.drawTestPattern( PATTERN_ALT_1 );
   delay( 1000 );
   
   // bir yazıyı tek ekranda 2 satır olarak görüntüle
   dmd.clearScreen( true );
   dmd.selectFont(System5x7);
   for (byte x=0;x<DISPLAYS_ACROSS;x++) {
     for (byte y=0;y<DISPLAYS_DOWN;y++) {
       dmd.drawString(  2+(32*x),  1+(16*y), "ERSiN", 5, GRAPHICS_NORMAL );
       dmd.drawString(  2+(32*x),  9+(16*y), "KECiS", 5, GRAPHICS_NORMAL );
     }
   }
   delay( 2000 );
   
   // ekranın dışına bir çerçeve çiz
   dmd.clearScreen( true );
   dmd.drawBox(  0,  0, (32*DISPLAYS_ACROSS)-1, (16*DISPLAYS_DOWN)-1, GRAPHICS_NORMAL );
   delay( 1000 );
   
   for (byte y=0;y<DISPLAYS_DOWN;y++) {
     for (byte x=0;x<DISPLAYS_ACROSS;x++) {
       // bir X çiz
       int ix=32*x;
       int iy=16*y;
       dmd.drawLine(  0+ix,  0+iy, 11+ix, 15+iy, GRAPHICS_NORMAL );
       dmd.drawLine(  0+ix, 15+iy, 11+ix,  0+iy, GRAPHICS_NORMAL );
       delay( 1000 );
   
       // bir daire çiz
       dmd.drawCircle( 16+ix,  8+iy,  5, GRAPHICS_NORMAL );
       delay( 1000 );
   
       // içi dolu bir kutu çiz
       dmd.drawFilledBox( 24+ix, 3+iy, 29+ix, 13+iy, GRAPHICS_NORMAL );
       delay( 1000 );
     }
   }

   // şerit kovalayan testi
   for( b = 0 ; b < 20 ; b++ )
   {
      dmd.drawTestPattern( (b&1)+PATTERN_STRIPE_0 );
      delay( 200 );      
   }
   delay( 200 );      
}