2013年4月14日日曜日

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

前回に引き続き、Sleepと外部入力による復帰の実装方法を考えます。

今回のゴールは、シリアルコンソールからの指示でArduinoを休止させるです。

標準でArduinoIDEに組み込まれている sleep.h ライブラリからスタートします。


私の環境だと、ライブラリ本体のファイルは下記のパスにありました。
C:\TOOL\arduino-1.0.3\hardware\tools\avr\avr\include\avr\sleep.h

マニュアルは、以下のパスにありました。
C:\TOOL\arduino-1.0.3\hardware\tools\avr\doc\avr-libc\avr-libc-user-manual\group__avr__sleep.html


例として、次のように記載されています。

    #include <avr/sleep.h>   ・・・この文はSleep関連の関数を使うために必要です。
    ...
      set_sleep_mode(<mode>);  ・・・Sleepモードを指定します。
      sleep_mode(); ・・・Sleepモードに入ります。

と、ここで set_sleep_mode(<mode>); で引数になるmodeでは何を指定するかが知りたいです。
これは、前回の表にあった、SleepModeです。
Sleep mode と スケッチ内での指定値
  idle ... SLEEP_MODE_IDLE
  ADC  ... SLEEP_MODE_ADC
  Power-down ...  SLEEP_MODE_PWR_DOWN
    Power-save ... SLEEP_MODE_PWR_SAVE
  Standby ...  SLEEP_MODE_STANDBY
  

Power-Downを使いたいので、SLEEP_MODE_PWR_DOWN と書きます。
 
休止モードの動作確認
  シリアル接続でPC側から"s"を送信したらSleepモードに入ります。
  休止モードに入ったかどうかを外から分かるように、
  13番PinのLEDを点滅させます。
 
 
スケッチは、次のようになります。

スケッチ
#include <avr/sleep.h>

int count=0;
char val;

void setup(){
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  pinMode(13,OUTPUT);
  Serial.begin(9600);
}

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;
     
     sleep_mode();     
    }
   
  }
}


スケッチの解説 << setup ブロック>>
 #include <avr/sleep.h>

int count=0;
char val;

void setup(){
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  pinMode(13,OUTPUT);
  Serial.begin(9600);
}



 #include <avr/sleep.h> .....  ライブラリを使うことを宣言。
                お約束事項です。

 set_sleep_mode(SLEEP_MODE_PWR_DOWN);    
            ..... スリープモード(休止モード)を決めます
               今回は、Power-Downモードです。

  pinMode(13,OUTPUT); ..... 動作確認用に13番ピンを出力指定。
  Serial.begin(9600); ..... シリアル接続ができるようにします。



スケッチの解説 << loop ブロック>>

void loop(){
  //Serial Output
  Serial.print(count);
  Serial.println(" sec");
 
  //LED Output
  if ((count % 2)==0){
    digitalWrite(13,HIGH);
  }else{
    digitalWrite(13,LOW);
  }
  


//Serial Output      ..... シリアル出力へカウントアップ表示
  Serial.print(count);
  Serial.println(" sec");
 


//LED Output    ..... ボード上(13番)のLEDを点滅させます。
   if ((count % 2)==0){  ..... 2で割った余りを使って       digitalWrite(13,HIGH);      奇数と偶数で処理を分岐
   }else{
    digitalWrite(13,LOW);
  }
 



  count++;
  delay(1000);
 

  count++;  ..... count変数を1増加させます。
  delay(1000);  ..... 1000ミリ秒待ちます。つまり1秒待ちます。


  if (Serial.available()){
    val=Serial.read();
    if (val=='s'){
      Serial.println("Sleep mode start!!");
      delay(100);
      count=0;
     
     sleep_mode();     
    }
  }


  if (Serial.available()){ ..... シリアル通信の受信をチェック 
   val=Serial.read();   ..... 受信したんだから、val変数へ保存
     if (val=='s'){   ..... val変数の内容が"s"かをチェック
       Serial.println("Sleep mode start!!");  
            ..... "s"だったので、スリープ開始!! と表示
      delay(100);  ..... PC側へ表示の処理が届くのをチョッと待つ。
       count=0;  ..... count変数を0に初期化。休止するから
            不要だけど、きちんとしておきたいので。     
     sleep_mode();     
..... ここで、スリープモード開始
     }
  }





接続図
いわゆるシリアル接続だけの直結です。あえて、絵にするまでも無かったですが。(笑)







実験
実際に、動かしたときのシリアルモニターの表示です。



















0 secから、1秒毎に、カウントアップされ表示されます。
8sec が表示されたあたりで、PCから s を送信しました。

ボード上のLEDも一秒毎にチカチカしていましたが、それも止まります。

実験、成功です。








0 件のコメント:

コメントを投稿