Network Stomper開発 Project 基板設計記[第1回(全5回)]

2019年11月11日 月曜日

「Network Stomper開発 Project 基板設計記[第1回(全5回)]」のイメージ

IIJは今年8月3日、4日に開催されたDIYのイベントMaker Faire Tokyo 2019に出展しました。展示テーマの一つ「音楽×IoT」の作品として、IPネットワーク経由でギターのエフェクタを操作する「Network Stomper(ネットワークストンパー)」を制作し、会場でギターの実演を行いました。

エフェクターを遠隔操作「ネットワーク・ストンパー」(Maker Faire Tokyo 2019)

このNetwork Stomperのコアになるハードウェア(制御ボード)は、IIJのエンジニアが一から開発しています。ハードウェアの開発は電源やノイズなど、ソフトウェアやネットワークの開発と異なるポイントに気をつけなければなりません。
実際に開発を担当したIIJ技術研究所の末永が、ハードウェア設計についてのレポートをまとめましたので、5回に分けて掲載します。

(編集部)

はじめに

Network Stomper開発 Projectでは、通常足で切り替えるギターエフェクタをWi-Fi経由で切り替える装置を作っています。これにより、ギタリストの立ち位置の制限を緩和できたら楽しいのではないかというアイデアです。エフェクタを改造してしまうのも一つの方法ですが、このProjectではエフェクタを操作する装置を作ります。どんなエフェクタでも無改造で使えれば余計な手間もかからなくて便利でしょう。

要件としては、

  • 足で操作する装置を動かすだけの大きな力を発揮しなければならない
  • 操作の遅延は可能な限り短くしなければならない
  • Wi-Fiで動作するコントローラが演奏の邪魔になってはならない
  • 従来通りの足による操作も受け付けなければならない
  • 装置全体の起動時間は可能な限り短くしなければならない
  • 秋葉原で売っている普通の部品で作れなければならない

といったところです。

結果として出来上がったのは以下のような駆動装置と、

以下のような5cm x 10cmの制御ボードです。基板は基板試作サービスのFusionPCBを利用し、部品の実装は家内制手工業により行われています。

本書では制御装置の設計についてゆるく解説します。

設計方針

色々と検討した結果、装置の駆動にはソレノイドを利用し、制御機構はArduino IDEで開発できるマイコンを採用することとしました。
ソレノイドは大きな力を発揮するには向かない素子ではあるのですが、モータをギアで減速して使うような方法と比較すると反応速度を上げやすく、サーボ制御がなくても位置が正確に決まるという利点があります。また、ソレノイドによる駆動機構は明和電機っぽくて音楽とは相性が良いような気がします。原理的には電磁石で鉄心を引っ張るという単純明解な素子となっています。
マイコンについては、起動時間の問題からラズパイ系よりもArduino系が良いという判断になりました。数年前まではArduinoとWi-Fiは面倒な組み合わせの一つでしたが、現在はEspressif 社製のESP-WROOM-02が使えるのでとてもコンパクトでお安く実現できるようになっています。ESP-WROOM-02はアンテナ内蔵で技適認証を取っているという点が大きな利点です。電波暗箱/暗室を利用しなくても堂々と開発できます。

制御ボードの詳細

制御ボードの役割は、Wi-Fiで受け取った指示にしたがってソレノイドのON/OFFを実行することです。色々と選択肢はありますが、まずはシンプルにESP-WROOM-02からリレーを駆動する回路を作りました。リレー制御でインタフェースしておけば、今回の目的以外でも汎用のWi-Fiスイッチとして活用できるであろうという目論見です。

上図のリレーの先にある青い端子台にソレノイドを接続します。スイッチは基板上にテスト用スイッチを置いているほか、ピンヘッダ経由で外付けスイッチを接続することも可能です。スイッチが押されたことを検出すると、Wi-Fiで他のボードに知らせるか、リレーを駆動するかします。この基板の回路図を以下に示します。

図 1 ESP-WROOM-2本体周辺回路

図 2 電源回路

図 3 スイッチ入力回路

図 4 リレー出力回路

図 5 USBシリアル回路

大まかなブロック構成としては、ESP-WROOM-02本体、電源回路、スイッチ入力回路、リレー出力回路、USBシリアル回路の6つです。

