ATtiny Düşük Güç Modu
ATtiny uygulamarı genelde diğer mikroişlemciler ve geliştirme kartları ile yapılan uygulamardan epey farklı oluyor. Bu farklara sebep olan başlıca etmen ATtiny mikroişlemcilerinin küçük ve yetenekli olmasını söyleyebiliriz.
Peki şu ana kadar yaptığınız ATtiny projelerinizde güç tüketimini neredeyse yarı yarıya azaltabileceğinizi söylesek ATtiny olan ilginiz artar mı? ATtiny düşük güç modu özellikleri ile projelerinizin pil ömrünü oldukça uzatacak ve geri dönüşü zor olan ya da sürekli erişilmesi güç olan senaryolarda hayat kurtaracaktır.
Bu içerikte, ATtiny85 ve ATtiny402 mikroişlemcileri kullanılarak işlemler yapılacaktır. Fakat elinizde aşağıdaki listede olan bir ATtiny mikroişlemcisi varsa, doğrudan belirtilen kısımda olan işlemleri aynı şekilde yapabilirsiniz.
ATtiny85 için olan bölüm: ATtiny25, ATtiny25V, ATtiny45, ATtiny45V, ATtiny85, ATtiny85V uyumludur.
ATtiny402 için olan bölüm: ATtiny202 uyumludur.
ATtiny85 Düşük Güç Uygulaması
Öncelikle kullanacağımız ATtiny85 mikroişlemcisine gerekli testleri yapabilmek ve program kodunu yüklemek için bir programlayıcıya ihtiyacımız var, bu konuda istediğiniz yolu izleyebilirsiniz, öneri olarak USB-AVR ya da doğrudan ATtiny85 geliştirme kartlarında olan programlayıcı kısımını kullanabilirisiz.
Ayrıca daha önce ki ATtiny85 içeriğimizde Arduino IDE desteğini ve nasıl program yüklendiğini anlattık buradan detaylara bakabilirsiniz.
Mikro USB, Type-C girişli ATtiny geliştirme kartları doğrudan programlanmayı destekler bu yüzden her hangi bir harici programlayıcıya ihtiyaç duymazsınız.
Bu program kodu yani senaryo için ATtiny85 oldukça yeterli bir mikroişlemcidir, 8 pinli olan bu mikroişlemci, 5 I/O pini sayesinde bir çok uygulamanın altından kalkabilir.
Program kodunu basit olması için şöyle yapalım; 15 dakikalık bir sayaç oluşturalım ve sayaç çalışırken her 2 saniyede LED’i yakalım ve 15 dakikalık süre bitince alarmı çalalım. Ayrıca reset sinyali geldiği zaman programı başa alıp tekrar başlatalım.
Devre Şeması

Kurulu Devre Görüntüsü

Kod kısmında belirtilmediği sürece, ATtiny85 varsayılan olarak 1 Mhz zamanlayıcısını yani timer’ını kullanır. Ayrıca 8 Mhz dahili saatide isterseniz seçebilirisiniz. Bu seçimi doğrudan Arduino IDE kısmından da yapabilirsiniz. Fakat 8 Mhz saati kullanmak için bu adımları takip etmelisiniz: Kart ayarları kısmından 8 Mhz saat hızını seçip, Araçlar kısmından “Önyükleyici Yazdır(Burn Bootloader)” seçeğine basmanız gerekiyor, bu olay aslında ATtiny85 mikroişlemcisine bir önyükleyici yazdırmıyor fakat, gerekli pinleri yani fuse ayarlarını 8 Mhz için yapmış oluyor.
Düşük Güç Modu(Uyku Modu)
ATtiny85, düşük güç uyku modunu destekler, bu uyku zamanında, saat durur, ADC ve I/O kısmına harcanan akım sınırlanır ve güç tasarrufu sağlanmış olur.
Mikroişlemciyi uyku modundan uyandırmanın dört yolu vardır:
- Reset pini (0) kesmesi(interrupt) ile.
- Pin değişim kesmesi(interrupt) ile.
- Watchdog Timer(Güvenlik Zamanlayıcı) kesmesi(interrupt) ile.
- Universal Serial Interface (USI) ile başlatma komutu vererek.
Bu uygulamamızda, uyandırmayı reset sinyali ile yapacağız aslında bir nevi pin 0 kesmesi olarak düşünebiliriz. Üstte ki 4 farklı yöntemi diğer uygulamalarda kullanıp bunlar hakkında bilgi vereceğiz.
Kullanmak istediğimiz uyku modunu bu şekilde tanımlıyoruz:
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
Uyku modunu aktifleştirmek için bu komutları kullanıyoruz:
sleep_enable();
sleep_cpu();
Uyku Modunu Optimize Etmek
Eğer yaptığınız projede bazı fonksiyonlar ve özellikler kullanılmıyorsa, bu kısımları uyku kısmında ya da program kısmında tamamen kapatabilirsiniz. ATtiny85’in veri sayfası(datasheet)na göre aşağıdaki özellikleri kapatabilirsiniz:
- Analog to Digital Converter (ADC) = Analog Dijital Dönüştürücü
- Analog Comparator = Analog Karşılaştırıcı
- Brown-out Detector
- Watchdog Timer = Güvenlik Zamanlayıcısı
- Pin Outputs = Pin Çıkışları
- Analog Input Buffer = Analog Giriş Tamponu
Yukarıdaki özelliklerden varsayılan olarak sadece ADC özelliği aktif gelmekte, bu özellik bile tek başına uyku modunda yaklaşık 320µA kullanmakta ve bu değer siz her hangi bir ADC özelliği ya da kodu kullanmamanıza rağmendir.
Aşağıdaki kod ile kolay bir şekilde ADC özelliğini devre dışı bırakabilirsiniz, biz bu kodu setup() kısmında kullanacağınız.
adc_disable();
Analog Comparator, Brown-out Detector ve Watchdog Timer ve Analog Input Buffer varsayılan olarak etkinleştirilmemiştir, dolayısıyla bunları devre dışı bırakmanın bir avantajı yoktur.
Giriş ve çıkış pinlerini (I/O) uyku fonksiyonunda önce tanımlamanız programın ve projenin devamlılığı için önemli bir adım olabilir, bunu tam olarak test edebilecek bir ortam oluşturamadık fakat, böyle yapamamız mantıklı geldi.
Sonuçlar
3V Saat pili ile yapılan testlerde uyku esnasında anlık olarak 0.2µA güç tüketimi gerçekleşti.

