2018年3月12日月曜日

AM2320で気温湿度を測定、128X32のOLEDで表示させる(複数のI2Cディバイス接続)

I2Cディバイス単独では動作するが、一緒に動かせない
それぞれスケッチ例などを参考に動かして問題ないことを確認したが、いざ一緒に動かそうとすると、うまくいかない。
どちらもI2Cでの通信なので、共存がうまくいかいような印象。

AM2320のスケッチを見ると、アドレスが0x5cとなっていて、
Wire.beginTransmission(am2321_I2C_adr);
Wire.write(0x00);
Wire.endTransmission();
のように、アドレス指定のあと、制御やデータ取得を行っている。
一方SSD1306を使用したOLEDディスプレーは、どのように制御しているのかがよくわからず、アドレス指定をどのようにしているのかが、はっきりしない。

アドレスもよくわからないが、類似品の128X64のOLEDディスプレーで、やはりSSD1306を制御チップに使っている製品は、秋月電子通商のページに0x3cとある。
テストスケッチで単独動作であればI2Cの競合がないので問題ないが、複数のI2Cディバイスを使う場合には問題になる。

原因は
SSD1306を使ったOLEDディスプレーのFAQのページを見ると、I2Cを一緒に使うと動作しないという質問があって、その回答を見ると、やはり競合が発生するようだ。
FAQのページ
https://github.com/olikraus/u8g2/blob/master/doc/faq.txt
以下は翻訳文
Q:xxx_SW_I2C()デバイスが他のI2Cデバイスと連携しないのはなぜですか?
A:SW_I2Cは、digitalWrite()でI2Cをエミュレートします。これは他と競合します
I2Cデバイスを同じピンに接続します。2つのオプションがあります。
(A)xxx_HW_I2C()または(B)xxx_SW_I2C()と異なるピンを使用する

スケッチのサンプルを見ると、大量のコンストラクタがあり、必要なものをアンコメントして選択するようになっている。
今回は制御チップがSSD1326で、表示画素数が128X32なので、対象になるのは
//U8X8_SSD1306_128X32_UNIVISION_SW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);   // Adafruit Feather ESP8266/32u4 Boards + FeatherWing OLED

//U8X8_SSD1306_128X32_UNIVISION_SW_I2C u8x8(/* clock=*/ 21, /* data=*/ 20, /* reset=*/ U8X8_PIN_NONE);   // Adafruit Feather M0 Basic Proto + FeatherWing OLED

//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);   // Adafruit ESP8266/32u4/ARM Boards + FeatherWing OLED

//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE, /* clock=*/ SCL, /* data=*/ SDA);   // pin remapping with ESP8266 HW I2C
このいずれかである。

最初は一番上のSW_I2Cで、clock=SCL,data=SDAを選択して結果的にうまく動かなかったので、FAQに従い、SCLとSDAに異なるピンを割り当てるとすると、2番めのclock=21,data=20でも良さそうだ。しかし20,21の意味がわからなかったので(ピンNoかと思われるが)、結局4番目のHW_I2Cでclock=SCL,data=SDAを選択した。配線はそのままで、SCL,SDAにOLEDとセンサーをぶら下げている。

結果的にこれでOKとなったが、どういう理屈でうまく行ったのかはわからない。

出来上がったものは、AM2320で温度湿度を測定、OLEDに表示させて、最高・最低温度を内部のEEPROMに記録するもの。電源はスマホのチャージ用バッテリーが使える。

arduino nanoにOLEDのディスプレー、温湿度センサーをI2Cでつないだところ。
2つのスイッチは最高最低温度の選択用と、そのリセットスイッチ。


2018年3月4日日曜日

BME280で温度湿度気圧を測る(arduino UNO)

arduinoで温度を測ろうと考えた
よくあるパターンだが、スケッチの勉強としてはおもしろい。せっかくだから最高・最低温度くらいは記録できるようにしたいし、一定時間ごとの気温の変化をSDカードに記録するようなこともしてみたい。

そこで、アマゾンからBME280のモジュールを980円(税込み)で購入。どうせなら気圧も一緒に測れるのがいい、ということで欲張って買ったはいいが、買ってしまって大後悔。電圧が3.3Vだし、スケッチ例を見ると内容が膨大。精度はよさそうだが、とてもお手軽に使えるようなものではない印象。