ESP-WROOM-02

GPIOを割り当てる

今回はボタン入力が3つとリレー出力を3つの3チャンネル制御という仕様にしました。最終的な制御対象のマルチエフェクタが3ボタンだから、というのがもっとも大きな理由です。Wi-Fi経由で操作するのでボタン入力はなくても良いのですが、デバッグのしやすさを考えてWi-Fiなしでも操作できるようにしています。
ボタンとリレーは大きな部品なので基板上の占有面積が大きくなります。そうすると余白もでてくることになるので、ついでにピンヘッダをつけてなるべく多くのGPIOを外だしするようにしました。さらにUSBシリアル変換チップも搭載してArduino IDEでお手軽に開発できる環境を作っています。
ボタン入力とリレーについてはGPIOの割り当てを決めておく必要があります。ESP-WROOM-02はGPIOにあまり余裕がありません。また、配線に制限のあるGPIOがいくつかあります。特に重要なのは、IO0、IO2、IO15の3つです。これらは起動時にINPUT端子として動作し、SoCであるESP-8266の起動モードを決定します (ESP8266 Pin List, 2018, p. Strapping)。IO2はpull upまたは未接続、IO15はpull down、IO0は必要に応じてpull upとpull downを選択できなければなりません。
また、汎用の通信端子としてUART(普通のシリアルポート)とI2Cは利用できるようにしておきたいところです。SPIも使えますが、ピンを多く消費するので今回は見送りました。ADCの入力としてTOUT端子というのもあるので一応、ピンヘッダには並べておくことにします。
という条件を考えて、ピン割り当ては以下としました。

ピン番号 割り当て機能
IO0 ファームウェア更新(pull up、ピンヘッダあり)
IO1(TXD) UART0-TXD
IO2 I2C-SDA (pull up)
IO3(RXD) UART0-RXD
IO4 リレー出力1(pull down)
IO5 リレー出力2(pull down)
IO12 ボタン入力2(pull up)
IO13 ボタン入力1(pull up)
IO14 I2C-SCL (pull up)
IO15 リレー出力3(pull down)
IO16 ボタン入力3(pull up)
TOUT ADC入力(未接続、ピンヘッダあり)

こんな感じでGPIOは売り切れです。IO12とIO13が逆転しているのはかつてIO15をボタン入力2に割りあてて設計していたら、pull upできないことに気が付き急遽IO12と入れ替えたためです。さらにIO16は入力割り込みが使えないということにも気が付きましたが、基板を製造したあとだったので、そのままにしてポーリングで監視しています。

内蔵ROMのメッセージ

UARTは別のピンを使ってSoCの内蔵ROMのメッセージを隠すという選択肢もあるのですが、今回はそのままにしました (ESP-WROOM-02 Datasheet v2.6, 2018, p. 6) (ESP8266EX Datasheet v6.0, 2018, p. 15)。このメッセージは少しやっかいで、ESP-8266に供給されているクロック周波数から自動的に通信速度が決まってしまい、ユーザは速度を指定できません。40MHz駆動の場合は115200bpsとなり普通なのですが、ESP-WROOM-02の26MHz駆動の場合は74880bpsという中途半端な数字になってしまいます (ESP8266EX Datasheet v6.0, 2018, p. 15)。74880bpsはシリアル端末ソフトの速度指定には含まれないことが多いようですが、76800bpsに設定するとデコードできることが多いようです(もともとRS-232Cの非同期通信はクロック信号を持たないのでタイミングのずれには寛容です)。
ESP-WROOM-02の場合、74880bpsで使っていれば通信速度は終始一定となるのですが、UARTの通信速度は安全性重視で9600bpsとするか、性能重視で115200bpsとするかの2択を軸に考えるのが普通の感覚です。自分の書いたプログラムでこのような普通の通信速度を採用しようと思うと、SoCの起動メッセージだけが速度が違うという状況になり、文字化けします。デバッグ専用ポートとして使っている分には構いませんが、汎用の通信ポートとしては難ありですね(ROMのメッセージが読めるのは開発初期のデバッグに役にたちますので無駄ではありません)。

TOUTは使える端子なのか?

