Yazar arşivleri: selimpehlivan

selimpehlivan hakkında

Sen anladın onu...

nRF24L01+

Nordic Semiconductor her ne kadar son zamanlarda bluetooth’a odaklanmış gözükse de uzun yıllardır sub-ghz rf çiplerini kullandığımız bir marka.
İnsanlar artık “uysa da uymasa da” bir protokol seçip, onu çalıştıran stack’in yüklü olduğu işlemciyi barındıran bir SOC alıp, ilave bir-iki özelliğini kurcalayıp proje üretiyorlar. Özellikle farklı cihazlarla beraber çalışma gibi durumlar söz konusu olduğunda bu elbette doğru bir yaklaşım. Öte yandan, eğer bir bluetooth uzaktan kumandası kullanıyorsanız, bunun kitlesel olarak üretilmiş cihazlarda bile bazen ne kadar başarısız sonuçlar verdiğini de yaşayarak görmüşsünüzdür.

Tam çalışma şeklini, iletişim protokolünü, güç yönetimini ve tüm radyo parametrelerini kendimiz ayarlayarak, tam olarak uygulamanızın ihtiyacına göre kablosuz haberleşme gerçekleyebildiğimiz çözümler de var. Bunlar genelde üreticilerin Proprietary RF (uygulamaya özel protokol) başlığı altında ele aldığı çözümlerdir. Teorik olarak herhangi bir RF SOC’unu alıp, dökümantasyonla mücadele edip bu şekilde çalıştırmak mümkün. Ancak, anlaşılır sebeplerle, 1GHz altında çalışan modüller protokolü size bırakılmış, böyle uygulamalar için oluyor genelde. Bizim bu yazıda ele alacağımız 24L01+ bu tarzın 2,4GHz’deki temsilcisi olması sebebiyle de ilginç.

Aslında bu çipin uygulama devresinde çok az harici eleman var, bu yüzden bunu board’a eklemek zor bir iş değil. Ama hazır modüller o kadar ucuza bulunabiliyor ki çipi temin etmeye çalışmaya (ki muhtemelen modülü bulmaktan daha zor) buna değmez.

nRF24L01+ modüllerle ilgili, ilk gördüğümde dikkatimi çeken şey çok ucuz olmaları olmuştu. Eğer uygar ve gelişmiş bir ülkede yaşıyor olsak, para birimimizin bir kesiri ile belirtilen bir fiyat etiketiyle bu ürüne sahip olabilirdik. Muhtemelen bir bardak çay parasından ucuza. İçinde olduğumuz duruma rağmen, bu modüller hâlâ herhangi bir uygulamaya eklemek için çok da düşünmeyeceğiniz kadar ucuzlar. Öte yandan bu ucuzluğuna rağmen pek çok kablosuz habereşme işinde kullanmaya da uygun gibi gözüküyorlar. Yani, bunlara bir bakmaya değer.

Donanım

Gerekenler;
– 3 port SPI,
– iki çıkış : CE ve CS
– bir tane de giriş (isteğe bağlı) IRQ.

Elimde nRF24L01+ modülünü doğrudan takmak için bir board var. Bunu bir ana dinleyici olarak tasarladım. Görevi, sürekli dinlemek ve kendine yollanan verileri RS485 üzerinden aktarmak. Daha otonom çalışma için board’un üzerinde röle çıkışları da var.

Alıcısı olan şeyin bir de göndericisi olmalı elbette. Bu taraf, uygulamaya göre şekillenir. Çünkü biz kablosuz haberleşmeyi data-agnostik işlerde kullanmıyoruz. Elimizde, benim eskiden kalma alışkanlıklarla “saha” dediğim, bir şey ölçmek ya da kontrol etmek istediğimiz bir uzak noktada bir modül var. Radyo haberleşmesi bize bu uzak modül ile, daha merkezi bir kontrol noktası arasında iletişim kurmak için gerekiyor. Yani bizde radyo haberleşmesi, yollanacak veriden bağımsız bir iş değil. Bu yüzden bir alıcı pek çok farklı işte kullanılabilir ancak gönderici kapasitif bir sıvı sensörü de olabilir, radar kullanan bir mesafe sensörü de olabilir, bir sıcaklık sensörü de olabilir, bir kapıya takılmış güvenlik anahtarı da olabilir. Ve işi bu modül tanımlar.
Ben, gönderici tarafın çalışma şeklini denemek için daha önce, bambaşka bir proje için hazırladığım bir prototip board’unu kullandım. Bu kartı seçmemin sebebi boyutları değil, üzerinde bir header ile bağlantısı olan SPI portu olmasıdır.

Bu arada ben gündelik konuşmadaki anlamıyla “alıcı” ve “gönderici” tabirlerini kullanıyorum. Gerçekte, modüller hangi tarafta olurlarsa olsunlar hem alma hem de yollama radyo fonksiyonlarını yürütmek zorundadırlar. Bizim alıcı ve verici derkenki kastımız “data” (veri) yönünü ima etmiyor, “information” (bilgi) yönünü ima ediyor.

Şimdi kullanacağımız pinlerden bahsedelim:
SPI = SCK, MISO, MOSI, CSN
Bu, bildiğiniz SPI faz 0. CSN de 0 iken etkin SPI slave select çıkışıdır.
Ben 1MHz SPI clock ile modüllerle sorunsuz haberleşiyorum. Gönderici tarafta salkım saçak kablolarla bağlantı olduğu için çok hızlandırmayı düşünmedim.

CE = Chip enable çıkışı. Nordic bu tabiri çiplerine dışarıdan bir işlem başlatan girişlerini tanımlarken kullanıyor. Mesela veri yollama işlemini başlatmak ya da alıcıyı etkinleştirmek gibi.

IRQ = Gönderme ya da alma işlemlerinin tamamlanışını, eğer ilgili maske bitini ayarlanmışsanız bu pinin 1->0 geçişinden anlayabiliyorsunuz. O yüzden “kesme” ismi verilmiş. Donanımda pin kıtlığı varsa bunu bağlamak için bir giriş ayırmadan da çipi çalıştırabiliriz ama o zaman periyodik olarak SPI konuşması yapmamız gerekir.

Sürücünün Tasarımı

Sürücü ile kastettiğim, bizim kartlar üzerinde çalışan firmware’in radyo modülleri üzerinden iletişim kurmasını sağlayan fonksiyonlar ve değişkenler. Bunu doğru tasarlarsak donanımımız asıl işini yaptıktan sonra (bir sensörden veri okumak gibi) ileteceği veya alacağı veriyi UART’tan yollamaktan çok da farklı olmayan bir şekilde iletip çevrimini tamamlayacaktır.

Burada konu ettiğimiz radyo çipi gibi amatörlerin beğenisini kazanmış, bilindik ürünlerle ilgili internette firmware araştırmaları yaptığımda karşıma çok fazla boş içerik çıkıyor. Bunun en basit nedeni, adamın birinin (hatta bazen çipin üreticisinin) bir arduino kütüphanesi yazması. Konuyla ilgilenen çoğu kişi bu kütüphaneyi referans gösteriyor. “Nasıl kullanılacağını açıklama” amaçlı pek çok makale gidip bir arduino kütüphanesine dair nesneyi main.c içine koyup .begin demekten öteye geçmiyor.

Bu çip için geçerli değil ama daha dehşet verici olan ise şu: Pek çok durumda, yazılmış arduino kütüphanesinin “kendisi” de ürünün pek çok özelliğini kullanmayan, dökümantasyonla tam uyuşmayan hasbel kader çalışmış bir kod oluyor. Ürünün üstünde olan ve benim tam da onu seçme sebebim olan bazı yönlere dair hiçbir ayrıntı görmüyorum. Yani, internetten çalışan bir kod arama macerası genellikle konuya ilgi duyan ama ayrıntıları çözecek motivasyonu ya da zamanı olmayan kişileri yanlış yönlendirecek ya da asıl işe yarar bilgiden yalıtacak şekilde çalışıyor. Ben bir şeyleri çalıştırmaya çabalarken de, yaptığım bir şeyle ilgili bilgiler paylaşırken de bundan uzak durmaya özen gösteriyorum. Açık dökümantasyonu olan ve geliştirme araçlarına sahip olduğumuz her şeyi nasıl çalıştığını anlayıp, kendi ihtiyacımız için en optimum ayarlarla kullanabilmeliyiz. Aksi halde başkasının gelinliğiyle/damatlığıyla düğün yapmış oluruz. En sonunda ortaya çıkan sonuç da çoğu zaman “optimal” bir çözüm olmaz.

Benim hemen hemen her yeni işte karşılaştığım bu can sıkıcı duruma dair düşüncelerimi de paylaşmamın ardından nRF24L01+ ‘e nasıl erişeceğimiz konusuna dönebiliriz:
SPI’ı , ilk byte’ı bir komut olan master paketlerine yanıt vererek haberleşiyor. Okuma, yazma, register/fifo erişimi gibi tüm olasılıklar ilk byte’ta verilen komuta göre belirleniyor:

Bu da demek oluyor ki, çipe erişme işlerimiz daima bir komutu yazarak başlamalı:

static unsigned char NRF_Command(unsigned char cmd);

Komutlar nrf24l01.h içinde tanımlı bir byte’lık sabitlerdir. Datasheet’in 51. sayfasında listesi verilmiştir. Yukarıdaki fonksiyonda CSN=0 yapıp, verilen komut byte’ını yazıp bu esnada MISO’dan da STATUS içeriğini okuyup sonraki eylemi beklemeye koyuluruz.

nRF24L01+ ‘e yaptıracağımız işler şunlar:
– Çipi konfigüre etmek;
– Çipin çalışma durumunu (MODE) değiştirmek,
– STATUS’ü okumak
– Veri buffer’larına gidecek veriyi yazmak ya da onlardan gelen veriyi okumak.

Bu görevler kısa süren eşzamanlı işlemlerle halledildikleri için generic bir sürücü, gerektiğinde çağrılacak fonksiyonlardan ibaret olabilir.

KONFİGÜRASYON:

Power-up sonrası nRF24’ün lojik kısımlarının çalışmaya başlaması için 100ms geçmesi gerekir. Bu yüzden, program başlar başlamaz çipi konfigüre edeceksek önce bir 100ms beklemek zorundayız. Sonra, çipin POWER_DOWN mode’da olduğundan emin olabiliriz.

