uchan note

プログラミングや電子工作の話題を書きます

レベル変換の仕組み(オームの法則からMOS-FETを使ったレベル変換回路まで)

レベル変換

レベル変換とは、電圧の異なる信号線をつなぐ際に電圧を変換することです。

例えば Raspberry Pi という小さな Linux ボードコンピュータの電源電圧は 3.3V です。 そのため GPIO の入出力電圧も 3.3V となっており、電子工作でよくある 5V 駆動の装置を直接つなぐことができません。 著者は最近、秋月電子通商で売っている中で最安のキャラクタ液晶表示器 SC1602Raspberry Pi から制御しようと思ってレベル変換回路を作りました。

また、いわゆる「L チカ」といって LED を点滅させるだけの回路でも、LED によっては 3.5V 程度の電圧がないと十分に光らない品種があり (赤色 LED に比べ、青色 LED は高い電圧を求める傾向があります)、3.3V の出力では十分でないケースがあります。

レベル変換は低電圧側の回路から高電圧側の回路を制御するだけでなく、逆に高電圧側から低電圧側の回路を制御するのに用いる場合もあります。

ハードウェアエンジニアにとっては良く知られた回路ですが、ソフトウェア専門の人がちょっと電子工作しようとするとハマることが多いと思います。 この記事では、オームの法則を復習しつつ、レベル変換回路の基礎を見てみます。

一方向レベル変換

一方向レベル変換回路は、低電圧側の回路からは出力 だけ を行い、高電圧側から低電圧側への通信はしない、またはその逆に高電圧側から低電圧側へのみ信号を伝達するときに使うことができる回路です。 キャラクタ液晶表示器 SC1602 はこの方法で制御を行うことができます。

信号の流れが一方向に制限される代わりに回路がとても単純で、部品代を抑えることができます。 なかなか実用的な回路である上に、オームの法則を復習しながら学ぶ回路として適切ですので、最初に取り上げることにしました。

f:id:uchan_nos:20161204102105p:plain

一方向レベル変換回路に行く前段階として、上図をもとにオームの法則をおさらいします。

電源の電圧を E(V)、抵抗器の抵抗を R(Ω) とすると、(a)、(b) の回路で、矢印で示した区間の電圧(電位差)はそれぞれ 0(V)、E(V) になります。 その理由を説明しましょう。

オームの法則

抵抗器の両端電圧 V(V)、抵抗器に流れる電流 I(A)、抵抗値 R(Ω) とすると、オームの法則は次のように表せます。

V = I × R

この式は、抵抗器に電流が流れることで電圧が発生する、ということを言っています。電流と抵抗値がともに 0 より大きい場合、電圧が 0 より大きくなりますよね。

さて、ここで回路 (a) を見ます。 この回路における矢印の区間は、導線だけで結ばれています。 理想的な回路では導線の抵抗値は 0 ですから、オームの法則に R = 0 を当てはめると V = 0 と計算できます。 つまり 矢印間の電圧は 0(V) です。

次は回路 (b) を考えましょう。 この回路では、矢印の間が開放されていて電流が流れません(または、抵抗値が無限大の抵抗器が付いているとみることもできます)。 当然、抵抗器にも電流は流れませんので、抵抗器の両端電圧はオームの法則に I = 0 を当てはめれば V = 0 となります。

したがって、矢印が指す 2 点のうち、上側の電位は電源のプラス極と同じに、下側の電位は電源のマイナス極と同じになります。 電源電圧は E(V) ですから、矢印間の電圧(電位差)は E(V) となります。

電位と電圧

先ほど 電位 という言葉を使いました。電圧ではなく電位と言ったのには深い理由があります。

電圧はある 2 点の間の電位の差のことを言います。 2 点間で考える値なので、「点 A と点 B の間の電圧」ということはできても、「点 C の電圧」というのはありません。 ですから「電源のプラス極の電圧」とは言えないのです。「電源のマイナス極から見たプラス極の電圧」とは言えます。