TOUTは特殊な端子で、おまけ感が強い仕様となっています。ESP-8266のデフォルトの動作としては、ADCは無線LANのパワー・アンプ用の電源(VDD3P3)の電圧監視に使われています。これにより起動時に無線LAN周りのキャリブレートを自動実行してくれるという仕組みです。本来このためにADCを搭載しているのでしょう。しかし、TOUTに外付けの回路がつながっていると、ADCの出力が変わってしまい、このチューニングがちゃんと実行できません。そこで、TOUTを使う場合にはファームウェアのヘッダ部分を書き換えてVDD3P3の電圧を固定値とするようにSoCに教えてあげる必要があります (ESP8266EX Datasheet v6.0, 2018, pp. 16-17)。このヘッダの調整をせずにTOUTを利用すると無線LANの性能が落ちるという残念な結果になりそうです。調整をしてもキャリブレートが走らなくなると微妙に損した気分になります。多分ほとんど変わりませんけど。そもそもArduino IDEではTOUTの扱いがどうなっているのか、ちゃんと調査していないこともありピンは付けてみたものの、使いどころがない端子となってしまいました。ADC_MODE(mode)というマクロを書いておくことでADCで電源電圧を取得するのか、TOUTの電圧を取得するのか切り替えることはできるのですが、このマクロがファームウェアのヘッダを付け替えるような仕組みにつながっているかどうかが確認できません。特にリンカに指示を出すわけではないような?
おそらくGitHubのESP8266 coreのチームも色々と悩んでいるのだろうとは思いますが、現状はあまり綺麗に使えるものではなく、Arduino本来のanalogRead()関数とのすり合わせもできていないようです。

欠番しているピンはなに?

IO6からIO11が欠番になっているのは、ESP-WROOM-02のモジュール内部でSPIフラッシュと繋がっているためです (ESP-WROOM-02 Datasheet v2.6, 2018, p. 12)。制御しようと思えば出来てしまうかもしれませんが、SPIフラッシュへのアクアスができなくなり、まともに動作しないでしょう。他のボード用のスケッチを移植する場合はGPIOの初期化コードをきちんと確認したほうがよさそうです。

電源供給

下図が図 1 ESP-WROOM-2本体周辺回路の関連部分の拡大です。

C3,C4は電源ラインのノイズを捨てるためのバイパスコンデンサです。この組み合わせはESP-WROOM-02のデータシートのリファレンス回路そのものです (ESP-WROOM-02 Datasheet v2.6, 2018, p. 13)。C4は明らかにノイズフィルタっぽいですが、C3の10uFはバイパスコンデンサというよりは、電源を安定させるバルクコンデンサといったほうが良いのかもしれません。設計が新しい電源回路を使っていて、負荷変動への応答性が良好な場合、10uFでも十分に安定性を確保できるでしょう。
世間的には100uF以上のバルクコンデンサを積んで昔ながらの電源ICを利用している回路もよく見かけますが、データシートのリファレンス回路からは高速電源ICを使ってくれ、というメッセージが感じられます。

リセット回路

下図が図 1 ESP-WROOM-2本体周辺回路と図 5 USBシリアル回路の関連部分の拡大です。

EN端子(Chip Enable)

EN端子はESP8266を有効にして動作を開始させるためのピンです。EN端子がLOWになっているとESP8266は待機状態となり電力をほとんど消費しなくなります。他にもCPUがいるような場合にはESP8266を必要なときだけ有効にして消費電力を抑えるという構成が可能です。今回はESP8266以外のコントローラは使っていませんので動作中は常にEN端子はHIGHにしておくこととします。EN端子をHIGHにするタイミングについてはESP8266のデータシートに注意事項が記載されています (ESP8266 Hardware Degisn Guidelines v2.4, 2018, p. 8)。電源端子が3.3VになってからEN端子をHIGHにするという順番を守ること、という内容です。典型的な設計として、10kΩ/100nFで作ったRC遅延回路を使うべしということも書いてあります。ESP-WROOM-02の回路図にはRC遅延回路は見当たりませんので、外付けで回路を組んでやる必要があるようです。CHIP Enableピンはリセットピンの代用として使うこともあるので標準では遅延回路は入れていないということなのでしょう。
実はこのリセットシーケンスは更新されており、ESP8266 System Descriptionsv1.4という古いドキュメントでは、1kΩと0.1uFという指定が書かれていました (ESP8266 System Description v1.4, 2016, p. 6)。手元にあったドキュメントを元にR5に1kΩ、C2に0.1uFを配置する設計にしてしまったのですが、これだと遅延が足りないようです。今のところ動作に問題はないのでそのままにしていますが、本来は抵抗の交換が必要です。回路を引くときは最新のドキュメントをチェックしましょう。