nRF24L01+’de çalışma öncesi yapılması gereken ayarlamalar şunlar:
Auto-Ack :
Firmware Sabiti.
Bu özelliği kullanıyorum, o yüzden hem alıcıda hem de göndericide pipe-0 için ack enable yapıyorum.
RX Address Enable:
Firmware sabiti.
Alıcıda pipe-0 ve pipe-1 yollayıcıda ise pipe-0 (ack’i almak için) etkin yapıyorum.
Address Width:
Firmware sabiti.
4 byte adresleme kullanıyorum.
Auto-Retransmission:
Firmware sabiti.
Alıcıda 0 ama göndericide sıfırdan farklı değerlere ayarlanmalı.
RF Channel:
Uygulama için parametrik.
7 bitlik radyo kanalı tanımı
RF Setup:
Uygulama için parametrik.
250kbps veri hızı kullanıyorum. Çıkış gücü ayarlanabilir olabilir.
Payload Width:
Firmware sabiti.
Sadece alıcı tarafta tanımlanması gerek. Yollayıcı tarafta TX payload olarak ne yüklersek radyo onu yolluyor.
P0 için RX Adresi:
Uygulama için parametrik
Alıcıda, bu ağı tanımlayan master adresi budur. Yollayıcıda burada alıcının adresi olmalı (ACK almak için böyle yapmak gerekiyor).
P1 için RX Adresi:
Uygulama için parametrik
Alıcıda, bu konfigürasyon çağrı adresi. Normal veri mesajlaşması dışındaki işlemler için rezerve tutuluyor. Yollayıcıda kullanılmayabilir veya konfigürasyon adresi olarak tanımlanabilr.
TX adresi:
Uygulama için parametrik.
Yollayıcıda bu ağın tanımlayıcısı olan master RX adresi (alıcının P0 adresi). Alıcı için ise tanımlanması gerekmiyor (konfigürasyon için adres gereksin dersek kullanılır).

Çip POWER-DOWN durumundayken konfigüre edilebilir. Ben de bunu tercih ediyorum. Çip yollama veya alma yapmadan önce STAND_BY-1 durumuna geçmiş olmalıdır. Bunu yaptırmak için CONFIG register’ına yazma işlemi yapan bir fonksiyon kullanıyorum:

void Radio_Stby(void)

CONFIG register’ında sürekli değiştirmemiz gereken bit PWR_UP biti (bit-1) olsa da burada CRC ayarlarını, TX/RX çalışmasını ve IRQ pinini sürecek kesme kaynaklarını belirleyen bitler de var. Her Stand_By’a geçişte bunları da doğru değerlere ayarlamak gerekiyor.

GÖNDERİCİ İÇİN İŞLEMLER:

Radyo STAND_BY -1 durumundayken;
– Yollanacak veriyi TX FIFO’ya yüklemek,
– CE = 1 yapmak, 15us beklemek ve CE=0 yapmak,
Yollama işlemini başlatır.

Bu işleri

void Radio_TX(unsigned char xdata *ptx)

isimli fonksiyonumda hallediyorum. Bu fonksiyon her çağrıldığında TX FIFO’ya belirtilen konumdaki paketi yükler ve sonra CE pulse’ını üretir. Burada TX adresini yeniden yüklemiyorum. Flash’tan yüklenen radyo ayarları bellek alanında master adresi tanımlanmıştır ve konfigürasyon aşamasının ilgili adımında bu adres TX adresi olarak yüklenir. Radyo üzerinden yeniden konfigürasyon işlemi için config çağrı adresinin yeninden yüklenmesi gerekecektir.

Auto-Retransmit fonksiyonunu kullandığımız için, belirtilen süre içinde ACK almazsa radyo tanımlanmış sayı kadar tekrar yollama denemesi yapacaktır:


TX için radyoyu STAND_BY-1 durumuna getirirken config register’ına ;

#define CONFIG_TX  0x4E

sabit değerini yazıyorum. Bu durumda nRF24L01+ ‘in IRQ pini veri yollandığında veya max. retransmit count deneme sayısına ulaşıldığında 0 olacak demektir. Ana programın IRQ pininin 1 -> 0 geçişini beklemesi gerekir.

Bu olduktan sonra

void Radio_Clear_IRQ(void)

fonksiyonu ile kesme nedeni okunup hemen sonra da flag’ler sıfırlanmış olunur. Yollayıcı program MAX_RT kesmesi gelmişse alıcının veriyi almadığı varsayımıyla uygun işlemi yapabilir. Tipik kullanımda ben her durumda veri yollaması sonrası donanımı düşük enerjili moda alıp işlemciyi de rtc kesmesi ile uyanacak şekilde kurup kapatıyorum. Gönderme işlemimiz MAX_RT kesmesi ile sonuçlanmışsa daha kısa, TX_DS kesmesi ile tamamlanmış ise de normalde düşündüğümüz uyku süremizi ayarlıyoruz.

ALICI İÇİN İŞLEMLER

Bu tür düşük enerjili saha node’larının master-slave çalıştıkları ağlarda alıcı sürekli açık olsa daha uygun olur gibi gözüküyor. Yani, en basit başlangıçta, bize sürekli dinleme durumunda olan bir radyo gerekli. Bunun için öncelikle nRF24L01+ ‘i başlatıyorum ve ardından onu STAND_BY-1 durumuna sokuyorum. Sonra biraz bekleyip CE pinini 1 yapıyorum. Bu durumda radyo daha önce konfigürasyon aşamasında bahsettiğim üzere, pipe-0 ve pipe-1 için tanımladığımız adreslere gelecek paketleri beklemeye başlıyor. Ayrıca kesmeyi de DATA_READY flag set edildiğinde pini sürmek üzere

#define CONFIG_RX  0x3F      

konfigürasyon değeriyle ayarlamış oluyorum. Bu durumda bir veri geldiğinde IRQ = 0 olacağını varsayıp bekliyoruz.

IRQ=0 algılandığında hemen çipin STATUS register’ını okuyorum. Aslında bu durumda iken tek kesme kaynağı veri alınması olsa da hangi dinleme pipe’ına veri geldiğini ayırt etmemiz için status içeriğini biliyor olmamız gerek.

void Radio_Read_RXData(unsigned char xdata *dest)

fonksiyonu RX FIFO’nun geçerli içeriğini dest ile belirtilen ram konumuna aktarır. Status ile belirlediğimiz dinleyici kanalına uygun kayıt konumunu seçeriz. Bu kısım gelen veriyi işlemeyle ilgili..

Read_RXData() fonksiyonu ile FIFO’yu okuduktan sonra radyo üstündeki gelen veri buffer’ının boş olduğundan emin olmak için bir kez daha STATUS register’ını okuyorum. Buffer boş ise işlemler bitmiştir, dolu ise bu kez hangi pipe’tan veri almışsak onunla ilgili hedef konumuna fifo içeriğini okuyorum. Bu şekilde, birbirine yakın zamanlarda gelmiş olan iki paketi de atlamadan alacağımızı ümit ediyorum.

Yeri gelmişken yazayım: Bu, birden çok dinleme “pipe” ‘ı mevzusu alıcının toplam iş çıkarma kapasitesini arttırmıyor. Çünkü, radyo belli bir anda tek bir kanalda dinleme yapıyor ve sadece bir paketi alabiliyor. Birden çok RX adresi olması otomatik ACK üretme işinde ve bir seviyeye kadar gelen paketleri sınıflandırmada işe yarar.

FIFO boş olduktan sonra kesme bayrağını TX işleminde yaptığım gibi STATUS register’ına yazarak sıfırlıyorum ve alma işlemi bitiyor.

Test programında yapılan son iş gelen veriyi seri porttan yollamak.

alpha-S

decolit alpha-s rgb led lamba modüllerinin çıplak kart halleri

Üç renkli LED elemanlar kullanarak rengarenk aydınlatmalar yapmak son zamanlarda bana da çekici gelmeye başlamıştı. Aslında bunun için hazır pek çok seçenek var ancak ben küçük bir board yapıp, üzerine kendi seçtiğim RGB LED’leri yerleştirip kendi tanımladığım kumanda şemasını yürütebilecek bir şeyler yapmak istedim. Sonrasında bu küçük kartları istediğim yerlere yerleştirip, onları değişken renklerle yakmak niyetindeyim. Noktasal olarak büyük bir ışık yoğunluğunu hedeflemiyor olsam da bir board üstüne 5 tane PLCC kılıf LED koymaktan kaçınmadım.

Kartın boyutları 58mm x 13.5mm oldu.


Deneme amacıyla ürettiğim board’ların üzerine Cree marka CLP6C-FKB model LED’ler taktım. Sonuç gayet güzel.

LED’leri doğrudan kartların besleme hattı üzerinden besliyorum ve her renk için bir pull-down transistör ile sürüyorum. Şemada 100R olarak gözüken seri dirençler besleme gerilimine göre seçilmesi gereken denge dirençleri.

Bu projeyi bir hafta sonu çalışması olarak uğraşmaya değer bulmama neden olan şey bu kartları seri haberleşme ile kumanda edilebilir ve kaskat bağlanabilir yapmam. Bu şekilde iş basit bir renk ayarından çok daha fazlası olabilir.

Aslında arka arkaya bağlanabilir renkli LED deyince akla gelen Neopixel diye bir LED çipi de var. Bunun Çin malı kopyaları ucuza bulunabiliyor. Ama bunlar adreslenebilir modüller değiller. Ben uzun clock katarları üretmek zorunda kalmak yerine doğrudan UART kullanan bir şey yapmak istedim. Bu şekilde tek bir komutla tüm lambalara aynı anda aynı şeyi yaptırabilmek mümkün. Veya istediğiniz belli bir adrese doğrudan komut verebilirsiniz. Eğer hızlı animasyonlar yapmak söz konusu ise bu daisy-chanining’e göre çok büyük bir fark yaratabilir.

Her modülün sol tarafında uart’ının RX ‘i sağ tarafında ise TX çıkışı bulunuyor.

Modülleri arka arkaya (kaskat) bağladığımızda soldan sağa birbirlerini sürmüş olacaklar.Bir modül sol tarafından bir paket aldığında bu paket onu adreslemiyorsa veya bir genel çağrı adresi taşıyorsa o komutu sağ taraftaki TX pininden aktaracaktır. 0-3V gerilim düzeyinde çalışıyor olsak bile bu şekilde alavere yaparak uzun bir lamba zincirini bir uçtan kumanda edebilmeyi umuyorum. Bu arada, 24mA kaynak akımı verebilen bir logic buffer kullanmakla sonraki modül ile aramızdaki kablonun kapasitesinden kaynaklanacak yavaşlamaları azaltmış olacağız. Şemadaki paralel kondansatöre takılmayın. Orada bir komponent yeri olsun istedim sadece.

Benim “adreslenebilir” bir lamba modülünden beklediğim kumanda işlevleri her kanal için ayrı ayrı olmak üzere;
* Açma ve kapama denetimi,
* Çıkış gücünü ayarlama,
* Rampalı açma/kapama,
* Çıkış gücünü rampalı değiştirme,
* Rampa sürelerini değiştirebilme
* Çıkış gücünü çıkışa yansıtmaksızın değiştirebilme (komut verildiğinde uygulanmak üzere)
* Tüm modüllere eşzamanlı komut verebilme