Bu pilin(CR2032) yaklaşık kapasitesini 200mA olarak kabul edersek, hesaplamalar sonucunda neredeyse 40 senelik bir pil ömrünü bize veriyor.
3V ve 5V voltajlarda, 1 Mhz ve 8 Mhz saat hızlarında ölçülen değerler:
5V | 3V | |||
1 Mhz | 8 Mhz | 1 Mhz | 8 Mhz | |
Çalışma Esnasında | 2.5 mA | 8 mA | 0.7 mA | 3.6 mA |
Uyku Modunda | 0.5 µA | 0.5 µA | 0.2 µA | 0.2 µA |
Program Kodu
/* ATtiny85 Düşük Güç Uygulaması */ #include <avr/sleep.h> // Utility macro #define adc_disable() (ADCSRA &= ~(1<<ADEN)) // ADC kapatma // constants const int buzzer = 1; // buzzer pini const int LED = 0; // led pini const unsigned long Alarm = 900000; // alarm süresi - 15 dakika unsigned long BaslamaZamani = 0; // başlama zamanı void setup () { pinMode(LED, OUTPUT); pinMode(buzzer, OUTPUT); pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); pinMode(4, INPUT_PULLUP); adc_disable(); // ADC uses ~320uA set_sleep_mode(SLEEP_MODE_PWR_DOWN); } void uykuModu (void) { sleep_enable(); sleep_cpu(); } void bipSesi (void) { for (int i=0; i < 500; i++) { digitalWrite(buzzer, HIGH); delay(1); digitalWrite(buzzer, LOW); delay(1); } } void LedYakma (int wait) { digitalWrite(LED, HIGH); delay(wait); digitalWrite(LED, LOW); } // Ana Döngü ---------------------------------------------- void loop () { // uzun led LedYakma(125); delay(125); LedYakma(125); do { // led yakma kısmı LedYakma(1); delay(2000); } while (millis() - BaslamaZamani < Alarm); // Alarm sesi bipSesi(); uykuModu(); // Sıfırlamadan sonra devam }
ATtiny402 Düşük Güç Uygulaması
ATtiny402, ATmel’in geliştirdiği ATtiny serisi mikroişlemcilerin yeni bir üyesi olduğunu belirtebiliriz. ATtiny ve ATmega mikroişlemci serisinde yapılan büyük güncelleme ile, adlandırılma ve özellikler oldukça değişti.
Bu değişim ve güncellemeye buradaki yazımızdan erişebilirsiniz.
ATtiny402, yeni isimlendirmeye göre 0-serisi olarak geçmekte, bu mikroişlemciyi özellikle tercih etme sebebimiz sıklıkla kullandığımız ATtiny85’e oldukça benzemesidir.
ATtiny85 ile yaptığımız projenin aynısını bu mikroişlemci içinde uygulayacağız, yani:
15 dakikalık bir sayaç oluşturalım ve sayaç çalışırken her 2 saniyede LED’i yakalım ve 15 dakikalık süre bitince alarmı çalalım. Ayrıca reset sinyali geldiği zaman programı başa alıp tekrar başlatalım.
Devre Şeması