RST端子(Reset)

こちらはSoCにリセットをかけるための端子です。LOWレベルに落とすとリセット状態になり、HIGHレベルにするとリセットが解除されます。リセットはEN端子を使って実現することもでき、データシートには明示的にEN端子をリセット端子として利用しても良いと書いてあります (ESP8266 Hardware Degisn Guidelines v2.4, 2018, p. 8)。EN端子によるリセットのほうがハードウェアの深い部分までリセットをかけられそうに思えますが、詳細はわかりません。今回はハードウェア的におかしくなった場合は電源OFF/ONで復帰すれば良いと考えてリセット動作はRST端子を使うことにしました。
実はこちらも古いドキュメントではEN端子はリセットにも使えるとしか書かれておらず、このような設計としたのですが、現在はEN端子の利用を推奨するという書き方になっています。RST端子には低消費電力モードであるDeep Sleep状態から復帰するという重要な役割があります。実際にはWakeup端子と言うべきなのでしょう。RST端子をスイッチ経由で操作するとDeep Sleep状態から復帰したのか、ユーザがリセットをかけたのか、分からなくなってしまうという問題が生じそうです。
RST端子を使う場合、遅延回路があったほうが良いと書かれていますが、EN端子用のような具体的な定数の指定はありません。RST端子は未接続でも動作するように設計されていますから、比較的おおらかな入力端子として設計されているのでしょう。今回はR22に10kΩ、C1に0.1uFの遅延回路を作ってあります。起動時のリセット解除タイミングを遅延させるという目的と、基板上のリセットボタンを押した時にチャタリングでノイジーな信号が印加されるのを抑止するという目的の2点が狙いです。リセットボタンを押すと、C1にチャージされていた電荷がR1(1kΩ)を経由して放電され緩やかに電圧が降下してリセットがかかります。ボタンを離すとR22(10kΩ)を経由してC1が充電されて緩やかに電圧が上昇してリセットが解除されます。解除のほうが10倍程度時間がかかる計算ですが、数ミリ秒の範囲内なので良しとします。
R1を省略しても動作はすると思われます。しかし、この場合スイッチを押した瞬間にC1が短絡されることとなり、理論上は無限に大きな電流が流れます。実際には抵抗が0ということはありませんので無限とはいきませんが、スパイク状のノイズを撒き散らす原因になりかねないのでR1で電流を制限しています。扱っているのがリセット信号ですから、避けられるノイズはできるだけ避けておきたいところです。
リセットスイッチを押してコンデンサの電荷がなくなると、R22とR1が直接に接続された状態となります。このとき、分圧比は10:1になりますので、R22で3Vの電圧降下が発生してR1では0.3Vの電圧降下が発生する計算となります。一方ESP8266のHIGHレベルは 2.5V以上、LOWレベルは0.8V以下という規定です。R1にかかる電圧の0.3VがRST端子への入力となれば確実にリセットがかかります。
RST端子はUSBシリアル回路へもつながっています。これはArduino IDEでプログラムを送り込む際に自動でリセットをかけるための仕掛けです。この回路はUSBシリアル回路の解説で記載します。

リセット動作の動作

この回路の電源投入直後の波形は以下のようになります。縦軸は1目盛1V、横軸は1目盛200マイクロ秒です。

黄色が3.3Vの電源電圧、紫色がEN端子にかかる電圧、水色がRST端子にかかる電圧の時間的な変化です。3.3V電源が立ち上がってから、180マイクロ秒くらいあとでEN端子がHIGHになり、さらに1.5ミリ秒程度たってからRST端子がHIGHになります。ここまでくるとソフトウェアが動作を開始します。よくあるコンデンサの充電曲線ですが、ちょっとしたタイミング制御には十分ですね。

起動後に手動でリセットボタンを押した時のRSTピンの電圧を下図に示します。色が変わってしまいわかり難くなってしまいましたが、先ほどの波形では水色に相当します。

コンデンサが緩やかに放電されている様子が分かります。横軸は電源投入のグラフと同じですので、リセットをかける動作が解除する動作よりも早いことも確認できます。

スイッチのチャタリングも目立ちませんし、まぁまぁ良いのではないかと考えていました。しかし、このリセット回路には不具合がありまして、不具合についてはUSBシリアル回路で記載します。

ブートセレクタ

以下が図 1 ESP-WROOM-2本体周辺回路と図 5 USBシリアル回路からの関連部分の拡大です。

ESP-WROOM-02はリセット解除時にIO0がLOWレベルになっているとUART起動モードとなり、シリアル通信でファームウェアを読み込んで実行します (ESP8266 Pin List, 2018, p. Strapping)。ESP-WROOM-02の開発環境では、この仕組みを使ってSPIフラッシュへのプログラムの書き込みを実行します。このプログラム書き込みモードと実行モードの切り替えをするスイッチがSW2となります。

SW2が開いている場合、IO0はR27の10kΩを経由して電源に接続されています。IO0が入力端子として設定されている場合、電流はほとんど流れません(50nA以下)から (ESP8266EX Datasheet v4.4, 2015, p. 17)、抵抗での電圧降下は生じずIO0への入力はほぼ電源電圧に一致します。IO0への入力はHIGHとなりSPIフラッシュからの起動が選択されます。

pull up抵抗の値にはあまり根拠はありません。経験則として10kΩから100kΩくらいにしておくと大抵はうまく動くことが知られています。抵抗値が小さいと、グランドと接続された場合により多くの電流が流れてしまうため消費電力が増えたり、GPIOに過電流が流れてしまったりします。IO0は普段は入力端子ですので電流は流れませんが、ソフトウェアからpinMode()でOUTPUTを指定してdigitalWrite()でLOWを出力した場合、このケースに当たります。抵抗値が大きすぎるとノイズにより微小な電流が流れた場合に大きな電圧降下が生じて電圧が不安定になることがあります。Espressif社のドキュメントでは1MΩを標準として、場合によっては100kΩという雰囲気で、このくらいであれば問題ないのだと思いますが、1MΩまで大きくするとオシロスコープのプローブの内部抵抗と同じ領域になってしまい測定が不自由になることがあります。

SW2を閉じている場合、R17の10kΩとR7の1kΩが直列接続されます。IO0はこの状態でのR7の電圧を読み取ることになります。直列接続では抵抗値の比で電源電圧が分圧され、電源電圧が3.3Vの場合ですとR17には3Vがかかり、R7には0.3Vがかかります。ESP8266は電源電圧の1/4、すなわち0.8V以下をLOWレベルとみなしますのでIO0への入力はLOWとなりプログラム書き込みモードでの起動が選択されます。

IO0への入力をLOWにする目的であれば、R7を不要としてグランドに直接接続してしまう方法も考えられます。ブレットボードでの実験などであれば、大抵は直接接続にするでしょう。この場合の問題点はIO0がGPIOでありOUTPUTに設定される可能性があるという点です。この設定をされてしまうと、R7を付けておかないとIO0からグランドに対して無制限に電流が流れてしまいます。ESP8266のGPIOポートは最大で12mAまでしか電流を供給できませんので (ESP8266EX Datasheet v6.0, 2018, p. 18)、運が良くて誤動作、運が悪ければ故障につながります。当然、そんなプログラムを意図して書くことはありませんが、他のボード用に書いたスケッチを移植する過程ではありがちなバグでもあります。Arduinoではスケッチの再利用性の高さも魅力の一つですので、ハードウェア側でなるべく安全側に倒す設計にしています。最近は例外が多いのですが、ソフトウェアでハードウェアが壊れることはない、という計算機の原則はやはり大切だと思います。

IO0もRSTと同様にUSBシリアル回路にも接続されています。これはArduino IDEでのプログラミングのための仕組みで、RSTと一緒にUSBシリアル回路と一緒に解説します。