Bu fonksiyonlar basit seri komutlarla kumanda edilebildiğinde ana kontrolcünün karmaşık efektleri yürütmesi kolayca mümkündür.

Firmware Yapısı

Ana program, dört ayrı thread’den oluşur:
+ Sürekli olarak çalışan ve her aşaması belirli bir zaman aşımı denetimi ile korunan bir seri haberleşme thread’i..
+ Zaman çoğullamalı olarak çalışan ve her biri bir renk sürücüsüne çıkış veren üç özdeş paralel renk kontrol thread’i.

Her renk kontrol thread’i 4 farklı duruma dair task’ler çalıştırır. Her task’in o renk için bir “durum” olduğunu düşünün. Bunlar;
OFF
ON
RAMPUP
RAMPDOWN
task’leridir. OFF ve ON task’leri kalıcı durumlardır. Bir komut alınmadığı sürece denetim bu task’i çalıştırmayı sürdürür. RAMP task’leri ise belli bir süre boyunca çalışan geçiş durumlarıdır. Set değeri değiştirildiğinde (kademeli geçiş komutu verilmişse) veya kademeli açma kapama komutları verildiğinde yeni set değerine ulaşılıncaya dek bu adımlarda kalınır.

Çıkış kontrol task’lerinin zaman bölümlemesi 10,7ms ‘dir. Yani her 10,7ms’de bir sıradaki renk kanalının geçerli durumuna dair task çalışır. Ve bu çevrim art arda sürekli devam eder. İki rezerve zaman slotunun da eklenmesiyle, bir tam çevrim 5×10,7 = 53,5ms ‘de tamamlanır. Bu demektir ki, çıkış güncellemeleri 53,5ms çözünürlükle yapılmaktadır. Durağan adımlarda bu önemli olmamakla beraber kademeli geçiş adımlarında bu süre değişim hızını tanımlar.

PWM

İşlemcinin üzerindeki 3 PWM kanalını da kullanıyoruz. PWM çözünürlüğü 8 bittir. PWM frekansı da 7,98 kHz’dir.
Bu projenin donanımını tasarlarken EFM8BB1 işlemcisini kullanmıştım. Firmware’e de bu işlemci üzerinde çalışarak başladım. Sonra iş deneme aşamasına gelince prototip montajları için bana yardımcı olan arkadaşımın elimdeki board’lara BB1 yerine yanlışlıkla SB1 takmış olduğunu fark ettim.
Sleepy-Bee ile Busy-Bee “hemen hemen” pin uyumludur. Ancak firmware’de oldukça yaşamsal farklar vardır. Ne yazık ki buna PCA modülü de dahil, ki bu board’da PWM’i bununla üretiyorum. O yüzden, elde olan asıl olandır mantığıyla benim firmware’i SB1 üzerinde çalışacak şekilde değiştirdim. Ancak asıl üretimim BB1 ile olacak. Çünkü bunda daha çok özellik var.
Bu işlemcilerde PWM çıkışı aktif duty cycle’da 0, pasif durumda da 1 oluyor. Ben BB1’de PCA0POL register’ı ile bu evirme işlemini donanımsal olarak halledebiliyordum. Ancak SB1’de POL register’ı yok. Bu durumda çıkış gücü 0 yazarsak en büyük 255 yazarsak en küçük olmuş olur. Ayrıca, kanalı kapatmak istediğimizde önce çıkışa 255 yazmalı sonra da _ECOM bitini sıfırlamalıyız.
8 bit PWM’de set değerini PCA0CPHx register’ına yazmak gerek. Daha yüksek çözünürlüklü PWM ayarlarında kullanılabilen auto-reload register’larının kullanım seçimi bu modda kullanılmıyor.
Çalışma sırasında PCA modülü ve sayacı sürekli devrede. Bir kanalın kapalı olması gerektiğinde
PCA0CPMx = 0x02; yazarak o çıkışın toggle olmasını engelliyorum. (PCA0CPHx = 255)
PCA0CPMx = 0x42; yazdığımda da PWM çalışmaya devam ediyor.

BB1 kullanan versiyonda işler biraz daha değişik. Burada o kanalın POL bitini = 0 yapıp _ECOM=0 yapmam çıkışı kapatmaya yetiyor. Duty cycle’ı değiştirmeme gerek yok.
Ayrıca, BB1 ‘de PWM’i center-aligned kullanıyorum.

Kontrolcü, komutlar tamamlanmadan yeni komutu işleme almaz. Ancak rampa komutları icra edilirken seri haberleşmeden yeni bir komut alınırsa komut kuyruğa eklenir ve geçerli komut tamamlanınca işleme alınır. Ani açma / kapama /set değeri değiştirme komutlarında bunun olma olasılığı yoktur. Rampa işlemlerinde komutun tamamlanması rampa ayarına bağlı olarak uzun sürebileceği için bu olasılık vardır.

Üç renk kanalı birbirinden tamamen bağımsız olarak çalışabilir ve kumanda edilebilirler. Ancak tamamen eşzamanlı olarak da kumanda edilebilirler.

Bir zincirde 128 adet modül arka arkaya bağlı olabilir. Her modülün adresi sabittir. Bir ağda aynı adresli iki modül olması çalışmayı bozmaz, sadece bu modüller ayrı ayrı ayarlanamamış olurlar. 0x81 adresi tüm modüllerin ortak çağrı adresidir.

Seri portun haberleşme hızı 38400bps’dir. Yazdığım ilk versiyonda modül aldığı paketin adresi kendi adresi değil ise paketi tamamlanmasını beklemeden iletmeye başlıyordu. Ancak sonra, kesme kodunu kısa tutma takıntım yüzünden bu özellikten vazgeçtim. Bu durumda, her modül için paket aktarım gecikmesi yaklaşık 1,6ms’dir.

Haberleşme Yapısı

Paket boyu tüm komutlar için sabittir ve 6 byte’tır. Her paket sync byte’ı (0xAA) ve hedef node adresi ile başlar (0x01..0x81). 0x81 genel çağrı adresidir.
Ardından gelen cmd byte’ı paketi tanımlar. Geçerli komutlar ve kullandıkları parametrelerin anlamı şöyledir:

node: 1..128 arası, hedef adresi. 129 tüm modülleri adresler.
cmd_X : kanal komutları. anlamları şunlar:
0: Bu kanala ait komut yok.
1: forced-on : Kanal kapalıysa hemen açılmasını sağlar. Eğer açıksa out_X’te o an yazılı olan set değerini çıkışa yansıtır.
2: turn_off : Kanalı hemen kapatır.
3: ramp-up: Çıkış gücünü kademeli olarak out_X ‘te yazılmış değere yükseltir. Kanal kapalı idiyse açılır ve set değerine kademeli yükselir.
4: ramp-down: Çıkış gücünü kademeli olarak out_X’te yazılmış değere azaltır.
5: rampdown-off: Çıkış gücünü sıfır değerine kadar kademeli azaltır ve sonra kanalı kapatır.
NOT: Ramp-up ve ramp-down komutları, o anki çıkış oranı, out_X set değerinden sırasıyla yüksekse ve düşükse tek seferde yeni set değerine gelir.

Bu projede önemli bileşenin lambaların kontrolcüsü olduğunu düşünüyorum. Firmware’i tamamlayıp denemelere başladığımda işin bu yönünün geliştirilmeye oldukça açık olduğunu gördüm. Yukarıdaki komutların çalışmasını hızlı biçimde deneyebilmek için basit bir PC programı hazırladım. Aşağıda onun görüntüsünü görüyorsunuz. Üzerine tıklayarak programı indirebilir ve deneyebilirsiniz:

Ermeni “meselesi” hakkındaki düşüncelerim

Bu blog, kişisel notlarımı üzerinde uzun uzun düşünme gereği duymadan not ettiğim bir karalama defteri. Üzerine çok eğilme fırsatı bulamamış olsam da oldukça uzun süredir sürdürdüğüm bir çeşit kaçamağım.
Bu bloga sahip olmanın benim için şöyle güzel bir yanı var: 12 sene önce yazdığım bir yazıya baktığımda vay be o zaman nasıl da farklı düşünüyormuşum diyebiliyorum.
Kişisel düşünce tarihimin aşamalarını bir bakışta görebiliyorum.

“Dünya görüşü” denen şeyi iki boyutlu bir harita gibi düşünürsek, ben o haritada epey yolculuk ettim. Kalmak istemeyeceğim duraklara da uğradım, sırf meraktan turist gibi de dolaştım. Yolculuğa başladığım yer ile şimdi olduğum yer o kadar farklı ki, hâlâ ben nereye aitim sorusunun yanıtından emin değilim. Bu ülkede insanların dünya görüşlerini birbirinden ayıran anahtar parametrelerden, din, muhafazakarlık, militarizm, seçkincilik, halkçılık, devlete bakış, sol/sağ ayrımı vs. konularda benim düşüncelerim 10-15 sene öncesine göre taban tabana zıt artık. Türkiye’nin son 10 senesini bilinci açık yaşamış her Türk vatandaşı için bu tür bir dönüşüm kısmen kaçınılmazdır diye düşünüyorum.

Fakat, böylesi bir dönüşüm sürecinde bakıyorum, yine önemli tartışma konularımızdan biri olan Ermeni soykırımı ya da techiri meselesinde benim düşüncem pek değişmemiş. İlginç. Konunun kendisi aslında üzerinde yazı yazmaya değer bile değil artık. Yıllar önce olup bitmiş bir olay. Ve şimdi ben, birine sırf Ermeni ya da başka bir milletten olduğu için kötülük eder miyim? O bana Türk olduğum için kötülük etmeye kalkarsa Çingene mahallesi kavgasına girer miyim? Geçelim bunları. Küçük ya da büyük hiçbir kavgamız kimliğimizle ilgili değil bizim. Biz Türk ya da Ermeni diye birbirimizi yerken paranın ırkının en saf ırk olduğunu keşfetmiş birileri bizim kavgamız üstünden kâr etmenin yollarını bulmuş olurlar bile ve bunu düşünmek öfkemizin yönünü de belirler, değil mi? En azından bu kadarını el yordamıyla bulabiliriz. Öyleyse ilginç olan ne bu hikayede? İlginç olan bu meselede benim görüşümü netleştirmemi sağlayan çıkarımlar. Onlardan söz edelim.

Birincisi, bu ülkede, uzmanlık alanı bu olan insanlar dahil hiç kimse, Ermeni meselesini bir dış sebep olmadan konuşmuyor. Bu yazıyı, dün Amerikan Başkanı 24 Nisan anma bildirisinde “genocide” sözcüğünü kullandığı için, evet, sırf bir iki danışman böyle bir sözcük yazdığı için yazıyorum. Çünkü dünden beri sırf bu basit sebep yüzünden kıyamet kopuyor. Madem bu kadar doluyuz bu konuda, madem bu kadar haklıyız, neden tüm kavgamızı Allahın dünyadan bi haber Amerikan demokrat kırolarının laf arasında deyip geçtikleri bir saçma söz üzerinden yapıyoruz?