これに対し、電位はある 1 点の値です。 ですから、先ほど「矢印の上側の電位」と書いたのです。

比喩として ビルの高さ海抜 の関係を考えます。 ビルの高さは「地面から屋上までの長さ」ですよね。 または、「地面の海抜と屋上の海抜の差」とも言えます。 これらは見方が違うだけで同じ値になります。

f:id:uchan_nos:20161204103752p:plain

ニコニ・コモンズのビルの絵 を利用させていただきました。ありがとうございます!

ビルの高さが電圧だとすれば、海抜は電位に相当します。 ビルの高さは、必ず地面と屋上という 2 点間の長さなのに対し、「地面の海抜」や「屋上の海抜」などと、海抜はある 1 点についての値です。

電子回路では電位より電圧をよく使います。それは、電位は基準点(基点)により値が変わってしまうからです。

例えば、電源のマイナス極を基準点とすると、電源のプラス極の電位は E です。 電源のプラス極を基準点とすると、電源のプラス極の電位は 0 で、マイナス極の電位は -E となります。

基準点をその回路とは切り離された点(例えば、あなたのパソコンのケース)に設定することもでき、そうするともはや電位の値自体は意味のあるものになりません。

一方で、電位の差である電圧は、電位の基準点に依らず計算できます。 差を取ることで基準点の影響が打ち消されるからです。 回路 (a) における矢印の間の電圧はいつでも 0 であり、電源のマイナス極とプラス極の間の電圧はいつでも E です。

この記事の中で「電位」というときは、その具体的な値は意味がありません。 必ずもう 1 点の電位との間の電圧を求める、という流れになります。

スイッチによる制御

さて、回路 (a) (b) の動作が分かったところで、スイッチを取り付けた下の回路を見てみます。

f:id:uchan_nos:20161204101152p:plain

図中のスイッチを押せば (a) と、離せば (b) と同じ回路になります。 したがって、矢印間の電圧はこうなります。

  • スイッチを押すと 0(V)
  • スイッチを離すと E(V)

さて、このスイッチは、プッシュスイッチとかモーメンタリスイッチと呼ばれる力学的なスイッチです。 外側から力をかけて ON/OFF を切り替えるものです。

これを 電子的に制御できる スイッチに変えてみたらどうでしょう。

f:id:uchan_nos:20161204102104p:plain

電子制御できるスイッチの 1 つである MOS-FET を取り付けてみました。 (回路の動作を大雑把に把握するのが目的なので、実用回路ではほぼ取り付けることになる補助的な部品は省きました。)

MOS-FET は 3 つの端子を持つ部品です。 図中では 1 から 3 の端子番号が振ってあります。 3 つの端子はそれぞれ次のような名前を持ちます。

  1. ドレイン
  2. ゲート
  3. ソース

MOS-FET は、ソースからみたゲートの電圧の高低により、ドレインとソース間が導通したり、しなかったりします。

ソースからみたゲートの電圧 ドレインとソース間
高い(しきい値電圧以上) 導通
低い(0(V) からしきい値電圧の範囲) 非導通

本当は、しきい値電圧付近では中途半端な状態になりますが、今はそれは気にしないで大丈夫です。

この知識をもとに先ほどの回路を見てみると、回路 (d) ではドレイン(1)とソース(3)間が導通し、白抜き矢印の方向に電流が流れます。 ドレインとソース間は短絡状態になり、矢印間の電圧は 0 となります。

回路 (e) ではドレインとソース間は導通せず、電流は流れません。 抵抗器にも電流が流れないので、矢印間の電圧は E となります。

再び、一方向レベル変換

さて、今までの知識を使って一方向レベル変換回路を作ってみます。 まず、3.3V 駆動の Raspberry Pi で、3.3V ではちょっと暗すぎる LED を明るく点灯させることを目指します(例えば 高輝度青色 LED OSUB5161A-PQ は順方向電圧が 3.4V なので、3.3V だと暗いです)。

