---
slug: "esp32-hw-394-wroom-32-circuit-python"
title: "HW-394 と書いてある ESP-WROOM-32 (ESP32) 開発ボードで CircuitPython をする"
description: "AliExpress で、ESP32 で検索すると出てくる ESP-WROOM-32 搭載の開発ボードで、基盤に「HW-394」と書いてあるものを買った時のメモ。"
url: "https://www.ytyng.com/blog/esp32-hw-394-wroom-32-circuit-python"
publish_date: "2023-12-24T09:20:13Z"
created: "2023-12-24T09:20:13Z"
updated: "2026-02-27T08:49:21.807Z"
categories: ["Python", "マイクロコントローラー"]
keywords: ""
featured_image_url: "https://media.ytyng.com/resize/20250615/bfa6f9b8fa534a2f9d8cd188616c1612.png.webp?width=768"
has_video: true
has_music: true
video_urls: ["https://media.ytyng.net/ytyng-blog/299/featured-video-1.mp4", "https://media.ytyng.net/ytyng-blog/299/featured-video-2.mp4", "https://media.ytyng.net/ytyng-blog/299/featured-video-3.mp4"]
music_urls: ["https://media.ytyng.net/ytyng-blog/299/featured-music-299-2.mp3", "https://media.ytyng.net/ytyng-blog/299/featured-music-299-3.mp3"]
lang: "ja"
---

# HW-394 と書いてある ESP-WROOM-32 (ESP32) 開発ボードで CircuitPython をする