İkincisi arşivleri açalım muhabbeti.. Bunu biraz daha entelektüel açıdan özgüveni olan arkadaşlar dillendiriyor. Herhalde arşivde mühürlü bir kağıt var ve üzerinde yaptık ya da yapmadık yazıyor. Allahın orijinal sözlerinden oluşan ve sırf bu işle iştigal eden bir melek tarafından getirilmiş, tek bir harfi bile değiştirilmemiş bir kitap üzerine bile “ilahiyat” diye bir “bilim” dalı üretmişiz ama arşiv denen şeyin kapısını açıp gidip bakarsak sonucu göreceğimiz ve tartışmaları bitireceğimiz bir şey olduğunu iddia edip tarih bilimini çöpe atabiliyoruz. Bu sanırım çok düşünmemiş olmanın, bir konu üstüne farklı kitaplar okuyup kararı kendin vermek gibi bir ayrıcalığı hayat boyu yaşamamış olmanın hazin sonucu.

Üçüncüsü ve bence en yüksek ağırlığa sahip olanı şu: Bu memlekette son birkaç senede, devleti yönettiğini iddia eden iktidar kurduğu ortaklıklar bitince fikir ve dünya görüşü olarak tamamen kendinden olanlara bile nasıl zulmetti görüyoruz. Onları geç, bunun bir iç kavga olduğunu düşünebilirsiniz haklı olarak. Bu ülkede kendisi gibi düşünmeyen insanlara düşman olma, ona gün yüzü göstermeme kültürünün ne kadar derin kökleri olduğunu her gün görüyoruz. Bu adamlar 106 sene önce “gavur” lara mı merhamet edeceklerdi? Mantıklı geliyor mu? Gelmiyor değil mi..
Diyeceksiniz ki, şimdiki iktidar ittihatçılara misal olur mu? Tamamen olmaz tabi. Ama benim örnek gösterdiğim ikitdar/ittihatçılar değil. Onların yaptıklarına kayıtsız kalan hatta destek veren halk. 12 Eylül’e destek verenlerle tarikat ortaklı dinci faşizme destek verenler aynı halk. Bunlar için Enver Paşa ile Erdoğan çok fark etmiyordur bence. Bu “potansiyel” ürkütücü değil mi?

Bu kadar büyük bir vahşet yaşanmış olabilir mi diye ben de bazen kuşkuya düşüyorum. Ama bir de şunu düşünün: Şu günlerde konuştuğumuz bir skandal var. İktidar belediyeleri hizmet pasaportları çıkarıp binlerce insanı Avrupa’ya kaçırmış. Bunlar Malatya Elazığ Bingöl gibi illerden adam toplamışlar.Belediye meclisi’nde karar çıkarıp kaymakamlıklara onaylatıp Almanya’ya insan götürmüşler. Aynı adamlar Almanya bizi kıskanıyor diyorlar mı? Diyorlar.. Aynı halk inanıyor mu inanıyor.. Devlet imkanları ile ülkeden kaçan o binlerce insanı tanıyan, sülalesine kadar bilen yüz binlerce insan yaşıyordur oralarda. Ve hepsi de Almanya bizi kıskanıyor denince inanıyor, alkışlıyor. İşte bu insanların 106 sene önceki hallerinden söz ediyoruz.
Sanırım paragrafın devamını yazmama gerek yok.

Bugünden geçmişe bakmak adına güzel bir konu oldu bu ama fazlası değil. Biz kabul etsek nolur etmesek ne olur. Biz kendimizden dediğimiz insanlara ne kadar merhamet gösteriyoruz ona baksak yeter. 106 sene önce, Dünya Savaşı’nın ardından gelen kaosta yaşanmış şeyleri yorumlamak bizim için verimli bir çalışma alanı değil bence. Şimdilerde muhalefet olma iddiasındaki düşük profilli insanların Amerika’ya tarih dersi vermesine tanıklık edeceksiniz. Sabırlar dilerim.

PIC32MM ile PWM

Aslında PIC32MM çiplerinde pin remap fonksiyonu “peripheral pin select” adıyla var. Ancak ilk üç capture/compare modülü için serbest pin ataması yapılamıyor. Bunlar aynı zamanda birden çok çıkışla kullanılabilen modüller. Bu çıkışların yerleri sabit. Örneğin, QFN28 kılıf olan versiyonda Output-Compare çıkışlarının hangi pinlerle paylaşıldığını aşağıda görüyorsunuz:

Pinler OCMxy designatoru ile isimlendirilmişler. Burada;
x modül adı oluyor. Yerleşik pin fonksiyonuna sahip modüller CCP1, CCP2 ve CCP3
y modülden çıkış alabilen kanal indeksi oluyor. A,B,C,D,E ve F olarak 6 “olası” kanal var. Bunlar tahmin edebileceğiniz gibi birbirlerinden tamamen bağımsız çıkış üretmiyorlar. Hatta; A,C,E’yi bir grup B,D,F’yi bir başka grup olarak kabul edebiliriz.

PIC32MM USB Curiosity Development Board üzerine PWM’leri denememiz için bir RGB LED koymuşlar. Bu malzemenin,
* Kırmızı LED’i OCM1B
* Yeşil LED’i OCM2B
* Mavi LED’i OCM3E
çıkışlarına bağlı. Her LED başka bir CCP modülünde olduğu için sayısız renk kombinasyonu elde edebiliriz.

LED’leri farklı PWM duty cycle’ları ile sürüp renk ve parlaklık ayarı yaptırmak, bu demonun ana fikrini oluşturuyor. Galiba, Microchip’in sitesinde de bununla ilgili bir demo görmüştüm ama indirip çalıştırmaya fırsatım olmadı. Zaten buna gerek de yok. Çok basit bir-iki ayarlamayla üç PWM kanalı emrinize amade oluyor.

Şart mı bilmiyorum ama ben bu deneme için elimdeki Initialize() kodunda bu pinleri (RD1, RC3 ve RC15) çıkış yaptım.

CCP modüllerini devreye almak için yapılacak minimum ayarlama; timebase seçmek, çalışma modunu ayarlamak, çıkış pinlerini ve polaritesini ayarlamak ve periyot register’ına pwm periyodunu girmekten ibaret.
RGB LED sürerken en basit anlamıyla birbirinden bağımsız edge aligned bir PWM yeterli olduğu için her modül 16 bit dual edge compare modunda, bağımsız çalışıyor (dead time da yok). Bu çok basit bir kullanım şekli. PIC32 MCCP Referans Manual’ini incelerseniz CCP modüllerinin uygun bir donanım tasarımıyla çok enteresan şeyler yapılabilecek özellikleri olduğunu göreceksiniz.

CCPxPR : PWM periyodunu belirler.
CCP1RA : Edge aligned PWM için bunu 0 kullanıyorum.
CCP1RB : Falling-edge match değeri. Duty Cycle’ı bu belirliyor.

Dev. Board’lar üzerindeki potansiyometreyi LED’lerin parlaklığını (PWM DC) ayarlamak için kullanıyorum. Hangi rengin seçileceğini de yandaki üç push-button belirliyor. Potansiyometre RC8 pini ile paylaşılan AN14 analog kanalına bağlı. MM’in ADC’sinden ayrıca bahsediyor olsam da burada ADC’yi 10 bit okuma için başlatan ve AN14’ü okuyan bir kod da main.c içinde var.

PIC32MM USB Curiosity Board üzerinde çalışmaya hazır kodlara bu klasörden erişebilirsiniz:

Demokrasi alışkanlık yapar.

Bence Türkiye’de “demokrasi”nin karşı karşıya olduğu en büyük tehlike halkın politikacıları yalan söylemeye zorlamasıdır.
Politikacılar yalancı ve istismarcı oldukları için halk masumca onlara kanmış değildir. Pazarda sesi en çok çıkanlar hilebaz çığırtkanlar oldukları için dürüst satıcıların sesleri duyulmuyor değildir.
Kök neden şu ki, bu halk düpedüz yalan istediği için, yalanı sevdiği için, istismar edilmekten garip bir zevk aldığı için, dünyaya dair görüşleri doğrudan yalanlar üzerine kurulu olduğu için piyasadaki politikacılar da yalancı soytarılardır.

Benim gençliğime kadar olan dönemde Türkiye’de demokrasi arada balans ayarına giren, vesayetçi güçlerin sınırlarını çizdiği güce erişimi kontrol edilmiş bir oyundu. Bu oyunu oynayanlar kişisel hayatlarında halka gözüktükleri kadar avam insanlar değillerdi. Halkın hoşuna gidecek şeyler söylemek politikanın bir gereğiydi ama sadece bunu yaparak iktidarda kalınamazdı. Politika yalnızca halkın önünde oynanan bir tiyatrodan ibaret değildi. Güç dengelerini gözetmek gerekiyordu.

Sonra bu oyun değişti. Söz millete geçti. Sözün millette olması hakimiyetin Allah’ta olması gibi bir şeydi. Sonuçta güç, millet adına onu kullanmaya hevesli acemi politikacıların eline geçti. Güç dengesi gözetme gereği kalmadı. Ve bizim gençliğimize kadarki dönemde gördüğümüz anlamıyla politika denen şey de bitti. Artık politika diye bir şey hiç yok. Bir adamın istediğini yapabildiği, dün söylediğinin tam zıddını bugün söylediğinde aynı kişiler tarafından alkışlandığı bir yerde artık demokrasi diye bir oyun sergilemeye gerek yok. Artık başka bir oyun var ve bu oyunda akıllı filan olmak da gerekmiyor. Şimdi Erdoğan çok da ötesini düşünmeden pat diye bir şey yapıveriyor. Ve onun ne anlama geldiğine, nedenine vs. o ve adamlarından çok muhalifleri kafa yoruyorlar.
Yalancı birinin hafızası iyi olmalıdır. Yalancı biri iyi gözlemci olmalıdır. İyi laf yapabilmelidir. Bunlar eskiden bir politikacıda aranan meziyetlerdi. Artık bunlara gerek yok.

Bu değişimin benim için ilginç olan kısmı halkın senelerdir kendisi için oynanan demokrasi oyununu aslında pek de hak etmediğini görmek oldu. Bir doktora ya da bir avukata gitsem, kendimi ona yakın hissetmeme neden olacak şey benim gibi konuşması olmazdı. Hatta pek çok profesyonel meslek erbabı için benim gibi konuşmaması, onu çoğu zaman anlayamıyor olmam, hatta onunla çatışma içinde olmam ona güven duymama neden olurdu. Benden daha çok şey bilmediğini düşündüğüm birine niye kendimle ilgili tasarruflar vereyim ki, değil mi? Ama ilginç bir şekilde konu halk ve onu yönetme iddiasındaki tipler olduğunda bu çok basit mantık çalışmıyor. Halk istisnasız her lafını anladığı ve duymak istediklerini ona söyleyen vasat oyuncuları tercih ediyor.

