Lesson 11 Membrane Switch Module
メンブレンスイッチによるキーボードです。
Wikipedia:メンブレンキーボード
https://ja.wikipedia.org/wiki/メンブレンキーボード
内部構造は、単なるスイッチ。配線は8本です。多い。
列ごと、行ごとのON / OFF を検出するので、列用に4つ、行用に4つでピン8つ使います。
サンプルプログラムにキーパッド用のライブラリが付属しているので、それを使います。
内容は、こちらのライブラリでした。
Arduino Library List:KeyPad
https://www.arduinolibraries.info/libraries/keypad
初期値として、キーの配列、使用する縦横のピン番号を設定。
const byte ROWS = 4; //four rows const byte COLS = 4; //four columns //define the cymbols on the buttons of the keypads char hexaKeys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad //initialize an instance of class NewKeypad Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
キー状態を取得して、入力があればコンソールに表示。
char customKey = customKeypad.getKey(); if (customKey){ Serial.println(customKey); |
起動して、キーボードのボタンを押すと…
押したキーの文字が出ましたー。
今回も、実際の処理はライブラリの中の実装です。見てみましょう。
今回使っているのは getKey()関数。
char Keypad::getKey() { single_key = true; if (getKeys() && key[0].stateChanged && (key[0].kstate==PRESSED)) return key[0].kchar; single_key = false; return NO_KEY; }
getKeys() でキー全体の状態を更新。
複数キー対応の場合は key 配列に順次複数キー押下状態が入るみたいですね。
今回はシングルキーのみ対応なので、key[0]の状態をチェック。状態が変化していて、かつ押下状態であれば、key[0].kchar が押されたキーのキャラクターとなるようです。
getKeys() の中まで追っていくと、かなり深いとこにはまりそうなので、今回はここまでとします…。キーボード制御は keyUp / keyDown の処理や、複数同時押下、チャタリング対策など、いろいろと考えないといけないので、かなり複雑です。
ピン8本の接続が必要になるので、今回のパーツは、M5Stackとの接続はナシでーす。(接続できたとしても、処理が複雑すぎて簡単には作れない気がする…。)
Lesson 12 DHT11 Temperature and Humidity Sensor
温度&湿度計、DHT11です!
部品からピンが4本出てますけど、実際は3本しか使わないです。あと、抵抗の接続が必要とのこと。
キット付属のパーツは、抵抗実装済みで、使うピンだけの3本ピン状態になっています。
SimpleDHTというライブラリを使って計測。
SimpleDHT
https://github.com/winlinvip/SimpleDHT
実行!
あれれ?うまくいかない…。
SimpleDHTに新しいバージョンが出てるみたいなのアップデートしてみる。もう一度実行!
うーん、結果は出るようになったけど、2回に1回、失敗になってますね。
あっ、DHT11の説明で、
Remark: For DHT11, no more than 1 Hz sampling rate (once every second).
ってあるので、
待ち時間 delay(1000); だと微妙な個体差でギリギリアウトになってるのかも。
ちょっと長めの delay(1100); にしたところ…
うまくいったー。
Sample DHT11... Sample RAW Bits: 0011 1011 0000 0000 0001 1101 0000 0011 0101 1011 Sample OK: 29 *C, 59 %
コンソールへの出力は、RAW Bits で取得したそのままのデータを出して、その後、それを変換した温度と湿度を出しています。
データは、上から、湿度整数部8ビット、湿度小数部8ビット、温度整数部8ビット、温度小数部8ビット、パリティ8ビットになっています。
パリティは8ビット区切りを上から足したものです。
0011 1011 + 0000 0000 + 0001 1101 + 0000 0011 = 0101 1011 ですね。
DHT11の解像度的に、小数部は基本的には 0000 になるはず。だけど温度が微妙に変。誤差かな…。
整数部を10進数にすると、
湿度: 0011 1011 = 0x3B = 59 (%)
温度: 0001 1101 = 0x1D = 29 (℃)
で、表示通りの値となりました。
今回も実際の処理はライブラリの中。どうやって値を取得しているか見てみます。こういう手順でした。
1.センサーへの計測開始を指示する:
LOWを20ms。その後、HIGHを 20~40 uS にする。これが計測開始の指示。
2.センサーが反応しているのを確認する:
ピンをINPUTに変更して、ピンの状態を確認。
ピンの状態が LOW 80uS、その後 HIGH 80uS になったら、DHT11側も計測開始したということ。
3.データの受信:
計測開始になったら5バイト(湿度2バイト、温度2バイト、パリティ1バイト)のデータが1ビットずつ連続して送られてくる。
データの送り方は、最初に LOW状態が 50uS 続き、その後 26~28uS がHIGHならデータ値は「0」。70uSが HIGHなら「1」。以降繰り返し。
LOW/HIGH だけの信号でバイト列送信するのもなかなか大変だ。
というか、こんなふうに逐次的に反応をする仕掛けが小さくて安価な DHT11 の中に入ってるってのもすごいよね。
DHT11の電源は3.3~5.5Vなので、M5Stack の Grove 端子からの電源でも動作可能です。
ということで、M5Stack Grove端子からの接続。
DHT11でも計測いけましたー。 pic.twitter.com/r13bywjw0v
— Nochi (@shikarunochi) 2018年9月19日
MicroPytho用のDHT11ライブラリは無かったので、今回は、Arduino で Adafruit の DHT ライブラリを使って動作しています。
M5Stackのチャージングベース(新型)には、DHT12 が付属しています。DHT12は、DHT11よりも細かくデータが取得でき(0.1度単位)、誤差も少なく、I2Cによる2本ピン接続で、より安定した動作が可能になっているとのことです。良いですねー。
知的好奇心 for IoT:WiFi温度・湿度計をDHT11からDHT12にアップグレードした
http://intellectualcuriosity.hatenablog.com/entry/2017/09/25/193739
DHT12は、MicroPython用ライブラリあったので MicroPythonでの動作です。
M5Stack FIRE用に買ったGroveケーブル到着!
…が、ツメがジャマで差し込めない!
ちょっとあせりましたが、ツメ切って無事装着完了です。
Grove経由でチャージベース内蔵のDHT12と通信して温度取得まで確認できましたー。 pic.twitter.com/8WrO8xhLAE— Nochi (@shikarunochi) 2018年9月18日
M5Stackと合体させて使うと、M5Stack本体の発熱を受けてしまうのが難点である…。