0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ESP32‑S3 × Python で作る小型I/Oデバイス(第5回:Python アプリの API 実装(ESP32IO クラス))

0
Last updated at Posted at 2026-03-18

連載一覧

はじめに

前回(第4.5回)では、ESP32‑S3 側のファームウェアをデバイス化し、
USB でつなぐだけで I/O デバイスとして扱える基盤が整いました。

今回は、そのファームウェアを Python から扱うための
ESP32IO クラス(API) を実装します。

これで ESP32‑S3 を「USB でつなぐだけの I/O デバイス」として Python から扱えるようになります。

目的は以下の通りです。

  • JSON コマンドを直接扱わず、Python から直感的に I/O を操作できるようにする
  • エラー処理やタイムアウトを統一し、堅牢な API とする
  • get_io_state や PWM 設定取得を活用して、テストツールや GUI の基盤を作れるようにする

※ 前回作成したファームウェアはこちら
 ZIPファイル内の ESP32_S3_IO_DEVICE です。
 ESP32_S3_IO_DEVICE_WiFi は不要です。

今回実装する API の要件

● 必須機能

  • シリアル通信の初期化
  • JSON コマンドの送信
  • JSON レスポンスの受信
  • タイムアウト処理
  • エラーコードの例外化
  • 各 I/O 操作のメソッド化
    • read_di()
    • set_do()
    • read_adc()
    • set_pwm()
      • get_pwm_config()
      • set_pwm_config()
    • get_io_state()

● 目標

  • ユーザーは JSON を意識しない
  • 例外処理が統一されている
  • get_io_state と PWM 設定取得によるデバッグ性の向上

API 設計方針

● 1. JSON の送受信を 1 箇所に集約する

内部メソッド _send_command() を用意し、
すべてのコマンドはこれを経由して送信します。

● 2. エラーコードは Python の例外に変換

例:

  • INVALID_DIO_IN_PIN_ID → InvalidPinError
  • JSON_PARSE_ERROR → ProtocolError

● 3. タイムアウトは読み取り側で管理

  • シリアルが固まってもアプリが固まらないようにする
  • デフォルト 1 秒程度

● 4. get_io_state を活用したデバッグ性の向上

  • 全 I/O の状態を一括確認
  • GUI やロガーの基盤にもなる

ESP32IO クラスの実装(コード)

以下は今回実装する ESP32IO クラスです。

read_di(pin_id)
set_do(pin_id, value)
read_adc(pin_id)
set_pwm(pin_id, duty)
get_pwm_config()
set_pwm_config(freq, res)
get_io_state()

  • pip install で使う場合

esp32io は PyPI に公開されているため、次のコマンドでインストールできます。

pip install esp32io==0.1.2

※この記事の内容はV0.1.2より後のバージョンは動作確認していません。

インストール後は、通常どおり import できます。

from esp32io import ESP32IO

  • ZIP 版を使う場合(任意)

pip install を使わずに GitHub のソースコードを直接利用したい場合は、
esp32io フォルダをプロジェクトと同じ階層に置くだけで使用できます。

your_project/
 ├─ esp32io/        ← GitHub から取得したフォルダ
 └─ your_script.py

この構成にすることで、Python が import esp32io を正しく解決できます。


ESP32IOクラスの使用例

以下の回路を例に、ADC の値を PWM に反映してLEDの明るさを調整するサンプルを示します。ESP32-S3-devkitc-1には下記リンク先のファームウェアを書き込んでおいてください。
https://github.com/noritama-lab/esp32io-firmware

image.png

pin_id → GPIO 対応表

種類 pin_id GPIO
DIO_IN 0–5 4, 5, 6, 7, 8, 9
DIO_OUT 0–5 10, 11, 12, 13, 14, 15
ADC 0–1 1, 2
PWM 0–1 38, 39

今回の回路では

  • 可変抵抗 → ADC pin_id:0(GPIO 1)
  • LED → PWM pin_id:0(GPIO 38)
    に接続されています。