I2C

下図が図 1 ESP-WROOM-2本体周辺回路からの関連部分の拡大です。

今回は利用しませんでしたが、基板上の土地が余っていたのでI2Cの信号線を引き出しています。I2Cはセンシングや表示に使えますので、使えるようにしておくとなにかと便利なインタフェースです。

R6,R8はI2Cの通信路を動かすためのpull up抵抗です。I2Cは仕様上マスタ側もスレーブ側も電圧源を持たないことになっていますので、このような形で外部から電圧をかける必要があります。本当は、通信は相手あっての話ですので、実際に使う段階で通信相手の事情も考慮してpull up抵抗をどこに追加するのか設計するのが一番だと思います。しかし、今回はお手軽さを優先してあらかじめpull upしてしまいました。

マイコンの内蔵pull upの機能を使えるのであれば、外付け抵抗はなくても動きますし、必要に応じて切り替えられるので便利です。が、ESP-8266の場合には残念ながら内蔵pull upの抵抗値が30kΩから100kΩという範囲で (Pull up resistors, 2015)、これはI2Cの駆動には大きく、配線の制約が強くなりすぎます。

I2Cの駆動電流は最大で3mAと決まっています。これを超える電流はI2Cデバイスで流しきれず電圧をしっかり下げることができなくなります。I2Cデバイスの入力トランジスタの発熱にもつながるでしょうから熱的にもよろしくありません。この観点から、3.3V電源であれば1.1kΩ以上の抵抗を付けて電流を制限する必要があることがわかります。

I2Cでは配線の浮遊容量も決まっており、400pFが最大値です (I2Cバス仕様書 v2.1, 2000, p. 6)。一方、ESP8266のI2Cのクロック速度は100khzが性能限界とされています (ESP8266EX Datasheet v6.0, 2018, p. 14)。そして100kbps(標準モード)のI2C通信のパルスの立ち上がり時間は1000nsec=1usecと規定されています (I2Cバス仕様書 v2.1, 2000, p. 30)。以上から、400pFのコンデンサを1usec以内に充電できれば合格であろうと分かります。単純にRC時定数τで信号が立ち上がると仮定すると、τ=RCですから、R=τ/CよりR=1 [usec]/400[pF]=2.5[kΩ]あたりが上限となりそうです。これより大きな抵抗をつけると電圧が上がりきりません。1τだと電圧は63.7%までの上昇に止まり、I2Cの仕様である70%には届きませんので実際にはもう少し低い抵抗値が必要でしょう。2kΩくらいの抵抗を付けておけば、規格通りのバスといえるでしょうか。この時点で、ESP8266の内蔵pull upでは明らかに抵抗が大きすぎ、配線の特性に敏感になりすぎるであろうとわかります。

試しに理論値を計算してみると、1usec経過時点で400pFのコンデンサを70%充電できる抵抗値は2.08kΩ以下となりました。とはいえ、ぴったりの抵抗はなかなかありませんし、高精度抵抗を直列にして頑張るところでもありません。1.1kΩから2kΩ付近で比較的入手しやすそうな1.2kΩ、1.5kΩ、2.2kΩあたりが候補かと思われます。1.2kΩだと電流が過大で規格に適合しません。大抵のデバイスには余裕がありますが、動いたとしても消費電力が多めになります。電流が多ければ接触抵抗などによる電圧の変動も大きくなります。2.2kΩだと信号の立ち上がりが若干規格値に及びませんが、電流超過よりは良いでしょうか。最終候補としては、規格重視で1.5kΩか、規格よりも消費電力を重視して2.2kΩか、というところで今回は2.2kΩを選びました。

