それぞれスケッチ例などを参考に動かして問題ないことを確認したが、いざ一緒に動かそうとすると、うまくいかない。
どちらも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つのスイッチは最高最低温度の選択用と、そのリセットスイッチ。 |
0 件のコメント:
コメントを投稿