テストツールの実行

プロジェクトの直下(zipの場合、esp32ioフォルダと同じ階層)に test.pyなどのpythonファイルを作成して以下のコードをコピペします。実行すると、可変抵抗の電圧を ADC で読み取り、その値を PWM のデューティ比に変換して LED の明るさを制御します。
このサンプルでは read_adc() と set_pwm() を使って ADC 値を PWM デューティに反映します。必要に応じて get_pwm_config() / set_pwm_config() を使うことで、PWM 周波数と分解能も Python 側から管理できます。

まずはこのテストツールを動かすことで、ESP32IO が正しく動作しているかを一括で確認できます。

from esp32io import ESP32IO
import time
import serial

def main():
    try:
        # ESP32IO に接続
        esp = ESP32IO("COM3", debug=False)
        print("ESP32 に接続しました。")

        # 現在の PWM 設定を確認し、必要なら変更
        print("現在のPWM設定:", esp.get_pwm_config())
        esp.set_pwm_config(5000, 8)

        while True:
            # ADC0 を読み取る
            adc_value = esp.read_adc(0)

            # PWM0 に反映(0〜4095 → 0〜255 にスケール)
            duty = int(adc_value / 4095 * 255)
            esp.set_pwm(0, duty)

            print(f"ADC={adc_value}, PWM duty={duty}")
            time.sleep(0.05)

    except serial.SerialException as e:
        print("ERROR: ESP32 に接続できませんでした。")
        print("理由:", e)
        print("COM ポートが正しいか確認してください。")

    except Exception as e:
        print("予期しないエラーが発生しました:", e)

    finally:
        # 安全のため PWM を停止
        try:
            esp.set_pwm(0, 0)
        except:
            pass
        print("終了しました。PWM を停止しました。")


if __name__ == "__main__":
    main()

ESP32IO の全コマンドを試せるテストツール

下記リンク先のテストツールに全コマンドの使用方法を示します。

  • テストツールはこちら:
    https://github.com/noritama-lab/esp32io-api
    (リンク先の「example」フォルダ内にある esp32io-sample.py がテストツールです。)
    esp32io-sample.py は、ESP32IO の全コマンドをまとめてテストできる初回動作確認ツールです。
    できること
  • DIO 出力(set_do)
  • DIO 入力(read_di)
  • ADC 読み取り(read_adc)
  • PWM 出力(set_pwm)
  • PWM 設定の取得・更新(get_pwm_config / set_pwm_config)
  • 全 I/O 状態の取得(get_io_state)
    このサンプル 1 つで、ESP32IO API の基本動作をすべて確認できます。

サンプルの実行方法

  • pip install でインストールした場合

通常どおり、次のコマンドで実行できます。

python examples/esp32io_sample.py

pip install 版では esp32io が site-packages に配置されるため、
直接実行でも import エラーは発生しません。


  • ZIP 版を使う場合

ZIP 版では、esp32io フォルダをプロジェクトと同じ階層に置く必要があります。
この場合、サンプルは次のように -m を使って実行してください。

python -m examples.esp32io_sample

-m を使うことで、examples/esp32io_sample.py
パッケージとして正しく実行できます。

python examples/esp32io_sample.py のような直接実行では、
esp32io パッケージが見つからず import エラーになります。

まとめ

  • Python から ESP32‑S3 を安全に扱うための API を実装した
  • JSON コマンドを意識せず I/O 操作が可能になった
  • PWM 周波数と分解能も Python から設定できるようになった
  • エラー処理とタイムアウトで堅牢性が向上
  • get_io_state によりデバッグ性が大幅に向上
  • 次回は GUI / ロギング / Wi‑Fi など応用編へつながる

次回予告

次回は、この API を使って

  • デバイスとしてまとめる
  • ケース化、配線、固定
  • 電源周りの設計
  • 実際の用途に合わせた応用例
    を紹介します。
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?