ESP32のリセット問題の件

スポンサーリンク

はじめに

BambuのAMSに仕込む温度湿度データロガーをESP32を使って作ろうとしています。 JLCPCBから届いた青箱をウキウキで開いていざ試してみると色々問題点が。。。 ESP8266の基板(前に自分で作ったやつ)を参考に自動書き込み機能を搭載したのですが、これが上手く動かない…(他にも色々問題はあるのですが)
Xian DIY ESP-WROOM-02 書き込み装置www.switch-science.com ということで、何が問題か検証してきました。忘れないようにブログにまとめておきます。 (力尽きたので途中ですが、公開しちゃいます。明日また追記していく感じで)

回路図

今回議論するのは回路図のAutoModeの部分です。

USBシリアル変換ICはCH340Kを使っています。だいたい何時もこのチップを使っています。

https://akizukidenshi.com/goodsaffix/ch340.pdf

DTR#,RTS#と書いてあって、これは負論理なんですよね。ESP32のモジュールの自動書き込み回路をそのまま真似出来ない理由がここです。

data terminal ready, active
low(high)

active lowですからね。難儀ですね。

ESP32-WROOM-32

ESP32のBootingモードで、書き込みの際にSPIからDownload Bootに変わればいいわけですね。IO2のSPI Flash Bootが Don't-careなのが嬉しいポイント。

https://akizukidenshi.com/goodsaffix/esp_wroom_32_datasheet_en.pdf

オシロスコープで波形を見てみる

プローブを接続できるようにCH340KのDTR#,RTS#とESP32のENとIO0にも配線しました。

ESP32 Dev Moduleを選択して書き込みしました。 オシロでみた波形がこちらになります。

Ch1(黄) CH340K-DTR# Ch2(青) CH340K-RTS# Ch3(オレンジ)ESP32-IO0 Ch4(緑) ESP32-EN0

Download modeに移行するにはIO0とEN0に入力される波形は下記のようになっていないとダメなのですが、残念ながらこれでは上手く出来ていませんね。

ESP32開発ボードを買って波形を見てみる

ちゃんと自動書き込みができるボードを買って、波形を見てみることにしました。

USBシリアル変換チップはCP2102/9が使われていました。テスターを使って回路を追っていくとJ3Yというnpnトランジスタのところまで配線が来ていました。このトランジスタにつながっているチップ抵抗も外した後に、オシロRTSとDTR波形をみれるように配線していきました。

そいで、波形をみていみますと、こんな感じです。CH340KのDTR# RTS#は負論理なので、逆転していますね。

Ch1(黄) DTR Ch2(青) RTS

書き込みツールの中身を見てみる

これひょっとしたら、コードをいじればなんとかなっちゃうんじゃないの、と思って覗いてみました。 pythonで書いてあるんですね〜loader.pyというファイルです。で、DTR,RTSをゴニョゴニョしている、それらしい部分を抜粋しました。最初どの部分が関係しているかわからなかったので、print("xian diy")を書き込んで探しましたww

ファイルの在処はここです↓

.arduino15/packages/esp32/tools/esptool_py/4.2.1/esptool/loader.py

そいでコードの抜粋です。

# This fpga delay is for Espressif internal use
            print("xian diy");
            fpga_delay = (
                True
                if self.FPGA_SLOW_BOOT
                and os.environ.get("ESPTOOL_ENV_FPGA", "").strip() == "1"
                else False
            )
            delay = (
                7 if fpga_delay else 0.5 if extra_delay else 0.05
            )  # 0.5 needed for ESP32 rev0 and rev1

            self._setDTR(False)  # IO0=HIGH
            self._setRTS(True)  # EN=LOW, chip in reset
            time.sleep(0.1)
            self._setDTR(True)  # IO0=LOW
            self._setRTS(False)  # EN=HIGH, chip out of reset
            time.sleep(delay)
            self._setDTR(False)  # IO0=HIGH, done

いまCH340KのDTR#,RTS#は負論理なんで、ここの論理を逆にしちゃえば良いのではと思い書き換えてみました。

self._setDTR(False)
 self._setRTS(True)

予想があたって上手く動きました!