Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * スリープへの移行とボタン押下による復帰
- * https://www.hiramine.com/physicalcomputing/atmega328/sleepbuttonwakeup.html
- */
- #include <avr/sleep.h>
- #define LEDPIN (13)
- unsigned long bootTime;
- void setup() {
- Serial.begin(115200);
- Serial.println("-- Sleep Test Start --");
- // スリープ中の消費電力を最小限に抑えるために、
- // i) 出力ピンは電流を供給なし
- // ii) 入力ピンは一定
- // にする。
- // i) ii) を実現する簡単な方法は、内部プルアップ抵抗を有効にすること。
- for ( int i = 0; i < 20; i++ )
- {
- pinMode(i, INPUT_PULLUP);
- }
- // LEDピンのセットアップ
- pinMode( LEDPIN, OUTPUT );
- digitalWrite( LEDPIN, LOW );
- bootTime = millis();
- Serial.println("Wake Up!");
- Serial.print("Boot Time: ");
- Serial.println(bootTime);
- }
- void loop() {
- Serial.print("Now Time : ");
- Serial.println(millis());
- // リセットかスリープモードへ移行
- if ((millis() - bootTime) > 300000) { // 5分経ったらリセット
- Serial.println("Reboot!");
- delay(100);
- software_reset();
- } else if ((millis() - bootTime) > 60000) { // 1分経ったらスリープ
- Serial.println("Good Night!");
- delay(100); // println が終わるまでの時間調整
- Sleep();
- } else {
- blink();
- }
- }
- void blink() {
- for (int i = 0; i < 2; i ++) {
- digitalWrite(LEDPIN, HIGH);
- delay(100);
- digitalWrite(LEDPIN, LOW);
- delay(400);
- }
- delay(1000);
- }
- void software_reset() {
- asm volatile ("jmp 0");
- }
- // 外部割り込みの結果呼び出される関数
- void wakeUpNow() {
- bootTime = millis();
- Serial.println("Good Morning!");
- Serial.print("Wake Time : ");
- Serial.println(bootTime);
- delay(30000); // 時間調整。30秒ととても大きな数字だけどこれだとバグらなかった。
- }
- void Sleep() {
- // ① アナログ・デジタル・コンバータ機能を無効にする(少しでも電力消費を抑えるため)
- byte adcsra_old = ADCSRA; // ADC Control と Register Aの設定値の以前の値を保持。
- ADCSRA = 0; // アナログ・デジタル・コンバータ機能の無効にする。
- // ② スリープモードを設定する(②⑤⑧でセット)
- set_sleep_mode(SLEEP_MODE_PWR_DOWN);
- // ③ 割り込み機能を無効にする(④⑤の処理を確実に実行するため)
- noInterrupts(); // cli()でも同じ
- // ④ 電圧降下検出機能を無効にする(少しでも電力消費を抑えるため)
- sleep_bod_disable();
- // ⑤ スリープ機能を有効にする(②⑤⑧でセット)
- sleep_enable();
- // ⑥ 割り込み機能を有効にする(④⑤の処理を実行したので元に戻す)
- interrupts(); // sei()でも同じ
- // ⑦ 外部割り込み条件を設定する(Wakeするための外部割り込み条件の割込設定)
- attachInterrupt(0, wakeUpNow, LOW); // INT0端子(2番ピン)の立ち下がりで割り込み発生。wakeUpNow関数が呼ばれる。
- // ⑧ スリープ実行(②⑤⑧でセット)
- sleep_cpu();
- // (⑧によってスリープに移行する。⑦で設定した外部割り込みでWakeし、⑨の処理が実施される)
- // ⑨ スリープ機能を無効にする(⑦で設定した外部割り込みでWakeしたので、スリープを無効にする)
- sleep_disable();
- // ⑩ 外部割り込み条件の設定を解除する(Wakeしたので)
- detachInterrupt(0);
- // ⑪ アナログ・デジタル・コンバータ機能を有効にする(Wakeしたので)
- ADCSRA = adcsra_old;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement