ESP32デバイスのI2Cスレーブ化

最近、AIとのやり取りの記録みたいな感じでブログ書いてる気がします。

今回は、PICとM5Stack ATOM Lite(ESP32)とI2C通信するのですが、PICをマスター、ATOM Liteをスレーブにする試みです。

目的はPICのデバックのため。結論的には、思ったより手軽にはできなくて、Arduino IDEのインストールが必要でした。

 

環境

PC:Windows10
PIC:PIC12F1822
ESP32:M5Stack ATOM Lite

 

目的

改めて。現在、PICを使ったデバイスづくりをしていて、I2C通信で各モジュールからデータを受け取り処理してようと思っているのですが、そういえば、PICプログラムのデバッグのため、取得しているデータを確認する手段がないな?っと思って、ESP32デバイス(ATOM Lite)をスレーブ側として、データを見れるようにしたかったのです。

結果として、MicroPythonのままやろうしたけどできなくて、Arduino IDEを入れてコンパイルしたプログラムを書き込むことでできました。
作業として一番大変だったのは、Arduino IDEにATOMを認識させるために「ボード」のインストールが必要なのですが、自動ダウンロードがうまくいかなくて、手動ダウンロードする作業でした・・・。

 

ATOMスレーブ化手順

環境構築

Arduino IDEのダウンロード→インストール

https://www.arduino.cc/en/software/#ide

ソフトウェア設定

・[基本設定] の「追加のボードマネージャのURL」に https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json を入力。

・[ツール] > [ボード] > [ボードマネージャ] で 「esp32」 を検索してインストール。
(このesp32のダウンロードがうまくいきませんでした)

・ATOM LiteをPCに接続

・ボードの選択: M5Stack-ATOM

・ポートの選択:ツール > シリアルポート で、ATOM Liteが接続されているCOMポートを選択

 

プログラムビルド・書き込み

ここでは、RTCの時刻データがちゃんと読み込めているか確認するため、UNIX時間を取得しています。

・下記のソースコード記載後、右矢印アイコン(→)を押して、書き込み

ソースコード

#include 

// PIC側で指定したアドレスと同じにする
#define SLAVE_ADDR 0x30

// ATOM LiteのGrove/内部ピン
#define SDA_PIN 25
#define SCL_PIN 21

void setup() {
  Serial.begin(115200); // PC通信用
  
  // I2Cスレーブとして初期化
  // Wire.begin(アドレス, SDAピン, SCLピン, 周波数);
  if (!Wire.begin(SLAVE_ADDR, SDA_PIN, SCL_PIN, 100000)) {
    Serial.println("I2C Init Failed");
  }

  // データを受信したときに実行する関数を指定
  Wire.onReceive(receiveEvent);

  Serial.println("I2C Slave Initialized. Waiting for PIC...");
}

void loop() {
  // 受信処理はバックグラウンド(割り込み)で行われるため
  // loop内では何もせず、100msごとに待機
  delay(100);
}

// PICからデータが送られてきたときに自動で呼ばれる関数
void receiveEvent(int howMany) {
  // UNIX時間は4バイトなので、4バイト届いたときだけ処理
  if (howMany == 4) {
    uint32_t unix_time = 0;
    
    for (int i = 0; i < 4; i++) {
      if (Wire.available()) {
        // 受信したバイトを左にシフトしながら結合
        unix_time = (unix_time << 8) | Wire.read();
      }
    }
    
    // シリアルモニタに表示
    Serial.print("Received UNIX Time: ");
    Serial.println(unix_time);
  } else {
    // 予期せぬバイト数が届いた場合はバッファをクリア
    while (Wire.available()) Wire.read();
  }
}

PICから受信

・右上の虫眼鏡アイコンをクリックして、シリアルモニタを表示

・右端の周波数を「115200band」にする
→周波数を合わせないと文字化けする(例:�>ѭ(��6��6�)

・受信するとシリアルモニタに「Received UNIX Time: 1738832719」などが表示される

以下、失敗ログです。

 

ボードesp32の手動インストール

・以下から該当バージョンのファイル(.tar.gz)をひたすらダウンロード
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

・キャッシュファイル先にコピー
保存先:

C:\Users\(ユーザー名)\AppData\Local\Arduino15\staging\packages

・IDEを起動して、インストール実行
(ダウンロードがスキップされて、インストールに進める)

 

失敗した試み:MicroPythonのままスレーブ化

MicroPythonのままスレーブ化できたら、お手軽だなと思ったのですが、MicroPythonはマスタ前提で、スレーブにするには直接メモリをいじりにいかないとダメなようです。
以下のslave.pyを、デフォルトのMicroPython(ESP32)のファームウェアで試してみましたが、エラーがでてプログラムが走りませんでした。
ファームウェアも公開されているので、それに書き換えたらいいのかもしれませんが、ファームウェアを書き換えたら、すでにお手軽じゃない

ESP8266 and ESP32 as an I2C slave in Micropython
https://www.az-delivery.de/en/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/esp8266-und-esp32-als-i2c-slave-in-micropython

Raspberry Pi PicoのMicroPythonなら上手く行くかもしれません。

Raspberry pi pico(ラズピコ)をslave(スレーブ)化し、ラズパイとI2C通信
https://python-academia.com/raspberry-pi-pico-slave/

Updated: 2026年2月6日 — 22:01

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です