Oysa, bizi yöneten insanların en az bizim kadar akıllı, donanımlı, dünya görüşü net insanlar olmasını gerekli bir şey olarak görüyor olsaydık, onların her kararının hoşumuza gitmeyebileceğini, çünkü yukarı doğru çekilmenin aşağı itilmekten çok daha rahat bozucu bir şey olduğunu da bilirdik.

Bir işletmeyi, bir atölyeyi, bir çiftliği, bir fabrikayı, bir okulu ya da bir ülkeyi yönetirken, kapasitesi olan yöneticilerin alacağı kararlar yönetilen insanlardan alabildiğine destek ve alkış almayacaktır, bundan emin olabilirsiniz.

Bizi yönetecek kişileri seçmeyi istemek gibi aslında çok da gerekli ve akılcı olmayan bir takıntıyı kutsallaştırmışsak, en azından bu kadarlık bir yönetim deneyimine sahip olmamız gerekmez miydi?

İnsanlar palavra dinlemeyi sıkıcı gerçeklerle yüzleşip kendilerini aptal gibi hissetmeye tercih edeceklerdir. Çevrenizde olup biteni anlamazsanız, içine düştüğünüz durumun farkında olmazsanız belki neşeniz kaçmaz. Ama bu o çevrede yaşıyor olduğunuz gerçeğini de değiştirmez. Bir bakmışsınız iki sene önce satın alabildiğiniz şeylere artık paranız yetmiyor. Bir bakmışsınız çocuğunuz eğitim alamadığı için işe yaramaz bir insana dönüşüyor. Bir bakmışsınız karnınız artık doymuyor. Bir bakmışsınız yapıldığı için nedensizce çok sevindiğiniz köprüden aslında siz hiç geçmiyorsunuz. Bir bakmışsınız siz elektrikli otomobil yapmamıza seviniyorken elektrikli scooter bile alamıyorsunuz.

Bu toplumda akşam saati pazar dağılırken, çer çöpten yiyecek araştırıp hâla gözü bu yalanlardan başka yalan görmeyen insanlar var. Ortak mütteahitlerin milyarlarca euro borcu tek kalemde silinirken kendi kıytırık borcu için namerde boyun bükmek zorunda kalan ama oy vereceği adamda “lider vasfı” arama prensibinden geri adım atmayan feraset sahipleri var. Hayatta teknolojiyle belki de tek ilişkisi, dünyayla tek bağı olan cep telefonuna çakılan ÖTV’yi Osmanlı’yı kuruyoruz, Ay’a gidiyoruz diye sineye çeken budalalar var.

Uzatmayayım örnekleri.. Zaten benden çok şey görüyorsunuzdur siz de.. Şimdi biz önümüze çıkarılan tiplerden tipler beğeniyoruz, oy veriyoruz ve en çok oyu alan gücün başına geçiyor. Kabaca, buna demokrasi diyoruz.
Yukarıda durumlarını özetlediğim milyonlar bir şey mi “seçiyorlar” ki siz her şeyin farkında olan insanlar onlarla aynı sandığa zarf atıyorsunuz? Bence demokrasi hakkında düşünmeye tümevarım yaparak devam etmeliyiz ve tam da bu insanlardan başlamalıyız.

Demokrasiye olan varsayımsal güvenimiz benim “gerçek İslam bu değil” sendromu adını taktığım şeye benziyor: Özünde toplum için oldukça tehlikeli, kendi içinde temel sorunları olan, yaşadığımız çağla uyumsuz bir şey var. Akıllı insanlar tarafından sınırları çizilerek ve modernize edilerek kullanıma sunulmuş. Biz bu oynadığımız şeyi o şeyin aslı sanmışız. Sonra oyunu abartıp, kum havuzumuzdan çıkıp tüm hayatımıza aktarınca elimiz ayağımız yanıyor. Ama üstümüzdeki ateşi söndürmeye çalışırken bile “gerçek İslam bu değil” deyip, bir zamanlar oynamamız için verilmiş “evcilleştirilmiş versiyon”u yâdediyoruz. Oyuncuları suçlamayı tercih ediyoruz.

Bence demokrasi de aynı din gibi. Gerçekliğine gerçekten iman edildiğinde toplumu mahvedecek bir şey. Serbest piyasa koşullarında varlığı yokluğundan daha kârlı olduğu için bir seviyeye kadar varolmasına izin verilen tehlikeli bir şey: Sigara gibi. Ama tüm bunları yana yana isteyenler de insanlar sonuçta, öyle değil mi? İnsanların palavralara bayılmasının suçlusu yalan söyleyenler değil ki. Demokrasiyi de bu yüzden onurlu bir toplumun olmazsa olmazı olarak görüyoruz. Çünkü biz böyle seviyoruz. Bu artık alışkanlık yapmış. Ve bunun farkında olanlar için alışkanlığımızı sorgulamamızı söylemenin riskine değmez.

Medya bile lazımmış.

Ekmek almak için fırına çıkmıştım ve bir tane de Cumhuriyet gazetesi aldım. “Covid19 tespit edilen kişi sayısı 5 oldu” gibi bir manşeti vardı yanlış hatırlamıyorsam. Ondan sonra bir daha gazete falan almadım. Bazen bir şey sarmak veya ateş yakmak için gazete lazım oluyor. Balkonun altındaki depoda tomarla gazete var. Bazen hemen hemen hiç okunmamış cillop gibi Zaman gazetelerine denk geliyorum. Esrarengiz bir biçimde bu gazeteleri milletin kapılarına bırakıyorlardı. Bunlar o döneme ait nüshalar. Harekete haksızlık ediliyor tadında yazılarla dolu. Birkaç tane cemaatçi yavşak ülkenin sahibiyle açıktan pazarlık edecek diye amma da kağıt israf etmişler.
Bazen Posta ya da Sabah gazetesine denk geliyorum. Bu gazetelerde kendinden emin, hatta biraz kasılmış bir genç adamın altında ekonomiye dair kendi kendine üç-dört kez tekrarlayınca sadece gülünç gelen cümleler yazılı oluyor. O genç adam 3 aydır kayıp. Bizim standartlarımıza göre bile fazlasıyla tuhaf bir şekilde ansızın istifa edip ortadan kaybolmasının ardından bunun haberini bile yapmaktan korkan çanak yalayıcı bir it sürüsü şimdi sanki ülkenin sahibi olan adamın damadı olan ve senelerce ekonomiyi yönetmeye çalışıyor gibi gözüken bu adam sanki hiç varolmamış gibi davranıyor.
Neyse ki, gazeteleri uzun süre görmek zorunda değilim. Soba ya da mangal yanar yanmaz beni geçmişe götüren bu sahneler gözden kayboluyorlar.
Çok uzun zamandır gazete almıyorum. Yine çok uzun bir zamandır TV de izlemiyorum. Aslında bu kavramı artık ayırt etmek zamanı geldi: Biz evde TV yayını izlemiyoruz, TV denen bir yüzeyi tamamen ekran olan, duvara asılı büyük aygıttan bizde var, hatta onu her gün açıyoruz. Ama orada patronu adına iktidarı yalayan onursuz adam ve kadınları göstermek için elektrik harcamıyoruz artık.
Ben bir zamanlar bilgisayar başında çalışırken TV’de aktüaliteye dair programları açardım. Konuk(lar) davet edilen konuşmalı programlar olurdu. Çok uzun bir süredir onları da izlemeyi bıraktım.
Eskiden ne diyor acaba bu yavşaklar diye arada girip baktığım “yandaş” ve hatta resmen “trol” haber siteleri vardı. Zavallı insanların kolay kolay hayır diyemeyecekleri şeylerin arasına parti bülteninde bile yazılması kıroluk olacak kabalıkta cümleleri serpiştirip bolca da futbol geyiği ile harmanlayıp etsiz çiğ köfte yaparlardı. Epeydir onların da hâli nice bilmiyorum.
Benim gibi, sosyal bilimler alanında eğitim almamış, kültür sanat yazın faaliyeti takip etmek gibi bir lüksü olmamış, yazılı basınla ilişkisi zamanında arada gazete okumak olmuş olan sıradan bir vatandaşı bile bu medyadan bu kadar bilinçli ve kesin bir seçimle uzaklaştırmış olmalarına dikkatinizi çekerim.
Ben şu yavan hâlimle, değil yazısını okumak, karşıma canlısını çıkarsanız iki üç dakika içinde siktir çekeceğim insanların yazar ya da aydın diye gündemde tutulmalarını anlayamıyorum. Türk ana akım medyasından bu kadar iyi yalıtılmış olduğum halde bana Rasim Ozan Kütahyalı, Nagehan Alçı, Hilal Kaplan, Ahmet Hakan ve adını şimdi ezberden yazma imkanım olmayan daha militan birkaç iktidar yalakası kokuları nereden geliyor inanın bilemiyorum.
Arada twitter’da, haber kanallarında icra edilen tartışma programı tiyatrolarından klipler görüyorum. Yok falanca füze atmış (bu lafı uyduran davarolar da artık füzeyi ne zannediyorarsa) yok filanca ötekinin suratına neler demiş. Ben takip ettiğim kitlenin sonucu olarak “muhalif” geçinen güruhun bu şekilde paylaşımlarını görüyorum. Ötekilerin durumu nedir düşünmek bile istemem. İktidarı yalamak için neredeyse evrim geçirip bir taraflarından yeni bir dil bitecek insanların kanalına çıkıp muhalif konuşma yapıp ertesi gün de twitter’da klibi yayınlanan arkadaş bigbang’den öncesini anlatsa ne yazar?
Madem başladık bir daha da dönmemek üzere bu programlara dair son hatırladığım şeyleri de yazayım.
Olay şudur: İktidar bir gündem belirler ve bunun gerçekte bizim yaşadığımız hayatla alakası bile yoktur. Aynı beş tip o akşam bu gündem hakkında konuşmak için televizyona çıkarlar. Bunların arasında muhalif olanlı da vardır ha. Öğretmeninden söz isteyen ilkokul çocuğu gibi sunucudan konuşma hakkı dilenirler. Diş geçirebildikleri bir “karşıt görüşlü” varsa o esnada nedense kameraya bakmadan atıp tutarlar. Bir de neden bilmiyorum bunlar söz sırası kendilerinde değilken telefonlarıyla oynuyorlar ve en dikkatimi çeken de akıcı ve spontane konuşma yeteneğine kenarından bile sahip değiller.

