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ı

ATtiny Düşük Güç Modu

Kurulu Devre Görüntüsü

ATtiny Düşük Güç Modu

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.

ATtiny Düşük Güç Modu

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:

5V3V
1 Mhz8 Mhz1 Mhz8 Mhz
Çalışma Esnasında2.5 mA8 mA0.7 mA3.6 mA
Uyku Modunda0.5 µA0.5 µA0.2 µA0.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ı

ATtiny Düşük Güç Modu

Kurulu Devre Görüntüsü

ATtiny Düşük Güç Modu

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.

ATtiny Düşük Güç Modu

Bu pilin(CR2032) yaklaşık kapasitesine 200mA olarak kabul edersek, hesaplamalar sonucunda neredeyse 200 senelik bir pil ömrünü bize veriyor.

 5V3V
ATtiny4020.11µA0.10µA
ATtiny850.47µA0.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;                    
}