ESP-WROOM-02でI2Cを使う場合、若干の制限が生じます。データシートによると、I2CのSDA信号は標準ではIO2を使うことになっています (ESP8266EX Datasheet v6.0, 2018, p. 6)。このIO2はブートモードの選択にも使われるピンで、起動時にはHIGHになっている必要があります。このピンを通信に使うというと厄介な問題が生じます。ESP-WROOM-02に再起動がかかった時に、I2Cで接続されたデバイスがSDAをLOWにしてしまうと起動に失敗するのです。これを防ぐためにはFETを追加するなどして、ESP-WROOM-02のリセット動作時にはI2Cバスを切り離しておく真面目なリセット回路が必要となります。今回はこの回路は組んでいませんので、I2Cを使っていると再起動に失敗する可能性があります。特に本機がI2Cのスレーブになっている場合はいつマスタが話しかけてくるのか分かりませんので危険です。本機がマスタの場合、要求を出さなければスレーブは何もしないはずなので危険性は低いのではないかと期待できます。

細かいですが、本機がマスタであったとしても、要求を出した時点でウォッチドッグリセットによる再起動がかかったり、ユーザがリセットボタンを押したりするなどのコーナーケースは残ります。ウォッチドッグリセットがかかると起動に失敗して動作が完全に停止する、という話になったのでは本末転倒な感じです。そうすると、真面目なリセット回路を設計するとしても、ウォッチドッグリセットを外部から知る手段はあるのか?など、色々考えるべきことが見つかります。こんなコーナーケースなんて考慮する必要があるのか?と思ってしまうところかもしれません。しかし、今までの経験からすると顧客はピンポイントでコーナーケースを突いてくる存在でして、どうしても考えずにはいられません。本機は売り物ではないので、なんとなく考えるだけですが。

I2Cインタフェースをちゃんと設計するのは案外手間がかかりますね。

I2Cの波形

I2Cインタフェースに温度・湿度・気圧センサの定番であるBosch BME280をつないだときの波形を上図に示します。黄色のチャンネル1がSDA(データ)、水色のチャンネル3がSCL(クロック)です。キャプチャ画像だとみづらくなってしまいますが、若干クロストークが見えたり、波形の立ち上がりと立ち下がりに鋭いオーバーシュートが見えたりしています。とはいえ、全体としてはそこそこ綺麗な矩形波になっています。

信号の立ち上がり、立ち下がり部分の拡大を上図に示します。クロックには割と大きなリンギングが見えますね。これは配線がコイルとして働いたものと考えることも、バスの終端で信号が反射したものと考えることもできます(同じ物理現象ですが、計算手法が2つあります)。真面目にインピーダンス計算をすれば軽減できるはずです。今回の配線はブレッドボードでよく使う2.57mmピンヘッダに刺すケーブル(約15cm)を刺しただけですので、品質は推して知るべしという結果になりました。SDA信号の立ち上がり時間はΔXの値で、237nsとなっています。目標は1000nsですので、十分に余裕がある数値です。筐体内部で配線するのであれば安心して使えるでしょう。同じI2Cでも高速モードを使うと厳しいかもしれないですね。

通信の様子がある程度わかるスケールでみると上図のようになります。縦軸が一目盛り2Vから1Vに変更されているので今までとは振幅が異なります(こうしないとオシロスコープがデコードしてくれない・・・)。こうしてみると細かいヒゲが気になってきますが、全体として均質ではあるのでバースト転送が発生しても頑張れるのではないかと思います。

第2回に続く…)

引用文献

  • Espressif Inc. (2015年8月1日). ESP8266EX Datasheet v4.4.
  • Espressif Inc. (2016年1月). ESP8266 System Description v1.4.
  • Espressif Inc. (2017年5月). ESP8266 Technical Reference v1.3.
  • Espressif Inc. (2018年3月). ESP-WROOM-02 Datasheet v2.6. 21.
  • Espressif Inc. (2018年12月). ESP8266 Hardware Degisn Guidelines v2.4.
  • Espressif Inc. (2018年12月13日). ESP8266 Pin List.
  • Espressif Inc. (2018年11月). ESP8266EX Datasheet v6.0.
  • Phillips Semiconductors. (2000年1月). I2Cバス仕様書 v2.1.
  • Pull up resistors. (2015年9月9日). 参照先: ESP8266 Developer Zone: https://bbs.espressif.com/viewtopic.php?t=1079#p4097

末永 洋樹

2019年11月11日 月曜日

2003年の入社以来SEILシリーズのファームウェア開発に取り組んでいましたが、最近は子会社のIIJ-IIでエッジコンピューティングを中心として次世代技術の動きを追っています。

Related
関連記事