TT Lab
はじめる
学ぶ 学習パス コース

センサーは正常なのに、ボードが聞き取れない

「デバイスが応答しません」という一行

TT Labで続きを見る

一言でいうと

I2Cは、線を引き下げることしかできません。引き上げるのは抵抗の仕事で、そのため、故障の半分は立ち上がりエッジにあります。

なぜ必要なのか

温度センサー1つが、昨日まで読めていたのに、今日は読めません。ドライバーは「デバイスが応答しません」としか言いません。この一文は、複数の原因を1つにまとめてしまったものです。アドレスが間違っているのかもしれませんし、センサーが壊れているのかもしれませんし、電源が入っていないのかもしれませんし、バスがまるごとロックされているのかもしれません。波形を見ると、この4つはまったく違う形をしています。

I2Cを読めるようになれば、ドライバーの一行だけのエラーを、どのビットで何があったかに変えられます。それが、このモジュールの目的です。

どう動くのか

線は2本です。SCLがクロック、SDAがデータで、どちらもオープンドレインです。デバイスはトランジスタで線を接地につなぐことしかできず、離すと、プルアップ抵抗が電源まで引き上げます。そのため、立ち下がりは速く、立ち上がりは、抵抗と寄生容量が決める速度で遅くなります。TIのI2Cのガイドは、この非対称性を、図で先に説明しています。抵抗が小さければ通信は速いですが、電流を多く使い、大きければ遅くなります(SBAA565、SLVA704)。

ルールは、2行に要約されます。データはSCLがローのときだけ変わります。そして、SCLがハイの間にSDAが動いたら、それはデータではなく条件です。下がればSTART、上がればSTOPです。NXPの規格書が、この定義をそのまま書いています(UM10204)。

      START                                   STOP
SDA  ‾‾\____  A6 A5 A4 A3 A2 A1 A0 R/W ACK  ____/‾‾
SCL  ‾‾‾‾\__/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\_/‾\__/‾‾‾‾

STARTのあとには、7ビットのアドレスと、読み書きのビット1つが続き、9番目のビットがACKです。この位置で、マスターはSDAを離し、アドレスが合ったデバイスが代わりに引き下げます。誰も引き下げなければ、プルアップのためにハイのまま残り、それがNACKです。つまり、NACKはデバイスが送った信号ではなく、何も起きなかったという事実です。アドレスを間違えたときと、センサーに電源がないときの波形が同じ理由が、これです。

読み取りの転送は、たいてい2回開始します。まず、書き込みのアドレスでレジスタ番号を渡し、STOPなしで繰り返しSTARTを出したあと、読み取りのアドレスで、あらためてアドレスを指定します。途中でSTOPを出すと、その間にほかのマスターが割り込めるので、繰り返しSTARTは「まだ終わっていない」という宣言です。そして、マスターは最後に受け取るバイトにわざとNACKを出します。これはエラーではなく、「もう送らなくてよい」という意味です。波形だけを見て、最後のNACKを故障として報告することが、よくあります。

クロックストレッチングは、スレーブがSCLを離さずに握り続けることです。準備ができていないので待ってほしいという意味で、マスターはSCLが解放されるまで待たなければなりません。波形では、マスターが作った別のローの区間と長さがはっきり違う区間が1つあるように見えます。このコースのキャプチャでは、ローの区間の中央値が5µsなのに、そのうち1つだけが47µsです。原因を探すとき、「誰がこの区間を作ったのか」を問うことが核心です。マスターは、自分が作っていない区間を説明できません。

最後が、弱いプルアップです。抵抗が大きすぎたり、配線の容量が大きすぎたりすると、立ち上がり時間が長くなり、ビット時間の中にVIHまで上がりきれません。このコースのキャプチャで、SDAの10% → 90%の立ち上がりは5.25µsなのに、SCLは1.00µsです。400kHzでSCLがハイの区間はそれより短いので、SDAが1を運ぶ時間がありません。半分の電圧(1.65V)で読むと、データは正常に見えますが、0.7 × 3.3 = 2.31Vで読むと、18個の区間のうち1つだけが1と読めます。同じファイルで、しきい値が違い、結論が違います。

現場での姿

バスがロックされる事故があります。スレーブがバイトを送っている途中でマスターが再起動すると、スレーブは自分が0を出していた位置で止まったまま、SDAを離しません。マスターはSTOPを作ろうとしますが、STOPはSDAを上げなければ成立しないので、作れません。波形には、STARTはあるのにSTOPがなく、SDAが長くローのまま残ります。再起動しても解決せず、SCLを何度か揺らして、スレーブに残りのビットをすべて出させる必要があります。

プルアップ抵抗を複数のボードに分けて付けておき、合算して小さくなりすぎた場合も見ます。このときは、立ち上がりが速くなって通信はできますが、消費電流が増え、バッテリー寿命の報告書で、あとから明らかになります。立ち上がり時間は、一方向にだけ悪い値ではありません。

次のクイズで確認すること

STARTとSTOPの定義、ACKの位置で実際に起きること、最後のバイトのNACKがなぜ正常なのか、クロックストレッチングを波形からどう見分けるか、弱いプルアップがどちらのエッジに現れるかを問います。