ATtiny202 電池長持ちSleep

ATtiny202LowPowerEyecatch
SBMJOB

ATtiny202小さいのでプラモデルに組み込みやすいのでボタン電池で動かしたいですよね。LED光らせる等の電力をあまり消費しない回路ならSleepモードを活用して電池を長持ちさせてみましょう。

目次

スポンサーリンク

目的

  • 電池を長持ちさせる
  • LEDを一定時間光らせて消す
  • タクトスイッチで再度LEDを光らせる

実装の大枠

一定時間LEDをゆっくり光らせたら、スリープモードに入れて電力消費を抑える。スイッチをおしたら割り込みでまたLEDを光らせる。という具合です。

情報収集

古い製品群のATtinyはこちらの情報が有用です。

あわせて読みたい

ATtiny202等の情報はこちらが有用です。

あわせて読みたい

ATtiny202のデータシートではこちらの章を読むといいでしょう。

https://akizukidenshi.com/goodsaffix/attiny202-402.pdf

上記PDF のSleep Controller (SLPCTRL)辺りを読むと理解が深まると思います。

あわせて読みたい

回路図

ソースコード

/* 10秒でスリープしてボタンで割り込みして再度光らせる
*/

#include <avr/sleep.h>

// Arduino pins

const int ledPin = 1;                 // PA7 LED pin
const int Button = 4;               // PA3 pushbutton

const int Unused2 = 2;              // PA1
const int Unused3 = 3;              // PA2
const int Unused5 = 5;              // PA0/UPDI
const int Unused6 = 0;              // PA6

// Constants
const unsigned long sleep10Sec = 10000; // led sleep in 10 sec

ISR(PORTA_PORT_vect) {
  PORTA.INTFLAGS = PORT_INT3_bm;        // Clear PA3 interrupt flag
}


void setup() {
  pinMode(ledPin, OUTPUT);
  PORTA.PIN3CTRL = PORT_PULLUPEN_bm;    // Same as pinMode(Button, INPUT_PULLUP);
  // Don't leave unused pins floating
  pinMode(Unused2, INPUT_PULLUP);
  pinMode(Unused3, INPUT_PULLUP);
  pinMode(Unused5, INPUT_PULLUP);
  pinMode(Unused6, INPUT_PULLUP);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
}

void loop () {
  unsigned long StartTime = millis();
  static unsigned int duty = 255;
  while (millis() - StartTime < sleep10Sec) {

    analogWrite(ledPin, duty--); //change the duty cycle
    if (!duty) {
      duty = 255;
    }
    delay(10);

  }
  // sleep in 10 sec
  digitalWrite(ledPin, LOW);
  delay(500);
  PORTA.PIN3CTRL = PORT_PULLUPEN_bm | PORT_ISC_LEVEL_gc; // Pullup + Trigger on low level
  sleep_cpu();
  // Continue after interrupt
  PORTA.PIN3CTRL = PORT_PULLUPEN_bm;                     // Turn off pin sense interrupt
}

ポイント

ATtinyのsleepライブラリをインクルード

#include <avr/sleep.h>

使用しないピンはプルアップで電圧の揺れを防止するとともに省電力化

SLEEP_MODE_PWR_DOWNにモード設定

  • SLEEP_MODE_IDLE :Idle with all peripherals running for immediate wake-up
  • SLEEP_MODE_STANDBY :Configurable operation of selected peripherals SleepWalking peripherals
  • SLEEP_MODE_PWR_DOWN :with full data retention

sleep_enable() スリープモードを利用可能としています。

const int Unused2 = 2;              // PA1
const int Unused3 = 3;              // PA2
const int Unused5 = 5;              // PA0/UPDI
const int Unused6 = 0;              // PA6

void setup() {
  .
  .
  .

  // Don't leave unused pins floating
  pinMode(Unused2, INPUT_PULLUP);
  pinMode(Unused3, INPUT_PULLUP);
  pinMode(Unused5, INPUT_PULLUP);
  pinMode(Unused6, INPUT_PULLUP);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
}

PA3のピン制御ポート(PORTA.PIN3CTRL)にプルアップとレベル割り込みを設定しています。
割り込みピンPA3をスイッチにしているので、スイッチを内部プルアップしてグランドに接続された時に割り込みが発生する!という意味です。

割り込みの種類はの四種類

  • 両エッジ BOTHEEDGES
  • 上昇感知エッジ RISING
  • 落下感知エッジ FALLING
  • 低レベルエッジ LEVEL

PORT_ISC_LEVEL_gc のLEVEL部分を上記に置き換えて指定します。

PORTA.PIN3CTRL = PORT_PULLUPEN_bm | PORT_ISC_LEVEL_gc; // Pullup + Trigger on low level

指定したスリープモードでスリープさせます。

  sleep_cpu();

タクトスイッチを押した時の割り込み時にINTFLAGSをクリアするためのメソッド
この辺りはレジスタのオンオフなのでとりあえずこれで覚えておきましょう。

ISR(PORTA_PORT_vect) {
  PORTA.INTFLAGS = PORT_INT3_bm;        // Clear PA3 interrupt flag
}

sleep_cpu()でスリープに入った後に、タクトスイッチを押して割り込み発生させたらsleep_cpu()直後から再開されるので、すかさず制御ポートを元に戻しておきましょう。

sleep_cpu();
  // Continue after interrupt
  PORTA.PIN3CTRL = PORT_PULLUPEN_bm;                     // Turn off pin sense interrupt

電流実測

スリープ時の電流を測定してみましょう。電池のプラスとATtiny202のVCCの間にマルチメータを差し込んで
簡単ですが全体の電流を測定すると。

0.1μA かなり低電流になっており十分低い値となっています。

スポンサーリンク

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

システム開発SE・アプリ開発・デバッガー等々なんでもやる猫の下僕です。現在は凶暴猫にカタカタ動く手を狙われながらキーボードを打っています。かなりゆるい性格なのでコメントやメッセージお気軽に〜お仕事のご依頼もお気軽にぃ〜

スポンサーリンク

コメント

コメントする

CAPTCHA


目次