2013年4月22日月曜日

Sleepと外部入力(タクトスイッチ)による復帰の仕方(その3)

今回は、いよいよ、外部入力(タクトスイッチ)による復帰を完成させます。
回路とスケッチを確認していきます。

回路図は以下のとおりです。
赤い線は、
Arduinoの5Vポート

青い線は、
Arduinoの2番ピン

オレンジの線は、
ArduinoのGND

それぞれ接続します。









Arduinoの2番ピンは、割り込みID 0です。
抵抗を入れているのは、大きい電流が流れるのを防止します。



スケッチは、以下のとおりです。

#include <avr/sleep.h>
#include <avr/interrupt.h>

int count=0;
int ret=0;
int pinNo=2;
char val;

void setup(){
  pinMode(2,INPUT);
  pinMode(13,OUTPUT);
  Serial.begin(9600);
}
void wakeup(){
   Serial.println("Wakeup!!");
   delay(100);
}

int sleepAndWakeup(int interruptNo){
     Serial.println("sleepAndWake Process start!!");
     delay(100);
     if(digitalRead(2)==LOW){
     Serial.println("PinNo.2 Low Level");
     delay(100);
     }else{
     Serial.println("PinNo2 High Level");
     delay(100);
     }
     Serial.println("sleep enable");
     delay(100);
     attachInterrupt(0,wakeup,FALLING);
     noInterrupts();
     set_sleep_mode(SLEEP_MODE_PWR_DOWN);
     sleep_enable();
     interrupts();
     sleep_cpu();
     sleep_disable();
     detachInterrupt(interruptNo);
     return 0;
}

void loop(){
  //Serial Output
  Serial.print(count);
  Serial.println(" sec");
 
  //LED Output
  if ((count % 2)==0){
    digitalWrite(13,HIGH);
  }else{
    digitalWrite(13,LOW);
  }
 
  count++;
  delay(1000);
 
  if (Serial.available()){
    val=Serial.read();
    if (val=='s'){
      Serial.println("Sleep mode start!!");
      delay(100);
      count=0;
     
     ret=sleepAndWakeup(pinNo);
    }
   
  }
}

長いので、パートに分けて、解説します。

#include <avr/sleep.h>  この行と次の行でライブラリーを組み込んでいます。
#include <avr/interrupt.h>     
int count=0;     
使用する変数を宣言しています。
int ret=0;
int pinNo=2;
char val;

void setup(){ 
  pinMode(2,INPUT);    
割り込みように使います。
  pinMode(13,OUTPUT);  
動作を概観から知るためです。
  Serial.begin(9600);     
シリアル通信を使うためです。
}



ここからが今回のポイントです。休止と復帰の処理です。


void wakeup(){       復帰後の処理として呼び出されます。
   Serial.println("Wakeup!!");
   delay(100);
}

int sleepAndWakeup(int interruptNo){     
休止の処理です。
     Serial.println("sleepAndWake Process start!!");
     delay(100);
     if(digitalRead(2)==LOW){          
確認のため2番ピンの入力レベルを表示     Serial.println("PinNo.2 Low Level");      HIGHが正解です。
     delay(100);
     }else{
     Serial.println("PinNo2 High Level");
     delay(100);
     }
     Serial.println("sleep enable");
     delay(100);
     attachInterrupt(0,wakeup,FALLING);  
0は割り込みIDを示しています。
     noInterrupts();               
割り込みを無効にして休止を実行します。
     set_sleep_mode(SLEEP_MODE_PWR_DOWN); 
休止モードを指定します。
     sleep_enable();    
休止処理を実行します。
     interrupts();     
割り込みを有効にして復帰を待ちます。
     sleep_cpu();     
CPUも休止します。      
     sleep_disable();   
タクトスイッチが押されLOWレベルになる復帰開始
     detachInterrupt(interruptNo);  
割り込み処理を解除します。
     return 0;
}




休止と復帰を呼び出すLOOPの処理です。

void loop(){
  //Serial Output
  Serial.print(count);   
秒数を表示します。
  Serial.println(" sec");
 
  //LED Output     
LEDの点滅を処理します。
 if ((count % 2)==0){
    digitalWrite(13,HIGH);
  }else{
    digitalWrite(13,LOW);
  }
 
  count++;
  delay(1000);
 
  if (Serial.available()){    
    val=Serial.read();    
    if (val=='s'){       
sキーがシリアル通信で入力されたら、休止開始です。
      Serial.println("Sleep mode start!!");
      delay(100);
      count=0;
     
     ret=sleepAndWakeup(pinNo);  
今回作成した休止の処理を呼び出します。
    }
   
  }
}



実行結果です。



















5秒後にsキーを送信し、しばらくしてから、ブレッドボード上にタクトスイッチを
押して、復帰させています。

実験成功です。



0 件のコメント:

コメントを投稿