[arduino]デジタルな居場所表示板をarduino nanoと1602A (16×2 LCD)で作製する
昇任して居室がもらえたのだけれど、前の使用者が自分の名前が刻印されたものが残されるのを嫌ったのか、部屋の前に据え付けてあった居場所表示板を根こそぎ引っぺがしていったので(下の写真で壁紙がはがれているのがお分かりかと思う)、私だけちゃんとした居場所表示板がないという状況になってしまった。それで、元々あったアナログな表示板(在室、授業、学外などのラベルに指示棒を手で動かすタイプ)を購入したいと思ったのだが、実際はこんな特殊なものはアマゾンやモノタロウにも売っていない、あるいは、あっても積極的に欲しいと思うようなデザインではなかった。そこで、私が「欲しい!、カッコイイ!」と思うようなデジタルなものを自作することにした。
主な材料はarduino nanoと16×2 の液晶と、小さな連結可能なブレッドボード。消費電力を抑えるため、あえて液晶制御用のI2C基盤は使わない。元々9V、650mAhの充電式電池で運用しようと考えたのだが、arduinoをスリープさせても10mAhぐらいは待機電力を消費するらしく、持続時間は最大で3日程度にとどまって現実的ではない。そこで部屋のドアのそばにあるコンセントからUSBを介して電力を供給するようにした。表示の切り替えはタクトスイッチ一つで順送りに変更できるようにして、在室している時だけバックライトが付くようにコードした。
下に回路図を示す。抵抗の値はうろ覚え(未だにバンドパターンから抵抗値を読み取るのが苦手)だが、液晶のコントラスト調整用に2kΩ、バックライト用 5pin digital outに470Ωの抵抗を入れたと思う。タクトスイッチは回路図では”RST”に入っているように見えるが、実際には足を窮屈に折り曲げて片方をGNDに入れている。スイッチ操作についてはたまにチャタリングするが、いろいろ試した結果、シンプルに0.1秒のdelayを入れることで基本的には素直に作動する。現時点で設置してから一ヶ月が経過したが、問題なく表示できている。
コードは下記。無論、アルファベット表記しかできないので、表示項目は英語で記述している。現在は、「在室」、「センター内」、「センター外」、「ウェブミーティング中」、「出張」、「帰宅」の6項目にしている。これ以上項目が多くなるとタクトスイッチを押す回数が増えて面倒になるかと思う。
#include <LiquidCrystal.h>
// LCD ←→ Arduinoのピンの割り当て
// rs → D6
// rw → D7
// enable → D8
// d4 → D9
// d5 → D10
// d6 → D11
// d7 → D12
// [構文]LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)
LiquidCrystal lcd(6, 7, 8, 9, 10, 11, 12);
const int buttonPin = 3;
int buttonState = 0;
int count = 0;
void lcd_indicate(void);
#define PUSH_SHORT 100
int count_low = 0;
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(5, OUTPUT); //バックライト用デジタル出力
}
void loop() {
if(digitalRead(buttonPin) == LOW){ //スイッチが押されているとき
if(count_low <= PUSH_SHORT)count_low ++;
}else{ //スイッチが押されていないとき
count_low = 0;
}
if(count_low == PUSH_SHORT){
count=count+1;
if(count==6){
count=0;
}
delay(100);
lcd_indicate();
}
}
void lcd_indicate(void){
if(count==0) {
lcd.begin(16, 2); // LCDの桁数と行数を指定する(16桁2行)
digitalWrite(5, HIGH); // バックライトON
lcd.clear(); // LCD画面をクリア
lcd.setCursor(0, 0); // カーソルの位置を指定
lcd.print("Takeshi is"); // 文字の表示
lcd.setCursor(0, 1); // カーソルの位置を指定
lcd.print("in the room."); // 文字の表示
}
if(count==1) {
lcd.begin(16, 2); // LCDの桁数と行数を指定する(16桁2行)
digitalWrite(5, LOW); // バックライトOFF
lcd.clear(); // LCD画面をクリア
lcd.setCursor(0, 0); // カーソルの位置を指定
lcd.print("Takeshi is"); // 文字の表示
lcd.setCursor(0, 1); // カーソルの位置を指定
lcd.print("elsewhare in ARC."); // 文字の表示
}
if(count==2) {
lcd.begin(16, 2); // LCDの桁数と行数を指定する(16桁2行)
digitalWrite(5, LOW); // バックライトOFF
lcd.clear(); // LCD画面をクリア
lcd.setCursor(0, 0); // カーソルの位置を指定
lcd.print("Takeshi is"); // 文字の表示
lcd.setCursor(0, 1); // カーソルの位置を指定
lcd.print("outside of ARC."); // 文字の表示
}
if(count==3) {
lcd.begin(16, 2); // LCDの桁数と行数を指定する(16桁2行)
digitalWrite(5, LOW); // バックライトOFF
lcd.clear(); // LCD画面をクリア
lcd.setCursor(0, 0); // カーソルの位置を指定
lcd.print("Takeshi is busy"); // 文字の表示
lcd.setCursor(0, 1); // カーソルの位置を指定
lcd.print("for webmeeting."); // 文字の表示
}
if(count==4) {
lcd.begin(16, 2); // LCDの桁数と行数を指定する(16桁2行)
digitalWrite(5, LOW); // バックライトOFF
lcd.clear(); // LCD画面をクリア
lcd.setCursor(0, 0); // カーソルの位置を指定
lcd.print("Takeshi is away"); // 文字の表示
lcd.setCursor(0, 1); // カーソルの位置を指定
lcd.print("on a trip."); // 文字の表示
}
if(count==5) {
lcd.begin(16, 2); // LCDの桁数と行数を指定する(16桁2行)
digitalWrite(5, LOW); // バックライトOFF
lcd.clear(); // LCD画面をクリア
lcd.setCursor(0, 0); // カーソルの位置を指定
lcd.print("Takeshi"); // 文字の表示
lcd.setCursor(0, 1); // カーソルの位置を指定
lcd.print("returned home."); // 文字の表示
}
}