HIROBIRO

HIROBIRO

金銭的、精神的自由を目指すブログ。

炊飯器の残量カウンターを電子工作で作った(2)(カウンタ機能作成編)

f:id:hirokun1735:20180303190056j:plain
 

前回の記事では炊飯器の残量カウンターの仕様を決め、必要になるマイコンや部品を紹介しました。
炊飯器の蓋の開閉回数から米の残量を把握し、LCD表示やアラームで教えてくれるシステムです。
次にArduinoで残量カウンターのプログラムを作成し、マイコンと傾斜センサを接続するケーブルを作成します。


 ちなみに前回の記事はこちらです。
www.hirobiro-life.com

LCDボードのサンプルプログラムについて

購入したLCDボード「サインスマートLCDキーパッドシールド」についてですが、サンプルプログラムが用意されています。

しかしこのプログラムはArduino IDEの初期バージョン用であり、最近のバージョンのプログラムでは上手く反応しません。


解決策をネットで検索したところ、サンプルプログラムで使われているライブラリ「DFR_Key」を別のライブラリ「LCDKeypad」に変更すればよいと分かりました。
このライブラリはサンプルプログラムを入手するためにダウンロードしたフォルダの中に入っているので探してみてください。

 

改良したサンプルプログラムは以下に書いておきます。

/*
Key Codes (in left-to-right order):

None   - -1
Select - 4
Left   - 3
Up     - 1
Down   - 2
Right  - 0

*/

#include <LiquidCrystal.h>
//#include <DFR_Key.h>
#include <LCDKeypad.h>

//Pin assignments for SainSmart LCD Keypad Shield
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); 
//---------------------------------------------

//DFR_Key keypad;
LCDKeypad keypad;

int localKey = 0;
String keyString = "";
                 
void setup() 
{ 
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Key Grab v0.2");
  delay(2500);

  Serial.begin(9600);            // 9600 bpsで通信する
  Serial.println("Start");       // 最初に1度だけ Start を表示
}

void loop() 
{ 
  //localKey = keypad.getKey();
  localKey = keypad.button();
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Current Key:")
  lcd.setCursor(0, 1);
  lcd.print(localKey);
  Serial.println(localKey);
  delay(100);
}

残量カウンターに必要な機能とは

このLCDのサンプルプログラムを基本として残量カウンターへと改良していきます。
とりあえず必要な機能を書き出すと以下の4つです。


①炊いた米の量に応じてカウンタ初期値を自分で設定
②傾斜スイッチがONするとカウントダウン
③カウンタが0になるとカウンタストップ&アラームで知らせる
④カウント中でもボタンを押してカウンタの数字を変更可能


今回は炊飯器の蓋の開閉回数で残りの米残量を調べるシステムです。
そのためある程度の誤差が出ることは想定しています。
蓋を間違えて開けることもあるでしょうし、ちょっとしかご飯をよそわないこともあるでしょう。
上で書いた④の機能はそういった場合に調整できるようにするためです。


アラーム機能だけはスピーカーが必要です。
今はまだ購入していないので後回しにして他の機能を実装しました。

ハードウェア作成

前回の記事で必要な部品は紹介し、さらにLCDボードの動作確認までしています。
LCDボードはArduinoの上からそのまま挿して取りつけます。
LCDボード上の端子にジャンパワイヤを繋げて傾斜センサと接続するのですが、ピンソケットをはんだ付けしておくと自由に抜き差しできて楽です。


f:id:hirokun1735:20180310000248j:plain


また傾斜センサから出ているピンはそのままジャンパワイヤのメス側と接続できます。


f:id:hirokun1735:20180310000101j:plain



さてこの傾斜センサとArduinoとの接続ですが、下の回路図のように配線しました。
これを作っていたときは気付いていなかったのですが、もう少し簡略化できます。


f:id:hirokun1735:20180310000102j:plain


この回路ではアナログ入力ピンA2に傾斜センサのON/OFF信号を入れています。
ONなら5Vを抵抗分圧した3.35V、OFFなら0Vが入力されます。
しかし実は抵抗R1は必要ないのです。


これはスイッチがONして5VとアナログピンA2が短絡すると過電流が流れると思って入れました。
しかし仕様書を確認するとアナログ入力ピンは入力インピーダンスが100MΩとなっているため、電流制限抵抗がなくても過電流は流れないのです。
というわけでこの記事を書いている今は抵抗は外しているのですが、とりあえずこの回路のまま話を進めます。
抵抗R2は必要ですよ。5VとGNDを短絡するとArduinoは壊れます。


この回路になるようジャンパワイヤを少し改造しました。
途中で線を切って間に抵抗を入れたり、別のジャンパワイヤと接続して配線を分岐させています。


f:id:hirokun1735:20180308003910j:plain


残量カウンタープログラム

残量カウンターのハードウェアの試作機は出来上がりました。
ここからはArduinoでプログラミングです。
作ったプログラムは以下です。

/*
Key Codes (in left-to-right order):
None   - 5
Select - 4
Left   - 3
Up     - 1
Down   - 2
Right  - 0
*/

#include <LiquidCrystal.h>
//#include <DFR_Key.h>
#include <LCDKeypad.h>

//Pin assignments for SainSmart LCD Keypad Shield
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); 
//---------------------------------------------

LCDKeypad keypad;