Türkiye Instagram Facebook ve Twitter aboneliği sayısında nüfusuna oranla dünyanın önde gelen ülkelerinden biri olsa da bu sektörler başta iktidar olmak üzere kitlesel siyasi partilerin paralı trollerinin kirletilmiş bilgi çöplüklerine dönmüş durumdadır. Bu iktidarın yok etmek konusunda en başarılı olduğu şeylerden biri de kuşkusuz medya. Medya, “kitlelere” gündemi daha takip edilebilir kılmak için maymunluk yapmak demektir. Bizde artık bu kamu hizmetini gören maymunlar yok. O yüzden bu necip millet peynire zam geldiğini fiyatlar 2,5 katını geçtikten sonra yavaş yavaş anlar gibi olmaya başladı. Ekonomik durumu anlaması bile yıllar geçmiş olmasına rağmen henüz tam mümkün olmayan bu aziz millet haliyle sosyal hayatımızın yüzlerce sene geriye gittiğinin, eğitim kalitemizin yerlerde süründüğünün, doğamızın bilinçli bir şekilde yok edildiğinin, çalışan haklarının ve orta sınıf yaşam standardının birkaç yaratılmış oligarkın zenginliğine kurban edildiğinin elbette farkına varamıyor. Ve bunda yukarıda uzun uzun anlattığım, gündeme kolay erişimin artık mümkün olmamasının büyük etkisi var.

Son yıllarda bu ülkenin her bir ayrıntısına dair en çok yaşadığım duygu, zamanında beğenmediğimiz şeylerin kaybettikten sonra değerini anlamış olmak. Bu basit blogda bile, geçmişte neleri eleştirdiğimi görünce kendi kendime hayret ediyorum. Şimdi o eleştirdiğim şeylerin daha kötüsünü geri getirmek için büyük mücadelelere gerek var. İşte tüm yanar dönerliği, can sıkan basitliği ve gerekmese bile birilerinin borazanı olmadan duramama huyuna rağmen çok sesli medya lazımmış be birader. Bunu bile aratır oldular bize..

EFM8 DAC

EFM8 ‘in üstündeki DAC biriminden bahsetmeye başlamadan önce, digital-to-analog converter denen şeyler hakkında uzun süre devam eden bir kanaatimi not etmek isterim: DAC bana hep lüks bir şey gibi gelmiştir. ADC bir şekilde en başından beri erişilebilirliği olan bir birimdi. Ama DAC, ister bir mcu’da isterse de bir plc’de olsun, sanki hep maliyeti arttıran bir şey gibi geldi bana.

15 sene kadar önce bir iplik boyama makinesinde, boya desenleri oluşturmak için boya püskürten kafaların dönme hızlarını akan ipliğin uzunluğuna bağlı olarak değiştirilebilir yapmam istenmişti. Bulduğum çözüm küçük bir işlemciyle encoder darbeleri saymak ve 8 bitlik bir DAC’a çıkış vererek asenkron motor sürücülerinin hızlarını değiştirmekti. O zaman National’ın paralel bir DAC’ını kullanmıştım, çıkışa bir de opamp koyunca sonuç muhteşem olmuştu. DAC deyince aklıma hep bu iş gelir.

Yıllar sonra da ilginç bir proje için dalga şekli üretme işiyle uğraşmak zorunda kaldım. Artık işlemcilerin üzerinde oldukça hızlı DAC’lar var. Ayrıca çok yüksek çözünürlüklü PWM’lerin olması zaten pek çok durumda DAC ihtiyacını tamamen ortadan kaldırıyor. Ama ben yine de üzerinde DAC birimi olan mcu’lara ayrı bir gözle bakıyorum.

EFM8’de 4 kanal DAC var. Bunlar iki çift olarak kullanılıyor gibi gösterilse de tamamen bağımsız çıkışlar olarak kullanabiliyorsunuz. Bir çifti, birbirinin aynı ya da eşlenik çıkış üretmek istersek beraber kullanabiliriz. DAC çözünürlüğü 12 bit.

Anlatacağım örnek uygulamada DAC çıkışını ses üretmede kullanıyorum. Bunun için 2 DAC kanalını toplam şeklinde kullanmak için bir devre hazırladım. Bu şekilde basit dalgalardan daha çok harmonik üretmek mümkün.

DAC sinyal yolu (bazı şekiller sevgili kızım tarafından çizilmişlerdir)

Bir stereo kuvvetlendirici kullanıyor olsam da mono ses üretiyorum. Kuvvetlendiricinin yüksek giriş direncinin karşısında iki çıkışı dirençlerle birbirine bağlamak bir toplama kuvvetlendiricisi elde etmemizi sağlıyor. Benim kullandığım amplifikatörün bir bias off girişi de var. Bununla yükleme/geçiş vb. anlarda pop/click türü gürültüler olmasın diye çıkışı kapatabiliyorum.

Referans gerilimini, referans gerilim bölücüsünü (REFGN) ve çıkış sürücüsü kazancını (DRVGN) ayarlayarak çeşitli çıkış aralıkları elde edebiliriz. Ben bunlardan 4 tanesini kullanıcı konfigürasyonu ile seçilebilir yaptım:

Bir dalga üretmek iki eksende hareket etmemizi gerektirir: Y ekseni tahmin etmesi kolay olacağı üzere
V = Vref * REFGN * DRVGN * (DAC0H:DAC0L) / 4095
çarpanlarıyla belirlenir.
X ekseni ise zaman. Dalga şeklimizin çözünürlüğüne bağlı olarak, istediğimiz frekansı bir tam periyotta üretecek bir hızla DAC güncellemesi yapmamızı gerektirir.

Daha açık bir deyişle, bir dalga şeklini 12 örnekle tanımlamışsak DAC güncelleme frekansımız istenen dalga frekansının 12 katı kadar olmalı. Örneğin;

Yandaki dalga şeklini tanımlayan “normalize” sinüs dizisi;
32,48,60,64,60,48,32,16,4,0,4,16

Bu diziyi, DAC’a 208us periyotla yüklersek yaklaşık 2,5ms periyotlu bir sinüs çıkışı alırız. Bu da 400Hz kadar eder. Ses çıkışını test etmek için bunu deneyebiliriz.
Burada ilginç olan iki nokta var: Birincisi sample genlikleri unipolar. Çünkü DAC çıkışımız 0V ile seçtiğimiz pozitif Vref gerilimi arasında bir gerilim üretebilir. O yüzden, genliği simetrik bir işaret üretmek istiyorsak Vref/2 kadarlık bir offset eklememiz gerekir.
İkinci nokta, DAC sayısal değerimizle ilgili. Ben bir dalga şekli tanımlarken onu 0..64 gibi bir aralıkta normalize ederek üretiyorum. Eğer donanımsal değil, yazılımsal genlik ayarı yapmak isterseniz bu 0..64 aralığını 0dB kabul edip, sample değerlerini istediğiniz bir sabitle çarpıp, anlık bir çıkış genliği üretirsiniz.

Eğer bu bir ses işareti ise ters-logaritmik bir adım bölümlemesi volume ayarı için uygun olacaktır. 4095 verilebilecek en büyük çıkış değeridir. DAC çıkışını yüklüyorsanız ve 3V gibi bir range ayarı yaptıysanız çıkışın max. değerden önce doyuma ulaşması tehlikesi vardır.

Aşağıda, genel amaçlı kullanıma uygun bir dalga tablosu tanımı paylaşıyorum. Burada her bir dalga tanımı 24 byte’tan oluşuyor (her sample little endian yerleşmiş 12 word). Bunu denemek isterseniz dikkatinizi çekmek istediğim bir şey var: İlk 4 dalga haricindeki dalga tanımları kendisini 3 kez tekrar ediyor. Yani bunların frekansını hesaplarken x12 değil x4 hızla yükleme yapmalısınız.
code quailfier ile dizinin flash bellekte yerleşmesini sağlıyorum ancak mutlak adres veremiyorum. _at_ directive kullandığınızda değişkenleri başlatamazsınız.
Bu yüzden de, bu işleri denerken en başta yaptığım gibi, çalma kesmesi içinde doğrudan bir code pointer’ı çalıştıramıyorum. Bunun yerine waveTable dizi indeksini volatile bir değişken olarak kullanıp compiler’ın verimliliğine güveniyoruz.

unsigned char code waveTable[288] = 
{ 
	// wav-1 : sine +18dB
	0x00,0x01,0x80,0x01,0xE0,0x01,0xF8,0x01,
	0xE0,0x01,0x80,0x01,0x00,0x01,0x80,0x00,
	0x20,0x00,0x00,0x00,0x20,0x00,0x80,0x00,
       // wav-2 : sine +28dB
	0x00,0x03,0x80,0x04,0xA0,0x05,0xE8,0x05,
        0xA0,0x05,0x80,0x04,0x00,0x03,0x80,0x01,
        0x60,0x00,0x00,0x00,0x60,0x00,0x80,0x01,
	// wav-3 : sine +32dB
	0x40,0x05,0xE0,0x07,0xD8,0x09,0x56,0x0A,
        0xD8,0x09,0xE0,0x07,0x40,0x05,0xA0,0x02,
        0xA8,0x00,0x00,0x00,0xA8,0x00,0xA0,0x02,
	// wav-4: sine +36dB
	0x80,0x07,0x0B,0x40,0x10,0x0E,0xC4,0x0E,
        0x10,0x0E,0x40,0x0B,0x80,0x07,0xC0,0x03,
        0xF0,0x00,0x00,0x00,0xF0,0x00,0xC0,0x03,
	// wav-5: symm.sawtooth +12dB
	0xC0,0x00,0xFC,0x00,0x00,0x00,0x40,0x00,
        0xC0,0x00,0xFC,0x00,0x00,0x00,0x40,0x00,
	0xC0,0x00,0xFC,0x00,0x00,0x00,0x40,0x00,
	// wav-6 symm.sawtooth +24dB
	0x00,0x03,0xF0,0x03,0x00,0x00,0x00,0x01,
        0x00,0x03,0xF0,0x03,0x00,0x00,0x00,0x01,
	0x00,0x03,0xF0,0x03,0x00,0x00,0x00,0x01,
        // wav-7: symm.sawtooth +32dB
	0xE0,0x07,0x56,0x0A,0x00,0x00,0xA0,0x02,
        0xE0,0x07,0x56,0x0A,0x00,0x00,0xA0,0x02,
	0xE0,0x07,0x56,0x0A,0x00,0x00,0xA0,0x02,
	// wav-8: symm.sawtooth +36dB
	0x00,0x0C,0xC0,0x0F,0x00,0x00,0x00,0x04,
        0x00,0x0C,0xC0,0x0F,0x00,0x00,0x00,0x04,
        0x00,0x0C,0xC0,0x0F,0x00,0x00,0x00,0x04,
	// wav-9: sq.wave: +12dB
	0xFC,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,
	0xFC,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,
	0xFC,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,
	// wav-10: sq.wave: +24dB
	0xF0,0x03,0xF0,0x03,0x00,0x00,0x00,0x00,
        0xF0,0x03,0xF0,0x03,0x00,0x00,0x00,0x00,
        0xF0,0x03,0xF0,0x03,0x00,0x00,0x00,0x00,
	// wav-11: sq.wave: +32dB
	0x56,0x0A,0x56,0x0A,0x00,0x00,0x00,0x00,
        0x56,0x0A,0x56,0x0A,0x00,0x00,0x00,0x00,
	0x56,0x0A,0x56,0x0A,0x00,0x00,0x00,0x00,
	// wav-12: sq.wave: +36dB
	0xC0,0x0F,0xC0,0x0F,0x00,0x00,0x00,0x00,
        0xC0,0x0F,0xC0,0x0F,0x00,0x00,0x00,0x00,
	0xC0,0x0F,0xC0,0x0F,0x00,0x00,0x00,0x00
};

