2025年4月8日火曜日

M5STACK LCD Unitのファームウェアアップデート

M5Stamp Picoを弄っていますが、やはり液晶が欲しいなって思っちゃいました。そこで、良く使用されるI2C OLEDディスプレイM5STACK LCD Unitを購入しました。今回は、M5STACK LCD Unitのファームウェアアップデートを行います(写真はアップデート済み)

M5STACK LCD Unitを検索するとファームウェアアップデートに関する情報が出てきます。と言うか、あまり使用例が出てこないんですよねぇ

M5STACKのUnit LCDサイト

上記を確認すると、I2C経由でのアップデート、または裏蓋開けてESP32ダウンローダを使用してアップデートの2つの方法がありました。蓋開けるのは面倒なので、I2C経由でのアップデートしてみようかと思います。GitHubのM5Stack Unit LCD FirmWareを確認するとマニュアルには、M5StickC Plus2は明記されていませんが、スケッチ内には記載があるので大丈夫そうです

GitHubのM5Stack Unit LCD FirmWare

早速、M5StickC Plus2に書き込んで実行してみましたが、searchUnitLCD()の応答待ちでスタックしているように見受けられました(LCD Unitの応答がない?!)

そこで勉強がてら、I2Cスキャナーのスケッチを作成して確認したところ、GroveコネクタのI2Cバス上にアドレスは存在していることは確認できました(スケッチは後述)

    • 内部I2Cバス:0x51(RTC), 0x61(6-axis IMU)
    • Grove I2Cバス:0x3E(LCD Unit)
    • ピンヘッダ I2Cバス:なし

流石にメーカー製のスケッチを解析する気にはなりませんでしたので、I2C経由は諦めてESP32ダウンローダ(Stamp ISPを使用)を使用することにしました

接続したら、M5Burnerから書き込んで終了(書き込む際、ESP32ダウンローダを抑えた方が接触不良なく書き込めます)。無事にアップロードできました

なお、M5STACKのUnit LCDサイト内にあるサンプル記述をM5StickC Plus2に書き込んで動作確認できました。次は、M5Stamp Picoで試したいと思います

参考までにI2Cスキャンのスケッチを下記に乗せておきます:

#include <M5unified .h>
#include <M5StickCPlus2.h>
#include <M5Unified.h>
#include "wire.h"

TwoWire *i2cWire;

uint8_t sda = -1;
uint8_t scl = -1;
uint8_t I2C_SEL = 0;

void I2C_Setting() {
  if (I2C_SEL == 1) {        // GROVEコネクタ
    sda = 32;
    scl = 33;
    Wire.begin(sda, scl);
    i2cWire = &Wire;
  } else if (I2C_SEL == 2) {  // ピンヘッダー
    Wire1.end();              // Wire1を終了し再割り当て
    sda = 0;
    scl = 26;
    Wire1.begin(sda, scl);
    i2cWire = &Wire1;
  } else {                    // 内部I2C
    Wire1.end();
    sda = 21;
    scl = 22;
    Wire1.begin(sda, scl);    // Wire1:通常内部I2C
    i2cWire = &Wire1;
  }
}

void setup() {
  auto cfg = M5.config();
  M5.begin(cfg);

  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setBrightness(5);
  M5.Lcd.setRotation(3);                          // 画面向き
  M5.Lcd.setTextSize(2);                          // フォントサイズ
  M5.Lcd.setTextFont(&fonts::lgfxJapanGothic_8);  // フォント
}

void loop() {
  int device_cnt = 0;

  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0, 0);

  M5.Lcd.printf("I2Cスキャン:\n");

  I2C_SEL = 0;
  while (I2C_SEL < 3) {
    I2C_Setting();

    if (I2C_SEL == 1) {
      M5.Lcd.printf("Groce: SDA:%2d SCL:%2d\n", sda, scl);
    } else if (I2C_SEL == 2) {
      M5.Lcd.printf("ピン : SDA:%2d SCL:%2d\n", sda, scl);
    } else {
      M5.Lcd.printf("内部 : SDA:%2d SCL:%2d\n", sda, scl);
    }

    device_cnt = 0;
    for (byte address = 0; address <= 127; address++) {
      i2cWire->beginTransmission(address);
      byte error = i2cWire->endTransmission();
      if (error == 0) {
        M5.Lcd.printf("0x%02X ", address);
        device_cnt++;
      }
      delay(1);
    }
    I2C_SEL++;
    if (device_cnt == 0) {
      M5.Lcd.printf("I2Cデバイスが見つからない!");
    }
    M5.Lcd.println();
  }
  delay(3000);
}


参考にさせて頂きましたサイト:

0 件のコメント:

コメントを投稿