int localKey = -1;
int mode = 1;
int first_rice = 5;   //米の量 X杯分
int rice = 0;
int sensor = 2;   //センサ信号アナログ入力ピン
int AnalogPin = 0;
int en_input1 = 1; //ボタン入力受付
int en_input2 = 1; //センサ入力受付
                 
void setup() 
{ 
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Rice Counter");
  lcd.setCursor(0, 1);
  lcd.print("Start");
  delay(2500);

  rice = first_rice;

  //keypad.setRate(10);

  //Serial.begin(9600);            // 9600 bpsで通信する
  //Serial.println("Start");       // 最初に1度だけ Start を表示
}

void loop() 
{ 
  localKey = keypad.button();
  AnalogPin = analogRead(sensor);
  //Serial.println(localKey);
  
  if(mode == 1){
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Rice Counter");
    lcd.setCursor(0, 1);
    lcd.print(rice);
    delay(100);

    if(en_input1 == 1){
      if(localKey == 1) {   //UPボタンで増やす
        rice += 1;
        en_input1 = 0;
      }else if(localKey == 2) {   //DOWNボタンで減らす
        rice -= 1;
        en_input1 = 0;
      }
    }else if(localKey == -1){   //UP,DOWNボタンから指を離すと次の入力受付
      en_input1 = 1;
    }

    //アナログ入力3V=614 スイッチonのとき3.35V
    if(en_input2 == 1){
      if(AnalogPin >= 614){   
        rice -= 1;
        en_input2 = 0;
        delay(1500);
      }
    }else if(AnalogPin <= 10){
      en_input2 = 1;
    }

    
      if(rice == 0) {
        mode = 2; //残り0で表示固定モードに移行
      }
    
  }else if(mode == 2){
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Rice Empty");
    lcd.setCursor(0, 1);
    lcd.print(rice);
    delay(100);    

    if(localKey == 4){
      mode = 1; //開閉カウントモードに移行
      rice = first_rice;
    }
  }
}

押ボタン入力について

押しボタン入力でカウンタの数字を増減できるようにするのは以下に書いた部分です。

 if(en_input1 == 1){
      if(localKey == 1) {   //UPボタンで増やす
        rice += 1;
        en_input1 = 0;
      }else if(localKey == 2) {   //DOWNボタンで減らす
        rice -= 1;
        en_input1 = 0;
      }
    }else if(localKey == -1){   //UP,DOWNボタンから指を離すと次の入力受付
      en_input1 = 1;
    }


最初は単純にUPボタンを押してlocalKeyが1になったら変数riceを1増やすとしていました。
しかしこれでは1回ボタンを押したつもりなのに数字が2以上増えてしまうことがあります。
またボタンを長押しすると押している間はずっとカウントが増え続けます。


理由は簡単で、マイコンがプログラムを処理するスピードが速いためです。
ボタン入力時間よりもマイコンが電圧を読み取る周期の方が短いために複数回ボタンを押されたと判定されるのです。


これを防ぐため、上のプログラムでは変数en_input1を使ってボタンをどれだけ長押ししてもカウンタが1以上は増えないようにしています。
一度ボタンから手を放してから再度ボタンを押すことで再び数字が変わるようになります。

傾斜スイッチ入力について

傾斜スイッチでも押ボタンと同じ問題が発生します。
炊飯器の蓋を開け、蓋に取りつけたセンサが傾くとセンサに電流が流れてカウンタが1減ります。
ご飯をよそう間はどうしても蓋を開けっ放しにするのでどんどん数字が減ってしまうのです。


また傾斜スイッチに限らず物理的なスイッチは入力されるときにわずかな機械的振動が発生します。
これは「チャタリング」と呼ばれる現象ですが、この振動のせいで1回だけ入力したつもりが複数回入力されたと判定されてしまいます。
傾斜スイッチに関するプログラムは以下の部分です。

 //アナログ入力3V=614 スイッチonのとき3.35V
 if(en_input2 == 1){
   if(AnalogPin >= 614){   
     rice -= 1;
     en_input2 = 0;
     delay(1500);
   }
 }else if(AnalogPin <= 10){
   en_input2 = 1;
 }


押ボタンスイッチのときと同様に変数en_input2を使って数字がどんどん変化しないようにしています。
またdelay(1500)を用いることで蓋を開けてから1.5秒待機するようにしています。
これは炊飯器の蓋を開けたときの蓋の振動がある程度収まるのを待つためです。

炊飯器に取りつけてテスト

プログラムとハードウェアが出来上がったので実際に炊飯器に取りつけてテストです。
Arduinoは電源アダプタでコンセントから給電し、傾斜センサは炊飯器の蓋の奥の邪魔にならない箇所にテープで貼り付けます。


f:id:hirokun1735:20180303190043j:plain


蓋を開けても配線が邪魔にならないことも確認します。


f:id:hirokun1735:20180303190056j:plain


実際に蓋を開け閉めして確かめたところ、ちゃんとカウンタとして機能することが確認できました。
これならちゃんと使えそうです!



炊飯器残量カウンタ試作機テスト


まとめ

Arduinoとジャンパワイヤ、傾斜センサを接続して残量カウンタのハードウェアを作成しました。
またArduinoにプログラムを書き込み、カウントミスが少なくなるようなカウンタ機能を実装しました。
次回は実際に炊飯器に接続して気付いた点を改良していきます。


次回の記事はこちら
www.hirobiro-life.com