DAC güncelleme “frekans” ayarı konusuna geri dönelim: Ben bu iş için Timer-2 kesmesini kullanıyorum. TMR2’ye vereceğimiz bir reload değeri ile DAC güncelleme hızını ayarlarız, böylece dalga üretecimizin X ekseni hassas biçimde ayarlanmış olur.

CKCON0 |= 0x30;   // TMR2 clock source -> SYSCLK
TMR2CN0 = 0;      // 
// çalıştırmak:
TMR2CN0_TR2 = 1;  // bu register bit addressable
// çalma frekansını değiştirmek:
TMR2RLL = rld_L;
TMR2RLH = rld_H; 

TDAC (DAC Erişim Periyodu) = istenen işaret periyodu / N
N : Bir periyodun örnekleme sayısı (yukarıdaki örnekte bu 12)
T2 : (TMR2 tick period) = 1/49M
Reload Değeri = 65536 – (TDAC / T2)

Bir çalma ayarında istenen frekans değerini değil, TMR2 reload değerini saklamayı tercih ediyorum.

TMR2 kesmesinde yapılacak iş “sıradaki” sample’ı DAC’a yazmak. Oynatılacak (veya çalınacak diyelim) dalga örneklerini flash bellekte saklıyorum. Bu noktada iki farklı yaklaşım geliştirdim:
Birinci yöntemde, çalma ayarları yüklenirken (mesela bir sequencer’ın belli bir adımının zamanı geldiğinde) flash’tan, sequencer’ın belirttiği dalga setini okuyorum ve yukarıda anlattığım şekilde düzey ölçeklemesi yapıp (normalize sample’ların volume ayar değeriyle çarpılması) ram’de bir çalma tablosu oluşturuyorum (hatta iki tablo oluşturup biri çalarken diğerini yükleme ve geçişleri hızlı yapma gibi bir şey denedim ama 49MHz çalışmada bu çok kritik bir hızlandırma değil).
Çalınacak sesin genliği ya da dalga şekli değişinceye dek çalma tablosu artık değişmiyor.
İkinci yaklaşım daha sade: Çalınacak sample’ları flash’ta normalize halleriyle değil, ölçeklenmiş halleriyle saklıyorum ve çalma sırasında doğrudan flash’tan okuma yapıyorum. Okunacak dalga tablosu indeksini sequencer yüklemesinde bir rom pointer’ında belirliyorum ve sonra kesme kodunda doğrudan pointer’ı çalıştırıyorum. Bu yaklaşımda TMR2 kesme kodu şöyle:

// Play Kesmesi:
void ISR_TMR2 (void) interrupt 5
{ 
   TMR2CN0_TF2H = 0;
   // playBuffer ba$a sarmasi gerekiyor mu?:
   if ( smpIndex > 11 ) 
   {
     smpIndex = 0;
     playIndex = wavIndex;	// çalma indeksini de ba$a sar.
     // durdurma istegi verilmi$ mi?
     if (STOP_REQ) 
     {
       TMR2CN0_TR2 = 0;  // artik player kesmesi tetiklenmeyecek..
       STOP_REQ = 0;
       return;
     }
  }
    
  ///// DAC Update:
  SFRPAGE = 0x30;     
  DAC0L = waveTable[playIndex];  // yukarida anlattigim mevzu!!
  ++playIndex;
  DAC0H = waveTable[playIndex];
  SFRPAGE = 0;
  ++playIndex;
  ++smpIndex;
  
}

playIndex waveTable’ın sıradaki elemanına erişmek için kullandığımız dizi indeksi. Bunu, çalma adımını yüklediğimizde (ne çalacağımızı bize söyleyen veri) öğreniyoruz ve indeksi başlatıyoruz. Bunun yerine, muhtemelen daha efektif bir kesme kodu için
unsigned char code * volatile data playPtr;
şeklinde bir işaretçi tanımı yapıp bunu çalınacak rom sample’ları boyunca da koşturabilirdik.

Burada, özellikle dikkat edilecek bir nokta var: Kesme kodu içinde SFRPAGE değiştiriliyor. Interrupt handler yedeklemeyi hallediyor mu halletmiyor mu hiç endişe etmemek için, bu kesmeyi başka bir kesmenin kesmesi ihtimalini ortadan kaldıralım. (Böyle cümleleri şık hale getirmeye çalışmak işi sulandırmak olur, sonuçta anlatım bozukluğu yok).
Daha açık konuşursam, bu işlemci bir de UART kesmesi çalıştırıyor (native priority’si daha yüksek). Çipi başlatırken UART kesmesini TMR2 kesmesinden daha düşük öncelikli olacak şekilde ayarlıyorum. Çünkü gelen bir byte biraz bekleyebilir (baudrate düşük).
DAC yazması yaparken başka bir koda atlamak SFRPAGE anahtarlaması dışında da sorunlar yaratacaktır. Çünkü DAC güncelleme hızımız SYSCLK hızında. Bu arada yeri gelmişken onu da not edeyim: DAC güncelleme hızını SYSCLK yapmamızla TMR2 kesmesi içinde DAC yazması yapmamız arasında bir bağlantı yok. DAC’ın kendi güncellemesi başka bir şey. Sanırım yazılımdan daha bağımsız DAC otomasyonları yapmak istersek kullanışlı olur. Yine de, ben merak edip DAC update source ile benim DAC yazma kesmemi aynı timer ile çalıştırdım. Sonuç değişmedi. Sonuçta SYSCLK çok hızlı olsa da biz çıkışı 200kHz hızıyla güncelleyebiliriz (bunu da denedim). Bu, tıpkı ADC’de olduğu gibi, “elektriksel” bir kısıt. Kişisel görüşüm, 200k gayet yüksek bir hız!

Son olarak, bir sequencer (kullanıcı tarafından belirlenmiş dalga şekillerini verilen ayarlara göre bir diziden okumak ve art arda üretmek) yapacaksak, çalmayı anlık olarak durdurmak ve devam ettirmek için kullanabileceğimiz makroları da vereyim:

#define Play_Sequencer()  SFRPAGE = 0x30; DAC0CF0=0x80; SFRPAGE=0; \
			  TMR2L = seqData.pt_rld_L; \
                          TMR2H = seqData.pt_rld_H; \								  
                          TMR2CN0_TR2=1; IE_ET2=1; \ 					  
                          PLAYING=1; MUTE=0; LED1=0
								  
#define Stop_Sequencer()  MUTE=1; \
	  	          TMR2CN0_TR2 = 0; IE_ET2=0; \					  
                          SFRPAGE=0x30; \
			  DAC0L=0; DAC0H=0; \
			  DAC0CF0 = 0; \
			  SFRPAGE=0; PLAYING=0; LED1=1 

Sequencer’ın verilen adımındaki ayarlara bakarak DAC’ı konfigüre etmek de şöyle olabilir:

	// cfg.<pwr> bitlerine bak:
	 switch ( seqData.cfg & 0x03 )
	 {
		case 0:		// 2V çiki$
		  REF0CN = 0x80;	
		  DACGCF2 = 0x11;		  
		  DAC0CF1 = 0x00;
		break;
			
		case 1:	  // 1,2V çiki$
		  REF0CN = 0x40;
		  DACGCF2 = 0x10;
		  DAC0CF1 = 0x00;
		break;
			
		case 2:    // 1,6V çiki$
		  REF0CN = 0x80;
		  DACGCF2 = 0x12;			  
		  DAC0CF1 = 0x00;	  
		break;

		case 3:	 // 2,4V çiki$
		  REF0CN = 0x80;
		  DACGCF2 = 0x10;		  
		  DAC0CF1 = 0x00;
		break;
		
	}

	/// wav pointer'ini ba$latalim:
	wav_address = 0x3C00 + 24 * seqData.wav;	
	playPtr = (unsigned char xdata *) wav_address;
	smpIndex = 0;

        /// çalma frekansini güncelle:
        TMR2RLL = seqData.pt_rld_L;
        TMR2RLH = seqData.pt_rld_H;

Yukarıdaki örnek kodda 12 sample’lık bir wav dizisi kullanılıyor ve flash bellekteki 0x3C00 sayfası bu işe ayrılmış. Kullanıcının seçtiği wav indeksi seqData.wav parametresinden okunuyor.
smpIndex, sınır denetimi yaparken 16 bit sayılarla kendimizi yormayalım diye kullanılan yardımcı bir değişkendir. Kesme koduna bakabilirsiniz.

Sonuçta, gördüğünüz gibi, DAC kullanarak bir dalga şekli üretmek, eğer çıkışta analog bir işaret kullanma ihtiyacınız varsa PWM ile aynı sonucu elde etmeye çalışmaktan daha basit bir iştir. Yukarıda bir audio çıkışı (benim aklıma waveform generator deyince ilk bu geliyor) üzerinden örnek verdim. Ancak daha önce, programlanabilir bir sabit akım kaynağı işi için de bu DAC çıkışını kullanmıştım. Çalıştığımız alan, LED parlaklığını PWM ile ayarlamamızın mümkün olmayacağı bir uygulamaydı. Bu durumda EFM8’in bir çipte 4 adet bağımsız kullanılabilen DAC çıkışlarını bir sabit akım kaynağına referans girişi yaparak basit ama doğruluğu yüksek bir çözüm üretebildik. (Bunu da burada paylaşırım bir ara)

Sıcak bir zemheri

Bu sabah yataktan kalkınca saate baktım: 8.20’yi gösteriyordu.
Perdeyi araladım. Sokak lambaları henüz yanıyordu.
Sonra salona geçip gece lambasını yaktım.
Normalde ilk işimin sobayı yakmak olması gerekirdi ama kısık çalışan kombi yeterli oluyor evi ısıtmaya.
Bilgisayarı açtım. Windows’un başlat menüsündeki Hava Durumu canlı kutucuğuna tıklamışım yanlışlıkla. Ben masadaki notlarıma bakarken ekranda lacivert bir fon üzerinde 10 günlük hava durumu listelenmişti.
10 gün boyunca yağmur gözükmüyor ve sıcaklık bugün 18 derece verilmiş.
Tam şu satırı yazarken yine kontrol ettim: Tarih 26 Aralık.
Benim çocukluğumda yeni yılda kar yağacak mı diye bir heyecanımız olurdu. Hiç unutmuyorum, bir sene tam yılbaşı akşamı saat 8 gibi müthiş bir kar başlamıştı ve o gece her taraf bembeyaz olmuştu. Bunun hangi sene olduğunu sorup öğrenmem lazım. İnsan yaşlandıkça geride birbirine benzeyen çok senesi birikmeye başlıyor.