Kurulu Devre Görüntüsü

ATtiny402 sadece SOIC kılıfında mevcut, bu yüzden DIP olarak kullanmak için bu şekilde lehimlemek gerekiyor.
Düşük Güç Modu(Uyku Modu)
Tıpkı ATtiny85’te olduğu gibi bu mikroişlemcide 3 farklı uyku modunu destekler; boşta(idle), bekleme(standby) ve güç kapalı(power-down). Güç kapalı uyku modu en düşük güç tüketimini sağlar; bu, işlemciyi ve RTC’nin watchdog zamanlayıcısı (WDT) ve Periyodik Aralık Zamanlayıcısı (PIT) kısmı dışındaki tüm çevre birimlerini kapatır.
İşlemciyi uyku modundan uyandırmanın üç yolu vardır:
- SENSE pini kesmesi(interrupt) ile.
- TWI adres eşleşmesi ile.
- Periodic Interval Timer(PIT) (Periyodik Aralık Zamanlayıcısında) bir zaman aşımı oluşturarak.
ATtiny85 bölümünde reset pini ile güç modundan uyandırma işlemi yapmıştık fakat yeni ATtiny mikroişlemcilerinde reset pini bulunmuyor bu yüzden pin-sense kesmesi kullanarak bu işlemi yapacağız.
Kullanmak istediğimiz uyku modunu bu şekilde tanımlıyoruz:
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
Uyku modunu aktifleştirmek için bu komutları kullanıyoruz:
sleep_cpu();
Pin-Sense Interrupt(Kesmesi)
Yeni AVR mikroişlemcileri her pinde dört tür kesmeyi destekler: Her iki kenarı algıla (BOTHEDGES), yükselen kenarları algıla (RISING), düşen kenarları algıla (FALLING) ve düşük seviyeyi algıla (LEVEL).
Ancak, bu kullanımda doğrudan bir komplikasyon olabiliyor. Asenkron pinler olarak adlandırılan bazı pinler, bu dört giriş türünden herhangi biriyle işlemciyi uyku modundan çıkarabilir; ATtiny402’de bu asenkron pinler PA2 ve PA6’dır.
Diğer pinler sadece BOTHEDGES ve LEVEL kesmelerinde işlemciyi uykudan uyandırabilir. Basit olması için, belirli bir pin seçme ihtiyacını ortadan kaldıran bir LEVEL kesmesini PA3 pini üzerinde kullandık. Her I/O pininde, giriş çekme ve kesme algılama tipini yapılandırmak için ayrı bir pin kontrol portu bulunur. PA3 için pin kontrol portu PORTA.PIN3CTR‘dir ve PA3’te bir pullup ve bir LEVEL kesme algısı yapılandırma ifadesi şudur:
PORTA.PIN3CTRL = PORT_PULLUPEN_bm | PORT_ISC_LEVEL_gc;
Farklı bir sense türü istiyorsanız, LEVEL kelimesini BOTHEDGES, RISING veya FALLING ile uygun şekilde değiştirebilirsiniz.
Ayrıca bir kesme hizmeti rutini sağlamamız gerekiyor, ancak kesmeyi yalnızca işlemciyi uyku modundan çıkarmak için kullandığımız için bunun PA3 kesme bayrağını temizlemekten başka bir şey yapmasına gerek yok:
ISR(PORTA_PORT_vect) {
PORTA.INTFLAGS = PORT_INT3_bm;
}
Doğruluk
Zamanlayıcı süresi, milisaniye cinsinden şu ifadeyle belirtilir:
const unsigned long Alarm = 900000;
Bu zamanlayıcı, zamanlaması için işlemci saatini kullanır, bu nedenle doğruluk, dahili sistem saatinin doğruluğuna bağlıdır.
Bu projenin orijinal versiyonunda kullanılan ATtiny85’te, dahili RC osilatörünün fabrika kalibrasyonu ±%10 olarak derecelendirilmiştir. OSCCAL kaydını kullanarak özel bir kalibrasyon yaparak bunu ±%1’e kadar yükseltebilirsiniz veya harici bir kristal bağlayabilirsiniz.
ATtiny402’deki dahili RC osilatörünün fabrika kalibrasyonu çok daha doğrudur, ±%2. Ancak, harici bir kristal bağlama seçeneğiniz yoktur.
Uyku Modunu Optimize Etmek
Uyku modundayken güç tüketimini en aza indirmek için I/O hatlarını boş girişler olarak bırakmamak önemlidir; aksi takdirde salınım(osilasyon) yaparak güç tüketebilirler. setup() ‘da üzerlerinde giriş pullup’larını etkinleştirerek bundan kaçınabiliriz :
pinMode(Kullanılmayan2, INPUT_PULLUP);
pinMode(Kullanılmayan3, INPUT_PULLUP);
pinMode(Kullanılmayan5, INPUT_PULLUP);
Alternatif olarak bunları çıktı olarak tanımlayabilirsiniz.
ATtiny85’te ADC’yi devre dışı bırakmak önemliydi, aksi takdirde bu uykuda önemli ölçüde güç çekerdi. Yeni ATtiny’lerde ADC otomatik olarak devre dışı bırakıldığından bu işlem burada gerekli değildir.
İşlemci saat hızı, işlemci çalışırken güç tüketimini etkilese de, işlemci daha sonra durdurulduğundan uyku akımıyla ilgisi yoktur.
Sonuçlar
3V Saat pili ile yapılan testlerde uyku esnasında anlık olarak 0.1 µA güç tüketimi gerçekleşti.