f:id:uchan_nos:20161204105527p:plain

Raspberry Pi の GPIO を MOS-FET のゲートに、GND をソースにつなぎます。 GPIO とゲートの間にある抵抗器は保護用の抵抗で、もし MOS-FET が壊れてショートしていたとしても、抵抗があることで GPIO に過電流が流れないようになります。

このように接続すると、ソースとゲート間の電圧を、Raspberry Pi 上のプログラムから自由に切り替えることができます。 すなわち、(d) (e) のどちらかの状態を、プログラムから選択できるわけですね。 GPIO に出力する値により次のどちらかになります。

  • 0 を出力:GPIO は 0V となり、MOS-FET は非導通。LED は消灯。
  • 1 を出力:GPIO は 3.3V となり、MOS-FET は導通。LED は点灯。

3.3V の信号で、5V の LED 点灯回路を制御できたので、レベル変換できたといえます。

※むむむ?「GPIO は 0V となり」って、どうも 1 点の電圧 を言っているように見えます。変ですね。

これは、暗黙的に Raspberry Pi の GND から見た GPIO の電圧のことを、GPIO の電圧と言っているからです。 電圧は 2 点間でしか考えることができませんが、その片方はしばしば「基板の GND 端子」とします。 電子工作の文書などで GND が基準であることはしばしば省略されるので慣れてください。

TBD62003A

このようなレベル変換はとてもよく使う回路なので、専用の IC があります。 ここでは秋月電子通商で手に入る TBD62003APG を使った回路を紹介します。

f:id:uchan_nos:20161204112806p:plain

型番の最後の PG は IC のパッケージ形状を表しています。 TBD62003APG はブレッドボードに指しやすい DIP タイプのパッケージです。 パッケージ形状は回路の動作には関係ありませんので、回路図ではどのパッケージでもよいという意味で TBD62003A と記載しています。

TBD62003A は、先ほど紹介した MOS-FET による一方向レベル変換回路が 7 回路も入った IC です。 回路図の I1 と O1、I2 と O2、... I7 と O7 がそれぞれ対応していて、Ix が MOS-FET のゲート、Ox がドレインにつながっています。

内部回路