Kurak bir sonbahardan sonra kurak bir kışa girdik. Zemheri dedikleri dönemdeyiz ama kışın karanlığından başka bir şeyi yok. Ne yağış var ne de soğuk. Bu yazıyı yazarken aklıma 4 sene önce yazdığım 27 isimli yazım geldi. O zaman bir Kasım akşamında havanın 27 derece olması beni şaşırtmış. Bugün öğleden sonra dışarı çıktığımda sıcaklık 20 dereceydi. Aralık 26’da. Sadece dört sene içinde buna şaşırmama şaşırır bir duruma gelmişiz.

Bizimki gibi yerlerde küresel ısınmayı dert etmek gündelik koşuşturmacalarla ilgisi olmayan birinin özenti bir hobisi gibi duruyo olsa da bizim onu dert etmememiz onun gündeminde de bizim olmayacağımız anlamına hiç gelmiyor. Yaşadığımız coğrafya bu çalkantıdan en sert şekilde etkilenecek.

Bahçede çalışırken düşündüm: Gündemde kuraklık var ve büyük şehirlerde su tasarrufu yapmak için söylenen bir iki beylik laftan öte bir şey yok gündemde. Peki, ne yapılabilirdi? Buna yanıt veremiyorum. “İnsanlar” iklim değişirken ne yapabilirler ki? Bırakın bizimkisi gibi ilkel toplulukları, uygar toplumlar bile hiçbir şey yapamazlar bu gidişatı durdurmak için. İçinde doğduğumuz koşullar bu hale sokmuş dünyayı. Bundan ne derecede vazgeçebileceğimiz üstünde bile anlaşamayız ki. İnsanlık böyle yavaş ama güçlü değişimlere tepki verebilecek bir uygarlık kurmamış. Daha kötüsü insan doğası da buna uygun değil.

İşin uygarlık ve insan doğası yanına kadar inmeye gerek yok. Biz, koskoca bir ülkenin bir köşesine devasa bir şehir kurmuşuz ve tüm ekonomimizi o şehirdeki düşük katma değerli faaliyetlere bağlamışız. O şehri beslemeye, o şehrin suyunu karşılamaya ve o şehrin pisliğini bertaraf etmek için oldukça verimsiz bir şekilde çabalıyoruz.. Zaten kırılgan olan bir dünyada, kolayca üretebileceğimiz tarım ürünlerini bile ithal ederek bu kırılganlığı akıl almaz bir budalalıkla arttırmaktan başka bir şey yapmıyoruz. Görünen o ki, biz “muasır medeniyet” seviyesine çıkıp kentlileşene kadar, bildiğimiz anlamdaki kentler sürdürülebilirliğini yitirmeye başlamış olacaklar.

Bunca insanın beni bu kadar korkutan bir şey hakkında durup bir an bile düşünme gereği duymaması beni de kendimden şüphe duymak zorunda bırakıyor.
Kuraklık sezonluk bir şey olabilir mi? Belki de iklim düşündüğümüz şekilde değişmez ya da değişse bile bu beslenmemiz, ekonomimiz ve yaşam standardımız üzerinde olumsuz etki yapmaz, değil mi? Ben hayal ettiğim araziyi alırsam, bir ev daha yaparsam ya da arabamı değiştirirsem kızım için iyi bir gelecek inşa etmiş olabilirim belki?
Tüm bu soruların birer soru olarak kalmalarını isterdim ama en korktuğum kısmı burası: Bunların yantını çok yakında öğreneceğiz gibi duruyor.

ADC Auto-Scan

Bir analog-dijital dönüştürücünün çalışma hızı ölçüm devresine ve ADC’nin yapısına bağlıdır. Öte yandan, çok sayıda analog kanalı örneklemek gibi bir ihtiyacımız varsa “hız”a dair kaygımız genellikle, ADC’nin kendi ölçüm hızı değil bizim kanallar arasındaki geçiş hızımızla ilgili olur. Çünkü biz bir işlemcinin üstündeki ADC’yi kullanıyoruz ve kanallar arasında geçmek ve ölçüm sonuçlarını bir yere yazmak gibi işler dönüştürme işleminden daha çok zaman alıyor.

Eğer çok sayıda analog girişi okumak gerekiyorsa ve dahası, bu kanalların aynı anda alınmış örnekleri (mesela bir besleme hattının akım ve gerilim ölçümü gibi) anlamlıysa veya kesin bir bir zaman aralığında alınmış belli sayıda örnek toplamak istiyorsak bu işleri donanımsal olarak halletmek işimizi çok kolaylaştıracaktır.

EFM8’de bu tür durumlarda kullanabileceğimiz bir tarama fonksiyonu var. Bu fonksiyon ADC modülünün ayarlarından bağımsız olarak istediğimiz zaman kullanabileceğimiz bir örnekleme otomasyonu sağlıyor.

  • ADC’yi istediğiniz referans ve örnekleme/dönüştürme hızı ayarlarıyla ayarlıyorsunuz.
  • Sonra tarama işleminin başlangıç kanalını seçiyorsunuz. Taramada en çok 4 kanal ardışık olarak örneklenebiliyor.
  • Sonra kaç kez örnekleme yapılacağını belirliyorsunuz. Burada, komutla başlatılan tek bir örneklemenin sayısı belirleniyor. Bir örnekleme kendi içinde istenen sayıda oversampling içerebilir.
  • Dönüştürme işlem sonucunun xram’de yazılacağı konumu belirliyorsunuz.
  • İşlemi başlatıyorsunuz.

Tarama ayarını bir kez yaptıktan sonra işlemleri otomatik başlatabilirsiniz. Tarama içindeki iki dönüştürme işlemi arasına sabit bir süre koyabilirsiniz veya tarama içindeki dönüştürmeleri birbirine olabildiğince yakın yaptırabilirsiniz.
Bir tarama işlemi yapılırken sonraki işlem için istenen ayarları hemen berlirleyip ADC’yi durmaksızın arka arkaya farklı ayarlarla çalıştırabilirsiniz. Bu, mesela double-buffering gereken okuma durumlarında işin buffer güncelleme kısmını çok basitleştirir.

Aşağıdaki kod örneği, AN6..AN9 kanallarının birer kez ölçülmesi ile elde edilen sonuçları xram’in 16..23 konumuna big endian olarak yazdırır:

SFRPAGE = 0x30;
ADC0MX = 6;		  // AN6 seç (ba$langiç kanali)
ADC0ASAH = 0x00;
ADC0ASAL = 0x10;	  // sonuçlari xram=16 adresinden itibaren yaz
ADC0ASCT = 3;		  // tarama 4 sample sürer (her kanal 1 kez)
ADC0ASCF = 0xC3;          // 4 kanal örneklenecek..	
ADC0ASCF = 0x43;          // _ASEN = 0
SFRPAGE = 0;
ADC0CN0_ADINT = 0;
ADC0CN0_ADBUSY = 1;

Yukarıdaki kodda en ilginç kısım, ADC0ASCF_ASEN bitini 1 yapıp işlemi başlattıktan sonra hemen sıfırlamamız.
ASEN=1 yapıldığında donanım tarama ile ilgili tüm ayarları dahili belleğe kopyalar. Yani, ASEN=1 yaptıktan sonra tüm ayarları bir sonraki tarama için değiştirebiliriz.

Yukarıdaki ayarlarla, ADINT=1 olduğunda işlemler bitmiş ve sonuçlar xram’e yazılmış olacak. Eğer durmaksızın sonraki 4 kanala geçmek isteseydik _ASEN=0 yapar yapmaz ADC0MX’i ve ADC0ASAL’i değiştirmemiz yeterliydi.

Ben bu örnekte öyle yapmadım ama ADC0ASCF_STEN bitini 0 yapıp ADC’yi bir timer ile tetiklenecek şekilde ayarlasaydık (ADC tetikleme kaynağı ayarının tarama özelliğiyle ilgisi yok) zaman aralıklı tarama çalışması elde etmiş olurduk. Belki ileride bununla ilgili bir örnek de paylaşırım.

ADC işleminin sonucunda üretilen veriyi eşzamanlı olmayan başka bir süreç kullanıyorsa bu işi otomatize etmek ve kullanıcı sürecin sadece ram’deki datayla uğraşmasını kodlamak performansı oldukça arttıracak bir iyileştirme. Donanımı kullanmasını bilmek ile donanımdan bağımsız kod yazmakta konfor aramak arasındaki farka oldukça dramatik bir örnek olarak göz önüne alınabilir.

Ekmek Gramajı

Enflasyonun elbette pek çok sebebi var. Ama 2020’den bakınca 1950’leri 90’larda ve 00’larda baktığımızda gördüğümüzden çok daha kolayca anlayabiliyoruz.

Merkez sağ-muhafazakar iktidarlar daima enflasyon ve hayat pahalılığı getiriyorlar. Yanında bolca iki taşı üst üste koyma, hizmet getirme, kalkınma hikayesini de bedavaya veriyorlar. Gerileyen yalnızca ekmek ağırlığı değil, sosyal haklar, sabit gelirlinin alım gücü, eğitim kalitesi vb.

Bunu karşılığında da ülkenin zenginliği belli bir kesime transfer ediliyor. Yani siz boğazınızdan kısıyor, yiyeceğinizin bir kısmını ve sahip olmanız gerekenleri iktidarın o dönemki zengin sınıfına bağışlıyorsunuz. Karşılığında da akşam haberlerinde size kalitesi günden güne düşen bir prodüksiyon sunuluyor.

İşbirlikçi, hain, ahlaksız tipler merkez sağ üzerinden politikaya girdikleri için bunlar oluyor, solcularsa süper adamlar zaten demek istemiyorum. Bunu merkez sağ, muhafazakar, dinciler yapmayı başarıyorlar çünkü bu ülkede bunu yapabilecek güce sadece onlar erişebiliyorlar. Kısaca yapıyorlar, çünkü yapabiliyorlar. Sorun, 1950’lere bakınca bile aynı şeyi gördüğümüze göre yapmaları da değil zaten.

Not: Ekmek zamanla küçülmeliydi zaten, yeme alışkanlıkları değişti diyenlere şu anda dünyanın en çok ekmek tüketen ülkesi olduğumuzu hatırlatırım. Buna karşılık, et ve balık tüketiminde kaçıncıyız bilmiyorum ama üst sıralarda değilizdir diye tahmin ediyorum.