AliExpress で、ESP32 で検索すると出てくる ESP-WROOM-32 搭載の開発ボードで、[基盤に「HW-394」と書いてあるもの](https://www.aliexpress.com/item/1005005495948290.html)を買いました。

4個入で16ドルでした。

![画像](https://media.ytyng.com/20231224/5e52364af9784cf392024a67df0e7ad3.jpg)


USBシリアルコンソールのチップで CH340C が実装されているものです。[HW-394 という印字が無く、パターンが同じタイプ](https://www.aliexpress.com/item/1005005335283537.html)もあるようです。

日本の Amazon でも、ESP-WROOM-32 + CH340C (もしくは別のシリアルコンソールチップ)の(謎メーカーの)同等商品が数多く売られていました。

HW-394 という印字が開発ボードの名前かどうかもわかりませんが、正式名称がわからないため、今後、この製品は HW-394 と呼びます。

後記:
後からわかったのですが、ESP32 DevKitC という規格でいろんなメーカーが作っているらしい

# 選定にあたっての注意

アリエク以外で売ってないですし、型番で検索しても公式ページなどは無いので怪しい商品です。

よく使う小さめのブレッドボードを使った時、基盤が大きすぎるため片側のピンしかアクセスできません。
そのためかなりおすすめしません。

![画像](https://media.ytyng.com/20231224/f98e176df26f4d9e8c76630f34a53cdc.jpg)

(写真では見えにくいですが、左側のピンしか使えません)

ESP32を使う場合、この商品は使わずに、CircuitPython の公式サイトで「ESP32」で検索すると出てくるボードを買うのが良いと思います。

https://circuitpython.org/downloads?q=ESP32

[Seeed Studio XIAO ESP32C3](https://circuitpython.org/board/seeed_xiao_esp32c3/) が、日本でも入手しやすく比較的安価で小さくて良いと思います。


# 開発方法
Mac (Apple Silicon M2) を使って開発します。

ESP32 は、USBシリアル接続を使わずに、ブラウザを使ってファイルを転送したりブラウザ内で開発したりできるようですが、今回はそれは行いません。Python ファイルの転送も USB シリアルポート経由で行います。

PyCharm でコードを書いて、シェルスクリプトでフラッシュの書き込みを行います。


# USB シリアルの接続ポートを確認する

HW-394 を Mac に USB-C-C のケーブルで接続します。
ドライバのインストール等は不要です。

接続後、以下のコマンドでポートを確認します。

```shell
python -m serial.tools.list_ports
```

結果

```
/dev/cu.Bluetooth-Incoming-Port
/dev/cu.usbserial-110
2 ports found
```

`Bluetooth-Incoming-Port` は除外し、検出された `/dev/cu.usbserial-110` が、今回作られた USB シリアルポートです。

ここで、シリアルポートが見えないようであれば、ケーブルを変えて、ハブを通さず直接接続したほうが良いです。途中で USB ハブをはさんでいるとうまく認識されないことがあります。

シェルスクリプト内でポートを扱う際、110 という数字は変動しそうなので、シェルスクリプトから取得する場合は私はこんな感じで探すようにしています。

```shell
port=$(ls -1 /dev/cu.usbserial* |head -n 1)
```

# CircuitPython のファームウェアを書き込む

RP2040(RaspberryPi Pico 等) のように、uf2 をドラッグアンドドロップして書き込むことはできません。ESP32はストレージデバイスとして認識されないためです。

ファームウェア書き込みのために、esptool というライブラリを使います。

## esptool のインストール方法

```shell
python3 -m pip install esptool
```

Pipenv を使う場合、以下のような Pipfile が良いと思います。

#### Pipfile
```
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
esptool = "*"

# 不具合を修正したフォークを使う
adafruit-ampy = {git = "git+ssh://git@github.com/ytyng/ampy.git"}

[requires]
python_version = "3.9"
```

```shell
pipenv install
```

adafruit-ampy については後ほど説明します。ファイルの転送に使います。

## CircuitPython のファームウェアの取得

HW-394 用の CircuitPython のファームウェアは用意されていません。そのため、構成の似ている
[DOIT ESP32 Development Board](https://circuitpython.org/board/doit_esp32_devkit_v1/) のファームウェアを使います。


本来の製品用のものではないため、自己責任での使用をお願いします。

[上記ページ](https://circuitpython.org/board/doit_esp32_devkit_v1/)から DOWNLOAD .BIN NOW を押して、ダウンロードします。

## ファームウェアの書き込み

esptool の `write_flash` を使って書き込みます。

```shell
#!/usr/bin/env zsh
port=$(ls -1 /dev/cu.usbserial* |head -n 1)

esptool.py --chip esp32 --port $port \
  --before default_reset --after hard_reset --no-stub \
  write_flash --flash_mode dio 0x0 \
  adafruit-circuitpython-doit_esp32_devkit_v1-en_US-8.2.9.bin
```

# Python の REPL に接続する

シリアルポートに接続することで、ボード上の Python コンソール (REPL) が使えます。

screen コマンドで接続します。

```shell
#!/usr/bin/env zsh

port=$(ls -1 /dev/cu.usbserial* |head -n 1)

screen $port 115200
```

```
Adafruit CircuitPython 8.2.9 on 2023-12-06; ESP32 Devkit V1 with ESP32
>>> import board
>>> dir(board)
['__class__', '__name__', 'D1', 'D12', 'D13', 'D14', 'D15', 'D16', 'D17', 'D18', 'D19', 'D2', 'D21', 'D22', 'D23', 'D25', 'D26', 'D27', 'D3', 'D32', 'D33', 'D34', 'D35', 'D4', 'D5', 'I2C', 'LED', 'MISO', 'MOSI', 'RX', 'RX0', 'RX2', 'SCK', 'SCL', 'SDA', 'SPI', 'TX', 'TX0', 'TX2', 'UART', 'VN', 'VP', 'board_id']
```

# Mac で書いた Python コードをフラッシュに書き込む

シリアルポートからファイルを書き込むには、 [rshell](https://github.com/dhylands/rshell) ,[mpfshell](https://github.com/wendlers/mpfshell), [ampy](https://pypi.org/project/adafruit-ampy/), および [upydev](https://pypi.org/project/upydev/0.0.9/) といったツールが使えそうですが、どれも開発ボードが MicroPython でないと使えないようです。

例えば、MicroPython では ubinascii というモジュール名なのが、CircuitPython では binascii となっていたりと、モジュール名が違うものがいくつかあるため、MicroPython 用のライブラリはそのまま CircuitPython では使えない場合が多いです。多くは、MicroPython 用のものは先頭に「u」がつく場合が多いです。

この中では ampy が一番シンプルなツールで CircuitPython への対応が容易そうなのでフォークして修正して使いました。本家では既にプルリクエストが上がっていますが、メンテが放置されているらしくマージされていません。

[修正済みampy](https://github.com/ytyng/ampy)

## 修正済みの ampy をインストールする

上で書いた Pipfile でインストールするか、

```shell
python3 -m pip install git+https://github.com/ytyng/ampy.git
```

でインストールしてください。

## Python コードを書く
基盤に実装されている D2 LEDを点滅させるスクリプトを書きます。

### blink_led_d2.py

```
import digitalio
import time
import board

print('brink_led.py loaded.')

led_pin = digitalio.DigitalInOut(board.D2)
led_pin.direction = digitalio.Direction.OUTPUT

while True:
    led_pin.value = True
    time.sleep(0.1)
    led_pin.value = False
    time.sleep(1.9)
```


## フラッシュに書き込む

### deploy.sh

```shell
#!/usr/bin/env zsh

export AMPY_PORT=$(ls -1 /dev/cu.usbserial* |head -n 1)

cd $(dirname $0)

ampy put blink_led_d21.py /code.py
```

フラッシュの `/code.py` としてコピーしした後、EN と書いてある基板上のボタン（リセットボタン)を押すと実行され、Lチカします。

![画像](https://media.ytyng.com/20231224/40ae557718e944328b5c2e506f91b701.jpg)

ピン番号を変更することで、他のピンでもLチカできることを確認しました。

![画像](https://media.ytyng.com/20231224/fe1a7bd34cc040288a30179f41c266a8.jpg)
