LoginSignup
2
2

M5StickC PlusのHATにWire1を使いたい!

Posted at

はじめに

M5StickC Plusでは,Grove端子のi2cの他にHAT用のi2cも同時に使いたいシチュエーションがあります.
つまりi2cの通信を2つ同時に行いたいわけですが,これはWireオブジェクトとWire1オブジェクトを同時に使うことで簡単に実現できる…ように見えて地味にハマったので備忘録として残しておきます.

前提

  • 諸々の開発環境は準備済みであること
  • [1]にあるサンプルコードのように,M5StickC.hを利用しつつWireのみを使うコードは動作していること
  • ライブラリのバージョンは以下の通り
    • m5stack/M5Unified@^0.1.9

問題

[2]のページによれば,以下のようにWireWire1をbeginし直せばどちらも使えるはず…とのことでした.

// [2]から引用

void setup() {
  M5.begin();

  Wire.begin(32, 33);
  Wire1.begin(0, 26);
}

これに基づいて書いてみたコードがこちら.

// これでは動きませんでした

#include <M5Unified.h>
#include <Wire.h>

void setup() {

  M5.begin();
  Wire1.begin(0, 26, 100000UL);

  Serial.begin(115200);
}


void loop() {
  Serial.println("start-transmission");
  Wire1.beginTransmission(0x38);

  Serial.print("start-write: ");
  bool rw = Wire1.write(0x02);
  Serial.println(rw);
  
  uint8_t re = Wire1.endTransmission();
  Serial.print("end-transmission: ");
  Serial.println(re);

  Wire1.requestFrom(0x38, 3);
  bool w1 = Wire1.available();
  Serial.print("available: ");
  Serial.println(w1);
  Serial.println("");

  if(w1){
    Serial.println("OK");
  }
  M5.update();
  delay(100);
}

実際のコードから関係ない処理は全部消して,見やすくなるように書き直しています.Serial.println("OK");が呼び出されればHATとの通信ができているものとして考えてください.このコードだと,Wire1.endTransmission()の戻り値がESP_FAILを意味する2になってコケていました.

M5Unified.hを使っていることくらいしか違いがなく𝕏で嘆いていたところ,有識者の方々から色んなコメントが届きました…ありがたや…

解決策

鍵になったのはらびやんさんから教えていただいたWire1.end()でした

このアドバイスをもとに以下のように修正したところ,無事HAT用の端子へWire1を割り当てて通信することができました!!一回end()呼ばないといけないとは…自力では辿り着けなかった気がします.感謝🙏🙏(delay(100);はなんとなくおきもちで入れているのでなくても良いかもしれません)

// これなら動く

#include <M5Unified.h>
#include <Wire.h>

void setup() {

  //----------------------ここから-------------------------
  auto cfg = M5.config();
  cfg.pmic_button = false;  // これで電源ボタン状態取得を行わなくなる
  cfg.internal_imu = false; // これで内蔵IMUを使わなくなる
  cfg.internal_rtc = false; // これで内蔵RTCを使わなくなる
  M5.begin(cfg);

  Wire1.end();
  delay(100);
  //----------------------ここまで追加----------------------

  Wire1.begin(0, 26, 100000UL);

  Serial.begin(115200);
}


void loop() {
  Serial.println("start-transmission");
  Wire1.beginTransmission(0x38);

  Serial.print("start-write: ");
  bool rw = Wire1.write(0x02);
  Serial.println(rw);
  
  uint8_t re = Wire1.endTransmission();
  Serial.print("end-transmission: ");
  Serial.println(re);

  Wire1.requestFrom(0x38, 3);
  bool w1 = Wire1.available();
  Serial.print("available: ");
  Serial.println(w1);
  Serial.println("");

  if(w1){
    Serial.println("OK");
  }
  M5.update();
  delay(100);
}

おわりに

いかがでしたか?groveポートとHATを同時に使いたいシチュエーション,それなりにあると思います.どなたかのお役に立てたら幸いです.各コメント全文は[3]から辿れます.

それでは.

参考

[1] Joystick hat 公式ドキュメント

[2] M5StickC非公式日本語リファレンス

[3] 元ツイのスレッド

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2