Bu pilin(CR2032) yaklaşık kapasitesine 200mA olarak kabul edersek, hesaplamalar sonucunda neredeyse 200 senelik bir pil ömrünü bize veriyor.
5V | 3V | |
ATtiny402 | 0.11µA | 0.10µA |
ATtiny85 | 0.47µA | 0.17µA |
Sonuç olarak, ATtiny402’nin uykuda, özellikle 5V besleme voltajında, eski ATtiny85’ten önemli ölçüde daha düşük akım kullanmasıdır.
ATtiny402 Programı Derlemek
ATtiny402 programını SpenceKonde isimli GitHub kullanıcısının oluşturduğu megaTiny Core’unu kullanarak derleyebilirsiniz. Board menüsünde megaTinyCore başlığı altında bulunan ATtiny412/402/212/202 seçeneğini seçin. Sonraki seçeneklerin aşağıdaki gibi ayarlanıp ayarlanmadığını kontrol edin (diğer seçenekleri göz ardı edin):
Çip: ” ATtiny402 “
Saat Hızı: “5MHz”
Programcı: “jtag2updi (megaTinyCore)”
Ardından programı bir UPDI programlayıcı kullanarak ATtiny402’ye yükleyebilirsiniz. Make UPDI Programmer’da açıklandığı gibi bir herhangi bir Arduino kartını UPDI programlayıcıya çevirebilirsiniz.
“Açıklamada flash ve önyükleme bellekleri bulunamıyor” hatasını görmezden gelebilirsiniz.
Program Kodu
#include <avr/sleep.h> const int Speaker = 0; // PA6 buzzer pini const int Lamp = 1; // PA7 LED pini const int Button = 4; // PA3 buton const int Kullanilmayan2 = 2; // PA1 const int Kullanilmayan3 = 3; // PA2 const int Kullanilmayan5 = 5; // PA0/UPDI // Constants const unsigned long Alarm = 900000; // 15 dakika void playBeep(void) { tone(Speaker, 523, 250); delay(250); tone(Speaker, 659, 250); delay(250); tone(Speaker, 523, 500); delay(500); noTone(Speaker); } void flashLed (int wait) { digitalWrite(Lamp, HIGH); delay(wait); digitalWrite(Lamp, LOW); } ISR(PORTA_PORT_vect) { PORTA.INTFLAGS = PORT_INT3_bm; // PA3 bayrağini temizlemek } // Main loop ********************************************** void setup() { pinMode(Lamp, OUTPUT); pinMode(Speaker, OUTPUT); PORTA.PIN3CTRL = PORT_PULLUPEN_bm; pinMode(Kullanilmayan2, INPUT_PULLUP); pinMode(Kullanilmayan3, INPUT_PULLUP); pinMode(Kullanilmayan5, INPUT_PULLUP); set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); } void loop () { unsigned long StartTime = millis(); flashLed(125); delay(125); flashLed(125); while (millis() - StartTime < Alarm) { flashLed(1); delay(2000); } // Alarm playBeep(); delay(1000); PORTA.PIN3CTRL = PORT_PULLUPEN_bm | PORT_ISC_LEVEL_gc; sleep_cpu(); PORTA.PIN3CTRL = PORT_PULLUPEN_bm; }
Yorum yapma özelliği, forum tarafından gelen istek sebebiyle kapatılmıştır. Lütfen tartışmalar ve sorularınız için topluluk forumumuza katılın.