今回は、二代目となるスタータキットを購入した話です。
「第2回 Arduino初心者スタータキット到着」の回で、初心者卒業宣言をしたにもかかわらず、二代目のスタータキットって、どゆこと?などと、我ながら思ってしまったのですが、またしても、費用対効果の高さに惹かれて購入してしまいました。
まず、Arduino DIYを進めるにあたって、筆者が欲しかったモジュールが以下です。
後ろに、それぞれ、単体で購入した場合の金額を記載しておきました。実は、本当に、「単体」で購入できていたら、もっと安いはずなのです。電源モジュール×5個セットで750円って……。さすがに個人のDIYで5個も要らないでしょ?通販での購入を基本に考えたところ、こんな感じでした。恐らく、配送料との兼ね合いで、「配送料無料」を謳うためには、1個150円で販売してしまうと足が出てしまうため、5個セット750円みたいな価格設定になっているもの、と推定します。
筆者が今回購入したのは、以下のスタータキットです。
Iduino UNO R3 スタータキット:3,186円
最初に購入したスタータキットをELEGOOスタータキット、今回購入分をIduinoスタータキットと呼ぶことにします。上でリストアップした、使ってみたかったモジュール類は全て入っていて、この価格です。もちろん、すべてのモジュールは1個づつしか入っていませんので、もし、複数必要な方は、たぶん、バラで購入したほうが安いですよ。
「今すぐ、使いたい、必要」、と、言うほどではないけれど、「あれば」、使ってみたいと思っていたモジュールも、キットに含まれていました。以下、そのリストです。
更に、電子工作する上で、前回の(初代)スタータキットには含まれなかったのだけれど、いつか必要になりそうな部品で、二代目スタータキットに含まれていたリストがこちら(↓)です。
前節、欲しかったモジュールの単体購入価格だけでも元が取れているというのに、おまけで色々と遊べそうなモジュールや部品がそろっていて、お得感モリモリです。
外観はこんな感じ(↓)です。
ELEGOO(初代)スタータキットとはボリュームが違います。
一度取り出すと、もう、元には収まらないというほど、ぎっしり詰め込んでありました。
こちら(↓)がArduinoとしては3機目、Arduino UNOとしては2機目となる、UNO本体です(Iduino UNOと呼ぶことにします)。
橙色の基板がユニークです。そして、今回も、ATmega328P-PUの雄姿が見えます。ソケット実装です。ただ、ちょっと、1機目のUNO(ELEGOO UNOと呼びます)の方がユーザ思いなところがあって、好感が持てました。
老眼だと、ピンソケットにジャンパを挿そうとするときに、ピンソケットの入り口と、基板のシルク面の距離が鬼門で、同時にピントが合わないため、「どの穴がVccだ?」って、なってしまうのですが、ELEGOO UNO(上図の上側)のように、ピンソケットの側面に名前が印字されているのはすごく助かります。
なので、気温・湿度ログ取得用の機体を、今回購入したIduino UNOに割り当てて、ELEGOO UNOを普段使いにしようと思いました。
万能シールド基板上に構成した、気温・湿度取得用のAM2302装置を、ELEGOO UNOからゴソっと外して、そのままIduino UNOへ換装しました。Iduino UNOの方に、気温・湿度取得用プログラムを書き込んだら、「以上終了」です。
Iduino UNOも、ELEGOO UNOと同様、USB⇔UART変換マイコンにATmega16U2が搭載されていましたので、USBに挿したところ、ELEGOO UNOと同じ通信ポート名で接続されました。従って、Windows側の測定スクリプトのポート名すら、変更する必要なく、そのまま動いてしまいました。
それにしても簡単。回路やソフトウェアの互換性もさることながら、フォームファクタまで統一されているのが利いています。全く異なる2社から販売されている、Arduino UNO互換機なのに、「シールドを外して換装したら終わり」って……。大したものです。
ただ、ですね、このスタータキット、本当の初心者さんには、お勧めしません。CD-ROM、入っていませんよ。パッキングリストにも載っていないので、本当に、セットとして、CD-ROMは含まれていないようです。パッキングリストに書かれていたHPに行っても、含まれているモジュールのデータシートなどは見つかりません(筆者の探し方がまずいのか??)。と、いうことで、本当の初心者がこのキットを買っても、途方に暮れることになります。
最初に購入した、ELEGOOスタータキット(「第2回 Arduino初心者スタータキット到着」)は、その点、IDEのインストールから手取り足取り教えてくれるチュートリアルがCD-ROMに入っており、すごく助かりました。
でもOKです。費用対効果は高かったので。「初心者卒業宣言」も、とうにしてあるので、データシートは自分で探します(1^−^)v。
実は、Iduinoキットの中にDHT11のモジュールが入っていました。
DHT11は、「第5回 気温と湿度を測定するセンサ」で検討した中の1つです。AM2302との比較で、精度などのパラメータで見劣りしたため、最終的にはAM2302を選択しました。その、DHT11がキットに含まれていました。検討したとき、データシートを確認済みで、ほぼ、AM2302と同じだった記憶があるので、そのまま接続して動作確認してみます。
AM2302との接続回路は以下図でした。
1-wire通信用のSDA端子にプルアップが必要だったため、ブレッドボード上に抵抗を挿して、配線しました。
今回のDHT11は、単体ではなく、モジュールになっています。
小さい基板上に、面実装タイプのプルアップ(チップ)抵抗が搭載されており、外付けにプルアップする必要はありません(チップ抵抗は"103"=10×103=10kΩでした)。だから、デュポンワイヤでつなぐだけ(↓)。
「第7回 AM2302の制御手順を仕上げる」で作成したプログラムをUNOへコンパイル&書き込みし、シリアルモニタを開いて、【req】コマンドを送信してみました。「ERR,-1」、アレ?取得できません。データシートはざっと確認して、ほぼ同じインターフェイスだと思っていたのですが、思わぬところでつまづきました。
「ERR,-1」と、言うことは、「DHT11がレスポンスシグナルを返さなかった」様です。DHT11のデータシートを再度確認してみたところ、ArduinoからDHT11に送るべき、スタートシグナルですが、「>18ms(TYP 20ms)」と、なっていました。長っ!ちなみに、AM2302のスタートシグナルは、TYP 1ms(MAX 20ms)という規定があったため、1msしか出していません。確かに、これではDHT11は反応してくれないはずです。
スタートシグナルを19msくらいに設定して、DHT11とAM2302の共用にしても良いですが、DHT11にはもう一か所、AM2302と異なる部分があることを知っていたので、#defineで切り替えることにしました。
#define DHT11
#ifdef DHT11
const int tbe_am2302=20000; // (20[ms]) start signal low width[us]
#else // DHT11
const int tbe_am2302=1000; // (1[ms]) start signal low width[us]
#endif // DHT11
これで、読み出せるはず。と、「ERR,-1」何で?時間(20ms=20,000μs)も間違えていないし、20,000だとintで表現可能な数値だし、これで読み出せるはずなのに。
こんな所で嵌まるとは……。デバッグにLogiscopeまで持ち出してしまいましたよ……。
実行サンプル:【 】内はLogiscopeからの送信データ
【trg,2,f,10000】
ハイ、おかしいですね。20msのLOWを出力したつもりが、3,636μsで立ち上がってしまっています。種明かしは、delayMicroseconds()でした。Arduino HP ⇒ REFERENCEを読んでみると、「delayMicroseconds()は、最大16,383μsまで」と、ありました。何でよ(1x_x;)。
16,383と言うことは、下位14ビットが有効なんですね?20,000=0x4e20で、下位14ビットを抜き出すと、0x0e20=3,616と、言うことで、Logiscopeの波形3,636μsとほぼ一致します。
以下の変更が必要でした。
delayMicroseconds (tbe_am2302);
↓
delay (tbe_am2302/1000);
delayMicroseconds (tbe_am2302%1000);
再挑戦。
実行サンプル:【 】内はLogiscopeからの送信データ
【trg,2,f,25000】
スタートシグナル(最初のLOW期間、20ms)が長すぎて、通信波形が全く視認できませんが……、スタートシグナルがちゃんと20ms出力されて、データが送信されてきたことは確認できました。データ部分を拡大してみたい場合は、【trg,2,r,5000】で、DHT11のレスポンスシグナルから取り込むのが吉です。
先ほど軽く触れた、「もう一か所の違い」というのは、送られてきたデータの形式です。AM2302では、気温・湿度データを×10倍した値が整数として送られてきます(10進数の固定小数形式)。一方で、DHT11は、16ビットデータの内、上位8ビットが整数部分、下位8ビットが小数部分として送られてくる、2進数の固定小数形式です。言い換えると、気温・湿度データが×256倍されて送られてきているわけです。
よって、AM2302では、読み込んだ16ビットデータを10で割って実際の値に換算していましたが、DHT11では、256で割って実際の値に換算する必要があります。これは共通化できないので、#ifdefで処理を切り替えます。
#ifdef DHT11
// DHT11
Serial.print (tmp/256.,1);
Serial.print (",");
Serial.println (hum/256.,1);
#else // DHT11
// AM2302
Serial.print (tmp/10.,1);
Serial.print (",");
Serial.println (hum/10.,1);
#endif // DHT11
※ここ(↑)の記述に誤りがあります。末尾の「後日のアップデート」で訂正していますので、ご覧ください。
姉妹品のようなAM2302とDHT11でしたが、思わぬところで手間取ってしまいました。気温・湿度を測定してみましょう。
測定プログラム:meas_am2302.ino
AM2302の測定プログラムを修正してあります。DHT11で使う場合は、先頭付近の
「//#define DHT11」のコメントを外して、有効にしてください。
実行サンプル:【 】内はシリアルモニタからの送信データ
RDY
【who】
DHT11,1.02
【req】
OK,29.0,43.0
【rrt】 …… 以下省略。rrt一回当たり一行、気温・湿度データが表示される。
OK,29.0,39.0
OK,29.0,43.0
OK,29.0,41.0
OK,29.0,40.0
OK,28.0,38.0
何回かデータを取得してみましたが、やはりそうですか?小数部分がすべて「.0」ですね。
データシートには、「湿度データの小数部分は0」だと書かれていたので、「データシートの通りだったね」という感じなのですが、気温データの方も、小数点以下は常に0みたいですね。
さすがに、室温のログ取得で1℃刻みの解像度では、使い物にならないでしょぅ?まあ、AM2302に比べて、ずいぶんとお安かったからなぁ……。価格相応と言うことでしょうか?
※ここ(↑)の記述に誤りがあります。末尾の「後日のアップデート」で訂正していますので、ご覧ください。
さあ、まだ、Iduinoスタータキットに含まれていた、最初のモジュールを使ってみただけ、です。これからしばらく楽しめそうです。
何度かDHT11を使っている間に、DHT11から送られてくる、気温データの下位バイトに数値が格納されていることに気が付きました。改めてDHT11のデータシートを確認してみたところ、
以下、DHT11データシートより引用:
Dataformat:
8bit humidity integer data + 8bit humidity decimal data +
8bit temperature integer data + 8bit temperature decimal data + 8bit checkbit.
う〜ん、気温の下位バイトは、「8bit temperature decimal data」で、「decimal → 小数」と訳していたのだけど、「小数第一位の数値」と、意訳しないといけなかったみたいです。すなわち、正しい気温・湿度データの計算式は、以下となります。
誤)
// DHT11
tmp=(rcv_dat[2]<<8) + rcv_dat[3];
hum=(rcv_dat[0]<<8) + rcv_dat[1];
Serial.print (tmp/256.,1);
Serial.print (",");
Serial.println (hum/256.,1);
正)
// DHT11
tmp=(rcv_dat[2]*10) + rcv_dat[3];
hum=(rcv_dat[0]*10) + rcv_dat[1];
Serial.print (tmp/10.,1);
Serial.print (",");
Serial.println (hum/10.,1);
※と、言うことで、DHT11でも、気温データは、小数第一位まで読み出すことができます。ただし、湿度データは、データシートにもある通り、常に小数第一位が0で読み出されます。
プログラム(meas_am2302.ino)の方も修正しておきましたm(1__)m。上の本文中の記述は修正していないので、間違ったコードと解説が残っていることにご注意ください。