まずは電圧変換
ともあれ動作テストぐらいはしないといけないので、まずは電圧変換のための「I2Cバス用双方向電圧レベル変換モジュール(FXMA2102)」を秋月電子通商から購入。(税込み200円)使い方が今ひとつよくわからなかったが、「FXMA2102による電圧レベル変換」というサイトがあったので、これに従って配線をする。
https://www.petitmonte.com/robot/howto_fxma2102.html

接続をする
購入したBME280モジュール自体の情報も、アマゾンの商品ページに、写真とともに回路図がある程度で、かなり心もとない。類似の商品がかなりあるが、少しずつ回路やピン配置が違っていたりして注意が必要。
仕方なく、秋月電子通商のBME280モジュールのページからマニュアルを参照、I2Cの接続方法を参考にしつつ配線をする。回路図を見ると、購入したモジュールにはSCL,SDAにプルアップの10kΩがすでについているので、電圧レベル変換モジュールの回路図にあるプルアップ抵抗は不要となる。(元々ついていないので、あえて追加する必要なしということ。)
BME280モジュールの回路図にある端子名称と、モジュール基板裏側に印刷されている名称が異なるので、戸惑わないようにしないといけないが、今回はI2C接続なので、基板に印刷されている名称のSCL、SDAに従ったほうがわかりやすい。
6ピンのSDOはオープンとするが、内部で10kΩでアースに接続されているため、I2Cのアドレスはデフォルトの0x76となる。(これも秋月のマニュアルに書いてある)
5ピンCSBも未使用なのでオープン。(内部でVDDにプルアップされている)

秋月電子通商のマニュアル(BME280モジュール)
http://akizukidenshi.com/download/ds/akizuki/AE-BME280_manu_v1.1.pdf
秋月電子通商のマニュアル(電圧レベル変換モジュール FXMA2102)
http://akizukidenshi.com/download/ds/akizuki/ae-fxma2102-web.pdf

アマゾンの商品ページから
(端子の名称と基板の名称は少し異なる)

基板の裏側には端子の名称が書かれている

arduino UNO(互換品)から3.3Vをセンサーモジュールに供給し、5VはVCCAに接続。電圧変換モジュールのOEをVCCAに5kΩでプルアップして配線完了。(OEは100kΩでアースに接続されているので、10kΩでもOK)

スケッチはスイッチサイエンスで購入ページに公開しているものをそのまま使用。一応I2Cのアドレスが0x76で間違いないことを確認する。

精度は?
動作に問題はなく、即温度、湿度、気圧がシリアルモニターに表示されるようになった。
BME280の仕様では、温度の精度は±1℃となっているが、手持ちの棒状温度計との比較では、十分その範囲内に入っているようだ。ただ、湿度は正確に測れるものがなく、乾湿計との比較ではかなり違いがある。市販のデジタル湿度計とは比較的近い値になっているので、たぶん問題はないだろうという程度しか評価できない。

気圧について、気象台のアメダスデータとの比較では、±1hpからは多少外れているようだが、実用上問題ないことは確か。
低気圧が近づいた時に記録した結果では、

アメダス(hp)     測定データ(hp)   差
991.8              990.32        -1.84
989.5              987.90        -1.60
986.5              984.83        -1.67
985.1              983.38        -1.72
984.2              982.41        -1.59
981.6              979.83        -1.77
981.3              979.72        -1.58
(気象台から5kmほどの距離で、室内で測定。)
配線が完了して測定中
棒状温度計との差はほとんどない

湿度の参考にした乾湿計
通常の温度計と、水で湿した温度計との温度差で湿度を測る

スイッチサイエンス公開スケッチ
https://github.com/SWITCHSCIENCE/BME280/tree/master/Arduino

なお、秋月電子通商さん、スイッチサイエンスさん、購入もしないでデータだけ頂きすみません。

INA219にはまる

 INA219電流センサーの互換品を買う。 互換品 オリジナル Adafruit Industries(エイダフルート) 商品レビューで評判が良くない。不良品が多すぎるという。 とはいえ全体の購入者数からすれば一部の人の評価だろうから、まあ大丈夫だろうと買う。 オリジナルの値段の...