今回のテーマは、気圧の測定です。気圧を測定可能なセンサとしては、BOSCH社のBMPシリーズが多く出回っています。
薄利多売のLSIにとって、100個や1,000個を購入して、センサモジュールを作る様な顧客には魅力が無いので、そういう小口の客は相手にしてもらえない(※)のですよ。最低でもロット単位で買い取ってくれる顧客(メーカ)が現れないと……。
たまたま、どこかのメーカが大量に購入して製造したモジュールが世の中に出回って、色々なショップでバラ売りされているのが実情です。そういう、パイオニア的メーカが現れない限り、古いチップも、新しいチップも、中々世の中には出回らないのです。
※「相手にしてもらえない」 ⇒ 購入する事はできるけど、バカ高い価格設定で買わされる、という意味。
今回のお買い物は以下の通りです。
秋月電子通商にて購入した耐熱ワイヤは、こちらのお買い物と一緒に購入しておいた物です。
肝心なBMP180モジュールはAmazonで購入したのですが、Amazonに出店しているストアが直接送ってくれる商品で、「送料無料」のストアを選びました。お陰で、3個の抱き合わせ販売で、399円と言う、ちょっと割高感のある商品となっています。1個バラの133円(=399円÷3個)で売って欲しかったのだけど……。
ただ、今回は、最低でも2個欲しいと思っていたので、以下の理由から、それほど割高感はありません。
Amazon内のRasbeeというストアで、中華ショップなので、中国から発送されるのに「送料無料」です。種明かしは、荷姿にありそうです。日本のはがきサイズより小さな、薄いクッション入り封筒にモジュール3個だけが封入されて届きました。
※これで良いのですよ。立派な箱に入って410円も取られるより、薄いクッション入り封筒で十分だから、安く届けてほしい。
中国から恐らく船便で、2回の通関を経て届くので、たっぷり2週間かかりました。その間、荷物のトラッキング情報が更新されていたのですが、ムチャクチャで、全くトラッキングできていない様子でした。
そりゃそうですね。中国国内と、日本国内では別な運送業者でしょうし、異なる企業間(しかも異なる国間)でトラッキング情報を的確に発信し続けるなんて、ちょっとムリッポです。挙句の果てに最後は、商品が手元に届いているにもかかわらず、「到着が遅れています。届かない場合は、ここで返金手続きができます」ですって。いやいや、もう届いてるから。
※トラッキングできないんだから、「できません」って正直に書いておけば良い物を、平気な顔して、さも「トラッキングできてます」的な嘘をつく辺りは、中華ショップらしいと言えば、らしい(誠実さに欠ける)。
今時、「送料無料」な事に感謝しつつ、トラッキング情報は無視して、2週間のんびり待てる場合のみ、選択可能なストアだと心してください。でも、そこを許容できるなら、Amazonに送料410円払うより断然お得です。
今回購入したのは、ちょっと古い、BMP180(BOSCH社製)というセンサを搭載したモジュール(下図)です。
センサ自体も小さいですが、モジュールも上図の通り、ものすごく小さいです。背景が1cm方眼ですので、小ささが解りますでしょう?端子は4本だけで、VIN,GND,SCL,SDAと、通信インターフェイスはI2Cです。
Amazonの販売ページに有った回路図を見たところ、モジュールには降圧レギュレータが載っていますので、VINには5Vを接続し、SCL,SDAには3.3V信号線を接続する必要があります。
ううむ……、3.3V定格で使うにも5V定格で使うにも中途半端で、嬉しくは無いですね(1−−;)。
今回は、5V定格のArduino UNOと、3.3V定格のArduino DUEで使いたいと考えています。
今回のモジュールは5Vの電源入力が必要とは言え、通信信号線(SCL,SDA)は3.3V定格なので、UNOで使うには、レベルシフタ(L/S)を挟む必要があります(下図)。
いつもであれば、毎回、上図の様なL/Sモジュールを挟んで使うのだけど、これが中々スペースを取るし、使い難いのです(12ピンDIP形状)。
実はL/Sモジュールを購入した時にも、L/Sモジュール×5個の抱き合わせ販売でしたので、未使用のL/Sモジュールが余っています。これを活用すべく、L/SモジュールとBMP180モジュールを合体させて、5V定格かつ、SIPタイプのモジュールに工作し、UNOで使い易くしておこうと思います。
回路図は以下となります。
万能基板などに実装しようとすると、ガタイが大きくなってしまうので、モジュール同士をピンヘッダと耐熱ワイヤで直接はんだ付けしてコンパクトに収めてみました。下図(完成図)でご確認ください。
Vcc,Vddの2本が耐熱ワイヤによる空中配線となりますが、残りは全てピンヘッダではんだ付けできます。これを実現するため、BMP180モジュールを裏返して実装しました。端子名が印刷されたシルク面が見えるので、返って使い易いかと。
元々のL/Sモジュールは、12ピンDIP(Dual Inline Package)形状なので、ブレッドボードや万能基板でも場所を取ってしまうのですが、上図の通り、親亀/子亀🐢の階層方式で積み重ねたことで、5ピンSIP(Single Inline Package)形状のコンパクトなモジュールに出来上がりました。
端子名 | 備考 | |
1 | Vcc | 5V電源入力 |
2 | GND | GND端子 |
3 | SCL | I2C通信線(5V定格) |
4 | SDA | |
5 | Vdd | 3.3V電源入力 |
これなら、ブレッドボードを使うにしても、スペースを取りませんし、何ならデュポンワイヤなどで接続しても使用可能です。
前節で工作したモジュールは、5V定格専用ですので、DUEやM5StickC Plus等、最近よく使っている3.3V定格のマイコンでは使用できません。
購入したBMP180モジュールは、5V電源を入力する必要があること以外、基本的に3.3V定格のモジュールなので、そのままピンヘッダをはんだ付けしてやれば、3.3V定格のマイコンで使用可能です。DUEやM5StickC Plus等には5V電源出力が備わっていますから、ここから電源供給もできて、問題ありません。
今回は、3個抱き合わせ販売でしたので、その内の2個を使って、5V版と3.3V版のモジュールを使い分けることができます。残り1個は、現時点では使い道が無いので、大切に保管しておきます。
まず、BMP180のデータシートを探しておきましょう。
BMP180のデータシートを検索する(別ウインドウが開きます)
データシートによると、どこかのI/Oレジスタを読み出すと、そのまま気温や気圧値が直読みできる、という簡単なインターフェイスではなく、どうやら気温も気圧も、BMP180内部でAD変換した値を読み出し、データシートに記された数式に従って計算して初めて、求めることができるみたいです。
計算手順は、データシートに計算式と手順が記されているので、「楽勝」、と、思いきや……。
計算手順の数式が、読めない!
BMP180データシートの計算手順ページだけ、コピー&ペーストされているらしく、解像度の粗いグラフィックデータになっていて、拡大しても粗いドットが大きくなるだけでした。お陰で、小さな演算子が足し算(+)なのか、掛け算(*)なのか分かり難いし、28みたいな冪数の肩の数字が判読できませんでした。
※BMP180データシートから一部拡大、引用。
データシートの計算手順だけが頼みの綱、なのに、これではダメダメだぁ〜。
後継のBMP280データシートも探して、見てみましたが、状況は変わらず、です。「ならば」と、逆に古いBMP085データシートを探してみたところ、こっちが正解でした。BMP085データシートが、コピー&ペーストの元データだったらしく、ちゃんとベクトルフォントで計算手順が記載されていました。拡大すれば、小さな文字も判読できます。良き良き。
これで解決。
※BMP085データシートで確認したところ、上に引用した部分で、黒い点(・)に見えている記号は、ちゃんとアスタリスク記号(*)でした。算数で時折、掛け算を表すのに使われるドット(・)ではありません!
最初、5V版に改造したモジュールを使い、UNOでプログラムしたのですが、気温44℃だの何だのと、「絶対間違ってるよね?」という値しか出て来ません。
試しに3.3V版モジュールを接続したDUEで試したところ、今度は気温も気圧も、それらしき値が出てきました。
Arduino IDEで、ターゲットをUNOからDUEに替えただけ、ですから、C言語のソース自体は一緒、なのですよ。何で答えが合わないのよ?って、デバッグしたところ、解りました。
計算式は、32ビットintが前提となっているらしく、16ビットintのUNOでは、シフト演算(<<)や乗算(×)等で16ビット値を溢れた時に計算を誤っていました。
UNOでも、long intを使うと32ビットint演算自体は可能なので、溢れそうなところをすべてlong intにキャストしてみたところ、DUEと同じ値を出力する様になりました。
こちらも解決。
完成したプログラムを以下にリンクしておきます。
完成プログラム:meas_bmp180.ino
当方では、UNOとDUEで動作確認してあります。コンパイルしてArduinoへ書き込むと、シリアルモニタから以下のコマンドを受け付けています。
尚、BMP180の計算手順では、気温が0.1℃、気圧がPaの整数で測定できます。【meas】コマンドでは、気温を小数点以下1桁[℃]、気圧を小数点以下1桁[hPa]、に換算して表示します。
Arduino UNOまたはDUEを使って実験しますので、以下接続表に従って接続してください。
Arduino UNO またはDUE |
接続 |
BMP180 (5V版→UNO/3.3V版→DUE) |
5V | → | Vcc(UNO)/VIN(DUE) |
3.3V | → | Vdd(UNOを使う場合のみ) |
GND | ⇔ | GND |
SCL | ⇔ | SCL |
SDA | ⇔ | SDA |
こちらのプログラムを書き込んで、実験を進めましょう。
実験中の様子を以下図に示します。
以下、サンプルに従って実験を進めましょう。
実験サンプル:
【meas,1】
OK: temp= 28.2 [degC] pres= 995.9 [hPa]
さてさて、それらしき値は表示されたのですが、正しさの検証は難しいですよね?
気温は、他のセンサモジュール(DHT11やAM2302等)や、部屋の気温計などと比べる事はできるし、体感的に違和感の有り/無しは解ります。
けど、気圧は……??
ちなみに、所謂「1気圧」とは、1,013.25hPaに相当するらしいです。また、天気図などに表示された気圧値は、海抜0mに於ける気圧に換算した値だそうです。本来は、測定地点の高度(海抜)で気圧が変化するためです。
なので、気圧変化に敏感で、頭痛などを起こす様な方でない限り、現在の気圧を体で感じられる方は少ないでしょう。
気象庁のHPに行けばデータが閲覧できるのではないか?と思い、訪ねてみました。
気象庁HPを検索する(別ウインドウが開きます)
気象庁HPから、色々探してみたのですが、中々、今の気圧が判る情報に辿り着けません。ようやく見つけたのは以下のページでした。
一覧表が表示されるので、測定地に一番近い都市の気圧値を読み取ってください。
タイトルの通り、「今日の」最新データなので、最新の気圧値を読み取ったら、すぐにBMP180で気圧値を計測して、比較してみます。しかし、決まった時間に更新されるような代物では無いみたいなので、手元のBMP180で測定した時間とは、最大で8時間くらいの時間差がありますことを、予めご理解ください。
そうは言っても、気圧って、気温と違って、数時間で大きく変わる性質の物ではないので、何日かかけて、測定・比較した結果が上図の通りです。横軸に測定した日付・時刻、縦軸に気圧[hPa]と、偏差[%]=(BMP180−気象庁発表)÷気象庁発表、を取ったグラフです。
測定期間は関東地方の梅雨入り前後で、期間中には、低気圧が通過して雨が降った日や、晴れて暑くなった日も存在しています。気象庁発表値(水色線)とBMP180での測定値(緑色線)を見比べてみると、ほぼ同じ様に上下変動を辿っている事が見て取れます。手元のBMP180は概ね、気象庁発表値よりも低めな気圧値を示す傾向にありました。
※気象庁発表値が海抜0m換算値であることを考えると、BMP180での測定地点は、少し標高の高い地点に存在するので、その分、気圧が低く観測できても矛盾はありません。その他、気象庁の観測時間と、BMP180での観測時間に最大8時間ほどの時間差があることも、偏差に影響しています。
多少の誤差は見て取れますが、気象庁発表データに近い値(偏差約1%、赤色破線)が計測できることを確認しました。
本HPの最初のテーマは、「部屋の気温と湿度のログを取りたい」でした。これを実現しようと作成した、データロガが今現在も現役で稼働し続けています。ここらで気圧データのログも追加しようかどうか、思案中です。追加すると決めた場合には、今回作成した5V版モジュールが活躍してくれるはず。