興味のある方向けに TBD62003A の 1 回路分の回路図を示します。 TBD62003A のデータシートからの引用です。(データシートは https://toshiba.semicon-storage.com/jp/product/linear/transistor-array.html からダウンロードできます)

f:id:uchan_nos:20161204112807p:plain

色々な部品が付いているのでごちゃっとしていますが、中央に MOS-FET があり、全体として (d) (e) と同じような配置になっていることが分かるかと思います。

本当の(?)レベル変換

今までの回路が嘘というわけではありませんが、L チカ回路は 3.3V を 5V に変換しているというより、LED に流れる 電流を ON/OFF していると言った方が自然でしょう。 LED は流れる電流量によって明るさが変わるので、電圧が何ボルトであろうが関係なく、一定の電流が流せることが重要です。

もっと直接的に、3.3V を 5V に変換すること自体に重きを置いた回路を見てみます。

f:id:uchan_nos:20161204125337p:plain

この回路は (f)L チカ回路から LED を取り除いたものです。 点 P の電圧(GND と点 P の間の電圧のことですよ)が、GPIO の出力により変化します。

  • 0 を出力:GPIO は 0V となり、MOS-FET は非導通。点 P の電圧は 5V
  • 1 を出力:GPIO は 3.3V となり、MOS-FET は導通。点 P の電圧は 0V

これで、駆動電圧 3.3V の機器から駆動電圧 5V の機器を制御できることになります。 ちなみに図中の 10k の抵抗器のことを プルアップ抵抗 と呼びます。 電源電圧まで引っ張り上げる(プルアップする)抵抗という意味です。

この回路を利用すれば Raspberry Pi から 5V 駆動の LCD 表示器を制御できます。 その回路図を示します。

f:id:uchan_nos:20161204131017p:plain

一気に複雑度が上がりましたが、個々の部分をゆっくり見れば分かると思います。

先に紹介した TBD62003A を使って、6 個の一方向レベル変換回路を組んでいます。 プルアップ抵抗は 10kΩ のものを使いました(抵抗値は経験による勘です)。

D0 から D5 は、Raspberry Pi の任意の GPIO ポートにつなぎます。 TBD62003A の出力側は LCD 表示器の入力ピンにつながっています。 こうすることで、0V と 5V で制御する必要のある LCD 表示器を 3.3V しか出力できない Raspberry Pi から制御することができます。 めでたし、めでたし。

ただし、ここで紹介したレベル変換回路の仕組み上、論理が反転することに注意してください。 GPIO に 1 を出力すると、LCD 表示器の入力ピンには 0 が入力されます。

したがって、ソフトウェア上で論理を反転させてから出力する必要があります。 特に難しいことではありませんが、もしあなたがハードウェアエンジニアなら、ソフトウェアがなるべく簡単になるようにハードウェアを設計したくなるかもしれません。

しかし本記事は ソフトウェアエンジニアのための記事 ですから、 ハードウェアはなるべく安く仕上げ、ソフトウェアで解決するというのが目指すべき道な気がします。 論理の反転程度のことは、ソフトウェアエンジニアの皆さんなら華麗に解決していただけることでしょう。

双方向レベル変換

ここまでは、片方がずっと出力で、もう一方がずっと入力である回路同士をつなぐレベル変換回路を見てきました。

入出力どちらもするような回路同士をつなぎたいときはどうすればいいのでしょうか。 それには 双方向レベル変換回路 を用います。 例えば駆動電圧の異なる 2 つの装置を I2C でつなぐとき、双方向レベル変換が必要になります。

双方向レベル変換は、一方向レベル変換に比べて高度な話題となります。 ですから、深入りせずにとりあえず双方向レベル変換ができることを目指します。

双方向レベル変換を行うには、手軽な選択肢が 2 つあります。

専用のモジュールは、そのまま買ってつなぐだけで動きますので非常に手軽です。

レベル変換回路の自作の方は、信号線 1 本につき MOS-FET を 2 つ使うだけの簡単な方法ですが、ちょっと回路の知識がないと厳しいかもしれません。 MOS-FET の端子の順番を間違えたりすると動かないばかりか、つないだ機器を壊す恐れがあります。

しかし、ちゃんと組めれば 1 個数円の MOS-FET 2N7002K 2 個で作れますから、コストは非常に低くなります。

双方向レベル変換の話はこのくらいにしておきましょう。

5V トレラント

レベル変換とはちょっと違う話ですが、関連する話として「5V トレラント」というものがあります。 これは、本来は 5V より低い電圧で動く IC チップだけど、入力端子に 5V を入力してよいということを意味します。 5V トレラントな装置は、レベル変換をしなくても 5V で動くマイコンから制御することができます。

例えば DRV8830 という、I2C で接続して速度制御と方向制御ができるモータードライバ IC があります。 この IC の動作電圧は 2.75V から 6.8V と広く、乾電池 2 本(3V)で動かせます。

3V で動かしたとき、当然この IC の入力ピンは 0V から 3V で制御することとなります。 Arduino の多くの機種は 5V 駆動、Raspberry Pi は 3.3V ですから、もしこの IC が 5V トレラントでないならレベル変換が必要になります。

幸いなことにこの IC の I2C 端子は 6.8V トレラントになっており、6.8V までは入力を加えても IC が壊れることはありません。 したがって、レベル変換なしでマイコンから直接制御することができます。

このように、高電圧側から低電圧側の装置を制御する場合、低電圧側がトレラントな設計であれば、レベル変換回路を組む必要がない場合があります。 よくデータシートを読んで、端子がトレラントかどうかをチェックする癖をつけるといいかもしれませんね。