Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

電子工作の基礎知識

CHIRIMEN でセンサーやアクチュエーターを扱う前に知っておきたい、電子工作の基礎知識をまとめた資料です。

このセクションの多くのページは、SparkFun Learn の チュートリアルを日本語に翻訳したものです。SparkFun Learn のチュートリアルは CC BY-SA 4.0 ライセンスで公開されており、 各ページの末尾に元記事へのリンクとライセンス表示を掲載しています。

目次

電気とは何か

電気は身の回りのいたるところにある。 スマートフォン、パソコン、照明、はんだごて、エアコンといった技術を動かしているのも電気であり、現代の生活の中でそこから逃れるのは難しい。 電気から離れようとしても、雷雨の稲妻から私たちの体の中のシナプスまで、自然の中でも電気は絶えず働いている。 では、電気とは正確には何なのか。 これは非常に難しい問いであり、掘り下げて問い続けても、確定的な答えはなく、電気が周囲とどう相互作用するかを表す抽象的なモデルがあるだけである。

電気は自然界のいたるところで起きる現象であり、さまざまな姿をとる。 このチュートリアルでは、電子機器を動かしている電気、つまり電流としての電気に焦点を当てる。 目標は、電源から配線を通って電気がどのように流れ、LEDを光らせ、モーターを回し、通信機器を動かしているのかを理解することである。

電気は簡潔には電荷の流れと定義されるが、この一言の背後には多くのことが隠れている。 電荷はどこから来るのか。 どうやってそれを動かすのか。 どこへ動いていくのか。 電荷の移動が、どうして機械的な動きや発光を引き起こすのか。 疑問は尽きない。 電気とは何かを説明するには、物質や分子よりもさらに奥、私たちが日常で関わるあらゆるものを構成する原子のレベルまでズームインする必要がある。

このチュートリアルは、エネルギー原子といった、物理学の基礎的な理解を土台にしている。 それぞれの概念は簡単にしか触れないので、必要に応じて他の資料もあわせて参照してほしい。

原子の世界へ

電気の基礎を理解するには、まず生命と物質を構成する基本要素の1つである原子に注目する必要がある。 原子には水素、炭素、酸素、銅といった化学元素として100種類以上の形があり、多くの種類の原子が組み合わさることで分子ができ、それが私たちの目に見え、手で触れられる物質を作り上げている。

原子は非常に小さく、大きくてもせいぜい300ピコメートル程度である(3×10⁻¹⁰メートル、つまり0.0000000003メートル)。 仮に1円玉ならぬ純銅製の硬貨があったとすると、その中には3.2×10²²個(32,000,000,000,000,000,000,000個)もの銅原子が含まれることになる。

電気のしくみを説明するには、原子ですら十分に小さいとは言えない。 さらにもう1段階掘り下げて、原子を構成する要素である陽子、中性子、電子を見ていく必要がある。

原子を構成する要素

原子は、電子、陽子、中性子という3種類の異なる粒子の組み合わせでできている。 どの原子にも中心に原子核があり、そこに陽子と中性子が密集している。 その原子核の周りを、複数の電子が軌道を描いて回っている。

すべての原子には、少なくとも1個の陽子が含まれている。 原子に含まれる陽子の数は重要な意味を持ち、その原子がどの化学元素にあたるかを決める。 たとえば陽子が1個の原子は水素、29個の原子は銅、94個の原子はプルトニウムである。 この陽子の数のことを、その原子の原子番号と呼ぶ。

陽子の相棒である中性子にも重要な役割があり、陽子を原子核の中にとどめておくとともに、その原子の同位体を決めている。 ただし電気のしくみを理解するうえでは重要ではないので、このチュートリアルでは深入りしない。

電気のしくみにとって決定的に重要なのは電子である(名前からしてそれらしい響きがあるのに気づいただろうか)。 もっとも安定した、釣り合いの取れた状態では、原子の電子の数は陽子の数と等しくなる。 下のボーアの原子模型のように、29個の陽子を持つ原子核(つまり銅原子)の周りには、同じ29個の電子が取り巻いている。

原子の中の電子は、すべてが永久に原子に縛りつけられているわけではない。 原子の一番外側の軌道にある電子は価電子と呼ばれる。 十分な外力が加われば、価電子は原子の軌道から離れて自由な状態になれる。 この自由電子こそが、電荷を動かすことを可能にし、電気そのものを成り立たせている。 ここで、電荷についてもう少し詳しく見ていこう。

電荷の流れ

このチュートリアルの冒頭で述べたとおり、電気は電荷の流れとして定義される。 電荷は、質量や体積、密度と同じように物質が持つ1つの性質であり、測定できる量である。 質量の大きさを数値で表せるのと同じように、電荷の大きさも数値で表せる。 電荷について押さえておくべき重要な点は、(+)と(-)という2つの種類があることである。

電荷を動かすには電荷キャリアが必要であり、ここで原子を構成する粒子、特に電子と陽子についての知識が役に立つ。 電子は常に負の電荷を持ち、陽子は常に正の電荷を持つ。 中性子はその名のとおり中性であり、電荷を持たない。 電子と陽子は、電荷の種類こそ違うが、電荷のそのものは同じである。

電子と陽子が電荷を持つことが重要なのは、それによって力を及ぼし合えるようになるからである。 その力こそが静電気力である。

静電気力

静電気力クーロンの法則とも呼ばれる)は、電荷どうしのあいだに働く力である。 同じ種類の電荷どうしは反発し合い、異なる種類の電荷どうしは引き合う。 異なる符号は引き合い、同じ符号は反発するというわけである。

2つの電荷に働く力の大きさは、両者の距離によって決まる。 2つの電荷が近づくほど、その力(引き合う力にせよ反発する力にせよ)は大きくなる。

この静電気力のおかげで、電子は他の電子を押しのけ、陽子には引き寄せられる。 この力は原子を1つにまとめておく「のり」の一部であると同時に、電子(そして電荷)を流すために必要な道具でもある。

電荷を流す

これで、電荷を流すために必要な道具がすべてそろった。 原子の中の電子は、常に負の電荷を持っているため、電荷キャリアとして働ける。 原子から電子を1個引き離し、動かすことができれば、電気を作り出せる。

電荷を流すための元素としてよく使われる銅の原子モデルを考えてみよう。 釣り合いの取れた状態の銅原子は、原子核に29個の陽子を持ち、その周りを同じ29個の電子が回っている。 電子は原子核からの距離がそれぞれ異なる軌道を回っている。 原子核に近い電子ほど中心への引力が強く働き、遠い軌道にある電子ほどその引力は弱い。 原子の一番外側にある電子は価電子と呼ばれ、原子から自由にするのに必要な力がもっとも小さい。

価電子に対して、別の負の電荷で押しやるか、正の電荷で引き寄せるかして十分な静電気力を加えれば、その電子を原子の軌道から弾き出し、自由電子にできる。

次に、無数の銅原子で満たされた銅線を考えてみよう。 自由電子が原子と原子のあいだの空間を漂っていると、その空間にある周囲の電荷から押されたりつつかれたりする。 そうした混沌の中で、自由電子はやがて新しい原子に取りつく先を見つける。 そのとき、飛び込んできた電子の負電荷が、その原子の別の価電子を弾き飛ばす。 すると、今度はその新しい電子が自由な空間を漂い、同じことを繰り返そうとする。 この連鎖反応が次々と続くことで、電流と呼ばれる電子の流れが生まれる。

導電性

元素の種類によって、電子を放出しやすいものとそうでないものがある。 できるだけ多くの電子を流したいなら、価電子をあまり強く抱え込まない原子を使うのがよい。 ある元素の導電性は、電子が原子にどれだけ強く束縛されているかを表す指標である。

導電性が高く、電子が動きやすい元素は導体と呼ばれる。 これは、電線や、電子の流れを助ける他の部品を作るときに使いたい種類の材料である。 銅、銀、金といった金属は、たいてい優れた導体として選ばれる代表格である。

導電性が低い元素は絶縁体と呼ばれる。 絶縁体には、電子の流れを妨げるという重要な役割がある。 ガラス、ゴム、プラスチック、空気などが代表的な絶縁体である。

静電気と電流

先に進む前に、電気が取りうる2つの形、静電気と電流について整理しておく。 電子工作で扱うことが多いのは電流のほうだが、静電気についても理解しておく価値がある。

静電気

静電気は、絶縁体によって隔てられた物体の上に、正負それぞれの電荷が偏って蓄積している状態を指す。 静電気(「静止した」電気)は、2つの電荷のかたまりが互いにつながる道筋を見つけ、電荷の偏りが解消されるまで、そのまま存在し続ける。

電荷が均衡を取り戻す道筋を見つけると、静電気放電が起きる。 このとき電荷どうしの引き合う力は非常に強くなり、空気やガラス、プラスチック、ゴムといった優れた絶縁体の中でさえ電荷が流れてしまう。 静電気放電は、電荷がどんな媒質を通り、どんな表面へ移動するかによっては人体に害を及ぼすこともある。 空気の隙間を通って電荷が均衡を取り戻すとき、移動する電子が空気中の電子と衝突して励起し、光としてエネルギーを放出することで、目に見える火花になることがある。

大きな静電気放電の中でも特に劇的な例がである。 雲の集まりが、別の雲の集団や地面に対して十分な電荷を蓄えると、その電荷は均衡を取り戻そうとする。 雲が放電すると、大量の正(あるいは負)の電荷が地面から雲へ、あるいはその逆へと空気中を駆け抜け、あの見慣れた現象を引き起こす。

風船を頭にこすりつけて髪の毛を逆立てたり、床の上をすり足で歩いてフワフワのスリッパで(もちろんうっかりと)家の猫にショックを与えてしまったりするときにも、身近な静電気を体験できる。 どちらの場合も、異なる種類の材料をこすり合わせる摩擦によって電子が移動している。 電子を失った側の物体は正に帯電し、電子を受け取った側の物体は負に帯電する。 この2つの物体は、電荷の均衡を取り戻す方法を見つけるまで、互いに引き合い続ける。

電子工作を扱ううえでは、静電気そのものを気にする場面はあまり多くない。 気にするとすれば、たいていは静電気放電から繊細な電子部品を守ろうとする場面である。 静電気対策としては、ESD(静電気放電)対応のリストストラップを身につけたり、非常に高い電荷のスパイクから回路を守る専用の部品を組み込んだりする方法がある。

電流

電流は、私たちの電子機器のすべてを動かしている電気の形である。 この形の電気は、電荷が絶えず流れ続けられるときに存在する。 電荷が集まってじっとしている静電気とは対照的に、電流は動的であり、電荷は常に動き続けている。 このチュートリアルの残りの部分では、この形の電気に焦点を当てていく。

回路

電流が流れるには、回路、つまり導電性の材料でできた、途切れることのない閉じたループが必要である。 回路は、端から端までつながった1本の導線だけの単純なものでもよいが、実用的な回路には通常、電線と、電気の流れを制御する他の部品が組み合わされている。 回路を作るうえで守るべきただ1つのルールは、絶縁体による隙間を作らないことである。

銅原子で満たされた電線があり、そこに電子の流れを起こしたいとする。 そのためには、すべての自由電子が、おおむね同じ方向へ流れていける行き先を持っている必要がある。 銅は優れた導体であり、電荷を流すのにうってつけである。 銅線でできた回路のどこかが切れていると、電荷は空気中を流れられず、切れた場所より内側にある電荷もどこへも行けなくなる。

逆に、電線が端から端までつながっていれば、すべての電子は隣り合う原子を持つことになり、みなおおむね同じ方向へ流れていける。

ここまでで、電子がどうやって流れるのかは理解できた。 しかし、そもそも電子を流れさせるきっかけは何なのか。 そして、いったん電子が流れ始めたら、電球を光らせたりモーターを回したりするのに必要なエネルギーはどうやって生み出されるのか。 それを理解するには、電場について知る必要がある。

電場

物質の中を電子がどう流れて電気になるのかは、これでひととおり理解できた。 電気について知るべきことは、ほぼこれですべて、と言いたいところだが、もう少しだけ続きがある。 ここからは、電子の流れを引き起こす源が必要になる。 たいていの場合、その源になるのが電場である。

「場」とは何か

とは、目に見える接触を伴わない物理的な相互作用をモデル化するための道具である。 場は物理的な姿を持たないため目には見えないが、その効果は紛れもなく現実のものである。

私たちが無意識のうちによく知っている場の1つが、地球の重力場、つまり巨大な物体が他の物体を引き寄せる効果である。 地球の重力場は、地球の中心を向く一群のベクトルとしてモデル化でき、地表のどこにいても、その力によって中心へ向けて押されているのを感じる。

地球のどこにいても、地表面という条件下では重力場の強さはほぼ均一に感じられるが、実際には場の強さはあらゆる場所で一様ではない。 場の発生源から離れるほど、その効果は弱くなる。 地球の重力場の大きさも、地球の中心から離れるほど小さくなる。

これから電場について見ていくが、地球の重力場のしくみを思い出しておくとよい。 両者にはよく似た点が多い。 重力場は質量を持つ物体に力を及ぼし、電場は電荷を持つ物体に力を及ぼす。

電場

電場は、電気がどのように生まれ、流れ続けるのかを理解するための重要な道具である。 電場は、電荷どうしのあいだの空間に働く、引く力や押す力を表す。 地球の重力場と比べたとき、電場には大きな違いが1つある。 地球の重力場は(他のあらゆるものが地球に比べてあまりに軽いため)基本的に他の物体を引き寄せるだけだが、電場は電荷を引き寄せるのと同じくらいの頻度で押しのけもする。

電場の向きは、その場の中に正の試験電荷を置いたときにその電荷が動く方向として定義される。 試験電荷は無限に小さいものとし、電荷自体が場に影響を与えないようにする。

まずは、正と負、それぞれ単独の電荷が作る電場を考えてみよう。 正の試験電荷を負の電荷の近くに置くと、その試験電荷はの電荷に引き寄せられる。 そのため、単独の負電荷については、あらゆる方向から中心に向かって内向きの矢印で電場を描く。 同じ試験電荷を別のの電荷の近くに置くと、今度は反発して外向きに動くため、正電荷からは外向きに矢印を描く。

複数の電荷を組み合わせると、より複雑な電場を作れる。

上の一様な電場は、正の電荷から離れ、負の電荷に向かう向きを指している。 ここに小さな正の試験電荷を落としたと想像すると、矢印の向きに沿って動くはずである。 すでに見たとおり、電気とはたいてい電子、つまり負の電荷の流れであり、電子は電場と逆向きに流れる。

電場は、電流を流すのに必要な押す力を与えてくれる。 回路の中の電場は、いわば電子ポンプのようなものであり、負の電荷を大量に蓄えた源が電子を押し出し、その電子は回路の中を、正の電荷が集まった側へ向かって流れていく。

電位(エネルギー)

電気を利用して回路や機器を動かすとき、私たちが実際にしているのはエネルギーの変換である。 電子回路は、エネルギーを蓄え、それを熱や光、運動といった別の形へと変換できなければならない。 回路に蓄えられたこのエネルギーを電気的な位置エネルギーと呼ぶ。

エネルギーと位置エネルギー

位置エネルギーを理解するには、まずエネルギーそのものを理解しておく必要がある。 エネルギーとは、ある物体が別の物体に対して仕事をする能力、すなわちその物体をある距離だけ動かす能力として定義される。 エネルギーにはさまざまな形があり、力学的エネルギーのように目に見えるものもあれば、化学エネルギーや電気エネルギーのように目に見えないものもある。 どんな形であれ、エネルギーは運動エネルギー位置エネルギーという2つの状態のどちらかをとる。

物体が動いているとき、その物体は運動エネルギーを持つという。 運動エネルギーの大きさは、物体の質量と速さによって決まる。 一方、位置エネルギーは、物体が静止しているときに持つ蓄えられたエネルギーであり、その物体を動かしたときにどれだけの仕事ができるかを表す。 位置エネルギーは、一般には私たちが制御できるエネルギーである。 物体が動き出すと、その位置エネルギーは運動エネルギーへと変換される。

再び重力を例にとってみよう。 ブルジュ・ハリファの最上階でじっと静止しているボウリングの球には、大きな位置エネルギー(蓄えられたエネルギー)がある。 球を落とすと、重力場に引かれて地面に向かって加速していく。 球が加速するにつれて、位置エネルギーは運動エネルギー(運動によるエネルギー)へと変換されていく。 やがて球の持つエネルギーはすべて運動エネルギーに変換され、それが衝突した相手へと受け渡される。 球が地面に達したとき、その位置エネルギーは非常に小さくなっている。

電気的な位置エネルギー

重力場の中の質量が重力による位置エネルギーを持つのとちょうど同じように、電場の中の電荷は電気的な位置エネルギーを持つ。 ある電荷の電気的な位置エネルギーは、その電荷が静電気力によって動き出したときにどれだけのエネルギーを運動エネルギーに変換でき、どれだけの仕事ができるかを表す。

塔の上に置かれたボウリングの球と同じように、別の正電荷のすぐ近くにある正電荷は高い位置エネルギーを持つ。 自由に動けるようにすると、この電荷は同符号の電荷から反発されて離れていく。 逆に、負電荷の近くに置かれた正の試験電荷は低い位置エネルギーを持ち、これは地面に置かれたボウリングの球に相当する。

何かに位置エネルギーを与えるには、それをある距離だけ動かすという仕事をする必要がある。 ボウリングの球の場合、その仕事とは、重力に逆らって163階分の高さまで運び上げることである。 同様に、正電荷を電場の矢印に逆らって動かす(別の正電荷に近づける、あるいは負電荷から遠ざける)にも仕事が必要になる。 場の上流へ進むほど、必要な仕事は大きくなる。 同じように、負電荷を正電荷から電場に逆らって引き離そうとするときにも仕事が必要になる。

電場の中にある電荷の電気的な位置エネルギーは、その電荷の種類(正か負か)、電荷の量、そして場の中でのその位置によって決まる。 電気的な位置エネルギーは、ジュール(J)という単位で測られる。

電位

電位は、電気的な位置エネルギーという考え方をさらに一歩進め、電場にどれだけのエネルギーが蓄えられているかを表す概念である。 これも、電場のふるまいをモデル化するのに役立つ考え方の1つである。 電位は、電気的な位置エネルギーとは別のものなので注意してほしい。

電場中のある地点における電位は、その地点における電気的な位置エネルギーを電荷量で割った値として定義される。 こうして電荷の量という要素を式から取り除くことで、電場のその場所がどれだけの位置エネルギーを与えうるかという情報だけが残る。 電位の単位はジュール毎クーロン(J/C)であり、これをボルト(V)と定義する。

どんな電場にも、私たちにとって特に重要な2つの地点がある。 1つは電位が高い地点で、正電荷が持ちうる位置エネルギーが最大になる場所であり、もう1つは電位が低い地点で、電荷が持ちうる位置エネルギーが最小になる場所である。

電気を論じるときにもっともよく登場する言葉の1つが電圧である。 電圧とは、電場の中の2点間における電位の差のことである。 電圧を見れば、その電場がどれだけの押す力を持っているかがわかる。

ここまでで、電位と位置エネルギーという材料がそろい、電流を作り出すために必要なものはすべて手に入った。 実際に電流を作ってみよう。

電気を実際に動かしてみる

素粒子物理学、場の理論、位置エネルギーを学んできたことで、電気を流すのに十分な知識が身についた。 実際に回路を組んでみよう。

まず、電気を作るために必要な材料を振り返っておく。

  • 電気の定義は電荷の流れである。通常、この電荷を運ぶのは自由に流れる電子である。
  • 負の電荷を持つ電子は、導電性材料の原子にゆるく結びついている。少し力を加えるだけで、電子を原子から解放し、おおむね一定の方向へ流すことができる。
  • 導電性材料でできた閉じた回路が、電子が途切れず流れ続けるための道筋を提供する。
  • 電圧の源が必要である。

ショート回路

電池は、化学エネルギーを電気エネルギーに変換する身近なエネルギー源である。 電池には2つの端子があり、それぞれが回路の残りの部分に接続される。 一方の端子には負の電荷が過剰にあり、正の電荷はもう一方に集まっている。 これはまさに、今にも働き出そうとしている電位差そのものである。

導電性の銅原子で満たされた電線をこの電池につなぐと、その電場が銅原子の中の負に帯電した自由電子に影響を及ぼす。 負極端子に押され、正極端子に引かれることで、銅の中の電子は原子から原子へと移動し、私たちが電気として知っている電荷の流れを作り出す。

電流が流れ始めて1秒経っても、電子自体が実際に移動した距離はごくわずか、せいぜい1センチメートルの何分の1かにすぎない。 それにもかかわらず、電流によって生み出されるエネルギーは膨大であり、特にこの回路には流れを遅くしたりエネルギーを消費したりするものが何もない場合はなおさらである。 純粋な導体だけをエネルギー源に直接つなぐのはよくない考えである。 エネルギーは系の中を非常に速く移動し、電線の中で熱に変換され、電線の融解や発火につながりかねない。

電球を光らせる

そのエネルギーを無駄にし、電池と電線を壊してしまうのではなく、何か役に立つことをする回路を組んでみよう。 一般に、電気回路は電気エネルギーを光や熱、運動といった別の形のエネルギーに変換する。 電池と電球を電線でつなげば、それだけで単純ながら機能する回路になる。

電子自体はかたつむりのようにゆっくりとしか動かないが、電場は回路全体にほぼ瞬時に(実際には光速に近い速さで)影響を及ぼす。 回路のどこにいる電子であっても、電位が低い場所にいても高い場所にいても、あるいは電球のすぐそばにいても、等しく電場の影響を受ける。 スイッチが閉じて電子が電場にさらされると、回路中のすべての電子がほぼ同時に流れ始めたように見える。 電球にもっとも近い電荷は、回路の中を一歩進んだところで、すぐに電気エネルギーを光(や熱)へと変換し始める。

まとめ

このチュートリアルで扱えたのは、電気という大きな全体のほんの入り口にすぎない。 まだ扱っていない概念は数多く残っている。 ここから先は、電圧、電流、抵抗とオームの法則のチュートリアルに進むとよい。 電場(電圧)と電子の流れ(電流)について理解した今なら、その2つの相互作用を支配する法則の理解へ、大きく近づいているはずである。

電気の基礎に関する、他の入門レベルのチュートリアルも紹介しておく。

もう少し実践的な内容を学びたいなら、次のような基礎スキル系のチュートリアルもおすすめである。

タグ: 概念、電気工学、物理学


出典:What is Electricity?(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

電圧、電流、抵抗とオームの法則

電気や電子工作の世界に足を踏み入れるとき、最初に理解しておくべきなのが電圧電流抵抗の3つである。 これらは電気を扱ううえでの基本的な構成要素であり、この3つを理解しなければ、回路を設計することも読み解くこともできない。

電圧、電流、抵抗は、最初はわかりにくく感じられるかもしれない。 理由は単純で、これらを肉眼で「見る」ことができないからである。 電線の中を流れているエネルギーも、テーブルの上に置かれた電池の電圧も、目には見えない。 空に走る雷は目に見えるが、それも雲から地面へのエネルギーの移動そのものではなく、その通り道の空気が起こす反応にすぎない。 このエネルギーの移動を捉えるには、テスター(マルチメーター)やスペクトラムアナライザー、オシロスコープといった計測器を使い、回路の中の電荷の動きを可視化する必要がある。 このチュートリアルでは、そうした計測器がなくても理解できる範囲で、電圧、電流、抵抗の基本と、3つの関係を説明する。

このチュートリアルで扱う内容:

  • 電荷と、電圧、電流、抵抗の関係
  • 電圧、電流、抵抗とは何か
  • オームの法則とは何か、電気を理解するためにどう使うか
  • これらの概念を確かめる簡単な実験

電荷

電気とは、電子の動きである。 電子が動くことで電荷が生まれ、その電荷を利用することで仕事をさせられる。 電球もステレオもスマートフォンも、電子の動きを利用して仕事をしているという点ではすべて同じであり、動作原理の根本は共通している。

このチュートリアルの3つの基本量は、電子の動き、より正確には電子が生み出す電荷を使って次のように説明できる。

  • 電圧は、2点間の電荷の差である。
  • 電流は、電荷が流れる速さである。
  • 電流を妨げようとする材料の性質である。

つまり、電圧、電流、抵抗について語るとき、実際に語っているのは電荷の動き、すなわち電子のふるまいである。 回路とは、電荷がある場所から別の場所へ移動できるようにする閉じたループのことであり、回路上の部品を使うことで、この電荷の動きを制御し、仕事に利用できる。

電気を研究したバイエルンの科学者ゲオルク・オームは、電流と電圧によって定義される抵抗の単位を示した人物である。 まずは電圧から見ていこう。

電圧

2点間に蓄えられた位置エネルギーの量を電圧と呼ぶ。 一方の点がもう一方より多くの電荷を持っているとき、その2点間の電荷の差を電圧と呼ぶ。 単位はボルトであり、技術的には、1クーロンの電荷が通過する際に1ジュールのエネルギーを与える2点間の電位差として定義される(ここで意味がわからなくても心配はいらない、後で説明する)。 「ボルト」という単位名は、最初の化学電池を発明したとされるイタリアの物理学者アレッサンドロ・ボルタにちなむ。 電圧は数式や回路図の中で記号「V」で表される。

電圧、電流、抵抗を説明するとき、よく使われるたとえが水タンクである。 このたとえでは、電荷は水の、電圧は水の圧力、電流は水の流量に対応する。

  • 水 = 電荷
  • 圧力 = 電圧
  • 流れ = 電流

地面から一定の高さにある水タンクを考える。 タンクの底にはホースが取り付けられている。

ホースの先端にかかる圧力が電圧に相当し、タンクの中の水が電荷に相当する。 タンクの水が多いほど電荷は大きく、ホースの先端で測られる圧力も高くなる。

このタンクは、一定量のエネルギーを蓄えて後から放出する電池と考えられる。 タンクの水を減らすと、ホース先端の圧力は下がる。 これは、懐中電灯の電池が減るにつれて明かりが暗くなるときのように、電圧が下がることに対応する。 同時に、ホースを流れる水の量も減る。 圧力が下がれば流れる水も減る、これが電流の話につながる。

電流

タンクからホースを通って流れる水の量が電流に相当する。 圧力が高いほど流量は多くなり、その逆も同様である。 水の場合は一定時間あたりに流れる水の体積を測るが、電気の場合は一定時間あたりに回路を流れる電荷の量を測る。 電流の単位はアンペア(通常は単に「アンプ」と呼ばれる)であり、1アンペアは回路上のある点を1秒間に6.241×10^18個の電子(1クーロン)が通過することと定義される。 数式の中でアンペアは記号「I」で表される。

同じ量の水が入った2つのタンクを考える。 それぞれの底からホースが伸びているが、一方のホースはもう一方より細い。

どちらのホースの先端でも圧力は同じだが、水が流れ始めると、細いホースのほうが太いホースより流量は少なくなる。 電気の言葉に置き換えると、細いホースを通る電流は太いホースを通る電流より小さいということになる。 もし両方のホースで流量を同じにしたいなら、細いホースのタンクの水(電荷)の量を増やす必要がある。

水を増やすと、細いホースの先端にかかる圧力(電圧)が上がり、より多くの水が押し出される。 これは、電圧を上げることで電流が増えることに対応する。

ここまでで、電圧と電流の関係が見えてきた。 しかし、もう1つ考慮すべき要素がある。 それがホースの太さであり、このたとえの中でホースの太さに相当するのが抵抗である。 モデルに、もう1つの項を加える必要がある。

  • 単位:クーロン
  • 単位:ボルト
  • 単位:アンペア
  • ホースの太さ = 抵抗

抵抗

再び、細いパイプと太いパイプを持つ2つの水タンクを考える。

同じ圧力であれば、細いパイプには太いパイプほどの水量を通せないのは道理である。 これが抵抗であり、細いパイプは、太いパイプのタンクと同じ圧力の水であっても、その流れを「妨げる」。

電気の言葉で言えば、これは電圧が等しく抵抗が異なる2つの回路に対応する。 抵抗が大きい回路ほど流せる電荷は少なくなり、つまり抵抗が大きい回路ほど流れる電流は小さくなる。

ここでゲオルク・オームの話に戻る。 オームは「1オーム」という抵抗の単位を、導体上の2点間で1ボルトの電圧が1アンペア(6.241×10^18個の電子)を押し流すときの抵抗として定義した。 この値は回路図の中でギリシャ文字「Ω」(オメガ、読みは「オーム」)で表されるのが一般的である。

オームの法則

電圧、電流、抵抗を組み合わせて、オームは次の式を導いた。

\[ V = I \times R \]

  • ボルト
  • アンペア
  • オーム

これがオームの法則である。 たとえば、電位1ボルト、電流1アンペア、抵抗1オームの回路があるとする。 オームの法則により、この関係は成り立つ。

太いホースのタンクで考えると、タンクの水量が1ボルト、ホースの「細さ」(流れへの抵抗)が1オームに相当し、オームの法則から流量(電流)は1アンペアとなる。

同じたとえで、今度は細いホースのタンクを見てみる。 ホースが細い分、流れへの抵抗は大きく、これを2オームとする。 タンクの水量はもう一方と同じなので、オームの法則から、細いホースのタンクの式は次のようになる。

電流はどうなるか。 抵抗が大きく電圧が同じであることから、電流の値は0.5アンペアになる。

抵抗が大きいタンクのほうが電流は小さい。 オームの法則の3つの値のうち2つがわかれば、残る1つを求められることがここからわかる。 これを実験で確かめてみよう。

オームの法則の実験

この実験では、9ボルトの電池でLEDを点灯させる。 LEDは繊細な部品であり、流せる電流には上限がある。 それを超えると壊れてしまう。 LEDのデータシートには必ず「定格電流」が記載されており、これがそのLEDに流せる電流の上限を示す値である。

必要な部品

このチュートリアル末尾の実験を行うには、次のものが必要である。

  • マルチメーター
  • 9ボルト電池
  • 入手できなければ、それに近い値のもの
  • LED

Note

LEDは「非オーム性」の部品として知られている。 つまり、LED自体を流れる電流の式は V = I × R ほど単純ではない。 LEDは回路に「順方向電圧降下」と呼ばれる電圧降下をもたらし、それによって流れる電流の量が変化する。 ただし、この実験の目的はLEDを過電流から守ることであり、LED自体の電流特性は無視して、オームの法則だけを使い、LEDを流れる電流が20mAを安全に下回るように抵抗値を選ぶ。

ここでは、9ボルトの電池と、定格電流20ミリアンペア(0.020アンペア)の赤色LEDを使う。 安全のため、定格の上限ではなく、データシートに記載された推奨電流である18ミリアンペア(0.018アンペア)で駆動することにする。 LEDを電池に直接つなぐと、オームの法則の値は次のようになる。

抵抗がまだない状態でこれを計算すると、ゼロで割ることになり、電流は無限大という結果になる。 実際には無限大にはならないが、電池が供給できる限りの電流が流れてしまう。 これほどの電流をLEDに流したくはないので、抵抗が必要になる。 回路は次のようになる。

同じくオームの法則を使えば、望みの電流値を得るための抵抗値を求められる。 必要な値を代入し、抵抗について解くと、LEDの電流を定格以下に保つには、およそ500オームの抵抗が必要だとわかる。

500オームは市販の抵抗ではあまり一般的な値ではないため、この作例では代わりに560オームの抵抗を使っている。

抵抗の値を、LEDの定格電流を下回りつつ、LEDを十分明るく点灯させられる値に選べたことになる。 LEDと電流制限抵抗の組み合わせは、電子工作の趣味の世界でよく登場する。 オームの法則を使って回路を流れる電流量を調整する場面は、この先何度も出てくるだろう。 LilyPad LEDボードも、この考え方を実装した例の1つである。 この基板ではLEDと同じ基板上にあらかじめ抵抗が実装されており、電流制限のために抵抗を別途配線する必要がない。

電流制限抵抗はLEDの前段と後段のどちらに置くべきか

話をもう一歩進めると、電流制限抵抗はLEDのどちら側に置いても同じように機能する。

電子工作を学び始めたばかりの人の多くが、電流制限抵抗をLEDのどちら側に置いても回路が変わらず動作するという事実に戸惑う。

輪になって循環し続ける川を想像してほしい。 そこにダムを1つ設ければ、川全体の流れが止まる。 一部だけが止まるわけではない。 今度は、その川に水車を1つ置いて流れを緩めるとする。 水車を輪のどこに置いても、川全体の流れが同じように緩やかになる。

これは単純化した説明であり、実際には電流制限抵抗を回路のどこにでも置けるわけではない。 置けるのはLEDのどちらか一方の側であり、その範囲でなら機能するということである。

より厳密な説明としては、キルヒホッフの電圧則が関係する。 電流制限抵抗をLEDのどちら側に置いても同じ効果が得られるのは、この法則があるからである。

まとめ

ここまでで、電圧、電流、抵抗の概念と、3つがどう関係し合っているかを理解できたはずである。 回路解析に使われる式や法則の大半は、オームの法則から直接導き出せる。 この単純な法則を理解することが、あらゆる電気回路の解析の土台になる。

電圧、電流、抵抗の先にある、より発展的な内容を学びたい場合は、次のチュートリアルも参照してほしい。

タグ: 概念、電気工学、LED、プロジェクトを始める


出典:Voltage, Current, Resistance, and Ohm’s Law(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

回路とは何か

電子工作の世界に足を踏み入れて最初に出会う概念の1つが回路である。 このチュートリアルでは、回路とは何かを説明し、あわせて電圧についてもう少し詳しく見ていく。

参考になるチュートリアル:

回路の基礎

電圧とその働き

電池や壁のコンセントには、決まった数のボルトがあると聞いたことがあるだろう。 これは、電池や、コンセントにつながる送電網が生み出す電気的なポテンシャル(電位)を表す量である。

そのボルトはすべて、使われるのを待って「そこにある」状態だが、1つ落とし穴がある。 電気が何か仕事をするには、その電気が動ける状態になっている必要があるのだ。 膨らませた風船のようなものだと考えるとよい。 口をつまんでいるあいだは、中の空気は何かをすることができる状態にあるだけで、実際に外へ出してやるまでは何もしない。

風船から出る空気とは違い、電気は銅線のような、電気を通せる材料の中しか流れられない。 電池や壁のコンセントに電線をつなぐと(警告:壁のコンセントの電圧は危険なので、実際に試してはいけない)、電気が流れる道筋を与えたことになる。 ただし、その電線がどこにもつながっていなければ、電気には行き先がなく、やはり動かない。

では、何が電気を動かすのか。 電気は、電圧の高いところから低いところへ流れようとする。 これは風船とまったく同じで、風船の中の圧縮された空気は、風船の内側(圧力が高い)から外側(圧力が低い)へ流れようとする。 電圧の高いところと低いところのあいだに電気を通す道筋を作れば、電気はその道筋に沿って流れる。 そして、その道筋の途中にLEDのような何か役に立つものを入れておけば、流れる電気がそのために仕事をしてくれる。 LEDが点灯するというわけだ。

では、電圧の高いところと低いところはどこにあるのか。 ここで知っておくと役立つのが、あらゆる電源には2つの側があるという点である。 電池の両端にある金属のキャップや、壁のコンセントにある2つ(かそれ以上)の穴が、これにあたる。 電池のような直流(DC)の電源では、この2つの側はしばしば端子と呼ばれ、それぞれ正極(「+」)、負極(「-」)と名付けられている。

なぜあらゆる電源に2つの側があるのか。 これは「電位」という考え方に戻る話であり、電気を流すには電圧の差が必要だからである。 奇妙に聞こえるかもしれないが、比べる対象が2つなければ「差」というもの自体が存在しない。 どんな電源でも、正極側は負極側より電圧が高く、これがまさに私たちの求めている状態である。 実際、電圧を測るときは、負極側を0ボルトとし、正極側をその電源が供給できる電圧として表すのが通例である。

電源はポンプのようなものだと考えられる。 ポンプには必ず2つの側があり、何かを送り出す出口と、何かを吸い込む入口がある。 電池も発電機も太陽電池も、同じしくみで動いている。 内部の何かが電気を出口(正極側)へ向けて送り出す仕事をしており、電気が装置から出ていった分だけ空白ができるため、負極側はその空白を埋めるために電気を吸い込む必要がある1

ここまでの内容をまとめる。

  • 電圧は電位にすぎず、電気が何かに役立つには実際に流れる必要がある。
  • 電気が流れるには道筋が必要であり、それは銅線のような電気を通す導体でなければならない。
  • 電気は電圧の高いところから低いところへ流れる。
  • 直流の電源には常に2つの側があり、正極と負極と呼ばれ、正極側のほうが負極側より電圧が高い。

もっとも単純な回路

これで、電気に仕事をさせる準備が整った。 電源の正極側から、発光ダイオード(LED)のような何か仕事をするものを経由して、電源の負極側へ戻るように接続すれば、電気、すなわち電流が流れる。 そして、電流が流れる道筋の途中に、電流が流れることで役立つことをしてくれるもの、たとえば光るLEDを入れておける。

電気を流し、何か役に立つことをさせるために必ず必要となるこの円環状の道筋のことを、回路と呼ぶ。 回路とは、始点と終点が同じ場所にある道筋のことであり、これはまさに今組み立てたものそのものである。

ショート回路と開放回路

「負荷」とは何か

回路を組み立てる理由は、電気に何か役立つことをさせるためである。 そのために私たちは、電流の流れを利用して光ったり、音を鳴らしたり、プログラムを動かしたりするものを回路の中に組み込む。

こうしたものは負荷と呼ばれる。 何かを背負って「重荷を負う(load down)」のと同じように、電源を「負荷で重くする」からである。 人が重すぎる荷物を背負うと大変なのと同じで、電源にも負荷をかけすぎると電流の流れが遅くなってしまう。 しかし人と違って、回路には負荷が軽すぎるという問題もありうる。 軽すぎる負荷は、逆に電流を流しすぎてしまい(荷物を何も背負わずに全力疾走するようなものだと考えるとよい)、部品や電源そのものを焼き切ってしまうことがある。

電圧、電流、負荷については、次のチュートリアルである電圧、電流、抵抗とオームの法則で詳しく学べる。 ここでは、回路の2つの特別なケースであるショート回路(短絡)と開放回路について見ていく。 この2つを知っておくと、自分の回路のトラブルシューティングをするときに大いに役立つ。

ショート回路(短絡)

電源の正極から負極まで、電線だけを直接つなぐとショート回路(短絡)と呼ばれる状態になる。 これは非常によくない状態であり、実際に試してはいけない。

一見すると最高の回路に見えるかもしれないが、なぜこれがよくないのか。 電流は電圧の高いところから低いところへ流れようとし、その途中に負荷を入れておけば、LEDを点灯させるといった役立つことをさせられることを思い出してほしい。

電流の経路にきちんと負荷が入っていれば、回路を流れる電流はその負荷が消費する分に制限され、たいていはごくわずかな量にとどまる。 しかし、電流の流れを制限するものを何も入れていないと、電流を遅くするものが何もなくなり、電流は限りなく大きくなろうとする。

電源が無限に電流を供給できるわけではないが、供給できる限りの、場合によってはかなり大きな電流を流そうとする。 これにより電線が焼け焦げたり、電源が壊れたり、電池が消耗したり、その他さまざまな厄介なことが起きる。 たいていの電源にはショート回路が起きたときに最大電流を制限する安全機構が組み込まれているが、必ずあるとは限らない。 すべての住宅や建物にブレーカーが備わっているのも、配線のどこかでショート回路が起きたときに火災を防ぐためである。

これに近い問題として、回路の一部に誤って過大な電流を流してしまい、部品を焼き切ってしまうケースもある。 これは厳密にはショート回路ではないが、それに近い。 たいていは、抵抗の値を間違えたことで、LEDのような別の部品に過大な電流が流れてしまうことで起きる。

要点はこうだ。 部品が急に熱くなったり、突然焼き切れたりしたときは、すぐに電源を切り、ショート回路が起きていないか確認すること。

開放回路

ショート回路の反対にあたるのが開放回路である。 これは、回路のループがどこかで完全にはつながっていない状態を指し、その意味では回路としてまったく機能していないとも言える。

先ほどのショート回路とは違い、この「回路」で何かが壊れることはないが、回路自体も動作しない。 電子工作を始めたばかりの人にとって、どこで断線しているかを見つけるのは難しいことが多く、特にブレッドボードを使っていると配線がすべて隠れてしまうため、なおさら見つけにくい。

回路が動作しないときは、開放回路が原因であることが多い。 たいていは、接続不良や配線の緩みが原因である(ショート回路も回路全体の電力を奪ってしまうことがあるので、あわせて確認するとよい)。

ヒント: 回路のどこが開放状態になっているかなかなか見つからないときは、テスター(マルチメーター)が非常に役立つ道具になる。 電圧測定モードにしておけば、通電中の回路のさまざまな地点の電圧を確認しながら、電圧が届かなくなっている場所を突き止められる。

まとめ

ここまでで、回路とは何かをもっとも基本的な形で学んだ。 学習を進めていくと、複数のループや、より多くの部品を含む複雑な回路にも出会うことになる。 しかし、どれほど複雑な回路であっても、ここで学んだ単純な1ループの回路と同じ規則に従っている。

電子工作の旅はまだ始まったばかりである。 次に学ぶとよい話題をいくつか挙げる。

  • 配線の基本も身につけておくとよい。
  • マルチメーターを使えば電圧、電流、抵抗を測定でき、うまく動かない回路の原因を探るときに大いに役立つ。
  • 回路にはさまざまな大きさ、形、構成がある。直列回路と並列回路のチュートリアルでは、回路をもう一歩先まで見ていく。

ここからは、回路でよく使われる部品についてのチュートリアルを挙げる。

  • 発光ダイオードのチュートリアルでは、1つまたは複数のLEDを点灯させる方法を紹介している。
  • 抵抗器は、回路でもっとも広く使われる部品の1つである。
  • コンデンサも、ほとんどの回路で使われている。ダイオードも同様である。

タグ: 概念、電気工学


出典:What is a Circuit?(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。


  1. 電気は電源の正極側から負極側へ流れる、と最初に書いたのはベンジャミン・フランクリンである。しかしフランクリンには、実際には電子がその逆方向に流れていることを知るすべがなかった。原子レベルで見ると、電子は負極側から出て正極側へ戻っていく。真実が発見されるまでの何百年ものあいだ、技術者たちはフランクリンの説に従ってきたため、今日でもこの「誤った」慣習がそのまま使われ続けている。実用上はこの違いは問題にならず、誰もが同じ慣習を使ってさえいれば、正しく動作する回路を組み立てられる。

直列回路と並列回路

部品数の少ない単純な回路は、初めて電子工作に触れる人にとっても比較的わかりやすい。 しかし、部品の種類や数が増えてくると、とたんに話がややこしくなる。 電流はどこへ流れているのか。 電圧はどうなっているのか。 もっと単純に考える方法はないのか。 このチュートリアルは、そうした疑問に答えるためのものである。

まず、抵抗と電池という最も基本的な部品を使った回路で、直列回路並列回路の違いを説明する。 そのうえで、コンデンサやインダクタ(コイル)のような別の種類の部品を直列や並列に組み合わせたときに何が起きるかを見ていく。

このチュートリアルで扱う内容:

  • 直列と並列という回路構成がどのようなものか
  • この構成の中で受動部品がどうふるまうか
  • この構成の中で電源が受動部品にどう作用するか

回路を実際に組み立てる前に、次の基礎的なチュートリアルにも目を通しておくとよい。

直列回路

ノードと電流の流れ

本題に入る前に、ノード(節点)について触れておく必要がある。 難しいものではなく、2つ以上の部品がつながる電気的な接続点を指す言葉にすぎない。 回路図の上では、部品と部品のあいだをつなぐ配線がノードにあたる。

これが、直列と並列の違いを理解するための下地の半分にあたる。 残る半分は、回路の中を電流がどう流れるかを理解することである。 電流は、回路の中で電圧の高いところから低いところへ流れる。 電流は、通れる経路があればそのすべてを使って、電圧が最も低い点(多くの場合グラウンドと呼ばれる)へ向かって流れようとする。 先ほどの回路を例にとると、電池のプラス端子からマイナス端子まで、電流は次の図のように流れる。

R1とR2のあいだのように、入ってくる電流と出ていく電流が同じ量になっているノードがある一方で、R2、R3、R4がつながる三又のノードでは、1本だった電流(青色)が2本に分かれている。 この違いこそが、直列と並列を分ける鍵である。

直列回路の定義

2つの部品が同じノードを共有し、なおかつ同じ電流が流れているとき、その2つは直列につながっているという。 抵抗を3つ直列につないだ回路を例に見てみよう。

この回路で電流が流れる経路は1本しかない。 電池のプラス端子を出た電流は、まずR1を通り、続けてR2、R3へと流れ、最後に電池のマイナス端子へ戻る。 電流が通れる経路が1本しかないことに注目してほしい。 このとき、これらの部品は直列につながっているという。

並列回路

並列回路の定義

部品どうしが2つのノードを共有しているとき、その部品は並列につながっているという。 抵抗3本を電池に並列につないだ回路図を見てみよう。

電池のプラス端子から出た電流は、R1にも、R2にも、R3にも流れる。 電池とR1をつなぐノードは、他の抵抗ともつながっている。 それぞれの抵抗のもう一方の端も同様に1つにまとまり、電池のマイナス端子へと戻っていく。 電池に戻るまでに電流が通れる経路は3本あり、このとき対応する抵抗どうしは並列につながっているという。

直列につながれた部品にはすべて同じ電流が流れるのに対し、並列につながれた部品にはすべて同じ電圧がかかる。 「直列と電流」「並列と電圧」が対応すると覚えるとよい。

直列と並列を組み合わせる

ここまでの構成は組み合わせられる。 次の図でも抵抗3本と電池を使っているが、電池のプラス端子を出た電流はまずR1を通る。 R1のもう一方の端でノードが分かれ、電流はR2とR3の両方へ流れられるようになる。 R2とR3を通った電流はその先でまた1つにまとまり、電池のマイナス端子へ戻る。

この例では、R2とR3が互いに並列につながっており、そのR2とR3の並列部分に対してR1が直列につながっている。

直列回路の合成抵抗を計算する

もう少し実用的な話をしよう。 抵抗を直列や並列につなぐと、そこを流れる電流の様子が変わる。 たとえば10Vの電源を10kΩの抵抗につないだ場合、オームの法則から1mAの電流が流れることがわかる。

ここに、もう1本10kΩの抵抗を直列に追加し、電源電圧はそのままにしたとする。 抵抗値が2倍になった分、電流は半分になる。

つまり、電流が通れる経路は相変わらず1本のままで、その経路をより通りにくくしただけということになる。 どれだけ通りにくくなったかというと、10kΩ + 10kΩ = 20kΩである。 抵抗を直列につないだときの合成抵抗は、こうして値をそのまま足し合わせるだけで求められる。

これを一般化すると、任意のN個の抵抗を直列につないだときの合成抵抗は、それぞれの値の総和になる。

\[ R_{合成} = R_1 + R_2 + \cdots + R_N \]

並列回路の合成抵抗を計算する

では並列につないだ抵抗はどうか。 直列よりも少しだけ複雑だが、それほど難しくはない。 先ほどと同じく10Vの電源と10kΩの抵抗から始め、今度はもう1本の10kΩを直列ではなく並列に追加する。 これで電流が通れる経路が2本になる。 電源電圧は変わっていないので、オームの法則により最初の抵抗には相変わらず1mAが流れる。 しかし2本目の抵抗にも同じく1mAが流れるため、電源全体から見ると合計2mAとなり、最初の1mAから倍増する。 電流が倍になったということは、合成抵抗が半分になったことを意味する。

10kΩ‖10kΩ = 5kΩ(「‖」は「並列に」を表す記号)と言えるが、常に同じ値の抵抗が2本とは限らない。 そこで、任意の本数の抵抗を並列につないだときの合成抵抗は、次の式で求められる。

\[ \frac{1}{R_{合成}} = \frac{1}{R_1} + \frac{1}{R_2} + \cdots + \frac{1}{R_N} \]

逆数の計算が面倒なときは、抵抗が2本の場合に限り、「和分の積」と呼ばれる方法も使える。

\[ R_{合成} = \frac{R_1 \times R_2}{R_1 + R_2} \]

ただし、この方法が使えるのは1回の計算につき抵抗2本までである。 3本以上を組み合わせたいときは、まずR1とR2の並列合成値を求め、その結果と3本目の抵抗をあらためて「和分の積」で計算すればよい。 本数が多い場合は、逆数の式のほうが手間が少ないこともある。

実験その1:抵抗を直列につないでみる

用意するもの:

  • 数本
  • マルチメーター
  • ブレッドボード

ここまでの説明どおりに実際に動くことを、簡単な実験で確かめてみよう。

まずは10kΩの抵抗を直列につなぎ、値がそのまま足し合わされる様子を見る。 ブレッドボードを使って図のとおりに抵抗を1本差し、テスターで抵抗値を測る。 10kΩと表示されることはわかりきっているが、これは「機材が壊れていないか」を確かめる意味もある確認作業だと思ってほしい。 世界が特に変わっていないことを確認できたら、同様にもう1本を、それぞれのリードがブレッドボード上で電気的につながる形で追加し、もう一度測ってみる。 今度はテスターがおよそ20kΩに近い値を示すはずである。

測定値が抵抗に表示された値とぴったり一致しないこともある。 抵抗には誤差(許容差)と呼ばれる特性があり、表示値に対して一定の割合だけ前後する可能性がある。 そのため9.99kΩや10.01kΩと表示されることもあるが、正しい値に近ければ特に問題はない。

抵抗がなくなるか、次に何が起きるか完全に予想がつくようになるまで、同じ手順を繰り返してみてほしい。

実験その2:抵抗を並列につないでみる

続いて、並列につないだ場合を試す。 先ほどと同様に10kΩの抵抗を1本差す(単体で10kΩに近い値が出ることはもう納得してもらえたと思う)。 2本目の10kΩ抵抗を、それぞれのリードが電気的に同じ行につながるように注意しながら、1本目の隣に差す。 ただし測定する前に、「和分の積」または逆数の式を使って、新しい抵抗値がいくつになるはずかを計算しておく(ヒント:5kΩになる)。 そのうえで実際に測定する。 5kΩに近い値になっているだろうか。 なっていなければ、抵抗を差した穴が正しいかどうかを確認してほしい。

同じ実験を3本、4本、5本の場合でも繰り返してみよう。 計算値と測定値はそれぞれ3.33kΩ、2.5kΩ、2kΩに近くなるはずである。 思ったとおりの結果になっただろうか。 ならなければ配線を見直し、なったならここまでの内容は理解できている。

抵抗を直列や並列につなぐときの経験則

抵抗の組み合わせに工夫が必要になる場面もある。 たとえば特定の基準電圧を作りたいとき、必要になる抵抗比は「標準的な」値の組み合わせにならないことが多い。 非常に高い精度の抵抗を入手すること自体は可能でも、発注してから届くまでの日数や、特注品の価格を考えると現実的でないこともある。 そんなときは、手持ちの抵抗を組み合わせて必要な値を自分で作り出せる。

コツ1:同じ値の抵抗を並列にする

同じ値Rの抵抗をN本並列につなぐと、合成抵抗はR/Nになる。 たとえば2.5kΩの抵抗が必要なのに、手元に10kΩしかないとする。 10kΩを4本並列につなげば、10kΩ/4 = 2.5kΩが得られる。

コツ2:許容できる誤差を把握する

自分の回路がどこまでの誤差を許容できるかを把握しておく。 たとえば3.2kΩの抵抗が必要なとき、10kΩを3本並列につなぐと3.3kΩになり、必要な値との誤差は約4%になる。 回路の要求精度が4%より厳しい場合は、手持ちの10kΩ抵抗を一本ずつ測定し、その中から値の低いものを選ぶという方法もある(抵抗自体にも個体差があるため)。 理論上、手持ちの10kΩがすべて誤差1%のものであれば、3.3kΩまでしか近づけられない。 ただし、部品メーカーの製造誤差によって実際にはそれより低い値の個体が混じっていることもあるので、一通り測ってみる価値はある。

コツ3:定格電力も直列接続と並列接続で変わる

抵抗を直列や並列につなぐときの考え方は、定格電力についても同じように働く。 たとえば2W定格の100Ωの抵抗が必要なのに、手元に1kΩで定格1/4W(¼W)の抵抗しかないとする。 1kΩを10本並列にすれば100Ω(1kΩ/10 = 100Ω)が得られ、定格電力も10×0.25W = 2.5Wになる。 きれいな解決策とは言えないが、急場をしのぐには十分である。

異なる値の抵抗を並列に組み合わせる場合は、合成抵抗と定格電力の両面で、もう少し注意が必要になる。

コツ4:異なる値の抵抗を並列にする

値の異なる2つの抵抗を並列につないだときの合成抵抗は、必ず小さいほうの抵抗値より小さくなる。 2つの抵抗値のちょうど中間くらいになると考えてしまいがちだが、それは誤りである(1kΩ‖10kΩは5kΩ前後にはならない)。 並列合成抵抗は、常に値の小さいほうの抵抗に引き寄せられる。 このコツ4は、繰り返し頭に入れておく価値がある。

コツ5:並列接続での電力損失

値の異なる抵抗を並列に組み合わせた場合、それぞれに流れる電流が異なるため、消費される電力も均等には分かれない。 先ほどの1kΩ‖10kΩの例で言えば、1kΩのほうには10kΩの10倍の電流が流れる。 オームの法則により電力 = 電圧 × 電流なので、1kΩの抵抗は10kΩの抵抗の10倍の電力を消費することになる。

コツ4とコツ5からわかるのは、値の異なる抵抗を並列に組み合わせるときほど注意深く扱う必要があるということである。 一方、値が同じ場合にはコツ1やコツ3のような単純な近道が使える。

コンデンサの直列接続と並列接続

コンデンサを組み合わせる考え方は、抵抗の場合とちょうど逆になる。 奇妙に聞こえるかもしれないが、これは事実である。

コンデンサは、ごく近い間隔で向かい合った2枚の電極板であり、その基本的な働きは大量の電子を蓄えることにある。 静電容量が大きいほど、蓄えられる電子の量も多くなる。 電極板の面積を大きくすれば、電子が存在できる物理的な空間が増える分、静電容量は大きくなる。 逆に電極板の間隔を広げると、電極間の電界が弱くなる分、静電容量は小さくなる。

ここで、10µFのコンデンサを2つ直列につなぎ、どちらも充電済みだとする。

直列回路では電流の経路が1本しかないことを思い出してほしい。 したがって、下側のコンデンサから放電される電子の数は、上側のコンデンサに入っていく電子の数と同じになるはずである。 つまり、静電容量が増えたわけではない。

実際には、それどころか事情はもっと悪い。 コンデンサを直列につなぐと、2つのコンデンサそれぞれの電極間隔が足し合わされる形になり、実質的に電極板の間隔を広げたのと同じことになる。 そのため合成容量は20µFにも10µFにもならず、5µFになる。 つまり、コンデンサを直列につないだときの合成容量は、抵抗を並列につないだときと同じ計算式で求められる。 「和分の積」と逆数の式のどちらも、コンデンサの直列合成に使える。

コンデンサを直列につなぐことに意味がないように思えるかもしれないが、それだけではない。 直列にすることで、電池を直列につないだときと同じように、耐えられる電圧(定格電圧)は2倍になる。

コンデンサを並列につなぐ場合は、抵抗を直列につなぐときと同じように、特別な計算をせずそのまま値を足し合わせるだけでよい。 これは、並列につなぐことで電極板の間隔を変えずに面積だけを実質的に増やしたことになるためである。 面積が増えれば、その分だけ静電容量も増える。

実験その3:コンデンサの充電を観察する

用意するもの:

  • 10kΩの抵抗1本
  • 100µFのコンデンサ3個
  • 単3形3本用の電池ボックス
  • 単3形電池3本
  • ブレッドボード
  • テスター
  • クリップ付きリード線

直列や並列につないだコンデンサの動きを、実際に確かめてみよう。 テスターで静電容量を直接測るのは難しいため、抵抗の実験より少し手間がかかる。

まず、コンデンサが0ボルトの状態から充電されるときに何が起きるかを見ておく。 一方のリードから電流が流れ込み始めると、同じ量の電流がもう一方のリードから流れ出る。 コンデンサに直列の抵抗が入っていなければ、この電流はかなり大きくなりうる。 いずれにせよ、コンデンサの電圧が印加電圧と等しくなるまで電流は流れ続け、両者の電圧が等しくなった時点で電流はゼロになる。

上で述べたとおり、コンデンサに直列の抵抗がないと流れる電流は非常に大きくなり、充電にかかる時間もミリ秒単位、あるいはそれ以下と非常に短くなる。 この実験では充電の様子をじっくり観察したいので、10kΩの抵抗を直列に入れて、動きを目で追える速さまで遅くする。 ただしその前に、RC時定数について説明しておく必要がある。

\[ \tau = R \times C \]

この式が言っているのは、秒単位の時定数(記号τ、タウと読む)が、オーム単位の抵抗値とファラド単位の静電容量の積に等しいということである。

実験その3(続き)

この実験の最初の段階では、10kΩの抵抗1本と100µF(0.0001ファラド)のコンデンサ1個を使う。 この2つの組み合わせで、時定数は1秒になる。

\[ \tau = 10,\text{k}\Omega \times 100,\mu\text{F} = 1,\text{秒} \]

100µFのコンデンサを10kΩの抵抗を通して充電すると、1時定数(この場合1秒)が経過した時点で、コンデンサの電圧は電源電圧のおよそ63%まで上昇する。 5時定数(この場合5秒)が経過すると、コンデンサは電源電圧のおよそ99%まで充電され、その電圧変化はおおむね下のグラフのような曲線を描く。

ここまでの内容を踏まえて、次の回路図のとおりに配線する(コンデンサの極性を間違えないように注意すること)。

テスターを電圧測定モードにしたまま、スイッチを入れた状態で電池ボックスの出力電圧を確認する。 これが電源電圧であり、4.5V前後になっているはずである(電池が新しければ、もう少し高くなる)。 続いて、電池ボックスのスイッチが「OFF」になっていることを確認してからブレッドボードに接続する。 赤と黒のリード線を正しい位置に接続することにも注意する。 コンデンサの足にワニ口クリップでテスターのプローブを挟むと測定しやすい(足を少し開いておくとさらにやりやすい)。

配線に問題がなく、テスターも電圧測定モードになっていることを確認したら、電池ボックスのスイッチを「ON」にする。 5秒ほど経つと、テスターの表示は電池ボックスの電圧にかなり近い値になるはずであり、これで先ほどの式が正しいことが確認できる。 今度はスイッチを切ってみる。 電圧はほとんど下がらずに保たれているはずである。 これは、コンデンサを放電させる経路がなく、回路が開いたままになっているためである。 コンデンサを放電させるには、別の10kΩ抵抗を並列に接続すればよい。 5秒ほどで、電圧はほぼゼロに戻る。

実験その3(さらに続き)

ここからが本題である。 まず、コンデンサ2個を直列につないでみる。 これは抵抗を2本並列につないだときと似た結果になるはずだと述べた。 そうであれば、「和分の積」を使って次のように予想できる。

\[ C_{合成} = \frac{100,\mu\text{F} \times 100,\mu\text{F}}{100,\mu\text{F} + 100,\mu\text{F}} = 50,\mu\text{F} \]

これが時定数にどう影響するだろうか。

\[ \tau = 10,\text{k}\Omega \times 50,\mu\text{F} = 0.5,\text{秒} \]

この予想を踏まえて、1個目のコンデンサに2個目を直列に追加し、テスターがゼロボルト(またはそれに近い値)を示していることを確認してから、スイッチを「ON」にしてみる。 電池ボックスの電圧まで充電されるのにかかった時間は、およそ半分になっただろうか。 これは、合成容量が半分になったためである。 電子を蓄える「タンク」が小さくなった分、満タンになるまでの時間も短くなる。 念のため3個目のコンデンサも直列に追加して試してみるとよいが、結果はもう予想がつくはずである。

次はコンデンサを並列につないでみる。 これは抵抗を直列につないだときと同じだと述べたので、合成容量は200µFになるはずである。 そうすると、時定数は次のようになる。

\[ \tau = 10,\text{k}\Omega \times 200,\mu\text{F} = 2,\text{秒} \]

つまり、並列につないだコンデンサが電源電圧の4.5Vまで充電されるのを目で確認するには、およそ10秒かかることになる。

証拠を示すために、この実験の最初に使った回路(10kΩの抵抗1本と100µFのコンデンサ1個の直列回路)に戻る。 このコンデンサはおよそ5秒で充電が完了することはすでにわかっている。 ここに2個目のコンデンサを並列に追加する。 テスターがほぼゼロボルトを示していることを確認し(ゼロでなければ抵抗を使って放電させる)、電池ボックスのスイッチを「ON」にする。 充電にかかる時間はかなり長くなったはずである。 予想どおり、電子の「タンク」が大きくなった分、満タンになるまでの時間が延びている。 納得できたら、3個目の100µFコンデンサも追加して、さらに長い充電時間を観察してみてほしい。

インダクタの直列接続と並列接続

インダクタ(コイル)を直列や並列に組み合わせる必要がある場面はそれほど多くないが、まったくないわけでもない。 話を完結させるために、ここでも簡単に触れておく。

基本的には抵抗と同じように組み合わされる。 つまり、直列につなぐときは値をそのまま足し合わせ、並列につなぐときは「和分の積」で計算する。 やっかいなのは、複数のインダクタを近くに配置すると、意図してもしていなくても、磁界が互いに干渉し合ってしまう場合があることである。 そのため、複数のインダクタを組み合わせるよりも、単体の部品で済ませるほうが望ましい。 ただし、市販のインダクタの多くは磁界の干渉を防ぐシールドが施されている。

いずれにせよ、インダクタも抵抗と同じように足し合わされると理解しておけば十分であり、それ以上の詳細はこのチュートリアルの範囲を超える。

まとめ

直列回路と並列回路の基礎を理解できたところで、関連するチュートリアルにも目を通してみてほしい。

  • 分圧回路:もっとも基本的で、繰り返し登場する回路の1つが分圧回路である。ここで学んだ内容がそのまま土台になる。
  • Arduinoとは何か:回路の基礎を身につけたら、Arduinoのようなマイコンボードの学習に進むこともできる。
  • スイッチの基礎:このチュートリアルでは扱わなかったが、スイッチもほぼすべての電子工作プロジェクトに登場する重要な部品である。
  • LilyPadの基礎:導電糸で縫う:回路はブレッドボードと配線だけとは限らない。E-テキスタイルでは、導電糸を使ってLEDなどの電子部品を布や衣類に縫い込む。

タグ: 概念、電気工学


出典:Series and Parallel Circuits(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

メートル法の接頭辞とSI単位

メートル法の接頭辞は、国際単位系(SI)の量を、より簡潔に表すのに欠かせない道具である。

電子工作の世界に足を踏み入れると、こうした単位は非常に重要な役割を果たし、世界中の人がそれを使って自分の成果を伝え、共有できるようになる。 電子工作でよく使われる単位には、電位差を表すボルト、電流を表すアンペア、電力を表すワット、静電容量を表すファラド、インダクタンスを表すヘンリー、抵抗を表すオームなどがある。

このチュートリアルでは、電子工作でよく使われる単位を紹介するとともに、途方もなく大きな量から極端に小さな量までを表すためのメートル法の接頭辞についても説明する。

SI単位

人類は何千年も前から物を測ってきており、そのための単位も時代とともに移り変わってきた。 今では、物理量を表す単位が何十種類も存在する。 たとえば長さは、フィート、メートル、ファゾム、チェーン、パーセク、リーグなど、さまざまな単位で測れる。 測定結果をよりよく伝え合うには、あらゆる科学者や測定者が共通して使える、標準化された単位系が必要になる。 この標準化された単位系が国際単位系、略してSIと呼ばれるものである。

物理量のSI単位

物理量SI単位単位記号
時間s
長さメートルm
質量グラムg
温度ケルビンK
ニュートンN

距離をフィートやマイルで、体積をリットルで、温度を華氏や摂氏で表すこともできるが、上記の単位は、あらゆる科学者が測定結果を共有するための標準化された表現である。 これらの単位を使うことで、誰もが同じ言葉で語れるようになる。

電子工作でよく使うSI単位

電子工作では、次のような単位に特に頻繁に出会う。

物理量SI単位単位記号
電位差(電圧)ボルトV
電流アンペアA
電力ワットW
エネルギー、仕事、熱量ジュールJ
電荷クーロンC
抵抗オームΩ
静電容量ファラドF
インダクタンスヘンリーH
周波数ヘルツHz

単位がわかったところで、これらの単位を接頭辞でどう拡張して、さらに使いやすくできるかを見ていこう。

接頭辞

メートル法の接頭辞について最初に習うのは、たいてい次の6つだろう。

接頭辞(記号)べき乗数値
キロ(k)10³1,000
ヘクト(h)10²100
デカ(da)10¹10
(接頭辞なし)10⁰1
デシ(d)10⁻¹0.1
センチ(c)10⁻²0.01
ミリ(m)10⁻³0.001

これらは、多くの学校の理科の授業で最初に習う標準的な6つの接頭辞である。 しかし、電子工作やコンピュータ科学の世界に踏み込むと、接頭辞の範囲はこの6つをはるかに超えて広がっていく。 この6つは10⁻³から10³までの範囲しかカバーしないが、電子工作で扱う値ははるかに広い範囲に及ぶことが多い。

大きな量を表す接頭辞

接頭辞(記号)べき乗数値
ヨタ(Y)10²⁴1秭(1septillion)
ゼタ(Z)10²¹1千垓(1sextillion)
エクサ(E)10¹⁸100京(1quintillion)
ペタ(P)10¹⁵1000兆(1quadrillion)
テラ(T)10¹²1兆(1trillion)
ギガ(G)10⁹10億(1billion)
メガ(M)10⁶100万(1million)
キロ(k)10³1000(1thousand)
(接頭辞なし)10⁰1

これらの接頭辞を使うと、大きな量をとても簡潔に表せる。 3,200,000,000ヘルツと書く代わりに、3.2ギガヘルツ、略して3.2GHzと書ける。 こうして、非常に大きな数の単位も簡潔に表現できる。 同じように、とても小さな数を表すための接頭辞もある。

小さな量を表す接頭辞

接頭辞(記号)べき乗数値
(接頭辞なし)10⁰1
ミリ(m)10⁻³1000分の1
マイクロ(µ)10⁻⁶100万分の1
ナノ(n)10⁻⁹10億分の1
ピコ(p)10⁻¹²1兆分の1
フェムト(f)10⁻¹⁵1000兆分の1
アト(a)10⁻¹⁸100京分の1
ゼプト(z)10⁻²¹1千垓分の1
ヨクト(y)10⁻²⁴1秭分の1

こうして、1兆分の1秒を「1ピコ秒」と呼べるようになる。 小さな値を表す接頭辞について1つ気をつけたいのは、その略記がすべて小文字である一方、大きな値を表す接頭辞(キロ、ヘクト、デカを除く)はすべて大文字であるという点である。 これにより、同じアルファベットが使われていても両者を区別できる。 たとえば1mW(ミリワット)は1MW(メガワット)とは異なる。

Note

大文字の「K」はすでにケルビンを表すために使われているため、接頭辞のキロには小文字の「k」が割り当てられている。 後述する「ビットとバイト」の節で見るように、2進数(基数2)の接頭辞を扱うときにも、kとKの混同が同じように問題になる。

単位の換算

このメートル法の接頭辞の優れた点は、いくつかの接頭辞のあいだの変換に慣れてしまえば、その考え方を他のすべての接頭辞にもそのまま応用できることである。

簡単な例として、1アンペア(A)をより小さな単位で表してみよう。 ミリアンペアはアンペアの1000分の1なので、1アンペアは1000ミリアンペアに等しい。 さらに進めると、1ミリアンペアは1000マイクロアンペアに等しい。 逆方向に見ると、1アンペアは0.001キロアンペア、つまり1000アンペアが1キロアンペアになる。 なかなかの大電流である。

気づいたかもしれないが、接頭辞を切り替えることは、小数点を3桁分ずらすことと同じであり、これは1000倍する、あるいは1000で割ることと同じである。 たとえばキロからメガのように、より大きな接頭辞に切り替えるときは、小数点を3桁分左にずらす。 100,000キロワットは100メガワットに等しい。 10キロワットは0.01メガワットに等しい。 メガはキロのすぐ上の接頭辞なので、ワットであれアンペアであれファラドであれ、より上の接頭辞に切り替えるときは、常に小数点を3桁左にずらせばよい。

逆に、ナノからピコのように、より小さな接頭辞に切り替えるときは、小数点を3桁分右にずらす。 1ナノファラドは1000ピコファラドに等しい。 0.5ナノファラドは500ピコファラドに等しい。 その関係を短くまとめると、次のようになる。

\[ \begin{aligned} 1,\text{ギガ} &= 1000,\text{メガ} \\ 1,\text{メガ} &= 1000,\text{キロ} \\ 1,\text{キロ} &= 1000,\text{(単位そのもの)} \\ 1,\text{(単位そのもの)} &= 1000,\text{ミリ} \\ 1,\text{ミリ} &= 1000,\text{マイクロ} \end{aligned} \]

このパターンがわかるだろうか。 それぞれの接頭辞は、その1つ下の接頭辞の1000倍になっている。 最初は少し圧倒されるかもしれないが、接頭辞どうしの変換はやがて自然にできるようになる。

ビットとバイト

ビットとバイトを扱っていると、混乱することがよくある。 コンピュータは10進数ではなく2進数で動作するため、メートル法の接頭辞を使うときに、どちらの基数を指しているのかがわかりにくいことがある。 たとえば1キロバイトは、1000バイト(10進)を意味することもあれば、1024バイト(2進)を意味することもあり、しばしば混乱のもとになる。

この混乱をなくすため、国際電気標準会議(IEC)は2進数のビットとバイト用に新しい接頭辞を定めた。 これは2進接頭辞と呼ばれる。

接頭辞(記号)べき乗数値
エクスビ(Ei)2⁶⁰1,152,921,504,606,846,976
ペビ(Pi)2⁵⁰1,125,899,906,842,624
テビ(Ti)2⁴⁰1,099,511,627,776
ギビ(Gi)2³⁰1,073,741,824
メビ(Mi)2²⁰1,048,576
キビ(Ki)2¹⁰1,024
(接頭辞なし)2⁰1ビットまたは1バイト

この方式を採用すると、1メガバイトは1000キロバイトになる一方、1メビバイトは1024キビバイトになる。 つまりビットとバイトの世界では、接頭辞が1つ上がるごとに1000(10³)ではなく1024(2¹⁰)倍になる。 残念ながら、この方式は実際にはあまり広く使われておらず、ビットやバイトの数を耳にするたびに、それが2進なのか10進なのかを気にする必要がある。

ハードディスクメーカーなどは、数値が大きく見える10進の表記で製品を売ることが多い。 1テラバイトのハードディスクは、実際にはおよそ931.3ギビバイトにしかならない。

ここで、大文字と小文字の「k」の問題が絡んでくる。 キビを表す正式な接頭辞は「Ki」だが、単に大文字の「K」と表記されることもあり、これは温度のケルビンを表す記号でもある。 そのため「キロバイト」という言葉を聞いたときは、それが1000バイト(10進)なのか1024バイト(2進)なのか、常に注意が必要になる。 一方、「キビバイト」という言葉であれば、それが2進での解釈(1024バイト)であることが確実にわかる。

ビットとバイトの換算

ここまでは、ビットやバイトをより大きな、あるいは小さな数に換算する方法を見てきたが、ビットとバイトを相互に変換する場面もある。 たいていの場合、1バイトは8ビットに等しく、1ビットは0.125バイト(8分の1)に等しい。 ビットに関しては他にもさまざまな単位の桁があるが、実際にはバイトが使われる場面が圧倒的に多い。 ビットとバイトを相互に変換する場面自体はそれほど多くないが、それでもメモリを扱うときなどには役立つ知識である。 たとえば、コードの中では個々のビット単位でデータを扱っていても、実際のメモリはバイト単位で管理されている、といった場面がある。

練習問題

それぞれの単位には、次のような標準的な略記を使う。

  • A:アンペア
  • V:ボルト
  • W:ワット
  • Hz:ヘルツ
  • F:ファラド
  • H:ヘンリー
  • Ω:オーム
  • s:秒
  • B:バイト
  • b:ビット

例: 400mAをAに換算せよ → 答え:400mA = 0.4A

以下を換算せよ。

  1. 50mAをAに
  2. 10nFをpFに
  3. 500kWをWに
  4. 0.01mVをµVに
  5. 20,000kΩをMΩに
  6. 4680MHzをGHzに
  7. 4TiBをGiBに
  8. 200MbをKbに
  9. 0.00007sをµsに
  10. 1450nHをµHに

解答

  1. 0.05A
  2. 10,000pF
  3. 500,000W
  4. 10µV
  5. 20MΩ
  6. 4.68GHz
  7. 4096GiB
  8. 200,000kb
  9. 70µs
  10. 1.45µH

慣れてくると、接頭辞の切り替えはあっという間にできるようになる。

まとめ

数値の大きさに応じて、もっとも適切な接頭辞に変換できることは重要なスキルである。 5,600,000や0.000000002のような、長くて読みにくい数値を避けられるようになる。 5.6Mや2nと書けば、情報をより速く、より整理された読みやすい形で伝えられる。

テスターの使い方のチュートリアルにも、ぜひ目を通してみてほしい。 テスターを使いこなすには、ここで見た接頭辞すべてについての理解が欠かせない。 測定値は、こうした接頭辞付きの単位で表示されることが多いからである。

タグ: 概念、電気工学、物理学


出典:Metric Prefixes and SI Units(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

回路図の読み方

回路図は、回路を設計し、組み立て、トラブルシューティングするための地図である。 回路図を読み、それにしたがって配線できることは、電子工学に携わるすべての人にとって重要なスキルである。

このチュートリアルを読み終えれば、回路図をひととおり読みこなせるようになるはずである。 まずは、基本的な回路図記号をひととおり見ていく。

そのうえで、これらの記号が回路図の上でどのようにつながり、回路のモデルを作っているのかを説明する。 あわせて、読み解くときに気をつけたいコツもいくつか紹介する。

参考になるチュートリアル:

回路図記号(その1)

さまざまな回路部品の記号を、まとめて見ていこう。 ここでは、標準化された基本的な回路図記号を紹介する。

抵抗器

もっとも基本的な回路部品であり、記号でもある。 抵抗器は、回路図の上ではたいていジグザグの線と、そこから伸びる2つの端子で表される。 国際規格の記号を使う回路図では、ジグザグの代わりに、何の特徴もない長方形が使われることもある。

ポテンショメータと可変抵抗器

可変抵抗器とポテンショメータは、どちらも標準的な抵抗器の記号に矢印を加えた形で表される。 可変抵抗器は端子が2つのままなので、矢印はただ中央を斜めに横切るように描かれる。 ポテンショメータは端子が3つの部品なので、矢印そのものが3つ目の端子(ワイパー)になる。

コンデンサ

コンデンサの記号としてよく使われるものが2種類ある。 一方は極性を持つ(たいていは電解またはタンタル)コンデンサを表し、もう一方は極性を持たないコンデンサを表す。 どちらも2本の端子があり、それぞれが垂直に伸びて板につながっている。

片方の板が曲線になっている記号は、そのコンデンサが極性を持つことを示している。 曲線側の板はたいていコンデンサのカソード側であり、正極であるアノード側のピンより低い電圧になっている必要がある。 極性を持つコンデンサの記号では、正極側のピンにプラス記号も添えられる。

インダクタ

インダクタは、たいてい波打った膨らみの連続、あるいはループ状のコイルとして表される。 国際規格の記号では、単純に塗りつぶした長方形として定義されることもある。

スイッチ

スイッチにはさまざまな種類がある。 もっとも基本的なスイッチである単極単投(SPST)は、2つの端子と、それらをつなぐアクチュエーター(接点を作動させる部分)を表す半分だけつながった線で構成される。

下に示すSPDTやSP3Tのように、投入先が複数あるスイッチでは、アクチュエーターの接続先がその分だけ増える。

複数の極を持つスイッチは、たいてい複数の同じスイッチが並び、中央のアクチュエーターどうしを点線でつないだ形で表される。

電源

プロジェクトへの電源供給の方法にさまざまな選択肢があるのと同じように、電源を表す回路図記号にも幅広い種類がある。

直流電源と交流電源

電子工作でよく使うのは、たいてい一定の電圧を供給する電源である。 供給元が直流(DC)か交流(AC)かを示すには、次の2つの記号のどちらかを使う。

電池

円筒形のアルカリ単3電池であれ、充電式のリチウムポリマー電池であれ、電池はたいてい、長さの異なる平行な線のペアとして描かれる。

線のペアが増えるほど、電池の中で直列につながったセルの数が多いことを示す。 また、長いほうの線が正極、短いほうの線が負極を表すのが一般的である。

電圧ノード

特に配線が込み入った回路図では、電圧そのものに特別な記号を割り当てることがある。 この端子が1つだけの記号に部品をつなぐと、それは5V、3.3V、VCC、GND(グラウンド)に直接つながっていることを意味する。 正の電圧ノードはたいてい上向きの矢印で示され、グラウンドノードはたいてい1〜3本の水平線(あるいは下向きの矢印や三角形)で示される。

回路図記号(その2)

ダイオード

基本的なダイオードは、線に押し当てられた三角形として表されるのが一般的である。 ダイオードも極性を持つため、2つの端子をそれぞれ見分けられるようにしておく必要がある。 正極であるアノードは、三角形の平らな辺につながる端子である。 負極であるカソードは、記号の線から伸びる端子である(マイナス記号だと思えばよい)。

ダイオードにはさまざまな種類があり、それぞれ標準のダイオード記号に少し手を加えた独自の記号を持つ。 発光ダイオード(LED)は、ダイオードの記号に外側へ向かう線を数本加えた形になる。 光からエネルギーを生み出す(いわば小さな太陽電池である)フォトダイオードは、逆にその矢印をダイオードに向かって内向きにする。

ショットキーダイオードやツェナーダイオードなど、その他の特殊なダイオードにもそれぞれ独自の記号があり、記号の線の部分に少しずつ違いがある。

トランジスタ

トランジスタは、BJTであれMOSFETであれ、正にドープされたものと負にドープされたものの2通りの構成がありうる。 そのため、それぞれの種類のトランジスタには、少なくとも2種類の描き方がある。

バイポーラ接合トランジスタ(BJT)

BJTは3端子の部品であり、コレクタ(C)、エミッタ(E)、ベース(B)を持つ。 BJTにはNPN型とPNP型の2種類があり、それぞれ固有の記号を持つ。

コレクタ(C)とエミッタ(E)のピンは互いに一直線上にあるが、エミッタには必ず矢印が描かれる。 矢印が内向きならPNP、外向きならNPNである。 どちらがどちらかを覚える語呂合わせとして、「NPNは中に向かってpointingしていない(not pointing in)」というものがある。

金属酸化膜電界効果トランジスタ(MOSFET)

BJTと同じくMOSFETも3端子の部品だが、今度はソース(S)、ドレイン(D)、ゲート(G)と呼ばれる。 こちらもnチャンネルかpチャンネルかによって記号が2種類あり、それぞれによく使われる記号がいくつかある。

記号の中央にある矢印(バルクと呼ばれる部分)が、そのMOSFETがnチャンネルかpチャンネルかを示す。 矢印が内向きならnチャンネル、外向きならpチャンネルである。 覚え方は「nは中(n is in)」(NPNの語呂合わせとはちょうど逆になる)。

デジタル論理ゲート

標準的な論理関数であるAND、OR、NOT、XORには、それぞれ固有の回路図記号がある。

出力に丸印を加えると、その機能が否定され、NAND、NOR、XNORになる。

入力が2つより多いこともあるが、形自体は変わらず(多少大きくなる程度で)、出力は常に1つだけである。

集積回路

集積回路は非常に多様な機能を持ち、種類も膨大にあるため、固有の回路記号を持たない。 たいていは、側面にピンが伸びる長方形として表される。 それぞれのピンには、番号と機能の両方がラベルとして付けられる。

ICの回路記号は非常に汎用的であるため、名前、値、ラベルが特に重要な意味を持つ。 それぞれのICには、そのチップの名前を正確に示す値が必ず添えられる。

固有の記号を持つIC:オペアンプと電圧レギュレータ

より一般的な集積回路の中には、固有の回路記号を持つものもある。 オペアンプはたいてい下のように描かれ、非反転入力(+)、反転入力(-)、出力、そして2つの電源ピンの、合計5つの端子を持つ。

1つのICパッケージに2つのオペアンプが内蔵されていて、電源用とグラウンド用のピンをそれぞれ1本ずつ共有する構成になっていることもよくあり、そのため右側の記号はピンが3本しかない。

単純な電圧レギュレータは、たいてい入力、出力、グラウンド(または調整用)の3端子の部品である。 これらはたいてい長方形で表され、左に入力ピン、右に出力ピン、下にグラウンド(調整)ピンが描かれる。

その他いろいろ

水晶振動子とセラミック発振子

水晶振動子やセラミック発振子は、マイコン回路にとって欠かせない部品であることが多い。 クロック信号を作り出す役割を担っている。 水晶振動子の記号はたいてい2端子だが、水晶にコンデンサを2つ組み合わせたセラミック発振子は、たいてい3端子になる。

ヘッダーとコネクタ

電源の供給であれ、情報の送出であれ、ほとんどの回路にコネクタは欠かせない。 その記号はコネクタの見た目によってさまざまであり、いくつか例を挙げる。

モーター、トランス、スピーカー、リレー

これらは、(ほとんどの場合)何らかの形でコイルを利用しているという共通点があるので、まとめて紹介する。 トランス(変圧器。「見た目以上の力を持つ」ロボットのことではない)は、たいてい2つのコイルが向かい合い、そのあいだを何本かの線で区切った形で表される。

リレーは、たいていコイルとスイッチを組み合わせた形になる。

スピーカーやブザーは、たいてい実物に近い形で描かれる。

モーターは、一般に丸で囲んだ「M」の文字で表され、端子の周りに多少の装飾が加わることもある。

ヒューズとPTC

大きな突入電流を制限するために使われるヒューズやPTCには、それぞれ固有の記号がある。

PTCの記号は、実は温度依存性を持つ抵抗であるサーミスタの一般的な記号でもある(国際規格の抵抗記号が中に入っているのに気づいただろうか)。


もちろん、この一覧に載っていない回路記号もまだまだたくさんある。 しかし、ここまでの記号を押さえておけば、回路図を読むうえで9割方は困らないはずである。 一般に、記号はそれが表す実物の部品と、見た目にも何らかの共通点を持っている。 記号に加えて、回路図上のそれぞれの部品には固有の名前と値が添えられ、それがさらに部品の識別を助けてくれる。

名前の識別子と値

回路図を読みこなすための大きな鍵の1つが、どの部品がどれなのかを見分けられることである。 部品記号はその情報の半分しか教えてくれず、それぞれの記号には名前と値の両方が添えられて初めて完全な情報になる。

名前と値

は、その部品が正確には何であるかを定義する。 抵抗器やコンデンサ、インダクタといった回路図の部品では、値はそれが何オーム、何ファラド、何ヘンリーであるかを示す。 集積回路のような部品では、値は単にそのチップの名前になっていることもある。 水晶振動子であれば、発振周波数が値として記載されることもある。 つまり、回路図の部品の値は、その部品のもっとも重要な特性を表している。

部品の名前は、たいてい1〜2文字のアルファベットと数字の組み合わせでできている。 アルファベットの部分は部品の種類を示し、抵抗器ならR、コンデンサならC、集積回路ならU、といった具合になる。 回路図上のそれぞれの部品名は一意でなければならず、たとえば1つの回路に複数の抵抗器があれば、R1、R2、R3のように名付けられる。 こうした部品名のおかげで、回路図の特定の場所を名指しできる。

名前の接頭辞はかなり標準化されている。 抵抗器のように、接頭辞が部品名の頭文字そのものになっているものもある。 一方で、そう単純にはいかない接頭辞もある。 たとえばインダクタはLで表されるが、これは電流を表す記号としてIがすでに使われているためである(ではCから始まる部品は何かというと……電子工学の世界とは、そういうものである)。 よく使われる部品と、その名前の接頭辞をまとめておく。

識別子部品
R抵抗器
Cコンデンサ
Lインダクタ
Sスイッチ
Dダイオード
Qトランジスタ
U集積回路
Y水晶振動子、発振器

これらは部品記号の「標準的な」名前ではあるが、必ずしも一律に守られているわけではない。 たとえば集積回路がUではなくICという接頭辞で表されていたり、水晶振動子がYではなくXTALとラベル付けされていたりすることもある。 どの部品がどれなのかは、状況に応じて判断してほしい。 たいていは記号自体が十分な手がかりを与えてくれる。

回路図を読む

回路図上のどの部品がどれなのかを理解できれば、読み解く作業の半分以上は終わったようなものである。 残るは、それらの記号がどうつながっているのかを見分けることだけである。

ネット、ノード、ラベル

回路図のネットは、回路の中で部品がどう配線されているかを示す。 ネットは、部品の端子どうしを結ぶ線として表される。 この回路図の緑色の線のように、他とは異なる色で描かれることもある(必須ではない)。

接続点とノード

配線は2つの端子だけをつなぐこともあれば、何十もの端子をつなぐこともある。 配線が2方向に分かれるとき、そこに接続点ができる。 回路図の上では、この接続点をノード、つまり配線の交点に置かれた小さな点で表す。

ノードがあることで、「この交点をまたぐ配線どうしは接続されている」ということを示せる。 逆に交点にノードがなければ、それは2本の別々の配線がただ交差しているだけで、接続はされていないことを意味する(回路図を設計するときは、こうした非接続の交差はできる限り避けるのが望ましいが、避けられないこともある)。

ネット名

回路図をより見やすくするために、配線を引き回す代わりに、ネットに名前を付けてラベルとして表示することがある。 同じ名前のネットは、たとえ配線でつながっているように見えなくても、接続されているとみなされる。 名前はネットの上に直接書かれることもあれば、配線からぶら下がった「タグ」として表示されることもある。

ネットの名前は、その配線上の信号の役割を具体的に表すように付けられることが多い。 たとえば電源系のネットには「VCC」や「5V」、シリアル通信のネットには「RX」や「TX」といった名前が付けられる。

回路図を読むコツ

機能ブロックを見分ける

本当に大規模な回路図は、機能ごとのブロックに分割されているべきである。 電源入力と電圧レギュレータのセクション、マイコンのセクション、コネクタ専用のセクションなどがあるかもしれない。 どのセクションが何を担っているかを見分け、入力から出力への回路の流れを追ってみるとよい。 優れた回路図の設計者は、まるで本を読むように、入力を左側に、出力を右側に配置していることもある。

電圧ノードを見分ける

電圧ノードは1端子の回路図部品であり、部品の端子をここにつなぐことで、特定の電圧レベルに割り当てられる。 これはネット名の特別な使い方であり、同じ名前の電圧ノードにつながる端子は、すべて互いに接続されているとみなされる。

グラウンドの電圧ノードは特によく使われる。 非常に多くの部品がグラウンドへの接続を必要とするからである。

部品のデータシートを参照する

回路図の中に理解できない部分があれば、その回路の中でもっとも重要な部品のデータシートを探してみるとよい。 たいてい、回路の中でもっとも多くの仕事をしているのは、マイコンやセンサーのような集積回路である。 こうした部品は回路図の中でもっとも大きく、たいてい中央付近に配置されていることが多い。

まとめ

回路図の読み方について、これでひととおり説明できた。 部品記号を知り、ネットをたどり、よく使われるラベルを見分けられるようになれば十分である。 回路図の仕組みを理解することで、電子工作の世界全体への扉が開ける。 新しく身につけた回路図の知識を実践できる、次のようなチュートリアルもぜひ試してみてほしい。

  • 分圧回路:もっとも基本的で根本的な回路の1つである。たった2本の抵抗で、大きな電圧を小さな電圧に変える方法を学べる。
  • ブレッドボードの使い方:回路図の読み方がわかったところで、今度は実際に組んでみよう。ブレッドボードは、一時的で機能する試作回路を作るのに最適な道具である。
  • 配線の基本:あるいは、ブレッドボードを使わずにいきなり配線してみるのもよい。電線を切り、被覆を剥き、接続する方法を知っておくことは、電子工作の重要なスキルである。
  • 直列回路と並列回路:直列や並列で回路を組むには、回路図をきちんと理解している必要がある。
  • 導電糸で縫う:電線を使いたくないなら、導電糸を使ったE-テキスタイルの回路を作ってみるのはどうだろうか。同じ回路図から、さまざまな素材でさまざまな作り方ができるというのが、回路図の美しさである。

タグ: 電気工学、スキル


出典:How to Read a Schematic(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

配線の基本

「電線(ワイヤー)」という言葉を耳にしたとき、たいていの人が思い浮かべるのは、直径数ミリから数センチほどの、柔軟で円筒形の金属の線だろう。 ワイヤーという言葉は機械的な用途にも電気的な用途にも使われるが、このチュートリアルでは電気配線に絞って説明する。

電線は現代社会を支える基盤の1つである。 家の中でも、照明をつけたり、コンロを温めたり、電話で話したりするのに電線が使われている。 電線は、電流をある場所から別の場所へ流すために使われる。 ほとんどの電線は、金属の芯を絶縁体で覆った構造をしている。 絶縁体とは、内部の電荷が自由に動けず、そのため電流を通さない材料のことである。 完璧な絶縁体というものは存在しないが、ガラスや紙、テフロンのように抵抗率の高い材料は、優れた絶縁体として使われる。 被覆があるのは、むき出しの電線に触れることで電流が人の体を通ってしまったり(よくない)、意図せず別の電線に接触してしまったりするのを防ぐためである。

参考になるチュートリアル:

より線と単線

電線には、単線とより線の2つの形式がある。

単線

単線は、1本の金属線(ストランドとも呼ばれる)だけでできている。 単線でよく知られる用途の1つがワイヤーラップである。

より線

より線は、複数本の細い単線を1本にまとめたものである。 同じ太さの単線に比べて、はるかに柔軟である。

単線とより線、それぞれの使いどころ

より線は同じ太さの単線より柔軟なので、ロボットアームのように頻繁に動かす必要がある配線に向いている。 逆に、ブレッドボードやプロトボード回路を試作するときのように、ほとんど動かす必要がない場面では単線が使われる。 単線であれば、ブレッドボードの穴やプリント基板のスルーホールにまっすぐ差し込みやすい。

より線をブレッドボードやスルーホールに使おうとすると、太さによっては、差し込むときに線がばらけてしまい、かなり扱いにくくなることがある。

Note

ヒント:より線をねじ端子やブレッドボード、スルーホールに接続したいときは、線をひとまとめによじり、先端にはんだを軽く染み込ませる「予備はんだ(テニング)」をしてみるとよい。 ただし、予備はんだをした先端のはんだ付け部分は、機械的な応力や熱サイクルによって割れることがある点には注意が必要である。

電線の太さ

電線の直径を表す言葉として「ゲージ」が使われる。 ゲージは、その電線が安全に扱える電流の量を判断するのに使われる。 ゲージには電気用と機械用があるが、このチュートリアルでは電気用のゲージだけを扱う。 ゲージの規格には主にAWG(アメリカン・ワイヤー・ゲージ)SWG(スタンダード・ワイヤー・ゲージ)の2種類があるが、両者の違いはこのチュートリアルではそれほど重要ではない。

電線が流せる電流量は、電線の材質、長さ、状態などいくつかの要因によって決まる。 一般に、太い電線ほど多くの電流を流せる。

SparkFunでは、試作やブレッドボード用にたいてい22 AWGの電線を使っている。 ブレッドボードやPCBで使うなら、単線のほうが穴にきれいに収まるので都合がよい。 はんだ付けを伴うその他の試作や製作では、より線が第一候補になる。 ただし、1本の電線に流す電流が多すぎないように注意すること。 発熱して溶けてしまうことがある。

より細い配線が必要な場合は、30 AWGのワイヤーラップ用電線という選択肢もある。

Note

ヒント:ワイヤーラップは、もともと試作回路を組むために使われていた技法である。 今日ではあまり一般的ではなくなったが、表面実装部品やPCBの小さなピンへの接続、スペースの限られたプロジェクト、基板の修理(いわゆる「グリーンワイヤー修理」)などには今でも有用である。 太い電線を継ぎ足す(スプライスする)ときにも、ワイヤーラップは役に立つ。

電線の被覆を剥く方法

安全で長持ちする電気接続は、きれいで正確な被覆剥きから始まる。 下の金属線を傷つけずに外側のプラスチック被覆だけを取り除くことが重要である。 もし電線に傷が入ってしまうと、接続が切れたり、ショートが起きたりすることがある。

道具

手動式ワイヤーストリッパー

シンプルな手動式のワイヤーストリッパーは、ハサミのような一対の刃でできている。 太さの異なる複数の切り欠きがあり、電線の太さに合った切り欠きを選ぶことが、電線を傷めないために非常に重要である。 メーカーによっては、ロック機構やエルゴノミックなハンドル、ねじを切断する機能が付いていることもある。

Note

警告:ホームセンターで売っている多くのワイヤーストリッパーは、細いゲージ(22〜30番)の電線を剥けないことがある。 試作を始めるなら、22 AWG以下の細い電線も剥ける道具を選ぶこと。 30 AWG(ワイヤーラップ用電線)まで剥ける道具であれば、なおよい。

ナイフでも被覆を剥くこと自体はできるが、金属部分に傷を入れたり切り込んでしまったりする恐れがある。 ナイフで電線の被覆を剥くのは、刃が滑って大怪我につながりかねないため、非常に危険でもある。

自動調整式ワイヤーストリッパー

自動調整式のワイヤーストリッパーもあり、電線を歯の中央に置いてハンドルを握るだけで自動的に被覆を剥いてくれる。 ほとんどどんな電線でも、毎回きれいに剥ける。 メーカーによっては、被覆付きと被覆なしの電線を切断したり圧着したりする機能が付いていることもある。

Note

ヒント:自動調整式のワイヤーストリッパーは、ケーブルのシースを剥いたり、複数本の被覆線を同時に剥いたりするのにも便利である。

ワイヤーラップツール

ワイヤーラップツールを使ってピンに電線を巻きつける場合、道具の中央にストリッパーの刃が内蔵されていて、細い電線の被覆を剥けるようになっていることが多い。 電線を刃のあいだに挟んで引っ張るだけでよい。

手動式ワイヤーストリッパーで被覆を剥く

電線の先端から1/4インチ(あるいは必要な長さ)のところで、適切な切り欠きを使ってハンドルを握り、少しひねると、被覆が切れて緩む。 そのままワイヤーストリッパーを電線の先端側へ引っ張ると、被覆がすっと抜ける。

コツと注意点

電線の太さと、ストリッパーの切り欠きのサイズを正しく合わせることが重要である。 切り欠きが大きすぎると被覆が剥けず、逆に小さすぎると電線自体を傷つけてしまう。 切り欠きが小さすぎると刃が閉じすぎて、下の金属線に食い込んでしまう。 より線の場合、外側の数本が切り取られてしまい、電線全体の太さが減り、強度も落ちてしまう。 単線の場合、傷が入るとその部分の強度と柔軟性が大きく落ち、曲げたときに折れる可能性が大きく高まる。

もし誤って電線に傷を入れてしまったら、その部分を切り落として、もう一度やり直すのがもっとも確実である。

電線を継ぎ足す(スプライス)方法

まず、ワイヤーストリッパーで両方の電線の先端の被覆を剥く。 より線を使う場合は、先端をよじって線をまとめ、はんだ付けの前に予備はんだをしておくとよい。

むき出しになった部分を覆えるだけの長さに熱収縮チューブを切り、あらかじめどちらかの電線に通しておく。 このとき、これから継ぎ足す部分から離れた位置までチューブをずらしておくことを忘れないようにする。

2本の電線の先端を向かい合わせ、むき出しの部分どうしを触れさせる。 はんだ付け用のマットにテープで固定して、電線どうしを押さえておく。

Note

ヒント:テープで固定する以外にも、「第三の手(クリップスタンド)」や3Dプリントした固定具を使う方法もある。

電線にはんだを流し込む。 はんだごてを電線に当てすぎないように注意する。 被覆が溶けて、想定より広い範囲がむき出しになってしまうことがある。

電線の裏側にもしっかりはんだが回っていることを確認する。

電線を裏返し、反対側にもはんだを行き渡らせる。 必要であればフラックスとはんだを追加する。

熱収縮チューブを使う場合は、接続部分にかぶせてスライドさせ、はんだごてやヒートガンで熱を加えて収縮させる。 仕上がると、熱収縮チューブがむき出しだった部分をきれいに覆う。

Note

ヒント:他にも継ぎ足しの方法はいろいろある。 電線どうしをよじり合わせる方法(互い違いにねじる「ツイストヘリックス」や、同じ方向にねじる方法)や、フックのように引っ掛けてからよじる「ウェスタンユニオン splice(別名リネマンズ splice)」もあり、これは主に単線向けだがより線にも使える。 上級者向けには、電線を途中で完全に切断せずに分岐させる「ウェスタンTスプライス」もある。 これは、限られたスペースの中でプルアップ抵抗のような部品を追加したいときに便利で、電線の途中の被覆をカッターやはんだごてで剥き、別の電線や端子を巻きつけてはんだ付けする。 仕上げに熱収縮チューブやホットグルーで絶縁するとよい。

電気コネクタを圧着する方法

電気コネクタは、機械的な組み立てによって電気回路どうしをつなぐための部品である。 接続は一時的なこともあれば、恒久的なこともある。 電気コネクタには何百もの種類があるが、電線どうしをつなぐものもあれば、電線を端子につなぐものもある。

代表的なコネクタをいくつか紹介する。 左上の絶縁スプライスコネクタは、2本の電線の端をつなぐためのものである。 その右にあるフォーク型端子(スペード端子、開放リング端子とも呼ばれる)は、ねじ端子のソケットに差し込んで使うのに便利で、ねじを軽く緩めておけば取り付けられる。 中央のリング端子もねじ端子への接続によく使われ、フォーク型よりも信頼性の高い接続が得られるが、取り付けや取り外しの際にねじを完全に外す必要がある。 右上のオス型スペード端子(ブレード端子)は、右下に示したメス型スペード端子(ダブルクリンプ)に差し込んで使う。 これらのコネクタには、フランジ付きフォークやロック機構付きリング端子など、用途に応じたさまざまな派生形もある。

これらのコネクタにはサイズや定格の違いもあり、たとえば1/4インチと2.8mmのメス型スペード端子ではサイズが異なる。 確実な接続を得るには、コネクタのサイズをきちんと合わせる必要がある。

圧着(クリンプ)とは何か

ここで言う圧着(クリンプ)とは、金属を変形させることで2つの金属部品を組み合わせ、一方が他方を保持するように接合する方法を指す。 この変形部分そのものを「クリンプ」と呼ぶ。

道具

電線にコネクタを圧着するには、圧着ピンに応じた専用の工具が必要になる。 圧着ピンの種類に応じて、いくつかのスタイルの圧着工具が存在する。

ラチェット式圧着工具

もっとも優れた圧着工具には、ラチェット機構が内蔵されている。 ハンドルを握るとラチェットがかかり、あご(ジョー)が途中で開かないようになっている。 十分な圧力がかかると、ラチェットが外れて圧着済みの部品が解放される。 これにより、必ず十分な圧力がかかったことを保証できる。 このタイプの工具は、あごの接触面も広く作られている。

コネクタのサイズによって、工具の「ダイ」(圧着工具の先端部分)のサイズも変わる。

手動式圧着工具

手動式の圧着工具でも、ほぼ同じ結果を得られるが、使う側により高い注意力が求められる。 このタイプの工具は一般に頑丈さに劣り、コネクタに対してあごが正しく揃っているか、圧着のたびに気を配る必要がある。 位置がずれると、望ましくない圧着になってしまう。 通常の使用による摩耗で、あごが完全に閉じなくなってくることもある。 基本的には、できる限り強く握れば十分である。

Note

警告:ペンチは圧着工具ではない。 ハンマーもバイスも、ニードルノーズプライヤーも、平らな石も同様である。 正しい圧着工具を正しく使えば、電線とコネクタのバレル部分のあいだに「コールドウェルド(常温接合)」ができる。 よく圧着された部分を輪切りにすると、電線とコネクタが一体化した固い形になっているのがわかる。 間違った道具を使うと、この状態にはならない。 なぜこれほどの完成度が求められるのか。 圧着が不十分だと、電線とコネクタのあいだに空気の隙間ができてしまう。 その隙間に湿気がたまり、湿気が腐食を招き、腐食が抵抗を生み、抵抗が発熱を招き、最終的には断線につながりかねないからである。

クイックディスコネクトコネクタを圧着する

単線に圧着接続を使うことについては賛否両論がある。 単線を圧着すると、その部分が弱点になり、断線につながると考える人も多い。 また、単線は端子の形に合わせて変形しにくいため、より線に比べて圧着がゆるみやすいとも言われる。 どうしても単線を使う必要がある場合は、圧着した後にその部分をはんだ付けしておくとよい。

まず、端子のサイズに合った太さの電線を選ぶ(あるいはその逆)。 ここでは、圧着した接続部分に電線がなじみやすいより線を使うことを前提とする。 次に電線の被覆を剥く。 むき出しにする長さは、コネクタの金属製バレル部分の長さと同じくらい、たいてい1/4インチ程度にする。 剥いた電線がバレルの中にほとんど隙間なく収まれば、コネクタのサイズは適切である。

電線は、被覆がバレルの端に触れるところまで挿入する。

電線と端子を圧着工具に差し込む。 端子の被覆の色と、圧着工具に示された色の位置を合わせる必要がある。 たとえば端子の被覆が赤なら、工具の赤い印の位置を使う。 工具に色の表示がなければ、側面のゲージ表示を使う。

端子はバレル側を上にして水平に置き、工具はそのバレルに対して垂直に、リング側にもっとも近い位置に当てる。 圧着を仕上げるには、工具をかなりの力で握り込む。 一般に、圧着を「やりすぎる」ことはほぼ不可能である。

圧着が終わったら、電線とコネクタを強い力で引っ張っても外れないことを確認する。 もし外れてしまうなら、圧着は正しくできていない。 実際に使う場所に取り付けてから失敗するよりは、この段階で失敗を見つけておくほうがよい。

Note

ヒント:電線がバレルに収まらない、あるいはゆるすぎる場合は、電線かコネクタのサイズや種類が合っていない。 必要であれば、電線とコネクタのあいだにはんだを追加することもできる。 ただし、正しく圧着された接続は気密性の高い常温接合になっており、本来はんだは不要である。 はんだを追加すると、機械的な振動や熱サイクルによる応力が接合部に加わりやすくなり、かえって断線の原因になることがある。 はんだ付けは接合部の抵抗を増やすこともあるが、低電力の用途であれば、その違いが問題になることはほとんどない。

圧着ピンを圧着する

電気コネクタには何百もの種類があることをもう一度思い出してほしい。 設計によっては、プラスチック製のハウジングに差し込む形のコネクタもある。 バレルで電線を締め付ける代わりに、電線とその被覆それぞれを挟み込む2組の圧着タブ(「羽根」)を持つものもある。 被覆用の圧着タブは、電線を引っ張る力を逃がす「ストレインリリーフ」の役割を果たす。 圧着ピンには、プラスチックハウジングに挿入したときに使うロック用のタブや、位置決め用のストッパーが付いていることもある。

たとえば、既製のプレミアムジャンパー線には、0.1インチ間隔のPTHパッドを持つPCBに接続するためのこの種のピンが使われている。

この作業は、より小さなピンを扱うため少し根気が必要になる。 慣れていないと時間がかかることもあるが、プロジェクトに合わせた自由な長さや構成のケーブルを自作できるようになる。

まず、電線を切って被覆を剥く。 電線の太さは、圧着ピンの仕様に合わせる必要がある。 ここでは、圧着ピンのデータシートが推奨する22 AWGのより線を使い、JST RCYコネクタに接続する。 金属帯から圧着ピンを切り離した後、電線の芯を導通用のタブに、被覆を絶縁用のタブに合わせて、電線が仕様に合っているか確認する。

十分に被覆を剥けていたら、圧着ピンを工具のあごの片方に差し込む。 絶縁タブを内側に少し曲げる必要があるかもしれない。 ここでは大きいほうのあごを使う。

工具のみぞをよく確認しながら、圧着ピンをダイに差し込む。 あごの片側には半円形のみぞが2つ、もう片側には1つ切られている。 みぞが2つあるほうでタブを圧着する。 さらに、ダイの半分は絶縁タブ用にくぼんでいる。

Note

警告:圧着ピンを正しく差し込まないと、ラチェット式の工具ではタブを十分に圧着できない。 その結果、電線とピンがきちんと導通せず、ピン自体が壊れてしまうことがある。 工具が途中の位置で固まってしまった場合は、ハンドルのすぐ上にある安全解除ピンを操作する必要がある。

ラチェット式の工具をゆっくり閉じて圧着ピンを固定し、剥いた電線を差し込む。 圧着ピンの絶縁タブがダイと面一になるよう、位置を調整する必要があるかもしれない。

準備ができたら、ハンドルをゆっくりとさらに握り込み、タブの圧着を進める。 うまくいかない場合は、ハンドルのすぐ上の安全解除ピンを操作する。 ラチェットが自動的に外れるまでハンドルを握り続ければ、圧着は完了である。

圧着したピンを工具から慎重に取り外す。 タブの様子を確認する。 うまくいっていなければ、もう一度あごに差し込んで圧着し直す必要があるかもしれない。

準備ができたら、圧着したピンをそれぞれのハウジングに挿入する。 ロック用のタブと、プラスチックハウジング側の穴の位置を合わせることを忘れないようにする。

正しく挿入できれば、電線はハウジングにカチッと収まるはずである。

よくある失敗

クイックディスコネクトや圧着ピンを圧着するときによくある失敗をいくつか挙げる。

電線に対してコネクタのサイズが合っていない、あるいはコネクタに対して電線のサイズが合っていない。

被覆を剥きすぎないよう注意すること。

害があるとは限らないが、電線がバレルの先から出すぎているのも望ましくない。 その場合は、余った部分を切りそろえるとよい。

ワイヤーラップツールの使い方

Note

注意:ワイヤーラップは細いゲージの電線を使うため、スペースの限られたプロジェクトには最適だが、電線が細い分、大きな電力を扱うことはできない。

30 AWGの電線をワイヤーラップツールの刃のあいだに挟み、引っ張って被覆を剥く。

端子に十分巻きつけられるだけの長さを剥いておく。 だいたい1インチほどあれば十分である。

むき出しにした電線を、側面の切り欠きの穴に差し込む。 切り欠きのある側に電線を入れ、円筒の側面の溝に沿わせる。

電線をヘッダーピン(ポスト)に差し込む。 ここでは、ミニブレッドボードに挿したオスヘッダーピンを例にしている。

Note

注意:スタック可能なメスヘッダーピンは、ワイヤーラップツールと電線と一緒にねじれてしまうことがある。 巻きつけには、オスヘッダーピンを使うことをおすすめする。

工具を時計回りに回して、四角いヘッダーピンに電線を巻きつけていく。 もう片方の手で電線とヘッダーピンを押さえながら、剥いた部分がすべて巻き終わるまで回し続ける。

ピンから工具を外す。 仕上がると、電線の被覆はピンの根元から始まっているはずである。 より確実で恒久的な接続にしたい場合は、電線とピンのあいだにはんだを追加するとよい。

同じピンにさらに接続を増やしたい場合は、最初の巻きつけの上にもう1本の電線を巻けばよい。 何本重ねられるかは、ヘッダーピンの長さによる。 マイコンやLED、抵抗のヘッダーに、試作用としてワイヤーラップツールを使ってみるのもよいだろう。

巻きつけた電線を外す

ピンから電線を外したいときは、工具の反対側の端を使って反時計回りに回す。 巻きつけが緩んだら、電線をピンから引き抜く。

配線の取り回し

電線をより合わせる

プロジェクトで使う長い電線は、より合わせて(編んで)おくとよい。 より合わせることには、いくつかの利点がある。

  • プロジェクトが整理された状態を保てる
  • 可動部分によって電線が引っ張られるのを防げる
  • 接続そのものが補強される

以下は、非アドレサブルLED用に4本のリード線を編み合わせる例である。 編むには、両手の人差し指と親指を使い、まず1組の電線を反時計回りにねじる。 ここでは緑と赤の電線を先にねじった。

もう1組の電線も反時計回りにねじる。

ねじった2組の電線を、今度は時計回りにねじり合わせる。

仕上がると、プロジェクトの配線が扱いやすく整理された状態になる。

Note

ヒント:長い電線をねじり合わせるときは、電動ドリルを使うと楽である。

スリーブとケーブルキャリア

スリーブやケーブルキャリアも、可動部分から配線を守るのに役立つ。

複雑な配線にラベルを付ける

付箋やテープ、マーカーを使って電線にラベルを付けておくと、同じ色の電線を使っているときや、配線が複雑なとき、トラブルシューティングをするときに、どの配線がどこにつながっているかを把握しやすくなる。

まとめ

これで、電気配線とその使いどころについて、ひととおり理解できたはずである。 試作でも、改造でも、最終的な製品作りでも、電線は頼れる存在になってくれる。 電気配線に関連する、次のようなチュートリアルもぜひ確認してほしい。

  • 電線は、自分の回路を作るうえでもっとも基本的な要素である。
  • コネクタの基礎を確認してほしい。
  • 試作を始めたいなら、ブレッドボードのチュートリアルから始めるとよい。
  • 接続にもっと柔軟性が欲しいなら、ウェアラブル作品に導電糸を使ってみるのもよい。

タグ: 電気工学、プロトタイピング、スキル、はんだ付け、ツール


出典:Working with Wire(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

コネクタの基礎

コネクタは、回路のさまざまな部分をつなぎ合わせるために使われる。 たいていコネクタが使われるのは、電源の入力、周辺機器との接続、交換する可能性のある基板など、将来その部分を切り離せるようにしておきたい場面である。

このチュートリアルで扱う内容:

  • コネクタの基本的な用語
  • コネクタをいくつかのカテゴリに分類する
  • カテゴリの中でのコネクタどうしの違い
  • 極性を持つコネクタの見分け方
  • 用途に応じてどのコネクタが適しているか

参考になるチュートリアル:

コネクタの用語

よく使われるコネクタの話に入る前に、コネクタを説明するときに使われる用語を確認しておこう。

ジェンダー(性別)

ジェンダーとは、コネクタが差し込む側か、差し込まれる側かを表す言葉であり、それぞれ「オス」「メス」と呼ばれる。 ただし、見た目はメスなのに「オス」と呼ばれる例外的なコネクタもあり、個々の部品を説明する中でそうした例といくつかの理由にも触れていく。

極性

極性:ほとんどのコネクタは、決まった1つの向きでしか接続できない。 この性質を極性と呼び、間違った向きで挿さらないようになっているコネクタは極性を持つ、あるいはキー付きであるという。

接点

接点:接点はコネクタの本体にあたる部分であり、互いに触れ合って電気的な接続を作る金属部品である。 問題が起きやすいのもこの部分であり、接点が汚れたり酸化したりすることや、接点どうしを押さえつけるばねの力が時間とともに弱まることがある。

ピッチ

ピッチ:多くのコネクタは、規則的な間隔で並んだ接点の配列でできている。 コネクタのピッチとは、ある接点の中心から隣の接点の中心までの距離のことである。 見た目がよく似ていてもピッチが異なるコネクタの系列がいくつもあるため、正しい相手方のコネクタを購入するのが難しくなることがあり、この点は重要である。

嵌合回数(メイティングサイクル)

嵌合回数:コネクタの寿命には限りがあり、抜き差しを繰り返すことで摩耗していく。 データシートでは、たいていこの寿命を嵌合回数として表しており、技術によって大きく差がある。 USBコネクタは数千から数万回の寿命を持つこともあるが、民生機器の内部で使われる基板間コネクタは数十回程度に限られることもある。 用途に見合った寿命のコネクタを選ぶことが重要である。

実装方法(マウント)

マウント:この言葉は紛らわしい場合がある。 「マウント」は、実際にどう取り付けられているか(パネル取り付け、宙づり、基板取り付け)、取り付け対象に対してどんな角度になっているか(ストレートかライトアングルか)、機械的にどう固定されているか(はんだ付けタブ、表面実装、スルーホール)など、いくつもの意味で使われる。 それぞれのコネクタの解説の中で、もう少し詳しく触れていく。

ストレインリリーフ

ストレインリリーフ:コネクタが基板やケーブルに取り付けられているとき、その電気的な接続部分は壊れやすいことが多い。 そこで、コネクタにかかる力を、壊れやすい電気接続部分ではなく、より頑丈な部分に逃がすための仕組みを設けるのが一般的である。 これについても、後ほど良い例をいくつか紹介する。

USBコネクタ

USBコネクタには、ホスト用と周辺機器用の2種類がある。 USB規格の中ではこの2つは区別されており、ケーブルや機器のコネクタもそれを反映した形になっている。 ただし、すべてのUSBコネクタには次のような共通点がある。

  • 極性がある:USBコネクタは、原則として一方向にしか挿せない。無理に逆向きに挿すこともできてしまうが、その場合は機器を壊すことになる。
  • 4本の接点:すべてのUSBコネクタには少なくとも4本の接点がある(5本のものや、USB 3.0以降ではさらに多くの接点を持つものもある)。これらは電源、グラウンド、2本のデータ線(D+とD-)用である。USBコネクタは5V、最大500mAを伝送するように設計されている。
  • シールド:USBコネクタには、回路の一部ではない金属製のシェルによるシールドが施されている。電気的なノイズの多い環境で信号を保つために重要である。
  • 確実な電源接続:データ線を通して機器に電源を供給してしまわないよう、電源ピンはデータ線より先に接続される必要がある。すべてのUSBコネクタはこれを踏まえて設計されている。
  • モールド成形のストレインリリーフ:すべてのUSBケーブルは、コネクタ部分にプラスチックのモールドが施されており、ケーブルにかかる力が電気的な接続部分を傷めないようになっている。

USB-Aコネクタ

USB-Aメスは、標準的な「ホスト」側のコネクタである。 パソコンやハブなど、周辺機器を接続する側の機器に見られる。 メスのA端子とオスのA端子を両端に持つ延長ケーブルもある。

USB-Aオスは、標準的な「周辺機器」側のコネクタである。 たいていのUSBケーブルの片方の端はUSB-Aオスになっており、キーボードやマウスのような機器には、あらかじめこの端子が付いたケーブルが内蔵されていることも多い。 USBメモリのように、基板取り付け型のUSB-Aオスコネクタもある。

USB-Bコネクタ

USB-Bメスは周辺機器向けの規格である。 かさばるが頑丈であるため、サイズが問題にならない用途では、取り外し可能なUSB接続を提供する手段として好まれる。 たいていはスルーホールの基板取り付け型で信頼性が高いが、パネル取り付け型もある。

USB-Bオスは、ほぼケーブルの先端にしか見られない。 USB-Bケーブルはどこにでもあり安価なため、USB-B接続の普及にも一役買っている。

USB-Miniコネクタ

USB-Miniは、小型機器向けにUSBコネクタを小型化しようとした最初の標準的な試みだった。 USB-Miniメスは、MP3プレーヤーや旧型の携帯電話、小型の外付けハードディスクなど、比較的小さな周辺機器に使われることが多く、たいてい表面実装型で、頑丈さよりも小型化を優先している。 USB-Miniは、USB-Microコネクタに徐々に置き換えられつつある。

USB-Miniオスも、ケーブル専用のコネクタである。 USB-Bと同じく非常に一般的で、どこでも安価に手に入る。

USB-Microコネクタ

USB-Microは、USBコネクタの中でも比較的新しい規格である。 USB-Miniと同じく小型化が主眼だが、USB-Microには低速信号用の5本目のピンが追加されており、状況に応じてホストにも周辺機器にもなれるUSB-OTG(オンザゴー)用途に対応できる。

USB-Microメスは、デジタルカメラやMP3プレーヤーなど、比較的新しい周辺機器に多く見られる。 すべての新しい携帯電話やタブレットの標準的な充電ポートとしてUSB-Microが採用されたことで、充電器やデータケーブルもますます一般的になっており、今後はUSB-Miniに代わって小型USBコネクタの主流になっていくと見られる。

USB-Microオスも、ケーブル専用のコネクタである。 USB-Microオス端子を持つケーブルには、USB-Microポートを持つ機器を周辺機器としてUSBホストに接続するためのものと、USB-Microメスポートをアダプターとして通常のUSB-Aメスポートに変換し、USB-OTG対応機器で使うためのものの、大きく2種類がある。

その後継として、USB 3.0 Micro-B(差動ペア2組とグラウンドのための追加ピンを持つ)や、上下どちら向きにも挿せる24ピンのUSB Type-Cも登場している。 USB Type-Cは500mAを超える電流にも対応できるため、電力を多く必要とする機器にも向いている。

Note

ケーブルによっては、USB-Cのすべてのピンが使われているとは限らない。USB 3.1のフル規格ではなく、USB 2.0相当の4ピンしか配線されていないケーブルもある。使用するUSBポートによっては、機器に供給できる電流量が制限されることもある。

オーディオ用コネクタ

もう1つよく知られたコネクタ群が、RCAや「フォン」といったオーディオビジュアル機器用のコネクタである。 USBの各規格ほど厳密に同じ系統とは言えないが、ここでは便宜上まとめて扱う。

「フォン」型コネクタ

1/8インチサイズのこのコネクタは、ヘッドホンの先端に付いているものとしてすぐにわかるだろう。 このコネクタには1/4インチ(6.35mm)、1/8インチ(3.5mm)、2.5mmという3つの一般的なサイズがある。 1/4インチサイズは主にプロ向けの音響機器や音楽業界で使われ、多くのエレキギターやアンプに1/4インチのTS(チップとスリーブ)ジャックが付いている。 1/8インチのTRS(チップ、リング、スリーブ)は、ヘッドホンや、MP3プレーヤーやパソコンの音声出力用コネクタとしてよく使われる。 携帯電話の中には、マイク付きのハンズフリー用ヘッドホンをつなぐために、2.5mmのTRRS(チップ、リング、リング、スリーブ)ジャックを備えているものもある。

こうしたコネクタやケーブルは広く出回っているため、汎用の接続用途にも適している。 たとえばUSBが登場するはるか以前、テキサス・インスツルメンツのグラフ電卓は、シリアル通信用のコネクタとして2.5mmのTRSを使っていた。 TS型のコネクタは電源の伝送を想定した設計ではないことに注意してほしい。 挿し込む際にチップとスリーブが一瞬ショートすることがあり、電源を痛める可能性がある。 シールドがないため高速なデータ通信には向かないが、低速なシリアルデータであれば問題なく通せる。

RCAコネクタ

何十年ものあいだ、家庭用オーディオの定番コネクタとして親しまれてきたRCAコネクタは、1940年代にRCA社が家庭用の蓄音機向けに導入したものである。 音響や映像の分野ではHDMIのような規格に徐々に取って代わられつつあるが、コネクタとケーブルの普及ぶりから、自作システムには今なお適した選択肢である。 廃れるまでには、まだしばらく時間がかかるだろう。

メスのRCAコネクタはたいてい機器側にあるが、延長用や変換用のケーブルにメス端子が付いていることもある。 RCAコネクタは、コンポーネント映像(販売地域によってPALかNTSC)、コンポジット映像、ステレオ音声、S/PDIF音声のいずれかの信号に使われることが多い。

オスのRCAコネクタはたいていケーブル側にある。

電源用コネクタ

多くのコネクタはデータと一緒に電源も伝送するが、中には電源の接続専用として使われるコネクタもある。 用途やサイズによってさまざまだが、ここではもっとも代表的なものだけを取り上げる。

バレルコネクタ

バレルコネクタは、かさばるACアダプター経由でコンセントにつなぐ、低価格の民生機器でよく見られる。 ACアダプターはさまざまな定格電力や電圧のものが広く出回っており、そのためバレルコネクタは小規模なプロジェクトへの電源供給によく使われる。

メス側のバレルコネクタ、いわゆる「ジャック」には、基板取り付け型(表面実装またはスルーホール)、ケーブル取り付け型、パネル取り付け型など、いくつかの種類がある。 中には、電源が差し込まれているかどうかを検出できる追加の接点を持つものもあり、外部電源で動作しているときに電池をバイパスして電池寿命を延ばすといった使い方ができる。

オス側のバレルコネクタ、いわゆる「プラグ」は、たいてい電線への取り付け用としてのみ販売されているが、電線への固定方法にはいくつかの種類がある。 あらかじめケーブルに取り付けられたプラグを購入することもできる。

Note

こうした低電力の同軸コネクタのジャックとプラグのどちらを「オス」と呼ぶかについては、意見が分かれることがある。 入手先によっては、中心にピンがあることを理由にジャック側を「オス」バレルコネクタと呼ぶこともあり、その場合プラグ側は逆になる。 目的のものが見つかったかどうかは、必ず商品写真と仕様を確認してほしい。

バレルコネクタは2本の接続、いわゆる「ピン(チップ)」と「スリーブ」しか持たない。 注文する際に区別すべき特性は3つあり、内径(ジャック内部のピンの直径)、外径(プラグ外側のスリーブの直径)、そして極性(スリーブの電圧がチップより高いか低いか)である。

スリーブの直径は、多くの場合5.5mmか3.5mmである。

ピンの直径はスリーブの直径によって決まり、5.5mmのスリーブには2.5mmまたは2.1mmのピンが組み合わされる。 残念ながら、これは2.5mmピン用のプラグが2.1mmのジャックにも物理的に挿さってしまうことを意味し、その場合の接続はよくても不安定なものになる。 3.5mmスリーブのプラグは、たいてい1.3mmピンのジャックと組み合わされる。

極性は最後に確認すべき要素であり、たいていスリーブが0V、チップがスリーブに対して正の電圧になる。 多くの機器には、その機器が想定する極性を示す小さな図が記載されており、これに従うことが重要である。 極性が違う電源を使うと、機器を壊してしまうことがある。

どちらのスリーブサイズのプラグも、たいてい長さ9.5mmだが、それより長いものや短いものもある。 SparkFunのすべての製品は、負極が5.5mmスリーブ、正極が2.1mmピンという組み合わせを採用しており、これが世の中でもっとも一般的な仕様と思われるため、できる限りこの標準に従うことをおすすめする。

「Molex」コネクタ

パソコンのハードディスクや光学ドライブなど、内蔵の周辺機器の多くは、一般に「Molex」コネクタと呼ばれるコネクタから電源を得ている。 正確にはMolexシリーズ8981コネクタと言い、Molexとは1950年代にこのコネクタを最初に設計した会社の名前だが、いつしかその区別はあいまいになった。

Molexコネクタは大電流を流せるように設計されており、1ピンあたり最大11Aまで対応する。 CNCマシンや3Dプリンタのように大きな電力が必要なプロジェクトでは、デスクトップパソコン用の電源ユニットを使い、Molexコネクタを介して各回路に電力を供給する方法がよく使われる。

Molexコネクタは、オスとメスの呼び方が少し独特である。 メスコネクタはたいていケーブルの先端にあり、オスコネクタのピンを囲むプラスチックのシェルの中に差し込む形になっている。 たいていのMolexコネクタは圧入式で非常にきつく、数回程度の抜き差ししか想定されていないため、頻繁に接続を変える用途には向かない。

IECコネクタ

Molexコネクタと同じく、これも一般名がある特定の部品を指す言葉として定着した例である。 IECコネクタは、たいていデスクトップパソコンの電源ユニットに見られる電源入力口を指す。 厳密にはIEC 60320-1のC13(メス)およびC14(オス)コネクタである。

IECコネクタは、ほぼ交流電源の入力専用として使われる。 プロジェクトにこのコネクタを使う利点は、IECから壁コンセントまでのケーブルが非常に一般的であり、世界各国のコンセント形状に合わせたものが手に入りやすいことである。

JSTコネクタ

SparkFunでは「2.0mm JSTコネクタ」という呼び方をよく使う。 これもまた、特定の製品を指す一般化された名称であり、JSTは高品質なコネクタを作る日本の会社の名前で、私たちがよく使う2.0mm JSTコネクタは、PHシリーズの2極極性付きコネクタである。

SparkFunのシングルセルのリチウムポリマー電池はすべて、標準でこのタイプのJSTコネクタを備えており、多くの基板もこのコネクタ(またはそのフットプリント)を電源入力として採用している。 コンパクトで頑丈、そして逆向きに接続しにくいという利点がある。 もう1つの特徴として、いったん接続すると外すのがかなり大変(丁寧に扱えばニッパーで外すこともできる)という点があり、これは見方によって長所にも短所にもなる。 使用中に外れにくい反面、充電のために電池を外そうとすると、コネクタを傷めてしまうこともある。

3極以上のPHシリーズコネクタもあり、SparkFunでも扱っているが、もっともよく使われるのは2極の電池用コネクタである。

SMAアンテナコネクタ

SMAコネクタの紛らわしい命名規則についても簡単に触れておく。

SparkFunでは、GPSBluetooth、セルラー通信、NordicXBeeなど、外部アンテナへ50Ω系のインピーダンス接続が必要な基板の一部にSMA系コネクタを使っている。 ただし、基板によってSMAコネクタのジェンダーや極性が異なるため、それぞれの基板のRFコネクタに合ったアンテナを選ぶ必要がある。

もともとのSMA規格では、オス(中心にピン、内側にねじ)とメス(中心に穴、外側にねじ)という組み合わせが定義されていた。 しかしこの構成には問題があり、FCC(アメリカ連邦通信委員会)がPart 15への準拠を進める中で、SMA系のRFコネクタのジェンダー(中心ピン)を入れ替える方向に動いた。 これは、家庭用の無線機器(家庭用Wi-Fiなど)にアンテナをねじ込むときに、一般ユーザーがRF機器を壊してしまうのを防ぐための変更である。 すべてのアンテナがメスであれば、中心の接点を壊す心配がなくなる。

このPart 15対応で変わったのは中心ピンだけであり、これによって極性が逆転した「新しい」規格、RP-SMA(リバースポーラリティSMA)が生まれた。 「RP(リバースポーラリティ)」という名前は、そのねじ山側のジェンダーに由来しており、ピン側は通常と逆のジェンダーになる。

外部アンテナ用にu.FLコネクタを備えていないSparkFunのRF基板やアンテナでは、旧規格(SMA)と新規格(RP-SMA)が次のように使い分けられている。

  • それぞれ900/1700/1800MHz帯、1.57542GHz帯は、たいてい旧規格を使う:アンテナがSMAオス、モジュールがSMAメス。
  • Bluetooth、ZigBee、Wi-Fi、Nordicは、たいてい新規格を使う:アンテナがRP-SMAオス、モジュールがRP-SMAメス。

実際のところ、ジェンダーの表記自体はあまり気にしなくてよい。 RP-SMAの基板やモジュールにはRP-SMAのアンテナを、SMAにはSMAのアンテナを合わせればよいだけである。 アンテナの対応周波数を基板に合わせることだけ忘れないようにしたい。

ピンヘッダーコネクタ

ピンヘッダーコネクタには、いくつかの接続方式が含まれる。 一般には、片側がPCBにはんだ付けされたピンの列になっており、基板面に対して垂直(「ストレート」と呼ばれる)か、平行(紛らわしいことに「ライトアングル」と呼ばれる)に取り付けられる。 こうしたコネクタにはさまざまなピッチがあり、ピンの列数もいろいろである。

もっともよく見かけるピンヘッダーは、0.1インチ(2.54mm)ピッチの単列または複列のコネクタである。 これは標準的なブレッドボードと互換性のあるピッチであり、オスメスの両方があり、Arduinoボードとシールドをつなぐのもこのタイプのコネクタである。 ブレッドボードへのジャンパー線の接続も簡単に行える。

これ以外のピッチも珍しくなく、たとえばXBee無線モジュールは同じ系統のコネクタの2.0mmピッチ版を使っている。

この部品にはよくある派生形として「マシンピン」版がある。 通常版が金属板を打ち抜いて折り曲げて作られるのに対し、マシンピン版は金属を削り出して成形されるため、より頑丈で接触も良く長寿命になる分、価格も高くなる。

こうしたピンヘッダーに接続するケーブルには、たいてい圧着コネクタ付きの個別の電線か、絶縁貫通接続(IDC)コネクタ付きのリボンケーブルのどちらかが使われる。 IDCコネクタはリボンケーブルの端に単純にクランプするだけで、ケーブル内のすべての導体に接続できる。 一般に、ケーブル側はメスのみで、相手側にオスのピンがある構成が前提になっている。

一時的な接続用のコネクタ

ねじ端子

被覆のない裸の電線を回路に接続したい場合には、ねじ端子が便利である。 複数の異なる機器を切り替えて接続したい場面にも向いている。

ねじ端子の欠点は、比較的簡単に緩んでしまい、裸の電線が回路の中でぶらつく状態になりかねないことである。 少量のホットグルーを使えば、後で外すことにそれほど苦労せずにこれを防げる。

ねじ端子は、対応する電線の太さの範囲が狭いことが多く、細すぎる電線も太すぎる電線も同じくらい問題になりうる。 SparkFunでは2.54mm(0.1インチのブレッドボード標準)、3.5mm、5mm、10mmピッチの4種類のねじ端子を扱っている。

たいていのねじ端子は高い拡張性を持ち、同じピッチの小さな単位をいくつも連結することで簡単に極数を増やせる。

スプリング端子

ねじ端子の代わりとして、スプリング端子(「プッシュイン」「ケージクランプ」「ポークホーム」コネクタとも呼ばれる)がある。 スプリング端子はねじ端子と似た働きをするが、ねじを締めて電線を固定する代わりに、ばねが金属片どうしを挟み込んで固定する。

スプリング端子は、振動の多い環境(自動車用途など)や、温度サイクルによって電線が伸縮するような環境でより優れた性能を発揮する。 また、ユーザーがねじを締める強さにばらつきが出るねじ端子と違い、対応する太さの範囲内であれば、電線の太さに応じて自動的に締め付ける力が調整される。

gamer:bit、LumiDrive、Qwiic MP3 Triggerなど、一部の基板にはI/Oピンへの簡単なアクセス手段としてスプリング端子が搭載されている。 ポークホーム式のコネクタには、ボールペンの先やプラスドライバーでタブを押し下げて配線できるものもある。

バナナコネクタ

たいていの電源系測定機器(テスターや電源装置)には、「バナナジャック」と呼ばれる非常に単純なコネクタが付いている。 これは、圧着式でばねを仕込んだ金属プラグである「バナナプラグ」と組み合わせて使い、単純な電源接続を作るためのものである。 複数を重ねて接続できるスタッカブルタイプも多く、どんな種類の電線にも簡単に接続できる。 数アンペア程度の電流を扱え、安価でもある。

ワニ口クリップ

その見た目からそう呼ばれるワニ口クリップは、端子や裸の電線へのテスト用接続に適している。 かさばりがちで、近くの露出した金属部分と簡単にショートしてしまうこともあり、グリップ力もそれほど強くない。 主にデバッグ中の低コストな接続手段として使われる。

ICクリップ(ICフック)

より繊細な計測作業のために、さまざまなICクリップが市販されている。 これらはICのピンにクリップを挟んでも隣のピンに触れないよう小さく作られており、中には表面実装部品の細かいピッチの足にも挟めるほど精巧なものもある。 ロジックアナライザーテストリードに使われることも多く、試作やトラブルシューティングに重宝する。

その他のコネクタ

RJ型モジュラーコネクタ

レジスタードジャックコネクタは、通信機器を電話局の交換機に接続するための標準的なコネクタである。 一般に「RJ45」「RJ12」などと呼ばれるが、これらの呼び方は必ずしも正確ではなく、RJという記号は、極数、実際に配線されている導体数、配線パターンを組み合わせたものである。 たとえば標準的なイーサネットケーブルの両端は一般に「RJ45」と呼ばれるが、本来のRJ45は8極8導体のモジュラージャックであることに加え、イーサネット用に配線されていることまでを意味する。

こうしたモジュラーコネクタは、入手しやすさ、複数の導体、ある程度の柔軟性、低コスト、そこそこの電流容量を兼ね備えており、非常に便利である。 本来大きな電力を伝送する目的では作られていないが、データと数百ミリアンペア程度の電力を機器間で送るのに使うこともできる。 ただし、こうした用途向けに配線したジャックを通常のイーサネットポートに接続しないよう注意が必要であり、接続すると故障の原因になる。

D-sub型コネクタ

シェルの形状にちなんで名付けられたD-subminiatureコネクタは、コンピュータの世界で古くから使われてきた定番のコネクタである。 DA-15、DB-25、DE-15、DE-9という4種類が特によく使われる。 数字はそのコネクタが持つ接続数を、アルファベットの組み合わせはシェルのサイズを表す。 そのため、DE-15とDE-9は同じシェルサイズだが、接続数は異なる。

ハードウェアをいじる人にとって特に馴染み深いのはDB-25とDE-9である。 今でも多くのデスクトップパソコンには少なくとも1つのDE-9シリアルポートがあり、DB-25パラレルポートを備えていることも多い。 DE-9DB-25のコネクタが付いたケーブルも広く出回っている。 先のモジュラーコネクタと同様、これらを2つの機器間の電源供給や通信に転用することもできるが、本来これらのケーブルの一般的な用途には電源伝送は含まれていないため、標準規格ではない機器を標準ポートに接続すると簡単に故障につながりかねず、転用は慎重に行う必要がある。

まとめ

これで、どのコネクタがどんな用途に適しているか、次のプロジェクトでどのコネクタが役立ちそうか、おおよその見当がついたはずである。 コネクタについてさらに学べる、次のようなチュートリアルもあわせて参照してほしい。

タグ: 部品、入力デバイス、電力、技術


出典:Connector Basics(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

ブレッドボードの使い方

ブレッドボードは、回路を組み立てる方法を学ぶうえで欠かせない道具の1つである。 このチュートリアルでは、ブレッドボードとは何か、なぜ「ブレッドボード(パン切り板)」と呼ばれるのか、そしてその使い方を説明する。 読み終えるころには、ブレッドボードの仕組みが基本的に理解でき、ブレッドボード上で簡単な回路を組み立てられるようになっているはずである。

参考になるチュートリアル:

歴史

1960年代より前に回路を組み立てようとすると、たいていはワイヤーラップという技法が使われていた。 ワイヤーラップは、パーフボード(プロトボードとも呼ばれる)に取り付けた導電性のピンに、被覆を剥いた電線を巻き付けていく方法である。 見てのとおり、この方法はすぐに配線が複雑になってしまう。 今でも使われている技法ではあるが、試作をずっと簡単にしてくれるものがある。 それがブレッドボードである。

「ブレッドボード」という名前の由来

「ブレッドボード」と聞くと、大きな木の板と、焼きたてのパンを思い浮かべるかもしれない。 実際、その想像はそれほど的外れではない。

電子部品がまだ大きくてかさばっていた時代、人々はパンを切るための板(ブレッドボード)と釘や画鋲を手に取り、その板の上に配線をつないで回路を組み立てる土台にしていた。 これが、電子部品の「回路を組み立てる板」を今でもブレッドボードと呼ぶ理由である。

その後、電子部品はずっと小型になり、回路をつなぐより良い方法も登場した。 それでも、この紛らわしい名前だけはそのまま残った。 厳密に言えば、文字通りのパン切り板を使う方法も今なおブレッドボードと呼べるが、このチュートリアルで扱うのは、現代の「はんだ付け不要」なブレッドボードについてである。

なぜブレッドボードを使うのか

電子工作で言う「ブレッドボード」とは、サンドイッチを作るためのまな板ではなく、はんだ付け不要のブレッドボードを指す。 これは一時的な回路や試作を作るのに適した部品であり、はんだ付けを一切必要としない。

プロトタイピング(試作)とは、アイデアを試すために暫定的なモデルを作り、そこから別の形を発展させたり複製したりする作業のことであり、ブレッドボードのもっとも一般的な使い道の1つである。 ある条件のもとで回路がどう動くか確信が持てないときは、まず試作を組んで実際に試してみるのが一番よい。

電子工作や回路を初めて学ぶ人にとって、ブレッドボードはたいてい最良の出発点になる。 単純な回路も複雑な回路も同じように組み立てられる点こそが、ブレッドボードの本当の魅力である。 このチュートリアルの後半で見るように、回路がブレッドボード1枚に収まらなくなったときは、複数のブレッドボードをつなぎ合わせて、どんな規模や複雑さの回路にも対応できる。

ブレッドボードのもう1つのよくある使い道は、IC(集積回路)のような新しい部品を試すことである。 ある部品がどう動作するのかを確かめながら何度も配線を組み替えたいとき、そのたびにはんだ付けをするわけにはいかない。

すでに触れたように、組み立てる回路が常に恒久的なものである必要はない。 SparkFunのテクニカルサポートチームも、顧客から報告された不具合を再現するとき、しばしばブレッドボードを使って回路を組み、テストし、分析している。 顧客の手元にある部品と同じ構成をつなぎ、回路を組んで問題を特定できたら、すべてをばらして片付け、また次のトラブルシューティングが必要になるまでしまっておける。

ブレッドボードの構造

ブレッドボードの仕組みを説明する一番の方法は、実際に分解して中を見てみることである。 小さめのブレッドボードを使うと、その仕組みがより見えやすくなる。

ターミナルストリップ

裏の粘着シートを剥がしたブレッドボードを見ると、裏面に金属の帯が横方向にいくつも並んでいるのがわかる。

金属の帯の上側には小さな金具(クリップ)があり、プラスチックの穴の下に隠れている。 それぞれの金属帯と差し込み穴は、0.1インチ(2.54mm)という規格化された間隔で並んでいる。 このクリップのおかげで、電線や部品の足を穴に差し込むだけで、その場に固定できる。

差し込んだ部品は、その行にある他のどの穴に差し込んだものとも電気的につながる。 これは、金属帯自体が導電性を持ち、帯の中のどの点からも電流が流れられるからである。

この金属帯にはクリップが5つしかないことに気づくだろう。 これはほとんどすべてのブレッドボードに共通する仕様である。 そのため、ブレッドボードの1つの区画には最大5個までしか部品をつなげない。 1行には穴が10個あるのに、なぜ5個までしかつなげないのか。 それは、ブレッドボードの中央に、それぞれの横一列を分断する溝があるからである。 この溝は、同じ行の両側を互いに電気的に切り離している。 その狙いについてはこの後すぐに説明するが、今のところは「同じ行でも溝の両側はつながっていない」ということだけ覚えておけば十分であり、そのため片側には5か所しか部品を差せない。

電源レール

ブレッドボードの中の接続のしくみがわかったところで、より一般的な、少し大きめのブレッドボードを見てみよう。 横方向の行のほかに、ブレッドボードにはたいてい電源レールと呼ばれる帯が、両端に縦方向に走っている。

電源レールは、横方向の帯と同じ金属の帯だが、通常はレール全体がひとつながりになっている点が異なる(製品によっては上下で分かれているものもある。詳しくは後述する)。 回路を組んでいると、電源をいろいろな場所で使いたくなる場面が多い。 電源レールがあれば、回路上のどこからでも簡単に電源へアクセスできる。 たいていの場合、電源レールには「+」と「-」の表示があり、正極側には赤、負極側には青または黒の線が引かれている。

左右の電源レールはそれぞれ独立していて、互いにはつながっていない。 そのため、両側で同じ電源を使いたい場合は、ジャンパー線で両側をつなぐ必要がある。 レールの「+」「-」の表示はあくまで目安であり、必ず「+」レールに電源、「-」レールにグラウンドをつながなければならないという決まりはない。 とはいえ、常にその決まりを守っておくと、後で回路を見返したときにわかりやすい。

DIPパッケージへの対応

先ほど、ブレッドボードの両側を分ける溝について触れた。 この溝には重要な役割がある。 IC(集積回路。単に「チップ」とも呼ばれる)の多くは、ブレッドボードにそのまま差し込めるように設計されている。 ブレッドボード上で場所を取りすぎないよう、これらのICはDIP(Dual In-line Package)と呼ばれる形状で作られている。

DIPパッケージのICは、両側から足が伸びていて、ちょうどあの溝をまたぐ形にぴったり収まる。 ICの各足はそれぞれ役割が異なるため、両側を電気的につなげてしまっては困る。 そこで、ブレッドボード中央の溝が役に立つ。 これにより、ICの反対側の足の働きに影響を与えることなく、両側それぞれに別の部品をつなげられる。

行と列の番号

ブレッドボードの行や列には、数字アルファベットの表示があることに気づくだろう。 これらは回路を組む際の目印以外の役割は持たない。 回路はすぐに複雑になりやすく、部品の足を1本差し間違えただけで、回路全体が誤動作したりまったく動かなくなったりする。 接続したい行の番号がわかっていれば、目分量で位置を探すよりもずっと簡単に、狙った穴へ配線できる。

これらの表示は、SparkFun Inventor’s Kitに付属するような説明書を使うときにも役立つ。 多くの書籍やガイドには回路図が載っており、それを見ながら回路を組み立てていくことになる。 ただし、書籍の回路図とまったく同じ位置にブレッドボード上で配置する必要はない。 それどころか、見た目が似ている必要すらない。 必要な電気的接続さえすべて満たしていれば、回路はどんな配置で組んでもかまわない。

バインディングポスト

ブレッドボードの中には、バインディングポストと呼ばれる接続端子が付いた台に乗っているものもある。 このポストを使うと、さまざまな種類の外部電源をブレッドボードに接続できる。 この点については、次の節でもう少し詳しく説明する。

その他の機能

回路を組むとき、必ずしも1枚のブレッドボードに収める必要はない。 より広いスペースが必要な回路もある。 多くのブレッドボードは側面(ものによっては上下面にも)に小さな突起と溝があり、これによって複数のブレッドボードを連結し、より大きな試作用のスペースを作れる。

裏面に粘着シートが付いていて、さまざまな面に貼り付けられるブレッドボードもある。 自作のケースや筐体の内側にブレッドボードを固定したいときなどに便利である。

Note

大きめのブレッドボードでは、電源レールの上半分と下半分が互いに独立している(左右ではなく上下で分かれている)ことがある。 これは、3.3Vと5Vのように異なる2つの電圧を同時に使いたいときに便利である。 ただし、電源レールが独立しているかどうかを知らずに回路を組むと、思わぬトラブルの原因になることがある。 テスターを使って、電源レールの導通の有無をあらかじめ確認しておくとよい。

ブレッドボードへの電源供給

ブレッドボードに電源を供給する方法にはいくつもの選択肢がある。

他の電源から取る

Arduinoのような開発ボードを使っているなら、Arduinoのメスヘッダーからそのまま電源を取り出せる。 Arduinoには電源ピンとグラウンドピンが複数あり、これをブレッドボードの電源レールや他の行に接続できる。

Arduino自体は、通常パソコンのUSBポートや、バッテリーパック、ACアダプター(ウォールワート)のような外部電源から電力を得ている。

バインディングポスト

前の節で触れたとおり、ブレッドボードによってはバインディングポストが付いていて、外部電源を接続できるようになっている。

バインディングポストを使う最初の一歩は、ジャンパー線を使ってポストをブレッドボードに接続することである。 一見ポストとブレッドボードが最初からつながっているように見えるかもしれないが、実際にはつながっていない。 もしつながっていたら、電源を供給できる場所が限定されてしまう。 ブレッドボードは自由自在に組み替えられることを前提とした部品であり、バインディングポストもその例外ではない。

そこで、ポストとブレッドボードをつなぐには配線が必要になる。 やり方は、ポストのつまみを回して軸に空いた穴を露出させ、被覆を剥いたジャンパー線の先をその穴に通し、ワイヤーがしっかり固定されるまでつまみを締め直せばよい。

たいていの場合、ポストからブレッドボードに接続する必要があるのは電源用とグラウンド用の2本だけである。 別の電源も使いたい場合は、3本目のポストを利用できる。

これでポストとブレッドボードはつながったが、まだ電気は流れていない。 ポスト経由でブレッドボードに電源を供給する方法はいくつもある。

ベンチトップ電源

多くの電子工作の実験室には、幅広い電圧や電流を回路に供給できるベンチトップ電源がある。 バナナコネクタを使えば、この電源からバインディングポストへ給電できる。

もちろん、ワニ口クリップやICフック、あるいはバナナ端子付きの他のケーブルを使って、ブレッドボードをさまざまな電源につなぐこともできる。

バインディングポストのもう1つの使い方として、バレルジャックを電線にはんだ付けし、その電線をバインディングポストに接続する方法もある。 これはやや高度な手法であり、ある程度のはんだ付けの技術が求められる。

ブレッドボード用電源モジュール

ブレッドボードに電源を供給するもう1つの方法として、さまざまなブレッドボード用電源モジュールを使う方法もある。 SparkFunでも、ブレッドボードに直接差し込んで使える電源キットやモジュールを複数扱っている。 ウォールワートを直接差し込めるものもあれば、パソコンのUSBポートから電源を取れるものもある。 そのほとんどが電圧を切り替えられるようになっており、回路を組む際によく使う電圧に幅広く対応できる。

最初の回路をブレッドボードで組む

ブレッドボードの内部構造と電源の供給方法がわかったところで、いよいよ実際に使ってみよう。 まずは簡単な回路から始める。

必要なもの

このチュートリアルの回路で使う部品は、LED、抵抗、ボタン(タクトスイッチ)、ジャンパー線、そしてブレッドボードである。 他にも手持ちの部品があれば、それを使って回路を少し変えてみてもよい。 1つの回路にも、組み方は1通りとは限らない。 中には何十通りもの組み方ができる回路もある。

回路を組む

Note

警告:ブレッドボード用電源スティックを使うときは、GNDピンを「-」側のレールに、VCCピンを「+」側のレールに差し込むように注意すること。 こうすることで、回路に逆極性の電源を加えてしまう事故を防ぎやすくなる。

ここに、ブレッドボード上に組んだ小さな回路がある。 写真に写っている赤い基板は、ヘッダーピンがはんだ付けされたブレッドボード用電源スティックであり、9Vのウォールワートからの電圧を5Vまたは3.3Vに変換して電源レールに供給している。

回路の構成は次のとおりである。

  • VCC側の電源レールと、LEDの正極(アノード)側の足が配線でつながっている。
  • LEDの負極(カソード)側の足は、330Ωの抵抗につながっている。
  • その抵抗は、ボタンへとつながっている。
  • ボタンを押すと回路がグラウンドにつながり、回路が閉じてLEDが点灯する。

回路図

回路図の読み方については別のチュートリアルで扱っているが、回路を組むうえで非常に重要な知識なので、ここでも簡単に触れておく。

回路図は、世界中の誰もが理解し、回路を組み立てられるようにするための共通の記号体系である。 電子部品にはそれぞれ固有の回路図記号があり、これらの記号をさまざまなソフトウェアを使って組み合わせることで回路図ができあがる。 もちろん、手描きで回路図を書いてもかまわない。 電子工作や回路設計の世界にさらに深く踏み込みたいなら、回路図を読めるようになることは非常に重要な一歩である。

上で紹介した回路の回路図を見てみよう。 上部の矢印は電源を表す(スイッチが5V側に切り替わっているとする)。 そこからLED(矢印の出ている三角形と線の記号)へとつながり、LEDは抵抗(ギザギザの線)につながる。 その先はボタン(掛け金のような形の記号)につながり、最後にボタンはグラウンド(下部の水平線)につながっている。

一見すると回路図は奇妙な描き方に見えるかもしれないが、何十年も前から使われてきた基本的な表記法である。 回路図があるおかげで、国籍や言語が異なる人どうしでも、誰かが設計した回路を組み立てたり、共同で開発したりできる。 すでに述べたとおり、1つの回路の組み方には何通りもの方法があるが、この回路図が示すように、必ず満たさなければならない接続関係も存在する。 この回路図から外れた配線をすれば、まったく別の回路になってしまう。

習うより慣れよ

最後に伝えておきたいのは、実際にブレッドボードを使わなくても回路を組めるツールやソフトウェアが数多くあるということである。 SparkFunでよく使われているソフトウェアの1つがFritzingである。 Fritzingは無料のソフトウェアで、仮想的なブレッドボード上で自分の回路を組み立てられる。 組み立てた回路の回路図も自動的に生成してくれる。 先ほどと同じ回路をFritzingで組んだものを見てみよう。

Fritzing以外にも同様のソフトウェアは数多くあり、無料のものも有料のものもある。 中には、組んだ回路をシミュレーションで動作確認できるものもある。 自分に合ったツールを探してみるとよい。

まとめ

ここまでで、ブレッドボードとは何か、どう動作するのかが理解できたはずである。 ここからが本当の面白さの始まりであり、ブレッドボードで回路を組むという世界は、まだほんの入り口に触れたにすぎない。 部品の使い方や、それらをブレッドボード上の回路に組み込む方法について、さらに学べるチュートリアルを以下に挙げる。

回路を組む技術がある程度身についたら、次のレベルとして、次のようなチュートリアルにも挑戦してみてほしい。

タグ: 電気工学、プロトタイピング、スキル


出典:How to Use a Breadboard(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

テスターの使い方

テスター(マルチメーター)は、いったいどう使えばいいのか。 このチュートリアルでは、デジタルマルチメーター(DMM)の使い方を説明する。 これは回路の診断や、他の人が設計した電子回路の理解、さらには電池のチェックにまで使える必須の道具であり、「マルチ(複数の)」「メーター(測定器)」という名前もそこから来ている。

もっとも基本的な測定対象は電圧と電流である。 テスターは、基本的な動作確認やトラブルシューティングにも大いに役立つ。 回路が動かない、スイッチはちゃんと機能しているのか。 そんなときはテスターを当ててみればよい。 テスターは、システムのトラブルシューティングにおける最初の頼みの綱である。 このチュートリアルでは、電圧、電流、抵抗、そして導通の測定方法を扱う。

参考になるチュートリアル:

Note

このチュートリアルではSparkFun VC830Lというテスターを例に説明するが、ここで紹介する方法はほとんどのテスターに当てはまる。

テスターの各部

テスターは3つの部分からできている。

  • 表示部
  • レンジ切り替えつまみ
  • 端子

表示部は、たいてい4桁の数字と、マイナス記号を表示できる。 薄暗い場所でも見やすいよう、バックライト付きの表示部を持つテスターもある。

レンジ切り替えつまみを使うと、電流(ミリアンペア、mA)、電圧(V)、抵抗(Ω)など、測定したい対象を切り替えられる。

2本のプローブを、本体前面にある端子のうち2つに差し込んで使う。 COMは「コモン(共通)」を意味し、ほぼ常に回路のグラウンドや「-」側につなぐ。 COM用のプローブは慣習的に黒色だが、赤いプローブとのあいだに色以外の違いはない。 10Aは、大きな電流(200mAを超えるもの)を測るときに使う特別な端子である。 mAVΩは、赤いプローブを差し込むのが慣習になっている端子であり、電流(200mAまで)、電圧(V)、抵抗(Ω)を測定できる。 プローブの先端にはバナナタイプのコネクタが付いていて、これをテスター本体に差し込む。 バナナプラグのプローブであれば、どんなものでもこのテスターで使え、さまざまな種類のプローブを使い分けられる。

プローブの種類

テスター用のプローブには、さまざまな種類が用意されている。 よく使うものをいくつか紹介する。

  • バナナ - ワニ口クリップ:太い電線やブレッドボードのピンに接続するのに適している。回路を操作しながらプローブを手で押さえておかなくてよいので、長時間のテストに向いている。
  • バナナ - ICフック:小型のICや、ICの足を挟むのに適している。
  • バナナ - ピンセット:SMD部品をテストしたいときに便利である。
  • バナナ - テストプローブ:もしプローブを1本壊してしまっても、安価に交換できる。

電圧を測定する

まずは単3形電池の電圧を測ってみよう。 黒いプローブをCOMに、赤いプローブをmAVΩに差し込む。 テスターを直流(DC)レンジの「2V」に設定する。 携帯型の電子機器のほとんどは、交流ではなく直流で動作している。 黒いプローブを電池のグラウンドまたは「-」側に、赤いプローブを電源または「+」側に当てる。 単3形電池の正極と負極の端子に、軽く力を入れてプローブを押し当てる。 新品の電池であれば、表示部にはおよそ1.5V前後の値が表示されるはずである(この電池は新品なので、電圧は1.5Vより少し高くなっている)。

電池やArduinoにつないだセンサーのような直流電圧を測るときは、まっすぐな線が引かれた「V」の位置につまみを合わせる。 壁のコンセントから来るような交流電圧は危険なので、交流電圧の設定(波線が添えられた「V」)を使う場面はめったにない。 交流を扱う必要があるなら、デジタルマルチメーターよりも非接触式のテスターを使うことをおすすめする。

赤と黒のプローブを入れ替えたらどうなるか。 表示される値の符号が単純に反転するだけであり、何も悪いことは起きない。 テスターは、コモン側のプローブを基準にして電圧を測定する。 電池の「+」側は、コモン(マイナス側のピン)と比べてどれだけ電圧が高いか。 1.5Vである。 プローブを入れ替えると、今度は「+」側がコモン、つまり基準の0点になる。 その新しい基準点と比べて、電池の「-」側の電圧はどうなるか。 -1.5Vになる。

続いて、実際の場面で電圧を測る流れを、簡単な回路で確かめてみよう。 回路は単純で、1kΩの抵抗と青色の高輝度LEDを、SparkFun Breadboard Power Supply Stickで駆動しているだけのものである。 まず、取り組んでいる回路に正しく電源が入っているかを確認する。 回路が5Vであるはずなのに4.5V未満だったり5.5Vを超えていたりしたら、それだけで何かがおかしいとすぐにわかり、電源の接続や配線を確認する必要が出てくる。

つまみをDCレンジの「20V」(直流電圧レンジは、まっすぐな線の「V」で示される)に合わせる。 テスターの多くはオートレンジ式ではないため、測定対象に合ったレンジを自分で選ぶ必要がある。 たとえば2Vレンジは2ボルトまで20Vレンジは20ボルトまで測定できる。 そのため12Vの電池を測るなら20Vレンジを使う。 5V系の回路でも20Vレンジを使う。 レンジの選び方を間違えると、表示が切り替わって「1」と表示されることが多い。

力を少し込めて(焼いた肉にフォークを刺すようなイメージで)、露出した金属部分にプローブを押し当てる。 一方のプローブはGNDの接続部に、もう一方はVCCまたは5Vの接続部に当てる。

回路の別々の部分を測定することもできる。 これは節点解析と呼ばれる手法であり、回路解析の基本的な考え方の1つである。 回路の各部分の電圧を測ることで、それぞれの部品にどれだけの電圧が必要かがわかる。 まずは回路全体を測ってみよう。 抵抗に電圧が入ってくる場所から、LED側のグラウンドまでを測ると、回路全体の電圧、つまりおよそ5V前後が表示されるはずである。

次に、LEDがどれだけの電圧を使っているかも見てみよう。 これは、LEDの電圧降下と呼ばれるものである。 今の時点でピンとこなくても心配はいらない。 電子工作を学び進めるうちに、自然と理解できるようになる。 ここで押さえておくべき重要な点は、回路のさまざまな部分を測定することで、回路全体を分析できるということである。

過負荷(オーバーロード)

測定しようとしている電圧に対して低すぎるレンジを選んだらどうなるか。 悪いことは何も起きない。 テスターは単に「1」と表示する。 これは、テスターが過負荷、つまりレンジ外であることを知らせているサインである。 測定しようとしている値が、そのレンジには大きすぎるということなので、テスターのつまみを1段階上のレンジに変えてみればよい。

レンジ切り替えつまみ

つまみの表示はなぜ10Vではなく20Vになっているのか。 20V未満の電圧を測りたいときは、20Vレンジに合わせる。 これにより、2.00から19.99までの範囲を読み取れる。

多くのテスターでは、表示の最初の桁は「1」しか表示できない。 そのため測定範囲は99.99ではなく19.99までに制限される。 これが、99Vではなく20Vが上限になっている理由である。

Note

警告:基本的には、直流の回路(テスターのつまみでまっすぐな線が引かれている設定)だけを扱うようにすること。 多くのテスターは交流(AC)も測定できるが、交流回路は危険を伴う。 壁のコンセントの交流、いわゆる「主電源電圧」は、うっかり触れるとかなりの衝撃を受けるようなものである。 交流を扱うときは、細心の注意を払うこと。 コンセントに電気が来ているかどうかを確かめたいだけなら、交流用の検電器を使うほうがよい。 交流の電圧を測る必要が出てくるのは、コンセントの様子がおかしいとき(本当に110Vや100Vが来ているのか)や、電熱器のようなヒーターを制御しようとしているときくらいである。 交流回路を測定するときは、慎重に、すべてを二重に確認しながら進めること。

抵抗を測定する

一般的な抵抗器にはカラーコードが記されている。 その読み方がわからなくても心配はいらない。 簡単に使えるオンラインの計算ツールがたくさんある。 それでも、インターネットにつなげない場面では、テスターで実際の抵抗値を測るのが便利である。

適当な抵抗器を1本選び、テスターを20kΩレンジに合わせる。 キーボードのキーを押すのと同じくらいの力加減で、抵抗器の足にプローブを押し当てる。

表示部には、0.001、あるいは実際の抵抗値のいずれかが表示される。

  • 今回の例では0.97と表示されており、これはこの抵抗器の値が970Ω、つまりおよそ1kΩであることを意味する(20kΩ、つまり20,000オームのレンジなので、小数点を右に3桁分ずらして970オームと読む)。
  • テスターが1またはOL表示された場合は過負荷であり、200kΩ2MΩ(メガオーム)といった、より大きなレンジを試す必要がある。これが起きても問題はなく、単にレンジのつまみを調整すればよいだけである。
  • テスターが0.00やそれに近い値を示した場合は、2kΩ200Ωといった、より小さなレンジに切り替える必要がある。

多くの抵抗器には5%の誤差があることを覚えておいてほしい。 つまり、カラーコードが10,000オーム(10kΩ)を示していても、製造工程のばらつきによって、実際の10kΩ抵抗器は9.5kΩから10.5kΩのあいだのどこかになりうる。 心配はいらない、プルアップ用や一般的な用途の抵抗としては、それで十分に機能する。

つまみを1段階下げて2kΩレンジにしてみよう。 どうなるだろうか。 大きな変化はない。 この抵抗器(1kΩ)は2kΩより小さいので、引き続き表示部に値が出る。 ただし、小数点以下の桁が1つ増え、少しだけ細かい値まで読み取れるようになっているはずである。 では、さらに1段階下げるとどうなるか。 1kΩは200Ωより大きいので、今度はレンジの上限を超えてしまい、過負荷であることを示す表示になり、より大きなレンジに戻す必要が出てくる。

経験則として、1オーム未満の抵抗器を見かけることはめったにない。 抵抗の測定は完璧ではないということも覚えておいてほしい。 温度は測定結果に大きく影響する。 また、部品を回路に実装したまま抵抗を測定するのは、なかなか厄介なことも多い。 基板上の周囲の部品が、測定結果に大きな影響を与えることがある。

電流を測定する

組み込み電子工作の世界で、電流の測定はもっとも扱いにくく、それでいてもっとも多くの情報を与えてくれる測定の1つである。 扱いにくい理由は、電流は直列に測定しなければならないからである。 電圧はVCCとGNDに(並列に)プローブを当てるだけで測れるのに対し、電流を測るには実際に電流の流れを物理的に断ち切り、その間にテスターを割り込ませる必要がある。 これを確かめるために、電圧測定の節で使ったのと同じ回路を使う。

まず必要になるのが、もう1本の電線である。 すでに述べたとおり、電流を測るには物理的に回路を断ち切る必要がある。 言い換えると、抵抗につながっているVCCの配線を一度引き抜き、その接続先だった場所に新しい配線を追加し、電源のプラス端子から抵抗までのあいだにテスターを挟み込む。 これにより、回路への電力が実質的に「切断」される。 そのうえでテスターを直列に挿入し、電流がブレッドボードへ「流れ込む」道筋の途中で測定できるようにする。

今回の写真では、簡単のためワニ口クリップを使っている。 電流を測るときは、数秒から数分にわたってシステムの様子を観察したくなることが多い。 その間ずっとプローブを手で押さえておくのは大変なので、両手を空けられるワニ口クリップ付きのプローブが役に立つ。 なお、ほとんどのテスターは同じ大きさの端子(「バナナプラグ」と呼ばれる)を使っているので、いざというときは友人のプローブを借りることもできる。

テスターを接続したら、つまみを適切なレンジに合わせて電流を測定する。 電流の測定も、電圧や抵抗と同じように、正しいレンジを選ぶ必要がある。 テスターを200mAレンジに合わせ、そこから調整していく。 ブレッドボードで作る多くのプロジェクトの消費電流は、たいてい200mA未満である。 赤いプローブが、ヒューズ付きの200mA端子に差し込まれていることを確認する。 今回使っているテスターでは、200mA用の端子は電圧や抵抗の測定と同じ端子(mAVΩという表示のある端子)を兼用している。 つまり、電流、電圧、抵抗のどれを測るときも、赤いプローブは同じ端子に差したままでよい。 ただし、回路が200mAに近い、あるいはそれを超える電流を使いそうな場合は、念のためプローブを10A側に差し替えること。 電流の許容量を超えると、単に過負荷の表示が出るだけでなく、ヒューズが飛んでしまうことがある(この点については後述する)。

このとき、テスター自体が1本の電線のように振る舞っていることに注意してほしい。 これによって回路が完成し、電源が入る。 これが重要なのは、時間の経過とともにLEDやマイコン、センサーなど、測定対象の消費電力が変化することがあるからである(たとえばLEDが点灯した瞬間に消費電流が20mA増え、消灯した瞬間にまた減る、といった具合である)。 テスターの表示部には、その瞬間の電流値が表示されるはずである。 どのテスターも、ある程度の時間にわたる測定値から平均を計算して表示しているため、値は多少ふらつくものだと考えておくとよい。 一般に、安価なテスターほど平均化の効き方が強く、反応も遅いため、表示される値は多少割り引いて見てほしい。 おおまかな範囲、たとえば通常の5V環境で7〜8mA程度、という程度の感覚で捉えておけばよい(7.48mAというような細かい値にこだわらなくてよい)。

他の測定と同じく、電流を測るときもプローブの色は関係ない。 プローブを入れ替えるとどうなるか。 何も悪いことは起きず、単に電流の表示がマイナスになるだけである。 電流自体はシステムの中を変わらず流れ続けており、見ている向きが変わって、表示がマイナスになっただけである。

Note

覚えておいてほしいのは、テスターを使い終わったら、必ず電圧測定モードに戻しておくということである(プローブを電圧用の端子に戻し、必要であれば直流電圧レンジに切り替える)。 2点間の電圧をさっと測ろうとしてテスターを手に取ったとき、電流測定モードのままになっていることはよくある。 その状態では表示部に電圧が出ず、代わりに「0.000」と表示され、VCCとGNDのあいだに電流が流れていないように見えてしまう。 しかしその一瞬のうちに、テスターを介してVCCとGNDを直結してしまっており、200mAのヒューズが飛んでしまう。これはよろしくない。 だから、その日の作業を終えてテスターを置くときは、次に使う人(未来の自分を含む)に優しい状態にしておくことを忘れないようにする。

電流の測定は、最初の数回はうまくいかないことも多い。 ヒューズを飛ばしてしまっても心配はいらない、私たちも何十回とやらかしてきた。 ヒューズの交換方法は、後の「ヒューズを交換する」の節で説明する。

導通を確認する

導通テストとは、2点間の抵抗を調べる操作のことである。 抵抗が非常に低ければ(数Ω未満)、その2点は電気的につながっていると判断され、音が鳴る。 数Ωを超える抵抗があれば回路は開いていると判断され、音は鳴らない。 このテストは、2点間の接続が正しくできているかを確認するのに役立つほか、本来つながっているべきではない2点がつながっていないかを確認するのにも役立つ。

導通テストは、組み込みハードウェアに携わる人にとって、おそらく単一の機能としてはもっとも重要なものである。 この機能を使えば、材料の導電性を調べたり、配線がどこでつながっていて、どこでつながっていないかをたどったりできる。

テスターを「導通」モードに設定する。 DMMの機種によって表示は異なるが、スピーカーから音が伝わっていくような波形が添えられたダイオードの記号を探すとよい。

2本のプローブの先端を触れ合わせてみる。 テスターから音が鳴るはずである(注:すべてのテスターに導通モードがあるわけではないが、たいていのものには備わっている)。 これは、プローブの間にごくわずかな電流が、抵抗なし(あるいは非常に小さな抵抗)で流れられることを示している。

Note

警告:導通を確認するときは、基本的にシステムの電源を切っておくこと。

電源が入っていないブレッドボードで、2本のプローブを別々のグラウンドピンに当ててみる。 つながっていることを示す音が聞こえるはずである。 続いて、マイコンのVCCピンから電源のVCCまでプローブを当ててみる。 VCCピンからマイコンまで電流が自由に流れられることを示す音が鳴るはずである。 音が鳴らなければ、銅箔パターンをたどっていき、配線やブレッドボード、PCBのどこかで断線していないかを確認していける。

導通テストは、2つのSMDピンが接触しているかどうかを確かめるのにも役立つ。 目で見てもわからないときは、たいていテスターが頼りになる2つ目の確認手段になる。

システムが動かないとき、導通テストはトラブルシューティングのもう1つの手がかりになる。 次のような手順を踏むとよい。

  1. システムの電源が入っているなら、電圧レンジでVCCとGNDを慎重に確認し、電圧が正しいレベルになっているかを確かめる。5V系のはずが4.2Vしか出ていない場合は、レギュレータを念入りに確認する。レギュレータが異常に熱くなっていたら、システムが電流を消費しすぎているサインかもしれない。
  2. システムの電源を切り、VCCとGNDのあいだの導通を確認する。導通があれば(音が鳴れば)、どこかにショートがある。
  3. システムの電源を切ったまま、導通テストでVCCとGNDがマイコンや他の部品のピンに正しく配線されているかを確認する。システム全体には電源が入っていても、個々のICの配線が間違っていることもある。
  4. マイコンが動くところまで確認できたら、テスターはいったん脇に置き、シリアル通信でのデバッグや、ロジックアナライザーを使ったデジタル信号の確認に進む。

導通テストと大きなコンデンサ: 通常のトラブルシューティングでは、グラウンドとVCCレールのあいだの導通を確認することが多い。 これは、試作した回路の電源を入れる前に、電源系統にショートがないかを確かめるよい方法である。 ただし、プローブを当てた瞬間に短く「ピッ」と鳴っても驚かないでほしい。 これは、電源系統にはたいてい相応の静電容量が存在しているためである。 テスターは2点間がつながっているかどうかを、非常に低い抵抗を基準に判定している。 コンデンサは、エネルギーが満ちるまでの一瞬だけショートのようにふるまい、満ちた後は開放状態のようにふるまう。 そのため、短く「ピッ」と鳴った後は何も鳴らなくなる。 それでよいのであって、単にコンデンサが充電されているだけである。

ヒューズを交換する

新しくテスターを使い始めた人がやりがちなもっともよくある失敗が、ブレッドボード上でVCCからGNDへ直接プローブを当てて電流を測ろうとすることである(これはよくない)。 これをすると、テスターを介して電源とグラウンドが即座にショートし、ブレッドボードの電源が瞬断してしまう。 テスターに大電流が流れ込むと、内部のヒューズが発熱し、200mAを超える電流が流れることでやがて焼き切れる。 これはほんの一瞬の出来事で、音も物理的な兆候もほとんどないまま起きる。

さて、こうなってしまったらどうすればよいか。 まず、電流の測定は直列に行うものであり、ブレッドボードやマイコンへのVCCラインを一度断ち切って測定するのだということを思い出してほしい。 ヒューズが切れた状態で電流を測ろうとすると、テスターは「0.00」と表示し、テスターをつないだ本来動くはずのシステムも起動しなくなることに気づくはずである。 これは、内部のヒューズが切れて、断線や開放状態と同じようにふるまっているためである。 心配はいらない、これはよくあることであり、修理には1ドルほどしかかからない。

ヒューズを交換するには、使いやすい小型のドライバーを用意し、ねじを外していく。 SparkFunのDMMは比較的簡単に分解できる。 まず電池カバーと電池を取り外す。 次に、電池カバーの下に隠れているねじ2本を外す。 テスターの表面パネルを少し持ち上げる。 パネルの下端にあるツメに注意しながら、少し力を入れてパネルを横にスライドさせ、ツメを外す。 ツメが外れれば、パネルは簡単に取り外せる。 これでテスターの内部が見えるようになる。 ヒューズをそっと持ち上げると、簡単に外れる。

必ず正しい種類のヒューズに交換すること。 つまり、200mAのヒューズは200mAのヒューズと交換する。

Note

警告:200mA用のヒューズの代わりに10A用のヒューズを取り付けてはならない。 ヒューズの配置と、プローブ用端子の配置が必ずしも一致しているとは限らない。 ヒューズ両端の金属キャップに記された表示を確認して、どちらがどちらかを必ず確かめること。

テスター内部の部品や基板のパターンは、それぞれ決まった電流量に耐えるように設計されている。 誤って200mA用の端子に5Aを流してしまうと、テスターを傷め、最悪の場合壊してしまう。

モーターやヒーターのような大電流を扱う部品を測定したい場面もある。 テスター前面には赤いプローブを差す場所が2つあるのに気づいただろうか。 左側の10Aと、右側のmAVΩである。 mAVΩ端子で200mAを超える電流を測ろうとすると、ヒューズを飛ばすリスクがある。 一方、10A端子を使えば、ヒューズを飛ばすリスクはずっと小さくなる。 その代わりに感度が犠牲になる。 先ほど触れたとおり、10A端子とそのレンジ設定では、0.01A(10mA)までしか読み取れない。 たいていのシステムは10mAを超える電流を使うので、10Aのレンジと端子で十分間に合うことが多い。 非常に小さな電力(マイクロアンペアやナノアンペアの単位)を測りたいなら、200mA端子で2mA、200µA、20µAといったレンジを使うとよい。

覚えておいてほしい: システムが100mAを超える電流を使う可能性があるなら、まず赤いプローブを10A端子に差し、10Aレンジから測定を始めるとよい。

50ドル以下のデジタルテスターで得られる測定値は、あくまでトラブルシューティング用の目安であり、厳密な科学実験の結果ではない。 ICが時間とともにどう電流や電圧を使うかを本格的に調べたいなら、AgilentのようなメーカーのハイエンドなベンチトップDMMを使うとよい。 こうした機器は精度が高く、いろいろと凝った機能も備えている。

良いテスターの条件

好みは人それぞれだが、一般的には導通テスト機能があるテスターが好まれる。 それ以外の機能は、いわばおまけのようなものである。

オートレンジ機能を持つ、凝ったテスターもある。 これは、測定対象の電圧、抵抗、電流に応じて、内部のレンジを自動的に切り替えてくれる機能である。 使い方さえわかっていれば、オートレンジは非常に便利である。 一般に、オートレンジ機能を持つテスターは品質も高く、機能も豊富な傾向がある。 もしオートレンジ付きのテスターを誰かからもらったら、ぜひ活用してほしい。 ただし、手動モードへの切り替え方も覚えておくこと。 回路の電圧や電流はかなり素早く変動することがあり、システムによっては変動が激しすぎて、オートレンジがうまく追従できないこともある。

バックライト付きの液晶は見栄えがよいが、暗闇の中で回路を測定したことは最近あっただろうか。 たいていは、真夜中に測定が必要になるような不気味な状況は避けたいものだが、暗い場所でも使えるテスターが欲しい、必要だという人もいるだろう。

レンジ切り替えつまみの心地よいクリック感も、個人的には大きなポイントだと思っている。 つまみの感触が柔らかすぎるテスターは、たいてい安っぽい作りであることが多い。

しっかりしたプローブも長所の1つである。 時間が経つと、リード線は曲げる部分から傷んでいきやすい。 プローブから配線がすっぽ抜けてしまうこともあり、しかもそれはたいてい、まさにそのプローブが必要な瞬間に起きる。 プローブが壊れても、比較的安価に交換できる

オートパワーオフは、安価なテスターにはあまり見られない、うれしい機能である。 夜中の2時にテスターの電源を切り忘れるのはよくあることなので、初心者にも上級者にも役立つ機能である。 SparkFunのデジタルテスターにはこの機能はないが、幸い消費電力が非常に少ないテスターであり、丸2日間つけっぱなしにしても9V電池がようやく弱ってくる程度で済んだこともある。 とはいえ、テスターの電源を切り忘れないようにしたい。

これで、身の回りのさまざまなものをデジタルテスターで測定する準備が整った。 気になる疑問があれば、遠慮なくテスターで確かめてみてほしい。 このLEDには本当に20mA流れているのか。 レモンにはどれくらいの電圧があるのか。 コップ一杯の水は電気を通すのか。 配線の代わりにアルミホイルを使えるのか。 デジタルテスターは、こうした電子工作にまつわる数々の疑問に答えてくれる。

まとめ

デジタルテスターの基本的な使い方が身についたところで、その技術を活かせる次のチュートリアルにも挑戦してみてほしい。

タグ: 電気工学、スキル、プロジェクトを始める、ツール


出典:How to Use a Multimeter(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

電力

なぜ電力を気にする必要があるのか。 電力とはエネルギーが変換される速さの尺度であり、エネルギーにはお金がかかる。 電池はただでは手に入らないし、コンセントから得られる電気もそうである。 つまり電力は、財布からどれだけの速さでお金が出ていっているかを測っているとも言える。

エネルギーは、熱、放射線、音、原子力など、さまざまな形をとり、その一部は人体に害を及ぼしうる。 電力が大きいほど、扱うエネルギーも大きくなる。 そのため、電子工作をするときは、自分がどれくらいの電力を扱っているのかを把握しておくことが重要である。 幸い、Arduinoで遊んだり、LEDを光らせたり、小さなモーターを回したりする程度であれば、電力を見誤ったとしても、抵抗を焦がすかICを溶かす程度で済むことが多い。

このチュートリアルで扱う内容:

  • 電力の定義
  • 電気エネルギーが変換される例
  • 電力のSI単位であるワット
  • 電圧、電流、抵抗を使った電力の計算
  • 最大定格電力

参考になるチュートリアル:

電力とは何か

このチュートリアルでは、電気の力、つまり電力に絞って説明する。

一般的な物理の言葉で言えば、電力とはエネルギーが変換(あるいは移動)する速さとして定義される。

では、エネルギーとは何であり、どのように移動するのか。 簡潔に言い表すのは難しいが、エネルギーとは基本的に、何かが別の何か動かす能力のことである。 エネルギーには、力学的、電気的、化学的、電磁的、熱的など、さまざまな形がある。

エネルギーは決して生み出されたり消えたりすることはなく、ただ別の形に変換されるだけである。 電子工作でしていることの多くは、さまざまな形のエネルギーを電気エネルギーとの間で変換することである。 LEDを光らせることは電気エネルギーを電磁エネルギーに変え、モーターを回すことは電気エネルギーを力学的エネルギーに変える。 ブザーを鳴らせば音のエネルギーが生まれ、9Vのアルカリ電池で回路を動かせば化学エネルギーが電気エネルギーに変わる。 これらはすべてエネルギーの変換の一種である。

変換されるエネルギーの種類変換する部品
力学的エネルギーモーター
電磁エネルギーLED
熱エネルギー抵抗器
化学エネルギー電池
風のエネルギー風車

電気エネルギーは、もとをたどれば電気的な位置エネルギー、つまり親しみを込めて電圧と呼んでいるものから始まる。 その位置エネルギーの中を電子が流れると、それが電気エネルギーに変わる。 実用的な回路のほとんどでは、その電気エネルギーがさらに別の形のエネルギーへと変換される。 電力は、どれだけの量の電気エネルギーがどれだけ速く移動しているかを組み合わせて測られる。

電力の生産者と消費者

回路の中のそれぞれの部品は、電気エネルギーを消費するか生産するかのどちらかである。 消費する部品は、電気エネルギーを別の形に変換する。 たとえばLEDが光るとき、電気エネルギーは電磁エネルギーに変換されており、この場合LEDは電力を消費している。 逆に、他の形のエネルギーから電気エネルギーへの変換が起きるとき、電力は生産されている。 回路に電力を供給する電池は、電力の生産者の一例である。

ワット数

エネルギーはジュール(J)という単位で測られる。 電力はある決まった時間あたりのエネルギー量を表すので、1秒あたりのジュール数として測れる。 1秒あたりのジュール数を表すSI単位がワット(記号 W)である。

\[ 1,\text{W} = 1,\text{J/s} \]

「ワット」という単位には、標準的なSI接頭辞が付くことがよくある。 マイクロワット(µW)、ミリワット(mW)、キロワット(kW)、メガワット(MW)、ギガワット(GW)などが、場面に応じてよく使われる。

接頭辞名接頭辞記号倍率
ナノワットnW10⁻⁹
マイクロワットµW10⁻⁶
ミリワットmW10⁻³
ワットW10⁰
キロワットkW10³
メガワットMW10⁶
ギガワットGW10⁹

Arduinoのようなマイコンは、たいていµWからmWの範囲で動作する。 ノートパソコンやデスクトップパソコンは、標準的なワットの範囲で動作する。 一般家庭の電力消費は、たいていキロワットの範囲になる。 大きなスタジアムはメガワットの規模になることもある。 そしてギガワットは、大規模な発電所やタイムマシンの世界の話になる。

電力を計算する

電力とはエネルギーが移動する速さであり、1秒あたりのジュール数(J/s)、つまりワット(W)で測られる。 電気に関する基本的な用語を踏まえると、回路の中の電力はどう計算できるだろうか。 位置エネルギーを表す標準的な量であるボルト(V)は、電荷1単位(クーロン)あたりのジュール数(J/C)として定義されている。 もう1つの電気の基本用語である電流は、電荷の流れる速さをアンペア(A)、つまり1秒あたりのクーロン数(C/s)で表す。 この2つを掛け合わせると、電力が得られる。

\[ \text{V} \times \text{A} = \left(\frac{\text{J}}{\text{C}}\right) \times \left(\frac{\text{C}}{\text{s}}\right) = \text{J/s} = \text{W} \]

回路の中のある部品の電力を計算するには、その部品にかかる電圧降下と、そこを流れる電流を掛け合わせればよい。

\[ P = V \times I \]

下に示すのは、9Vの電池を10Ωの抵抗につないだだけの、単純な(実用的とは言えない)回路である。

抵抗にかかる電力はどう計算すればよいか。 まず、そこを流れる電流を求める必要がある。 これは簡単で、オームの法則を使えばよい。

\[ I = \frac{V}{R} = \frac{9,\text{V}}{10,\Omega} = 0.9,\text{A} \]

これで、抵抗には900mA(0.9A)の電流が流れ、9Vの電圧がかかっていることがわかった。 このとき、抵抗にはどれだけの電力がかかっているか。

\[ P = V \times I = 9,\text{V} \times 0.9,\text{A} = 8.1,\text{W} \]

抵抗は電気エネルギーを熱に変換する部品である。 つまりこの回路は、1秒ごとに8.1ジュールの電気エネルギーを熱に変換していることになる。

抵抗性回路の電力を計算する

純粋に抵抗だけの回路であれば、電圧、電流、抵抗の3つのうち2つさえわかれば電力を計算できる。

オームの法則(V = IR、あるいは I = V/R)をこれまでの電力の式に代入すると、2つの新しい式が得られる。 1つ目は、電圧と抵抗だけで表したものである。

\[ P = \frac{V^2}{R} \]

先ほどの例で言えば、9²/10(V²/R)は8.1Wであり、抵抗を流れる電流をあらためて計算する必要はない。

2つ目の式は、電流と抵抗だけで表したものである。

\[ P = I^2 \times R \]

抵抗にかかる電力を気にする理由は何か。 他の部品についても同じことが言える。 電力とは、あるエネルギーが別の種類のエネルギーへ変換される速さであることを思い出してほしい。 電源から流れてきた電気エネルギーが抵抗に達すると、そのエネルギーは熱に変換される。 場合によっては、その抵抗が処理しきれないほどの熱になることもある。 そこで重要になってくるのが、定格電力である。

定格電力

すべての電子部品は、あるエネルギーを別の種類のエネルギーに変換している。 LEDが光を放つ、モーターが回る、電池が充電されるといった変換は、望ましいものである。 一方で、望ましくない、しかし避けられないエネルギー変換もある。 こうした望ましくないエネルギーの変換は電力損失と呼ばれ、たいていは熱として現れる。 電力損失が大きすぎる、つまり部品の発熱が大きすぎると、それは非常に望ましくない事態になりうる。

エネルギーの変換自体が部品の主目的である場合でも、他の形のエネルギーへの損失は必ず生じる。 たとえばLEDやモーターも、目的の変換とは別に、副産物として熱を発生させる。

ほとんどの部品には、放散できる最大の電力についての定格が定められており、その値を超えないように動作させることが重要である。 そうすることで、いわゆる「魔法の煙を逃がしてしまう」事態を避けられる。

抵抗器の定格電力

抵抗器は、電力損失の代表格ともいえる部品である。 抵抗器に電圧をかけると、そこには必ず電流が流れる。 電圧が高いほど電流も大きくなり、電流が大きいほど電力も大きくなる。

先ほどの電力計算の例を思い出してほしい。 9Vを10Ωの抵抗にかけると、その抵抗は8.1Wを消費することになる。 8.1Wというのは、たいていの抵抗器にとって非常に大きな値である。 一般的な抵抗器の定格は⅛W(0.125W)から½W(0.5W)程度であり、標準的な½W抵抗器に8Wをかけようものなら、消火器を用意しておいたほうがよい。

大きな電力を扱えるように作られた抵抗器もあり、これは特にパワー抵抗器と呼ばれる。

抵抗値を選ぶときは、定格電力にも気を配る必要がある。 何かを温めることが目的(ヒーターの発熱体は、実質的に非常に高出力の抵抗器である)でない限り、抵抗器での電力損失はできるだけ小さく抑えるようにしたい。

抵抗器の定格電力は、LEDの電流制限抵抗の値を決めるときにも関わってくる。 たとえば、10mmの超高輝度赤色LEDを9Vの電池で最大の明るさで光らせたいとする。

このLEDの最大順方向電流は80mA、順方向電圧はおよそ2.2Vである。 LEDに80mAを流すには、85Ωの抵抗が必要になる。

抵抗には6.8Vがかかり、そこに80mAが流れるということは、抵抗での電力損失は0.544W(6.8V×0.08A)になる。 これは½Wの抵抗にとってはあまり嬉しくない値である。 溶けることはなくても、かなり熱くなるはずである。 安全のため、1Wの抵抗に切り替えるとよい(あるいは、電力を節約したいなら専用のLEDドライバを使うという手もある)。

最大定格電力を考慮すべきなのは抵抗器だけではない。 何らかの抵抗成分を持つ部品はすべて、熱による電力損失を生む。 電圧レギュレータ、ダイオード、増幅回路、モータードライバなど、大きな電力にさらされることの多い部品を扱うときは、電力損失と熱によるストレスに特に注意を払う必要がある。

まとめ

電力という概念について理解できたところで、関連するチュートリアルにも目を通してみてほしい。

  • プロジェクトへの電源供給:電力とは何かはもうわかった。では、それをどうやってプロジェクトに届けるのか。
  • :光は電気工学者にとって役立つ道具である。光と電子工学の関係を理解することは、多くのプロジェクトに欠かせないスキルである。
  • Arduinoとは何か:このチュートリアルでもArduinoについて何度も触れた。まだよくわからない場合は、このチュートリアルを確認してほしい。
  • ダイオード:交流を直流に変換する場合でも、単に電源インジケータ用のLEDを光らせる場合でも、ダイオードはプロジェクトに電力を供給するうえで特に便利な部品である。
  • 抵抗器:もっとも基本的な電子部品であり、ほぼすべての回路に欠かせない。

タグ: 概念、電気工学、LED、物理学、電力


出典:Electric Power(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

極性

電子工作の世界では、極性とは、回路部品が対称であるかどうかを表す性質である。 極性を持たない部品、つまり極性のない部品は、どちら向きにつないでも本来の働きをする。 対称な部品はたいてい端子が2本以下で、その部品のどの端子も互いに等価である。 極性のない部品はどちら向きにつないでも同じように機能する。

極性を持つ部品、つまり極性のある部品は、回路に対して決まった1つの向きでしかつなげない。 極性を持つ部品には、2本のこともあれば、20本、200本の端子があることもあり、それぞれの端子には固有の役割や位置がある。 極性を持つ部品を回路に間違った向きでつなぐと、よくても意図したとおりに動かないだけで済むが、最悪の場合、その部品は煙を上げ、火花を散らし、完全に壊れてしまう。

極性は非常に重要な概念であり、特に実際に回路を組み立てる場面で重要になる。 ブレッドボードに部品を差し込むときも、PCBにはんだ付けするときも、E-テキスタイルの作品に部品を縫い込むときも、極性を持つ部品を見分け、正しい向きで接続できることが欠かせない。 このチュートリアルでは、どの部品に極性があってどの部品にはないのか、部品の極性をどう見分けるのか、そしていくつかの部品について実際に極性をテストする方法を説明する。

参考になるチュートリアル:

ダイオードとLEDの極性

Note

ここでは、回路内の正の電荷を基準とした電流の向き(いわゆる「慣用電流」)を使って説明する。

ダイオードは一方向にしか電流を流さない部品であり、常に極性を持つ。 ダイオードには2つの端子があり、正極側はアノード、負極側はカソードと呼ばれる。

ダイオードを流れる電流は、アノードからカソードへの方向にしか流れない。 これが、ダイオードを正しい向きでつなぐことが重要な理由である。 物理的には、どのダイオードにもアノードかカソードのどちらかを示す目印が必ずついている。 たいていはカソード側の端子付近に線が入っており、これはダイオードの回路記号に描かれている縦線と対応している。

以下にいくつかダイオードの例を示す。 上にある1N4001整流ダイオードは、カソード側に灰色のリングがある。 その下の1N4148信号用ダイオードは、黒いリングでカソードを示している。 一番下には表面実装型のダイオードが2つあり、それぞれ線でカソード側のピンを示している。

LED

LEDは発光ダイオードの略であり、その名のとおりダイオードの仲間なので、やはり極性を持つ。 LEDの正極と負極のピンを見分ける方法はいくつかある。 足の長いほうを探すという方法があり、これはたいてい正極(アノード)側のピンを示している。

もし誰かが足を切りそろえてしまっていたら、LEDの外装にある平らな部分を探すとよい。 平らな面に近いほうのピンが、負極(カソード)側のピンになる。

これら以外の目印がある場合もある。 SMDタイプのダイオードには、アノードとカソードを示すさまざまな表記方法がある。 テスター(マルチメーター)を使って極性を調べるのがもっとも簡単な場合も多い。 テスターをダイオードモード(たいていダイオードの記号で示されている)に切り替え、それぞれのプローブをLEDの端子に当ててみる。 LEDが点灯すれば、プラス側のプローブがアノードに、マイナス側のプローブがカソードに触れていることになる。 点灯しなければ、プローブを入れ替えて試してみればよい。

極性を持つ部品は、ダイオードだけではない。 間違った向きにつなぐと動作しない部品は他にもたくさんある。 次は、集積回路をはじめとする、他のよくある極性を持つ部品について見ていこう。

集積回路の極性

集積回路(IC)には8本のピンのものもあれば80本のピンのものもあり、それぞれのピンには固有の役割と位置がある。 ICでは極性をきちんと守ることが非常に重要である。 間違った向きにつなぐと、煙を上げて溶け、壊れてしまう可能性が高い。

スルーホール型のICは、たいていDIP(デュアルインラインパッケージ)と呼ばれる、ブレッドボードの中央をまたげるように0.1インチ間隔で2列に並んだピン配置になっている。 DIPタイプのICには、多数あるピンのうちどれが1番ピンかを示す切り欠きがあることが多い。 切り欠きがない場合は、ケースの1番ピン付近に刻印された丸い印があることもある。

どのICパッケージでも、1番ピンから反時計回りに進むにつれてピン番号が順に増えていく。

表面実装型のICには、QFN、SOIC、SSOPなど、さまざまな形状のパッケージがある。 これらのICでは、たいてい1番ピンの近くに丸い印がついている。

電解コンデンサ

コンデンサのすべてが極性を持つわけではないが、極性を持つコンデンサでは、その極性を間違えないことが非常に重要である。

セラミックコンデンサ(1µF以下の小さな、たいてい黄色い部品)は極性を持たない。 どちら向きに差し込んでもかまわない。

小さな缶のような見た目をした電解コンデンサ(電解液を使っていることに由来する名前である)は極性を持つ。 コンデンサの負極側のピンは、たいてい**「-」の表示や、缶に沿ったカラーストライプで示されている。 正極側の足のほうが長く**なっていることもある。

以下は10µF(左)と1mFの電解コンデンサで、どちらも負極側の足に「-」の表示があり、正極側の足のほうが長くなっている。

電解コンデンサに長時間逆向きの電圧をかけ続けると、短くも派手な、そして致命的な故障を引き起こす。 「ポン」という音とともに、コンデンサの上部が膨らむか、破裂する。 そうなったコンデンサは二度と使い物にならず、ショート回路のようにふるまうようになる。

その他の極性を持つ部品

電池と電源

回路の極性を正しく保つことは、結局のところ電源を正しく接続することに尽きる。 プロジェクトの電源がACアダプターであれ、リポ電池であれ、うっかり逆向きに接続して、-9Vや-4.2Vをプロジェクトに加えてしまわないよう注意することが重要である。

電池を交換したことのある人なら、その極性の見分け方はよく知っているだろう。 たいていの電池は、「+」または「-」の記号で正極と負極の端子を示している。 赤い線が正極、黒い線が負極を表していることもある。

電源には、たいてい標準化されたコネクタが使われており、そのコネクタ自体にも極性があることが多い。 たとえばバレルジャックには内側と外側の2つの導体があり、内側(中心)の導体がたいてい正極側になる。 JSTのような一部のコネクタは、逆向きには差し込めないようキー溝の形で作られている。

逆接続に対する追加の保護として、ダイオードやMOSFETを使った逆接保護回路を追加することもできる。

トランジスタ、MOSFET、電圧レギュレータ

これらは(伝統的には)3端子の極性を持つ部品であり、パッケージの形状が似ているためひとまとめに扱われることが多い。 スルーホール型のトランジスタやMOSFET、電圧レギュレータは、たいていTO-92やTO-220というパッケージで提供される。 どのピンが何かを知るには、TO-92パッケージの平らな面や、TO-220パッケージの金属製の放熱板を目印にし、データシートのピン配置図と照らし合わせる。

その他

ここまでで紹介したのは、極性を持つ部品のほんの一部にすぎない。 抵抗器のように本来極性を持たない部品でも、極性を持つパッケージに入っていることがある。 5個程度の抵抗器があらかじめまとめられた抵抗アレイは、その一例である。

幸い、極性を持つ部品には、どのピンが何かを教えてくれる何らかの目印が必ず用意されている。 必ずデータシートを確認し、ケースについている丸印やその他の目印もあわせてチェックするようにしたい。

まとめ

極性とは何か、そしてそれをどう見分けるかがわかったところで、関連するチュートリアルにも目を通してみてほしい。

  • コネクタの基礎:コネクタの中にも、それ自体が極性を持つものが数多くある。電源やその他の信号を逆向きに加えてしまわないようにする、優れた手段になっていることが多い。
  • ダイオード:部品の極性を語るうえでの代表例である。このチュートリアルでは、ダイオードの動作原理や種類についてさらに詳しく扱っている。
  • LilyPadデザインキット実験1:回路はブレッドボードや基板の上だけに存在するわけではなく、シャツなどの布に縫い込むこともできる。LilyPadデザインキットのチュートリアルで始め方を確認してほしい。LEDを正しく配線するうえで、極性の知識が大いに役立つ。

タグ: 概念、電気工学


出典:Polarity(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

分圧回路

分圧回路は、大きな電圧を小さな電圧に変換する単純な回路である。 直列につないだ2本の抵抗と入力電圧だけを使って、入力電圧のある割合にあたる出力電圧を作り出せる。 分圧回路は、電子工作でもっとも基本的な回路の1つである。 オームの法則を学ぶことがアルファベットを覚えるようなものだとすれば、分圧回路を学ぶことは、それを使って「catネコ」という単語を綴れるようになるようなものである。

このチュートリアルで扱う内容:

  • 分圧回路がどのような見た目をしているか
  • 出力電圧が、入力電圧と2本の抵抗によってどう決まるか
  • 実際の分圧回路がどうふるまうか
  • 分圧回路の実践的な応用例

参考になるチュートリアル:

理想的な分圧回路

分圧回路には、重要な要素が2つある。 回路そのものと、その式である。

回路

分圧回路は、直列につないだ2本の抵抗に電源電圧をかけるだけの回路である。 描き方はいくつかあるが、どれも本質的には同じ回路になる。

入力電圧(Vin)に近いほうの抵抗をR1、グラウンドに近いほうの抵抗をR2と呼ぶことにする。 R2にかかる電圧降下をVoutと呼び、これがこの回路の目的である「分圧された電圧」にあたる。

回路の構成はこれだけである。 Voutが、私たちの求める分圧された電圧であり、これが入力電圧のある割合になる。

分圧回路の式では、上の回路にある3つの値、つまり入力電圧(Vin)と2本の抵抗値(R1とR2)がわかっていることを前提とする。 これらの値がわかれば、次の式で出力電圧(Vout)を求められる。

\[ V_{out} = V_{in} \times \frac{R_2}{R_1 + R_2} \]

この式は覚えておくとよい。 この式は、出力電圧が入力電圧R1とR2の比正比例することを示している。 この式がどこから導かれるのか気になる場合は、このチュートリアルの末尾にある導出の節を参照してほしい。 ただし今は、まずこの式をそのまま覚えてしまってかまわない。

簡略化した見方

分圧回路を扱ううえで覚えておくと便利な、いくつかの一般化されたパターンがある。 これらは、分圧回路をぱっと評価するのに役立つ簡略化である。

まず、R1とR2が等しい場合、出力電圧は入力電圧のちょうど半分になる。 これは抵抗の実際の値に関係なく常に成り立つ。

R2がR1よりもはるかに大きい(少なくとも1桁以上大きい)場合、出力電圧は入力電圧にかなり近くなる。 このときR1にかかる電圧はごくわずかになる。

逆に、R2がR1よりはるかに小さい場合、出力電圧は入力電圧に比べてごくわずかになる。 入力電圧のほとんどはR1にかかることになる。

応用例

分圧回路には無数の応用があり、電気工学者が使うもっとも一般的な回路の1つである。 ここでは、分圧回路が使われている代表的な場面をいくつか紹介する。

ポテンショメータ

ポテンショメータは、調整可能な分圧回路を作るのに使える可変抵抗器である。

ポットの内部には1本の抵抗体と、それを2つに分けて動く「ワイパー」があり、ワイパーを動かすことで両側の抵抗の比を調整できる。 外部にはたいてい3本のピンがあり、2本は抵抗体の両端に、残る1本はワイパーにつながっている。

外側の2つのピンを電源につなぐと(片方をグラウンドに、もう片方をVinに)、中央のピンの出力(Vout)は分圧回路と同じようにふるまう。 ポットを一方向いっぱいに回すと出力電圧はゼロに近づき、反対方向に回すと出力電圧は入力電圧に近づく。 ワイパーが中央の位置にあるときは、出力電圧は入力電圧のちょうど半分になる。

ポテンショメータにはさまざまなパッケージがあり、それ自体にも多くの応用がある。 基準電圧を作る、ラジオの選局を調整する、ジョイスティックで位置を測るなど、可変の入力電圧が必要なあらゆる場面で使われている。

抵抗性センサーを読み取る

現実世界のセンサーの多くは、単純な抵抗性の部品である。 フォトセルは、感知した光の量に応じて抵抗値が変わる可変抵抗器である。 フレックスセンサー感圧抵抗(FSR)サーミスタなども同様に可変抵抗器の一種である。

マイコン(少なくともアナログ-デジタル変換器、ADCを備えたもの)にとって、電圧はとても測りやすい量である。 しかし抵抗はそう簡単には測れない。 そこで、このような抵抗性センサーにもう1本抵抗を追加して分圧回路を作れば、その出力電圧を測ることで、逆算してセンサーの抵抗値を求められる。

たとえばフォトセルの抵抗値は、明るい場所では1kΩ程度、暗い場所では10kΩ程度まで変化する。 これに、ちょうど中間くらいの固定抵抗(たとえば5.6kΩ)を組み合わせると、この分圧回路から広い範囲の出力が得られる。

明るさR2(センサー)R1(固定)比 R2/(R1+R2)Vout
明るい1kΩ5.6kΩ0.150.76V
薄暗い7kΩ5.6kΩ0.562.78V
暗い10kΩ5.6kΩ0.673.21V

明るいときと暗いときで、およそ2.45Vの変化幅になる。 たいていのADCにとっては、十分な分解能である。

レベルシフト

より複雑なセンサーになると、UARTSPII2Cのような、本格的なシリアルインターフェースで測定値を送ってくることがある。 こうしたセンサーの多くは、消費電力を抑えるために比較的低い電圧で動作する。 しかし、そうした低電圧のセンサーが、より高い電源電圧で動作するマイコンとやり取りする場面も少なくない。 これがレベルシフトの問題であり、その解決策の1つが分圧回路である。

たとえばADXL345加速度センサーの最大入力電圧は3.3Vなので、これを(5Vで動作する)Arduinoとやり取りさせるには、5Vの信号を3.3Vまで落とす必要がある。 ここで分圧回路の出番である。 5Vの信号をおよそ3.3Vまで分圧できる比率の抵抗を2本用意するだけでよい。 こうした用途には、1kΩから10kΩ程度の範囲の抵抗がよく使われる。

ただし、この方法は一方向にしか使えない点に注意してほしい。 分圧回路だけでは、低い電圧を高い電圧に昇圧することはできない。

やってはいけない使い方

12Vの電源を5Vに落とすために分圧回路を使いたくなるかもしれないが、分圧回路を負荷への電力供給に使ってはならない

負荷が必要とする電流は、そのままR1にも流れることになる。 R1にかかる電流と電圧は電力を生み、それは熱として放出される。 その電力が抵抗の定格(たいてい⅛Wから1W程度)を超えると、発熱が深刻な問題になり、かわいそうな抵抗器を溶かしてしまいかねない。

その効率の悪さについては言うまでもない。 基本的に、ある程度以上の電力を必要とするものへの電源供給に、分圧回路を使うべきではない。 電圧を落として電源として使いたい場合は、電圧レギュレータやスイッチング電源を検討してほしい。

補足:式の導出

分圧回路についてもっと知りたいなら、ここでオームの法則から分圧回路の式がどう導かれるのかを見ていこう。 これは分圧回路の使い方を理解するうえで必須ではないが、興味があれば、オームの法則と代数を使った小さな演習として楽しんでほしい。

Voutの電圧を測りたいとする。 オームの法則を使って、この電圧を求める式をどう組み立てればよいか。 Vin、R1、R2の値がわかっているとして、Voutをこれらの値で表す式を求めてみよう。

まず、回路に流れる電流I1とI2(それぞれの抵抗を流れる電流)を書き出すところから始める。

Voutを計算するのが目標なので、この電圧にオームの法則を適用してみよう。 関わる抵抗と電流はそれぞれ1つずつなので簡単である。

\[ V_{out} = I_2 \times R_2 \]

R2の値はわかっているが、I2はどうか。 これは未知の値だが、少しだけ手がかりがある。 I1はI2に等しいと仮定できる(これは実は大きな仮定である)。 これで何がわかるだろうか。 ひとまずこの点は保留しておこう。 これで回路は、I1とI2をどちらもIとして表せる、次のような形になる。

\[ V_{out} = I \times R_2 \]

Vinについては何がわかっているか。 Vinは、直列につながれたR1とR2の両方にかかる電圧である。 直列の抵抗は足し合わされるので、次のように言える。

\[ V_{in} = I \times (R_1 + R_2) \]

これは、オームの法則のもっとも基本的な形、Vin = I × Rにほかならない。 ここで RR1 + R2 に戻すと、次のように書ける。

\[ I = \frac{V_{in}}{R_1 + R_2} \]

そしてIはI2に等しいので、これを先ほどのVoutの式に代入すると、

\[ V_{out} = V_{in} \times \frac{R_2}{R_1 + R_2} \]

これが、分圧回路の式である。 出力電圧は入力電圧のある割合になっており、その割合はR2をR1とR2の和で割ったものである。

まとめ

電子工作でもっともよく使われる回路の1つの要点をつかんだところで、さらに学べることはまだたくさんある。

Arduinoのようなマイコンが、分圧回路の作るアナログ電圧をどう読み取るのか知りたくないだろうか。

分圧回路とADCの組み合わせは、電子工作の世界で多くのことを可能にしてくれる。 次のようなチュートリアルもあわせて参照してほしい。

  • 加速度センサージャイロセンサーの一部にはアナログ出力のものがあり、使える値として読み取るにはADCが必要になる。
  • パルス幅変調は、アナログ入力とは逆の、いわばアナログ出力に相当する仕組みである。
  • INA169のようなICを使うと、ADCで電流を検出できる。
  • 分圧回路とADCを組み合わせれば、トリムポットやジョイスティック、スライダー、感圧抵抗など、さまざまなセンサーや可変部品を読み取れる。
  • Arduinoの map() 関数は、ADCの値を別の範囲に変換してくれる。
  • 電池残量警告インジケーターの製作例では、分圧回路を使って電池の電圧低下を知らせている。

タグ: 概念、電気工学


出典:Voltage Dividers(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

プルアップ抵抗

プルアップ抵抗は、マイコン(MCU)やその他のデジタルロジック機器を使うときによく登場する部品である。 このチュートリアルでは、プルアップ抵抗をいつ、どこで使うのかを説明し、そのうえで簡単な計算を通じて、なぜプルアップ抵抗が重要なのかを見ていく。

参考になるチュートリアル:

プルアップ抵抗とは何か

あるMCUに、入力として設定した1本のピンがあるとする。 そのピンに何も接続されていないとき、プログラムがそのピンの状態を読み取ったら、ハイ(VCCに引かれた状態)になるか、ロー(グラウンドに引かれた状態)になるか。 これはどちらとも判断がつかない。 この現象は*フローティング(浮遊)*と呼ばれる。 この不確定な状態を防ぐために、プルアップ抵抗やプルダウン抵抗を使うと、わずかな電流しか消費せずに、ピンの状態をハイかローのどちらかに確定させられる。

(ここでは、プルダウンよりも一般的なプルアップに絞って説明する。両者は同じ考え方で動作し、違いはプルアップ抵抗が高い電圧側(たいてい3.3Vか5Vで、VCCと呼ばれることが多い)につながり、プルダウン抵抗がグラウンド側につながる点だけである。)

プルアップは、ボタンやスイッチと組み合わせて使われることが多い。

プルアップ抵抗があると、ボタンが押されていないとき、入力ピンはハイの状態を読み取る。 言い換えると、VCCから入力ピンへ向けてわずかな電流が流れており(グラウンドへは流れない)、入力ピンの電圧はVCCに近い値になる。 ボタンが押されると、入力ピンは直接グラウンドにつながる。 電流は抵抗を通ってグラウンドへ流れ、入力ピンはローの状態を読み取る。 もしこの抵抗がなければ、ボタンを押した瞬間にVCCとグラウンドが直結してしまい、これは非常によくない状態、いわゆるショートになってしまう。

では、どの程度の抵抗値を選べばよいのか。

手短に言えば、プルアップにはおよそ10kΩ程度の抵抗値を選ぶとよい。

抵抗値が低いプルアップは「強い(strong)」プルアップと呼ばれ(流れる電流が多い)、抵抗値が高いプルアップは「弱い(weak)」プルアップと呼ばれる(流れる電流が少ない)。

プルアップ抵抗の値は、次の2つの条件を満たすように選ぶ必要がある。

  1. ボタンが押されているとき、入力ピンはローに引かれる。このとき抵抗R1の値が、VCCからボタンを通ってグラウンドへ流れる電流の量を左右する。
  2. ボタンが押されていないとき、入力ピンはハイに引かれる。このときプルアップ抵抗の値が、入力ピンにかかる電圧を左右する。

条件1については、抵抗値をあまり低くしすぎたくない。 抵抗が低いほど、ボタンを押したときに消費される電力が大きくなる。 一般には大きめの抵抗値(10kΩ程度)が望ましいが、条件2と矛盾しない範囲にとどめる必要もある。 4MΩの抵抗をプルアップに使うこと自体は可能かもしれないが、抵抗値が大きすぎる(弱すぎる)ため、常に期待どおりに機能するとは限らない。

条件2についての一般的な目安は、プルアップ抵抗(R1)の値を、入力ピンの入力インピーダンス(R2)の10分の1程度に抑えることである。 マイコンの入力ピンのインピーダンスは、100kΩから1MΩ程度まで幅がある。 ここで言う「インピーダンス」は、単に「抵抗」を難しく言い換えたものだと考えてよく、上の図のR2にあたる。 つまり、ボタンが押されていないとき、VCCからR1を通って入力ピンへごくわずかな電流が流れる。 プルアップ抵抗R1と入力ピンのインピーダンスR2は電圧を分圧しており、この電圧が、入力ピンがハイと判定されるのに十分な高さになっている必要がある。

たとえば、プルアップR1に1MΩの抵抗を使い、入力ピンのインピーダンスR2もおよそ1MΩ程度だとすると(この2つで分圧回路を作ることになる)、入力ピンの電圧はVCCのおよそ半分になり、マイコンはそのピンをハイの状態として認識できないかもしれない。 5V系のシステムで、入力ピンの電圧が2.5Vだったら、MCUはそれをどう読み取るだろうか。 ハイなのかローなのか。 MCU自身にもわからず、ハイと読み取られることもローと読み取られることもありうる。 R1に10kΩから100kΩ程度の抵抗を使えば、こうした問題の多くは避けられる。

プルアップ抵抗は非常によく必要とされる部品であるため、Arduinoプラットフォームで使われるATmega328のような多くのマイコンには、有効化と無効化ができる内蔵プルアップが備わっている。 Arduinoで内蔵プルアップを有効にするには、setup() 関数の中で次のようなコードを書けばよい。

pinMode(5, INPUT_PULLUP); // ピン5の内蔵プルアップ抵抗を有効にする

もう1つ触れておきたいのは、プルアップの抵抗値が大きいほど、そのピンが電圧の変化に反応する速さが遅くなるという点である。 これは、入力ピンにつながっているシステムが、実質的にコンデンサとして働き、プルアップ抵抗と組み合わさってRCフィルタを形成するためであり、RCフィルタには充放電に一定の時間がかかる。 USBのように非常に速く変化する信号を扱う場合、大きな値のプルアップ抵抗は、ピンの状態が確実に切り替わる速さを制限してしまうことがある。 USBの信号線でよく1kΩから4.7kΩ程度の抵抗が使われているのは、このためである。

こうしたさまざまな要素が絡み合って、どの値のプルアップ抵抗を使うべきかが決まる。

プルアップ抵抗の値を計算する

上の回路(Vcc = 5V)で、ボタンを押したときの電流をおよそ1mAに制限したいとする。 どの抵抗値を使えばよいか。

オームの法則を使えば、プルアップ抵抗の値は簡単に計算できる。

\[ V = I \times R \]

上の回路図に当てはめると、オームの法則は次のようになる。

\[ 5\text{V} = 0.001\text{A} \times R \]

これを簡単な代数で抵抗について解くと、

\[ R = \frac{5\text{V}}{0.001\text{A}} = 5{,}000,\Omega \]

単位をすべてボルト、アンペア、オームに揃えてから計算することを忘れないようにする(たとえば1mAは0.001アンペアである)。 答えは、5kΩの抵抗を使えばよいということになる。

まとめ

これで、プルアップ抵抗が何であり、どう動作するかがわかったはずである。 電子部品とその応用についてさらに学びたいなら、次のチュートリアルもおすすめである。

タグ: 概念、電気工学


出典:Pull-up Resistors(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

交流と直流の違い

オーストラリアのロックバンドAC/DCのバンド名の由来をご存じだろうか。 もちろん、交流(Alternating Current)と直流(Direct Current)である。 ACとDCはどちらも、回路内の電流の流れ方を表す言葉である。 直流(DC)では、電荷(電流)は一方向にしか流れない。 一方、交流(AC)の電荷は周期的に向きを変える。 電流の向きが変わるため、交流回路の電圧も周期的に反転する。

自分で作るデジタル電子工作の多くは直流を使うことになるが、交流の概念も理解しておくことが重要である。 たいていの住宅は交流で配線されているため、プロジェクトをコンセントに接続したい場合は交流を直流に変換する必要がある。 また交流には、単一の部品(変圧器)だけで電圧のレベルを変換できるという便利な性質があり、これが長距離の送電に交流が採用されてきた理由でもある。

このチュートリアルで扱う内容:

  • 交流と直流の歴史的背景
  • 交流と直流を発生させるさまざまな方法
  • 交流と直流の応用例

参考になるチュートリアル:

交流(AC)

交流とは、周期的に向きを変える電荷の流れのことである。 その結果、電圧のレベルも電流と一緒に反転する。 交流は住宅やオフィスビルなどへの電力供給に使われている。

交流の発生

交流は「オルタネータ」と呼ばれる装置を使って発生させることができる。 これは交流を発生させるために設計された、特殊な発電機の一種である。

磁場の中でコイル状の配線を回転させると、その配線に沿って電流が誘導される。 配線を回転させる動力源には、風力タービン、蒸気タービン、水流などさまざまなものがありうる。 配線が回転するたびに磁極が周期的に切り替わるため、配線上の電圧と電流も交互に入れ替わる。

交流の発生は、電圧の水の例えとも比較できる。

一組の水道管で交流を作り出すには、水を管の中で前後に動かすピストンに機械式のクランクを接続する(これが私たちの「交流」にあたる)。 管の途中にある狭くなった部分は、水の流れる向きに関係なく抵抗として働き続けることに注目してほしい。

波形

交流には、電圧と電流が交互に変化する限り、さまざまな形がありうる。 交流回路にオシロスコープをつなぎ、電圧を時間の関数としてグラフにすると、いろいろな波形が見えてくる。 もっとも一般的な交流の形は正弦波である。 たいていの住宅やオフィスの交流電圧は、正弦波を描くように振動している。

このほかによく見られる交流の形として、矩形波と三角波がある。

矩形波は、デジタル回路やスイッチング回路の動作テストによく使われる。

三角波は音響合成の分野で見られ、アンプのようなリニア回路のテストに役立つ。

正弦波を数式で表す

交流の波形を数学的な言葉で表したいことがよくある。 ここでは、よく使われる正弦波を例に見ていこう。 正弦波には振幅、周波数、位相という3つの要素がある。

電圧だけに注目すると、正弦波は次のような数式で表せる。

V(t) は時間の関数としての電圧を表しており、時間が変化するにつれて電圧も変化することを意味する。 イコールの右側の式は、電圧が時間とともにどのように変化するかを表している。

VP振幅である。 これは、正弦波が正負どちらの方向にも到達しうる最大電圧を表しており、電圧は+VPボルト、-VPボルト、あるいはその間のどこかの値を取りうる。

**sin()**関数は、電圧が周期的な正弦波の形、つまり0Vを中心とした滑らかな振動になることを示している。

は、周波数の単位をサイクル(ヘルツ)から角周波数(ラジアン毎秒)に変換するための定数である。

fは正弦波の周波数を表す。 これはヘルツ、つまり1秒あたりの回数として与えられる。 周波数は、ある波形(この場合は正弦波の1サイクル、つまり1回の上昇と下降)が1秒間に何回起こるかを示している。

tは独立変数である時間(秒単位)を表す。 時間が変化するにつれて、波形も変化する。

φは正弦波の位相を表す。 位相は、波形が時間に対してどれだけずれているかを示す指標である。 たいてい0度から360度の間の数値として、度単位で与えられる。 正弦波は周期的な性質を持つため、波形を360度ずらしても、0度ずらした場合と同じ波形になる。 簡単にするため、このチュートリアルの残りの部分では位相を0度と仮定する。

身近な例として、コンセントから得られる電力の波形を見てみよう。 アメリカ合衆国では、家庭に供給される電力は交流であり、ゼロからピークまでの電圧(振幅)はおよそ170V、周波数は60Hzである。 これらの数値を先ほどの式に当てはめると(位相は0度と仮定する)、次のようになる。

この式は、手元のグラフ電卓や、Desmosのような無料のオンライングラフ作成ツールを使ってグラフにできる(式の中で“v“の代わりに“y“を使う必要がある場合もある)。

予想どおり、電圧は周期的に170Vまで上昇し、-170Vまで下降していることが分かる。 また、正弦波は1秒間に60サイクル発生している。 コンセントの電圧をオシロスコープで測定すればこのような波形が見られるはずだが、警告:コンセントの電圧をオシロスコープで測定してはいけない。機器を破損する可能性が高い。

注記: アメリカの交流電圧は120Vだと聞いたことがあるかもしれないが、これも正しい。 なぜだろうか。 交流について語るとき(電圧が絶えず変化するため)、平均値や実効値を使うほうが扱いやすいことが多い。 そのために使われるのが二乗平均平方根(RMS)と呼ばれる方法である。 電力を計算したいときには、交流のRMS値を使うと便利なことが多い。 先ほどの例では電圧が-170Vから170Vの間で変動していたが、その実効値(RMS)は120Vになる。

応用例

家庭やオフィスのコンセントは、ほぼ必ず交流である。 これは、交流を長距離にわたって発生させ、送電するのが比較的容易だからである。 高い電圧(110kVを超える程度)で送電すると、電力の送電時の損失が少なくなる。 電圧が高いほど電流は少なくて済み、電流が少ないほど、電線の抵抗によって発生する熱も少なくなる。 交流は変圧器を使うことで、高電圧との間で容易に変換できる。

交流はまた、電動モーターを動かす力にもなる。 モーターと発電機はまったく同じ装置であり、モーターは電気エネルギーを機械エネルギーに変換する(モーターの軸を回すと、端子に電圧が発生する)。 これは食器洗い機や冷蔵庫など、交流で動く多くの大型家電にとって便利な性質である。

直流(DC)

直流は、交流に比べて理解しやすい。 前後に振動する代わりに、直流は一定の電圧または電流を供給する。

直流の発生

直流は、次のようないくつかの方法で発生させることができる。

  • 整流子と呼ばれる装置を備えた交流発電機を使う方法
  • 整流器と呼ばれる、交流を直流に変換する装置を使う方法
  • 電池を使う方法。電池内部の化学反応によって直流が発生する

再び水の例えを使うと、直流は先端にホースが付いた水タンクによく似ている。

このタンクは、ホースから出ていく一方向にしか水を押し出せない。 直流を発生させる電池と同じように、タンクが空になれば、もう水は管を流れなくなる。

直流を数式で表す

直流は「単方向」の電流の流れとして定義される。つまり、電流は一方向にしか流れない。 流れる向きさえ変わらなければ、電圧や電流は時間とともに変化してもよい。 話を単純にするため、ここでは電圧が一定であると仮定しよう。 たとえば単3形電池が1.5Vを供給すると仮定すると、これは次のような数式で表せる。

これを時間についてグラフにすると、一定の電圧が見えてくる。

これは何を意味するのだろうか。 たいていの直流電源は、時間が経っても一定の電圧を供給し続けると考えてよいということである。 実際には、電池は徐々に電荷を失っていくため、使用するにつれて電圧は下がっていく。 とはいえ、たいていの目的においては、電圧は一定だと仮定してよい。

応用例

SparkFunで販売されているほぼすべての電子工作プロジェクトや部品は、直流で動作する。 電池で動くもの、ACアダプタを使ってコンセントに差し込むもの、USBケーブルで給電するものは、いずれも直流に依存している。 直流で動作する電子機器の例としては、次のようなものがある。

  • 携帯電話
  • LilyPadを使ったダイスガントレットのようなウェアラブルプロジェクト
  • 薄型テレビ(交流がテレビに入り、内部で直流に変換される)
  • 懐中電灯
  • ハイブリッド車や電気自動車

電流戦争

現在ではほぼすべての住宅や事業所が交流で配線されているが、これは一夜にして決まったことではない。 1880年代後半、アメリカ合衆国とヨーロッパ各地でさまざまな発明が生まれ、交流と直流の配電方式をめぐる本格的な争いへと発展していった。

1886年、ブダペストの電気会社ガンツ・ワークスは、ローマ全域に交流で電力を供給した。 一方、トーマス・エジソンは1887年までにアメリカ国内に121の直流発電所を建設していた。 この争いの転機となったのは、翌年、ピッツバーグの著名な実業家ジョージ・ウェスティングハウスが、ニコラ・テスラが持つ交流モーターと交流送電の特許を買い取ったことである。

交流対直流

トーマス・エジソン

1800年代後半、直流は高電圧への変換が容易ではなかった。 そのためエジソンは、個々の近隣地区や市街地に電力を供給する、小規模で地域密着型の発電所からなるシステムを提案した。 電力は発電所から3本の電線、すなわち+110ボルト、0ボルト、-110ボルトを使って配電された。 照明やモーターは、+110Vまたは-110Vのソケットと0V(中性線)の間に接続することができた。 110Vという電圧は、発電所から負荷(住宅やオフィスなど)までの間である程度の電圧降下が起きることを見込んだ値だった。

送電線での電圧降下は考慮に入れられていたものの、発電所は利用者から1マイル以内に設置する必要があった。 この制約により、農村地域での電力供給は非常に困難、あるいは事実上不可能だった。

人物説明
ニコラ・テスラ交流モーターと交流送電の特許を持っていた発明家
ジョージ・ウェスティングハウステスラの特許を買い取り、交流配電システムの実用化を進めた実業家

テスラの特許を得たウェスティングハウスは、交流配電システムの完成に取り組んだ。 変圧器を使えば、交流の電圧を数千ボルトまで安価に昇圧し、また使いやすいレベルまで降圧することができた。 電圧が高いほど、同じ電力をより少ない電流で送電できるため、送電線の抵抗による電力損失も少なくなった。 その結果、大規模な発電所を遠く離れた場所に設置しても、より多くの人々や建物に電力を供給できるようになった。

エジソンによる印象操作

その後の数年間、エジソンはアメリカ国内で交流の使用を思いとどまらせるための運動を展開した。 これには州議会への働きかけや、交流に関する誤った情報の流布も含まれていた。 エジソンはまた、交流が直流よりも危険であることを示そうとして、複数の技術者に動物を公開の場で交流によって感電死させるよう指示した。 その危険性を示す試みとして、エジソンの部下だったハロルド・P・ブラウンとアーサー・ケネリーは、ニューヨーク州のために交流を使った初の電気椅子を設計した。

交流の台頭

1891年、ドイツのフランクフルトで国際電気技術博覧会が開催され、三相交流による初の長距離送電が披露された。 この送電は博覧会場の照明やモーターに電力を供給するものだった。 後にゼネラル・エレクトリックとなる会社の代表者数名もこの場に立ち会い、その展示に大いに感銘を受けた。 翌年、ゼネラル・エレクトリックが設立され、交流技術への投資を始めた。

ナイアガラの滝にあるエドワード・ディーン・アダムズ発電所(1896年)

ウェスティングハウスは1893年、ナイアガラの滝の水力を利用する水力発電ダムを建設し、バッファローまで交流を送電する契約を勝ち取った。 このプロジェクトは1896年11月16日に完成し、交流電力がバッファローの産業を支えるようになった。 この出来事は、アメリカにおける直流の衰退を象徴する出来事となった。 ヨーロッパでは220〜240ボルトかつ50Hzの交流規格が採用される一方、北米では120ボルトかつ60Hzが標準となった。

高圧直流送電(HVDC)

スイスの技術者ルネ・チュリーは、1880年代に一連の電動発電機を使い、長距離にわたって直流電力を送電できる高圧直流システムを考案した。 しかし、チュリー式システムはコストと保守の負担が大きく、HVDCはその後ほぼ1世紀にわたって採用されることがなかった。

1970年代に半導体電子工学が発明されたことで、交流と直流の間を経済的に変換することが可能になった。 専用の設備を使えば、高圧の直流電力(800kVに達するものもある)を発生させられるようになった。 ヨーロッパの一部地域では、さまざまな国を電気的に接続するためにHVDC送電線の導入が進められている。

HVDC送電線は、非常に長距離にわたって送電する場合、同等の交流送電線よりも損失が少ない。 さらに、HVDCは異なる交流方式(たとえば50Hzと60Hz)どうしを接続することも可能にする。 こうした利点がある一方で、HVDCシステムは一般的な交流システムに比べてコストが高く、信頼性の面でも劣る。

結局のところ、エジソン、テスラ、ウェスティングハウスの願いはそれぞれかなえられたと言えるかもしれない。 交流と直流は共存し、それぞれの役割を果たしている。

まとめ

これで、交流と直流の違いについて十分に理解できたはずである。 交流は電圧レベルの変換が容易であり、高電圧送電をより現実的なものにしている。 一方、直流はほぼすべての電子機器の中に見られる。 この2つはあまり相性がよくないため、たいていの電子機器をコンセントに接続したいなら、交流を直流に変換する必要があることも覚えておこう。 ここまで理解できれば、交流を含むより複雑な回路や概念にも取り組む準備が整ったはずである。

さらに電子工作の世界を深く学びたいなら、次のチュートリアルも確認してみてほしい。

タグ: 概念、電気工学、電力


出典:Alternating Current (AC) vs. Direct Current (DC)(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

アナログとデジタルの違い

私たちはアナログな世界に生きている。 ものを塗る色は無限に存在し(たとえ私たちの目にはその違いが分からなくても)、耳にできる音色も無限にあり、嗅ぐことができる匂いも無限にある。 これらのアナログな信号すべてに共通しているのは、その無限の可能性である。

デジタルの信号や物体は、離散的あるいは有限の領域を扱う。 つまり、取りうる値の集合が限られているということである。 それは2通りだけのこともあれば、255通り、4,294,967,296通りということもあるが、いずれにせよ∞(無限)ではない。

電子工作に取り組むということは、アナログとデジタル両方の信号、入力、出力を扱うということでもある。 私たちの電子工作プロジェクトは、何らかの形で現実のアナログな世界とやり取りしなければならないが、たいていのマイクロプロセッサやコンピュータ、論理回路は純粋にデジタルな部品である。 この2種類の信号は、いわば異なる電子的な「言語」のようなものであり、両方の言語を話せるバイリンガルな部品もあれば、どちらか一方しか理解できない部品もある。

このチュートリアルでは、デジタル信号とアナログ信号それぞれの基本を、具体例を交えて紹介する。 また、アナログ回路とデジタル回路、そしてそれぞれに使われる部品についても解説する。

アナログとデジタルという概念そのものは独立した話題であり、それほど多くの電子工学の予備知識を必要としない。 とはいえ、まだ読んでいなければ、次のチュートリアルにも目を通しておくとよい。

参考になるチュートリアル:

あわせて、グラフの読み方や、有限集合と無限集合の違いといった数学的な概念も役に立つ。

アナログ信号

信号とは何か

先に進む前に、信号とは何か、特に電子的な信号について少し説明しておこう(交通信号や、伝説のパワートリオによるアルバム、あるいは一般的な意味でのコミュニケーション手段とは区別してほしい)。 ここで言う信号とは、何らかの情報を伝える時間とともに変化する「量」のことである。 電気工学において、時間とともに変化するその「量」とは、たいてい電圧である(電圧でなければ、たいてい電流である)。 つまり信号について語るときは、時間とともに変化する電圧のことだと考えればよい。

信号は、情報を送受信するために機器と機器の間でやり取りされる。 その情報は映像であったり、音声であったり、何らかの形で符号化されたデータであったりする。 信号はたいてい配線を通じて伝送されるが、無線周波数(RF)の電波として空中を伝わることもある。 たとえば音声信号はパソコンのオーディオカードとスピーカーの間でやり取りされ、データ信号はタブレットとWiFiルーターの間を空中を通じてやり取りされる。

アナログ信号のグラフ

信号は時間とともに変化するため、横軸(x軸)に時間を、縦軸(y軸)に電圧を取ってグラフにすると分かりやすい。 信号のグラフを見れば、それがアナログかデジタルかを見分けるのはたいてい簡単である。 アナログ信号の時間対電圧のグラフは、滑らか連続的になるはずである。

これらの信号は最大値と最小値の範囲に収まっていることが多いが、その範囲の中には依然として無限の値がありうる。 たとえば、コンセントから得られるアナログ電圧は-120Vから+120Vの間に収まっているかもしれないが、分解能を上げていけばいくほど、その信号が実際に取りうる値は無限に存在することが分かる(64.4V、64.42V、64.424Vというように、精度を上げるほど無限に細かい値がありうる)。

アナログ信号の例

映像や音声の伝送には、アナログ信号が使われることが多い。 たとえば古いRCAジャックから出てくるコンポジット映像信号は、たいてい0V〜1.073Vの範囲で符号化されたアナログ信号である。 信号のわずかな変化が、映像の色や位置に大きな影響を与える。

純粋な音声信号もアナログである。 マイクから出てくる信号は、さまざまなアナログの周波数と倍音成分に満ちており、それらが組み合わさって美しい音楽を作り出している。

デジタル信号

デジタル信号は、取りうる値の集合が有限でなければならない。 その集合に含まれる値の数は、2個からとても大きいがそれでも無限ではないある数までの間で、いくらでもありうる。 もっとも一般的なデジタル信号は、たとえば0Vか5Vかというように2通りの値のどちらかを取る。 このような信号のタイミング図は矩形波のような形になる。

あるいは、デジタル信号がアナログ波形を離散的に表現したものであることもある。 遠くから見ると、下の波形は滑らかでアナログのように見えるかもしれないが、近づいてよく見ると、信号が値を近似しようとする小さな離散的な階段状の段差があることが分かる。

これが、アナログ波形とデジタル波形の大きな違いである。 アナログ波形は滑らかで連続的だが、デジタル波形は段階的で、矩形状で、離散的である。

デジタル信号の例

すべての音声や映像の信号がアナログというわけではない。 映像(および音声)用のHDMIや、音声用のMIDII2SAC’97といった標準規格は、いずれもデジタルで伝送される。

集積回路どうしの通信の多くもデジタルである。 シリアル通信、I2C、SPIといったインターフェースは、いずれも符号化された矩形波の連続としてデータを伝送する。

アナログ回路とデジタル回路

アナログ電子回路

抵抗器、コンデンサ、インダクタ、ダイオード、トランジスタ、オペアンプといった基本的な電子部品のほとんどは、本質的にアナログである。 これらの部品だけを組み合わせて作られた回路は、たいていアナログ回路になる。

アナログ回路は、多数の部品を使った非常に洗練された設計になることもあれば、2つの抵抗器を組み合わせただけの分圧回路のように、とても単純なこともある。 とはいえ全般的に、アナログ回路は同じ仕事をデジタルで実現する回路に比べて設計がはるかに難しい。 アナログのラジオ受信機やアナログの電池充電器を設計するには、特別な才能を持つアナログ回路の達人が必要になる。デジタル部品を使えば、こうした設計ははるかに簡単になる。

アナログ回路は、たいていノイズ(電圧の小さく望ましくない変動)の影響を受けやすい。 アナログ信号の電圧レベルのわずかな変化が、処理の過程で大きな誤差を生むことがある。

デジタル電子回路

デジタル回路は、離散的なデジタル信号を使って動作する。 これらの回路はたいてい、トランジスタと論理ゲートの組み合わせでできており、より高いレベルではマイクロコントローラやその他の演算チップで構成される。 パソコンに搭載されているような大きく高性能なプロセッサであれ、小さなマイクロコントローラであれ、たいていのプロセッサはデジタルの領域で動作している。

デジタル回路は、デジタル信号を送るために2進数方式を使うのが一般的である。 このような方式では、2つの異なる電圧をそれぞれ異なるロジックレベルに割り当てる。高い電圧(たいてい5V、3.3V、1.8Vなど)が一方の値を、低い電圧(たいてい0V)がもう一方の値を表す。

デジタル回路は一般に設計しやすいが、同じ仕事をするアナログ回路に比べてコストがやや高くなる傾向がある。

アナログとデジタルの組み合わせ

1つの回路の中にアナログとデジタルの部品が混在しているのは、決して珍しいことではない。 マイクロコントローラはたいていデジタルの塊のような存在だが、アナログ回路とやり取りするための内部回路を備えていることが多い(アナログ-デジタル変換器、パルス幅変調、デジタル-アナログ変換器など)。 アナログ-デジタル変換器(ADC)を使えば、マイクロコントローラはフォトセルや温度センサーのようなアナログセンサーと接続し、アナログ電圧を読み取ることができる。 それほど一般的ではないが、デジタル-アナログ変換器を使えば、マイクロコントローラがアナログ電圧を出力することもでき、これは音を鳴らしたいときなどに便利である。

まとめ

これでアナログ信号とデジタル信号の違いが分かったところで、アナログ-デジタル変換のチュートリアルも確認してみることをおすすめする。 マイクロコントローラや、およそ論理を扱う電子機器全般を扱うということは、たいていの場合デジタルの領域で作業するということでもある。 光や温度を感知したい場合や、マイクロコントローラをさまざまなアナログセンサーと組み合わせたい場合は、そのセンサーが出力するアナログ電圧をデジタルの値に変換する方法を知っておく必要がある。

また、パルス幅変調(PWM)のチュートリアルを読んでみるのもおすすめである。 PWMは、マイクロコントローラがデジタル信号をアナログ信号であるかのように見せかけるために使う仕組みである。

デジタルインターフェースを深く扱う話題としては、次のようなものがある。

一方、アナログの世界をさらに深く知りたいなら、次のチュートリアルも確認してみてほしい。

タグ: 概念、電気工学


出典:Analog vs. Digital(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

2進数

心の準備をしてほしい。 数というごく単純なものについて、これまで当たり前だと思っていた認識が覆されることになる。 これまでの人生では、「100個」のものと言われたら、次のような量を思い浮かべていたはずである。

しかし実際には、次のような量を意味していたのかもしれない。

いや、心配しなくていい。 これは何かの錯覚や思考実験ではなく、単に基数という考え方の違いにすぎない。 あなたはたった今、2進数の世界に足を踏み入れ、基数の異なる数体系に出会ったのである。

数体系と基数

数体系とは、数を表現するための方法である。 私たちは小学校のころからずっと10進数という数体系の心地よい枠組みの中で過ごしてきたが、数体系には他にも数多くの種類がある。 2進数、8進数、16進数、20進数など、基数の異なる数体系は無数に存在するが、電気工学において特に重要なものはそのうちごく一部である。

とりわけよく使われる数体系には、それぞれ固有の名前が付いている。 たとえば10進数はdecimal(10進法)と呼ばれる。 今回取り上げる2進数はbinary(2進法)と呼ばれ、もうひとつよく使われる16進数はhexadecimal(16進法)と呼ばれる。

数の基数は、値の末尾に小さく添えた整数(下付き文字)で表されることが多い。 先ほどの例で言えば、最初の画像は実際には「100₁₀」個であり、2番目の画像は「100₂」個ということになる。 基数を明示することで、値の解釈があいまいになるのを防げる。

なぜ2進数を使うのか

なぜ2進数なのか、と疑問に思うかもしれないが、それを言うならなぜ10進数なのだろうか。 私たちはずっと10進数を使い続けてきたため、日常生活で10進数を採用した理由についてはあまり深く考えたことがないはずである。 指が10本あるからかもしれないし、あるいは古代ローマ人がその属州にこの数え方を強制したからかもしれない。 理由が何であれ、これまでに身につけてきたさまざまな工夫によって、10進数は私たちの生活にしっかりと根付いている。 誰もが10ずつ数えることができるし、大きな数を10の倍数に丸めることさえする。 私たちは10という数にすっかり夢中なのである。

一方、コンピュータや電子機器には指も足の指もない。 もっとも基本的なレベルでは、これらは何かの状態をたった2通りの方法でしか表現できない。 オンかオフか、ハイかローか、1か0かである。 そのため、ほぼすべての電子機器は、数を保存し、操作し、計算するために2進数、つまり基数2の数体系に依存している。

電子機器がこれほど2進数に依存しているということは、2進数の仕組みを理解しておくことが重要だということでもある。 コンピュータプログラムのいたるところで、2進数やその親戚である16進数に出会うことになる。 デジタルロジック回路や、その他の非常に低レベルな電子回路の解析にも、2進数の知識が大いに役立つ。

このチュートリアルでは、10進数に対して行えることは、2進数に対しても行えるということが分かるはずである。 中には2進数のほうが簡単な演算もあれば(他方で面倒になる演算もあるが)、そういったことも含めてこのチュートリアルで扱っていく。

このチュートリアルは、かなり抽象的な概念にまで踏み込んでいく。 内容の多くは、足し算、掛け算、割り算(余りを含む)、指数といった数学的な概念の上に成り立っている。

電子工作の予備知識は必要ない(ほとんどの人がすでに知っている10進数の仕組みを理解していれば十分である)が、このチュートリアルではArduinoのプログラミングにおける2進数の使われ方にも触れるため、データ型についての知識があると役立つ場面がある。 また、デジタルロジックの知識があると、2進数についての理解をさらに深めるのに役立つ。

数え方と変換

各数体系の基数はradix(基数)とも呼ばれる。 10進数の基数は10であり、2進数の基数は2である。 基数によって、その数体系を成り立たせるために必要な記号の種類の数が決まる。 10進数では、0個からちょうど10個未満までの値を表すために、0、1、2、3、4、5、6、7、8、9という10種類の数字表記を使う。 これらの記号はそれぞれ、非常に明確で標準化された値を表している。

2進数で使える記号はたった2種類、0と1だけである。 しかしこの2種類の記号だけを使って、10進数で表せるどんな数でも作り出すことができる。

2進数での数え方

10進数であれば、眠っていてもできるほど際限なく数えられるが、2進数ではどう数えればよいだろうか。 2進数における0と1は、見慣れた0と1そのままである。 そこから先が、いよいよ2進数らしくなってくる。

使える数字が2種類しかないため、10進数のときと同じように、使える記号を使い果たしたら1桁左にずれ、そこに1を加えて、それより右側の桁はすべて0に戻す必要がある。 つまり1の次は10になり、次に11、そして100になる。 実際に数えてみよう。

10進数2進数10進数2進数
001610000
111710001
2101810010
3111910011
41002010100
51012110101
61102210110
71112310111
810002411000
910012511001
1010102611010
1110112711011
1211002811100
1311012911101
1411103011110
1511113111111

パターンが見えてきただろうか。 続いて、2進数を10進数に変換する方法を見ていこう。

2進数を10進数に変換する

2進数から10進数への変換方法はひとつではない。 ここでは2つの方法を紹介する。 ひとつは数式を使う「数学寄り」の方法、もうひとつはより視覚的な方法である。 両方紹介するが、1つ目の方法で使う用語が難しく感じたら、2つ目の方法まで読み飛ばしてもかまわない。

方法1

2進数を10進数に変換するのに使える便利な関数がある。

各桁の値に、その桁の重み(2の累乗)を掛けて、すべて足し合わせるという方法である。 この式には4つの重要な要素がある。

  • 各桁の数字:これはおなじみの0と1のことだが、2進数では必ず0か1のどちらかでなければならない。
  • 桁の位置:これも重要な要素である。位置は一番右の桁を0として始まり、この1または0が最下位桁になる。左に1つ移動するごとに、その桁の重要度(位取り)も1つずつ増していく。
  • 2進数の長さ:これは変数nの値によって決まる(正確には「n+1」)。たとえば101という2進数の長さは3であり、10011110のようなより大きな数の長さは8である。
  • 重み:各桁には、2ⁿ、2ⁿ⁻¹、…、2¹のような重みが掛けられる。一番右の重みである2⁰は1に等しく、1桁左に移動するごとに2、4、8、16、32、64、128、256……と続いていく。2の累乗は2進数においてきわめて重要であり、すぐに馴染み深いものになるはずである。

nや指数の記号を取り除いて、8桁分の2進数の位取り記数法の式を具体的に書き出してみよう。

値 = a7×2⁷ + a6×2⁶ + a5×2⁵ + a4×2⁴ + a3×2³ + a2×2² + a1×2¹ + a0×2⁰

さらに一歩進めて、各桁に具体的な数字を当てはめてみよう。 たとえば2進数10011011があったとすると、各桁の値は次のようになる。

念のため、このチュートリアルでは一番右の値を常に最下位桁とすることを前提とする。 最下位桁とは、数全体の値への影響がもっとも小さい桁のことである。 桁の重要度をどちらの端から数えるかは、実は取り決めの問題であり、これはエンディアンと呼ばれる規則の一部である。 2進数は、最上位桁が一番左にある「ビッグエンディアン」と、このチュートリアルで採用する「リトルエンディアン」のどちらの方式でも表せる(2進数はたいていリトルエンディアンで表記されているのをよく見かけるはずである)。

それでは、これらの桁の値を先ほどの2進数から10進数への変換式に当てはめてみよう。 この数はリトルエンディアンなので、最下位の値には一番小さい重みを掛けることになる。

1×2⁷ + 0×2⁶ + 0×2⁵ + 1×2⁴ + 1×2³ + 0×2² + 1×2¹ + 1×2⁰

これを整理すると、10進数の値が求められる。

= 1×128 + 0×64 + 0×32 + 1×16 + 1×8 + 0×4 + 1×2 + 1×1
= 128 + 16 + 8 + 2 + 1
= 155

10進数に比べて2進数で数を表すにははるかに多くの桁数が必要になることにすぐ気づくはずだが、それでもたった2種類の数字だけですべてを表せているのである。

方法2

2進数を10進数に変換するもうひとつの、より視覚的な方法は、各桁の1と0を「箱」に振り分けることから始まる。 それぞれの箱には、おなじみの1、2、4、8、16……という、2の累乗の重みが割り当てられている。 8桁分の箱を並べると、次のようになる。

1286432168421

先ほどの2進数10011011をこれらの箱に振り分けると、次のようになる。

1286432168421
10011011

値が0になっている箱は、線を引いて取り除いてしまおう。

12816821
11111

残った重みをすべて足し合わせれば、求める数が得られる。

128 + 16 + 8 + 2 + 1 = 155

10進数から2進数への変換

2進数から10進数への変換と同じく、10進数から2進数への変換にも複数の方法がある。 最初の方法は割り算と余りを使うもので、2つ目は引き算を使うものである。 両方試してみて、使いやすいほうを選んでほしい。

方法1

10進数を2進数に変換するのは、その逆ほど単純ではない。 この変換では、10進数を0になるまで2で繰り返し割っていく。 割るたびに得られる余りが、作成する2進数の1桁になる。

余りの求め方を忘れてしまった場合は、2で割っているので、割られる数が偶数なら余りは0奇数なら余りは1になることを思い出してほしい。

たとえば155を2進数に変換する場合は、次のような手順になる。

155 ÷ 2 = 77 余り 1(一番右の桁、1桁目)
 77 ÷ 2 = 38 余り 1(2桁目)
 38 ÷ 2 = 19 余り 0(3桁目)
 19 ÷ 2 =  9 余り 1
  9 ÷ 2 =  4 余り 1
  4 ÷ 2 =  2 余り 0
  2 ÷ 2 =  1 余り 0
  1 ÷ 2 =  0 余り 1(8桁目)

最初に得られた余りが最下位(一番右)の桁になるため、上から下へと読んでいけば、右から左へと2進数を組み立てられる:10011011。 先ほどの例と照らし合わせてみてほしい。ぴったり一致するはずである。

方法2

割り算と余りを求める方法が性に合わない場合は、もっと簡単な方法もある。 まず、変換したい10進数より小さい範囲でもっとも大きい2の累乗を見つけ、それを10進数から引く。 そして、0になるまで、可能な限り大きい2の累乗を使ってこの引き算を繰り返す。 引き算に使われた重みの位置には2進数の1が、使われなかった位置には0が入る。

先ほどの例を続けると、155は128で引くことができ、27が残る。

155 - 128 = 27
1286432168421
1

新しく得られた27は、64でも32でも引くことができない。 この2つの位置には0が入る。 16では引くことができ、11が残る。

27 - 16 = 11
1286432168421
1001

11は8で引くことができ、3が残る。 その後、4では引くことができない。

11 - 8 = 3
1286432168421
100110

3は2で引くことができ、1が残る。 そして最後に、1は1で引くことができ、0になる。

3 - 2 = 1
1 - 1 = 0
1286432168421
10011011

これで2進数が求められた。

変換用の計算ツール

幸いなことに、2進数から10進数へ、あるいはその逆を変換してくれる計算ツールはインターネット上に数多く存在する。 手計算で変換する必要に迫られることは、実際にはそう多くない。

ビット、ニブル、バイト

2進数の構造について説明する中で、数の長さについて簡単に触れた。 2進数の長さとは、その数に含まれる1と0の個数のことである。

よく使われる2進数の長さ

2進数の値は、よく一定の桁数(1と0の個数)にまとめられ、この桁数を数の長さと呼ぶ。 2進数の長さとしてよく使われるのが、ビット、ニブル、バイトである。 2進数の中の1つの1または0をビットと呼ぶ。 そこから、4ビットのまとまりをニブル、8ビットのまとまりをバイトと呼ぶ。

バイトは、2進数を扱う際によく耳にする言葉である。 プロセッサはすべて、あらかじめ決められたビット数で動作するように作られており、その長さはたいていバイトの倍数、つまり8、16、32、64ビットなどになっている。

まとめると、次のようになる。

長さ名称
1ビット0
4ニブル1011
8バイト10110101

ワードという言葉も、長さを表す用語として時折使われる。 ワードの語感はニブルやバイトほど親しみやすくはなく、意味もややあいまいである。 ワードの長さは、たいていプロセッサのアーキテクチャによって決まる。 16ビットのこともあれば、32ビット、64ビット、あるいはそれ以上のこともある。

先頭のゼロによる桁揃え

2進数の値を1バイト分(あるいはそれ以上)の桁数で表そうとすると、数を8桁にするために先頭に0を追加する必要が出てくることがある。 先頭のゼロとは、数の中でもっとも上位にある1のビットより左側に付け加えられた、1つ以上の0のことである。 10進数では先頭にゼロを付けることはあまりない。007と書いても、7という値について何か新しい情報が加わるわけではない(むしろ別の意味に取られるかもしれない)。

2進数の値に先頭のゼロを付けることは必須ではないが、その数のビット長についての情報を伝えるのに役立つ。 たとえば、1という数を00000001と表記することで、これがバイト単位で扱われていることを示せる。 どちらの数も同じ値を表しているが、前に7つの0が付いた表記のほうが、その値のビット長についての情報を余分に持っていることになる。

ビット単位の演算子

2進数の値を操作する方法はいくつもある。 10進数と同じように、2進数に対しても標準的な数学演算、つまり足し算、引き算、掛け算、割り算を行うことができる。 また、ビット単位の演算子を使えば、2進数の値の個々のビットを操作することもできる。

ビット単位の演算子は、1つまたは2つの2進数全体に対して、ビットごとに処理を行う関数である。 これらはブール論理を使って2進数の記号の集合に対して働くもので、電子工学とプログラミングの両方で幅広く使われている。

補数(NOT)

2進数の値の補数を求めるとは、その値のあらゆる要素をちょうど正反対にすることに等しい。 補数関数は、ある数を見て、すべての1を0に、すべての0を1に変える。 補数演算子はNOTとも呼ばれる。

たとえば10110101の補数を求めると、次のようになる。

NOT 10110101(10進数で181)
    --------  =
    01001010(10進数で74)

NOTは、1つの2進数の値だけに作用する唯一のビット単位演算子である。

OR

ORは2つの数を受け取り、それらの和集合を作り出す。 2つの2進数をORで演算する手順は次のとおりである。 まず、それぞれの数のビットの位置をそろえ、同じ位置にあるビットどうしを比較する。 それぞれのビットの比較において、どちらか一方でも、あるいは両方が1であれば、その桁の結果は1になる。 両方の値がその位置で0であれば、結果もその位置で0になる。

ORで起こりうる4通りの組み合わせと、その結果は次のとおりである。

  • 0 OR 0 = 0
  • 0 OR 1 = 1
  • 1 OR 0 = 1
  • 1 OR 1 = 1

たとえば10011010と01000110のORを求めるには、それぞれの数をビットごとにそろえる。 どちらか一方、あるいは両方の数の同じ桁に1があれば、結果もその桁は1になる。

   10011010
OR 01000110
   -------- =
   11011110

ORの演算は、桁上がりのない2進数の足し算だと考えるとよい。 0足す0は0だが、1に何を足しても結果は1になる。

AND

ANDは2つの数を受け取り、それらの論理積を作り出す。 ANDは、演算対象となる両方の値がともに1である場合にのみ、1を生み出す。

2つの2進数をANDで演算する手順は、ORの場合とよく似ている。 まず、それぞれの数のビットの位置をそろえ、同じ位置にあるビットどうしを比較する。 それぞれのビットの比較において、どちらか一方でも、あるいは両方が0であれば、その桁の結果は0になる。 両方の値がその位置で1であれば、結果もその位置で1になる。

ANDで起こりうる4通りの組み合わせと、その結果は次のとおりである。

  • 0 AND 0 = 0
  • 0 AND 1 = 0
  • 1 AND 0 = 0
  • 1 AND 1 = 1

たとえば10011010と01000110のANDを求めるには、それぞれの値をそろえる。 それぞれの桁の結果は、その桁の両方のビットがともに1である場合にのみ1になる。

    10011010
AND 01000110
    -------- =
    00000010

ANDは、掛け算のようなものだと考えるとよい。 0を掛ければ、結果は必ず0になる。

XOR

XORは排他的論理和である。 XORは通常のORと似た動作をするが、どちらか一方だけが1である場合にのみ1を生み出すという点が異なる。

XORで起こりうる4通りの組み合わせと、その結果は次のとおりである。

  • 0 XOR 0 = 0
  • 0 XOR 1 = 1
  • 1 XOR 0 = 1
  • 1 XOR 1 = 0

たとえば10011010と01000110のXORを求めると、次のようになる。

    10011010
XOR 01000110
    -------- =
    11011100

2桁目に注目してほしい。 2つの1どうしをXORした結果、0になっている。

ビットシフト

ビットシフトは、これまで紹介してきたようなビット単位の演算子とは厳密には異なるが、1つの2進数の値を操作するのに便利な手段である。

ビットシフトには2つの要素がある。シフトさせる方向である。 数は左右どちらの方向にもシフトでき、1ビットだけ、あるいは複数ビットまとめてシフトすることもできる。

右方向にシフトすると、数の最下位ビット(右端)が1つ以上切り捨てられ、そのまま失われる。 ビット長をそろえるために、先頭にゼロを追加することもできる。

たとえば10011010を右に2ビットシフトすると、次のようになる。

右に2ビットシフト 10011010(10進数で154)
                 -------- =
                 00100110(10進数で38)

左方向にシフトすると、すべてのビットが数の最上位側(左側)へと押し出される。 シフトのたびに、最下位ビットの位置にゼロが追加される。

たとえば10011010を左に1ビットシフトすると、次のようになる。

左に1ビットシフト 10011010(10進数で154)
                 -------- =
                100110100(10進数で308)

この単純なビットシフトは、実は比較的複雑な数学的な操作を行っている。 左にnビットシフトすると、その数は2ⁿ倍される(先ほどの例で入力値が2倍になっていたことに気づいただろうか)。 一方、右にnビットシフトすると、その数は2ⁿで整数除算される。 右シフトによる除算は少し奇妙に感じられることがある。 シフトによる除算で生じる端数は切り捨てられるため、154を右に2回シフトすると、154÷4=38.5ではなく38になる。 ビットシフトは、2、4、8などの数で割ったり掛けたりするための、非常に高速な手段になりうる。

これらのビット単位の演算子は、2進数に対して標準的な数学演算を行うために必要な道具のほとんどを提供してくれる。

プログラミングにおける2進数

もっとも基本的なレベルでは、2進数があらゆる電子機器を動かしている。 そのため、コンピュータプログラミングの中で2進数に出会うのは避けられないことである。

プログラム内での2進数の表現

Arduinoをはじめとするたいていのプログラミング言語では、2進数の前に0bを付けることで2進数として表現できる。 この0bが付いていなければ、その数は単なる10進数として扱われる。

たとえば、コード上で次の2つの数はまったく異なる値になる。

a = 0b01101010; // 10進数で106
c = 01101010;  // 10進数で1,101,010(0bの接頭辞がないため10進数として扱われる)

プログラミングにおけるビット単位の演算子

前のセクションで紹介したビット単位の演算子は、いずれもプログラミング言語の中で実行できる。

ANDビット演算子

2つの2進数の値をANDで演算するには、アンパサンド&)演算子を使う。 たとえば次のようになる。

x = 0b10011010 & 0b01000110;
// xは0b00000010になる

2進数の値をANDで演算することは、値にビットマスクを適用したり、ある2進数の特定のビットが1かどうかを調べたりするのに役立つ。

このANDビット演算子は、二重アンパサンド(&&)を使い、複数の論理式の入力に基づいて真偽値を生み出すAND条件演算子と混同しないように注意する必要がある。

ORビット演算子

ORビット演算子はパイプ|、Shift+バックスラッシュのキーで、キーボードのBackspaceの下にあることが多い)である。 たとえば次のようになる。

y = 0b10011010 | 0b01000110;
// yは0b11011110になる

2進数の値をORで演算することは、数の中の1つ以上のビットを1に設定したいときに役立つ。

ANDのときと同じく、ORビット演算子を二重パイプ(||)のOR条件演算子と混同しないよう注意しよう。

NOTビット演算子

NOTビット演算子はチルダ~、Shift+バッククォートのキーで、Tabキーの上にあることが多い)である。 たとえば次のようになる。

z = ~(0b10100110);
// zは0b01011001になる

XORビット演算子

2つの値をXORで演算するには、両者の間にキャレット^)を置く。

r = 0b10011010 ^ 0b01000110;
// rは0b11011100になる

XORは、ビットが異なっているかどうかを調べるのに便利である。 なぜなら、片方が0でもう片方が1の場合にのみ1という結果になるからである。

左シフトと右シフト

2進数をnビット左または右にシフトするには、<<nまたは>>n演算子を使う。 いくつか例を見てみよう。

i = 0b10100101 << 4;    // iを左に4ビットシフト
// iは0b101001010000になる
j = 0b10010010 >> 2;    // jを右に2ビットシフト
// jは0b00100100になる

シフトは、2の累乗で掛け算や割り算をするための、特に効率のよい方法である。 先ほどの例では、左に4ビットシフトすることでその値は2⁴(16)倍になっている。 2つ目の例では、右に2ビットシフトすることでその数は2²(4)で割られている。

まとめ

2進数は、電子工学におけるあらゆる計算、演算、処理の土台となるものである。 ここからさらに学べることは数多くある。

2進数や、その他の重要な数体系についてさらに学びたいなら、次のようなキットやチュートリアルもおすすめである。

  • バイナリブラスターの組み立てガイド:2進数の変換を練習したいなら、Binary Blaster Kitが役立つ。これははんだ付けが必要なキットである。組み立てたら、それを使って2進数、16進数、10進数の関係についての理解度を試すことができる。
  • 16進数:この16進の数体系と、2進数や10進数との関係について学べる。

10進数と2進数の変換ができるようになったら、その知識を、文字が世界共通の方式でどのように符号化されているかを理解することにも応用できる。

また、身につけた知識を、低レベルな回路やICの理解にも応用できる。

さらに、通信プロトコルの中で2進数がどのような役割を果たしているかも見てみるとよい。

タグ: 通信、コンピュータ工学、プログラミング


出典:Binary(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

アナログ-デジタル変換 (ADC)

マイコンが検出できるのは、基本的には二値の信号である。 ボタンが押されているか、いないか。 これがデジタル信号である。 5ボルトで動作するマイコンは、0ボルト(0V)を2進数の0、5ボルト(5V)を2進数の1として認識する。 しかし現実の世界はそれほど単純ではなく、その中間の値をとる。 信号が2.72Vだったら、それは0なのか1なのか。 このように変化し続ける信号を測定する必要がある場面は多く、こうした信号をアナログ信号と呼ぶ。 5V系のアナログセンサーは、0.01Vや4.99V、あるいはその間のどんな値も出力しうる。 幸い、ほとんどすべてのマイコンには、こうした電圧をプログラムの中で判断材料として使える値に変換する仕組みが内蔵されている。

このチュートリアルを読む前に知っておくとよい話題:

ADCとは何か

ADC(Analog to Digital Converter、アナログ-デジタル変換器)は、ピンにかかっているアナログ電圧をデジタルな数値に変換してくれる、非常に便利な機能である。 アナログの世界からデジタルの世界へと変換することで、身の回りのアナログな世界と電子回路とのあいだをつなげられるようになる。

マイコンのすべてのピンがアナログ-デジタル変換に対応しているわけではない。 Arduinoのボードでは、ラベルの先頭に「A」が付いたピン(A0からA5まで)が、アナログ電圧を読み取れるピンであることを示している。

ADCの性能はマイコンによって大きく異なる。 Arduinoに搭載されているADCは10ビットADCであり、1,024段階(2^10)の離散的なアナログレベルを検出できる。 マイコンによっては8ビットADC(2^8 = 256段階)のものもあれば、16ビットADC(2^16 = 65,536段階)のものもある。

ADCの内部動作はかなり複雑である。 実現方法にはいくつかの方式があるが(一覧はWikipediaを参照)、よく使われる方式の1つは、アナログ電圧で内部のコンデンサを充電し、それを内部の抵抗を通して放電するのにかかる時間を測るという方法である。 マイコンは、コンデンサが放電しきるまでに経過したクロックサイクルの数を数えており、ADCの変換が完了した時点で返される値は、このクロックサイクル数に基づいている。

ADCの値と電圧の関係

ADCが返す値は比率としての値である。 つまりADCは、5Vを1023として扱い、5V未満の電圧はすべて5Vと1023の間の比率として表す。

Arduinoの10ビットADCを5V系で使う場合が多いことを踏まえると、この関係は次の式に単純化できる。

\[ \text{ADCの値} = \left(\frac{\text{読み取った電圧}}{5,\text{V}}\right) \times 1023 \]

システムの電源電圧が3.3Vなら、式の5Vを3.3Vに置き換えるだけでよい。 たとえば3.3V系でADCが512という値を返したとき、実際の電圧はおよそ1.65Vである。

逆に、アナログ電圧が2.12Vのとき、ADCはどんな値を返すだろうか。 先の式をADCの値について解くと、

\[ \text{ADCの値} = \left(\frac{2.12,\text{V}}{5,\text{V}}\right) \times 1023 \approx 434 \]

という計算になり、ADCはおよそ434を返すはずだとわかる。

Arduinoを使ったADCの例

実際にArduinoを使ってアナログ電圧を検出してみよう。 トリムポット(可変抵抗)や光センサー、あるいは簡単な分圧回路を使って電圧を作り出す。 ここでは例として、簡単なトリムポットの回路を組む。

まず、ピンを入力として定義する必要がある。 回路図に合わせて、ここではA3ピンを使う。

pinMode(A3, INPUT);

続いて、analogRead() コマンドでアナログ-デジタル変換を行う。

int x = analogRead(A3); // A3ピンのアナログ値をxに読み込む

戻り値として x に格納されるのは、0から1023までのいずれかの値である。 Arduinoは10ビットのADCを持つため、2^10 = 1024段階を表現できる。 この値をintに格納するのは、x が10ビットであり、バイト型(8ビット)には収まらない大きさだからである。

値が変化する様子を確認するために、シリアルに出力してみる。

Serial.print("Analog value: ");
Serial.println(x);

アナログ電圧を変化させると、x の値もそれに応じて変化する。 たとえば x が334と表示され、Arduinoが5Vで動作しているとすると、実際の電圧はいくらになるだろうか。 テスター(デジタルマルチメーター)を取り出して実際の電圧を測ってみると、およそ1.63Vになっているはずである。 これで、Arduinoを使った自作のデジタルマルチメーターができあがったことになる。

配線を間違えるとどうなるか

アナログセンサーを通常の(デジタル用の)ピンにつないだらどうなるか。 悪いことは何も起きない。 ただし、analogRead を正しく実行できなくなる。

int x = analogRead(8); // デジタルピン8でアナログ値を読もうとしている(これはうまくいかない)

このコードはコンパイルは通るが、x には意味のない値が入る。

デジタルセンサーをアナログピンにつないだらどうなるか。 これも同様に、壊れることはない。 ボタンのようなデジタル信号をアナログ-デジタル変換すると、ADCの値はほぼ1023(5V、つまり2進数の1に相当)か、ほぼ0(0V、つまり2進数の0に相当)のどちらかに偏った値になるはずである。

まとめ

アナログ-デジタル変換を学ぶことは、電子工作において大きな意味を持つ。 この重要な概念を理解したところで、ADCを利用しているさまざまなプロジェクトやセンサーにも目を向けてみてほしい。

  • 加速度センサージャイロセンサーの一部にはアナログ出力のものがあり、使える値として読み取るにはADCが必要になる。
  • PWMパルス幅変調は、アナログ入力とは逆の、いわばアナログ出力に相当する仕組みである。
  • INA169のようなICを使うと、ADCで電流を検出できる。
  • 分圧回路とADCを組み合わせれば、トリムポットやジョイスティック、スライダー、感圧抵抗(FSR)など、さまざまなセンサーや可変部品を読み取れる。
  • ArduinoにはADCの値を別の範囲に変換する map() 関数がある。

タグ: Arduino、概念、電気工学


出典:Analog to Digital Conversion(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

デジタルロジック

デジタルロジック、あるいはブール論理は、現代のあらゆるコンピュータシステムを支える基本的な概念である。 簡単に言えば、比較的単純な「はい/いいえ」の質問を組み合わせて、非常に複雑な判断を下せるようにするルールの体系である。

このチュートリアルでは、次のようなことを学ぶ。

デジタル回路

デジタルロジック回路は、組み合わせ回路順序回路という2つのカテゴリーに分けられる。 組み合わせ回路は「即座に」変化する。入力が変化した瞬間、回路の出力もそれに応じて変化する(もちろん、信号が回路素子の中を伝わるのに多少の時間がかかるため、実際にはわずかな遅延がある)。 一方、順序回路にはクロック信号があり、変化はクロックのエッジ(立ち上がりや立ち下がり)に合わせて回路の各段階を伝わっていく。

一般に、順序回路は、クロック信号によって動作するメモリ素子で区切られた、組み合わせ論理のブロックの集まりとして構成される。

プログラミング

デジタルロジックはプログラミングにおいても重要である。 デジタルロジックを理解することで、プログラムの中で複雑な意思決定が可能になる。

プログラミングには理解しておくべき細かな注意点もいくつかあるが、それについては基本を押さえたあとで扱う。

参考になるチュートリアル:

まだ読んでいなければ、2進数のチュートリアルに目を通しておくとよい。 その中にもブール論理について少し触れている部分があるが、ここではその話題をさらに深く掘り下げていく。 このほかにも、始める前に理解しておくとよい話題がいくつかある。

組み合わせ論理

組み合わせ回路は、5種類の基本的な論理ゲートから構成される。

  • ANDゲート:両方の入力が1のときに出力が1になる
  • ORゲート:少なくとも一方の入力が1のときに出力が1になる
  • XORゲート:どちらか一方だけの入力が1のときに出力が1になる
  • NANDゲート:少なくとも一方の入力が0のときに出力が1になる
  • NORゲート:両方の入力が0のときに出力が1になる

デジタルロジックにはもうひとつ、6番目の要素としてインバータ(NOTゲートと呼ばれることもある)がある。 インバータは何の判断も下さないため、厳密にはゲートとは言えない。 インバータの出力は、入力が0であれば1に、入力が1であれば0になる。

先ほどの図について、いくつか補足しておく。

  • ゲートの名前自体は印字されないことが多い。記号だけで識別できると考えられているためである。
  • A、B、Qのような端子表記は標準的なものだが、システム全体の入出力に関わらない信号については、論理回路図ではたいてい省略される。
  • 入力が2つの素子が標準的だが、まれに3つ以上の入力を持つ素子も見かける。ただし出力は常に1つだけである。

デジタルロジック回路は、たいていこの6つの記号を使って表され、入力は左側、出力は右側に配置される。 入力どうしを結線することはできるが、出力どうしを結線してはならない。出力は必ず他の入力に接続する。 ただし、1つの出力を複数の入力に接続することは可能である。

真理値表

先ほどの説明だけでも個々のブロックの機能を表すには十分だが、もっと便利な道具がある。真理値表である。 真理値表とは、ある回路に入力しうる値の組み合わせに対して、その出力がどうなるかを説明する単純な表である。 先ほどの6つの主要な素子について、真理値表を示す。

真理値表は、頭が痛くなるほど多くの入力や出力があっても、いくらでも拡張できる。 4入力の回路とその真理値表は、次のようになる。

ブール論理の記法

論理演算を表す式を、簡潔な数学的表記で書けると便利である。 そのために、AND、OR、XOR、NOTという固有の演算にはそれぞれ数学的な記号が用意されている。

  • AとBのANDは、ABと書く(A・Bと書かれることもある)
  • AとBのORは、A + Bと書く
  • AとBのXORは、A ⊕ Bと書く
  • Aの否定(NOT)は、A′あるいはAの上に横線を引いて表す

このリストには2つ、NANDとNORが抜けていることに気づいただろうか。 これらはたいてい、対応する表記全体を否定することで表す。

  • AとBのNANDは、(AB)′、あるいは(A・B)′と書く
  • AとBのNORは、(A + B)′と書く

順序論理

組み合わせ論理は便利だが、順序回路を組み合わせなければ、現代のコンピューティングは成り立たない。

順序回路は、論理システムに「記憶」を持たせるものである。 先ほど触れたように、組み合わせ論理は遅延を伴って結果を出す。 その遅延の大きさは、部品の製造プロセス、シリコンの温度、回路の複雑さなど、非常に多くの要因によって変わってくる。 もしある回路の出力が、別の2つの組み合わせ回路の結果に依存していて、その結果が異なるタイミングで届いた場合(実際の世界ではよく起こることである)、その組み合わせ回路は一瞬「グリッチ」を起こし、意図した動作とは異なる結果を一時的に出力してしまうことがある。

一方、順序回路は特定のタイミングでのみ出力をサンプリングし、伝搬させる。 そのタイミングの間に入力が変化しても、それは無視される。 このサンプリングのタイミングは、たいてい回路全体で同期されており、「クロック」と呼ばれる。 コンピュータの「速度」として語られる数値は、まさにこのクロックの値である。 グローバルな同期クロックに頼らない「非同期」の順序回路を設計することも可能ではあるが、そうしたシステムには大きな難しさが伴うため、ここでは扱わない。

余談だが、デジタルロジックのどの部分にも、最小遅延時間と最大遅延時間という2つの特性値がある。 回路が最小遅延時間を満たせない場合(つまり本来より速く動作してしまう場合)、その回路は修復不可能な形で故障する。 その回路がコンピュータのCPUのようなより大きな装置の一部であれば、装置全体が使い物にならなくなる。 最大遅延時間を満たせない場合(つまり本来より遅く動作する場合)は、システム内でもっとも遅い回路に合わせてクロック速度を落とすことで対応できる。 最大遅延時間は、回路を構成するシリコンの温度が上がるにつれて増加する傾向があり、これがコンピュータが過熱したときや、オーバークロックのようにクロック速度を上げすぎたときに不安定になる理由である。

順序回路の素子

組み合わせ論理と同じく、順序回路にもその構成要素となるいくつかの基本的な回路素子がある。 これらのブロックは、出力からのフィードバックを使って入力を安定させることで、基本的な組み合わせ素子から構成されている。 これには「ラッチ」と「フリップフロップ」という2つの「種類」がある。 これらの用語はしばしば同じ意味で使われるが、ラッチはクロックによる制御がないため一般的にはあまり実用性が高くなく、ここではフリップフロップに焦点を当てる。

D型フリップフロップ

もっとも単純なタイプのフリップフロップがD型である。 D型フリップフロップの動作は単純で、クロックのエッジ(通常は立ち上がりだが、内蔵のインバータによって立ち下がりでクロックされるものもある)が来ると、入力の値が出力にラッチされる。

たいてい、クロック入力は記号に食い込む小さな三角形で示される。 たいていのフリップフロップは、「通常」の出力と、その反転出力という2つの出力を持つ。

T型フリップフロップ

D型よりもわずかに複雑なのがT型である。 「T」は「トグル(toggle)」の頭文字である。 クロックのエッジが来たとき、入力Tが1であれば出力の状態が反転する。 入力が0であれば、出力はそのまま変わらない。 D型と同じく、出力の反転出力もたいてい用意されている。

T型フリップフロップの便利な使い道のひとつが、クロック分周回路である。 Tを常に1にしておくと、出力はクロック周波数を2で割ったものになる。 T型フリップフロップを連ねることで、装置のマスタークロックからより遅いクロックを作り出すことができる。

JK型フリップフロップ

最後に紹介するのがJK型である。 JK型は、3つのうち唯一、真理値表がないと説明が難しいタイプである。 J、Kという2つの入力を持ち、その組み合わせに応じて、出力をそのまま維持したり、セットしたり、クリアしたり、反転させたりできる。 もちろん、どのフリップフロップでも同じだが、重要なのはクロックが来た瞬間の入力の値だけである。

セットアップ時間、ホールド時間、伝搬遅延

すべての順序回路には、セットアップ時間ホールド時間、そして伝搬遅延と呼ばれる値がある。 この3つを理解することは、期待どおりに動作する順序回路を設計するうえで欠かせない。

セットアップ時間とは、クロックの立ち上がりエッジが発生する前に、フリップフロップが正しくデータをラッチするために信号が入力に到達していなければならない最小の時間のことである。 同様に、ホールド時間とは、クロックの立ち上がりエッジが発生したあと、信号が変化するまでに安定した状態を保っていなければならない最小の時間のことである。

セットアップ時間とホールド時間は最小値として示されるのに対し、伝搬遅延は最大値として示される。 簡単に言えば、伝搬遅延とは、クロックの立ち下がりエッジのあと、出力に信号が現れるまでにかかりうる最大の時間のことである。 次の図はこれらの関係を示したものである。

上の図では、信号の遷移がわずかに斜めに描かれていることに注目してほしい。 これには2つの意味がある。ひとつは、クロックやデータのエッジは実際には決して直角にはならず、常にいくらかの立ち上がり時間や立ち下がり時間を持つことを思い出させるためであり、もうひとつは、各時間を示す垂直線が信号のどこと交わっているかを見やすくするためである。

この3つの値の組み合わせによって、その装置が使用できる最高のクロック速度が決まる。 ある部品の伝搬遅延と、回路内の次の部品のセットアップ時間の合計が、あるクロックパルスの立ち下がりエッジから次のクロックパルスの立ち上がりエッジまでの時間を超えてしまうと、2番目の部品の入力でデータが安定せず、予期しない動作を引き起こすことになる。

メタステーブル状態

セットアップ時間とホールド時間を守らないと、「メタステーブル状態」と呼ばれる問題が発生することがある。 回路がメタステーブル状態にあるとき、フリップフロップの出力は2つの正常な状態の間を、回路のクロック速度よりもはるかに速い速度で激しく振動することがある。

メタステーブル状態の問題は、動作の誤りから、消費電流の増加によるチップの損傷にまで及ぶことがある。 メタステーブル状態はたいてい自然に解消するが、解消するころにはシステムが完全に未知の状態になっていることがあり、正常な動作を取り戻すには完全なリセットが必要になる場合もある。

メタステーブル状態がよく発生するのは、信号がクロックドメインをまたぐとき、つまり異なるクロック源で動作している装置間で信号がやり取りされるときである。 クロックが同期していないため(たとえ公称の周波数が同じであっても、現実にはわずかな違いがある)、いずれクロックのエッジとデータのエッジが危険なほど近づいてしまい、セットアップ時間違反を引き起こすことになる。 この問題に対する簡単な対策は、システムへのすべての入力を、2段に連ねたD型フリップフロップに通すことである。 たとえ最初のフリップフロップがメタステーブル状態に陥っても、次のクロックパルスが来るまでには(望むらくは)安定した状態に落ち着いているはずであり、2番目のフリップフロップは正しいデータを読み取れる。 これにより、入力されるデータのエッジに1クロック分の遅延が生じるが、メタステーブル状態のリスクに比べれば、ほとんどの場合は無視できるほど小さな代償である。

プログラミングにおけるブール論理

ここまでの内容は、プログラミングの世界にもそのまま応用できる。 たいていのプログラムは単なる決定木であり、「これが真であれば、これを行う」という形をしている。 これを説明するために、ここではArduinoの文脈でC言語のコードを使う。

ビット単位の論理演算

「ビット単位」の論理と言うとき、実際に意味しているのは、値を返す論理演算のことである。 たとえば、次のようなコードを考えてみよう。

byte a = 0b01010101;
byte b = 0b10101010;
byte c;

abに対してビット単位の演算を行い、その結果をcに入れることができる。 次のようになる。

c = a & b;  // aとbのビット単位AND。結果は0b00000000
c = a | b;  // aとbのビット単位OR。結果は0b11111111
c = a ^ b;  // aとbのビット単位XOR。結果は0b11111111
c = ~a;     // aのビット単位補数。結果は0b10101010

言い換えると、結果の各ビットは、対応する2つのオペランドの各ビットに演算を適用した結果に等しい。

なるほど、それは分かった。しかしそれが何の役に立つのだろうか。 実は、ビット単位の演算子を使ってレジスタを操作することで、いろいろと便利なことができる。 特定の1ビットだけを選んでクリアしたり、セットしたり、反転させたりできるほか、あるビット(あるいは複数のビット)がセットされているかクリアされているかを調べることもできる。 これらの演算の例をいくつか見てみよう。

c = 0b00001111 & a; // aの上位ニブルをクリアし、下位ニブルはそのまま残す
                     // 結果は0b00000101
c = 0b11110000 | a; // aの上位ニブルをセットし、下位ニブルはそのまま残す
                     // 結果は0b11110101
c = 0b11110000 ^ a; // aの上位ニブルのすべてのビットを反転させる
                     // 結果は0b10100101

ビット単位の演算はすべて、等号と組み合わせることで自己代入の形にできる。

a ^= 0b11110000; // aを0b11110000とXORし、結果をaに書き戻す
b |= 0b00111100; // bを0b00111100とORし、結果をbに書き戻す

ビットシフト

データに対して行えるもうひとつの便利なビット単位の演算がビットシフトである。 これは単に、データを左または右へ指定した桁数だけずらす操作であり、シフトによってはみ出したデータは消え、反対側からは0が入ってくる。

byte d = 0b11010110;
byte e = d >> 2;  // dを右に2ビットシフト。e = 0b00110101
e = e << 3;       // eを左に3ビットシフト。e = 0b10101000

ビットシフトの使い道については後ほど紹介するが、非常に便利な応用のひとつが掛け算と割り算である。 右に1ビットシフトするごとに2で割ったことになり(ただし余りの情報は失われる)、左に1ビットシフトするごとに2倍したことになる。 これが便利なのは、Arduinoのような小さなプロセッサでは掛け算や割り算はたいてい時間のかかる処理だが、ビットシフトはたいてい非常に高速に実行できるためである。

比較演算子と関係演算子

2つの値を比較する方法も必要になる。 それを行うのが、比較の結果に応じて「真」または「偽」を返す一群の演算子である。

  • == 「等しい」(値が等しければ真、そうでなければ偽)
  • != 「等しくない」(値が異なれば真)
  • > 「より大きい」(左のオペランドが右のオペランドより大きければ真)
  • < 「より小さい」(左のオペランドが右のオペランドより小さければ真)
  • >= 「以上」(左のオペランドが右のオペランド以上であれば真)
  • <= 「以下」(左のオペランドが右のオペランド以下であれば真)

比較する値どうしが同じデータ型であることは、一般に非常に重要である。 たとえば「byte」型と「int」型を比較すると、予期しない挙動が起きることがある。

論理演算子

論理演算子は、同じ型の新しい値を作るのではなく、「真」か「偽」を生み出す演算子である。 これは私たちが普段考えるような接続詞に近い。「雨が降っていなくて、風があれば、凧あげに行こう」というような文である。 これをC言語に翻訳すると、次のようになる。

if ( (raining != true) && (windy == true) ) flyKite();

2つの副節を囲むかっこに注目してほしい。 厳密には必要ないが、副節をまとめてグループ化しておくことは、コードをできるだけ読みやすく保つためのよい習慣である。

また、論理AND演算子(&&)は、それぞれの副節が真か偽かに基づいて、真偽の答えを生み出すことにも注目してほしい。 副節のひとつに数値を使った条件を入れることも同じように簡単にできる。

if ( (raining != true) && ( (windSpeed >= 5) || (reallyBusy != true) ) ) flyKite();

この条件は、雨が降っていなければ、そして風が十分にある場合、あるいはそれほど忙しくない場合に、凧あげに行くというものである(風がなくても、暇であれば一応挑戦はしてみる)。

ここでもかっこに注目してほしい。 もし「(windSpeed >= 5) || (reallyBusy != true)」のかっこを取り除いてしまうと(||はOR演算子を表す)、意図したとおりに動くかどうかがあいまいな文になってしまう。

フロー制御

複雑な論理式を組み立てられるようになったところで、その答えを使って何ができるかを見ていこう。

if/else if/else文

もっとも単純な判断が「if/else」である。 if/else if/elseを使うと、一連のテストを設定でき、そのうちどれか1つだけが実行される。

if ( reallyBusy == true ) workHarder();
else if ( (raining != true) && (windy == true) ) flyKite();
else work();

この3つの文により、本当に忙しいときは決して凧あげをせず、忙しくなくても凧あげ日和でなければ、ただ仕事を続けることになる。 ここで、2つ目のelse if()if()に変えてみよう。

if ( reallyBusy == true ) workHarder();
if ( (raining != true) && (windy == true) ) flyKite();
else work();

こうすると、たとえ本当に忙しくても、凧あげ日和であれば、ほんの一瞬だけ「もっと頑張って働く」状態になり、天気がよいことに気づいた瞬間に凧あげに切り替わってしまう。 さらに、凧あげ日和でなければ、「もっと頑張って働く」状態から、最初のif文が実行された直後にただの「働く」状態へと即座に格下げされてしまう。

「workHarder()」を「turnLEDOn()」に、「work()」を「turnLEDOff()」に置き換えたらどうなるか、想像してみてほしい。 最初の例では、LEDはしばらく点灯したまま、あるいは消灯したままになる。 しかし2つ目の例では、「reallyBusy」の状態にかかわらず、最初のif文でLEDが点灯した直後にほぼ即座に消灯してしまい、「reallyBusy」を示すはずのランプが一向に点かないと首をかしげることになるだろう。

switch/case/default文

if/elseの長い連鎖よりも強力さでは劣るが読みやすいのが、switch/case/default文である。 これは、ある変数の値に基づいて判断を行うものである。

switch (menuSelection) {
  case '1':
    doMenuOne();
    break;
  case '2':
    doMenuTwo();
    break;
  case '3':
    doMenuThree();
    break;
  default:
    flyKite();
    break;
}

switch()文は、値が等しいかどうかの判定しかできないが、それはよくある用途であるため十分に役立つ。 ここで注目してほしいのは、「break;」文と「default:」のケースという2つの重要な要素である。

「default:」は、他のどのケースにも一致しなかった場合に実行される。 これは厳密には必須ではなく、default節がなければ、すべてのケースが一致しなかった場合に何も起こらない。 とはいえ、たいていは何かを実行させたいはずであり、すべてのケースが一致しない可能性はないと決めつけないほうがよい。

「break;」は現在の条件分岐から抜け出す。 これはどの種類の条件分岐の中でも使えるが、この場合、各caseの末尾にbreakを入れ忘れると、後続のcaseに一致しなくても、その後のコードが実行され続けてしまう。

while/do…whileループ

ここまでは、一度だけ判断を行うコードを見てきた。 では、ある条件が成り立つ限り、動作を何度も繰り返したい場合はどうすればよいだろうか。 そこで登場するのがwhile()とdo…while()である。

while (windy == true) flyKite();

コードがwhile()文に到達すると、プログラムはまず条件(「風はあるか」)を評価し、それが「真」であればコードを実行する。 コードの実行が終わると、条件が再び評価される。 条件がまだ「真」であれば、コードは再び実行される。 これは、条件が「偽」になるか、break文に出会うまで繰り返される。

while()ループの中には、if()文(あるいはswitch()や別のwhile()、その他何でも)を入れ子にすることができる。

while (windy == true) {
  flyKite();
  if (bossIsMad == true) break;
}

このループでは、風がやむか、上司の機嫌が悪くなるまで凧あげを続けることになる。

while()ループの変種として、do…while()ループがある。

do {
  flyKite();
} while (windy == true);

この場合、かっこの中のコードは、たとえ条件が偽であっても1回は必ず実行される。 つまり、風の状態にかかわらず、とりあえず外に出て凧を引っ張ってはみるが、風がなければすぐにあきらめる、ということになる。

最後に、条件式に「true」を直接指定することで、永遠に実行され続けるコードを作ることもできる。

while (true) {
  flyKite();
}

このコードでは、風の有無、上司の満足度、空腹、猛獣の存在などに関係なく、ひたすら凧を引きずり続けることになる。 もちろん、break文を使えばこのコードから抜け出すことは可能だが、自分から実行を止めることは決してない。

for()ループ

最後に紹介する繰り返しの種類がfor()ループである。 for()ループを使うと、特定の回数だけコードのかたまりを実行できる。 for文の構文は次のようになる。

for (byte i = 0; i < 10; i++) {
  Serial.print("Hello, world!");
}

for()ループのかっこの中には、セミコロンで区切られた3つの文がある。 1つ目はイテレータ(繰り返しのたびに変化させる変数)であり、その初期値もここで設定する。 2つ目は、1回実行するたびに行う比較であり、この比較が偽になった時点でループを抜ける。 最後の文は、ループを1回実行するたびに行いたい処理であり、この場合はイテレータを1ずつ増やしている。

for()ループでもっともよくある間違いは、いわゆる「off-by-one(1つずれ)」エラーである。 コードを10回実行させたいつもりが、実際には9回や11回実行されてしまうというもので、たいていは「<=」と「<」を取り違えたことが原因である。

まとめ

デジタルロジックを理解することは、電子工学において欠かせないスキルである。 さらに詳しく知りたい場合は、次のような情報源も参考になる。

タグ: コンピュータ工学、概念、電気工学、プログラミング


出典:Digital Logic(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

ロジックレベル

私たちはアナログ信号の世界に生きている。 しかしデジタル電子工学の世界には、ONかOFFかという2つの状態しか存在しない。 この2つの状態を使うことで、機器は大量のデータを符号化し、伝送し、制御することができる。 ロジックレベルとは、もっとも広い意味では、信号が取りうる特定の離散的な状態のことを指す。 デジタル電子工学では、一般に2進数の1と2進数の0という2つの論理状態だけを扱う。

このチュートリアルで扱う内容:

  • ロジックレベルとは何か
  • デジタル電子工学におけるロジックレベルの一般的な規格
  • 異なる技術どうしをインターフェースする方法
  • レベルシフト
  • 電圧バックブーストレギュレータ

参考になるチュートリアル:

このチュートリアルは、基本的な電子工学の知識の上に成り立っている。 まだ読んでいなければ、次のチュートリアルにも目を通しておくとよい。

ロジックレベルとは何か

簡単に言えば、ロジックレベルとは、信号が取りうる特定の電圧や状態のことである。 デジタル回路における2つの状態は、よくONまたはOFFと呼ばれる。 2進数で表すと、ONは2進数の1に、OFFは2進数の0に対応する。 Arduinoでは、これらの信号をそれぞれHIGH(ハイ)、LOW(ロー)と呼ぶ。 過去30年ほどの間に、電子工学ではさまざまな電圧レベルを定めるための技術規格がいくつも生まれてきた。

Logic 0とLogic 1

デジタル電子回路は、データや情報を保存、処理、伝送するために2進論理に依存している。 2進論理とは、ONかOFFかという2つの状態のどちらかを指す。 これは一般に2進数の1または2進数の0として表される。 2進数の1はHIGH信号とも呼ばれ、2進数の0はLOW信号とも呼ばれる。

信号の強さは、たいていその電圧レベルによって表される。 logic 0(LOW)やlogic 1(HIGH)はどのように定義されるのだろうか。 これはたいていチップのメーカーが仕様書の中で定めている。 もっとも一般的な規格はTTL(トランジスタ・トランジスタ・ロジック)である。

アクティブローとアクティブハイ

ICやマイクロコントローラを扱っていると、アクティブローのピンとアクティブハイのピンに出会うことになるはずである。 簡単に言えば、これはそのピンをどうやって有効化するかを表す言葉である。 アクティブローのピンであれば、そのピンをグラウンドに接続することでLOWに「引き下げ」なければならない。 アクティブハイのピンであれば、HIGHの電圧(たいてい3.3Vや5V)に接続する。

たとえば、チップイネーブルピン(CE)を持つシフトレジスタがあるとしよう。 データシートの中でCEピンの上に横線が引かれているのを見かけたら、そのピンはアクティブローである。 チップを有効にするには、そのCEピンをGNDに引き下げる必要がある。 一方、CEピンの上に横線がなければ、そのピンはアクティブハイであり、有効にするにはHIGHに引き上げる必要がある。

多くのICでは、アクティブローのピンとアクティブハイのピンが入り混じっていることがある。 ピン名の上に横線が引かれていないか、必ず確認しよう。 この横線はNOT(バーとも呼ばれる)を表している。 何かがNOTされると、その状態は正反対になる。 つまり、アクティブハイの入力をNOTすれば、それはアクティブローになるということである。単純な話である。

TTLのロジックレベル

私たちが使うシステムの大半は、3.3Vまたは5VのTTLレベルに依存している。 TTLとはTransistor-Transistor Logic(トランジスタ・トランジスタ・ロジック)の頭文字を取ったものである。 バイポーラトランジスタで構成された回路によってスイッチングを行い、論理状態を維持する仕組みである。 トランジスタとは、要するに電気的に制御されるスイッチの、もったいぶった呼び方にすぎない。 どのロジックファミリーにも、知っておくべきしきい値電圧がいくつかある。 以下は標準的な5VのTTLレベルの例である。

  • VOH:TTLデバイスがHIGH信号として出力する最小の電圧レベル
  • VIH:HIGHと見なされるために必要な最小の入力電圧レベル
  • VOL:デバイスがLOW信号として出力する最大の電圧レベル
  • VIL:まだLOWと見なされる最大の入力電圧レベル

最小の出力HIGH電圧(VOH)が2.7Vであることに気づくはずである。 つまり、HIGHを出力する側のデバイスの出力電圧は、常に少なくとも2.7Vになるということである。 最小の入力HIGH電圧(VIH)は2Vであり、基本的に2V以上の電圧であれば、TTLデバイスにはlogic 1(HIGH)として読み取られる。

また、送信側の出力と受信側の入力の間に0.7Vの余裕があることにも気づくだろう。 これはノイズマージンと呼ばれることもある。

同様に、最大の出力LOW電圧(VOL)は0.4Vである。 つまり、logic 0を送ろうとするデバイスの出力は、常に0.4V未満になるということである。 最大の入力LOW電圧(VIL)は0.8Vである。 つまり、0.8V未満の入力信号は、デバイスに読み込まれる際にlogic 0(LOW)と見なされる。

では、0.8Vから2Vの間の電圧だった場合はどうなるのだろうか。 正直なところ、それは誰にも分からない。 この範囲の電圧は未定義であり、「フローティング」とも呼ばれる無効な状態になる。 デバイスの出力ピンがこの範囲で「フローティング」している場合、その信号がどうなるかはまったく保証されない。 HIGHとLOWの間を不規則に行き来することもある。

汎用的なTTLデバイスの入出力の許容範囲を、別の視点から見てみよう。

もうひとつよく出会う電圧規格として、3.3Vのデバイスがある。

3.3V CMOSのロジックレベル

技術の進歩とともに、消費電力が少なく、より低い基準電圧(Vcc = 5Vではなく3.3V)で動作するデバイスが作られるようになった。 3.3Vデバイスの製造技術も5V用のものとは少し異なっており、より小さなフットプリントと、システム全体のコスト削減を実現している。

一般的な互換性を確保するため、電圧レベルのほとんどは5Vデバイスとほぼ同じ値になっていることに気づくはずである。 3.3Vデバイスは、追加の部品なしに5Vデバイスとやり取りできる。 たとえば、3.3Vデバイスが出力するlogic 1(HIGH)は少なくとも2.4Vになる。 これはVIHの2Vを上回っているため、5Vシステムからも問題なくlogic 1(HIGH)と解釈される。

ただし、逆方向、つまり5Vデバイスから3.3Vデバイスに接続する場合は注意が必要であり、その3.3Vデバイスが5V耐性を持っているかを必ず確認すること。 ここで確認すべき仕様は、最大入力電圧である。 一部の3.3Vデバイスでは、3.6Vを超える電圧をかけると、チップに恒久的な損傷を与えてしまう。 5V信号を3.3Vレベルまで下げるには、簡単な分圧回路(1kΩと2kΩの組み合わせなど)を使うか、ロジックレベルシフターのような専用の部品を使うとよい。

Arduinoのロジックレベル

ATmega328(Arduino UnoやSparkFunのRedBoardの中核を担うマイクロコントローラ)のデータシートを見ると、電圧レベルが少し異なっていることに気づくはずである。

Arduinoは、もう少し余裕を持たせたプラットフォームの上に構築されている。 もっとも顕著な違いは、無効な電圧の範囲が1.5V〜3.0Vの間だけに収まっている点である。 Arduinoのほうがノイズマージンが大きく、LOW信号として認識されるしきい値も高い。 これにより、他のハードウェアとのインターフェースの構築がずっと簡単になる。

まとめ

これで、電子工学でもっともよく使われる概念のひとつを理解できたはずである。 ここからさらに学べる新しい世界が広がっている。

Arduinoのようなマイクロコントローラが、分圧回路から得られるアナログ電圧をどうやって読み取るのか気になるなら、アナログ-デジタル変換のチュートリアルを確認してみてほしい。

さまざまなレベルの電圧を使って他の機器を制御する方法については、パルス幅変調(PWM)のチュートリアルで学べる。

異なるロジックレベルの間を切り替えるために、分圧回路ロジックレベルコンバータを使う方法にも興味があるかもしれない。 関連するチュートリアルとしては、次のようなものがある。

  • シリアル通信:非同期シリアル通信の概念(パケット、信号レベル、ボーレート、UARTなど)を扱う。
  • 分圧回路:大きな電圧を小さな電圧に変換する分圧回路について、実際の回路や使われ方を解説する。

より高い電圧で動作する機器を制御したい場合は、トランジスタやリレーを追加するという方法もある。

  • トランジスタ:バイポーラ接合トランジスタの短期集中講座。トランジスタの仕組みと、どのような回路で使われるかを学べる。

タグ: 概念、電気工学


出典:Logic Levels(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

LogicBlocksとデジタルロジック入門

デジタルエレクトロニクスの世界を動かしている原動力、デジタルロジックに実際に触れてみよう。 LogicBlocksキットは、デジタルロジックを発見し、その仕組みを目で見て確かめ、それが何を作り出せるのかを探るための入り口である。

このチュートリアルは、キットに同梱されている「LogicBlocks Kit Information」の小冊子の内容をもとにしており、その一部をここでも改めて紹介する。 すでにLogicBlocksキットに慣れ親しんでいるなら、1〜3章は読み飛ばして、実験編に直接進んでもかまわない。

このチュートリアルで扱う内容:

  1. デジタルロジックとは何か
  2. LogicBlocksの基礎
  3. 各ブロックの詳細

参考になるチュートリアル:

LogicBlocksに取り組む前に、次のチュートリアルを先に読んでおくことをおすすめする。

  • アナログとデジタルの違い:アナログ信号とデジタル信号の違いを扱うチュートリアル。ここではデジタルロジックについて多く語ることになるため重要である。
  • デジタルロジック:デジタルロジックの理論をさらに深く学びたいなら、このチュートリアルを確認してほしい。
  • 2進数:2進数はコンピュータの言語である。デジタルロジックは、2進数を足し合わせたり保存したりするために使う道具である。

デジタルロジックとは何か

デジタルとは何か

電子的な信号は、アナログとデジタルという2つのカテゴリーに分けられる。 アナログ信号はどんな形も取ることができ、無限の値を表現できる。 デジタル信号は、非常にはっきりと定義された、離散的な値の集合しか取らない。たいていはたった2つだけである。

多くの電子システムはアナログとデジタルの回路を組み合わせて使っているが、たいていのコンピュータや日常的な電子機器の中心にあるのは、離散的なデジタル回路である。

デジタルロジックとは何か

私たち人間は(たいてい)論理的な存在である。 何かを決断し、それに基づいて行動するとき、その裏では論理が働いている。 論理とは、1つ以上の入力を評価し、いくつもの結果と照らし合わせて、進むべき道筋を決めるプロセスのことである。 私たちがあらゆる決断に論理を用いているのと同じように、コンピュータもデジタルロジック回路を使って決断を下している。 コンピュータは、決断を伝えるために標準的な論理ゲートの組み合わせを使っている。

デジタルロジックについてさらに深く知りたい場合は、デジタルロジックのチュートリアルを確認してほしい。

デジタルロジックはどこで見られるか

デジタルロジックは、あらゆる回路の中に存在する。 電源への接続はANDの一例である。電源とグラウンドの両方が接続されて初めて、回路に電気が流れる。

他にはどこにあるだろうか。至るところにある。 街の信号機は、歩行者が「歩行者用ボタン」を押したときに論理を使っている。 このボタンは、ANDの論理ゲートを使ったプロセスを起動する。 歩行者が歩行者用ボタンを押し、なおかつその歩行者が渡ろうとしている方向の車道の信号が赤であれば、歩行者用の青信号が点灯する。 このAND文の2つの条件のどちらかが満たされなければ、歩行者用の青信号が点灯することは決してない。

入力と出力

デジタルロジック回路は、デジタルの入力を使って論理的な判断を下し、デジタルの出力を作り出す。 どんな論理回路も、何らかの出力を作り出す前に、少なくとも1つの入力を必要とする。

デジタルロジックの入力と出力は、たいてい2進数である。 つまり、取りうる値は2通りしかないということである。

2進数の値を表す方法にはいくつかの種類がある。 もっとも簡潔で一般的なのは1/0という表記だが、TRUE/FALSE(真/偽)やHIGH/LOW(ハイ/ロー)というブール値としての表記を見かけることもある。 ハードウェアのレベルでこれらの値を表すときは、実際の電圧レベルが割り当てられることもある。0V(ボルト)が0を表し、それより高い電圧(たいてい3Vや5V)が1を表す。

10
HIGHLOW
TrueFalse
5V0V

論理ゲート

コンピュータが論理的な判断を下すには、AND、OR、NOTという3つの基本的な論理関数の組み合わせを使う。

  • AND:すべての入力がTRUEである場合、かつその場合に限り、TRUEを出力する
  • OR:入力のうちいずれか(1つ以上)がTRUEであれば、TRUEを出力する
  • NOT:唯一、入力を1つしか持たない演算子である。NOT演算子は入力を否定する。つまり、出力は入力の反対になる

これらの関数はそれぞれ、論理ゲートを使って実現できる。 論理ゲートは、デジタルロジック回路を作るために使われるものであり、コンピュータやその他の電子機器を構成する基本的な部品である。 論理ゲートは1つ以上の入力を受け取り、特定の関数(AND、OR、NOTなど)をそれらに適用し、その関数に基づいて出力を生み出す。

論理ゲートには、抵抗器やコンデンサ、インダクタと同じように、それぞれ固有の回路図記号がある。 そして、標準的な電子部品の記号と同じように、論理ゲートも入力線と出力線をつなぎ合わせることで回路図の中に描くことができる。

真理値表

論理ゲートや論理関数の「論理」は、真理値表、ベン図、ブール代数など、いくつかの方法で表すことができる。 その中でも、真理値表がもっとも一般的である。 真理値表とは、考えられるすべての入力の組み合わせと、それに対応する出力を漏れなく一覧にしたものである。

すべての入力は表の左側に、出力は右側に並べられる。 表の各行が、ひとつの入力の組み合わせに対応する。

入力A入力B出力Y
000
010
100
111

上の表はANDゲートの真理値表である。 ANDゲートは2つの入力と1つの出力を持つため、真理値表には入力用の列が2つ、出力用の列が1つある。 入力が2つあるということは、0/0、0/1、1/0、1/1という4通りの入力の組み合わせがあるということである。 そのため、ANDゲートの真理値表には、それぞれの入力の組み合わせに対応する4行がある。 ANDの出力が1になるのは、両方の入力がともに1である場合だけである。

LogicBlocksの基礎

LogicBlocksには6種類のブロックがあり、論理ゲート、入力ブロック、ユーティリティブロックという3つのカテゴリーに分けられる。

論理ゲートブロック

論理ゲートのLogicBlocksには、AND、OR、NOTという3つの基本的な論理ゲートがある。 これらはできる限り、対応する回路図記号に似せた形になっており、ゲート名のラベルも付いている。

それぞれのゲートには1つの出力(先端がとがったオスのヘッダー)がある。 メスのヘッダーは入力を表しており、ANDゲートとORゲートには2つの入力が、NOTゲートには1つの入力がある。

論理ゲートのLogicBlocksにはそれぞれLEDが付いており、出力の状態を表している。 LEDが点灯していれば、そのゲートは1を出力しており、消灯していれば0を出力していることになる。

入力ブロック

入力ブロックは、LogicBlocksにデジタルの入力を与えるために使う。 入力ブロックの出力を0か1に切り替えるスイッチが付いている。 入力ブロックのLEDは、そのブロックが送り出している値を表示する。

入力ブロックには1つのオスの出力ヘッダーがあり、これをゲートブロックのメスの入力に差し込んで使う。

ユーティリティブロック(とケーブル)

ユーティリティブロックの中でも重要なのが電源ブロックである。 それぞれの論理ゲートは動作するために電源を必要とし、この基板がそれを供給する役割を担う。 電源ブロックには1つのメスの入力ヘッダーがあり、回路の最後の論理ゲートの出力に接続する。 1つのデジタルロジック回路全体に対して必要な電源ブロックは、たった1つだけである。

分配ブロックというLogicBlocksもあり、これは1つの入力を2つの出力に分けるだけの役割を持つ。 信号に対して何か演算を行うわけではなく、単に通過させるだけである。 1つの入力を2つ以上の論理ゲートに流し込む必要がある、より複雑なデジタルロジック回路を作るときに便利である。

このカテゴリーにはフィードバックケーブルも含まれる。 このケーブルは、より高度なLogicBlocks回路において、たいてい分配ブロックと組み合わせて使われる。

ルール

LogicBlocksを扱ううえでのルールは、実質的にひとつだけである。 あるブロックの出力を別のブロックの入力に接続するとき、3本のピンがそれぞれ正しく一致するようにすることである。 それぞれの入力と出力は、電源(+)、グラウンド(-)、信号(→)という3本のピンで構成されている。

また、LogicBlocks回路には常に電源ブロックがちょうど1つだけ接続されている必要がある。

論理ブロック(あるいはケーブル)のすべての入力には、別のブロック(あるいはケーブル)の出力を接続しておく必要がある。 入力が浮いたまま(未接続のまま)になっていると、そのゲートは入力が1なのか0なのかを判別できず、結果として出力が不安定になってしまう。

応答時間

論理ゲートは、人間には到底感知できないほどの速さ(ナノ秒単位)で出力の判断を下す。 そこでLogicBlocksでは、その過程を目に見えるようにするため、あえて動作を遅くしてある。 LogicBlocksを長く連ねた場合、この遅延のおかげで、あるブロックの結果が別のブロックの入力にどう影響するかを視覚的に確認しやすくなる。

この遅延はおよそ0.5秒程度である。 何が起きているかを見るのにちょうどよい長さである。

各ブロックの詳細

ここでは、LogicBlocksキットに含まれる各部品の細かい仕様を見ていく。 それぞれのブロックの役割、真理値表、そして他にどのブロックと組み合わせられるかを確認する。

入力LogicBlock

入力ブロックは、LogicBlocksの世界を動かす原動力である。 この小さな長方形のブロックには1つのオスコネクタがあり、ゲートブロック、電源ブロック、分配ブロックのメスの入力ピンに差し込むことができる。

それぞれの入力ブロックには2ポジションのスイッチがあり、これを使ってブロックを1または0(TRUEまたはFALSE、ONまたはOFF)に設定する。

入力ブロックの緑色のLEDは、そのブロックが出力している値を表す。 LEDが点灯していれば、そのブロックは1に設定されていることを示す。 LEDが消灯していれば、出力値は0である。

ANDゲートLogicBlock

ANDのLogicBlockは、2入力1出力のANDゲートである。 このブロックはANDゲートの回路図記号によく似た「D字型」をしている。 2つのメスの入力ヘッダーはANDブロックの両側にあり、出力は上部中央にある。

これらの入力には、入力ブロックまたは別のゲートブロックの出力を接続できる。 オスの出力ヘッダーは、別のゲートの入力、あるいは電源ブロックに接続できる。

それぞれのANDゲートブロックには青色のLEDが1つ付いており、ゲートの出力を表す。 LEDが点灯していれば、そのANDゲートは出力として1(TRUE、ON)を出していることを意味する。 LEDが消灯していれば、ANDゲートの出力は0である。

ANDの真理値表、回路記号、ブール記法

ANDブロックの真理値表は次のとおりである。

入力A入力B出力
000
010
100
111

そして、これからよく目にすることになるANDゲートの回路記号がある。 ANDのブール式の記号は中点(·)である。 たとえば上のゲートは、A · B = Yという式で表せる。

ORゲートLogicBlock

ORのLogicBlockは、2入力1出力のORゲートである。 このブロックはORゲートの回路図記号のような形をしており、出力側が凸型の弧、入力側が凹型の弧になっている。 2つのメスの入力はORブロックの両側にあり、出力はブロック上部中央にある。

2つの入力のどちらにも、入力ブロックまたは別のゲートブロックの出力を接続できる。 このオスの出力コネクタは、別のゲートの入力、あるいは電源ブロックに接続できる。

それぞれのORゲートブロックには黄色のLEDが1つ付いており、ゲートの出力を表す。 LEDが点灯していれば、そのORゲートは出力として1(TRUE、ON)を出していることを意味する。 LEDが消灯していれば、ORゲートの出力は0である。

ORの真理値表、回路記号、ブール記法

2入力1出力のORゲートの真理値表は次のとおりである。

入力A入力B出力
000
011
101
111

そして、ブロック自体の形によく似た回路記号がある。 ORのブール式の記号はプラス記号(+)である。 上のOR回路は、A + B = Yというブール式で表せる。

NOTゲートLogicBlock

NOTのLogicBlockは、1入力1出力のNOTゲートである。 このブロックは台形の形をしている(三角形のNOTゲート回路記号にできるだけ近づけた形である)。 メスの入力コネクタは辺の長いほうの側にあり、出力は辺の短いほうの側にある。

この入力には、入力ブロックまたは別のゲートブロックの出力を接続できる。 このオスコネクタは、別のゲートの入力、あるいは電源ブロックに接続できる。

それぞれのNOTブロックには赤色のLEDが1つ付いており、ゲートの出力を表す。 LEDが点灯していれば、そのNOTゲートは出力として1(TRUE、ON)を出していることを意味する。 LEDが消灯していれば、NOTゲートの出力は0である。

NOTの真理値表、回路記号、ブール記法

NOTゲートは受け取った信号を反転させるため、インバータとも呼ばれることが多い。 0は1に、1は0に変わる。 インバータの真理値表はおおよそ次のようになる。

入力A出力
01
10

ブール式を書くとき、NOT演算はたいてい、反転させる変数の上に引かれたバー(横線)で示される。 たとえば上の回路のブール式は、単純にAの上に横線を引いた形で表される。

電源LogicBlock

電源なしに動作する電子回路は存在しない。そこで登場するのが電源ブロックである。

電源ブロックは、1枚の20mmコイン電池で動作し、最適な状態でおよそ3Vを供給し、かなり長持ちする。 LogicBlocksは2V〜5Vの範囲で動作し、消費電流もごくわずかである。

電源ブロックには1つのメスコネクタがあり、ゲートブロックの出力に接続する。 どの回路でも、接続してよい電源ブロックは1つだけである。

電源ブロックは、あらゆるLogicBlocks回路の最後のピースである。 一連の論理ゲートのうち、一番最後のゲートの出力に接続する必要がある。

分配LogicBlockとフィードバックケーブル

分配ブロックを使うと、1つのブロックの出力を2つの別々のブロックの入力に流し込むことができる。

より高度な回路を作る際には、複数のゲートに入力を分配したり、フィードバックを加えたりしたくなることがある。 そんなときに役立つのが、分配ブロックとフィードバックケーブルである。 フィードバックケーブルは、たいてい分配ブロックの2つの出力のうちの一方に接続して使われる。

フィードバックケーブルは、赤、黄、黒の3本の配線でできている。 赤は必ず+ピンに、黒は-ピンに接続し、黄色は信号をそのまま通過させる。

まとめ

LogicBlocksとデジタルロジックの基礎を学んだところで、いよいよ実験の時間である。 LogicBlocks Experimenter’s Guideでは、ここまでに紹介したわずかな部品を使って、2対1マルチプレクサをはじめとする、あらゆる基本的な論理回路を組み立てていく。

タグ: 概念、電気工学


出典:LogicBlocks & Digital Logic Introduction(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

16進数

たった10種類の数字だけで数を表すことに、窮屈さを感じたことはないだろうか。 あるいは、大きな数をもっと少ない桁数で表したいと思ったことは。 それとも、催眠術のように続く2進数の1と0の羅列を見ずに、バイトの値をぱっと見分けたいと思ったことは。 こうした用途では、16進数がエンジニアの好んで使う数体系になることが多い。

16進数(Hexadecimal16進法Hexヘックス、Base16とも呼ばれる)は、数値を書き表し、共有するために使える数体系である。 その点では、私たちが日常的に使っているもっとも有名な数体系である10進数と何も変わらない。 10進数は基数10の数体系であり(指が10本ある私たちにはぴったりである)、10種類の固有の数字を組み合わせて、位取りによって数を表現する。

16進数も、10進数と同じように、複数の数字を組み合わせて大きな数を作る。 ただし16進数では、16種類の固有の数字を使う。 0から9までの標準的な数字に加えて、A、B、C、D、E、Fという、通常は数として見慣れない6つの文字も使う。

このほかにも(無限に)さまざまな数体系が存在する。 2進数(基数2)も、コンピュータの言語であることから工学の世界でよく使われる。 基数2、つまり2進数の体系は、0と1というたった2つの数字の値だけで数を表す。

16進数は、10進数や2進数と並んで、電子工学やプログラミングの世界でもっともよく出会う数体系のひとつである。 多くの場合、2進数や10進数よりも16進数で数を表すほうが理にかなっているため、16進数の仕組みを理解しておくことは重要である。

このチュートリアルで扱う内容:

  • 16進数の基本:16進数で使う16種類の数字、16進数の表し方、16進数での数え方を扱う
  • 10進数との相互変換:10進数と16進数を変換するおすすめの方法を扱う
  • 2進数との相互変換:2進数と16進数の変換方法を紹介する
  • 変換用の計算ツール:16進数、2進数、10進数を相互に変換できる簡単な自動計算ツールを紹介する

参考になるチュートリアル:

このチュートリアルに取り組む前に、10進数についてある程度知っておく必要がある。 筆算の割り算を覚えているだろうか。余り、商、積、和、指数といった概念は、16進数と10進数の関係を学ぶ際に、また必要になってくる。

算数のおさらいに加えて、このチュートリアルの前に(あるいは並行して)2進数のチュートリアルを読んでおくことをおすすめする。

16進数の基本

ここでは16進数のごく基本的な部分、つまり16進数を表すのに使う数字の一覧と、ある数が16進数であることを示すための表記方法を扱う。 また、16進数での数え方という形で、非常に単純な「10進数から16進数への」変換も扱う。

数字:0-9とA-F

16進数は基数16の数体系である。 つまり、数を表すのに使える数字が16種類あるということである。 そのうち10種類は10進数でおなじみの数字、0、1、2、3、4、5、6、7、8、9であり、これらはそれぞれ見慣れた値と同じ値を表す。 残りの6種類はA、B、C、D、E、Fで表され、それぞれ10、11、12、13、14、15という値に対応している。

A〜Fは大文字と小文字のどちらの表記も見かけるはずである。 どちらも問題ない。 大文字か小文字かについて、それほど厳密な標準は決まっていない。 A3Fa3fA3fも、すべて同じ数を表している。

下付き文字

10進数と16進数には共通する10種類の数字があるため、非常によく似た見た目の数がたくさんできてしまう。 しかし16進数の10は、10進数の10とはまったく異なる数である。 実際、16進数の10は10進数の16に相当する。 そのため、ある数が基数10なのか基数16なのか(あるいは基数8や基数2なのか)を明示する方法が必要になる。 そこで登場するのが基数の下付き文字である。

これから見ていくように、下付き文字だけが数の基数を明示する方法ではない。 下付き文字は、もっとも文字どおりに基数を示す方式のひとつにすぎない。

16進数での数え方

16進数での数え方は10進数での数え方とよく似ているが、扱う数字が6つ多い。 ある桁が「F」を超えると、その桁は「0」に戻り、左隣の桁が1つ繰り上がる。

実際に数えてみよう。

10進数16進数10進数16進数
0088
1199
2210A
3311B
4412C
5513D
6614E
7715F

16進数のF₁₆に達すると、10進数で9₁₀から10₁₀に繰り上がるのと同じように、16進数でも10₁₆に繰り上がる。

10進数16進数10進数16進数
16102418
17112519
1812261A
1913271B
2014281C
2115291D
2216301E
2317311F

そして1F₁₆に達すると20₁₆に繰り上がり、再び一番右の桁が0からFまで巡っていく。

16進数を表す識別子

「0x47DE」なのか「#47DE」なのか、それとも単に47,222という10進数を意味しているのか。 このような混乱を避けるため、16進数にはたいてい、それが16進数であることを示す識別子が前後に付けられる。

識別子備考
0x0x47DEUNIXやC系のプログラミング言語(Arduinoも含む)でよく見かける接頭辞である
##FF7734HTMLや画像編集ソフトでの色の指定によく使われる
%%20URLの中で「スペース」(%20)のような文字を表すのによく使われる
\x\x0A「バックスペース」(\x08)、「エスケープ」(\x1B)、「改行」(\x0A)のような制御コードを表すのによく使われる
&#x&#x3A9HTML、XML、XHTMLでUnicode文字を表すのに使われる(たとえばΩはΩと表示される)
0h0h5ETI-89のような、多くのプログラム可能なグラフ電卓で使われる接頭辞である
下付きの数字や文字BE37₁₆、13F₁₆基数16の数をより数学的に表す方式である。10進数は下付きの10(基数10)で、2進数は基数2で表せる

このほかにも、特定のプログラミング言語に固有の接頭辞や接尾辞がいくつも存在する。 たとえばアセンブリ言語では、「H」や「h」という接尾辞(7Fhなど)や、「$」という接頭辞($6ADなど)が使われることがある。 自分が使っているプログラミング言語でどの接頭辞や接尾辞を使うべきか分からない場合は、サンプルコードを参照してほしい。

「0x」という接頭辞は、特にArduinoのプログラミングをしていると頻繁に見かけることになる。 このチュートリアルでも、以降はこの表記を使うことにする。

10進数との相互変換

ここまでで、16個ほどの値を10進数と16進数の間で変換する方法は分かったはずである。 もっと大きな数を変換するには、いくつかのコツがある。

10進数から16進数への変換

10進数から16進数への変換には、割り算と余りを多用する。 筆算の割り算をすっかり忘れてしまった場合は、Wikipediaなどでおさらいしておくとよい。

ある数(Nとする)を10進数から16進数に変換する手順は、次のようになる。

  1. Nを16で割る。その割り算の余りが、求める16進数の最初の桁(最下位、つまり一番右の桁)になる。(割り算の結果)を次のステップに使う。
    • 注意:余りが10、11、12、13、14、15になった場合は、それぞれ16進数の数字A、B、C、D、E、Fになる。
  2. 前のステップで得た商をさらに16で割る。この割り算の余りが、16進数の2桁目(右から2番目)になる。この割り算で得た商を次のステップに使う。
  3. ステップ2で得た商をさらに16で割る。この割り算の余りが、16進数の3桁目になる。パターンが見えてきただろうか。
  4. 前のステップで得た商を16で割り続け、その余りを記録していく。これを割り算の結果が0になるまで続ける。その最後の割り算の余りが、16進数の一番左、つまり最上位の桁になる。

10進数から16進数への変換例:61453を変換する

言葉での説明はこれくらいにして、実際に例を計算してみよう。 61453₁₀を16進数に変換してみる。

  1. 61453を16で割ると、商は3840余りは13になる。この余りが、求める16進数の一番右、つまり最下位の桁になる。13はAではなくDなので、最初の桁はDである。3840を次のステップに使う。
  2. 次に3840を16で割ると、商は240、余りは0になる。2桁目は0であり、240を次の桁の計算に使う。
  3. 240を16で割ると、15になり、余りはまた0になる。3桁目は0であり、15をステップ4に使う。
  4. 最後に、15を16で割る。ここでようやく商が0になり、余りは15になる。この余りは、この桁の16進数がFであることを意味する。

最後に、得られた4つの16進数の桁をすべて組み合わせると、求める16進数の値が得られる:0xF00D

16進数から10進数への変換

16進数から10進数への変換を支配する、少々ややこしい数式がある。

値 = hn×16ⁿ + hn-1×16ⁿ⁻¹ + … + h1×16¹ + h0×16⁰

この式にはいくつかの重要な要素がある。 それぞれのhの項(hnhn-1など)は、16進数の値の1桁を表している。 たとえば16進数の値が0xF00Dであれば、h0はD、h1h2は0、h3はFである。

16の累乗は16進数において非常に重要な要素である。 より重要度の高い桁(数の左側にある桁)ほど、より大きな16の累乗が掛けられる。 最下位の桁であるh0には16⁰(つまり1)が掛けられる。 16進数の値が4桁であれば、最上位の桁には16³、つまり4096が掛けられる。

16進数を10進数に変換するには、先ほどの式のそれぞれのhに値を当てはめる必要がある。 そして各桁に対応する16の累乗を掛け、それらをすべて足し合わせる。 手順は次のとおりである。

  1. 16進数の値の一番右の桁から始める。それに16⁰、つまり1を掛ける。つまり、そのままの値を脇に置いておく。
    • アルファベットの16進数(A、B、C、D、E、F)は、対応する10進数の値(10、11、12、13、14、15)に変換するのを忘れないこと。
  2. 1桁左に移動する。その桁に16¹、つまり16を掛ける。その積を覚えておき、脇に置いておく。
  3. さらに1桁左に移動する。その桁に16²(256)を掛け、その積を記録しておく。
  4. 16進数の値の各桁を、増えていく16の累乗(4096、65536、1048576……)で掛け続け、それぞれの積を記録していく。
  5. 16進数のすべての桁に対応する16の累乗を掛け終えたら、それらをすべて足し合わせる。その合計が、その16進数に相当する10進数の値である。

16進数から10進数への変換例:0xC0DEを変換する

4桁の16進数、0xC0DEを10進数に変換する例を見てみよう。 表を作り、各桁を別々の列に並べると、変換作業がしやすくなる。

桁の位置(n)3210
並べた16進数の桁C0DE
A〜Fを変換1201314
16ⁿを掛ける12×16³0×16²13×16¹14×16⁰
得られた積49152020814

これらの積をすべて足し合わせると、49152 + 0 + 208 + 14 = 49374になる。

つまり、C0DE₁₆ = 49374₁₀である。

この表を使う方法は、16進数の各桁、位置、16の累乗を整理して把握するのに最適である。 もっと大きな16進数を変換したい場合は、左に列を追加してnを増やしていくだけでよい。

手計算のやり方が分かったところで、時間を節約するために計算ツールを使ってみるのもよいだろう。

2進数との相互変換

一安心してほしい。面倒な変換はもう終わりである。 電気工学やコンピュータ工学で16進数が使われるのは、コンピュータの言語である1と0、つまり2進数との相互変換が非常に簡単だからである。

16進数と2進数の変換が簡単なのは、16進数の各桁が2進数の4ビット(ビットとは1個の2進数の桁のこと)にちょうど対応しているためである。 つまり1バイト(8個の2進数の桁)は、常に2桁の16進数で表せるということである。 これにより、16進数は1バイトやそのまとまりを表すのに、非常に簡潔で便利な方法になっている。

2進数から16進数への変換

まず、最初の16個の16進数の値を2進数に対応付けてみよう。

10進数16進数2進数10進数16進数2進数
00000000881000
01100010991001
022001010A1010
033001111B1011
044010012C1100
055010113D1101
066011014E1110
077011115F1111

16進数や2進数を使い続けるうちに、これら16個の値は自然と頭に染みついていくはずである。 これが、2進数と16進数を変換するための鍵になる。

2進数と16進数を変換するには、4つの2進数の桁(ビット)が1つの16進数の桁に対応するという性質を利用する。 2進数から16進数へ変換するには、次の手順に従う

  1. 2進数の値を、右端から4桁ずつのグループに分割する。
  2. それぞれの4桁のグループについて、先ほどの表を参照して対応する16進数の値を見つけ、4桁の2進数のグループをその1つの16進数の値に置き換える

これだけである。実際にやってみよう。

2進数から16進数への変換例:0b101111010100001を変換する

まず、2進数の一番右端から始めて、1と0を4桁ずつのグループに分ける。

0101 1110 1010 0001

次に、先ほどの表を参照して、それぞれの4桁のグループを16進数の桁に変換する。

0101 → 5
1110 → E
1010 → A
0001 → 1

これで完成である。0b101111010100001 = 0x5EA1となる。

16進数から2進数への変換

16進数から2進数への変換は、2進数から16進数への変換とよく似ている。 16進数の桁を1つずつ取り出し、それぞれを4桁の2進数に変換していく。 これを、数がすべて0と1で埋まるまで繰り返す。

16進数から2進数への変換例:0xDEADBEEFを変換する

0xDEADBEEF(システムクラッシュを示すためによく使われるコードである)を変換するには、まず桁を1つずつ「箱」に振り分ける。

D E A D B E E F

そして、それぞれの16進数の桁を4ビットに変換する。

D → 1101
E → 1110
A → 1010
D → 1101
B → 1011
E → 1110
E → 1110
F → 1111

つまり、0xDEADBEEF = 0b11011110101011011011111011101111となる。1と0がたくさん並ぶことになる。

バイトを表現し識別するための16進数

これまでの例は、16進数が持つ大きな強みのひとつ、バイトの値を簡単に表せるという点を示している。 16進数の値は、長く続く1と0の並びよりも短く覚えやすいため、扱いやすいことが多い。

たとえば上のレジスタマップは、LSM9DS0(優れた9軸センサー)のものである。 このセンサーを制御するために使われるレジスタアドレスが、16進数と2進数の両方で一覧になっている。 CTRL_REG2_Gレジスタにアクセスしたい場合、0b010001と覚えるより0x21と覚えるほうがずっと簡単であり、16進数の値のタイプミスを見つけるのも2進数の場合よりずっと簡単である。 そのため、コードの中では2進数よりも16進数の値を使うことのほうが圧倒的に多い。

まとめ

16進数の仕組みを理解することは、電子工学やプログラミングの実に多くの分野にとって欠かせない。

16進数の新しい知識を身につけたところで、次のような関連するチュートリアルも確認してみてほしい。

  • デジタルロジックShift registers(シフトレジスタ):これらのチュートリアルは、16進数をより大きく一般的な電子工学の概念の土台として使っている。デジタルロジックは、コンピュータが行うあらゆる判断の中核である。シフトレジスタは、1つの入力や出力を8個以上に分配するのに使える。
  • I2CSPI:これらの通信インターフェースは、ほぼ必ず何らかの形で16進数を使う。SPIやI2Cで通信する機器はたいてい一連のレジスタを持ち、それぞれ16進数のアドレスに対応付けられている。I2Cデバイスにはそれぞれ固有の7ビットアドレスが割り当てられており、たいてい16進数で表記される。
  • バイナリブラスターの組み立てガイド:16進数の変換を練習したいなら、Binary Blaster Kitが役立つ。これははんだ付けが必要なキットである。組み立てたら、それを使って2進数、16進数、10進数の関係についての理解度を試すことができる。

タグ: 通信、コンピュータ工学、概念、プログラミング


出典:Hexadecimal(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

ASCII

コンピュータが2進数で動作しているとしたら、文字や単語をどうやって保存しているのだろうか。 それを実現するために、私たちは文字に数を割り当てている。 これは文字コード化と呼ばれる。

文字コード化がどのように機能するかを理解するために、簡単な例を作ってみよう。 まず、アルファベットに1から26までの数字を割り当てる。

1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z

簡単な暗号メッセージを書くには、文字を数字に置き換える。 たとえば 8 5 12 12 15 である。 数字を使うことで、h e l l o という単語を作り出すことができる。

しかし、大文字と小文字のアルファベット、数字、句読点まで含めた英語のアルファベット全体を表すには、26文字だけでは足りない。 そこで生まれたのが、コンピュータ向けの初期の文字コード化規格のひとつであるAmerican Standard Code for Information Interchange(ASCII)である。

このチュートリアルで扱う内容:

  • ASCIIの簡単な歴史
  • 10進数、2進数、16進数をASCIIに変換する方法

参考になるチュートリアル:

このガイドを読み始める前に、知っておくとよい概念がいくつかある。

  • 2進数:コンピュータが数をどのように保存しているかを知っておくと、その数を文字に変換する際に役立つ
  • 16進数:16進数は、2進数を4ビットずつのまとまりで表すためによく使われる
  • Installing Arduino IDE(Arduino IDEのインストール):ASCII文字を表示してみるには、Arduinoを使うのがよい方法である

歴史

アメリカ規格協会(ASA、現在のアメリカ規格協会ANSI)は、1960年10月6日にASCIIの策定に着手した。 この符号化方式は、エミール・ボードーが考案した5ビットの電信符号に起源を持つ。 委員会は最終的に、ASCIIを7ビットの符号として採用することを決めた。

7ビットあれば128文字を表現できる。 この符号化方式にはアメリカ英語の文字と記号だけが選ばれたが、7ビットにしたことで、(たとえば8ビットにする場合と比べて)データ伝送にかかるコストを抑えることができた。

ASCIIの最初の32文字は、制御文字として予約されている。 これらの文字は、プリンターのような他の機器に特別な指示を伝えるために使われた。 たとえば、改行したり、文字を削除したり、機器によってはベルを鳴らしたりすることができた(Teletype Model 33 ASRなどがその例である)。

ASAは1963年に最初のバージョンのASCIIを発表し、1967年に改訂した。 この規格への最後の大きな更新は1986年に行われた。 ASCIIが最初に商用で使われたのは、AT&T(American Telephone & Telegraph)のTWX(テレタイプライター交換)ネットワークだった。

1968年3月11日、リンドン・B・ジョンソン大統領は、アメリカ連邦政府のすべてのコンピュータがASCIIをサポートすることを義務付け、これによりASCIIはアメリカのコンピュータ史における確固たる地位を築いた。

当時は国際電信アルファベット No.2 (International Telegraph Alphabet No.2: ITA2)(ITA2)のような他の符号化方式も存在していたが、ASCIIはすぐにアメリカ英語の符号化における標準となった。 ASCIIは、2007年にUTF-8に追い抜かれるまで、インターネット上でもっとも一般的な符号化方式だった。

ASCIIテーブル

ある文字のASCII値を調べるには、ASCIIテーブルを参照するのが一般的である。 ASCIIテーブルは、それぞれの文字を0から127までの割り当てられた値と対応付けている。

制御文字

制御文字は、ASCIIテーブルの最初の32文字を占めている。 これらの文字は表示されることを意図しておらず、代わりにプリンターのような他の機器にコマンドの指示を送るために使われる。 非常に古いシステム(12ビットのPDP-8など)を扱う可能性もあるため、念のため8進数での表記も併記しておく。

10進2進8進16進文字説明
00000 000000000NULヌル文字
10000 000100101SOHヘディング開始
20000 001000202STXテキスト開始
30000 001100303ETXテキスト終了
40000 010000404EOT転送終了
50000 010100505ENQ照会
60000 011000606ACK肯定応答
70000 011100707BELベル
80000 100001008BSバックスペース
90000 100101109TAB水平タブ
100000 10100120ALF改行
110000 10110130BVT垂直タブ
120000 11000140CFF改ページ
130000 11010150DCR復帰
140000 11100160ESOシフトアウト
150000 11110170FSIシフトイン
160001 000002010DLEデータリンクエスケープ
170001 000102111DC1装置制御1
180001 001002212DC2装置制御2
190001 001102313DC3装置制御3
200001 010002414DC4装置制御4
210001 010102515NAK否定応答
220001 011002616SYN同期アイドル
230001 011102717ETB伝送ブロック終了
240001 100003018CAN取り消し
250001 100103119EM媒体終了
260001 10100321ASUB置換
270001 10110331BESCエスケープ
280001 11000341CFSファイル区切り
290001 11010351DGSグループ区切り
300001 11100361ERSレコード区切り
310001 11110371FUSユニット区切り
1270111 11111777FDEL削除

表示可能文字

ASCIIの符号化方式には95個の表示可能文字がある。 「space」の文字は、表示可能な空白(半角スペース)を表していることに注意してほしい。

10進2進8進16進文字
320010 000004020(半角スペース)
330010 000104121!
340010 001004222
350010 001104323#
360010 010004424$
370010 010104525%
380010 011004626&
390010 011104727
400010 100005028(
410010 100105129)
420010 10100522A*
430010 10110532B+
440010 11000542C,
450010 11010552D-
460010 11100562E.
470010 11110572F/
48〜570011 0000〜0011 1001060〜07130〜390〜9
580011 10100723A:
590011 10110733B;
600011 11000743C<
610011 11010753D=
620011 11100763E>
630011 11110773F?
640100 000010040@
65〜900100 0001〜0101 1010101〜13241〜5AA〜Z
910101 10111335B[
920101 11001345C\
930101 11011355D]
940101 11101365E^
950101 11111375F_
960110 000014060`
97〜1220110 0001〜0111 1010141〜17261〜7Aa〜z
1230111 10111737B{
1240111 11001747C|
1250111 11011757D}
1260111 11101767E~

実際に試してみる

ASCII符号化を使って何かを表示してみたいなら、Arduinoで試すことができる。 Arduinoを始めるには、Installing Arduino IDE(Arduino IDEのインストール)のチュートリアルを参照してほしい。

Arduino IDEを開き、次のコードを貼り付けてみよう。

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  Serial.write(0x48); // H
  Serial.write(0x65); // e
  Serial.write(0x6C); // l
  Serial.write(0x6C); // l
  Serial.write(0x6F); // o
  Serial.write(0x21); // !
  Serial.write(0x0A); // \n

  delay(1000);
}

これをArduinoで実行し、シリアルコンソールを開いてみよう。 「Hello!」が何度も表示されるはずである。

ここでSerial.print()ではなくSerial.write()を使っていることに注目してほしい。 write()コマンドは、シリアル回線に生のバイトをそのまま送信する。 一方print()は、その数値を解釈しようとし、ASCII符号化された文字列を送信しようとする。 たとえばSerial.print(0x48)は、コンソールに72と表示してしまう。

また、「ラインフィード」の制御文字である0x0AというASCII文字を使っていることにも注目してほしい。 これは、プリンター(ここではコンソール)に次の行へ進むよう指示する文字である。 「Enter」キーを押すのとよく似た働きをする。

まとめ

文字コード化の方式は数多く存在する。 World Wide Webでもっとも普及している符号化方式はUTF-8である。 2016年6月の時点で、UTF-8はすべてのウェブページの87%で使われている。

UTF-8はASCIIとの後方互換性を持っており、最初の128文字はASCIIとまったく同じである。 UTF-8は、ラテン文字、ギリシャ文字、キリル文字、アラビア文字、中国語、韓国語、日本語の文字を含む、現代のほとんどの書き言葉の文字を、2バイト、3バイト、4バイトを使って符号化できる。

基本的なASCII符号化の知識は、シリアルターミナルを扱う際にも役立つ。 数あるシリアルターミナルプログラムの使い方については、Serial Terminal Basics(シリアルターミナルの基礎)のチュートリアルを参照してほしい。

タグ: 通信、コンピュータ工学、概念、プログラミング


出典:ASCII(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

シリアル通信

組み込み電子工学とは、要するに回路(プロセッサやその他の集積回路)どうしを結びつけて、共生的なシステムを作り上げることである。 個々の回路が情報をやり取りするには、共通の通信プロトコルを共有していなければならない。 このデータ交換を実現するために、何百もの通信プロトコルが定義されてきたが、それらはおおむね、パラレル(並列)かシリアル(直列)かのどちらかに分類できる。

パラレルとシリアル

パラレルインターフェースは、複数のビットを同時に転送する。 たいてい、8本、16本、あるいはそれ以上の配線からなるバスを必要とし、大量の1と0の波を一度に送り出す。

シリアルインターフェースは、データを1ビットずつ順番に流していく。 これらのインターフェースは、わずか1本の配線だけで動作することもあり、たいてい4本を超えることはない。

この2つのインターフェースは、車の流れにたとえるとイメージしやすい。 パラレルインターフェースは8車線以上あるメガハイウェイであり、シリアルインターフェースは田舎の2車線道路のようなものである。 一定の時間で見れば、メガハイウェイのほうがより多くの人を目的地に送り届けられる可能性があるが、その田舎の2車線道路も十分に役目を果たし、しかも建設費用はごくわずかで済む。

パラレル通信には確かに利点がある。 高速で、単純で、比較的実装しやすい。 しかし、それだけ多くの入出力(I/O)線を必要とする。 基本的なArduino UnoからMegaへプロジェクトを移行したことがある人なら、マイクロプロセッサのI/O線がいかに貴重で数が限られているかを知っているはずである。 そのため、私たちはしばしば、ピン数の節約と引き換えに速度をある程度犠牲にする、シリアル通信を選ぶことになる。

非同期シリアル

長年にわたり、組み込みシステムの特定のニーズに応えるために、数十種類ものシリアルプロトコルが作られてきた。 USB(ユニバーサルシリアルバス)やイーサネットは、コンピュータの世界でよく知られたシリアルインターフェースの一例である。 このほかにも、SPI、I2C、そして今日ここで取り上げるシリアル規格が非常によく使われている。 これらのシリアルインターフェースは、いずれも同期式か非同期式かのどちらかに分類できる。

同期式のシリアルインターフェースは、データ線に必ずクロック信号を組み合わせるため、同期式シリアルバス上のすべての機器がクロックを共有する。 これにより、より単純で、たいてい高速なシリアル転送が実現できるが、通信する機器の間にもう1本配線が必要になる。 同期式インターフェースの例としては、SPIやI2Cがある。

非同期とは、外部のクロック信号の助けを借りずにデータを転送することを意味する。 この伝送方式は、必要な配線とI/Oピンの数を最小限に抑えるのに理想的だが、データの送受信を確実に行うために、多少の工夫が必要になる。 このチュートリアルで取り上げるシリアルプロトコルは、非同期転送のもっとも一般的な形式である。 あまりに一般的なため、たいていの人が「シリアル」と言うとき、実はこのプロトコルのことを指している(このチュートリアルを通じて、そのことに気づくはずである)。

このチュートリアルで扱うクロックを使わないシリアルプロトコルは、組み込み電子工学で広く使われている。 GPSモジュール、Bluetooth、XBee、シリアルLCDなど、外部デバイスをプロジェクトに追加したいなら、このシリアル通信の技を身につけておく必要があるだろう。

参考になるチュートリアル:

このチュートリアルは、次のようないくつかの、より基礎的な電子工学の概念の上に成り立っている。

これらの概念にあまり馴染みがない場合は、先にそちらを確認しておくとよい。

それでは、シリアル通信の旅に出かけよう。

シリアルのルール

非同期シリアルプロトコルには、堅牢でエラーのないデータ転送を保証するための、いくつかの組み込みルールがある。 外部のクロック信号を使わない代わりに得られるこれらの仕組みは、次のとおりである。

  • データビット
  • 同期ビット
  • パリティビット
  • ボーレート

これらのさまざまな信号方式を通じて、シリアルでデータを送る方法はひとつではないことが分かるはずである。 このプロトコルは非常に柔軟に設定できる。 重要なのは、シリアルバス上の両方の機器が、まったく同じプロトコル設定を使うようにすることである。

ボーレート

ボーレートは、シリアル線を通じてデータがどれだけ速く送られるかを指定する。 たいてい、bps(ビット毎秒)という単位で表される。 ボーレートの逆数を取れば、1ビットの送信にかかる時間が分かる。 この値によって、送信側がシリアル線をどれだけの時間HIGHまたはLOWに保つか、あるいは受信側がどの周期で線をサンプリングするかが決まる。

ボーレートは、常識の範囲内であればほぼどんな値でもよい。 唯一の要件は、両方の機器が同じ速度で動作していることである。 速度がそれほど重要でない単純な用途でよく使われるボーレートのひとつが、9600bpsである。 このほかにも1200、2400、4800、19200、38400、57600、115200といった「標準的な」ボーレートがある。

ボーレートが高いほど、データの送受信は速くなるが、転送速度には限界がある。 たいていのマイクロコントローラでは115200を超える速度を目にすることはあまりなく、これでも十分に速い。 これより速くしすぎると、クロックとサンプリング周期が追いつかなくなり、受信側でエラーが発生し始める。

データのフレーム化

送信される各データブロック(たいてい1バイト)は、実際にはパケットあるいはフレームと呼ばれるビットのまとまりとして送られる。 フレームは、データに同期ビットとパリティビットを付け加えることで作られる。

それでは、このフレームを構成する各部分を詳しく見ていこう。

データチャンク

すべてのシリアルパケットの中心となるのが、そこに含まれるデータである。 このデータのまとまりを、あえてチャンクとあいまいに呼んでいるのは、そのサイズが特に決まっていないからである。 1パケットあたりのデータ量は、5ビットから9ビットの間で自由に設定できる。 標準的なデータサイズはもちろん基本の8ビット(1バイト)だが、それ以外のサイズにもそれぞれ用途がある。 7ビットのデータチャンクは、7ビットのASCII文字だけを転送する場合など、8ビットより効率的なことがある。

文字の長さについて合意したら、両方のシリアル機器は、データのエンディアンについても合意する必要がある。 データは最上位ビット(msb)から送られるのか、それとも最下位ビット(lsb)からなのか。 特に明記されていない場合、たいていデータは最下位ビット(lsb)から先に転送されると考えてよい。

同期ビット

同期ビットは、それぞれのデータチャンクと一緒に転送される、2つまたは3つの特別なビットである。 これらはスタートビットストップビットである。 その名のとおり、これらのビットはパケットの始まりと終わりを示す。 スタートビットは常に1つだけだが、ストップビットの数は1つまたは2つに設定でき(たいてい1つのままにされる)。

スタートビットは、アイドル状態のデータ線が1から0に変化することで常に示され、ストップビットは線を1に保つことでアイドル状態へと戻る。

パリティビット

パリティは、非常に単純で低レベルなエラーチェックの一種である。 奇数パリティと偶数パリティの2種類がある。 パリティビットを求めるには、データバイトの5〜9ビットすべてを足し合わせ、その合計が偶数か奇数かによってビットを立てるかどうかを決める。 たとえば、パリティが偶数に設定されており、0b01011101(1の数が5個で奇数)というデータバイトに追加する場合、パリティビットは1に設定される。 逆に、パリティモードが奇数に設定されていれば、パリティビットは0になる。

パリティは任意であり、それほど広くは使われていない。 ノイズの多い伝送路でデータを送る際には役立つことがあるが、データ転送を多少遅くしてしまい、送信側と受信側の両方にエラー処理の実装が必要になる(たいてい、受信に失敗したデータは再送しなければならない)。

9600 8N1(具体例)

9600 8N1、すなわち9600ボー、データビット8、パリティなし、ストップビット1というのは、もっともよく使われるシリアルプロトコルのひとつである。 では、9600 8N1のパケットが実際にどのような形になるか、例を見てみよう。

ASCII文字の「O」と「K」を送信する機器は、2つのデータパケットを作ることになる。 O(大文字)のASCII値は79であり、これは8ビットの2進数で01001111になる。 一方、Kの2進数の値は01001011である。 あとは同期ビットを付け加えるだけである。

特に明記されてはいないが、データは最下位ビットから転送されると仮定されている。 それぞれのバイトが右から左へと読まれる形で送られていることに注目してほしい。

9600bpsで転送しているため、それぞれのビットをHIGHまたはLOWに保つ時間は1/9600bps、つまり1ビットあたり104マイクロ秒である。

送信される1バイトのデータごとに、実際には10ビットが送られている。スタートビット、8つのデータビット、そしてストップビットである。 そのため、9600bpsでは、実際には毎秒9600ビット、つまり毎秒960(9600÷10)バイトを送っていることになる。

これでシリアルパケットの構成方法が分かったところで、ハードウェアの話に進もう。 そこでは、これらの1と0、そしてボーレートが信号レベルでどのように実装されているかを見ていく。

配線とハードウェア

シリアルバスは、たった2本の配線、すなわちデータを送るための線と受け取るための線から成り立っている。 そのため、シリアル機器には2つのシリアルピン、つまり受信用のRXと送信用のTXが必要である。

ここで重要なのは、RXTXというラベルは、その機器自身から見た呼び方だということである。 つまり、片方の機器のRXは、もう片方の機器のTXへとつなぐ必要があり、その逆もまた然りである。 VCCとVCC、GNDとGND、MOSIとMOSIのように同じ名前どうしをつなぐことに慣れていると奇妙に感じるかもしれないが、考えてみれば理にかなっている。 送信機は受信機と話すべきであり、別の送信機と話すべきではないからである。

両方の機器がデータを送信および受信できるシリアルインターフェースは、全二重または半二重のどちらかに分類される。 全二重とは、両方の機器が同時に送受信できることを意味する。 半二重通信では、シリアル機器は送信と受信を交互に行わなければならない。

シリアルバスの中には、送信側と受信側の機器間の接続がたった1本で済むものもある。 たとえば、SparkFunのシリアル対応LCDはひたすら「聞く」だけで、制御側の機器にデータを送り返す必要がない。 これは単方向(シンプレックス)シリアル通信と呼ばれるものである。 必要なのは、マスター側のTXからリスナー側のRX線への1本の配線だけである。

ハードウェアでの実装

ここまでは、非同期シリアルを概念的な側面から見てきた。 必要な配線は分かった。 では、シリアル通信は実際に信号レベルでどのように実装されているのだろうか。 実は、その方法は多岐にわたる。 シリアル信号にはさまざまな規格が存在する。 ここでは、シリアル信号のハードウェア実装としてよく使われる2つの方式、ロジックレベル(TTL)とRS-232を見てみよう。

マイクロコントローラやその他の低レベルなICがシリアル通信を行うとき、たいていTTL(トランジスタ・トランジスタ・ロジック)レベルで行われる。 TTLシリアル信号は、マイクロコントローラの電源電圧の範囲内、たいてい0Vから3.3Vまたは5Vの間に収まる。 VCCレベル(3.3V、5Vなど)の信号は、アイドル状態の線か、値が1のビットか、ストップビットのいずれかを示す。 0V(GND)の信号は、スタートビットか、値が0のデータビットのいずれかを表す。

RS-232は、いくつかの古いコンピュータや周辺機器で見られる規格であり、いわばTTLシリアルを逆さまにしたようなものである。 RS-232信号はたいてい-13Vから13Vの範囲だが、仕様上は±3Vから±25Vまでの範囲が許容されている。 これらの信号では、低い電圧(-5V、-13Vなど)が、アイドル状態の線か、ストップビットか、値が1のデータビットのいずれかを示す。 高いRS-232信号は、スタートビットか、値が0のデータビットのいずれかを意味する。 これはTTLシリアルとはちょうど逆の関係になる。

2つのシリアル信号規格を比べると、TTLのほうが組み込み回路への実装がずっと簡単である。 しかし、電圧レベルが低いため、長い伝送路では損失の影響を受けやすい。 RS-232や、あるいはRS-485のようなより複雑な規格のほうが、長距離のシリアル伝送には適している。

2つのシリアル機器を接続するときは、それぞれの信号電圧が一致していることを必ず確認すること。 TTLシリアル機器をRS-232バスに直接接続することはできない。 その場合は信号のレベルを変換する必要がある。

続いて、マイクロコントローラがパラレルバス上のデータをシリアルインターフェースとの間で変換するために使う道具、UARTについて見ていこう。

UART

このシリアルというパズルの最後のピースは、シリアルパケットを作り出し、なおかつ物理的なハードウェア線を制御できる何かを見つけることである。 そこで登場するのがUARTである。

汎用非同期受信/送信機(UART)は、シリアル通信を実装する役割を担う回路のブロックである。 基本的に、UARTはパラレルインターフェースとシリアルインターフェースの間を取り持つ仲介役として働く。 UARTの片方の端には8本ほどのデータ線(といくつかの制御ピン)からなるバスがあり、もう片方の端には、RXとTXという2本のシリアル配線がある。

UARTは単体のICとしても存在するが、たいていマイクロコントローラの内部に組み込まれている。 自分のマイクロコントローラにUARTが搭載されているかどうかは、データシートを確認する必要がある。 UARTをまったく持たないものもあれば、1つだけ持つもの、複数持つものもある。 たとえば、おなじみのATmega328を採用したArduino Unoは1つのUARTしか持たないが、ATmega2560を採用したArduino Megaには、なんと4つものUARTが搭載されている。

UART(Universal Asynchronous Receiver/Transmitter)という頭文字のRとTが示すとおり、UARTはシリアルデータの送信と受信の両方を担う。 送信側では、UARTは同期ビットとパリティビットを付け加えてデータパケットを作成し、設定されたボーレードに従って正確なタイミングでTX線からそのパケットを送り出さなければならない。 受信側では、UARTは想定されるボーレートに応じた頻度でRX線をサンプリングし、同期ビットを見分けて、データを取り出さなければならない。

より高度なUARTは、受信したデータをバッファに格納しておき、マイクロコントローラが取りに来るまでそこに保持する。 UARTはたいてい、先入れ先出し(FIFO)方式でバッファ内のデータを取り出す。 バッファはわずか数ビットのこともあれば、数千バイトに及ぶこともある。

ソフトウェアUART

マイクロコントローラにUARTが搭載されていない(あるいは数が足りない)場合、シリアルインターフェースをビットバンギング、つまりプロセッサが直接制御する方式で実現することもできる。 これは、ArduinoのSoftwareSerialライブラリのようなものが採用しているアプローチである。 ビットバンギングはプロセッサに大きな負荷をかけ、たいていUARTほど正確ではないが、いざというときには役に立つ。

よくある落とし穴

シリアル通信についてはこれでほぼ一通り説明した。 最後に、経験レベルを問わずエンジニアが陥りやすい、よくある間違いをいくつか紹介しておこう。

RXとTXの取り違え

単純なことのように思えるが、私自身も何度もやらかしたことのあるミスである。 ラベルを一致させたくなる気持ちは分かるが、シリアル機器どうしをつなぐときは、必ずRXとTXの配線を交差させること。

ボーレートの不一致

ボーレートは、シリアル通信における「言語」のようなものである。 2つの機器が異なる速度で話していると、データが誤って解釈されたり、まったく受信されなかったりすることがある。 受信側がでたらめなデータしか受け取っていない場合は、まずボーレートが一致しているかを確認しよう。

バスの競合

シリアル通信は、1本のシリアルバス上でちょうど2つの機器だけが通信することを想定して設計されている。 同じシリアル線で2つ以上の機器が同時に送信しようとすると、バスの競合が起きることがある。

たとえば、GPSモジュールをArduinoに接続する場合、そのモジュールのTX線をArduinoのRX線に配線することになるだろう。 しかし、そのArduinoのRXピンは、Arduinoのプログラム書き込みやシリアルモニタの使用時に使われるUSB-シリアル変換チップのTXピンにもすでに接続されている。 これにより、GPSモジュールとFTDIチップの両方が同時に同じ線で送信しようとする状況が起こりうる。

同じ線で2つの機器が同時にデータを送信しようとするのは望ましくない。 「うまくいって」も、どちらの機器もデータを送信できない結果に終わる。 最悪の場合、両方の機器の送信ラインが壊れてしまうこともある(まれではあるし、たいてい保護回路が備わっているが)。

逆に、1つの送信機器に複数の受信機器を接続するのは、比較的安全である。 仕様に厳密に沿っているとは言えず、経験豊富なエンジニアからは眉をひそめられるかもしれないが、動作はする。 たとえば、シリアルLCDをArduinoに接続する場合、もっとも簡単な方法は、LCDモジュールのRX線をArduinoのTX線につなぐことかもしれない。 ArduinoのTXはすでにUSBプログラマーのRX線に接続されているが、それでも送信ラインを制御している機器はひとつだけである。

このようにTX線を複数の機器へ分配するのは、ファームウェアの観点からは依然として危険を伴う。 どの機器がどの送信内容を受け取るかを選ぶことができないためである。 LCDが本来受け取るはずのないデータを受信してしまい、未知の状態に陥るよう命令されてしまう可能性がある。

一般論として、1本のシリアルバスには2つのシリアル機器、というのが原則である。

まとめ

これでシリアル通信について新しい知識が身についたところで、探求できる新しい概念、プロジェクト、技術が数多く広がっている。

同期式の通信規格など、他の通信規格についてもさらに学びたいなら、次のような通信プロトコルも確認してみてほしい。

多くの技術がシリアル通信を大いに活用している。

シリアル通信が実際に動いているところを見てみたい場合は、次のようなチュートリアルもおすすめである。

タグ: 通信、概念


出典:Serial Communication(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

SPI(シリアルペリフェラルインターフェース)

SPI(シリアルペリフェラルインターフェース)は、マイクロコントローラとシフトレジスタ、センサー、SDカードのような小型の周辺機器の間でデータをやり取りするために、よく使われるインターフェースバスである。 クロック線とデータ線を別々に持ち、さらに通信したい機器を選ぶための選択線も備えている。

参考になるチュートリアル:

このチュートリアルを読む前に知っておくと役立つ内容は、次のとおりである。

シリアルポートの何が問題なのか

TX線とRX線を使う一般的なシリアルポートは「非同期(asynchronous)」と呼ばれる。これは、データがいつ送られるかを制御する仕組みがなく、両側が正確に同じ速度で動作している保証もないためである。 コンピュータはたいてい、すべてを単一の「クロック」(コンピュータに搭載され、あらゆる動作を駆動するメインの水晶振動子)に同期させることを前提としているため、わずかにクロックの異なる2つのシステムどうしが通信しようとすると、これが問題になることがある。

この問題を回避するため、非同期シリアル通信では、各バイトにスタートビットとストップビットを追加し、受信側がデータの到着に合わせて同期を取り直せるようにしている。 両側は、あらかじめ伝送速度(たとえば9600ビット毎秒など)についても合意しておく必要がある。 伝送速度にわずかなずれがあっても、受信側は各バイトの先頭で同期を取り直すため、問題にはならない。

(ちなみに、上の図で「11001010」が0x53と一致していないことに気づいたなら、なかなか鋭い観察眼である。シリアルプロトコルではたいてい最下位ビットから先に送信されるため、もっとも小さいビットが一番左に来る。下位ニブルは実際には0011=0x3であり、上位ニブルは0101=0x5である。)

非同期シリアルは問題なく機能するが、各バイトに追加するスタートビットとストップビットのオーバーヘッドや、データを送受信するために必要な複雑なハードウェアといった負担がある。 また、自分のプロジェクトでも経験したことがあるかもしれないが、両側の速度が一致していないと、受信データは文字化けしてしまう。 これは、受信側が非常に特定のタイミング(上の図の矢印の位置)でビットをサンプリングしているためであり、受信側が誤ったタイミングを見ていれば、誤ったビットを読み取ってしまう。

同期式という解決策

SPIは少し異なる方式で動作する。 これは「同期式」のデータバスであり、データ用の線とは別に、両側を完全に同期させ続ける「クロック」用の線を持つ。 このクロックは発振する信号であり、受信側にデータ線上のビットをいつサンプリングすべきかを正確に伝える。 これはクロック信号の立ち上がり(ローからハイ)または立ち下がり(ハイからロー)のどちらかのエッジに対応しており、どちらを使うかはデータシートに明記されている。 受信側はそのエッジを検出すると、すぐにデータ線を見て次のビットを読み取る(下の図の矢印を参照)。 クロックがデータと一緒に送られてくるため、速度をあらかじめ指定しておく必要はないが、各デバイスにはそれぞれ動作できる最高速度がある(適切なクロックエッジと速度の選び方については、後ほど説明する)。

SPIがこれほど人気がある理由のひとつは、受信側のハードウェアが単純なシフトレジスタで済むという点である。 これは、非同期シリアルが必要とする本格的なUART(汎用非同期受信/送信機)に比べて、はるかに単純で(そして安価な)ハードウェアである。

データの受信

Note

SPIのピン名としてPICO/POCIという表記を見慣れないかもしれない。SparkFunは、コントローラとペリフェラルの間の信号を表すのに「Master」「Slave」という用語を使うのをやめようという、OSHWA(オープンソースハードウェア協会)の他のメンバーとの決議に加わっている。これらの用語は廃止されたものと見なされ、現在ではそれぞれ「controller(コントローラ)」「peripheral(ペリフェラル)」という用語に置き換えられている。

旧称新称
MasterController
SlavePeripheral
MISOPOCI
MOSIPICO
SSCS

命名規則は、メーカーやプログラミング言語、企業、団体によって異なる場合がある。

一方向の通信にはこれでよさそうだが、では逆方向にデータを送り返すにはどうすればよいのだろうか、と思うかもしれない。 ここから少し話が込み入ってくる。

SPIでは、片側だけがクロック信号を生成する(たいていCLKまたはSCK、Serial ClocKと呼ばれる)。 クロックを生成する側を「コントローラ」、もう一方を「ペリフェラル」と呼ぶ。 コントローラは常にひとつだけ(たいていマイクロコントローラ自身)だが、ペリフェラルは複数存在することがある(これについては後ほど詳しく説明する)。

コントローラからペリフェラルへデータを送るときは、PICO(Peripheral In / Controller Out)と呼ばれるデータ線を使って送られる。 ペリフェラルがコントローラに応答を送り返す必要がある場合、コントローラはあらかじめ決められた回数だけクロックを生成し続け、ペリフェラルはPOCI(Peripheral Out / Controller In)と呼ばれる3本目のデータ線にデータを乗せる。

先ほどの説明で「あらかじめ決められた」という表現を使ったことに注目してほしい。 コントローラは常にクロック信号を生成する側であるため、ペリフェラルがいつデータを返す必要があり、どれだけの量のデータが返されるのかを前もって知っておかなければならない。 これは、任意のタイミングでどちらの方向にも任意の量のデータを送ることができる非同期シリアルとは大きく異なる点である。 実際には、SPIはたいてい非常に決まったコマンド体系を持つセンサーとやり取りするために使われるため、これは問題にならない。 たとえば「データを読み取る」というコマンドをある機器に送れば、その機器がたとえば常に2バイトを返してくることが分かっている、というような場合である (可変長のデータを返したい場合は、まずデータ長を示す1〜2バイトを返し、その後コントローラが必要な分だけデータを取得するという方法もある)。

なお、SPIは「全二重」(送信線と受信線が別々にある)であるため、状況によっては送信と受信を同時に行うこともできる(たとえば、前回のセンサー値を取得しながら次の測定を要求する場合など)。 これが可能かどうかは、使用する機器のデータシートに記載されている。

チップセレクト(CS)

もうひとつ知っておくべき線として、CS(チップセレクト)がある。 これは、ペリフェラルに対してデータの送受信を開始すべきタイミングを伝えるものであり、複数のペリフェラルが存在する場合には、どのペリフェラルと通信したいかを選択するためにも使われる。

CS線はたいてい通常時はHIGHに保たれており、これによってそのペリフェラルはSPIバスから切り離された状態になる(このような論理方式は「アクティブロー」と呼ばれ、イネーブル線やリセット線でよく使われる)。 ペリフェラルにデータを送信する直前に、この線をLOWにすることでペリフェラルが有効になる。 そのペリフェラルの使用が終わったら、再びHIGHに戻す。 シフトレジスタでは、これは「ラッチ」入力に対応しており、受信したデータを出力線へと転送する役割を持つ。

複数のペリフェラル

複数のペリフェラルをSPIバスに接続する方法は2通りある。

1つ目は、一般的な方法として、それぞれのペリフェラルに個別のCS線を用意する方法である。 特定のペリフェラルと通信するには、そのペリフェラルのCS線をLOWにし、他のすべてのCS線はHIGHのままにしておく(2つ以上のペリフェラルを同時に有効化してしまうと、両方が同じPOCI線で応答しようとして、データが化けてしまう可能性がある)。 ペリフェラルの数が多いほど、CS線もたくさん必要になる。出力ピンが足りなくなってきたら、CS出力を増やせるバイナリデコーダICを使う方法もある。

2つ目の方法として、一部の部品は数珠つなぎ(デイジーチェーン)で接続することを想定しており、あるペリフェラルのPOCI(出力)を次のペリフェラルのPICO(入力)につないでいく。 この場合、1本のCS線がすべてのペリフェラルに接続される。 すべてのデータが送信し終わると、CS線がHIGHに戻され、すべてのチップが同時に有効化される。 この方式は、数珠つなぎにしたシフトレジスタやアドレサブルLEDドライバーでよく使われる。

このレイアウトでは、データはあるペリフェラルから次のペリフェラルへと溢れ出るように流れていくため、特定の1つのペリフェラルにデータを送りたい場合でも、すべてのペリフェラルに届くだけのデータ量を送信する必要がある。 また、最初に送信したデータは、最後のペリフェラルに届くことになる点にも注意してほしい。

このタイプのレイアウトは、LEDの駆動のようにデータを受け取る必要のない、出力専用の用途でよく使われる。 このような場合、コントローラのPOCI線は未接続のままにしておいてよい。 とはいえ、コントローラにデータを返す必要がある場合は、デイジーチェーンのループを閉じる(上の図の青い配線)ことでも実現できる。 ただし、この方法を取る場合、ペリフェラル1からの戻りデータは、コントローラに届くまでにすべてのペリフェラルを通過することになるため、必要なデータを取得できるだけの十分な受信コマンドを送るようにすること。

SPIのプログラミング

多くのマイクロコントローラには、データの送受信に関するあらゆる細部を処理してくれる、非常に高速なSPI専用の周辺回路が内蔵されている。 SPIプロトコル自体も十分にシンプルなので、I/O線を正しい順序で操作してデータを転送する独自のルーチンを自分で書くこともできる。

Arduinoを使っている場合、SPI機器と通信する方法は2通りある。

  1. shiftIn()shiftOut()というコマンドを使う方法。これらはソフトウェアで実装されたコマンドであり、どのピンの組み合わせでも動作するが、いくらか低速になる。
  2. マイクロコントローラに内蔵されたSPI用ハードウェアを活用する、SPIライブラリを使う方法。上記のコマンドよりもはるかに高速だが、特定のピンでしか動作しない。

インターフェースを設定する際には、いくつかのオプションを選ぶ必要がある。 これらのオプションは、通信相手の機器の設定と一致している必要があるため、その機器のデータシートで何が必要かを確認すること。

  • インターフェースは、最上位ビット(MSB)から先に送ることも、最下位ビット(LSB)から先に送ることもできる。ArduinoのSPIライブラリでは、これはsetBitOrder()関数で制御する。
  • ペリフェラルは、クロックパルスの立ち上がりエッジか立ち下がりエッジのどちらかでデータを読み取る。さらに、クロックがHIGHのときとLOWのときのどちらを「アイドル」状態と見なすかも選べる。ArduinoのSPIライブラリでは、これら両方の設定をsetDataMode()関数で制御する。
  • SPIは非常に高速(毎秒数百万バイト)に動作できるが、これは一部の機器には速すぎることがある。そのような機器に対応するため、データレートを調整できる。ArduinoのSPIライブラリでは、速度はsetClockDivider()関数で設定し、コントローラのクロック(たいていのArduinoでは16MHz)を8MHz(÷2)から125kHz(÷128)までの範囲に分周する。
  • SPIライブラリを使う場合、そのハードウェアはSCK、PICO、POCIという特定のピンに固定配線されているため、これらのピンをそのまま使う必要がある。専用のCSピンも用意されている(SPIハードウェアを機能させるには、少なくとも出力に設定しておく必要がある)が、ペリフェラル機器へのCSには、他の任意の出力ピンを使うこともできる。
  • 古いArduinoでは、CSピンを自分で制御する必要があり、データ転送の前にLOWにし、転送後にHIGHに戻す。Dueのような新しいArduinoでは、データ転送の一部として各CSピンを自動的に制御できる。

まとめ

これでSPIについての知識が身についたはずである。

コツと注意点

  • 高速な信号を扱うため、SPIは短距離(数フィート程度まで)でのデータ送信にのみ使うべきである。それより遠くまでデータを送る必要がある場合は、クロック速度を落とすか、専用のドライバーICの使用を検討すること。
  • 思ったとおりに動作しない場合、ロジックアナライザーが非常に役立つ道具になる。Saleae USB Logic Analyzerのような高機能なアナライザーであれば、データバイトを解読して表示したり記録したりすることもできる。

SPIの利点

  • 非同期シリアルよりも高速である
  • 受信側のハードウェアを単純なシフトレジスタで済ませられる
  • 複数のペリフェラルに対応できる

SPIの欠点

  • 他の通信方式に比べて、より多くの信号線(配線)を必要とする
  • 通信内容をあらかじめ明確に定義しておく必要がある(好きなタイミングで任意の量のデータを送ることはできない)
  • コントローラがすべての通信を制御しなければならない(ペリフェラルどうしが直接会話することはできない)
  • たいてい、それぞれのペリフェラルに個別のCS線が必要であり、ペリフェラルの数が多い場合には扱いにくくなることがある

さらに学びたいなら、次のような他の通信方式のチュートリアルも確認してみてほしい。

タグ: 通信、概念


出典:Serial Peripheral Interface (SPI)(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

I2C

このチュートリアルでは、I2C通信プロトコルについて、なぜそれを使いたくなるのか、そしてどのように実装されているのかを学ぶ。

Inter-Integrated Circuit(I2C)プロトコルは、複数の「ペリフェラル」デジタル集積回路(「チップ」)が、1つまたは複数の「コントローラ」チップと通信できるようにするためのプロトコルである。 SPI(シリアルペリフェラルインターフェース)と同じく、単一の機器の中での短距離通信を想定している。 また、非同期シリアルインターフェース(RS-232やUARTなど)と同じく、情報をやり取りするのに必要な信号線はたった2本だけである。

参考になるチュートリアル:

このチュートリアルを読む前に知っておくと役立つ内容は、次のとおりである。

なぜI2Cを使うのか

I2Cで通信したくなる理由を理解するには、まず他の選択肢と比較して、どこが違うのかを見る必要がある。

シリアルUARTポートの何が問題なのか

シリアルポートは非同期(クロックデータが送られない)であるため、それを使う機器は事前にデータレートについて合意しておかなければならない。 また、両方の機器のクロックはほぼ同じ速度でなければならず、その状態を保ち続ける必要がある。両端のクロック速度に大きな差が生じると、データが文字化けしてしまう。

非同期シリアルポートにはハードウェア面でのオーバーヘッドがある。両端のUARTは比較的複雑であり、ソフトウェアで正確に実装しようとすると難しい。 それぞれのデータフレームには少なくとも1つのスタートビットとストップビットが含まれるため、8ビットのデータを送るのに10ビット分の送信時間が必要になり、実効データレートを圧迫する。

非同期シリアルポートのもうひとつの根本的な弱点は、本質的に2台の機器(それもちょうど2台)どうしの通信にしか向いていないという点である。 1つのシリアルポートに複数の機器を接続すること自体は可能だが、バスの競合(2台の機器が同時に同じ線を駆動しようとする状態)が常に問題となり、機器を損傷から守るには慎重な対策(たいてい外部のハードウェア)が必要になる。

最後に、データレートも課題である。 非同期シリアル通信には理論上の上限はないが、たいていのUARTデバイスは決まった一定のボーレートしかサポートしておらず、その最大値はたいてい毎秒230400ビット程度である。

SPIの何が問題なのか

SPIのもっとも分かりやすい欠点は、必要なピンの数である。 1つのコントローラと1つのペリフェラルをSPIバスで接続するだけでも4本の線が必要であり、ペリフェラルを追加するたびに、コントローラ側にチップセレクト用のI/Oピンが1本ずつ追加で必要になる。 このピン接続の急速な増加は、多数の機器を1つのコントローラに接続したい状況では望ましくない。 また、機器ごとの接続本数が多いことは、PCBのレイアウトが窮屈な状況では配線をより難しくする要因にもなる。

SPIはバス上にコントローラを1つしか置けないが、ペリフェラルの数には(バスに接続された機器の駆動能力と、利用できるチップセレクトピンの数の制約はあるものの)特に制限がない。

SPIは、高速な全二重(送受信を同時に行える)接続に向いており、機器によっては10MHz(つまり毎秒1000万ビット)を超えるクロック速度をサポートし、速度のスケーラビリティにも優れている。 両端のハードウェアはたいてい非常に単純なシフトレジスタで済むため、ソフトウェアでの実装も容易である。

そこで登場するI2C。両方のいいとこ取り

I2Cは、非同期シリアルと同じくたった2本の配線しか必要としないが、その2本の配線で最大1008台ものペリフェラルデバイスをサポートできる。 また、SPIとは異なり、I2Cは複数コントローラのシステムにも対応しており、複数のコントローラがバス上のすべてのペリフェラルデバイスと通信できる(ただし、コントローラどうしがバス上で直接会話することはできず、バスの使用権を順番にやり取りする必要がある)。

データレートは非同期シリアルとSPIの中間程度であり、たいていのI2Cデバイスは100kHzまたは400kHzで通信できる。 I2Cには多少のオーバーヘッドがあり、8ビットのデータを送るたびに、メタデータとして1ビット(後述する「ACK/NACK」ビット)を追加で送信する必要がある。

I2Cの実装に必要なハードウェアは、SPIよりは複雑だが、非同期シリアルよりは単純である。 ソフトウェアでもかなり手軽に実装できる。

Note

I2Cバス上の機器どうしの関係を表す用語として、「マスター」「スレーブ」という言葉に馴染みがあるかもしれない。これらの用語は廃止されたものと見なされ、現在ではそれぞれ「コントローラ」「ペリフェラル」という用語に置き換えられている。命名規則は、メーカーやプログラミング言語、企業、団体によって異なる場合がある(main/secondary、initiator-responder、source/replicaなど)。

I2Cの歴史

I2Cは、もともと1982年にPhilipsによって、同社のさまざまなチップ向けに開発された。 当初の仕様では100kHzの通信しかサポートされておらず、アドレスも7ビットに限られていたため、バス上の機器数は112台までに制限されていた(いくつかのアドレスは予約されており、有効なI2Cアドレスとしては使われない)。 1992年に最初の公開仕様が発表され、400kHzのファストモードと、拡張された10ビットアドレス空間が追加された。 たいていの場合(たとえば多くのArduino互換ボードに搭載されているATmega328では)、I2Cのサポートはこの時点で止まっている。 このほかにも、次の3つの追加モードが規定されている。

  • ファストモードプラス(1MHz)
  • ハイスピードモード(3.4MHz)
  • ウルトラファストモード(5MHz)

「素の」I2Cに加えて、1995年にIntelはSystem Management Bus(SMBus)と呼ばれる派生仕様を導入した。 SMBusは、PCマザーボード上のサポートIC間の通信の予測可能性を最大化することを目的とした、より厳密に制御された規格である。 I2Cとの最大の違いは、SMBusが10kHzから100kHzまでの速度に制限されているのに対し、I2Cは0kHzから5MHzまでの機器をサポートできる点である。 SMBusには、低速動作を無効にするクロックタイムアウトモードが含まれているが、多くのSMBus機器は、組み込みI2Cシステムとの相互運用性を最大化するために、それでも低速動作をサポートしている。

ハードウェアレベルで見るI2C

信号

それぞれのI2Cバスは、SDAとSCLという2つの信号から構成される。 SDA(Serial Data)はデータ信号であり、SCL(Serial Clock)はクロック信号である。 クロック信号は常にその時点のバスコントローラによって生成されるが、一部のペリフェラルデバイスは、コントローラがさらにデータを送るのを遅らせたり(あるいはコントローラがクロックを出す前にデータを準備する時間を稼いだりする)ために、クロックを一時的にLOWに固定することがある。 これは「クロックストレッチング」と呼ばれ、後述のプロトコルの節で説明する。

UARTやSPIの接続とは異なり、I2Cバスのドライバーは「オープンドレイン」方式になっている。 つまり、対応する信号線をLOWに引き下げることはできるが、HIGHに駆動することはできない。 そのため、ある機器が線をHIGHにしようとし、別の機器がLOWに引き下げようとするといったバスの競合が起こりえず、ドライバーの損傷やシステム内での過大な電力消費のリスクがなくなる。 それぞれの信号線にはプルアップ抵抗が付いており、どの機器も線をLOWにしていないときに信号をHIGHへと戻す役割を果たす。

抵抗値の選び方はバス上の機器によって変わるが、経験則としてはまず4.7kΩの抵抗から始め、必要に応じて値を下げていくのがよい。 I2Cはかなり堅牢なプロトコルであり、短い配線(2〜3m程度)であれば問題なく使える。 配線が長い場合や、機器の数が多いシステムでは、より小さい抵抗値のほうが適している。

SparkFunのカタログで扱われているたいていのI2Cデバイスには、SCLピンとSDAピン用のプルアップ抵抗があらかじめ搭載されている。 同じバスに多数のI2Cデバイスを接続する場合、いくつかの機器のプルアップ抵抗を切り離すことで、抵抗の合成値を調整する必要が出てくることがある。 接続する内容や設計にもよるが、同じバスにはおよそ7台程度のI2Cデバイスを接続できる。 問題が生じた場合は、ホビーナイフでジャンパーパッドをつなぐトレースを切断するか、はんだごてを使ってジャンパーパッドのはんだを取り除くことで、特定の基板上の抵抗を切り離すことができる。

配線をより長く延ばす必要がある設計の場合は、PCA9615のような信号を延長する専用ICを使うという方法もある。

信号のロジックレベル

バス上の機器は実際には信号をHIGHに駆動しないため、I2Cには異なるI/O電圧を持つ機器どうしを接続する際にも、ある程度の柔軟性がある。 一般に、片方の機器がもう片方よりも高い電圧で動作しているシステムでは、間にレベルシフト回路を挟まなくても、I2Cで両者を接続できる場合がある。 コツは、プルアップ抵抗を2つの電圧のうち低いほうに接続することである。 これは、低いほうのシステム電圧が、高いほうのシステムのHIGHレベル入力電圧を上回っている場合に限って有効である。たとえば5VのArduinoと3.3Vの加速度センサーの組み合わせなどである。 Arduinoの設計やI2Cデバイスによっては、動作の一貫性を保ち、バス上のいずれの機器も傷めないために、ロジックレベルコンバータを使うことをおすすめする。

2つのシステム間の電圧差が大きすぎる場合(たとえば5Vと2.5Vなど)、SparkFunではPCA9306レベルトランスレータブレイクアウトのような、シンプルなI2Cレベルシフター基板も扱っている。 この専用のレベルシフター基板にはイネーブル線も付いており、特定の機器への通信を無効にするために使うことができる。 これは、同じアドレスを持つ複数の機器を1つのコントローラに接続したい場合(Wiiヌンチャクなどがよい例である)に便利である。 双方向のロジックレベルコンバータを使うという方法もある。

プロトコル

I2Cによる通信は、UARTやSPIによる通信よりも複雑である。 バス上の機器がそれを有効なI2C通信として認識するには、信号が特定のプロトコルに従っている必要がある。 幸い、たいていの機器は細かい部分をすべて処理してくれるため、私たちはやり取りしたいデータの内容に集中できる。

基本

メッセージは2種類のフレームに分けられる。ひとつは、コントローラがメッセージの送信先となるペリフェラルを示すアドレスフレームであり、もうひとつは、コントローラからペリフェラルへ、あるいはその逆方向にやり取りされる8ビットのデータメッセージであるデータフレーム(1つまたは複数)である。 データはSCLがLOWになったあとにSDA線に置かれ、SCLがHIGHになったあとにサンプリングされる。 クロックのエッジからデータの読み書きまでの時間は、バス上の機器によって定義されており、チップごとに異なる。

スタート条件

アドレスフレームを開始するため、コントローラ機器はSCLをHIGHのままにしつつ、SDAをLOWに引き下げる。 これにより、すべてのペリフェラルデバイスに、これから通信が始まることが伝わる。 2台のコントローラが同時にバスの所有権を得ようとした場合、先にSDAをLOWに引き下げたほうが競争に勝ち、バスの制御権を得る。 バスの制御権を他のコントローラに明け渡すことなく、新しい通信シーケンスを開始する「リピーテッドスタート」を発行することも可能であり、これについては後ほど説明する。

アドレスフレーム

アドレスフレームは、どの新しい通信シーケンスでも必ず最初に来る。 7ビットアドレスの場合、アドレスは最上位ビット(MSB)から先にクロック出力され、続いて読み取り(1)か書き込み(0)かを示すR/Wビットが送られる。

フレームの9ビット目はNACK/ACKビットである。 これはデータフレームであれアドレスフレームであれ、すべてのフレームに共通している。 フレームの最初の8ビットが送信されると、受信側の機器にSDAの制御権が渡される。 受信側の機器が9番目のクロックパルスより前にSDA線をLOWに引き下げなければ、その受信機器がデータを受信できなかったか、メッセージの解析方法が分からなかったと判断できる。 その場合、やり取りは中断され、その後どう進めるかはシステムのコントローラに委ねられる。

データフレーム

アドレスフレームが送信されたあと、データの送信が始まる。 コントローラは一定の間隔でクロックパルスを生成し続けるだけであり、R/Wビットが読み取りか書き込みかに応じて、コントローラかペリフェラルのどちらかがSDA上にデータを乗せる。 データフレームの数は任意であり、たいていのペリフェラルデバイスは内部レジスタを自動的にインクリメントするため、続けて読み書きすると次のレジスタが順番に対象になる。

ストップ条件

すべてのデータフレームが送信されると、コントローラはストップ条件を生成する。 ストップ条件は、SCLが0から1(LOWからHIGH)へ遷移したあとで、SDAが0から1へ遷移し、SCLがHIGHのまま保たれることとして定義される。 通常のデータ書き込み動作中は、誤ったストップ条件を避けるため、SCLがHIGHの間はSDAの値を変化させてはならない

プロトコルの高度な話題

10ビットアドレス

10ビットアドレス方式では、ペリフェラルのアドレスを送るのに2つのフレームが必要になる。 最初のフレームはb11110xyzというコードで構成され、「x」はペリフェラルアドレスの最上位ビット、「y」はペリフェラルアドレスの8ビット目、「z」は前述の読み取り/書き込みビットである。 最初のフレームのACKビットは、アドレスの先頭2ビットが一致するすべてのペリフェラルによって立てられる。

通常の7ビット転送と同じように、直後にもう1つの転送が始まり、この転送にはアドレスの7:0ビットが含まれる。 この時点で、アドレス指定されたペリフェラルはACKビットで応答するはずである。 もし応答しなければ、その失敗モードは7ビットシステムの場合と同じである。

10ビットアドレスの機器は、7ビットアドレスの機器と共存できる。 アドレスの先頭にある「11110」の部分は、有効な7ビットアドレスのどれとも一致しないためである。

リピーテッドスタート条件

コントローラが、バス上の他のコントローラに割り込まれることなく、複数のメッセージを一度にやり取りできるようにしたい場合がある。 そのために定義されているのが、リピーテッドスタート条件である。

リピーテッドスタートを行うには、SCLがLOWの間にSDAをHIGHに戻し、SCLをHIGHにしたあと、SCLがHIGHのままの状態で再びSDAをLOWにする。 バス上でストップ条件が発生していないため、それまでの通信は本当の意味では完了しておらず、現在のコントローラがバスの制御権を保持し続ける。

この時点で、次のメッセージの送信を開始できる。 この新しいメッセージの構文は、他のメッセージと同じであり、アドレスフレームに続いてデータフレームが送られる。 リピーテッドスタートの回数に制限はなく、コントローラはストップ条件を発行するまでバスの制御を保持し続ける。

クロックストレッチング

コントローラのデータレートが、ペリフェラルがデータを供給できる速度を上回ってしまうことがある。 これは、データがまだ準備できていない場合(たとえばペリフェラルがアナログ-デジタル変換をまだ完了していない場合)や、前の処理がまだ終わっていない場合(たとえば不揮発性メモリへの書き込みが完了しておらず、他の要求に応じる前にそれを完了させる必要があるEEPROMなど)に起こりうる。

このような場合、一部のペリフェラルデバイスは「クロックストレッチング」と呼ばれる動作を行う。 本来、クロッキングはすべてコントローラによって駆動されており、ペリフェラルはコントローラのクロックパルスに応じて、単にバスにデータを乗せたり、バスからデータを受け取ったりするだけである。 データ転送の過程のどの時点でも、アドレス指定されたペリフェラルは、コントローラがSCL線を解放したあとも、それをLOWに保持し続けることができる。 コントローラは、ペリフェラルがSCL線を解放するまで、それ以上のクロックパルスやデータ転送を控えなければならない。

Qwiic Connectシステム

SparkFun Qwiic Connectシステムは、SparkXのNateによって開発され、2017年にリリースされた。 馴染みがなければ説明すると、Qwiic Connectシステムは、I2Cセンサー、アクチュエータ、シールド、ケーブルなどからなるエコシステムであり、試作をより速く、よりミスの少ないものにしてくれる。

Qwiic対応のすべての基板は、共通の1mmピッチで4ピンのJSTコネクタを採用しており、基板間の配線をはんだ付けしたり被覆を剥いたりする余分な手間を省いてくれる。 このコネクタは必要なPCB上のスペースを削減し、極性のある接続なので配線を間違える心配もない。 複数の基板を数珠つなぎにすることで、同じバスに複数の機器を接続することもできる。

Qwiicケーブル(4ピンJST)は、開発ボードからセンサー、シールド、アクセサリー基板などへ簡単に差し込むことができ、新しい試作を組み立てる作業を手軽にしてくれる。

ブレッドボード上でSDAとSCLの配線をうっかり入れ替えてしまう心配もない。 Qwiicコネクタには極性があるため、最初から必ず正しく配線できる。

いよいよI2Cバスの力を活用するときである。 たいていのQwiic基板には2つ以上のコネクタが付いており、複数の機器を接続できるようになっている。

まとめ

I2Cは比較的複雑なインターフェースであり、それを扱うのに役立つ情報源が数多く存在する。 以下にいくつか特に参考になるものを挙げる。

  • Wikipedia Article on I2C:完璧ではないが、出発点としては悪くない
  • Standards Doc:かつてのPhilips SemiconductorはNXPになった。これはI2Cの公式仕様書である
  • I2C primer:I2Cと関連技術についての公式入門書
  • Linux Tools for I2C:pcDuinoやRaspberry PiのようなLinux組み込み環境で、I2Cや関連バスを扱うための便利なツール集
  • Qwiic Connect System:SparkFunのQwiic Connectシステムについて

長距離でI2Cを使いたい場合は、専用のPCA9615差動I2Cバスエクステンダーを確認してみてほしい。

タグ: 通信、概念、Qwiic


出典:I2C(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

シリアルターミナルの基礎

COMポート、ボーレート、フロー制御、TX、RX。 これらはすべて、電子工作、特にマイクロコントローラを扱うときによく飛び交う言葉である。 これらの用語や、それが使われる文脈に馴染みがない人にとっては、時に混乱を招くこともある。 このチュートリアルでは、これらの用語が何を意味し、それらがどのようにつながってターミナル上でのシリアル通信という全体像を作り上げているのかを解説する。

簡単に言えば、シリアルターミナルプログラムは、マイクロコントローラを扱う作業をはるかに簡単にしてくれる。 マイクロコントローラとの間で送受信されるデータを見ることができ、そのデータはトラブルシューティングやデバッグ、通信テスト、センサーの校正、モジュールの設定、データの監視など、さまざまな目的に使える。 ターミナルアプリケーションの使い方を一通り身につければ、電子工作やプログラミングの強力な武器になる。

このチュートリアルで扱う内容:

世の中には数多くのターミナルプログラムがあり、それぞれに長所と短所がある。 このチュートリアルでは、ターミナルとは何か、どのターミナルプログラムがどんな状況やOSに向いているか、そして各プログラムの設定方法と使い方について解説する。

参考になるチュートリアル:

このチュートリアルに入る前に、次の話題に馴染んでおくとよい。

ターミナルとは何か

ターミナルエミュレータにはさまざまな呼び名があり、「ターミナル」という言葉自体もいろいろな意味で使われるため、人によって指しているものが異なり、混乱を招くことがある。 ここで整理しておこう。

簡単な歴史

「ターミナル」という言葉の由来を理解するには、それほど遠くない過去にさかのぼる必要がある。 コンピュータが大きく、かさばり、部屋全体を占領していた時代、コンピュータとやり取りする方法はごくわずかしかなかった。 パンチカードや紙テープのリールもそのひとつだったが、データの入力と取得に使われるターミナルというものも存在した。 これらのターミナルにはさまざまな形状があったが、やがて後のパーソナルコンピュータの祖先のような姿になっていった。 多くはキーボードと画面から構成されていた。 文字だけを表示できるターミナルはテキストターミナルと呼ばれ、後にグラフィカルターミナルが登場した。 ターミナルエミュレータについて語るとき、参照されているのはこの過去のターミナルたちである。

現代のターミナル

今日のターミナルプログラムは、こうしたかつてのターミナルで作業していた体験を「エミュレート(模倣)」している。 これらはエミュレータ、アプリケーション、プログラム、ターム、TTYなどと呼ばれる。 このチュートリアルでは、単に「ターミナル」という言葉を使うことにする。 かつては特定の種類のコンピュータターミナルをエミュレートするものが多かったが、今日のたいていのターミナルはもっと汎用的なインターフェースを持っている。

現代のOSで作業する際は、こうしたアプリケーションの中で作業することを表すのにターミナルウィンドウという言葉がよく使われる。 他のチュートリアルやハードウェアの使い方ガイドを読んでいると、ターミナルウィンドウを開くよう求められることがよくあるはずだが、それは好みのターミナルプログラムのどれかを開けばよいという意味である。

また、多くのターミナルプログラムはシリアル通信以外にもさまざまな機能を備えている点も触れておく価値がある。 telnetやSSHのようなネットワーク通信の機能を持つものも多いが、このチュートリアルではそうした機能は扱わない。

ターミナルとコマンドラインの違い

ターミナルはコマンドプロンプトではないが、両者はいくらか似ている。 Mac OSでは、コマンドプロンプトそのものが「ターミナル」と呼ばれているため、この言葉を使うとよく混乱が生じる。 いずれにせよ、ターミナルウィンドウでできることの一部はコマンドプロンプトでも実行できるが、その逆は成り立たない。ターミナルウィンドウの中でコマンドライン用の命令を実行することはできない。 コマンドラインインターフェースの中でシリアルターミナル接続を作る方法については、このチュートリアルの後半で扱う。 今はまず、この2つを区別できるようにしておこう。

基本用語

シリアルターミナルウィンドウを扱う際に知っておくべき用語をいくつか紹介する。 これらの用語の多くは、シリアル通信のチュートリアルでさらに詳しく扱っているので、全体像をつかむためにもぜひそちらも読んでほしい。

ASCII:American Standard Code for Information Interchangeの文字コード化方式の略で、ASCIIはキーボード上の特殊文字を、多くのプログラムや機器が認識できる7ビットの2進数の整数に変換する。シリアルターミナルを扱う際は、ASCII表が非常に役立つ。

ボーレート:簡単に言えば、データがどれくらいの速さで送受信されているかを示す。9600が標準的な速度だが、機器によっては他の速度が使われることもある。通信の鎖でつながったすべての機器は同じ速度で「話す」必要があり、そうでなければどちらか一方でデータが誤って解釈されてしまうことを覚えておこう。

送信(TX):Data OutやTXOとも呼ばれる。どの機器でもTX線はデータを送信するためのものであり、通信したい相手の機器のRX線に接続する必要がある。

受信(RX):Data InやRXIとも呼ばれる。どの機器でもRX線はデータを受信するためのものであり、通信したい相手の機器のTX線に接続する必要がある。

COMポート(シリアルポート):パソコンに接続する機器にはそれぞれ特定のポート番号が割り当てられる。これにより、接続された各機器を識別しやすくなる。ある機器にポートが割り当てられると、その機器を接続するたびに同じポートが使われる。

自分の機器は、パソコン上でCOM#(Windowsマシンの場合)または**/dev/tty.usbserial-########**(Mac/Linuxコンピュータの場合)として表示される。ここで#の部分は固有の数字やアルファベットである。

TTY:TTYはテレタイプライター(teletypewriter)、あるいはテレタイプ(teletype)の略である。「ターミナル」がかつてのターミナルを指す言葉であるのと同じように、「テレタイプ」もそれに由来する。これは、ターミナル、そしてメインフレームに情報を入力するために使われていた電気機械式のタイプライターである。MacやLinuxでターミナルを扱う際は、「COMポート」の代わりに通信ポートを表す言葉としてttyがよく使われる。

データビット、ストップビット、パリティビット:ターミナルとの間で送受信されるそれぞれのデータパケットには、特定のフォーマットがある。このフォーマットはさまざまであり、ターミナルの設定を調整することで異なるパケット構成に対応できる。もっともよく見かける構成のひとつが8-N-1であり、これはデータビット8、パリティビットなし、ストップビット1を意味する。

フロー制御:フロー制御とは、送信側が受信側の処理速度を超える速さでデータを送りすぎないようにするために、機器間でデータの送信速度を制御する仕組みである。これらのチュートリアルで使われるたいていのアプリケーションでは、フロー制御を使う必要はない。フロー制御は、8-N-1-Noneという略記の中に含まれることもあり、これはフロー制御なしを意味する。

キャリッジリターンとラインフィード:キャリッジリターンとラインフィードは、キーボードのEnterキーを押したときに送信されるASCII文字である。これらの用語はタイプライターの時代に由来する。キャリッジリターンは、紙を保持するキャリッジがその行の先頭に戻ることを意味していた。ラインフィード(改行とも呼ばれる)は、前の行に重ねて打たないよう、キャリッジを次の行へ移動させることを意味していた。

現代のキーボードで入力する際も、この考え方は変わらない。 Enter(あるいはReturn)を押すたびに、カーソルを次の行へ移動させ、その新しい行の先頭に戻すよう指示していることになる。

ASCII表を確認すると、ラインフィードの文字は10(16進数で0x0A)、キャリッジリターンは13(16進数で0x0D)であることが分かる。 この2つの文字の重要性はいくら強調してもし足りない。 ターミナルウィンドウを扱う際は、Enterキーをエミュレートするためにこの2つの文字のどちらか(あるいは両方)が使われているかをよく意識する必要がある。 機器によっては、コマンドが送信されたことを認識するのにどちらか片方の文字だけを必要とするものもある。 さらに重要なのは、マイクロコントローラを扱う際、自分がどのようにデータを送っているかを意識することである。 5文字の文字列をマイコンに送る必要がある場合、各コマンドの後に10と13が送られることを考慮して、実際には7文字分を保持できる文字列が必要になることがある。

ローカルエコー:ローカルエコーは、シリアルターミナル側でも、通信相手の機器側でも(時には両方でも)変更できる設定である。この設定は、入力したものをすべてターミナルに表示するよう指示するだけのものである。この利点は、エラーが起きた際に、実際に正しいコマンドを入力できているかを確認できることである。ただし、ローカルエコーが裏目に出ることもあるので注意しよう。機器によっては、ローカルエコーを二重入力として解釈してしまうことがある。たとえば、ローカルエコーを有効にした状態でhelloと入力すると、受信側の機器にはhheellllooと見えてしまうことがあり、これはおそらく正しいコマンドではない。たいていの機器はローカルエコーの有無にかかわらずコマンドを処理できるが、これが問題になりうることは覚えておこう。

シリアルポートプロファイル(SPP):シリアルポートプロファイルは、Bluetooth機器とホスト/ペリフェラル機器の間でシリアル通信を可能にするBluetoothのプロファイルである。このプロファイルが有効になっていれば、シリアルターミナルを通じてBluetoothモジュールに接続できる。これは設定目的にも通信目的にも使える。このチュートリアルには直接関係しないが、プロジェクトでBluetoothを使いたい場合は知っておくとよいプロファイルである。

機器に接続する

ターミナルとは何か、そしてその周辺の用語が分かったところで、いよいよ機器を接続して通信してみよう。 このセクションでは、機器の接続方法、割り当てられたポートの調べ方、そのポートを通じた通信方法を紹介する。

必要なもの

この例では、次のものが必要である。

  • FTDI Basic(5Vでも3.3Vでもよい)。手元にFTDIケーブルしかなければ、それでもよい。
  • USB Mini-Bケーブル(FTDIケーブルを使う場合は不要)。
  • ジャンパー線。たいていのFTDI製品はメスヘッダーを備えているため、オス-オスのジャンパーケーブルで十分なはずである。あるいは、両端の被覆を剥いた配線を使ってもよい。

機器を見つける

必要なものがそろったら、FTDI BasicをUSBケーブルに接続し、そのケーブルをパソコンに接続する。 この種の機器をパソコンに接続するのが初めてであれば、ドライバーのインストールが必要になることがある。 その場合は、FTDIドライバーのインストールガイドを参照してほしい。 ドライバーが最新であれば、そのまま続けよう。

使っているOSによって、機器に割り当てられたポートを調べる方法はいくつか異なる。

デバイスマネージャー(Windows)

どのバージョンのWindowsでも、デバイスマネージャーというプログラムが用意されている。 デバイスマネージャーを開くには、スタートメニューを開き、検索欄に

devmgmt.msc

と入力してEnterキーを押せばすぐに開く。 あるいは、マイコンピュータを右クリックして「プロパティ」を選び、そこからデバイスマネージャーを開くこともできる(Windows 7の場合)。 複数のシリアル機器と頻繁に通信する予定であれば、デバイスマネージャーへのデスクトップショートカットを作っておくとよいだろう。

デバイスマネージャーを開いたら、「ポート」タブを展開する。 必要な情報はここにある。

この画像には、いくつかのCOMポートが表示されている。 まず知っておくべきなのは、COM1は常に本物のシリアルポート用に予約されており、USB用ではないということである。 両端にDB9コネクタが付いた、あの灰色のかさばるケーブルのことである。 たいていのコンピュータ(特にノートパソコン)にはもはやシリアルポートが搭載されておらず、より多くのUSBポートに置き換えられて時代遅れになりつつある。 それでも、OSは本物のシリアルポートを持つユーザーのために、COM1をそのポート専用に予約し続けている。

もうひとつ、たいていのコンピュータに表示される可能性が高いポートがLPT1である。 これはパラレルポート用に予約されている。 パラレルポートとケーブルはシリアルケーブルよりもさらに時代遅れになりつつあるが、それでも多くのコンピュータには(プリンターへの接続によく使われる)これらのポートが搭載されており、OSはそれに対応する必要がある。

これらを脇に置いておけば、実際に使う必要のあるポートに集中できる。 FTDIを接続すると、新しいCOMポートがリストに追加されるはずである。

たいてい、コンピュータは接続した機器を順に番号付けしていく。 たとえば、これがパソコンに接続する最初のシリアル通信機器であれば、COM2として割り当てられるはずである。 何台もの機器を接続してきたコンピュータでは、8台目、9台目としてCOM9のように割り当てられることもある(COM1のことを忘れないように)。

重要なのは、いったんある機器がコンピュータに関連付けられ、ポートが割り当てられると、その機器を接続するたびにコンピュータがそれを覚えているという点である。 そのため、たとえばCOM4が割り当てられたArduino基板があるなら、毎回デバイスマネージャーを開いてどのCOMポートにあるかを確認する必要はない。その機器は常にCOM4になるからである。 これはよい面も悪い面もある。 たいていの人は数十台以上のシリアル機器をパソコンに接続することはないが、中には大量に機器を接続する人もおり、コンピュータが割り当てられるポート数には上限がある(確か256だったと思う)。 そのため、古いCOMポートを削除する必要が出てくることもある。

複数の機器を持っていて、どれが今接続したばかりの機器か分からない場合は、その機器を一度抜いてどのCOMポートが消えるかを確認し、また接続し直せばよい。 そのCOMポートが再び現れれば、それが探していた機器である。

最後にもうひとつ、たとえ異なるドライバーを必要とする場合でも、すべてのシリアル機器はWindowsではCOMポートとして表示されるということも触れておく。 たとえばArduino UnoとFTDI Basicはそれぞれ異なるドライバーを必要とする技術的に異なる種類の機器だが、Windowsはそれらを区別しない。 どちらも同じように扱われ、気にする必要があるのはどのCOMポートに割り当てられているかだけである。 Mac OSとLinuxはこの点を少し異なる方法で扱う。詳しくは以下を読んでほしい。

コマンドライン(Mac、Linux)

Windowsと同じように、Mac OSとLinuxもパソコンに接続されたそれぞれの機器に特定のポートを割り当てる。 ただし、Windowsとは異なり、現在接続されているすべての機器を一覧表示できる専用のプログラムはない。 とはいえ心配は要らない。機器を見つけるためのシンプルな方法がちゃんとある。

Mac OS Xのデフォルトのコマンドラインインターフェースはターミナルである。 開くには、ユーティリティフォルダを開く。そこにターミナルのアイコンがあるはずである。 Linuxを使っているなら、コマンドラインウィンドウの開き方はすでに知っているものとする。

開いたら、次のコマンドを入力する。

ls /dev/tty.*

これで、パソコン上のすべてのシリアルポートの一覧が表示されるはずである。

いくつかのBluetoothポートも表示されることに気づくだろう。 これらの名前の中にあるSPPの部分に注目してほしい。それは、そのBluetooth機器がシリアルターミナルとも通信できることを示している。

注目すべき重要な機器はtty.usbserialtty.usbmodemである。 この例では、FTDI BasicとArduino Unoの両方をパソコンに接続している。 これは、両者の重要な違いを示すためのものである。 先に述べたように、一部の機器はコンピュータとの通信方法によって扱いが異なる。 FDTI Basicに搭載されているFT232 ICは本物のシリアル機器であり、usbserialとして表示される。 一方Unoは HID機器であり、usbmodemとして表示される。 HID(ヒューマンインターフェースデバイス)プロファイルはキーボードやマウス、ジョイスティックなどに使われるものであり、シリアルデータを送れるにもかかわらず、HID機器としてコンピュータから少し異なる扱いを受ける。 いずれにせよ、シリアルターミナルに接続する際に探すべきなのはこれらのtty.usb______というポートである。

エコーテスト

準備が整ったところで、いよいよFTDIと実際に通信してみよう。 それぞれのターミナルプログラムの詳細は以降のセクションで扱うが、この例ではCoolTermを使って説明する。ただし、どのターミナルでも同じことができる。

正しい設定(9600、8-N-1-None)でターミナルを開く。

ローカルエコーがオフになっていることを確認する。

ジャンパー線を使い、FTDI BasicのTX線とRX線を接続する。

さあ、何か入力してみよう。

入力したものはすべてターミナルウィンドウに表示されるはずである。 たいしたことではないが、これでターミナルとの通信ができていることになる。 データはキーボードからパソコンへ、USBケーブルを通じてFTDIへ、FTDIのTXピンから出て、RXピンに入り、再びUSBケーブルを通ってパソコンに戻り、最終的にターミナルウィンドウに表示されている。 信じられなければ、ジャンパーを抜いてもう一度入力してみてほしい。 ローカルエコーをオフにしていれば、何も表示されないはずである。これがエコーテストである。

おまけ

もし2枚のFTDI基板や似たようなシリアル機器を持っているなら、両方を接続してみるとよい。 片方のTX線をもう片方のRX線に、そしてその逆も接続する。 そして2つのシリアルターミナルウィンドウを開き(複数のターミナルウィンドウを同時に開くこともできる)、それぞれ異なる機器に接続する。 両方が同じボーレートと設定になっていることを確認する。 接続して、入力を始めてみよう。 片方のターミナルに入力したものが、もう片方のターミナルに表示され、その逆も起こるはずである。 これで、非常に単純なチャットクライアントを作り上げたことになる。

それでは、さまざまなターミナルプログラムを見ていこう。

Arduino Serial Monitor(Windows、Mac、Linux)

Arduino統合開発環境(IDE)は、Arduinoプラットフォームのソフトウェア側を担っている。 そして、ターミナルを使うことがArduinoやその他のマイクロコントローラを扱ううえで非常に大きな部分を占めるため、Arduino IDEにはシリアルターミナルが同梱されている。 Arduino環境の中では、これはSerial Monitorと呼ばれている。

接続する

Serial Monitorは、どのバージョンのArduino IDEにも同梱されている。 開くには、Serial Monitorのアイコンをクリックするだけでよい。

Serial Monitorで開くポートを選ぶ手順は、Arduinoのコードをアップロードするためのポートを選ぶのと同じである。 ツール → シリアルポートに移動し、正しいポートを選択する。

開くと、次のような画面が表示されるはずである。

設定

Serial Monitorの設定項目は限られているが、たいていのシリアル通信のニーズには十分対応できる。 最初に変更できる設定はボーレートである。 ボーレートのドロップダウンメニューをクリックして、正しいボーレートを選択する。

Enterキーのエミュレーションも、キャリッジリターン、ラインフィード、両方、あるいはどちらもなし、に変更できる。

最後に、左下隅のチェックボックスで、ターミナルを自動スクロールするかどうかも設定できる。

長所

Serial Monitorは、Arduinoとシリアル接続をすばやく簡単に確立するのに優れた方法である。 すでにArduino IDEで作業しているなら、データを表示するために別のターミナルを開く必要は特にない。

短所

Serial Monitorは設定項目が少なく、高度なシリアル通信には物足りないことがある。

HyperTerminal(Windows)

HyperTerminalは、XPまでのWindows OSで事実上標準的なターミナルプログラムだった。Windows Vista、7、8には同梱されていない。 Windows Vista、7、8を使っていて、どうしてもHyperTerminalが必要な場合は、インターネットを少し調べれば回避策が見つかるはずである。 とはいえ、より優れた代替ソフトのほうが手に入れやすいので、それについてはすぐ後で紹介する。

Tera Term(Windows)

Tera Termは、Windows向けのターミナルプログラムの中でも特に人気の高いもののひとつである。 長年使われ続けており、オープンソースで、使い方もシンプルである。 Windowsユーザーにとって、もっともよい選択肢のひとつである。

Tera Termをインストールしたら、接続したいシリアルポートを選ぶ「TeraTerm: New connection」というポップアップが表示されるはずである。 「Serial」のラジオボタンを選び、ドロップダウンメニューから自分のポートを選択する。 Tera Termはデフォルトでボーレートを9600bps(8-N-1)に設定する。 シリアルの設定を調整する必要がある場合は、Setup → Serial Portに進む。

ローカルエコーを有効にしたい場合は、SetupメニューからTerminalを選択する。 ターミナル画面をクリアしたい場合は、Editメニューにある「Clear buffer」または「Clear screen」コマンドを使う。

RealTerm(Windows)

Tera TermはASCIIだけのシンプルなシリアルターミナル作業には優れているが、0〜255の範囲の2進数値の並びを送りたい場合はどうすればよいだろうか。 そのような用途には、RealTermがよく使われる。 RealTermは、2進数やその他の入力しにくいデータの並びを送信するために特別に設計されている。

RealTermでは、「Send」タブから2進数、16進数、10進数の値の並びを長く送信できる機能があり、これが他のターミナルプログラムとの大きな違いになっている。 「Display」タブの「Display As」の項目では、受信したデータを標準的なASCII文字として表示するか、16進数の値として表示するかなど、さまざまな表示形式を選べる。

RealTermは、より高度なターミナル用途に向いている。 特定のバイト列を送る必要がある場合はRealTermを、より基本的なターミナル作業にはTera Termを使うのがおすすめである。

YAT - Yet Another Terminal(Windows)

YATは使いやすく機能豊富なシリアルターミナルである。 テキスト通信とバイナリ通信の両方に対応し、あらかじめ定義したコマンド、複数ドキュメントに対応したユーザーインターフェース、そのほか多くの付加機能を備えている。

CoolTerm(Windows、Mac、Linux)

CoolTermは、どのOSを使っていても便利だが、Windowsほど選択肢の多くないMac OSでは特に重宝する。

設定を変更するには、歯車とレンチのアイコンのOptionsをクリックする。 ここでポート、ボーレート、ビットのオプション、フロー制御を選択できる。

左側のTerminalタブでは、Enterキーのエミュレーション(キャリッジリターン/ラインフィード)の変更、ローカルエコーのオンオフ、ラインモードとローモードの切り替えができる。 ラインモードはEnterキーが押されるまでデータを送信せず、ローモードは文字を直接画面に送信する。

CoolTermの優れた機能のひとつがHex Viewである。 送信しているデータの実際の16進数の値をASCII値の代わりに見たい場合、Hex Viewが大いに役立つ。

ここでは「hello」と入力している。キャリッジリターンとラインフィードに対応する0Dと0Aが表示されていることに注目してほしい。

Send String機能を使えば、文字列全体を16進数モードやASCIIモードで送信することもできる。

ZTerm(Mac)

ZTermは、Macユーザー向けのもうひとつのターミナルの選択肢である。 CoolTermに比べると使いやすさでは劣るように見えるが、慣れてしまえば同じくらい便利である。

接続する際は正しいポートを選択する。 一度接続すると、次回起動時にはZTermが直前の接続を自動的に開こうとする。 これを避けたい場合は、ZTermを起動する際にShiftキーを押しながら起動すればよい。

接続後の設定変更はSettings → Connectionから、接続後にポートを変更したい場合はSettings → Modem Preferencesから行える。

マクロ機能も便利である。Macros → Edit Macrosから、頻繁に入力するコマンドをマクロとして登録しておける。

コマンドライン(Windows、Mac、Linux)

先に述べたとおり、コマンドラインインターフェースを使ってシリアル接続を作ることもできる。 大きな制約は、接続オプションの少なさである。 ここまで紹介してきたたいていのプログラムには、特定の接続に合わせて調整できる多くのオプションがあるのに対し、コマンドラインの方法はとっさに機器へ手早く接続するための手段に近い。 3つの主要なOSでの実現方法を紹介する。

TerminalとScreen(Mac、Linux)

Mac

ターミナルを開く。 ls /dev/tty.*と入力して、利用可能なすべてのポートを確認する。

screenコマンドを使えば、シンプルなシリアル接続を確立できる。

screen <ポート名> <ボーレート>と入力して接続を作る。

ターミナルは空白になり、カーソルだけが表示される。これでそのポートに接続できている。

切断するには、control-aに続けてcontrol-\と入力する。 本当に切断してよいか確認が表示される。

screenで制御できる他のオプションもあるが、この方法はコマンドラインに慣れている場合にのみ使うことをおすすめする。 すべてのオプションとコマンドの一覧はman screenで確認できる。

Linux

screenコマンドはLinuxでも使える。 Macの手順との違いはわずかである。

screenがインストールされていない場合は、sudo apt-get install screenで入手する。

接続方法はMacと同じである。

切断するには、control-aに続けてshift-kと入力する。

これだけである。

MS-DOSプロンプト(Windows)

Windowsでコマンドラインにたどり着くもっとも速い方法は、スタートメニューをクリックし、検索欄にcmdと入力してEnterを押すことである。

これで空白のMS-DOSコマンドラインプロンプトが開く。

シリアルコマンドを実行するには、まずPowerShellに入る必要がある。 powershellと入力してPowerShellのコマンドモードに入る。

利用可能なすべてのCOMポートの一覧を見るには、次のように入力する。

[System.IO.Ports.SerialPort]::getportnames()

必要なポートのインスタンスを、次のコマンドで作成する。

$port = new-Object System.IO.Ports.SerialPort COM#,Baudrate,None,8,one

これで、そのCOMポートに接続し、データを送受信できるようになる。

$port.open()
$port.WriteLine("some string")
$port.ReadLine()
$port.Close()

繰り返しになるが、この方法によるシリアル通信は、コマンドラインの上級者にのみおすすめする。

コツと裏技

COMポートの変更と削除(Windows)

機器を特定のCOMポートに割り当てたい場合がある。 たとえば、古いバージョンのTera Termでは、COM16番以下のポートにしか接続できなかった。 そのため、機器がCOM17にある場合は、接続できるように変更する必要があった。 この問題は新しいバージョンのTera Termでは解決されているが、それでも一定数以下のCOMポートしか許容しないプログラムは他にも数多く存在する。

これを回避するには、デバイスマネージャーを開き、変更したいポートを右クリックして「プロパティ」を選び、「ポートの設定」から「詳細設定」に進む。 そこには利用可能なすべてのCOMポートのドロップダウンメニューがあり、一部には「使用中」と表示されている。 たとえばCOM9をCOM3に変更したい場合、このメニューでCOM3を選んでOKをクリックするだけでよい。

警告: 古いポートを整理する際、COM1は絶対に選ばないこと。この方法は本当に必要なときだけ使うべきであり、頻繁に行うべきではない。

TTYとCUの違い(Mac、Linux)

UnixやLinuxの環境では、それぞれのシリアル通信ポートにtty.*cu.*という2つの側面がある。 Arduino IDEなどでポートを確認すると、1つのポートに対して両方が表示されることがある。

この2つの違いは、TTYデバイスが機器やシステムへの着信(call in)に使われるのに対し、CUデバイス(call-up)は機器やシステムからの発信(call out)に使われるという点である。 これにより、同時に双方向の通信(全二重)が可能になる。 ターミナルやその他のプログラムを通じてネットワーク通信を行う場合に特に重要になる知識だが、頻繁に出てくる疑問でもある。 このチュートリアルの目的においては、シリアル通信には常にttyのオプションを使うと覚えておけばよい。

そのポートに接続できない

特定のポートには、一度に1つの接続しか開くことができない(ただし、異なるポートに接続する複数のターミナルウィンドウを同時に開くことはできる)。 そのため、Arduino Serial Monitorのウィンドウを開いたまま、別のターミナルプログラムで同じポートに接続しようとすると、接続できないというエラーが表示される。 ポートへの接続に問題がある場合は、まずそのポートが他の場所で開かれていないか確認しよう。

他の接続が開かれていないのに接続できない場合は、すべての設定(ボーレートなど)が正しいか確認すること。

接続はできているのにデータが見えない

正しいポートに接続できているのにデータが見えない場合、考えられる原因は2つある。 まずボーレートを確認しよう。 何度も同じことを言うようだが、ボーレートを一致させることがもっとも重要な設定である。ボーレートを確認しよう。

もうひとつの原因は、TXとRXの線が逆になっている可能性である。 TX→RX、RX→TXになっているか確認しよう。

Arduinoのプログラミングとシリアル通信

Arduinoには専用のUART(シリアルのTX線とRX線を指すもったいぶった呼び方)が1つある。 Arduinoは、この2本の線を通じてプログラムが書き込まれる。 そのため、Arduino(や他のマイクロコントローラ)を扱う際は、特にコードを開発していて頻繁にアップロードする必要がある場合、これらの線を使って他のシリアル機器と通信するのは避けたほうがよい。

UARTに別の機器を接続していると、パソコンからのデータがArduinoに正しく解釈されず、コードが意図どおりに動かなかったり、アップロードできなかったりすることがある。

同じルールがシリアルターミナルにも当てはまる。 プログラムしようとしているのと同じポートでターミナルを開いていると、うまくいかない。 Arduinoはそのポートと通信できないというエラーを出す。 その場合は、接続を閉じてから再度試してみよう。

これを回避する簡単な方法は、Arduinoに内蔵されているSoftware Serialライブラリを使って、外部とのシリアル通信専用の別のUARTを作ることである。 そうすれば、デフォルトのUARTをプログラミング用に開けたまま、別のポートで通信できる。

まとめ

盛りだくさんの情報だった。 少なくとも、ターミナルウィンドウとは何か、その使い方、自分の環境に合ったターミナルプログラムの選び方、そしてそのインターフェースの操作方法は分かったはずである。 繰り返しになるが、ターミナルプログラムはシリアル機器やマイクロコントローラを扱ううえで非常に強力な道具である。 さあ、データを集めに行こう。

さまざまな種類の通信についてさらに知りたい場合は、次のチュートリアルも参考になる。

シリアルターミナルを使う必要がある製品の例としては、次のような使い方ガイドがある(いずれも英語)。

タグ: Arduino、通信、Raspberry Pi、スキル


出典:Serial Terminal Basics(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

赤外線通信

送信用赤外線LED(左)と受信用赤外線フォトセンサー(右)

IR、つまり赤外線通信は、一般的で安価、かつ扱いやすい無線通信技術である。 赤外線は可視光と非常によく似ているが、波長がわずかに長いという違いがある。 つまり赤外線は人間の目には見えないということであり、これが無線通信にうってつけの性質になっている。 たとえばテレビのリモコンのボタンを押すと、赤外線LEDが1秒間に38,000回のペースでオンとオフを繰り返し、音量やチャンネルの操作といった情報をテレビの赤外線フォトセンサーに送信する。

このチュートリアルでは、まず一般的な赤外線通信プロトコルの内部の仕組みを説明する。 そのあとで、Arduinoを使って赤外線データを送受信する2つの例を紹介する。 最初の例では、TSOP382赤外線フォトセンサーを使って、一般的なリモコンから届く赤外線データを読み取る。 次の例では、赤外線LEDからデータを送信して、ホームステレオのような一般的な家電機器を制御する方法を紹介する。

必要なソフトウェア

こまごまとした信号処理はすべて、Ken Shirriffによって書かれた優れたArduinoライブラリが処理してくれるため、赤外線データを簡単に送受信できる。 このライブラリの仕組みについてさらに詳しく知りたい場合は、Ken Shirriffのブログ記事「A Multi-Protocol Infrared remote Library for the Arduino」を参照してほしい。 また、このチュートリアルで使うサンプルコードは、そのライブラリのexamplesディレクトリの中にある。

参考になるチュートリアル:

このチュートリアルで扱う概念には、次のようなものがある。

赤外線通信の基礎

赤外線は、単に私たちの目に見えない光であり、これが通信にとって好都合な理由である。 赤外線の発生源は私たちの周りのいたるところにある。 太陽、電球、あるいは熱を持つあらゆるものは、赤外線のスペクトルにおいて非常に明るい。 テレビのリモコンを使うとき、赤外線LEDがテレビに情報を送信するために使われている。 では、テレビの赤外線受信機は、周囲のあらゆる赤外線の中から、どうやってリモコンからの信号を選び出しているのだろうか。 答えは、赤外線信号が変調されているからである。 信号を変調するとは、データに一定のパターンを割り当てることであり、これにより受信側はどれを聞き取ればよいか分かるようになる。

赤外線通信でよく使われる変調方式は、38kHz変調と呼ばれるものである。 38kHzの信号のような規則性を持つ自然の光源はほとんど存在しないため、その周波数でデータを送る赤外線送信機は、周囲の赤外線の中でも際立つことになる。 38kHzで変調された赤外線データがもっとも一般的だが、他の周波数が使われることもある。

リモコンのボタンを押すと、送信用の赤外線LEDが1秒足らずの間、非常に速く点滅し、符号化されたデータを機器へ送信する。

もしテレビのリモコンの赤外線LEDにオシロスコープをつなげば、上のような信号が見えるはずである。 この変調された信号こそ、受信側のシステムが実際に目にしているものである。 とはいえ、受信機器の役目は、この信号を復調し、マイクロコントローラが読み取れる2値の波形として出力することである。 先ほどの波形をTSOP382のOUTピンで読み取ると、次のような波形が見えるはずである。

送信される変調信号どうしの間隔を制御することで、この波形はマイクロコントローラの入力ピンで読み取り、シリアルなビット列として復号できるようになる。

赤外線の送受信ペアがどのように機能するかを概念的に示した図を以下に示す。

Arduinoやその他のマイクロコントローラは、このシステムのどちらの側にも接続でき、データを送信すること(左側)も、受信すること(右側)もできる。

ハードウェアの接続

このチュートリアルのハードウェアには、次のようなものが必要である。 手元にあるものによっては、すべてが必要ではないかもしれない。

  • Arduino Uno
  • 赤外線LED
  • TSOP382赤外線受信機
  • 小型プッシュボタンスイッチ
  • 330Ω抵抗器
  • 赤外線キーチェーンリモコン、あるいは38kHz変調を使う任意の赤外線リモコン

Note

赤外線リモコンの代わりに、38kHz変調を使う任意の赤外線リモコンを使うこともできる。

Arduinoを使った2つの別々の回路を組み立てることになる。 最初の例の回路では、TSOP382赤外線フォトセンサーを使って、一般的なリモコンからの赤外線信号を受信して復調する。 2つ目の例の回路では、950nmの赤外線LEDと電流制限抵抗を使って、ホームステレオやテレビのような一般的な家電機器に赤外線コードを送信する。

回路図

Arduinoへの接続に必要な、完全なセットアップは次のとおりである。

LEDを正しく接続すること。長いほうの脚が正極であり、抵抗器を経てArduinoの出力ピンに接続する。 短いほうの脚が負極であり、グラウンド(GND)に接続する。

また、赤外線は可視スペクトルの外にあるため、赤外線LEDの光を目で見ることはできない。 とはいえ、たいていの携帯電話のカメラは短波長の赤外線を検知できるため、LEDがかすかに光っているのを見ることができる。

また、TSOP382の極性にも注意しよう。 センサーのピン配置については、TSOP382のデータシートを参照してほしい。

LEDに接続する電流制限抵抗は、最大出力と最長の通信距離を得るには100Ω(40mA)程度まで下げることができる。 より大きな抵抗値を使うと、LEDはそれほど明るく光らず、通信距離も短くなる。 330Ωの抵抗であれば、薄暗い部屋の中でも赤外線LEDを問題なく動作させられるはずである。

ライブラリの概要

Note

この例は、パソコン上で最新版のArduino IDEを使っていることを前提としている。Arduinoを使うのが初めてであれば、Arduino IDEのインストールについてのチュートリアルを確認してほしい。Arduinoライブラリをインストールしたことがなければ、インストールガイドも確認してほしい。

Ken ShirriffのIRremoteライブラリをダウンロードしてインストールする

ArduinoにすばやくIR制御機能を追加するには、Ken ShirriffのIRremoteライブラリをダウンロードすることをおすすめする。 Shirriffは、赤外線リモコン用のライブラリを書いている。 このライブラリはArduino Library Managerから入手できる。 IRremote by shirriffで検索すれば、最新版をインストールできるはずである。 手動でライブラリをダウンロードしたい場合は、GitHubリポジトリから入手できる。

ライブラリのインストールについて助けが必要な場合は、Installing an Arduino Libraryのチュートリアルを確認してほしい。 ダウンロードしたフォルダを、Arduinoのスケッチブック内の「libraries」フォルダに展開する必要がある。

Note

警告:「libraries」フォルダにコピーするフォルダの名前は、必ず「IRremote」にすること。ディレクトリ名にハイフン(-)が含まれていると、コードのコンパイル時にエラーが起きることがある。

IRremoteライブラリは、プロジェクトに赤外線機能を追加するための強力な道具である。 家電機器に赤外線コードを送信したい場合も、リモコンからArduinoへ赤外線コードを受信したい場合も(あるいはその両方でも)使うことができる。 ここでは、このライブラリでできる簡単なことをいくつか紹介する。 さらに詳しい使い方については、Ken Shirriffのブログを参照してほしい。

赤外線を受信する例

赤外線リモコンは、対応する家電機器と同じくらいありふれた存在である。 使わなくなった古いリモコンたちを、次のプロジェクトで活用できるとしたらどうだろうか。 この例では、TSOP382赤外線受信機とArduinoを使って、任意の赤外線リモコンからコードを読み取る方法を紹介する。 個々のボタン操作からコードを受信できるようになれば、リモコンとArduinoは汎用の近距離通信インターフェースになる。

この例で必要なのは、Arduinoに接続したTSOP382赤外線受信機と一般的なリモコンだけである。赤外線LEDとボタンは接続したままでよいが、次の例まで使うことはない。

まず、IR用のArduinoライブラリをインストールする必要がある。 Arduinoライブラリのインストール方法については、Installing an Arduino Libraryのチュートリアルを参照してほしい。

IRライブラリを入手したら、Arduinoのプロジェクトディレクトリに移動する。Arduino/libraries/IRremote/examples/IRrecvDemoを開き、IRrecvDemo.inoを開く。 このスケッチをArduinoに書き込む。

このスケッチは、使っているリモコンの種類を自動的に判別し、どのボタンが押されたかを識別する。 Arduino IDEでシリアルポート9600bpsで開き、リモコンのさまざまなボタンを押してみよう。

特定のボタンが押されたとき、その受信値を使ってコードの中で何か別のこと(モーターやLEDのオンオフなど)を行うことができる。

それぞれのボタン操作の結果は、value()メソッドを呼び出すことで取得できる。

results.value

その値をターミナルウィンドウに出力することもできる。

Serial.println(results.value, HEX); // ボタン操作の16進数の値を表示する

あるいは、条件分岐を実行するためにその値を読み取る必要があるかもしれない。

if (irrecv.decode(&results)) // コードを受信したかどうかを確認する
{
    if (results.value == 0xC284) // ボタン操作が16進数の0xC284と一致する場合
    {
        // ここで何か処理を行う
    }
    irrecv.resume(); // 次の値を受信する
}

赤外線を送信する例

この例では、Arduinoと赤外線LEDを使って赤外線リモコンを模倣し、家電機器(テレビやステレオなど)を制御する。 LEDで家電機器を制御するには、その機器がどの種類の赤外線プロトコルを使っているかを知る必要がある。 これを知るもっとも簡単な方法は、その機器に付属しているリモコンを手元に用意することである。 この例では、TSOP382赤外線受信機でリモコンのボタン操作を受信し、そのデータをコピーして、赤外線LEDから送信する。

この例では、LEDとTSOP382の両方を使う。

まだの場合は、まずIR用のArduinoライブラリをインストールする。 Arduinoライブラリのインストール方法については、Installing an Arduino Libraryのチュートリアルを参照してほしい。

IRremoteライブラリを入手したら、Arduinoのプロジェクトディレクトリに移動する。Arduino/libraries/IRremote/examples/IRrecordを開き、IRrecord.inoを開く。 このスケッチをArduinoに書き込む。

スケッチを書き込んだら、Arduinoのシリアルモニタを9600bpsで開く。 リモコンをTSOP382に向けて、ボタンを押してみよう。 ターミナルウィンドウに、押したボタンに対応する特定のコードが表示されるはずである。

今度は、LEDを対象の家電機器に向けて、Arduinoに接続したプッシュボタンを押してみると、リモコンのボタン操作に対応するコードが送信される。 どのコードがどのボタンに対応しているかが分かれば、Arduinoと赤外線LEDを使って独自のリモコンを作ることができる。

たとえば、送信の例の回路では、私のPanasonicリモコンの音量アップボタンを押したときに未知のコードを受信した。 2行目のデータバイトは、音量アップコマンドのマークとスペースのタイミングとして表示された生のコードである。

未知のコードを受信し、それを送信したい場合は、Arduinoのスケッチの中で次の行を使う。

irsend.sendRaw(rawCodes, codeLen, 38);

家電機器のリモコンを持っていない場合や、幸運にも一般的なプロトコルを使うリモコンを持っている場合は、IRremoteライブラリのIRSendDemo.inoの例にあらかじめ用意されているメーカーコードを試してみることもできる。

たとえば、ソニー製のテレビを持っていて、LEDでテレビの電源をオンオフしたい場合は、次のようなコードを使うことができる。

for (int i = 0; i < 3; i++)
{
    irsend.sendSony(0xa90, 12); // ソニーテレビの電源コード
    delay(40);
}

家電機器のメーカーによって、コマンドを送るプロトコルは異なる。 そのため、このライブラリを使うには機器のメーカーを指定する必要がある。 また、ソニーのコマンドはfor()ループを使って3回送信する必要があることにも注意してほしい。 どのプロトコルにもそれぞれ細かい癖がある。 一般的な赤外線プロトコルの非公式なコマンドについては、San BergmansのWebサイトが優れた参考資料になる。

一般的な赤外線プロトコルとして、IR用Arduinoライブラリは、NEC、Sony SIRC、Philips RC5、Philips RC6、そして生データ形式に対応している。 それぞれのメーカー向けにArduinoのコードで使えるメソッドは次のとおりである。

void sendNEC(unsigned long data, int nbits);
void sendSony(unsigned long data, int nbits);
void sendRC5(unsigned long data, int nbits);
void sendRC6(unsigned long data, int nbits);
void sendDISH(unsigned long data, int nbits);
void sendSharp(unsigned long data, int nbits);
void sendPanasonic(unsigned int address, unsigned long data);
void sendJVC(unsigned long data, int nbits, int repeat);
void sendRaw(unsigned int buf[], int len, int hz);

datanbitsのフィールドには、使用しているプロトコルに固有の情報を入力する必要がある。 この機能の使い方についてさらに詳しくは、IR用Arduinoライブラリのブログ記事のSending libraryの詳細についての節を参照してほしい。

もっとパワーが欲しい場合は? 赤外線LEDは素晴らしい部品である。赤外線受信機と組み合わせれば、リモコン制御や、基本的な遠隔データ通信にも使える。 唯一の問題は、Arduinoではその全性能を引き出せないという点である。 LEDの送信距離は最適とは言えないかもしれない。 Arduinoの出力ピンから取り出せる電流は最大でおよそ30mA程度である。 つまりLEDは、フルパワーである50mAでは駆動できないということである。 これにより、送信距離が短くなってしまう。

まとめ

赤外線LEDや受信機についてのさらなる資料やリソースを探しているなら、次のようなリンクを確認してみてほしい。

これで、自分だけの赤外線通信システムを作る準備が整ったはずである。 この目に見えない変調光源で、何を制御してみたいだろうか。 アイデアが必要なら、次のようなチュートリアルも確認してみてほしい。

タグ: Arduino、通信、接続ガイド、光、技術、無線


出典:IR Communication(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

光を操ることは、電子工作愛好家にとって非常に役立つスキルである。 照明から距離測定まで、光は電子的なものと物理的なものを、実にさまざまな有用な形で橋渡ししてくれる。

波長

ある光の束を特徴づける鍵となる要素は、その波長である。 光は波として空間を伝わり、2つの波の山の間の距離がその光の波長である。 人間にとって、波長は光の色を決める要素である。

物理学において物事は決して単純にはいかないもので、光の束は光子と呼ばれる粒子の流れとしてもふるまう(マゾヒスティックな人は光の波動粒子二重性についてのこの記事を参照してほしい)。 波長が短い光ほど、1つの光子あたりのエネルギーが大きくなる。

強度

光の束を特徴づけるもうひとつの要素が強度である。 放射強度は、アイスクリームコーンの先端にある円で囲まれた球面をエネルギーが横切る速さ、つまりワット毎ステラジアンで測定される。 これを理解するために、中心にごく小さな星がある球体を想像してみよう。 光はその星からあらゆる方向に均等に広がっていく。 今度は、その星の中心を頂点とし、球の表面まで伸びるアイスクリームコーンを追加する。 このコーンの底の角度は1ラジアンである(円には2πラジアンが含まれており、1ラジアンはおよそ57.3度である)。 このアイスクリームコーンによって定義される面積をステラジアンと呼ぶ。

可視光と不可視光

光について語るとき、私たちがたいてい思い浮かべるのは可視光、つまり虹や日光のあの素晴らしいものである。 しかし光は実際には、非常に幅広い波長の範囲にわたって存在している。 これは電磁スペクトルと呼ばれる。

一方の端には、生命とは根本的に相容れない、有害で高エネルギーの電離放射線であるガンマ線やX線がある。 もう一方の端には、非常に低い周波数で波長の長い電波があり、これは広大な距離を越えて情報を運び、宇宙の始まりそのものを垣間見せてくれる。

この記事では、可視光と、それにもっとも近い領域である赤外線と紫外線に絞って扱う。 紫外線から遠赤外線にかけては、光は私たちが可視光で見慣れているのとかなり似たふるまいをする。影ができ、レンズで焦点を合わせられ、白い紙のようなもので拡散できる、といった具合である。 それより長い、あるいは短い波長の領域に踏み込むと、物事は奇妙になり始めるため、それについては別の機会に譲ることにする。

ここでは、光を紫外線、可視光、赤外線という3つのグループに分けて説明する。 紫外線は可視光よりわずかに波長が短い光であり、赤外線はわずかに波長が長い光である。 この3つのグループの中では、可視光と赤外線のほうが電子工学においていくらか使い道が多く一般的であるため、それらについてより多くの時間を割くことにする。

紫外線

紫外線は10nmから400nmの間の光であり、X線と可視光の間に位置する。 紫外線は生命体にとって非常に有害なことがあり、もっともよく知られている影響は日焼けだろう。

UVA

UVA(波長315nm〜400nm)は、紫外線の中でもっともエネルギーの低い帯域である。 これは人間にはほぼ見えないが、多くの昆虫、さらには一部の鳥はこの光の帯域を見ることができる。 白色蛍光灯や白色LEDは、UVA光を素材に当てることで、その素材がUVA光子を吸収し、可視スペクトルの光子を放出する(私たちには白く見える)という仕組みで動作している。

UVAは、偽造文書の検出にもよく使われる。 偽造対策として、多くの文書(パスポート、運転免許証、紙幣など)には、UVA放射線を当てると光る透かしが入っている。 ブラックライトポスターも、UVA光に反応するもののひとつの例であり、漂白剤、石鹸、そして多くの生体材料もUVA光を当てると光る。

太陽光に含まれるUVA光のほとんどは地表に到達する。

UVB

UVB(280nm〜315nm)は、UVAよりも高いエネルギーレベルの光である。 これは太陽光に含まれており、日焼けや皮膚がんを引き起こす肌へのダメージだけでなく、人体内でのビタミンDの合成にも関与している。 また溶接トーチからも発生し、たとえ十分な距離があっても、防護なしでその閃光を短時間見ただけで深刻な目の損傷を引き起こすことがある。

UVB光は通常の窓ガラスによってかなりよく遮断される。これが、開いた車の窓から腕を出しているとその腕だけが日焼けしてしまう理由である。 リチャード・ファインマン(ノーベル賞受賞者であり、ボンゴ奏者としても知られる)は、トリニティ核実験の爆発を観察する際、爆発が放つ紫外線放射から身を守るため、ピックアップトラックのフロントガラスを使ったという。

太陽が放出するUVB光のうち、地表に到達するのはおよそ10%に過ぎず、残りの90%は大気(主にオゾン層)に吸収される。

UVC

UVC(100nm〜280nm)は、私たちにとって興味深い紫外線の限界にあたる帯域である。 太陽が発するUVCのほとんどは地表に到達せず、大気がそれを非常に効果的に遮っている。

電子的に消去や書き換えができるEEPROMやフラッシュメモリが登場する以前の悪しき時代には、不揮発性で非磁気的な電子データストレージの手段はEPROMしかなかった。 一度書き込まれたEPROMは、強力なUVC光源に20〜30分間さらすことでしか消去できなかった。 趣味でやっている人にとって、書き換えたコードがバグを修正できたかどうかを確かめるのに、それだけ待たされるのは長い時間である。

可視光

可視光は、およそ380nmから740nmの範囲の光である。 これには個人差があり、これより短い、あるいは長い波長の光を検知できる目を持つ人もいるが、一般にたいていの人の目はこの領域に感度を持っている。

人間の目

人間の目が光を知覚する方法には、2つの特異な点がある。目はそれぞれの波長に対して異なる感度を持っていることと、光の強度を線形ではなく対数的に知覚することである。

色の知覚

このグラフに示されているように、私たちの目はそれぞれの波長の光を異なる効率で拾い上げ、知覚された強度を混ぜ合わせることで「色」と呼ぶものを作り出している。 さらに、光量が少ない状況では、私たちの色の知覚が歪んでしまうことも分かる。

このため、光の強度を表す特別な単位であるカンデラが作られた。 カンデラは、光源の色に応じて強度を重み付けしたものであり、人間の目には、波長が違っていても1カンデラの光源はどれも同じくらいの明るさに知覚される。 LEDの明るさはたいていミリカンデラ(mcd)で表され、色によって知覚される強度の違いを示すよい例が、RGB LEDの明るさである。たとえば赤が800mcd、緑が4000mcd、青が900mcdといった具合である。 下のグラフには、この3色の波長(625nm、520nm、467.5nm)を示してある。

人間の目は、異なる波長の光を混ぜ合わせることで、実際には存在しない波長の光を検知しているかのように錯覚させることができる。たいていのカラーディスプレイはこの原理で動作している。 実際に使われている色はたった3色(何らかの赤、緑、青)だけであり、この3色の光をさまざまな強度で混ぜ合わせることで、自然界のほとんどの色(少なくとも私たちの目にとっては)を再現できる。

強度の知覚

私たちは自然に、光を線形な現象だと考えがちである。 2つの光源があったとき、片方がもう片方の2倍明るいと感じることは十分にありうる。 これが色によってどう影響を受けるかはすでに見てきたが、今度は単一の色の光の強度と、それに対する私たちの知覚との関係を考えてみよう。 LEDの強度は、それを駆動する電流に対して線形に変化する。

ちょっとした実験をしてみよう。 Arduino、ブレッドボード、抵抗器、LED、プッシュボタンがあれば、次の回路を組んで、コードをダウンロードし、Arduinoに書き込んでみてほしい。

この回路はとても単純である。ボタンを1回押すとLEDが点灯する。 押したまま保持すると、LEDは徐々に明るくなっていく。 離すと、LEDの明るさが増えるのが止まり、Arduinoはシリアルポート経由で、押し始めたときと比べてどれだけ明るくなったかを出力する。 LEDが最初の2倍の明るさになったところで止めてみてほしい。

これがなぜこんなに難しいのだろうか。 LEDの光の出力は線形であるため、LEDに流れる電流を2倍にすれば、放出される光のエネルギー量も2倍になる。 しかし私たちの目は線形には反応せず、対数的に反応する。 理由は単純である。私たちの目は、星明かりから日中の明るさまで、あらゆる照明条件にわたって有用な情報を提供する必要がある。 雲のない満月の夜、光の強度は晴れた日中のわずか44万分の1程度しかないが、それでも私たちの目はその両極端、そしてその間のあらゆる状況で正常に機能しなければならない。 これが、線形な光源の相対的な明るさを判断するのを非常に難しくしている。

色覚異常

色覚異常は、その名前から連想されるような、単純に色を知覚できないという症状ではない。 実際には色覚異常には多くの種類があり、もっとも一般的な赤緑色覚異常は、男性人口のおよそ10%に何らかの形で影響を与えている。

色覚異常は簡単な検査で診断でき、これは同じような大きさの点で構成された背景の中から、異なる色の点で作られた模様や記号を識別できるかを調べるものである。

色覚異常を持つ人々への配慮として、情報を伝えるために色だけに頼らないようにしてほしい。 悪い設計の例としては、ある状態を示すために色が変わるLED(緑は「正常」、赤は「失敗」)、数値と地域を結びつけるために色の範囲を使う地図、白地に黒か黒地に白以外の文字色などが挙げられる。

赤外線

赤外線は、可視光よりも波長が長く、マイクロ波よりも波長が短い光である。 慣例的に700nmから始まり1mm(1,000,000nm)までとされており、紫外線や可視光よりもはるかに広いスペクトルの領域を占めている。 太陽から地表に届く光エネルギーのおよそ55%は赤外線である。

近赤外線

近赤外線は電子工学において非常に興味深い領域である。これは、赤外線リモコン、物体センサー、距離検出器が動作する領域である。 これは可視光の範囲のすぐ上にあり、半導体技術で作り出すことも検知することも非常に簡単である。

近赤外線の帯域は1400nmまで広がっている。 よく使われる発光波長は850nmと950nmである。 私たちの周りには常に膨大な量の近赤外線が存在しており、赤外線を使った信号伝達やセンシングが干渉を受ける可能性は大きい。 たいていの赤外線信号システム(赤外線リモコンなど)は、望まない波長の光を除去しようとするのではなく、決まった周波数でビームを変調することでこの問題を解決している。

近赤外線はデジタルカメラでもよく検知される。 あまりによく検知されるため、たいていのデジタルカメラには赤外線の波長を遮断する物理的なフィルターが搭載されている。 このフィルターを取り外せば、赤外線領域での感度を高めることができる。 可視光を遮り赤外線だけを通す単純なフィルターは、35mmフィルムのネガから作ることができる。写真の写っていないフィルムロールの端の部分がちょうどよい。

長波長赤外線

長波長赤外線は8000nm〜15000nmの範囲の光である。 これはサーモグラフィーの領域であり、物の相対的な温度を示すあの見事な疑似カラー画像はここから生まれている。

近赤外線イメージングと長波長赤外線イメージングの違いを誤解するのは、よくある間違いである。 近赤外線イメージングは比較的簡単に実現できる。標準的なCMOSやCCDのイメージングチップは、近赤外線領域の光を簡単に検知できる。 一方、長波長赤外線には専用のセンサーが必要である。この光の波長は近赤外線の1000倍も長いため、センサー素子にもそれに応じた大きな構造が必要になる。

この領域のもうひとつの、ますます身近になっている用途がレーザーエッチングとレーザー切断である。 たいていのレーザーカッターは、10640nmの波長でレーザー光を発生させるCO2レーザー管を使っている。

まとめ

光は魅力的で複雑な存在であり、このチュートリアルではその表面をなぞったにすぎない。 さらに学びたい場合は、次のような優れた情報源を確認してみてほしい。

タグ: 概念、光、物理学


出典:Light(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

抵抗器

抵抗器は、電子部品の中でもっともありふれた存在である。 ほぼすべての回路に欠かせない部品であり、私たちのお気に入りの式であるオームの法則にも重要な役割で登場する。

このチュートリアルで扱う内容:

  • 抵抗器とは何か
  • 抵抗の単位
  • 抵抗器の回路図記号
  • 抵抗器の直列接続と並列接続
  • 抵抗器のさまざまな種類
  • カラーコードの読み方
  • 表面実装抵抗器の表示の読み方
  • 抵抗器の応用例

参考になるチュートリアル:

抵抗器の基礎

抵抗器は、決まった、変化することのない電気抵抗を持つ電子部品である。 抵抗器が持つ抵抗は、回路の中を流れる電子の流れを制限する

抵抗器は受動部品であり、電力を消費するだけで、生み出すことはない。 抵抗器は、オペアンプやマイコン、その他の集積回路のような能動部品を補う形で回路に組み込まれることが多い。 一般的な用途としては、電流の制限、分圧、I/Oラインのプルアップなどが挙げられる。

抵抗の単位

抵抗器の電気抵抗はオームという単位で測られる。 オームの記号はギリシャ文字の大文字オメガ「Ω」である。 1Ωの定義は(少し回りくどいが)、1ボルト(1V)の電位差を加えたときに1アンペア(1A)の電流が流れる、2点間の抵抗のことである。

他のSI単位と同じように、オームの値が大きいときや小さいときは、キロ、メガ、ギガといった接頭辞をつけて読みやすくする。 抵抗器ではキロオーム(kΩ)やメガオーム(MΩ)の範囲がよく使われる(ミリオーム(mΩ)の抵抗器はあまり見かけない)。 たとえば4,700Ωの抵抗器は4.7kΩの抵抗器と同じであり、5,600,000Ωの抵抗器は5,600kΩ、あるいは(より一般的には)5.6MΩと表記される。

回路図記号

すべての抵抗器には2つの端子があり、抵抗器の両端に1つずつある。 回路図の上では、抵抗器は次の2種類のどちらかの記号で描かれる。

ギザギザの線(あるいは四角形)から伸びている線が、それぞれ抵抗器の端子であり、回路の他の部分へとつながる。

抵抗器の回路記号には、たいてい抵抗値と名前が添えられる。 オームで表される値は、回路を評価するうえでも実際に組み立てるうえでも欠かせない情報である。 抵抗器の名前は、たいてい R に数字を続けたものになる。 1つの回路の中では、それぞれの抵抗器に固有の名前と番号をつける。

抵抗器の種類

抵抗器にはさまざまな形やサイズがある。 スルーホール型のものも、表面実装型のものもある。 値が固定された標準的な抵抗器もあれば、複数の抵抗器がまとまったパッケージや、特殊な可変抵抗器もある。

端子形状と実装方法

抵抗器の実装方法には、スルーホールと表面実装の2種類がある。 それぞれ、PTH(plated through-hole)、SMDまたはSMT(surface-mount technology/device)と略されることが多い。

スルーホール型の抵抗器には長くしなやかなリード線が付いており、ブレッドボードに差し込んだり、プロトタイピングボードやプリント基板(PCB)に手ではんだ付けしたりできる。 ブレッドボードでの試作や、0.6mmほどしかない小さなSMD抵抗器をはんだ付けしたくない場面でよく使われる。 長いリード線はたいてい切りそろえる必要があり、表面実装タイプに比べてスペースを多く取る。

もっとも一般的なスルーホール抵抗器はアキシャル(円筒型)パッケージで、そのサイズは定格電力に比例する。 一般的な½W抵抗器は長さ約9.2mm、より小さな¼W抵抗器は約6.3mmである。

表面実装型の抵抗器は、たいてい小さな黒い長方形で、両端に銀色の光沢のある小さな導電性の端子がついている。 これらの抵抗器はPCBの上に置かれ、対応するランド(はんだ付け用のパッド)にはんだ付けされる。 非常に小さいため、ロボットによって配置され、オーブンではんだを溶かして固定するのが一般的である。

SMD抵抗器は0805(0.08インチ×0.05インチ)、0603、0402といった標準化されたサイズで作られている。 大量生産される基板や、スペースが貴重な設計に向いているが、手ではんだ付けするには安定した精密な手つきが求められる。

抵抗体の材質

抵抗器はさまざまな材料で作られる。 現代の一般的な抵抗器のほとんどは、カーボン、金属、または金属酸化物の薄膜でできている。 これらの抵抗器では、導電性(それでいて抵抗も持つ)の薄い膜がらせん状に巻きつけられ、絶縁材料で覆われている。 飾り気のない標準的なスルーホール抵抗器の多くは、カーボン皮膜抵抗か金属皮膜抵抗である。

その他のスルーホール抵抗器には、巻線型や、極薄の金属箔で作られたものもある。 これらはたいてい高価で高性能な部品であり、高い定格電力や高い耐熱温度といった特有の性質を目的に選ばれる。

表面実装抵抗器は、たいてい厚膜型または薄膜型のいずれかである。 厚膜型は安価だが薄膜型ほどの精度はない。 どちらのタイプも、抵抗性の金属合金の薄い膜がセラミックの基板とガラス/エポキシのコーティングのあいだに挟まれ、両端の導電性の端子につながっている。

特殊なパッケージ

このほかにも、特殊な用途向けの抵抗器がいろいろある。 5個程度の抵抗器があらかじめ配線された抵抗アレイというパッケージもある。 こうしたアレイの中の抵抗器は、共通のピンを共有していたり、分圧回路として構成されていたりする。

可変抵抗器(ポテンショメータ)

抵抗器は必ずしも固定値である必要はない。 レオスタットと呼ばれる可変抵抗器は、決まった範囲の中で抵抗値を調整できる。 レオスタットとよく似たものにポテンショメータ(ポット)がある。 ポットは内部で2つの抵抗を直列につなぎ、そのあいだの中間タップ(ワイパー)を動かすことで調整可能な分圧回路を作り出す。 この種の可変抵抗器は、音量つまみのように調整が必要な入力によく使われる。

抵抗値の表示を読み取る

抵抗器の多くは値を直接表示しているわけではないが、その抵抗値がわかるような表示が施されている。 PTH抵抗器はカラーコード方式(回路に彩りを添えてもくれる)を使い、SMD抵抗器には独自の表示方式がある。

カラーバンドの読み方

スルーホールのアキシャル抵抗器は、たいていカラーバンド方式で値を表示する。 ほとんどの抵抗器には4本のカラーバンドが巻かれているが、5本や6本のものも見つかる。

4バンドの抵抗器

標準的な4バンド抵抗器では、最初の2本のバンドが抵抗値の上位2桁を示す。 3本目のバンドは重みの値であり、最初の2桁に10のべき乗を掛け合わせる倍率を表す。

最後のバンドは抵抗器の誤差(許容差)を示す。 誤差は、抵抗器の実際の抵抗値が、公称値に対してどれだけ前後しうるかを表す。 完璧な抵抗器は存在せず、製造プロセスによって誤差の良し悪しが決まる。 たとえば誤差5%の1kΩ抵抗器は、実際には0.95kΩから1.05kΩのあいだのどこかになりうる。

どのバンドが最初でどれが最後かは、どう見分けるのか。 最後の誤差バンドは、値を示す他のバンドとはっきり離れて配置されていることが多く、たいてい銀色か金色である。

5バンドと6バンドの抵抗器

5バンド抵抗器では、最初の2本のバンドと倍率バンドのあいだに、3桁目を示すバンドが追加される。 5バンド抵抗器は、選べる誤差の種類もより幅広い。

6バンド抵抗器は、基本的には5バンド抵抗器の末尾に、温度係数を示すバンドが1本加わったものである。 これは、セ氏温度が変化したときに抵抗値がどれだけ変化するかを示す。 たいてい、この温度係数の値は非常に小さく、ppmのオーダーである。

カラーバンドを読み取る

カラーバンドを読み取るときは、下のようなカラーコード表を参照する。 最初の2本のバンドについては、その色に対応する数字を調べる。 たとえばここに示す4.7kΩの抵抗器は、最初のバンドが黄色、次が紫色であり、それぞれ数字の4と7に対応する(47)。 この抵抗器の3本目のバンドは赤色であり、47に10²(つまり100)を掛けることを示している。 47×100は4,700である。

カラーコードを覚えたいなら、語呂合わせが役立つこともある。 覚え方はいくつも知られている(中には品のないものもある)。

もう1つの覚え方として、虹の色の並び「赤橙黄緑青藍紫」から藍(indigo)を抜き、先頭に黒と茶色、末尾に灰色と白を加える、という方法もある。

抵抗器のカラーコード表

値(上位2桁)倍率(3桁目)誤差(4桁目)
0×1
1×10
2×100
3×1,000
4×10,000
5×100,000
6×1,000,000
7×10,000,000
8×100,000,000
9×1,000,000,000
±5%
±10%

たとえば「黄、紫、赤、金」の4バンドなら、47×100 = 4,700Ω、誤差±5%となり、1kΩ±5%の抵抗器であれば「茶、黒、赤、金」のように読み取れる。

表面実装抵抗器の表示を読み取る

0603や0805パッケージのようなSMD抵抗器は、値の表示方法が異なる。 よく見られる表示方式がいくつかあり、たいてい部品の上面に3〜4文字(数字またはアルファベット)が印刷されている。

見えている3文字がすべて数字であれば、それはおそらくE24方式の表示である。 この表示方法は、PTH抵抗器のカラーバンド方式とよく似た考え方に基づいている。 最初の2つの数字が値の上位2桁を、最後の数字が倍率を表す。

上の写真の例では、抵抗器に104105205751754という表示がある。 104と表示された抵抗器は100kΩ(10×10⁴)、105は1MΩ(10×10⁵)、205は2MΩ(20×10⁵)である。 751は750Ω(75×10¹)、754は750kΩ(75×10⁴)である。

もう1つよく使われる表示方式がE96であり、この中ではもっとも読み解きにくい。 E96方式の抵抗器には3文字が表示され、最初の2つが数字、最後の1つがアルファベットになっている。 最初の2つの数字は、下の対応表を使って値の上位3桁を示す。

コードコードコードコードコードコード
011001714733215493166546481681
021021815034221503246647582698
031051915435226513326748783715
041072015836232523406849984732
051102116237237533486951185750
061132216538243543577052386768
071152316939249553657153687787
081182417440255563747254988806
091212517841261573837356289825
101242618242267583927457690845
111272718743274594027559091866
121302819144280604127660492887
131332919645287614227761993909
141373020046294624327863494931
151403120547301634427964995953
161433221048309644538066596976

末尾のアルファベットは倍率を表し、次の表と対応する。

文字倍率文字倍率文字倍率
Z0.001A1D1000
Y または R0.01B または H10E10000
X または S0.1C100F100000

たとえば01Cという表示は、おなじみの10kΩ(100×100)であり、01Bは1kΩ(100×10)、01Dは100kΩになる。 ここまでは簡単だが、他のコードはそう単純にいかないこともある。 先ほどの写真にある85Aは750Ω(750×1)、30Cは実は20kΩである。

定格電力

抵抗器の定格電力は、あまり目立たない値の1つだが、抵抗器の種類を選ぶときには重要になる話題である。

電力とは、エネルギーが別の形に変換される速さのことであり、2点間の電位差にそのあいだを流れる電流を掛け合わせて計算され、単位はワット(W)である。 たとえば電球は電気を光に変換する。 しかし抵抗器は、流れ込んだ電気エネルギーをに変換することしかできない。 熱は電子部品にとってあまり良い遊び相手ではなく、熱がこもりすぎると煙や火花、火災につながる。

すべての抵抗器には、決まった最大定格電力がある。 抵抗器が熱くなりすぎないようにするには、抵抗器にかかる電力を最大定格未満に保つことが重要である。 定格電力はワットで測られ、たいてい⅛W(0.125W)から1Wの範囲に収まる。 1Wを超える定格電力を持つ抵抗器は、パワー抵抗器と呼ばれ、電力を消費する能力そのものを目的として使われる。

定格電力の見分け方

抵抗器の定格電力は、たいていパッケージの大きさから見分けられる。 標準的なスルーホール抵抗器は¼Wか½Wの定格であることが多い。 より特殊な用途向けのパワー抵抗器では、定格電力が抵抗器自体に表示されていることもある。

表面実装抵抗器の定格電力も、サイズからある程度判断できる。 0402サイズと0603サイズはたいてい1/16W定格、0805サイズは1/10Wに対応する。

抵抗器にかかる電力を計算する

電力はたいてい電圧と電流の積(P = IV)として計算されるが、オームの法則を使えば抵抗値からも電力を計算できる。 抵抗器を流れる電流がわかっているなら、電力は次のように計算できる。

\[ P = I^2 \times R \]

あるいは、抵抗器にかかる電圧がわかっているなら、電力は次のように計算できる。

\[ P = \frac{V^2}{R} \]

抵抗の直列接続と並列接続

電子工作では、抵抗器を直列や並列の回路にまとめて使うことがよくある。 抵抗器を直列や並列に組み合わせると合成抵抗が生まれ、それは2つの式のどちらかで計算できる。 抵抗値の組み合わせ方を知っておくと、特定の抵抗値を作り出したいときに役立つ。

直列抵抗

抵抗器を直列につないだ場合、抵抗値は単純に足し合わされる。

\[ R_{合成} = R_1 + R_2 + \cdots + R_N \]

N個の抵抗器を直列につないだ場合、合成抵抗はすべての抵抗値の総和になる。

たとえば、どうしても12.33kΩの抵抗器が必要だとする。 そんなときは、より入手しやすい12kΩと330Ωの抵抗器を見つけて、直列につなげばよい。

並列抵抗

並列につないだ抵抗器の合成抵抗を求めるのは、直列ほど簡単ではない。 N個の抵抗器を並列につないだときの合成抵抗は、それぞれの抵抗の逆数の和の、さらに逆数になる。 言葉で説明するより、式を見たほうがわかりやすいだろう。

\[ \frac{1}{R_{合成}} = \frac{1}{R_1} + \frac{1}{R_2} + \cdots + \frac{1}{R_N} \]

(抵抗の逆数は実はコンダクタンスと呼ばれており、より簡潔に言えば、並列につないだ抵抗器のコンダクタンスは、それぞれのコンダクタンスの総和になる。)

この式の特別な場合として、抵抗器が2本だけの場合は、逆数の入れ子が少ない次の式で合成抵抗を求められる。

\[ R_{合成} = \frac{R_1 \times R_2}{R_1 + R_2} \]

さらに特別な場合として、同じ値の抵抗器2本を並列につないだ場合、合成抵抗はその値のちょうど半分になる。 たとえば10kΩの抵抗器2本を並列につなぐと、合成抵抗は5kΩになる。

2つの抵抗器が並列であることを示す省略記法として、並列演算子 が使われる。 たとえばR1とR2が並列であれば、概念上はR1‖R2と書ける。 分数だらけの式を書かずに済み、すっきりする。

抵抗ネットワーク

合成抵抗の計算に慣れてもらうための定番として、電子工学の先生たちは、入り組んだ抵抗ネットワークの合成抵抗を求めさせるのが大好きである。

穏やかな問題の例としては、「この回路の端子AからBまでの抵抗はいくつか」というものがある。

この手の問題を解くには、回路の一番奥から手をつけ、端子に向かって少しずつ単純化していく。 この例では、R7、R8、R9がすべて直列につながっているので、まとめて足し合わせられる。 この3本はR6と並列になっているので、これら4本の抵抗はR6‖(R7+R8+R9)という1本の抵抗にまとめられる。 すると回路はこうなる。

今度は、右側の4本の抵抗をさらに単純化できる。 R4、R5、そして先ほどまとめたR6〜R9の合成抵抗は、すべて直列につながっているので足し合わせられる。 そうしてできた直列部分は、R3と並列になっている。

こうして、A端子とB端子のあいだに残るのは3本の直列抵抗だけになる。 あとは足し合わせるだけである。 つまり、この回路全体の合成抵抗は R1+R2+R3‖(R4+R5+R6‖(R7+R8+R9)) となる。

応用例

抵抗器は、これまでに作られたほぼすべての電子回路に登場する。 ここでは、抵抗器に大きく依存しているいくつかの回路の例を紹介する。

LEDの電流制限

LEDに電力を加えたときに壊れてしまわないようにするうえで、抵抗器は鍵となる部品である。 LEDに直列に抵抗器をつなぐことで、両方の部品を流れる電流を安全な値に制限できる。

電流制限抵抗の値を決めるときは、LEDの2つの特性値、標準順方向電圧最大順方向電流を確認する。 標準順方向電圧は、LEDを点灯させるのに必要な電圧であり、LEDの色によって(たいてい1.7Vから3.4Vの範囲で)異なる。 最大順方向電流は、基本的なLEDではたいてい20mA程度であり、LEDに流し続ける電流は常にこの定格以下に保つ必要がある。

この2つの値がわかれば、次の式で電流制限抵抗の値を決められる。

\[ R = \frac{V_S - V_F}{I_F} \]

VS は電源電圧(電池や電源の電圧)であり、VFIF は、それぞれLEDの順方向電圧と流したい電流である。

たとえば、9Vの電池でLEDを点灯させるとする。 赤色LEDであれば、順方向電圧はおよそ1.8V程度になる。 電流を10mAに制限したいなら、およそ720Ωの抵抗器を直列に入れればよい。

分圧回路

分圧回路は、大きな電圧を小さな電圧に変換する抵抗器の回路である。 2本の抵抗器を直列につなぐだけで、入力電圧のある割合の出力電圧を作り出せる。

R1とR2という2つの抵抗器を直列につなぎ、その両端に電源電圧(Vin)を接続する。 VoutからGNDまでの電圧は、次の式で計算できる。

\[ V_{out} = V_{in} \times \frac{R_2}{R_1 + R_2} \]

たとえばR1が1.7kΩ、R2が3.3kΩであれば、5Vの入力電圧をVout端子で3.3Vに変換できる。

分圧回路は、フォトセルフレックスセンサー感圧抵抗(FSR)のような抵抗性のセンサーを読み取るのに非常に便利である。 分圧回路の一方をセンサーに、もう一方を固定の抵抗器にする。 2つの部品のあいだの出力電圧を、マイコン(MCU)のアナログ-デジタル変換器に接続して、センサーの値を読み取る。

プルアップ抵抗

プルアップ抵抗は、マイコンの入力ピンを既知の状態にバイアスしたいときに使われる。 抵抗器の一方の端はMCUのピンに、もう一方の端は高い電圧(たいてい5Vか3.3V)につながる。

プルアップ抵抗がないと、MCUの入力はフローティング状態のままになりうる。 フローティング状態のピンがハイ(5V)なのかロー(0V)なのかは、保証されない。

プルアップ抵抗は、ボタンやスイッチの入力を扱うときによく使われる。 スイッチが開いているときは、プルアップ抵抗が入力ピンをバイアスする。 そしてスイッチが閉じたときには、ショートから回路を守る役割も果たす。

上の回路では、スイッチが開いているとき、MCUの入力ピンは抵抗器を通して5Vにつながっている。 スイッチが閉じると、入力ピンは直接GNDにつながる。

プルアップ抵抗の値は、特に厳密に決める必要はない。 ただし、5V程度の電圧をかけたときに電力を無駄に消費しすぎない程度には高い値にしておくべきである。 たいてい10kΩ程度の値がよく使われる。

まとめ

抵抗器についての基礎が身についたところで、電子工作の他の基礎的な部品にも目を向けてみよう。 抵抗器だけがすべてではない。

抵抗器の応用をさらに知りたいなら、次のチュートリアルもおすすめである。

タグ: 部品、電気工学、技術


出典:Resistors(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

コンデンサ

コンデンサは、2端子の電子部品である。 抵抗器やインダクタと並んで、もっとも基本的な受動部品の1つであり、コンデンサがまったく使われていない回路を探すほうが難しいくらいである。

コンデンサを特別な存在にしているのは、エネルギーを蓄える能力である。 いわば、満充電の電池のようなものだ。 一般にキャパシタとも呼ばれるこの部品は、回路の中であらゆる重要な役割を担っており、局所的なエネルギーの蓄積、電圧スパイクの抑制、複雑な信号のフィルタリングなど、その用途は幅広い。

このチュートリアルで扱う内容:

  • コンデンサがどう作られているか
  • コンデンサがどう動作するか
  • 静電容量の単位
  • コンデンサの種類
  • コンデンサの見分け方
  • 静電容量が直列や並列でどう合成されるか
  • コンデンサのよくある応用例

参考になるチュートリアル:

記号と単位

回路図記号

コンデンサを回路図に描く方法には、一般的なものが2通りある。 コンデンサには常に2つの端子があり、そこから回路の残りの部分へとつながる。 コンデンサの記号は、平行な2本の線(まっすぐなものと、曲がったもの)で表され、どちらの記号でも2本の線は互いに平行で、近くにあるが接触してはいない(これは実際のコンデンサの構造をそのまま表している)。 言葉で説明するより、見たほうが早い。

曲線を使った記号(上の写真の2番目)は、そのコンデンサが極性を持つこと、つまりおそらく電解コンデンサであることを示している。 詳しくは、このチュートリアルの後半にある「コンデンサの種類」の節で説明する。

それぞれのコンデンサには、C1、C2のような名前と、値が添えられる。 この値は、そのコンデンサの静電容量、つまり何ファラドあるかを示す。 ファラドという単位について、もう少し詳しく見ていこう。

静電容量の単位

すべてのコンデンサが同じというわけではない。 それぞれのコンデンサは、決まった大きさの静電容量を持つように作られている。 コンデンサの静電容量は、どれだけの電荷を蓄えられるかを表す量であり、静電容量が大きいほど蓄えられる電荷の量も多くなる。 静電容量の標準単位はファラド(記号 F)と呼ばれる。

実は1ファラドというのは非常に大きな静電容量であり、0.001F(1ミリファラド、1mF)であっても十分に大きなコンデンサになる。 実際に使われるコンデンサの多くは、ピコファラド(10⁻¹²)からマイクロファラド(10⁻⁶)程度の範囲に収まる。

接頭辞の名前記号倍率ファラド換算
ピコファラドpF10⁻¹²0.000000000001 F
ナノファラドnF10⁻⁹0.000000001 F
マイクロファラドµF10⁻⁶0.000001 F
ミリファラドmF10⁻³0.001 F
キロファラドkF10³1000 F

ファラドからキロファラドの範囲に入ってくると、スーパーキャパシタやウルトラキャパシタと呼ばれる特殊なコンデンサの話になってくる。

コンデンサの理論

Note

ここで説明する内容は、電子工作を始めたばかりの人にとって必ずしも重要ではなく、後半になるほど話が少し込み入ってくる。 「コンデンサの作り方」の節はぜひ読んでほしいが、それ以外の節は、難しく感じたら読み飛ばしてもかまわない。

コンデンサの作り方

コンデンサの回路記号は、実際の構造をかなり忠実に表している。 コンデンサは、2枚の金属板と、誘電体と呼ばれる絶縁材料からできている。 2枚の金属板は互いにごく近い距離で平行に配置されるが、誘電体がそのあいだに挟まることで、金属板どうしが直接触れ合わないようになっている。

誘電体には、紙、ガラス、ゴム、セラミック、プラスチックなど、電流の流れを妨げるものであればさまざまな絶縁材料が使われる。

金属板には、アルミニウム、タンタル、銀といった導電性の材料が使われる。 それぞれの金属板は端子用の配線につながっており、最終的に回路の他の部分と接続される。

コンデンサの静電容量、つまり何ファラドあるかは、その構造によって決まる。 静電容量を大きくするには、より大きなコンデンサが必要になる。 金属板が重なり合う面積が大きいほど静電容量は大きくなり、金属板どうしの距離が離れるほど静電容量は小さくなる。 誘電体の材質も、コンデンサの静電容量に影響を与える。 コンデンサの静電容量は、次の式で計算できる。

\[ C = \varepsilon_r , \varepsilon_0 , \frac{A}{d} \]

ここで εr は誘電体の比誘電率(誘電体の材質によって決まる定数)、A は金属板が重なり合う面積、d は金属板どうしの距離である。

コンデンサの動作原理

電流とは電荷の流れであり、電子部品はこの電荷の流れを利用して光ったり回転したりと、それぞれの働きをしている。 電流がコンデンサに流れ込むと、その電荷は絶縁性の誘電体を通り抜けられないため、金属板の上に「取り残される」。 電子、つまり負の電荷を持つ粒子が一方の金属板に吸い寄せられ、その板全体が負に帯電する。 一方の板に集まった大量の負の電荷は、もう一方の板にある同じ負の電荷を押しのけ、その結果もう一方の板は正に帯電する。

それぞれの板の正負の電荷は、異符号どうしなので互いに引き合う。 しかし、あいだに誘電体が挟まっているため、どれだけ引き合いたくても、電荷は(他に行き場が見つかるまで)その板の上に永遠に留まり続ける。 これらの板の上で静止した電荷は電場を作り出し、それが電気的な位置エネルギー電圧に影響を与える。 このように電荷がコンデンサの上に集まると、電池が化学エネルギーを蓄えるのとちょうど同じように、コンデンサは電気エネルギーを蓄えていることになる。

充電と放電

正負の電荷がコンデンサの金属板の上にそれぞれ集まると、そのコンデンサは充電された状態になる。 コンデンサが電場を保持し、電荷を保ち続けられるのは、それぞれの板の正負の電荷が互いに引き合いながらも、決して触れ合うことがないからである。

やがて、コンデンサの金属板は電荷でいっぱいになり、それ以上受け入れられなくなる。 一方の板に集まった負の電荷が十分に多くなると、新たに加わろうとする負の電荷を押し返すようになる。 ここで関係してくるのが、コンデンサの静電容量(ファラド)であり、これがそのコンデンサに蓄えられる電荷の最大量を表している。

回路の中に、電荷どうしが互いに向かうための別の道筋ができると、電荷はコンデンサから出ていき、コンデンサは放電する。

たとえば下の回路では、電池を使ってコンデンサの両端に電位差を作り出せる。 これにより、それぞれの板に等しく符号の異なる電荷が蓄積していき、それ以上の電流の流入を押し返すほどいっぱいになる。 コンデンサに直列にLEDを配置すれば、電流の通り道ができ、コンデンサに蓄えられたエネルギーを使ってLEDを一瞬だけ点灯させられる。

電荷、電圧、電流の計算

コンデンサの静電容量、つまり何ファラドあるかを見れば、どれだけの電荷を蓄えられるかがわかる。 そのコンデンサが現在どれだけの電荷を蓄えているかは、板のあいだの電位差(電圧)によって決まる。 電荷、静電容量、電圧のこの関係は、次の式でモデル化できる。

\[ Q = C \times V \]

コンデンサに蓄えられる電荷(Q)は、その静電容量(C)と、かかっている電圧(V)の積である。

コンデンサの静電容量は、常に一定の既知の値であるはずのものである。 そのため、電圧を調整することで、コンデンサの電荷を増減できる。 電圧が高いほど電荷は多くなり、電圧が低いほど電荷は少なくなる。

この式は、1ファラドの定義を考えるうえでも役に立つ。 1ファラド(F)とは、1ボルトあたり1単位のエネルギー(クーロン)を蓄えられる容量のことである。

電流の計算

電荷、電圧、静電容量の式をもう一歩進めれば、静電容量と電圧が電流にどう影響するかもわかる。 なぜなら、電流とは電荷が流れる速さだからである。 コンデンサと電圧、電流の関係を要約すると次のようになる。 コンデンサを流れる電流の大きさは、静電容量と、電圧がどれだけ速く上下しているかの両方によって決まる。 コンデンサの両端の電圧が急激に上昇すると、大きな正の電流がコンデンサを流れる。 電圧の上昇がゆるやかであれば、コンデンサを流れる電流も小さくなる。 コンデンサの両端の電圧が一定で変化していなければ、電流はまったく流れない。

(ここから先は微分が絡んでくるやや込み入った話であり、時間領域の解析やフィルタ設計のような込み入った話に踏み込むまでは特に必要ないので、この式に抵抗があれば次の節まで読み飛ばしてかまわない。) コンデンサを流れる電流を計算する式は次のとおりである。

\[ i(t) = C , \frac{dV}{dt} \]

この式の dV/dt の部分は、電圧の時間に関する微分(もう少し噛み砕けば瞬間的な変化の速さ)であり、「まさに今この瞬間、電圧がどれだけ速く上下しているか」を表している。 この式からわかる重要な点は、電圧が一定であればその微分はゼロになり、つまり電流もゼロになるということである。 これが、一定の直流電圧がかかったコンデンサに電流が流れない理由である。

コンデンサの種類

コンデンサにはさまざまな種類があり、種類によって得意な用途と不得意な用途がある。

コンデンサの種類を選ぶときに考慮すべき要素がいくつかある。

  • 大きさ:物理的な体積と静電容量の両方の意味での大きさである。回路の中でコンデンサがもっとも大きな部品になることも珍しくない一方、非常に小さなものもある。一般に、静電容量が大きいほど、より大きなコンデンサが必要になる。
  • 最大電圧:それぞれのコンデンサには、かけられる電圧の上限が定められている。1.5V定格のものもあれば、100V定格のものもある。この上限を超えると、たいていコンデンサは壊れてしまう。
  • 漏れ電流:コンデンサは完璧な部品ではない。どのコンデンサも、誘電体を通してわずかな電流が一方の端子からもう一方へ漏れ出す性質を持っている。このわずかな電流の損失(たいていナノアンペア程度かそれ以下)を漏れ電流と呼ぶ。漏れ電流があると、コンデンサに蓄えられたエネルギーは少しずつ、しかし確実に失われていく。
  • 等価直列抵抗(ESR):コンデンサの端子は100%導電性というわけではなく、常にごくわずかな抵抗(たいてい0.01Ω未満)を持っている。この抵抗は、コンデンサに大きな電流が流れたときに熱や電力損失を生む原因になる。
  • 誤差(許容差):コンデンサも、正確に狙った静電容量ちょうどに作ることはできない。それぞれのコンデンサには公称の静電容量が定められているが、種類によっては実際の値が目的の値の±1%から±20%程度まで変動することがある。

セラミックコンデンサ

もっとも広く使われ、もっとも多く生産されているコンデンサがセラミックコンデンサである。 この名前は、誘電体に使われている材料に由来する。

セラミックコンデンサは、物理的な大きさも静電容量も小さいことが多い。 10µFを大きく超えるセラミックコンデンサを見つけるのは難しい。 表面実装型のセラミックコンデンサは、0402(0.4mm×0.2mm)、0603(0.6mm×0.3mm)、0805といった小さなパッケージでよく見られる。 スルーホール型のセラミックコンデンサは、たいてい小さな(黄色や赤色が多い)球根のような形をしていて、2本の端子が飛び出している。

同じくらい人気のある電解コンデンサと比べると、セラミックコンデンサはより理想的なコンデンサに近い(ESRも漏れ電流もずっと小さい)が、静電容量が小さい点が制約になる。 たいてい、もっとも安価な選択肢でもある。 高周波のカップリングやデカップリングの用途によく合う。

アルミニウム電解コンデンサとタンタル電解コンデンサ

電解コンデンサの優れた点は、比較的小さな体積に大量の静電容量を詰め込めることである。 1µFから1mF程度の静電容量が必要なら、たいていは電解コンデンサの形で見つかる。 最大電圧の定格が比較的高いため、高電圧の用途にも特に向いている。

電解コンデンサの中でもっとも一般的なアルミニウム電解コンデンサは、たいてい小さな缶のような外観をしていて、両方のリード線が底面から伸びている。

残念ながら、電解コンデンサはたいてい極性を持つ。 正極のピン(アノード)と、負極のピン(カソード)と呼ばれるピンがある。 電解コンデンサに電圧をかけるときは、アノードがカソードより高い電圧になっていなければならない。 電解コンデンサのカソードは、たいてい「-」の表示や、外装のカラーストライプで示されており、アノード側のリードがわずかに長くなっていることでも見分けられる。 電解コンデンサに逆向きの電圧をかけてしまうと、派手に(「ポン」という音とともに)破裂し、二度と使えなくなる。 一度破裂した電解コンデンサは、ショート回路のようにふるまうようになる。

電解コンデンサは漏れ電流でも知られている。 つまり、誘電体を通してわずかな電流(nAのオーダー)が一方の端子からもう一方へ流れてしまう。 そのため、大きな静電容量と高い電圧定格を持ちながらも、エネルギー貯蔵用としては理想的とは言えない側面がある。

スーパーキャパシタ

エネルギーを蓄えるためのコンデンサを探しているなら、スーパーキャパシタが最適である。 このコンデンサは、ファラド単位という非常に大きな静電容量を持つように特別に設計されている。

スーパーキャパシタは大量の電荷を蓄えられる一方で、高い電圧には対応できない。 たとえばこの10Fのスーパーキャパシタは、最大定格電圧がわずか2.5Vである。 これを超える電圧をかけると壊れてしまう。 スーパーキャパシタは、より高い電圧定格を得るために(その代わり合成静電容量は小さくなるが)直列に接続されることが多い。

スーパーキャパシタの主な用途は、電池と同じようにエネルギーを蓄えて放出することであり、電池はスーパーキャパシタにとって最大の競合相手でもある。 同じ体積の電池ほど多くのエネルギーは蓄えられないものの、スーパーキャパシタはずっと速くエネルギーを放出でき、寿命もたいてい電池よりずっと長い。

その他の種類

電解コンデンサとセラミックコンデンサだけで、世の中のコンデンサの種類のおよそ80%を占める(スーパーキャパシタはわずか2%程度だが、その名のとおりスーパーな存在である)。 もう1つよく使われる種類がフィルムコンデンサであり、寄生損失(ESR)が非常に小さいため、大電流を扱う用途に適している。

このほかにも、あまり一般的でないコンデンサが数多く存在する。 可変コンデンサは静電容量を変化させられるため、同調回路において可変抵抗の代わりに使うのに適している。 より合わせた電線やプリント基板も、それぞれ絶縁体を挟んだ2つの導体からなるため、(望まない形であることも多いが)静電容量を生み出すことがある。 ライデン瓶(導体で満たされ、導体に囲まれたガラス瓶)は、コンデンサ一族の元祖ともいえる存在である。 そして、フラックスキャパシタ(インダクタとコンデンサを組み合わせた奇妙な部品)は、いつか栄光の過去へ時間を遡ろうと計画しているなら欠かせない部品である。

コンデンサの直列接続と並列接続

抵抗器と同じように、複数のコンデンサを直列や並列に組み合わせて、合成静電容量を作り出せる。 ただし、コンデンサが合成される様子は、抵抗の場合とはまったく逆になる。

コンデンサの並列接続

コンデンサを互いに並列につなぐと、合成静電容量は単純にすべての静電容量の総和になる。 これは、抵抗を直列につないだときの合成の仕方に対応する。

たとえば10µF、1µF、0.1µFの3つのコンデンサを並列につなぐと、合成静電容量は11.1µF(10+1+0.1)になる。

コンデンサの直列接続

抵抗を並列に合成する計算が面倒なのと同じように、コンデンサを直列につなぐ場合も少し癖のある計算になる。 N個のコンデンサを直列につないだときの合成静電容量は、それぞれの静電容量の逆数の和の、さらに逆数になる。

\[ \frac{1}{C_{合成}} = \frac{1}{C_1} + \frac{1}{C_2} + \cdots + \frac{1}{C_N} \]

コンデンサが2個だけの場合は、「和分の積」の方法で合成静電容量を計算できる。

\[ C_{合成} = \frac{C_1 \times C_2}{C_1 + C_2} \]

さらに、同じ値のコンデンサが2個直列につながっている場合、合成静電容量はその値のちょうど半分になる。 たとえば10Fのスーパーキャパシタを2個直列につなぐと、合成静電容量は5Fになる(副次的な効果として、全体の耐圧が2.5Vから5Vへと倍増する)。

応用例

この気の利いた(実際には物理的にかなり大きいこともある)受動部品には、無数の応用例がある。 その用途の広さがわかるように、いくつか例を挙げる。

デカップリング(バイパス)コンデンサ

回路の中で見かけるコンデンサの多くは、特に集積回路を使った回路では、デカップリング用である。 デカップリングコンデンサの役割は、電源信号に含まれる高周波ノイズを抑えることである。 繊細なICにとって有害になりかねない小さな電圧のリップルを、電源電圧から取り除いてくれる。

いわば、デカップリングコンデンサはICのための非常に小さな、局所的な電源のような働きをする(パソコンにとっての無停電電源装置(UPS)に近い)。 電源電圧がごく一瞬だけ落ち込んだとき(回路の負荷が絶えず切り替わるような場合、これは実はよくあることである)、デカップリングコンデンサが一瞬だけ正しい電圧で電力を供給してくれる。 これが、この種のコンデンサがバイパスコンデンサとも呼ばれる理由であり、一時的に電源の役割を「肩代わり(バイパス)」してくれるからである。

デカップリングコンデンサは、電源(5Vや3.3Vなど)とグラウンドのあいだに接続する。 特定の周波数帯のノイズを取り除くのに向き不向きがあるため、値の異なる、あるいは種類の異なる複数のコンデンサを組み合わせて電源をバイパスするのも珍しくない。

電源からグラウンドへの短絡のように見えるかもしれないが、実際にはコンデンサを通ってグラウンドへ流れるのは高周波の信号だけである。 直流信号はそのままICへ向かう。 これらのコンデンサがバイパスコンデンサと呼ばれるもう1つの理由は、高周波(kHzからMHzの範囲)の信号がICを迂回(バイパス)し、代わりにコンデンサを通ってグラウンドへ抜けていくためである。

デカップリングコンデンサを物理的に配置するときは、できる限りICの近くに置くべきである。 ICから離れるほど、その効果は弱くなる。

良い設計の基本として、すべてのICには少なくとも1つのデカップリングコンデンサを添えるべきである。 たいていは0.1µFがよい選択であり、1µFや10µFのコンデンサをあわせて追加してもよい。 安価な部品であり、ICが大きな電圧の落ち込みやスパイクにさらされずに済むようにしてくれる。

電源のフィルタリング

ダイオードによる整流回路は、壁のコンセントから来る交流電圧を、ほとんどの電子機器が必要とする直流電圧に変換するのに使える。 しかし、ダイオードだけでは交流信号をきれいな直流信号に変えることはできず、コンデンサの助けが必要になる。 ブリッジ整流回路に並列コンデンサを追加すると、次のような整流された信号を、

次のような、ほぼ一定の直流信号に変えられる。

コンデンサは頑固な部品であり、電圧の急な変化に常に抵抗しようとする。 整流された電圧が上昇していくあいだ、このフィルタコンデンサは充電されていく。 整流電圧が急に下がり始めると、コンデンサは蓄えたエネルギーを取り崩し、非常にゆっくりと放電しながら負荷にエネルギーを供給する。 入力側の整流信号が再び上昇し始めてコンデンサが再充電されるまでに、コンデンサが完全に放電しきってしまうことはないようにする必要がある。 この駆け引きは、電源が使われている限り、1秒間に何度も繰り返される。

AC-DC電源アダプターを分解してみれば、必ずと言っていいほど比較的大きなコンデンサが少なくとも1つは見つかる。 下の写真は、9VのDC用ACアダプターの中身である。 コンデンサがいくつ見つかるだろうか。

思っていたより多くのコンデンサが見つかるかもしれない。 47µFから1000µFまでの、缶のような外観の電解コンデンサが4個ある。 手前にある大きな黄色い四角形は、高電圧用の0.1µFポリプロピレンフィルムコンデンサである。 青い円盤状のコンデンサと、中央の小さな緑色のコンデンサは、どちらもセラミックコンデンサである。

エネルギーの蓄積と供給

コンデンサがエネルギーを蓄えられるなら、電池と同じように、そのエネルギーを回路に供給する用途に使えるのは当然のことのように思える。 問題は、コンデンサのエネルギー密度が電池よりずっと低いことであり、同じ大きさの化学電池ほど多くのエネルギーを詰め込むことができない(もっとも、その差は年々縮まってきている)。

コンデンサの利点は、たいてい電池より長寿命であることであり、環境面でも優れた選択肢になりうる。 また、電池よりずっと速くエネルギーを放出できるため、短時間だけ大きな電力が必要な用途にも向いている。 カメラのフラッシュは、コンデンサから電力を得ていることが多い(そのコンデンサ自体は、電池によって充電されていることが多い)。

電池かコンデンサか

電池コンデンサ
容量
エネルギー密度
充放電の速さ
寿命

信号のフィルタリング

コンデンサは、周波数の異なる信号に対して独特の応答を示す。 低周波や直流の成分を遮断しながら、より高い周波数だけを通すことができる。 まるで、高周波の信号だけを通す、選り好みの激しいクラブの用心棒のような存在である。

信号のフィルタリングは、あらゆる信号処理の用途で役立つ。 ラジオの受信機では、(他の部品とあわせて)コンデンサを使って不要な周波数を取り除いていることがある。

コンデンサによる信号フィルタリングのもう1つの例が、スピーカー内部にある受動的なクロスオーバー回路であり、1つの音声信号を複数の帯域に分割する役割を持つ。 直列に入れたコンデンサは低周波を遮断し、残った高周波成分だけがスピーカーのツイーターへ送られる。 低周波を通すサブウーファー側の回路では、並列に入れたコンデンサを通して高周波の大部分がグラウンドへ逃がされる。

ディレーティング

コンデンサを扱うときは、システム内で起こりうる最大の電圧スパイクより、十分に高い耐圧を持つコンデンサを選んで設計することが重要である。

コンデンサの耐圧に十分な余裕(ディレーティング)を持たせずに定格電圧を超えてしまうと、コンデンサの種類ごとにどんなことが起きるかを紹介した、SparkFunのエンジニアによる実験動画もある。

まとめ

これで、コンデンサについての基礎知識がひととおり身についたはずである。 電子工作の基礎をさらに学びたいなら、他のよく使われる部品についても読んでみてほしい。

次のようなチュートリアルにも興味があるかもしれない。

タグ: 部品、電気工学、技術


出典:Capacitors(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

ダイオード

抵抗器コンデンサ、インダクタといった単純な受動部品を卒業したら、次は半導体という素晴らしい世界に踏み出す番である。 半導体部品の中でもっとも広く使われているものの1つがダイオードである。

このチュートリアルで扱う内容:

  • ダイオードとは何か
  • ダイオードが動作する仕組み
  • ダイオードの重要な特性
  • ダイオードのさまざまな種類
  • ダイオードの見た目
  • ダイオードの代表的な応用例

参考になるチュートリアル:

理想的なダイオード

理想的なダイオードの重要な働きは、電流が流れる向きを制御することである。 ダイオードを流れる電流は一方向、いわゆる順方向にしか流れない。 逆方向に流れようとする電流は遮断される。 いわば、電子回路における一方向弁のような部品である。

ダイオードにかかる電圧が負であれば電流は流れず、理想的なダイオードは開放回路のようにふるまう。 このとき、ダイオードはオフ、あるいは逆バイアスの状態にあるという。

ダイオードにかかる電圧が負でない限り、ダイオードは「オン」になって電流を通す。 理想的には、電流が流れているダイオードは短絡回路(両端の電圧が0V)のようにふるまう。 ダイオードに電流が流れているとき、それは順バイアスの状態にある(電子工学の用語で「オン」を意味する)。

理想的なダイオードの特性オン(順バイアス)オフ(逆バイアス)
流れる電流I>0I=0
かかる電圧V=0V<0
ダイオードの状態短絡回路開放回路

回路記号

すべてのダイオードには2つの端子(部品の両端の接続点)があり、その2つの端子は極性を持つ、つまり明確に異なる役割を持つ。 ダイオードの接続を間違えないことが重要である。 正極側の端子はアノード、負極側の端子はカソードと呼ばれる。 電流はアノード側からカソード側へは流れるが、その逆には流れない。 電流の向きを忘れてしまったときは、「ACID」(anode current in diode、「アノードから電流がダイオードに入る」)という語呂合わせを思い出すとよい。

標準的なダイオードの回路記号は、線に押し当てられた三角形である。 このチュートリアルの後半で扱うように、ダイオードにはさまざまな種類があるが、たいていの回路記号はこの形を基本としている。

三角形の平らな辺に入っている端子がアノードを表す。 電流は三角形(矢印)が指す方向にしか流れない。

上の例では、左側のダイオードD1は順バイアスがかかっており、回路に電流を流している。 これは実質的に短絡回路のように見える。 右側のダイオードD2は逆バイアスがかかっている。 この回路には電流が流れず、実質的に開放回路のように見える。

もちろん、理想的なダイオードというものは実際には存在しない。 しかし心配は無用で、現実のダイオードはこの理想モデルから少し外れた、いくつかの固有の特性を持っているだけである。

現実のダイオードの特性

理想的には、ダイオードは逆方向の電流をすべて遮断し、順方向であれば単なる短絡回路のようにふるまうはずである。 しかし残念ながら、実際のダイオードの動作はそこまで理想的ではない。 ダイオードは順方向に電流を流しているときにもいくらかの電力を消費し、逆方向の電流もすべてを遮断できるわけではない。 現実のダイオードはもう少し複雑で、それぞれが実際の動作を決める固有の特性を持っている。

電流電圧特性

もっとも重要なダイオードの特性は、その電流電圧(i-v)特性である。 これは、ある部品にかかる電圧に対して、そこを流れる電流がどうなるかを定義するものである。 たとえば抵抗器は、単純な線形の電流電圧特性(オームの法則)を持つ。 しかし、ダイオードのi-v曲線はまったくの非線形であり、次のような形になる。

かかる電圧に応じて、ダイオードは次の3つの領域のいずれかで動作する。

  1. 順バイアス:ダイオードにかかる電圧が正のとき、ダイオードは「オン」になり電流が流れる。有意な電流を流すには、電圧が順方向電圧(VF)を上回っている必要がある。
  2. 逆バイアス:ダイオードの「オフ」の状態であり、電圧がVFより低く、-VBRより高い範囲にある。この領域では電流の流れはほぼ遮断され、ダイオードはオフの状態にある。逆飽和電流と呼ばれる非常に小さな電流(nAのオーダー)だけは、逆方向に流れることができる。
  3. 降伏(ブレークダウン):ダイオードにかかる電圧が非常に大きな負の値になると、カソードからアノードへ向かって大きな電流が逆方向に流れられるようになる。

順方向電圧

順方向に「オン」になって電流を通すには、ダイオードに一定以上の正の電圧をかける必要がある。 ダイオードをオンにするのに必要な標準的な電圧を順方向電圧(VF)と呼ぶ。 「カットイン電圧」や「オン電圧」と呼ばれることもある。

i-v曲線からわかるように、ダイオードを流れる電流とかかる電圧は互いに依存し合っている。 電流が多いほど電圧も高く、電圧が低いほど電流も少ない。 ただし、電圧がおおよそ順方向電圧の定格に達すると、それ以降は電流が大きく増えても電圧の増加はごくわずかにとどまる。 ダイオードが十分に導通しているとき、かかっている電圧は順方向電圧の定格にほぼ等しいとみなしてよい。

ダイオードのVFの値は、使われている半導体材料によって決まる。 一般に、シリコン系のダイオードのVFはおよそ0.6〜1Vである。 ゲルマニウム系のダイオードはそれより低く、およそ0.3V程度になることが多い。 ダイオードの種類も順方向電圧降下に影響し、発光ダイオードはVFがかなり大きくなる一方、ショットキーダイオードは通常より低い順方向電圧になるよう特別に設計されている。

降伏電圧

十分に大きな負の電圧をダイオードにかけると、ダイオードは耐えきれずに逆方向へ電流を流し始める。 この大きな負の電圧を降伏電圧(ブレークダウン電圧)と呼ぶ。 降伏領域で動作するよう意図的に設計されたダイオードもあるが、一般的なダイオードにとって大きな負の電圧にさらされることはあまり好ましくない。

一般的なダイオードの降伏電圧は、およそ-50Vから-100V、あるいはそれ以上の負の値になることが多い。

ダイオードのデータシート

ここまでに挙げた特性は、すべてそれぞれのダイオードのデータシートに記載されている。 たとえば1N4148ダイオードのデータシートには、最大順方向電圧(1V)と降伏電圧(100V)が、他の多くの情報とあわせて記載されている。

データシートには、ダイオードの動作をさらに詳しく示すために、見慣れたi-vグラフが載っていることもある。 このグラフでは、i-v曲線の順方向領域のカーブした部分が拡大されている。 電流が多いほど、より高い電圧が必要になっている様子に注目してほしい。

このグラフからは、もう1つの重要なダイオードの特性、最大順方向電流も読み取れる。 どんな部品とも同じく、ダイオードにも耐えられる電力には限りがあり、それを超えると壊れてしまう。 すべてのダイオードには最大電流、逆電圧、消費電力の定格が記載されているはずである。 定格を超える電圧や電流にさらされたダイオードは、発熱したり、最悪の場合は溶けたり煙を上げたりすることになる。

1Aかそれ以上の大電流に適したダイオードもあれば、上で紹介した1N4148のような小信号ダイオードは200mA程度にしか対応していないこともある。

1N4148は、数あるダイオードのほんの一例にすぎない。 次は、実に多様なダイオードの種類と、それぞれの役割を見ていこう。

ダイオードの種類

標準的なダイオード

信号用ダイオード

標準的な信号用ダイオードは、ダイオードの中でももっとも基本的で、飾り気のない部類に入る。 たいてい中〜高程度の順方向電圧降下と、低めの最大電流定格を持つ。 信号用ダイオードの代表例が1N4148である。 非常に汎用性が高く、標準的な順方向電圧降下は0.72V、最大順方向電流は300mAである。

電力用ダイオード

整流ダイオード(電力用ダイオード)は、はるかに高い最大電流定格を持つ標準的なダイオードである。 この高い電流定格は、たいてい順方向電圧が大きくなることと引き換えになっている。 1N4001が電力用ダイオードの一例である。 1N4001の電流定格は1A、順方向電圧は1.1Vである。

もちろん、たいていのダイオードには表面実装型のバリエーションもある。 どのダイオードにも(どれほど小さく見づらくても)どちらのピンがカソードかを示す何らかの目印があることに気づくはずである。

発光ダイオード(LED)

ダイオード一族の中でもっとも華やかなのが、発光ダイオード(LED)である。 その名のとおり、正の電圧をかけると文字どおり光る。

通常のダイオードと同じく、LEDも一方向にしか電流を通さない。 LEDにも点灯に必要な順方向電圧の定格があり、その値は通常のダイオードより大きく(1.2〜3V程度)、発光する色によっても異なる。 たとえば超高輝度青色LEDの順方向電圧はおよそ3.3Vだが、同じサイズの超高輝度赤色LEDではわずか2.2Vである。

LEDは照明用途でよく見かけるものだが、それだけではない。 高効率であることから、街灯やディスプレイ、バックライトなど、幅広い用途で使われている。 赤外線LEDのように、人の目には見えない光を発するLEDもあり、これはほとんどのリモコンの心臓部となっている。 LEDのもう1つのよくある用途が、危険な高電圧系統を低電圧の回路から光学的に絶縁することである。 フォトカプラ(オプトアイソレータ)は、赤外線LEDとフォトセンサーを組み合わせた部品で、LEDからの光を検知すると電流が流れる仕組みになっている。 下は、フォトカプラを使った回路の例である。 LEDの回路記号が通常のダイオードとは異なり、記号から外側へ向かう矢印がいくつか追加されていることに注目してほしい。

ショットキーダイオード

もう1つよく使われるダイオードがショットキーダイオードである。 ショットキーダイオードの半導体構造は通常のダイオードと少し異なり、そのため順方向電圧降下がかなり小さく、たいてい0.15Vから0.45V程度になる。 それでいて、降伏電圧は通常どおり大きい。

ショットキーダイオードは、わずかな電圧損失も惜しいような場面で特に有用である。 独自の回路記号が与えられており、カソード側の線の両端が少し折れ曲がった形をしている。

ツェナーダイオード

ツェナーダイオードは、ダイオード一族の中でも少し変わった存在である。 意図的に逆方向電流を流すために使われることが多い。

ツェナーダイオードは、非常に精密な降伏電圧(ツェナー降伏電圧、あるいはツェナー電圧)を持つように設計されている。 ツェナーダイオードに十分な電流が逆方向に流れると、その両端の電圧降下はツェナー電圧のところで一定に保たれる。

この降伏特性を利用して、ツェナーダイオードはそのツェナー電圧ちょうどの、既知の基準電圧を作るためによく使われる。 小さな負荷に対する電圧レギュレータとして使うこともできるが、大きな電流を引く回路に対する電圧の安定化には向いていない。

ツェナーダイオードにも独自の回路記号があり、カソード側の線の両端が波打った形をしている。 記号自体に、そのダイオードのツェナー電圧の値が示されていることもある。 下は、3.3Vのツェナーダイオードを使って安定した3.3Vの基準電圧を作る回路の例である。

フォトダイオード

フォトダイオードは、光子(光の粒子)のエネルギーを捉えて電流を生み出すように特別に作られたダイオードであり、いわばLEDの逆の働きをする部品である。

太陽電池はフォトダイオードの技術をもっとも活用している存在だが、フォトダイオードは光の検出や、光を使った通信にも使われる。

ダイオードの応用例

これほど単純な部品でありながら、ダイオードの用途は非常に幅広い。 ほぼすべての回路に、何らかの形でダイオードが使われている。 小信号のデジタル論理回路から、高電圧の電力変換回路まで、その応用範囲は多岐にわたる。 ここでは、そうした応用例のいくつかを紹介する。

整流回路

整流回路は、交流(AC)を直流(DC)に変換する回路である。 この変換は、あらゆる家庭用電子機器にとって欠かせないものである。 壁のコンセントから来るのは交流信号だが、パソコンをはじめとする多くの電子機器を動かしているのは直流である。

交流回路の電流は文字どおり交互に、つまり正の方向と負の方向をすばやく切り替えながら流れるが、直流信号の電流は一方向にしか流れない。 そのため、交流を直流に変換するには、電流が負の方向に流れないようにするだけでよい。 これはまさに、ダイオードの出番である。

半波整流回路は、たった1本のダイオードで作れる。 正弦波のような交流信号をダイオードに通すと、信号の負の部分が切り取られる。

全波ブリッジ整流回路は、4本のダイオードを使って、交流信号の負の山を正の山に変換する。

こうした回路は、壁のコンセントの120/240VACの信号を3.3V、5V、12Vなどの直流信号に変換するAC-DC電源にとって欠かせない部品である。 ACアダプターを分解してみれば、たいてい中に何本かのダイオードが整流のために使われているのが見つかるはずである。

逆接保護

電池を逆向きに入れてしまったり、赤と黒の電源配線を入れ替えてしまったりしたことはないだろうか。 もしそれでも回路が無事だったなら、それはダイオードのおかげかもしれない。 電源の正極側に直列に入れたダイオードは、逆接保護ダイオードと呼ばれる。 これにより、電流は正の方向にしか流れず、電源が回路に加える電圧は常に正になる。

この応用は、電源コネクタに極性がなく、うっかり負極側を入力回路の正極側につないでしまいやすい場合に特に役立つ。

逆接保護ダイオードの欠点は、順方向電圧降下によっていくらかの電圧損失が生じることである。 そのため、ショットキーダイオードは逆接保護用のダイオードとして優れた選択肢になる。

論理ゲート

トランジスタを使わなくても、ANDやORのような単純なデジタル論理ゲートをダイオードだけで作ることができる。

たとえば、2入力のORゲートは、カソードを共有する2本のダイオードで作れる。 この論理回路の出力も、そのカソードの共有点から取り出す。 どちらか一方(あるいは両方)の入力が論理1(ハイ、5V)のとき、出力も論理1になる。 両方の入力が論理0(ロー、0V)のときは、出力は抵抗を通してローに引かれる。

ANDゲートも同様の考え方で作れる。 今度は2本のダイオードのアノードどうしをつなぎ、そこから回路の出力を取り出す。 両方の入力が論理1のときにだけ、電流が出力ピンへ向かって流れてそこをハイに引き上げる。 どちらかの入力がローのときは、5V電源からの電流がそのダイオードを通って流れてしまう。

どちらの論理ゲートも、ダイオードを1本追加するだけで入力を増やせる。

フライバックダイオードと電圧サージの抑制

ダイオードは、予期しない大きな電圧サージによる損傷を防ぐためにもよく使われる。 TVS(過渡電圧抑制)ダイオードは、ツェナーダイオードに似た比較的低い降伏電圧(たいてい20V前後)を持ちながら、非常に大きな電力定格(キロワット単位のこともある)を備えた特殊なダイオードである。 電圧が降伏電圧を超えたときに電流を逃がし、エネルギーを吸収するように設計されている。

フライバックダイオードも同じように電圧サージを抑える働きをするが、こちらはモーターのようなインダクタ性の部品によって引き起こされる電圧サージを対象にしている。 インダクタを流れる電流が急激に変化すると電圧サージが発生し、非常に大きな負のスパイクになることもある。 インダクタ性の負荷に並列にフライバックダイオードを入れておくと、その負の電圧信号を安全に逃がす経路ができ、インダクタとダイオードのあいだをぐるぐると循環しながら、やがて減衰していく。

これらは、この小さな半導体部品が持つ応用例のほんの一部にすぎない。

まとめ

これでダイオードについて理解できたところで、他の半導体部品にも目を向けてみてほしい。

他のよく使われる電子部品についても、ぜひ調べてみてほしい。

タグ: 部品、電気工学、技術


出典:Diodes(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

発光ダイオード(LED)

LEDは私たちの身の回りのいたるところにある。 スマートフォンにも、車にも、家庭の中にも使われている。 何か電子機器が光っているとき、その裏にはたいていLEDがいる。 LEDには実にさまざまな大きさ、形、色があるが、見た目がどうであれ共通点がひとつある。 どんなプロジェクトにも「加えるとうれしくなる」部品だということである。

まずは基本から押さえよう。 そもそもLEDとは何なのか。

LED(エルイーディー)は、電気エネルギーを光に変換する特殊な種類のダイオードである。 実際、LEDは「Light Emitting Diode(発光ダイオード)」の略であり、名は体を表している。 このことは、ダイオードとLEDの回路図記号がよく似ていることにも表れている。

つまり、LEDは小さな電球のようなものである。 ただし、点灯させるのに必要な電力は電球よりもはるかに少ない。 エネルギー効率も高いため、従来の電球のように熱くなることもあまりない(大電力を流した場合は別だが)。 そのため、モバイル機器のような低消費電力の用途に最適である。 とはいえ、高出力の世界でも侮れない。 高輝度LEDはアクセント照明やスポットライト、さらには自動車のヘッドライトにまで使われるようになっている。

参考になるチュートリアル:

LEDの使い方

LEDをあらゆるものに取り付けたくなってきただろうか。 そうなるだろうと思っていた。

ここでいくつかのルールを押さえておこう。

1. 極性が重要である

電子工学における極性とは、回路部品が対称かどうかを示すものである。 LEDはダイオードの一種であるため、電流を一方向にしか流さない。 そして電流が流れなければ、光も出ない。 幸い、これはLEDを逆向きに接続しても壊れないということでもある。 単に動作しないだけである。

LEDの正極側はアノードと呼ばれ、リード線(脚)が長いほうで見分けられる。 もう一方の負極側はカソードと呼ばれる。 電流はアノードからカソードへとしか流れない。 LEDが逆向きに取り付けられていると、電流の流れをせき止めてしまい、回路全体が正しく動作しなくなることがある。 LEDを追加したら回路が動かなくなっても慌てず、まずは向きを反転させてみよう。

2. 電流が多いほど、光も強くなる

LEDの明るさは、そこに流れる電流量に直接左右される。 これには2つの意味がある。 ひとつは、非常に明るいLEDほど電池を早く消耗させるということである。余分な明るさは余分な電力から生まれているからである。 もうひとつは、LEDに流れる電流量を調整することで、明るさをコントロールできるということである。 とはいえ、電流を抑える理由は雰囲気づくりだけではない。

3. 電力にも「かけすぎ」がある

LEDを電流源に直接つなぐと、許される限りの電力を消費しようとして、悲劇の主人公さながらに自らを破壊してしまう。 だからこそ、LEDに流れる電流量を制限することが重要になる。

そのために使うのが抵抗器である。 抵抗器は回路内の電子の流れを制限し、LEDが過大な電流を引き込もうとするのを防いでくれる。 心配は要らない。 最適な抵抗値を求めるには、ちょっとした基本的な計算をするだけでよい。 詳しくは抵抗器のチュートリアルの応用例の節を参照してほしい。

こうした計算に身構える必要はない。 実際には、そこまでひどく失敗することは難しい。 次のセクションでは、電卓を使わずにLED回路を組む方法を紹介する。

計算なしでLEDを使う

データシートの読み方を説明する前に、まずはLEDを実際につないでみよう。 これはLEDのチュートリアルであって、読解のチュートリアルではないのだから。

これは数学のチュートリアルでもないので、LEDを動かすための経験則をいくつか紹介する。 前のセクションの内容から察しがついているかもしれないが、必要なのは電池、抵抗器、LEDである。 電源には電池を使う。入手しやすく、危険なほど大きな電流を供給する心配もないからである。

LED回路の基本形は非常にシンプルで、電池、抵抗器、LEDを直列につなぐだけである。 次のようになる。

330Ω抵抗器

たいていのLEDには330Ω(橙、橙、茶)の抵抗器がちょうどよい値になる。 前のセクションの情報を使って正確な値を求めることもできるが、ここでは計算なしでLEDを扱う方法を紹介しているので、まずは上の回路に330Ωの抵抗器を差し込んで、何が起きるか見てみよう。

試行錯誤

抵抗器の興味深い性質は、余分な電力を熱として放出するということである。 そのため、抵抗器が温かくなっているようなら、もう少し小さい抵抗値に変えたほうがよいだろう。 逆に、抵抗値が小さすぎるとLEDを焼き切ってしまう危険がある。 手元にいくつかLEDと抵抗器を用意して試せる場合は、次のようなフローチャートに沿って試行錯誤しながら回路を設計するとよい。

コイン電池でのLED「スロウィー」

LEDを光らせるもうひとつの方法は、コイン電池に直接つなぐだけというものである。 コイン電池は、LEDを傷めるほどの電流を供給できないため、直接接続してしまってかまわない。 CR2032コイン電池をLEDのリード線の間に挟むだけでよい。 LEDの長いほうの脚が、電池の「+」と表示されている側に触れるようにする。 あとはテープを巻いて磁石を付ければ、どこにでも貼り付けられる「スロウィー」の完成である。

もちろん、試行錯誤の方法でうまくいかない場合は、電卓を取り出してきちんと計算することもできる。 心配はいらない。回路に最適な抵抗値を計算するのはそれほど難しくない。 ただし、最適な抵抗値を求める前に、まずはLEDにとって最適な電流値を知る必要がある。 そのためにデータシートを見てみよう。

データシートを読み解く

見慣れないLEDをいきなり回路につなぐのは、あまり健全なことではない。 まずはそのLEDのことをよく知ろう。 そのための一番の方法が、データシートを読むことである。

例として、Basic Red 5mm LEDのデータシートを見てみよう。

LEDの電流

表の上から順に見ていくと、まず次のような表に出会う。

これは何を意味しているのだろうか。

表の1行目は、そのLEDが連続的に許容できる電流の大きさを示している。 この場合、20mA以下であれば安全に使え、20mAでもっとも明るく点灯する。 2行目は、短時間だけ流してよい最大のピーク電流を示している。 このLEDは短時間であれば30mAまでの急な電流上昇に耐えられるが、その電流を長く維持するのは避けたほうがよい。 このデータシートには、上から3行目に16〜18mAという安定した動作電流の範囲まで書かれており、これが抵抗値を計算する際の目標値としてちょうどよい。

その下の数行は、このチュートリアルの目的にとってはそれほど重要ではない。 逆電圧はダイオードの特性のひとつで、たいていの場合気にする必要はない。 消費電力は、LEDが損傷を受けずに使えるミリワット単位の電力量を示している。 LEDを推奨される電圧と電流の範囲内で使っている限り、この点は自然とクリアできるはずである。

LEDの電圧

他にどんな表があるか見てみよう。

これは便利な表である。 1行目は、LEDにかかる順方向電圧降下を示している。 「順方向電圧」という言葉は、LEDを扱う際に頻繁に登場する。 この数値を見れば、回路がLEDに供給すべき電圧の大きさが分かる。 1つの電源に複数のLEDを接続する場合、この数値は特に重要である。 すべてのLEDの順方向電圧を合計した値が、供給電圧を超えることはできないからである。 この点については、このチュートリアルの後半でさらに詳しく扱う。

LEDの波長

この表の2行目には、光の波長が示されている。 波長とは、光の色を非常に厳密に表現する方法だと考えればよい。 この数値には多少のばらつきがあるため、表には最小値と最大値が示されている。 このLEDの場合は620〜625nmであり、赤色のスペクトル(620〜750nm)の中でも下限に近い波長である。 波長についても、このチュートリアルの後半でさらに詳しく取り上げる。

LEDの明るさ

表の最後の行(「光度」とラベル付けされている)は、そのLEDがどれだけ明るく光れるかを示す指標である。 単位のmcd、つまりミリカンデラは、光源の強さを測るための標準的な単位である。 このLEDの最大光度は200mcdであり、これは人の目を引くには十分だが、懐中電灯ほどの明るさではないという程度である。 200mcdであれば、インジケーターとして使うのにちょうどよい。

配光角

次に登場するのは、LEDの配光角を表す扇形のグラフである。 LEDのスタイルによって、レンズや反射板を使って光を一点に集中させたり、逆に広範囲に拡散させたりする設計になっている。 あらゆる方向に光子を放つ投光器のようなLEDもあれば、真正面から見ないと光っているかどうか分からないほど指向性の強いLEDもある。 このグラフを読むには、グラフの真下にLEDが直立していると想像するとよい。 グラフの「放射状の線」は配光角を表し、円形の線は最大強度に対する割合(パーセント)で強度を表している。 このLEDは配光角がかなり狭い。 LEDを真上(真下)から見たときにもっとも明るいことが、0度の位置で青い線が一番外側の円と交わっていることから分かる。 光の強さが半分になる角度、つまり50%配光角を求めるには、グラフ上で50%の円をたどっていき、青い線と交わったところから、一番近い放射状の線をたどって角度を読み取る。 このLEDの場合、50%配光角はおよそ20度である。

寸法

最後に、機構図がある。 この図には、LEDを実際に筐体に取り付けるために必要な寸法がすべて記載されている。 たいていのLEDと同じく、このLEDにも底部に小さなフランジ(つば)が付いていることに注目してほしい。 これはパネルに取り付けるときに役立つ。 LED本体にぴったり合う大きさの穴をあけておけば、フランジが引っかかってLEDが落ちるのを防いでくれる。

データシートの読み方が分かったところで、世の中にはどんな種類のLEDがあるのか見ていこう。

LEDの種類

おめでとう、これで基本は身についたはずである。 すでにいくつかLEDを手に入れて、あちこち光らせ始めているかもしれない。 それは素晴らしいことである。 それでは、標準的なLED以外の、もう少し凝ったLEDについても紹介しよう。

RGB LED

RGB(赤、緑、青)LEDは、実は3つのLEDが1つにまとまったものである。 とはいえ、3色しか作れないというわけではない。 赤、緑、青は加法混色の三原色であるため、それぞれの強度を調整することで、虹のあらゆる色を作り出せる。 たいていのRGB LEDには4本のピンがあり、それぞれの色に1本ずつと、共通ピンが1本ある。 製品によっては共通ピンがアノードのものもあれば、カソードのものもある。

集積回路内蔵LED

サイクリングLED

LEDの中には、他よりも「賢い」ものもある。 たとえばサイクリングLEDがそうである。 このLEDの内部には実際に集積回路が組み込まれており、外部の制御回路なしにLED自身が点滅できるようになっている。 これをただ電源につなぐだけで、あとは自動的に動作してくれる。 外部の制御回路を組み込むスペースがないものの、もう少し動きのある演出をしたいプロジェクトに最適である。 何千もの色を巡回するRGBの点滅LEDまである。

アドレサブルLED

個別に制御できるタイプのLEDもある。 数珠つなぎにした個々のLEDを制御するために、さまざまなチップセット(WS2812、APA102、UCS1903など)が使われている。

抵抗内蔵LED

抵抗が内蔵されたLEDというものも存在する。 これらのLEDには、電流を制限するための小さな抵抗が組み込まれている。 電源に直接つなぐだけで点灯させることができ、3.3V、5V、9Vでの動作が確認されている。

Note

抵抗内蔵LEDのデータシートによれば、推奨される順方向電圧はおよそ5Vである。 5Vでテストすると約18mAが流れる。 9V電池での負荷テストでは約30mAが流れ、これは入力電圧としてはかなり高めの範囲にあたる。 電圧を高くしすぎるとLEDの寿命が縮まる。 およそ16Vの負荷テストでは、このLEDは焼き切れてしまった。

表面実装(SMD)パッケージ

SMD LEDは、特定の種類のLEDというよりはパッケージの形式である。 電子機器がどんどん小型化する中で、メーカーはより小さな空間により多くの部品を詰め込む方法を編み出してきた。 SMD(表面実装部品)は、標準タイプの部品を小型化したものである。 SMD LEDにはさまざまなサイズがあり、かなり大きなものから、米粒より小さなものまである。 非常に小さく、脚ではなくパッドを持つため標準タイプほど扱いやすくはないが、スペースに余裕がない場合には最適な選択肢になりうる。

SMD LEDはまた、ピックアンドプレース装置を使って大量のLEDをPCBやテープにすばやく実装するのにも向いている。 これらすべての部品を手作業ではんだ付けするのは、あまり現実的ではないだろう。

高出力LED

LuxeonやCREEといったメーカーの高出力LEDは、桁違いに明るい。 一般に、1ワット以上の電力を消費できるLEDは高出力LEDと見なされる。 これらは、高性能な懐中電灯によく使われる高級なLEDである。 これらを並べた配列は、スポットライトや自動車のヘッドライトにも使われる。 これほど大きな電力が流れるため、放熱板が必要になることが多い。 放熱板とは、表面積の大きな熱伝導性の金属の塊であり、余分な熱をできるだけ多く周囲の空気に逃がす役割を持つ。

高出力LEDは、適切に冷却しないと自らを傷めてしまうほどの熱を発生させることがある。 「余分な熱」という言葉に惑わされないでほしい。 それでも、これらの部品は従来の電球に比べればはるかに効率がよい。 制御には、定電流LEDドライバーを使うとよい。

特殊なLED

可視光の範囲外の光を放つLEDも存在する。 たとえば赤外線LEDは、日常的に使っているものが多いはずである。 テレビのリモコンなどで、目に見えない光の形で小さな情報を送るのに使われている。 これらは標準的なLEDと見た目がよく似ているため、区別が難しいこともある。

一方で、スペクトルの反対側には紫外線LEDもある。 紫外線LEDは、ブラックライトのように特定の素材を蛍光させる。 多くの細菌が紫外線に弱いため、表面の消毒にも使われている。 偽造防止(紙幣、クレジットカード、書類など)や日焼けなど、用途は多岐にわたる。 これらのLEDを使うときは、必ず保護メガネを着用すること。

これだけ凝ったLEDが手元にあれば、あらゆるものを光らせない理由はない。 とはいえ、LEDについての知識欲がまだ満たされないなら、続きを読んでほしい。 LED、色、光度についてさらに掘り下げていく。

さらに深く

LED入門を卒業して、もっと知りたくなっただろうか。 心配は要らない、まだまだ話すことがある。 LEDを動かしている(あるいは点滅させている)科学的な仕組みから見ていこう。 LEDが特殊な種類のダイオードであることはすでに触れたが、それが具体的に何を意味するのかをもう少し掘り下げてみよう。

私たちが「LED」と呼んでいるものは、実際にはLED本体とパッケージを合わせたものだが、LED本体そのものは実はとても小さい。 それは不純物をドープした半導体材料のチップであり、電荷キャリアのための境界(pn接合)を作り出している。 電流が半導体に流れ込むと、電子はこの境界の片側からもう一方へと飛び移り、その過程でエネルギーを放出する。 たいていのダイオードでは、このエネルギーは熱として失われるが、LEDではこのエネルギーが光として放出される。

光の波長、つまり色は、そのダイオードを作る半導体材料の種類によって決まる。 これは、半導体のエネルギーバンド構造が材料ごとに異なり、その結果、放出される光子の周波数も異なってくるためである。

光度を放出する強さは、半導体のバンドギャップに依存する波長とは異なり、ダイオードに流れる電力の大きさに依存する。 光度についてはすでに前のセクションで少し触れたが、単に明るさに数値を付けるだけでは語り尽くせない話がある。

光度を測る単位はカンデラと呼ばれるが、1個のLEDの明るさについて話すときは、たいていミリカンデラの範囲になる。 この単位の興味深い点は、それが単純な光のエネルギー量の測定ではなく、実際の「明るさ」そのものを測る指標だということである。 これは、特定の方向に放出される電力を、その光の視感度関数によって重み付けすることで求められる。 人間の目はある波長の光には敏感で、別の波長にはそれほど敏感ではないが、視感度関数はその感度の違いを考慮した標準化されたモデルである。

LEDの光度は、数十ミリカンデラから数万ミリカンデラまで幅広い。 テレビの電源ランプはおよそ100mcd程度であるのに対し、性能のよい懐中電灯は20,000mcdにも達することがある。 数千ミリカンデラを超える明るさのものを直視するのは目を痛める可能性があるため、試さないほうがよい。

順方向電圧降下

先ほど、順方向電圧降下という概念についても説明すると約束していた。 データシートを見ていたときに、回路内のすべてのLEDの順方向電圧を合計した値がシステム電圧を超えることはできないと述べたのを覚えているだろうか。 これは、回路内のすべての部品が電圧を「分け合わなければならない」ためであり、それぞれの部品が使う電圧の合計は、常に利用可能な電圧の総量と等しくなる。 これはキルヒホッフの電圧則と呼ばれる。 そのため、5Vの電源があり、それぞれのLEDの順方向電圧降下が2.4Vだとすると、同時に点灯できるLEDは2個までということになる。

キルヒホッフの法則は、他の部品の順方向電圧から、ある部品にかかる電圧を概算したいときにも役立つ。 たとえば先ほどの例で、5Vの電源に2個のLED(それぞれ順方向電圧降下2.4V)を接続する場合を考えてみよう。 もちろん電流制限用の抵抗器も回路に含めたいところである。 その抵抗器にかかる電圧はどう求めればよいだろうか。 これは簡単である。

5(システム電圧) = 2.4(LED1) + 2.4(LED2) + 抵抗器
5 = 4.8 + 抵抗器
抵抗器 = 5 - 4.8
抵抗器 = 0.2

つまり、抵抗器には0.2Vがかかっていることになる。 これは単純化した例であり、実際にはいつもこれほど簡単というわけではないが、順方向電圧降下がなぜ重要なのかがイメージできたはずである。 キルヒホッフの法則から求めた電圧の値を使えば、オームの法則を使ってある部品に流れる電流を求めることもできる。 要するに、システム電圧は、回路内のすべての部品の順方向電圧の合計とちょうど等しくなるようにしたいということである。

電流制限抵抗の計算

LEDに直列に入れる電流制限抵抗の正確な値を計算したい場合は、抵抗器のチュートリアルの応用例を参照してほしい。 より詳しい情報が載っている。

まとめ

これでLEDについて、ほとんどすべてと言えるほどのことを学んだはずである。 さあ、思う存分あらゆるものにLEDを取り付けてみよう。

LEDに関連する話題についてさらに学びたいなら、次のチュートリアルもおすすめである。

  • :光は電気工学者にとって役立つ道具である。光と電子工学の関係を理解することは、多くのプロジェクトにとって基本的なスキルである。
  • 赤外線通信:一般的な赤外線(IR)通信の仕組みと、Arduinoを使った簡単な赤外線送受信機の作り方を解説する。
  • LEDはどうやって作られるのか:LEDメーカーを訪ね、SparkFunのために作られているPTH 5mm LEDがどのように製造されているかを紹介する。

タグ: 部品、電気工学、LED、光、技術


出典:Light-Emitting Diodes (LEDs)(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

LEDはどうやって作られるのか

2014年に中国を訪れた際、部品の供給元であるYunSunが親切にも深圳まで迎えに来てくれて、工場を案内してくれた。

YunSun LED

SparkFunは10年以上にわたってLEDを使い、販売してきたが、それがどのように作られているのか、実際に見たことも、きちんと理解したこともなかった。 そこでYunSunの主な窓口であるMerry Xiaoに、ぜひ学びたいと伝えたところ、工場が休みになる土曜日にわざわざ見学の機会を設けてくれた。 本当にありがたいことである。

写真に写っているのは、YunSunのオーナーであるMr. Siである。 彼は非常にユーモアのある人物で、写っているのは筆者の妻Alicia Gibbが取り組んでいたプロジェクトを手に持っているところである。 Merryも同行し、通訳を務めてくれた。

基本的な部品

これはLEDダイ(半導体チップ)が並んだシートである。 YunSunは、品質の高い台湾企業からこのダイを仕入れている。 写真の親指の隣にあるのは、4,000個のダイである。 このシート1枚のコストはおよそ80元、日本円にして約200円程度である。

それぞれのシートの角には、そのバッチの特性が記載されている。 この特定のシートに載っているダイは波長がおよそ519nmで、緑色と青緑色のちょうど境目にあたる。 薄いシート3枚で、合計12,000個のLEDがこれから作られようとしている。

工程は、打ち抜き加工されたリードフレームから始まる。 1枚のフレームには、LED20個分の基本構造が含まれている。 上の写真にはおよそ15枚のフレーム、つまり300個分のLEDが写っている。

機械

最初の機械は、リードフレームを受け取り、カソード端子の上部にあるカップそれぞれに、少量の接着剤を塗布する。

紙のシートに載って出荷されたままの状態では、LEDダイは互いに近すぎて扱うことができない。 そこで、ダイを広げて弱い粘着性を持つフィルムに貼り付ける専用の機械(写真には写っていない)が使われる。 このフィルムはリードフレームの上に吊るされ、上の写真のような状態になる。 作業者は顕微鏡を使ってダイの位置を手作業で合わせ、ピンセットでダイをリードフレームへと押し込む。 リードフレーム側の接着剤のほうが強いため、ダイはそちらに移り、作業者はすぐに次のダイへと進む。 1分間に80個以上、1日あたりおよそ40,000個を位置合わせできるという。

これはLEDのワイヤーボンディング機械である。 LEDダイの上部からアノードのリードへ向けて、髪の毛ほどの太さの金線を接続する。

この見学でまず驚かされたことの1つは、作業全体が屋外と変わらない環境で行われていたことである。 シリコンダイの取り扱いにはクリーンルーム技術が必要だと思い込んでいたが、これなら自宅の地下室でもできそうなくらいであった。

以下は、ワイヤーボンディング機械が実際に動作している様子を撮影した動画である。

LED Wire Bonding Machine(LEDワイヤーボンディング機械)

この機械はセットアップにかなりの調整と手間がかかったそうだが、いったん稼働し始めると、コンピュータによる位置合わせなしで自動的に動作する様子は見事であった。

ボンディングされるリードは1本だけであるため、カソード側の接着剤には導電性があるのだろう。 この接着剤は次の工程に進む前に、およそ30分かけて硬化する。

ここでもう1つ意外だったことがある。 これは7セグメントディスプレイである。 てっきり、セグメントの裏側にはそれぞれ通常サイズ(3mm程度)のLEDが入っているものと思い込んでいたが、実際には基板に直接ダイが取り付けられている7セグメント用の基板を見るまで、それが誤りだとは気づかなかった。

7セグメント用ボンディング機械を大きく撮影した写真。

成形と検査

スルーホール型LEDの工程に話を戻すと、ワイヤーボンディングが完了し、接着剤が硬化したあと、リードフレームはLED用の金型にセットされ、周囲にエポキシ樹脂が注入される。

LEDの形を決めているのは、まさにこの金型である。 これも「なるほど」と思わされた瞬間だった。 これまでさまざまな形のLEDを見てきたが、それらはいつもある程度決まった寸法の範囲に収まっていた。 たとえば5mmタイプのLEDで、星形の頭を持つものをあまり見かけないのには理由がある。

  1. 金型は、射出成形と同じように、LEDの頭の部分を型から外せなければならない。オーバーハング(庇状の出っ張り)を持つ形状は、型に引っかかって外れなくなってしまう。では2分割の金型ではどうかというと、それは次の理由につながる。
  2. LED業界全体が、専門特化した小規模なサプライヤーの集まりによって成り立っている。つまり、シリコンの製造だけを行う会社、リードの製造だけを行う会社、金型の製造だけを行う会社、といった具合に分業されている。工程全体を1社で担っている企業はほとんど存在しないため、YunSunも各サプライヤーが用意している選択肢の中から選ばざるを得ない。筆者らはYunSunに超カスタムで格好いいLEDを作ってほしいと非常に意気込んでいたが、それはほぼ不可能に近い。YunSunだけでなく、変わったサイズのリードフレームやカスタムサイズの金型を用意し、機械のリード間隔を調整し、新しい検査治具と作業手順を作るよう、さらに5社ほどのサプライヤーを説得しなければならないからである。不可能ではないが、想像していたよりもはるかに難しいことだと分かった。

これは、ある金型メーカーのカタログで、実にさまざまな形やサイズが掲載されている。 繰り返しになるが、カスタム形状が不可能というわけではないものの、カタログに載っていない形の場合は、実現がはるかに難しくなる。

エポキシ樹脂を注入したあと、LEDは45分間焼成されるという。 この時点でLEDを金型から取り出せるようになる。 その後さらに8〜12時間焼成し、エポキシを完全に硬化させる。 硬化を終えたLEDは、上の写真のように大きなバッチにまとめられる。

製造工程を支えるため、リードフレームにはアノードとカソードをつなぐ金属片が残されている。 検査の前に、上の写真の機械がこの余分な金属を切り離し、カソードを個別に独立させ、すべてのアノードをまとめてつなげる。 LEDの片方の脚がもう片方より短いのはなぜだろうか。 それは主に、製造工程の自動化や検査をしやすくするためである。 なぜカソード側が短く選ばれたのかといえば、検査の際にロー側(カソード側)を制御するほうが簡単だからだと考えられる。

次の工程では、それぞれのLEDが適切な電流値で動作しているかどうかを検査し、確認する。 電流が少なすぎる場合(断線がある場合)や多すぎる場合(短絡がある場合)は、そのLEDは取り除かれる。 この機械は、一連のポゴピンを使ってそれぞれのLEDを個別かつ高速に検査し、結果をコンピュータの画面に表示する。 これは、SparkFunの製品検査のために設計しているポゴピン式の検査治具と非常によく似ている。

品質検査(QC)に合格したLEDは、さらに別の切断工程を経て、アノードがリードフレームから切り離される。

SparkFunのために作られた、大量の5mm赤色LEDである。

同じ工程を使って、さまざまな形、色、サイズのLEDを作ることができる。

工場全体の様子

全体として、工場はコンパクトで整然としたレイアウトになっていた。 その日必要とされる形やタイプに応じて使い分けられる、4本のラインが用意されていた。

Merry、Alicia、筆者、そしてMr. Siである。 休みの日にもかかわらず工場を案内してくれたYunSunには、心から感謝している。 もしLEDやLED電球が必要になったら、ぜひMerry(merry あっと 100led.com)に連絡してみてほしい。 YunSunは、一緒に仕事をするうえで本当に素晴らしい会社である。

まとめ

ここまで読んでいただき、ありがとうございました。 このようなチュートリアルの制作には多くの手間がかかっているので、何か学びがあったなら幸いである。

LEDで遊んでみたくなった方には、次のような製品もおすすめである。

LEDがどうやって作られているかを読んだところで、次のようなチュートリアルにも興味が湧くかもしれない。

タグ: 記事、LED


出典:How LEDs are Made(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

トランジスタ

トランジスタは、現代の電子回路の世界を動かしている部品である。 ほぼすべての現代的な回路において、制御の要となる重要な部品である。 目にする機会もあるが、たいていは集積回路のダイの奥深くに隠れている。 このチュートリアルでは、もっとも一般的なトランジスタであるバイポーラ接合トランジスタ(BJT)の基礎を紹介する。

個別部品として少数使う場合、トランジスタは単純な電子スイッチや、デジタル論理回路、信号増幅回路を作るのに使われる。 数千、数百万、数十億という単位で使う場合には、トランジスタどうしが接続され、小さなチップに埋め込まれて、コンピュータのメモリやマイクロプロセッサ、その他の複雑なICを構成する。

このチュートリアルを読み終えるころには、トランジスタがどう動作するかについて幅広い理解が得られるはずである。 半導体物理や等価回路モデルにまで深入りはしないが、トランジスタがスイッチとしても増幅器としても使えることを理解できる程度には掘り下げていく。

トランジスタには大きく分けて2種類ある。バイポーラ接合型(BJT)と金属酸化膜電界効果型(MOSFET)である。 このチュートリアルでは、理解しやすいBJTに焦点を当てる。 さらに、BJTにもNPNPNPという2つのバージョンがある。 まずは的を絞り、NPNについてしっかり理解することに集中する。 NPNをきちんと理解できれば、そこからの違いを比較することで、PNP(さらにはMOSFET)の理解もぐっと楽になる。

参考になるチュートリアル:

  • 電圧、電流、抵抗とオームの法則 電子工学の基礎を紹介している。
  • 電気の基礎 電気を電子の流れとして説明している。
  • 電力 トランジスタの主な用途の1つが増幅、つまり信号の電力を大きくすることであり、その仕組みを説明している。
  • ダイオード トランジスタもダイオードと同じ半導体部品であり、いわば2本のダイオードのアノードどうしを結びつけたようなものである。ダイオードの動作原理を理解しておくと、トランジスタの動作を理解するうえで大いに役立つ。

記号、ピン、内部構造

トランジスタは基本的に3端子の部品である。 バイポーラ接合トランジスタ(BJT)では、それぞれのピンをコレクタ(C)、ベース(B)、エミッタ(E)と呼ぶ。 NPN型とPNP型、それぞれの回路記号を以下に示す。

NPNとPNPの違いは、エミッタに付いている矢印の向きだけである。 NPNでは矢印が外を向き、PNPでは内を向く。 覚え方として、「NPN: Not Pointing iN(内を向いていない)」という語呂合わせがある。 少しひねくれた理屈だが、実際に役に立つ。

トランジスタの内部構造

トランジスタは半導体を使ってその働きを実現している。 半導体とは、銅線のような純粋な導体でもなく、空気のような絶縁体でもない、その中間的な性質を持つ材料である。 半導体の導電性、つまり電子をどれだけ流しやすいかは、温度や電子の過不足といった要因によって変化する。 ここで、トランジスタの内部を少しだけのぞいてみよう。 量子物理学の深い話にまでは立ち入らないので安心してほしい。

2つのダイオードとしてのトランジスタ

トランジスタは、いわば別の半導体部品であるダイオードを拡張したようなものである。 ある意味で、トランジスタは2本のダイオードのカソード(あるいはアノード)どうしを結びつけたものだと考えられる。

ここで重要なのは、ベースとエミッタをつなぐダイオードのほうである。 これは回路記号の矢印の向きと一致しており、トランジスタの中を電流がどちらに流れるように意図されているかを示している。

このダイオードによる表現は理解の出発点としては悪くないが、正確さにはほど遠い。 この模型だけをもとにトランジスタの動作を理解しようとしてはいけない(そしてもちろん、これをそのままブレッドボードで再現しようとしても動かない)。 3つの端子のあいだの相互作用を支配しているのは、もっと不思議な量子物理学レベルの現象である。

(ただし、この模型はトランジスタをテストしたいときには実際に役立つ。テスターのダイオード(または抵抗)測定モードを使って、BE間とBC間を測れば、この「ダイオード」が実際に存在するかどうかを確認できる。)

トランジスタの構造と動作

トランジスタは、3種類の異なる半導体材料の層を積み重ねて作られている。 これらの層の一部には電子が余分に加えられており(「ドーピング」と呼ばれる処理である)、別の層は電子が取り除かれている(「ホール」、つまり電子の欠如がドープされている)。 電子が余分にある半導体材料はn型(電子が負の電荷を持つことからnegativeのn)、電子が取り除かれた材料はp型positiveのp)と呼ばれる。 トランジスタは、nの上にp、その上にまたnを重ねるか、あるいはpの上にn、その上にまたpを重ねることで作られる。

多少大まかに言えば、電子はn領域からp領域へは、わずかな力(電圧)さえあれば簡単に流れるが、p領域からn領域へ流れるのは非常に難しく(大きな電圧が必要になる)。 しかしトランジスタの特別なところ、つまり先ほどの2ダイオードモデルを時代遅れにしてしまう性質は、ベース-エミッタ接合が順バイアスになっている限り(つまりベースがエミッタより高い電圧になっている限り)、p型のベースからn型のコレクタへも電子が簡単に流れられるという点である。

NPNトランジスタは、エミッタからコレクタへ電子を通すように設計されている(そのため慣用電流はコレクタからエミッタへ流れる)。 エミッタは電子をベースへ「放出(emit)」し、ベースはエミッタが放出する電子の量を制御する。 放出された電子のほとんどはコレクタに「集められ(collect)」、回路の次の部分へ送られる。

PNPも同じ考え方で、向きだけが逆に動作する。 ベースが電流を制御する点は同じだが、電流の向きが逆、つまりエミッタからコレクタへ流れる。 電子の代わりに、エミッタは「ホール」(電子が欠けている状態という概念上の存在)を放出し、それをコレクタが集める。

トランジスタは、いわば電子のバルブ(弁)のようなものである。 ベースのピンは、エミッタからコレクタへ流れる電子の量を調整するための取っ手のようなものだと考えられる。 このたとえをもう少し掘り下げてみよう。

水のたとえをさらに広げる

電気の概念に関するチュートリアルを読み進めてきたなら、のたとえにはすっかり慣れているだろう。 電流は水の流量に、電圧はその水をパイプに押し通す圧力に、抵抗はパイプの太さに相当する、というものである。

当然ながら、この水のたとえはトランジスタにも応用できる。 トランジスタは水のバルブ、つまり流量を制御するための仕組みのようなものである。

バルブには3つの状態があり、それぞれがシステムの流量に異なる影響を与える。

1)オン(短絡回路)

バルブを完全に開くと、水は自由に流れ、まるでバルブがそこに存在しないかのように通り抜ける。

同じように、適切な条件のもとでは、トランジスタはコレクタとエミッタのあいだが短絡回路であるかのようにふるまう。 電流はコレクタから自由に流れ込み、エミッタから出ていく。

2)オフ(開放回路)

バルブを閉じると、水の流れを完全に止めることができる。

同じように、トランジスタはコレクタとエミッタのあいだに開放回路を作り出せる。

3)線形の流量制御

バルブを精密に調整すれば、全開と全閉のあいだの任意の地点まで流量を細かく制御できる。

トランジスタも同じことができる。 回路を流れる電流を、完全にオフ(開放回路)と完全にオン(短絡回路)のあいだの任意の地点で線形に制御するのである。

水のたとえで言えば、パイプの太さは回路の抵抗に相当する。 バルブがパイプの実効的な太さを細かく調整できるなら、トランジスタはコレクタとエミッタのあいだの抵抗を細かく調整できる。 つまりある意味で、トランジスタは可変抵抗器のようなものである。

電力を増幅する

もう1つ、少し無理やりだが役に立つたとえがある。 バルブをほんの少しひねるだけで、フーバーダムの放水ゲートの流量を制御できると想像してほしい。 そのつまみをひねるのに使うわずかな力が、その何千倍もの力を生み出す可能性を秘めている。 たとえとしてはやや無理があるが、この考え方はトランジスタにも当てはまる。 トランジスタが特別なのは、電気信号を増幅でき、低電力の信号をそれと相似形の、はるかに高い電力の信号に変えられるからである。

動作モード

抵抗器が電圧と電流のあいだに線形な関係を強制するのとは違い、トランジスタは非線形な部品である。 トランジスタには、そこを流れる電流のようすを表す4つの異なる動作モードがある(トランジスタを流れる電流という場合、たいていはNPNのコレクタからエミッタへ流れる電流を指す)。

トランジスタの4つの動作モードは次のとおりである。

  • 飽和(サチュレーション):トランジスタは短絡回路のようにふるまう。コレクタからエミッタへ電流が自由に流れる。
  • 遮断(カットオフ):トランジスタは開放回路のようにふるまう。コレクタからエミッタへ電流は流れない。
  • 活性(アクティブ):コレクタからエミッタへの電流が、ベース電流に比例する。
  • 逆活性(リバースアクティブ):活性モードと同じく電流はベース電流に比例するが、向きが逆になる。電流はエミッタからコレクタへ流れる(トランジスタ本来の使い方ではない)。

トランジスタがどのモードにあるかを判断するには、3つのピンそれぞれの電圧と、それらの関係を見る必要がある。 ベース-エミッタ間の電圧(VBE)とベース-コレクタ間の電圧(VBC)によって、トランジスタのモードが決まる。

上の単純化した図は、各端子の電圧の正負がモードにどう影響するかを示している。 実際にはもう少し複雑である。

それぞれのモードを個別に見ていき、そのモードにするにはどうすればよいか、電流の流れにどんな影響があるかを確認していこう。

Note

このページの大部分はNPNトランジスタを前提にしている。PNPトランジスタの動作を理解するには、単純に極性、つまり「>」と「<」の向きを反転させればよい。

飽和モード

飽和は、トランジスタのオンモードである。 飽和モードのトランジスタは、コレクタとエミッタのあいだが短絡回路であるかのようにふるまう。

飽和モードでは、トランジスタ内部の2つの「ダイオード」がどちらも順バイアスになっている。 つまりVBEは0より大きく、かつVBCも0より大きい必要がある。 言い換えると、VBはVEとVCの両方より高くなければならない。

実際には、ベース-エミッタ間の接合はダイオードそのものなので、飽和状態に入るにはVBEがしきい値電圧を超えている必要がある。 この電圧降下にはVth、Vγ、Vdなどいくつもの略称があり、実際の値はトランジスタによって(さらには温度によっても)異なる。 多くのトランジスタでは(室温で)この降下をおよそ0.6Vと見積もれる。

もう1つ、現実にはこうもいかないという話がある。 エミッタとコレクタのあいだの導通は完璧ではなく、両端のあいだにはわずかな電圧降下が生じる。 トランジスタのデータシートでは、この電圧を**CE飽和電圧VCE(sat)**として定義しており、飽和状態に必要なコレクタ-エミッタ間の電圧である。 この値はたいてい0.05〜0.2V程度である。 つまり、トランジスタを飽和させるには、VCがVEよりわずかに高くなっている必要がある(ただしどちらもVBよりは低い)。

遮断モード

遮断モードは飽和の対極にある。 遮断モードのトランジスタはオフの状態であり、コレクタ電流はなく、したがってエミッタ電流もない。 ほとんど開放回路のように見える。

トランジスタを遮断モードにするには、ベース電圧がエミッタ電圧とコレクタ電圧の両方より低くなければならない。 VBCとVBEはどちらも負である必要がある。

実際には、VBEが0VからVth(およそ0.6V)のあいだであれば、遮断モードが成立する。

活性モード

活性モードで動作させるには、トランジスタのVBEが0より大きく、VBCが負でなければならない。 つまりベース電圧はコレクタより低く、エミッタより高くなければならない。 これは同時に、コレクタがエミッタより高くなければならないことも意味する。

実際には、トランジスタを「オン」にするには、ベース-エミッタ間(VBE)に0より大きい順方向電圧降下(Vth、Vγ、Vdのいずれかで略される)が必要である。 たいていこの電圧はおよそ0.6Vである。

活性モードでの増幅

活性モードは、トランジスタをもっとも強力な状態、つまり増幅器にするモードである。 ベースピンに入る電流が、コレクタからエミッタへ流れる電流を増幅する。

トランジスタの利得(増幅率)を表す略記がβである(βFhFEと書かれることもある)。 βは、コレクタ電流(IC)とベース電流(IB)を線形の関係で結びつける。

IC = β × IB

βの実際の値はトランジスタによって異なる。 たいてい100前後だが、50から200、場合によっては2000程度まで、使用するトランジスタや流れる電流量によって幅がある。 たとえばβが100のトランジスタなら、ベースに1mAの電流を入力すると、コレクタには100mAの電流が流れることになる。

エミッタ電流IEについてはどうか。 活性モードでは、コレクタ電流とベース電流が素子に流れ込み、IEが流れ出る。 エミッタ電流をコレクタ電流と関連づけるもう1つの定数がαであり、共通ベース電流利得と呼ばれる。

IC = α × IE

αはたいてい1に非常に近いが、1より小さい値になる。 つまり活性モードでは、ICはIEに非常に近いが、IEよりわずかに小さい

βからα、あるいはその逆を計算することもできる。

α = β / (β + 1)

たとえばβが100なら、αは0.99になる。 つまりICが100mAなら、IEは101mAになる。

逆活性モード

飽和が遮断の対極にあるように、逆活性モードは活性モードの対極にある。 逆活性モードのトランジスタは導通し、増幅すら行うが、電流はエミッタからコレクタへ、逆向きに流れる。 逆活性モードの欠点は、β(この場合はβRと表記する)がはるかに小さいことである。

トランジスタを逆活性モードにするには、エミッタ電圧がベースより高く、ベースがコレクタより高くなければならない(VBE<0かつVBC>0)。

逆活性モードは、通常トランジスタを動作させたい状態ではない。 存在は知っておくとよいが、実際の設計に組み込まれることはまずない。

PNPとの対応

ここまでの内容は、BJTの半分にすぎない。 PNPトランジスタはどうだろうか。 PNPはNPNとよく似た動作をし、同じ4つのモードを持つが、すべてが逆になっている。 PNPトランジスタがどのモードにあるかを知るには、すべての「<」と「>」を反転させればよい。

たとえばPNPを飽和させるには、VCとVEがVBより高くなければならない。 PNPをオンにするにはベースを低く引き、オフにするにはコレクタやエミッタより高くする。 そしてPNPを活性モードにするには、VEがVBより高く、VBがVCより高くなければならない。

まとめると、次のようになる。

電圧の関係NPNのモードPNPのモード
VE < VB < VC活性逆活性
VE < VB > VC飽和遮断
VE > VB < VC遮断飽和
VE > VB > VC逆活性活性

NPNとPNPのもう1つの対照的な特徴が、電流の向きである。 活性モードと飽和モードでは、PNPの電流はエミッタからコレクタへ流れる。 つまり、エミッタはコレクタより高い電圧になっている必要がある。

応用例1:スイッチ

トランジスタのもっとも基本的な応用の1つが、回路の別の部分への電力供給を制御する、つまり電子スイッチとして使うことである。 遮断モードか飽和モードのどちらかで駆動することで、トランジスタはオンとオフの二値的な効果を持つスイッチとして働く。

トランジスタによるスイッチは、論理ゲートを作るための重要な構成要素であり、その論理ゲートがマイコンやマイクロプロセッサ、その他の集積回路を構成する。 以下にいくつかの応用回路を紹介する。

トランジスタスイッチ

もっとも基本的なトランジスタスイッチ回路、NPNスイッチを見てみよう。 ここではNPNを使って高出力のLEDを制御する。

制御用の入力はベースに入り、出力はコレクタにつながり、エミッタは固定の電圧に保たれる。

通常のスイッチがアクチュエーターを物理的に切り替える必要があるのに対し、このスイッチはベースピンの電圧によって制御される。 ArduinoのようなマイコンのI/Oピンをハイかローにプログラムすれば、LEDのオンとオフを切り替えられる。

ベースの電圧が0.6V(あるいはそのトランジスタのVth)を超えると、トランジスタは飽和し始め、コレクタとエミッタのあいだが短絡回路のようになる。 ベースの電圧が0.6Vより低いと、トランジスタは遮断モードになり、CE間が開放回路のようになるため電流は流れない。

上の回路は、スイッチであるトランジスタが回路のロー(グラウンド)側にあることからローサイドスイッチと呼ばれる。 一方、PNPトランジスタを使えばハイサイドスイッチを作れる。

NPNの回路と似ているが、ベースが入力、エミッタが一定電圧につながっている点は同じである。 ただし今度はエミッタがハイ側につながり、負荷はグラウンド側でトランジスタに接続される。

この回路もNPN式のスイッチと同じようにうまく機能するが、1つ大きな違いがある。 負荷を「オン」にするにはベースをローにする必要があるという点である。 これは、特に負荷側の高電圧(この図でエミッタVEにつながるVCCが12Vの場合など)が制御入力側のハイレベルより高いときに問題を引き起こしかねない。 たとえば、5Vで動作するArduinoで12Vのモーターをオフに切り替えようとすると、この回路はうまく機能しない。 その場合、VB(制御ピンにつながる)は常にVEより低くなるため、スイッチをオフにすることが不可能になってしまう。

ベース抵抗を忘れずに

上のどちらの回路にも、制御入力とトランジスタのベースのあいだに直列の抵抗が入っていることに気づいただろう。 この抵抗を追加し忘れてはいけない。 ベースに抵抗のないトランジスタは、電流制限抵抗のないLEDのようなものである。

トランジスタは、ある意味で単に2本のダイオードをつないだものであることを思い出してほしい。 負荷をオンにするには、ベース-エミッタ間のダイオードを順バイアスにする。 このダイオードをオンにするには0.6Vあれば十分であり、それ以上の電圧をかければかけるほど、より多くの電流が流れる。 トランジスタによっては、流せる電流の上限がわずか10〜100mA程度に定められていることもある。 定格を超える電流を流すと、トランジスタが壊れてしまうことがある。

制御用の電源とベースのあいだに入れる直列抵抗は、ベースへの電流を制限する役割を果たす。 ベース-エミッタ間の接合は心地よい0.6Vの電圧降下を得られ、残りの電圧は抵抗が引き受ける。 抵抗の値と、そこにかかる電圧によって、流れる電流が決まる。

抵抗は、電流を効果的に制限できるだけの大きさが必要だが、ベースに十分な電流を供給できる程度に小さくもなければならない。 たいてい1mAから10mA程度あれば十分だが、念のためトランジスタのデータシートを確認してほしい。

デジタル論理回路

トランジスタを組み合わせれば、AND、OR、NOTといった基本的な論理ゲートをすべて作れる。

(注:近年では、BJTよりもMOSFETを使って論理ゲートを作ることのほうが多い。MOSFETのほうが電力効率に優れているため、より良い選択肢とされている。)

インバータ

インバータ(NOTゲート)を実装したトランジスタ回路を見てみよう。

ベースに高い電圧が入るとトランジスタがオンになり、コレクタとエミッタが実質的につながる。 エミッタは直接グラウンドにつながっているため、コレクタもほぼグラウンド電位になる(実際にはVCE(sat)分、およそ0.05〜0.2V程度高くなる)。 逆に入力がローのとき、トランジスタは開放回路のように見え、出力はVCCまで引き上げられる。

(これは実は共通エミッタと呼ばれる基本的な構成であり、この後もう少し詳しく取り上げる。)

ANDゲート

2入力ANDゲートを作るのに使われる2本のトランジスタの例を見てみよう。

どちらか一方のトランジスタがオフなら、2つ目のトランジスタのコレクタにある出力はローに引かれる。 両方のトランジスタが「オン」(両方のベースがハイ)なら、回路の出力もハイになる。

ORゲート

最後に、2入力ORゲートを見てみよう。

この回路では、AかBのどちらか(あるいは両方)がハイであれば、対応するトランジスタがオンになり、出力をハイに引き上げる。 両方のトランジスタがオフなら、出力は抵抗を通してローに引かれる。

Hブリッジ

Hブリッジは、モーターを時計回りにも反時計回りにも駆動できるトランジスタベースの回路である。 非常によく使われる回路であり、前進も後退もできる無数のロボットの原動力になっている。

基本的にHブリッジは、2本の入力線と2本の出力を持つ4本のトランジスタの組み合わせである。

(注:実際によく設計されたHブリッジには、フライバックダイオードやベース抵抗、シュミットトリガーなど、もう少し多くの要素が加わっていることが多い。)

両方の入力が同じ電圧であれば、モーターへの出力も同じ電圧になり、モーターは回転できない。 しかし2つの入力が逆であれば、モーターはどちらかの向きに回転する。

Hブリッジの真理値表はおおよそ次のようになる。

入力A入力B出力A出力Bモーターの動き
0011停止(ブレーキ)
0110時計回り
1001反時計回り
1100停止(ブレーキ)

発振回路

発振回路は、ハイとローのあいだを周期的に行き来する信号を作り出す回路である。 発振回路は、単純にLEDを点滅させるものから、マイコンを動かすクロック信号を作るものまで、あらゆる回路で使われている。 発振回路を作る方法には、水晶振動子、オペアンプ、そしてもちろんトランジスタなど、さまざまなものがある。

ここでは、非安定マルチバイブレータと呼ばれる発振回路の例を見てみよう。 フィードバックを使うことで、2本のトランジスタから互いに補い合う2つの発振信号を作り出せる。

2本のトランジスタに加えて、この回路の本当の鍵となるのはコンデンサである。 コンデンサが交互に充電と放電を繰り返すことで、2本のトランジスタが交互にオンとオフする。

この回路の動作を分析することは、コンデンサとトランジスタの両方の動作を学ぶうえで格好の題材になる。 まず、C1が完全に充電され(およそVCC分の電圧を蓄えている)、C2は放電済み、Q1はオン、Q2はオフの状態から始めるとしよう。 その後は次のように進む。

  • Q1がオンだと、C1の(回路図上での)左側の板はおよそ0Vにつながる。これによりC1はQ1のコレクタを通して放電する。
  • C1が放電しているあいだ、C2はより値の小さい抵抗R4を通してすばやく充電される。
  • C1が完全に放電すると、その右側の板の電圧はおよそ0.6Vまで引き上げられ、Q2がオンになる。
  • ここで状態が入れ替わる。C1は放電済み、C2は充電済み、Q1はオフ、Q2はオンになる。ここから同じ動きが逆側で繰り返される。
  • Q2がオンになると、C2はQ2のコレクタを通して放電できるようになる。
  • Q1がオフのあいだ、C1はR1を通して比較的すばやく充電される。
  • C2が完全に放電すると、Q1が再びオンになり、最初の状態に戻る。

頭の中だけで追うのは難しいかもしれない。 C1、C2、R2、R3の値を選び(R1とR4は比較的小さく保つことで)、このマルチバイブレータ回路の速さを設定できる。

周期 T ≈ 0.693 × (R2×C1 + R3×C2)

コンデンサと抵抗の値をそれぞれ10µFと47kΩに設定すると、発振周波数はおよそ1.5Hzになる。 つまり、それぞれのLEDはおよそ1秒間に1.5回点滅することになる。

ここまで見てきたように、トランジスタを使った回路は無数に存在する。 しかしまだほんの入り口に触れたにすぎない。 ここで紹介した例は、主にトランジスタを飽和モードと遮断モードでスイッチとして使う方法を示したものだが、増幅についてはどうだろうか。 次は増幅の例を見ていこう。

応用例2:増幅器

トランジスタのもっとも強力な応用のいくつかは、増幅、つまり低電力の信号をより高い電力の信号に変える用途に関わっている。 増幅器は信号の電圧を増幅し、µVの範囲のものをより扱いやすいmVやVのレベルに変換できる。 あるいは電流を増幅し、フォトダイオードが生み出すµA単位の電流を、はるかに大きな電流に変換するのにも使える。 電流を入力して、より高い電圧を出力する(あるいはその逆の)増幅器もあり、それぞれトランスレジスタンス増幅器、トランスコンダクタンス増幅器と呼ばれる。

トランジスタは、多くの増幅回路にとって鍵となる部品である。 トランジスタ増幅器には見渡す限りさまざまな種類があるが、幸いその多くは、いくつかの基本的な回路をもとにしている。 これから紹介する回路を覚えておけば、パターンマッチングによって、より複雑な増幅器も理解しやすくなるはずである。

基本構成

もっとも基本的な3つのトランジスタ増幅器は、共通エミッタ、共通コレクタ、共通ベースである。 この3つの構成では、いずれも3つの端子のうち1つが常に共通の電圧(たいていグラウンド)に固定され、残りの2つが増幅器の入力または出力になる。

共通エミッタ

共通エミッタは、もっともよく使われるトランジスタの構成の1つである。 この回路では、エミッタがベースとコレクタの両方に共通する電圧(たいていグラウンド)に固定される。 ベースが信号の入力、コレクタが出力になる。

共通エミッタ回路がよく使われるのは、特に低周波での電圧増幅に適しているからである。 たとえば音声信号の増幅などに向いている。 1.5V程度の小さなピークトゥピーク入力信号があれば、もう少し複雑な回路を使ってはるかに高い電圧に増幅できる。

共通エミッタには1つ癖があり、それは入力信号を反転させてしまうことである(前の節のインバータと比べてみてほしい)。

共通コレクタ(エミッタフォロワ)

コレクタピンを共通電圧に固定し、ベースを入力、エミッタを出力として使うと、共通コレクタになる。 この構成はエミッタフォロワとも呼ばれる。

共通コレクタは電圧の増幅をまったく行わない(実際には、出力電圧は入力電圧よりも0.6V低くなる)。 そのため、この回路は電圧フォロワと呼ばれることもある。

一方でこの回路は電流増幅器として大きな可能性を秘めている。 それに加えて、高い電流利得とほぼ1倍の電圧利得を組み合わせることで、優れた電圧バッファにもなる。 電圧バッファは、負荷回路がそれを駆動している回路に望ましくない影響を与えないようにする役割を果たす。

たとえば、負荷に1Vを供給したいとき、簡単な方法として分圧回路を使うこともできるし、エミッタフォロワを使うこともできる。

負荷が大きくなる(つまり抵抗が小さくなる)ほど、分圧回路の出力電圧は下がってしまう。 しかしエミッタフォロワの出力電圧は、負荷が何であってもほぼ一定に保たれる。 出力インピーダンスの大きい回路と違って、大きな負荷がエミッタフォロワを「重くする」ことはない。

共通ベース

この節を締めくくるために共通ベースにも触れておくが、3つの基本構成の中ではもっとも使用頻度が低い。 共通ベース増幅器では、エミッタが入力、コレクタが出力になる。 ベースは両方に共通する。

共通ベースは、いわばエミッタフォロワの逆のような存在である。 そこそこの電圧増幅器であり、入力電流と出力電流はほぼ等しい(厳密には入力電流のほうがわずかに大きい)。

共通ベース回路は電流バッファとして特に優れている。 低い入力インピーダンスで入力電流を受け取り、ほぼ同じ電流を、より高いインピーダンスの出力へ届けられる。

まとめ

この3つの増幅器構成は、より複雑な多くのトランジスタ増幅器の核となっている。 それぞれ、電流の増幅、電圧の増幅、バッファリングのどれかで真価を発揮する得意分野がある。

共通エミッタ共通コレクタ共通ベース
電圧利得
電流利得
入力インピーダンス
出力インピーダンス

多段増幅器

トランジスタ増幅器の多様さについては、まだまだ語り尽くせない。 ここでは、上で紹介した単段の増幅器を組み合わせるとどうなるかを示す例をいくつか紹介する。

ダーリントン接続

ダーリントン接続は、共通コレクタを2段重ねて、高い電流利得を持つ増幅器を作る構成である。

出力電圧は入力電圧とほぼ同じ(1.2〜1.4V程度低くなる)が、電流利得は2つのトランジスタの利得の積になる。 つまりβ²であり、1万倍を超えることもある。

小さな入力電流で大きな負荷を駆動したいときには、ダーリントンペアは優れた道具になる。

差動増幅器

差動増幅器は、2つの入力信号の差を取り、その差を増幅する回路である。 入力と出力を比較して次の出力を作り出すフィードバック回路にとって、重要な構成要素である。

差動増幅器の基本形は次のようになる。

この回路はロングテールペアとも呼ばれる。 これは2つの共通エミッタ回路を組み合わせ、互いに比較することで差動出力を作り出すものである。 2つの入力はそれぞれのトランジスタのベースに加えられ、出力は2つのコレクタ間の差動電圧として得られる。

プッシュプル増幅器

プッシュプル増幅器は、多くの多段増幅器の「最終段」として便利な回路である。 エネルギー効率の良い電力増幅器であり、スピーカーの駆動によく使われる。

基本的なプッシュプル増幅器は、どちらも共通コレクタとして構成されたNPNとPNPのトランジスタを使う。

プッシュプル増幅器は電圧をほとんど増幅しない(出力電圧は入力よりわずかに低くなる)が、電流は増幅する。 正負両方の電源を持つ回路(バイポーラ電源回路)では特に有用であり、正電源から負荷へ電流を「プッシュ」し、負電源へ電流を「プル」して逃がすことができる。

バイポーラ電源を使っている(あるいは使っていない)場合でも、プッシュプルは増幅器の最終段として優れており、負荷に対するバッファとして機能する。

すべてを組み合わせる(オペアンプの例)

多段トランジスタ回路の代表例として、オペアンプを見てみよう。 よく使われるトランジスタ回路を見分け、その役割を理解できれば、それだけで大きな武器になる。 ここでは、非常にシンプルなオペアンプであるLM358の内部回路を見てみよう。

すぐに消化しきれないほどの複雑さがあるが、見覚えのある構成もいくつか見つかるはずである。

  • Q1、Q2、Q3、Q4が入力段を構成している。共通コレクタ(Q1とQ4)が差動増幅器につながっているように見えないだろうか。PNPを使っているため上下が逆に見えるだけである。これらのトランジスタが増幅器の入力差動段を構成している。
  • Q11とQ12は2段目を構成する。Q11は共通コレクタ、Q12は共通エミッタである。この2本のトランジスタは、Q3のコレクタからの信号をバッファリングしつつ、最終段へ向かう信号に高い利得を与える。
  • Q6とQ13は最終段を構成しており、こちらも見覚えがあるはずである(RSCを無視すれば)、プッシュプルである。この段が出力をバッファリングし、より大きな負荷を駆動できるようにしている。
  • ここまで触れていない構成もいくつかある。Q8とQ9はカレントミラーとして構成されており、一方のトランジスタを流れる電流量をもう一方にそのままコピーする。

このトランジスタの集中講義を終えた今、この回路のすべてを理解できるとは思っていないが、よく使われるトランジスタ回路を見分けられるようになっていれば、正しい道を歩んでいると言える。

まとめ

トランジスタについてさらに深く学びたいなら、次のような資料もおすすめである。

  • Getting Started in Electronics by Forrest Mims:Mimsは電子工学をわかりやすく、実践的に説明する名手である。トランジスタについてもう一歩踏み込んだ入門書として一読の価値がある。
  • LTSpiceFalstad Circuit:無料で使える回路シミュレーションツールである。デジタル上で回路を実験することは、優れた学習方法であり、ブレッドボードの手間や部品を壊す心配なしにいろいろ試せる。ここで扱った回路もぜひ組んでみてほしい。
  • 2N3904のデータシート:トランジスタについて学ぶもう1つの方法は、データシートを読み込むことである。2N3904は非常によく使われるトランジスタであり(PNP版の兄弟にあたるのが2N3906である)、データシートを見て、見覚えのある特性を探してみてほしい。

電子工作についてさらに学びたいなら、次のようなチュートリアルもおすすめである。

  • 集積回路:数千個のトランジスタを組み合わせて黒い箱に詰め込むと何ができるか。それがICである。
  • シフトレジスタ:もっとも一般的な集積回路の1つである。わずかな入力だけで何十個ものLEDを点滅させる方法を学べる。
  • Eagleを使ったPCB設計:新しく身につけたトランジスタの知識を、実際のPCB設計に活かしてみよう。
  • はんだ付けの基本:PCBを設計したら、はんだ付けの方法も知っておく必要がある。

タグ: 部品、電気工学、技術


出典:Transistors(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

集積回路

集積回路(IC)は、現代の電子工学を支える要である。 ほとんどの回路にとって心臓であり頭脳でもある。 ほぼすべての基板の上で見かける、あの黒くて小さな「チップ」がICである。 よほど変わったアナログ電子工学の達人でもない限り、作る電子工作プロジェクトにはたいてい少なくとも1つのICが使われているはずであり、その中身を理解しておくことは重要である。

ICとは、抵抗器トランジスタコンデンサといった電子部品の集まりを、小さなチップの中に詰め込んで互いに接続し、1つの共通の目的を果たすようにしたものである。 単純な論理ゲート1つだけのものから、オペアンプ、555タイマー、電圧レギュレータ、モータードライバ、マイコン、マイクロプロセッサ、FPGAまで、実にさまざまな種類がある。

このチュートリアルで扱う内容:

  • ICの構成
  • よく使われるICのパッケージ
  • ICの見分け方
  • よく使われるICの種類

参考になるチュートリアル:

ICの内部

集積回路と聞いて思い浮かぶのは、たいてい黒くて小さなチップである。 では、その黒い箱の中身はどうなっているのだろうか。

ICの本当の「中身」は、半導体ウエハー、銅、その他の材料を複雑に積み重ねた構造であり、これらが相互接続されて回路の中のトランジスタや抵抗、その他の部品を形作っている。 このウエハーを切り出し、成形したものをダイと呼ぶ。

IC自体は小さいが、それを構成する半導体ウエハーや銅の層は信じられないほど薄く、層と層のあいだの接続も非常に緻密である。 先ほどのダイを拡大すると、その様子がよくわかる。

ICのダイは、回路をこれ以上ないほど小さくした姿であり、そのままではんだ付けしたり接続したりするには小さすぎる。 ICに接続する作業を楽にするため、私たちはダイをパッケージに収める。 ICパッケージが、あの繊細で小さなダイを、誰もが見慣れた黒いチップへと変えてくれる。

ICのパッケージ

パッケージは、ICのダイを封入し、私たちが接続しやすいように端子を外部に引き出す役割を果たす。 ダイの外周にある接続点は、それぞれ細い金線を通じてパッケージのパッドピンにつながっている。 ピンは、IC本体から突き出た銀色の端子であり、回路の他の部分へと接続される。 このピンこそが、回路の他の部品や配線とつながる部分であり、私たちにとってもっとも重要な要素である。

パッケージには多くの種類があり、それぞれ独自の寸法や実装方式、ピン数を持っている。

極性の表示とピン番号

すべてのICは極性を持ち、どのピンも位置と機能の両方において唯一無二である。 そのため、パッケージにはどのピンがどれかを示す何らかの方法が必要になる。 たいていのICは、1番ピンを示すために切り欠き丸印のどちらかを使う(両方あることもあれば、どちらか一方だけのこともある)。

1番ピンの位置がわかれば、そこから反時計回りに進むにつれてピン番号が順番に増えていく。

実装方式

パッケージの種類を特徴づける主な要素の1つが、基板への実装方式である。 パッケージはすべて、スルーホール(PTH)か表面実装(SMDまたはSMT)のどちらかに分類される。 スルーホールパッケージは一般に大きく、扱いやすい。 基板の片面から挿し込み、反対側ではんだ付けするように設計されている。

表面実装パッケージは、小さなものから極小のものまでさまざまなサイズがある。 すべて基板の片面に乗せて、その面ではんだ付けするように設計されている。 SMDパッケージのピンは、チップの側面から垂直に突き出ているものもあれば、チップの底面にマトリクス状に配置されているものもある。 この形状のICは手作業での実装にあまり向いておらず、たいてい専用の道具が必要になる。

DIP(デュアルインラインパッケージ)

DIP(デュアルインラインパッケージの略)は、もっともよく見かけるスルーホール型のICパッケージである。 この小さなチップは、四角い黒いプラスチックのケースから、2列に並んだピンが垂直に突き出た形をしている。

DIP ICのそれぞれのピンは0.1インチ(2.54mm)間隔で並んでおり、これはブレッドボードをはじめとする試作用基板にぴったり収まる標準的な間隔である。 DIPパッケージ全体の大きさは、ピン数によって変わり、4ピンから64ピン程度まで幅がある。

ピンの2つの列のあいだの間隔は、DIP ICがブレッドボードの中央部分をまたげるようにちょうどよく設計されている。 これにより、それぞれのピンが基板上で独立した行に対応し、互いにショートしないようになっている。

DIP ICはブレッドボードで使うだけでなく、PCBにはんだ付けすることもできる。 基板の片面から挿し込み、反対側ではんだ付けして固定する。 ICを直接はんだ付けする代わりに、ソケットを使うのがよい場合もある。 ソケットを使えば、ICが「青い煙を吐いて」しまったときに、取り外して交換できる。

表面実装(SMD/SMT)パッケージ

今日では、表面実装パッケージには実に多くの種類がある。 表面実装型のICを扱うには、たいてい対応する銅箔パターンを持つ専用のプリント基板(PCB)が必要になる。

ここでは、比較的よく見かける表面実装パッケージをいくつか紹介する。 手はんだのしやすさで言えば、「なんとかできる」ものから、「専用の道具があればなんとかできる」もの、「非常に特殊な、たいていは自動化された道具でなければ無理」なものまで幅がある。

スモールアウトライン(SOP)

スモールアウトラインIC(SOIC)パッケージは、DIPの表面実装版のようなものである。 DIPのすべてのピンを外側に折り曲げ、サイズを小さくしたものだと考えるとよい。 手先が安定していて、よく目を凝らせば、SOICパッケージは手はんだしやすいSMD部品の部類に入る。 SOICパッケージでは、ピンの間隔はたいてい0.05インチ(1.27mm)程度である。

SSOP(シュリンクスモールアウトラインパッケージ)は、SOICパッケージをさらに小さくしたものである。 似たようなICパッケージには、TSOP(シンスモールアウトラインパッケージ)やTSSOP(シンシュリンクスモールアウトラインパッケージ)もある。

MAX232マルチプレクサのような、比較的単純で1つの役割に特化したICの多くは、SOICやSSOPの形で提供される。

クアッドフラットパッケージ

ICのピンを四方すべてに広げると、クアッドフラットパッケージ(QFP)のような形になる。 QFPのICは、1辺あたり8ピン(合計32ピン)から、70ピン以上(合計300ピン以上)まで幅がある。 QFPのピン間隔はたいてい0.4mmから1mm程度である。 標準的なQFPパッケージをさらに小さくしたものに、シン(TQFP)、ベリーシン(VQFP)、ローププロファイル(LQFP)パッケージがある。

QFPのICのピンを削り取ったような形にすると、クアッドフラットノーリード(QFN)パッケージになる。 QFNパッケージの接続部は、ICの底面の角に露出した小さなパッドである。 側面と底面の両方に露出しているものもあれば、底面だけに露出しているものもある。

シン(TQFN)、ベリーシン(VQFN)、マイクロリード(MLF)パッケージは、標準的なQFNパッケージをさらに小さくしたものである。 デュアルノーリード(DFN)やシンデュアルノーリード(TDFN)のように、2辺だけにピンを持つパッケージもある。

多くのマイクロプロセッサやセンサー、その他の現代的なICはQFPやQFNパッケージで提供されている。 人気の高いATmega328マイコンはTQFPパッケージとQFN系(MLF)パッケージの両方で提供されており、MPU-6050のような小型の加速度センサージャイロセンサーは極小のQFN形状で提供されている。

ボールグリッドアレイ

最後に、より高度なICのために、ボールグリッドアレイ(BGA)パッケージがある。 これは、ICの底面に小さなはんだのボールを2次元格子状に並べた、驚くほど緻密なパッケージである。 はんだボールがダイに直接取り付けられていることさえある。

BGAパッケージは、pcDuinoRaspberry Piに搭載されているような、高度なマイクロプロセッサ向けに使われることが多い。

BGAパッケージのICを手ではんだ付けできるなら、はんだ付けの達人と自負してよい。 たいていは、ピックアンドプレース機やリフロー炉を使った自動化された工程でPCBに実装される。

よく使われるIC

集積回路は電子工作のあらゆる場面に登場するため、そのすべてを網羅するのは難しい。 ここでは、電子工作の学習でよく出会うICをいくつか紹介する。

論理ゲート、タイマー、シフトレジスタなど

ICそのものを構成する基本要素である論理ゲートも、それ自体を1つのICとしてパッケージ化できる。 論理ゲート用のICには、この4入力ANDゲートのように、1つのパッケージに複数のゲートが収められているものもある。

論理ゲートをIC内部で組み合わせることで、タイマー、カウンター、ラッチ、シフトレジスタなど、その他の基本的な論理回路も作れる。 こうした単純な回路の多くは、DIPだけでなくSOICやSSOPのパッケージでも見つかる。

マイコン、マイクロプロセッサ、FPGAなど

数千、数百万、数十億個ものトランジスタを小さなチップに詰め込んだマイコン、マイクロプロセッサ、FPGAも、すべて集積回路の一種である。 これらの部品は、機能、複雑さ、大きさにおいて非常に幅広い。 Arduinoに搭載されているATmega328のような8ビットマイコンから、パソコンの動作を統括する複雑な64ビットマルチコアのマイクロプロセッサまで、さまざまなものがある。

これらの部品は、たいてい回路の中でもっとも大きなICになる。 単純なマイコンは、DIPからQFN/QFPまでのパッケージに収められ、ピン数は8から100程度である。 これらの部品が複雑になるほど、パッケージも同じように複雑になっていく。 FPGAや複雑なマイクロプロセッサは1000本を超えるピンを持つこともあり、QFN、LGA、BGAといった高度なパッケージでしか提供されない。

センサー

温度センサーや加速度センサージャイロセンサーといった現代のデジタルセンサーも、すべて集積回路として作られている。

これらのICは、基板上のマイコンや他のICと比べてたいてい小さく、ピン数は3から20程度である。 DIPパッケージのセンサーICは珍しくなりつつあり、現代の部品はたいていQFP、QFN、あるいはBGAパッケージで提供されている。

まとめ

集積回路は、ほぼすべての回路に登場する部品である。 ICについて理解できたところで、次のような関連する概念のチュートリアルも確認してみてほしい。

  • PCB基板の基礎:ICは何らかの方法で回路に接続する必要がある。たいていはプリント基板(PCB)にはんだ付けすることになる。あの緑色の小さな基板について、このチュートリアルで学べる。
  • シリアル通信SPI通信、I2C:どれも、ICどうしが通信するための通信プロトコルである。

次のようなスキル系のチュートリアルもおすすめである。電子工作を始めたばかりの人なら、ぜひ身につけておきたいスキルである。

  • はんだ付けの基本:ブレッドボードでICを使うのでなければ、はんだ付けが必要になるはずである。
  • PCB設計:すでにPCBに慣れているなら、実際に自分で設計してみるのはどうだろうか。

タグ: 部品、電気工学、技術


出典:Integrated Circuits(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

ボタンとスイッチの基礎

もっとも基本的でありながら見落とされがちな回路部品の1つが、スイッチである。

スイッチを評価するのに複雑な計算式は必要ない。 スイッチがしているのは、開放回路と短絡回路を切り替えることだけである。 単純な部品だが、ボタンやスイッチなしで暮らすことなど考えられるだろうか。 ユーザーからの入力を受け付けないブリンク回路に何の意味があるだろうか。 非常停止スイッチのない危険なロボットなど論外である。 絶対に押してはいけない大きな赤いボタンのない世界を想像できるだろうか。

このチュートリアルで扱う内容:

  • モーメンタリー(自動復帰)スイッチとメンテイン(維持)スイッチの違い
  • SPST、SPDT、DPDTなどの表記が何を意味するか
  • ノーマリークローズとノーマリーオープンのボタンの違い
  • スイッチのさまざまな見た目
  • 重要なスイッチの定格
  • スイッチの応用例

参考になるチュートリアル:

スイッチとは何か

スイッチは、電気回路が開いているか閉じているかを制御する部品である。 配線を実際に切ったり継ぎ足したりすることなく、回路内の電流の流れを制御できる。 スイッチは、ユーザーの操作や制御を必要とするあらゆる回路に欠かせない部品である。

スイッチが取りうる状態は、開(オフ)か閉(オン)のどちらか一方だけである。 オフの状態では、スイッチは回路の中に開いた隙間があるように見える。 これは実質的に開放回路であり、電流が流れるのを妨げる。

オンの状態では、スイッチは完全に導通する1本の電線のようにふるまう。 つまり短絡である。 これにより回路が閉じ、システムが「オン」になって、残りの部分に電流が滞りなく流れられるようになる。

スイッチにはトグル式、ロータリー式、DIP式、押しボタン式、ロッカー式、メンブレン式など、実にさまざまな種類がある。 それぞれのスイッチには、他と区別するための固有の特徴がある。 どんな動作でスイッチが切り替わるか、あるいはスイッチがいくつの回路を制御できるか、といった特徴である。 次は、スイッチの基本的な特徴をいくつか見ていこう。

スイッチを特徴づける要素

操作方法

ある状態から別の状態へ切り替えるには、スイッチを操作(アクチュエート)する必要がある。 つまり、スイッチの状態を「切り替える」には何らかの物理的な動作が必要になる。 スイッチの操作方法は、そのスイッチを特徴づけるもっとも大きな要素の1つである。

スイッチの操作には、押す、スライドさせる、揺らす、回す、倒す、引く、鍵を回す、加熱する、磁化する、蹴る、はじく……など、スイッチ内部の機械的な接点を接触させたり離したりできる物理的な動作であれば、どんなものでもありうる。

モーメンタリーとメンテイン

すべてのスイッチは、モーメンタリー(自動復帰)かメンテイン(維持)のどちらかに分類できる。

メンテインスイッチは、壁の照明スイッチのように、操作されるまで1つの状態を保ち続け、新しい状態に切り替わった後もその状態を保つ。 「トグルスイッチ」や「ON/OFFスイッチ」と呼ばれることもある。

モーメンタリースイッチは、操作され続けているあいだだけ有効な状態を保つ。 操作されていなければ、常に「オフ」の状態に戻る。 キーボードのキーは、身近なモーメンタリースイッチの代表例である。

用語について1つ補足しておくと、一般に「ボタン」と呼ばれるスイッチの多くはモーメンタリー型に分類される。 ボタンを押すという操作自体が、いかにも「押している間だけ」という感覚に結びつくからである。 中にはメンテイン式のボタンも存在するが、このチュートリアルで単に「ボタン」と言うときは、基本的に「押している間だけオンになるモーメンタリースイッチ」を指すものと考えてほしい。

実装方法

多くの部品と同じく、スイッチの端子の形式も表面実装(SMD)かスルーホール(PTH)のどちらかになる。 スルーホール型のスイッチはたいてい大きめで、ブレッドボードでの試作に使いやすいよう設計されているものもある。

SMD型のスイッチはPTH型より小さく、PCBの上に平らに実装される。 たいてい軽い力での操作を前提としており、スルーホール型ほどの操作力には耐えられないことが多い。

筐体の外側に取り付けるパネルマウント型のスイッチも、よく使われる実装方法の1つである。 筐体の内側に隠れたスイッチは操作しづらい。 パネルマウント型のスイッチには、PTH、SMD、あるいは配線をはんだ付けする頑丈なラグ端子など、さまざまな端子形式がある。

もう1つ重要なスイッチの特徴として、スイッチ内部の回路構成があり、これは章を1つ割くだけの価値がある話題である。 SPSTなのか、DPSTなのか、4PDTなのか、こうした表記は、いったい何を意味しているのだろうか。

極(ポール)と投(スロー)、開と閉

スイッチには少なくとも2本の端子が必要であり、一方から電流が(場合によっては)入り、もう一方から(場合によっては)出ていく。 ただし、これはもっとも単純なスイッチの説明にすぎない。 実際には、スイッチに2本より多くのピンがあることのほうが多い。 では、こうした端子はスイッチの内部構造とどう対応しているのだろうか。 ここで重要になるのが、スイッチが持つ「極(ポール)」と「投(スロー)」の数である。

スイッチの(ポール)の数は、そのスイッチが制御できる独立した回路の数を表す。 極が1つのスイッチは、1つの回路にしか影響を与えられない。 4極のスイッチなら、4つの異なる回路を個別に制御できる。

スイッチの(スロー)の数は、それぞれの極が接続できる位置の数を表す。 たとえば投が2つのスイッチなら、スイッチ内の各回路(極)は2つの端子のどちらかに接続できる。

極と投の数がわかれば、スイッチをより具体的に分類できる。 よく見かけるのは「単極単投」「単極双投」「双極双投」といった分類で、それぞれ略してSPST、SPDT、DPDTと呼ばれる。

SPST

単極単投(SPST)スイッチは、もっとも単純な構成である。 出力が1つ、入力が1つしかない。 このスイッチは閉じているか、完全に切り離されているかのどちらかである。 SPSTはオンとオフの切り替えに最適であり、モーメンタリースイッチの一般的な形式でもある。 SPSTスイッチに必要な端子は2本だけである。

SPDT

もう1つよく使われるのがSPDTである。 SPDTには3本の端子があり、1本の共通ピンと、共通ピンとの接続を奪い合う2本のピンで構成される。 SPDTは、2つの電源の切り替えや入力の入れ替えなど、2つの回路のどちらかを選びたい場面に適している。 シンプルなスライドスイッチの多くはSPDT型である。 SPDTスイッチにはたいてい3本の端子がある(余談だが、SPDTの投を1つ未接続のままにしておけば、実質的にSPSTとして使うこともできる)。

DPDT

SPDTにもう1つ極を追加すると、双極双投(DPDT)スイッチになる。 基本的にはSPDTスイッチを2つ組み合わせたもので、2つの独立した回路を制御できるが、常に1つのアクチュエーターで一緒に切り替わる。 DPDTには6本の端子がある。

XPYT

3極以上、あるいは3投以上のスイッチはあまり一般的ではないが、実際に存在する(形も独特で接続もしにくいことが多い)。 極や投が2つを超えると、略称にはそのまま数字を当てはめていく。 たとえば4PDTスイッチは、4つの独立した回路を、それぞれ2つの位置で制御できる。

Note

豆知識:英語では“poles“(極)を“pulls“と間違えて発音してしまう人がよくいるが、正しくは“poles“である。

ノーマリーオープンとノーマリークローズ

モーメンタリースイッチが操作されていないとき、それは「通常」の状態にある。 ボタンの構造によって、この通常の状態は開放回路にも短絡回路にもなりうる。 操作されるまで開いているボタンはノーマリーオープン(略してNO)と呼ばれる。 NOスイッチを操作すると回路が閉じるため、「push-to-make(押して導通させる)」スイッチとも呼ばれる。

逆に、操作されない限り短絡回路のようにふるまうボタンはノーマリークローズ(NC)スイッチと呼ばれる。 NCスイッチは「push-to-break(押して遮断する)」であり、操作すると回路が開く。

この2つのうち、ノーマリーオープンのモーメンタリースイッチに出会う機会のほうがずっと多いだろう。

モーメンタリースイッチ

モーメンタリースイッチは、操作されている(押されている、保持されている、磁化されているなど)あいだだけオンの状態を保つスイッチである。 たいていは、リセットボタンやキーパッドのボタンのように、断続的なユーザー入力に使うのに適している。

モーメンタリースイッチの例

押しボタン

押しボタンスイッチは、モーメンタリースイッチの代表格である。 たいてい押したときに心地よい「クリック」というタクタイルフィードバックがある。 大きさや色、照光式(内部のLEDがボタン越しに光る)など、実にさまざまなバリエーションがある。 端子はスルーホール、表面実装、パネルマウントなど、いろいろな形式がある。

ボタンマトリクス

キーボードのような大量のモーメンタリーボタンの集まりや、キーパッドのようなもう少し小さなまとまりでは、たいていすべてのスイッチを大きなマトリクス状に配置する。 パッド上のそれぞれのボタンには、行と列が割り当てられる。 これによりマイコン側で多少の処理が余分に必要になるが、その分I/Oピンを大幅に節約できる。

その他

モーメンタリースイッチは、必ずしも押し下げる動作で操作するとは限らない。 一部のジョイスティックのように、横に押す動作で操作するものもある。

もう一方の極端な例として、リードスイッチは磁場にさらされると開閉する。 非接触式のスイッチを作るのに適している。

メンテインスイッチ

メンテインスイッチは、新しい状態に操作されるまでその状態を保ち続ける。 身近な例は、すぐそこの壁にある(部屋の照明を制御しているあのスイッチである)。 メンテインスイッチは、電源のオンとオフのように「一度設定したらそのまま」にしておきたい用途に適している。

メンテインスイッチの例

スライドスイッチ

飾り気のないシンプルなON/OFFスイッチや切り替えスイッチが必要なら、スライドスイッチがぴったりかもしれない。 このスイッチにはスイッチ本体から突き出た小さなつまみがあり、それを本体の上でスライドさせて2つ(またはそれ以上)の位置のどれかに合わせる。

スライドスイッチはたいていSPDTかDPDTの構成で見られる。 共通端子はたいてい中央にあり、2つの選択位置がその両側に配置される。

トグルスイッチ

「トグルスイッチ」と聞くと、「ミサイル発射!」のようなイメージを思い浮かべるかもしれない。 トグルスイッチには長いレバーがあり、揺らすような動きで動作する。 新しい位置に切り替わるとき、トグルスイッチは実に気持ちのよい「カチッ」という音を立てる。

トグルスイッチにはSPST(2端子)やSPDT(3端子)が一般的だが、それ以外の構成のものも見つかる。 他のスイッチと同じく、スルーホール型、表面実装型、そしておそらくもっとも一般的なパネルマウント型がある。

DIPスイッチ

DIPスイッチは、スルーホール型のDIP ICと同じ考え方で設計されたスルーホール型のスイッチである。 DIP ICと同じように、中央部分をまたぐ形でブレッドボードに配置できる。 8個以上の独立したSPSTスイッチが、小さなスライドレバーとともに配列されている製品が多い。 コンピュータの黎明期には広く使われていたが、今でもハードウェア側で機器を設定する用途に役立っている。

ラッチングボタン

押しボタンのすべてがモーメンタリーというわけではない。 一部の押しボタンは、一度押すとその位置で固定され、もう一度押すまでその状態を保つ。 ギターのエフェクトペダルにあるようなスイッチが、この一例である。

その他

メンテインスイッチの多様さは、ここで紹介した以上に広がっている。 プルチェーンスイッチはプロジェクトに気の利いた雰囲気を加えてくれる。 キースイッチは、誰にでも殺人ロボットの電源を入れられては困る場面に。 テスターに付いているようなロータリースイッチは、特に多くの投を必要とする場面でユニークな入力手段になる。

そしてもちろん、あの大きなナイフスイッチなしで暮らせるマッドサイエンティストなどいないだろう。

スイッチの応用例

オンとオフの制御

スイッチのもっとも身近な応用が、単純なオンとオフの制御である。 暗い部屋に入るたびにしているあの動作である。 オンとオフスイッチは、電源ラインに直列にSPSTスイッチを1つ挟むだけで実現できる。 たいていはトグルスイッチやスライドスイッチのようなメンテイン型が使われるが、モーメンタリー型のオンとオフスイッチにも用途はある。

このようなスイッチを実装するときは、プロジェクトが消費するすべての電流がそのスイッチを通ることになる点に注意してほしい。 理想的にはスイッチは完全な導体だが、現実には2つの接点のあいだにわずかな抵抗がある。 その抵抗のせいで、すべてのスイッチには耐えられる最大電流の定格が定められている。 スイッチの最大電流定格を超えると、プラスチックが溶けたり、魔法の煙が出てきたりすることになる。

たとえば、このSPDTスライドスイッチは、小規模なプロジェクト(Simon風のゲームやメトロノームなど)の電流を制御するのには適しているが、大出力のモータードライバーや100個連なったLEDストリングの制御には向かない。 そうした用途には、4A対応のトグルスイッチ6A対応のランプスイッチのようなものを検討するとよい。

ユーザー入力

もちろん、ユーザー入力もスイッチのもっとも一般的な応用の1つである。 たとえばスイッチをマイコンの入力ピンに接続したいなら、次のような簡単な回路だけで済む。

スイッチが開いているとき、MCUのピンは抵抗を通して5Vにつながっている。 スイッチが閉じると、ピンは直接GNDにつながる。 この回路の抵抗はプルアップ抵抗であり、入力をハイにバイアスし、スイッチが閉じたときにグラウンドへの短絡が起きないようにするために必要である。

まとめ

これでスイッチの基礎はひととおりカバーできた。 次は、次のような関連するチュートリアルを探ってみるとよい。

  • プルアップ抵抗:プルアップ抵抗は、モーメンタリーボタンのほとんどの回路と組み合わせて使われる。電源とグラウンドが短絡しないようにし、I/Oラインがフローティングにならないようにしてくれる。
  • トランジスタ:これも(他の多くの用途とあわせて)電子的に制御できるスイッチのようなものとして使える。
  • リレー:もう1つの電子的に制御できるスイッチであり、大電力の回路のオンとオフに適している(SparkFun Learnには独立したリレーの概念解説チュートリアルは現時点で存在しない)。
  • 加速度センサーの基礎:スマートフォンや新しいゲームコントローラーに搭載されている動き検出用の加速度センサーは、こうした従来型のスイッチに代わる入力デバイスとして急速に普及している。
  • プロジェクトへの電源供給:あなたのスイッチは、どんな電源をオンとオフすることになるだろうか。

タグ: 部品、概念、電気工学、入力デバイス、技術


出典:Button and Switch Basics(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

モーターと最適な選び方

はじめに

身の回りには、常に一つや二つのモーターがある。 携帯電話のバイブレーションモーターから、お気に入りのゲーム機のファンやCDドライブまで、モーターはいたるところに存在する。 モーターは、機器が私たちや環境と関わり合うための手段を提供する部品である。 用途が非常に幅広いため、モーターの設計や動作の仕方もさまざまである。

このチュートリアルで学ぶこと

このチュートリアルでは、次の基本的なモーターの種類と用途を扱う。

  • DCブラシモーター
  • ブラシレスモーター
  • ステッピングモーター
  • リニアモーター

参考になるチュートリアル:

モーターはなぜ動くのか

もっとも曖昧で単純な答えは「磁力」である。 ここから、この単純な力をスーパーカーにまで発展させていこう。

話を単純にするため、いくつかの概念を思考実験というレンズを通して見ていく。 細部を多少簡略化するので、より厳密な議論に踏み込みたい場合はGriffiths博士の教科書を参照してほしい。 この思考実験では、磁場は動いている電子、すなわち電流によって生み出されるものとする。 この考え方は古典的なモデルとしては使いやすいが、原子レベルまで踏み込むと成り立たなくなる。 磁力を原子レベルで理解したい場合、Griffithsは別の著書でさらに詳しく説明している。

電磁気

磁石や磁場を作り出すには、それらがどのように生成されるかを見ていく必要がある。 電流と磁場の関係は右手の法則に従う。 電流が導線を流れると、指を導線に巻きつける向きに磁場が生じる。 これは、電流が流れる導線に働くアンペールの力の法則を簡略化したものである。 その導線をあらかじめ存在する磁場の中に置くと、力を発生させることができる。 この力はローレンツ力と呼ばれる。

右手の法則は、電流の向きと磁場の向きの関係を示している(画像提供:HyperPhysics)。

電流を増やせば、磁場の強さも強くなる。 とはいえ、磁場を実用的な仕事に使うには、莫大な電流が必要になる。 さらに、その電流を流す導線自体も同じ強さの磁場を帯びることになり、制御できない磁場が生まれてしまう。 導線をループ状に曲げることで、方向のそろった集中した磁場を作ることができる。

磁場そのものは変わっていない。導線をループ状に曲げることで、磁場の向きがそろうだけである(画像提供:HyperPhysics)。

電磁石

導線をループさせて電流を流すと、電磁石ができる。 導線1巻きで磁場を集中できるなら、もっと巻いたらどうなるだろうか。数百巻き増やしてみるとどうか。 回路に加える巻数が増えるほど、同じ電流でも磁場は強くなる。 それなら、なぜモーターや電磁石には何千、何百万という巻線が使われていないのだろうか。 それは、導線が長くなるほど抵抗が大きくなるからである。 オームの法則(V = I×R)によれば、抵抗が増えても同じ電流を維持するには、電圧を上げなければならない。 場合によっては電圧を高くするほうが理にかなっていることもあれば、抵抗の小さい太い導線を使うほうがよいこともある。 太い導線を使うのはコストが高く、扱いも難しくなるのが一般的である。 これらは、モーターを設計する際に検討すべき要素である。

通電した電磁石が磁場を作り出している様子(画像提供:HyperPhysics)。

実験してみよう

自分で電磁石を作るには、ボルト(または他の丸い鋼製の物)と、マグネットワイヤー(30〜22ゲージ程度でよい)、電池を用意する。

Note

注意:この実験にリチウム電池は使わないこと。

鋼の周りに導線を75〜100回ほど巻きつける。 鋼の芯を使うことで磁場がさらに集中し、実効的な強さが増す。 これがなぜ起きるのかは、次のセクションで説明する。

熱収縮チューブやテープを使うと、コイルを鋼の芯に固定しやすくなる。

やすりで導線の両端の被覆を取り除き、それぞれの端を電池の各端子につなぐ。 これでモーターの最初の部品が完成した。 電磁石の強さを試すには、クリップなど小さな鋼製の物を持ち上げてみるとよい。

強磁性

先ほどの思考実験の出発点に立ち返ると、磁場は電流によってのみ生まれるとされていた。 電流を電子の流れと定義するなら、原子の周りを回る電子もまた電流を作り出し、したがって磁場を生み出すはずである。 すべての原子に電子があるなら、あらゆるものが磁性を帯びるのだろうか。答えはイエスである。 カエルを含むあらゆる物質は、十分なエネルギーが与えられれば磁気的な性質を示す。 しかし、すべての磁性が同じように生じるわけではない。 冷蔵庫の磁石でネジを持ち上げられるのに、カエルでは持ち上げられないのは、強磁性常磁性の違いによるものである。 この二つ(および他のいくつかの種類)を区別するには、量子力学の議論が必要になる。

ここでは、もっとも強い現象であり、私たちが日常でもっともよく経験する強磁性に焦点を当てる。 量子レベルの理解を省くため、強磁性体の原子は隣り合う原子と磁場の向きをそろえる傾向があるということだけを受け入れることにする。 向きをそろえる傾向があるとはいえ、材質のばらつきや結晶構造などの要因によって、磁区と呼ばれる領域が生じる。

磁区の向きがばらばらだと、隣り合う磁場が互いに打ち消し合い、磁化されていない状態になる。 強い外部磁場にさらされると、これらの磁区の向きをそろえ直すことができる。 磁区の向きをそろえることで全体の磁場が強まり、磁石ができあがる。

画像提供:HyperPhysics

この向きの変化は、加えた磁場の強さによっては永続的になることがある。 これは好都合である。次のセクションで、まさにこの性質が必要になるからである。

永久磁石

永久磁石は、電磁石と同じように振る舞う。 違いは、その名のとおり永続的である点だけである。

図では、矢印はN極から出てS極へ向かう向きに描かれる。 もう一つの慣習として、赤をN極、青をS極として色分けすることもある。 磁石の極性を調べるには、方位磁針を使うとよい。 異なる極どうしが引き合うため、磁針のN極は磁石のS極を指す。

同じ実験を電磁石で行い、極性を調べることもできる。

電流の向きを逆にすると、電磁石の極性が反転する様子を確認できる。

これは、モーターを組み立てるうえで重要な原理である。 ここからは、実際にいくつかの種類のモーターを見ながら、磁石と電磁石がどのように使われているかを見ていく。

DCブラシモーター:定番の方式

DCブラシモーターは、現在使われているモーターの中でもっとも単純な部類に入る。 家電製品、おもちゃ、自動車など、あらゆる場所で見つけることができる。 構造も制御も単純なため、プロにもホビイストにも定番の選択肢となっている。

ブラシモーターの構造

仕組みを理解するために、まずは簡単なホビーモーターを分解してみよう。 見てのとおり、構造は単純で、いくつかの主要な部品からできている。

  • ブラシ:整流子を通じて、接点からアーマチュア(電機子)へ電力を伝える
  • 接点:コントローラからの電力をブラシへ伝える
  • 整流子:アーマチュアが回転するのに合わせて、適切な巻線の組へ電力を送る
  • 巻線:電気を、軸を駆動する磁場に変換する
  • :モーターの機械的な動力を、応用先の機構へ伝える
  • 磁石:巻線が引きつけたり反発したりするための磁場を提供する
  • ブッシング:軸の摩擦を抑える
  • ケース(缶):モーターの機械的な外装となる

動作の仕組み

巻線に電流が流れると、モーターの周囲にある磁石に引きつけられる。 これによってモーターが回転し、ブラシが次の整流子の接点に触れる。 この新しい接点によって別の巻線の組に電流が流れ、同じ過程が繰り返される。 モーターの回転方向を逆にするには、モーター接点の極性を入れ替えればよい。 ブラシモーターの内部で発生する火花は、ブラシが次の接点へ飛び移る際に生じるものである。 コイルの各導線は、もっとも近い二つの整流子接点に接続されている。

モーターが一定の状態で固定されてしまうのを防ぐため、巻線の数は必ず奇数にする。 大型のモーターでは、より多くの巻線の組を使うことで「コギング」を抑え、低回転数(RPM)でも滑らかな制御を実現している。 コギングは、モーターの軸を手で回してみると体感できる。磁石が露出した固定子にもっとも近づいた位置で「引っかかり」を感じるはずである。 コギングは設計上のいくつかの工夫で解消できるが、もっとも効果的なのは固定子そのものを取り除くことである。 このタイプのモーターは、鉄芯なし(コアレス)モーターと呼ばれる。

長所

  • 制御が容易
  • 低回転数でのトルクに優れる
  • 安価で大量生産に向いている

短所

  • ブラシが経年劣化する
  • ブラシの火花が電磁ノイズを発生させることがある
  • ブラシの発熱により、速度に制限がかかることが多い

ブラシレスモーター:さらなるパワー

ブラシレスモーターの勢いは止まらない、と言うと少し大げさかもしれない。 とはいえ、ブラシレスモーターは航空機から地上を走る乗り物まで、ホビー市場を席巻し始めている。 これらのモーターの制御は長らく難題だったが、マイクロコントローラが安価かつ高性能になったことで扱えるようになった。 その驚くべき可能性を引き出すため、より高速で効率的なコントローラの開発は今も進んでいる。 故障しやすいブラシがないため、これらのモーターはより大きなパワーを、しかも静かに発揮できる。 高級な家電や乗り物の多くがブラシレス方式へ移行しており、Tesla Model Sはその代表例である。

ブラシレスモーターの構造

仕組みを理解するために、まずは簡単なブラシレスモーターを分解してみよう。 これらは、ラジコン飛行機やヘリコプターでよく見られる。

  • 巻線:電気を、ロータを駆動する磁場に変換する
  • 接点:コントローラからの電力を巻線へ伝える
  • ベアリング:軸の摩擦を抑える
  • 磁石:巻線が引きつけたり反発したりするための磁場を提供する
  • :モーターの機械的な動力を、応用先の機構へ伝える

動作の仕組み

ブラシレスモーターの機構は驚くほど単純である。 唯一の可動部分は、磁石を内蔵したロータだけである。 複雑になるのは、巻線に通電する順序を制御する部分である。 それぞれの巻線の極性は、電流が流れる向きによって決まる。 上のアニメーションは、コントローラが従う単純なパターンを示している。 交流によって極性が切り替わり、それぞれの巻線に「押す・引く」の効果が生まれる。 ポイントは、このパターンをロータの回転速度と同期させ続けることである。 これを実現する広く使われている方法は二つある。 多くのホビー向けコントローラは、通電していない巻線に生じる電圧(逆起電力)を測定する。 この方法は高速回転時には非常に信頼性が高い。 モーターの回転が遅くなるほど、発生する電圧の測定が難しくなり、誤差も生じやすくなる。 より新しいホビー向けコントローラや多くの産業用コントローラは、ホール効果センサーを使って磁石の位置を直接測定する。 これは、PCファンの制御にもっともよく使われる方式である。

長所

  • 信頼性が高い
  • 高速回転が可能
  • 効率が良い
  • 大量生産されており入手しやすい

短所

  • 専用のコントローラなしでは制御が難しい
  • 始動時の負荷を小さく抑える必要がある
  • 駆動用途では専用のギアボックスが必要になることが多い

ステッピングモーター:シンプルかつ精密

ステッピングモーターは、位置制御に優れたモーターである。 デスクトップ用プリンター、プロッター、3Dプリンター、CNCフライス盤など、正確な位置制御が必要なあらゆる機器で見つけることができる。 ステッパーはブラシレスモーターの中でも特殊な部類に入り、高い保持トルクを持つように作られている。 この高い保持トルクによって、次の位置へ少しずつ「ステップ」する動作が可能になる。 その結果、エンコーダを必要としない単純な位置決めシステムが実現し、ステッピングモーター用のコントローラは非常に作りやすく、扱いやすいものになっている。

ステッピングモーターの構造

仕組みを理解するために、まずは簡単なステッピングモーターを分解してみよう。 見てのとおり、これらのモーターは直接駆動の負荷向けに作られており、いくつかの主要な部品からできている。

  • :モーターの機械的な動力を、応用先の機構へ伝える
  • ベアリング:軸の摩擦を抑える
  • 磁石:巻線が引きつけたり反発したりするための磁場を提供する
  • ポール(磁極片):磁場を集中させ、ステップの分解能を高める
  • 巻線:電気を、軸を駆動する磁場に変換する
  • 接点:コントローラからの電力を巻線へ伝える

動作の仕組み

画像提供:PCB heaven

ステッピングモーターは、ブラシレスモーターとまったく同じように振る舞うが、1ステップの角度がはるかに小さい点が異なる。 唯一の可動部分は、磁石を内蔵したロータだけである。 複雑になるのは、巻線に通電する順序を制御する部分である。 それぞれの巻線の極性は、電流が流れる向きによって決まる。 上のアニメーションは、コントローラが従う単純なパターンを示している。 交流によって極性が切り替わり、それぞれの巻線に「押す・引く」の効果が生まれる。 ステッパーで特徴的なのは、磁石の構造がブラシレスモーターとは異なる点である。 小さなスケールで磁石の配列をきれいに動作させるのは難しく、コストも高くなる。 これを避けるため、多くのステッピングモーターでは板を積み重ねる方式を使い、磁極を「歯」の形に導いている。

ブラシレスモーターでは逆起電力を使って速度を測定するが、ステッパーは各巻線への短い通電によって、想定した時刻に目的の位置へ「確実に」到達することを頼りにしている。 高速動作では、ロータがこのシーケンスに追いつけずに脱調(ストール)することがある。 これを避ける方法はあるが、モーターの巻線とインダクタンスの関係についてより深い理解が必要になる。

長所

  • 位置精度に優れる
  • 保持トルクが高い
  • 信頼性が高い
  • 多くのステッパーが標準的なサイズで手に入る

短所

  • 1ステップの角度が小さいため最高速度に制限がある
  • 大きな負荷がかかると「ステップ抜け」を起こすことがある
  • 常に最大電流を消費する

リニアモーター:これからの技術

これからの技術はリニアである。 高速のピック&プレース機では、速度がすべてを左右する。 速度が上がれば摩擦が増え、摩擦が増えればメンテナンスが必要になり、メンテナンスが発生すればダウンタイムにつながり、ダウンタイムは生産性の低下を招く。 回転運動を直線運動に変換する部品を取り除くことで、システムははるかに軽く、効率的になる。 リニアモーターはメンテナンスが容易で、可動部分が一つしかないため非常に信頼性が高い。 しかも非常に高速である。 これは、実際の製造現場で使っているピック&プレース機であり、驚くほど高速に動作する。 このマシンはとてもパワフルなため、ペースメーカーに関する警告表示まで付いている。 高出力の希土類磁石が一列に並んでいる。

リニアモーターの構造

階下にあるピック&プレース機の内部を見て、仕組みを理解してみよう。

  • モーションモジュール:電磁石とコントローラを内蔵する
  • 磁石:コイルが引きつけたり反発したりするための磁場を提供する
  • リニアベアリング:モーターを磁石と正しく整列させておく、唯一の可動部分

動作の仕組み

リニアモーターの機構は、ブラシレスモーターとほぼ同じである。 違いは、ブラシレスモーターを一直線に「展開」したものがリニアモーターだという点だけである。 唯一の可動部分はモーションモジュールである。 複雑になるのは、コイルに通電する順序を制御する部分である。 それぞれのコイルの極性は、電流が流れる向きによって決まる。 上のアニメーションは、コントローラが従う単純なパターンを示している。 交流によって極性が切り替わり、それぞれのコイルに「押す・引く」の効果が生まれる。 リニアモーターでは通常、モーションモジュールの位置を追跡するためのエンコーダや、何らかの高度な位置決めシステムが備わっている。 高い位置精度を実現するため、コントローラは従来型のシステムよりもはるかに複雑になる。 マイクロステッピングは、磁石を「絞り込んで」滑らかで精密な動作を実現する方法である。 ただし、これを実現するにはモーターごとに調整された高度に専用化されたコントローラが必要になる。 コントローラの技術が進歩するにつれ、これらのモーターの価格も下がっていくと考えられる。 いつか、3Dプリンターが時間単位ではなく秒単位で印刷できる日が来るかもしれない。

長所

  • 信頼性が高い
  • 高速動作が可能
  • 効率が良い
  • 回転運動から直線運動への変換が不要

短所

  • 高価である
  • 専用のコントローラが必要になる
  • システムごとに専用設計となる
  • (繰り返しになるが)高価である

まとめ

ここまで、いくつかの種類のモーターと、それぞれの使いどころを見てきた。 モーターを選ぶには、まず用途の要件を明確にする必要がある。 要件が定まれば、それぞれのモーターの種類の長所と短所を比較検討できる。 さらに重要なのは、それぞれのモーターの定格を確認することである。 どのモーターにも入力電力と出力電力の値が示されている。 システムの負荷要件を計算することもできるが、実際に試してみるほうが早いこともある。 モーターを組み込む作業の足がかりとして、次のようなページも参考にしてほしい。

最後に、物理学全般について学べる場所を紹介する。

タグ: 概念、モーター、技術


出典:Motors and Selecting the Right One(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

パルス幅変調(PWM)

パルス幅変調とは何か

パルス幅変調(PWM)は、ある種のデジタル信号を指す呼び名である。 パルス幅変調は、精巧な制御回路をはじめとするさまざまな用途で使われている。 SparkFunでよく使われる例は、RGB LEDの明るさを調光したり、サーボの向きを制御したりする用途である。 どちらの用途でも幅広い結果を得られるのは、パルス幅変調によって信号がハイである時間の割合をアナログ的に変化させられるからである。 信号自体はどの瞬間もハイ(たいてい5V)かロー(グラウンド)のどちらかしか取れないが、一定の時間間隔の中でハイである時間とローである時間の比率を変えることができる。

参考になるチュートリアル:

デューティ比

信号がハイのとき、これを「オン時間」と呼ぶ。 この「オン時間」の量を表すのに、デューティ比という概念を使う。 デューティ比はパーセントで表され、ある周期の中でデジタル信号がオンになっている時間の割合を示す。 この周期は、波形の周波数の逆数にあたる。

デジタル信号がオンとオフに時間を半分ずつ費やす場合、そのデューティ比は50%であるといい、理想的な矩形波に近い形になる。 50%より高い割合であれば、デジタル信号はロー状態よりハイ状態に多くの時間を費やしており、デューティ比が50%より低ければその逆になる。 次のグラフは、この3つのパターンを示したものである。

デューティ比100%は電圧を5ボルト(ハイ)に固定した状態と同じであり、デューティ比0%は信号をグラウンドに落とした状態と同じである。

応用例

デューティ比を調整することで、LEDの明るさを制御できる。

RGB(赤・緑・青)LEDを使えば、3色それぞれをさまざまな比率で調光することで、混ぜ合わせる色の割合を制御できる。

3色すべてを同じ比率で点灯させると、明るさの異なる白色光になる。 青と緑を同じ比率で混ぜるとティール(青緑)になる。 もう少し複雑な例を試すなら、赤を完全に点灯、緑をデューティ比50%、青を完全に消灯にしてみると、オレンジ色が得られる。

LEDを制御する際、正しい調光効果を得るには矩形波の周波数を十分に高くする必要がある。 1Hzでデューティ比20%の波形は、目にはオンとオフを繰り返しているのがはっきりと見えてしまう一方、100Hz以上でデューティ比20%の波形は、単に完全点灯より暗く見えるだけになる。 つまり、LEDで調光効果を狙うなら、周期を大きくしすぎないことが要点である。

パルス幅変調は、ロボットアームのような機械部品に取り付けたサーボモーターの角度を制御するのにも使える。 サーボには、制御線からの入力に応じて特定の位置まで回転するシャフトが備わっている。 SparkFunのサーボモーターは、およそ180度の可動域を持つ。

周波数や周期は、制御する個々のサーボによって決まる。 典型的なサーボモーターは20msごとに更新され、1msから2msの間のパルス幅、つまり50Hzの波形上でデューティ比5%から10%の間で駆動することを想定している。 1.5msのパルスでは、サーボは自然な位置である90度になる。 1msのパルスでは0度、2msのパルスでは180度になる。 この間の値でサーボを更新すれば、可動域全体を使うことができる。

まとめ

パルス幅変調は制御を中心にさまざまな用途で使われている。 LEDの調光やサーボモーターの角度制御に使えることはすでに紹介したので、ここからは他の使い道も探ってみてほしい。

さらに学びたい場合は、次のチュートリアルも参考にしてほしい。

タグ: 概念、電気工学、LED、光、モーター


出典:Pulse Width Modulation(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

電池とは何か

電池とは、1つ以上のセルが化学反応を起こし、回路の中に電子の流れを生み出す装置の集合体である。 すべての電池は、アノード(「-」側)、カソード(「+」側)、そして電解質(アノードやカソードと化学的に反応する物質)という3つの基本的な要素から構成される。

電池のアノードとカソードが回路に接続されると、アノードと電解質の間で化学反応が起きる。 この反応によって電子が回路を流れ、再びカソードへと戻り、そこで別の化学反応が起きる。 カソードやアノードの物質が消費され、あるいは反応にこれ以上使えなくなると、電池は電気を生み出せなくなる。 この状態が、いわゆる電池が「切れた」状態である。

使い切ったら捨てなければならない電池は一次電池と呼ばれる。 充電できる電池は二次電池と呼ばれる。

電池がなければ、クアッドコプターは壁につながれたままになり、車は手回しクランクで動かさなければならず、Xboxのコントローラーも(懐かしい時代のように)常にケーブルをつないでおく必要があっただろう。 電池は、電気的な位置エネルギーを持ち運び可能な容器に蓄える手段を提供してくれる。

現代的な電池の発明は、しばしばアレッサンドロ・ボルタの功績とされている。 実はその始まりは、カエルの解剖にまつわる意外な偶然の出来事だった。

このチュートリアルで扱う内容:

  • 電池がどのように発明されたか
  • 電池を構成する部品
  • 電池の仕組み
  • 電池を説明する際によく使われる用語
  • 回路の中で電池を使うさまざまな方法

参考になるチュートリアル:

このガイドを読み始める前に、知っておくとよい概念がいくつかある。

歴史

「バッテリー」という言葉

歴史的に、「バッテリー(battery)」という言葉は、大砲の一群(バッテリー)のように、「ある機能を果たすために似たものを一連にまとめたもの」を表すのに使われてきた。 1749年、ベンジャミン・フランクリンは、自身の電気実験のためにつなぎ合わせた一連のコンデンサを指して、初めてこの言葉を使った。 その後、この言葉は電力を供給する目的でつなぎ合わされた電気化学セルの集まり全般を指すようになった。

電池の発明

1780年のある運命的な日、イタリアの物理学者であり医師、生物学者、哲学者でもあったルイージ・ガルヴァーニは、真鍮のフックに取り付けられたカエルを解剖していた。 鉄製のメスでカエルの脚に触れると、脚がぴくりと動いた。 ガルヴァーニは、そのエネルギーは脚そのものから来ていると考えたが、彼の同僚科学者であったアレッサンドロ・ボルタはそうは考えなかった。

ボルタは、カエルの脚の反応は実際には液体に浸された異なる金属によって引き起こされていると仮説を立てた。 彼はカエルの死骸の代わりに塩水に浸した布を使って同じ実験を繰り返し、同様の電圧が得られることを確かめた。 ボルタは1791年にこの発見を発表し、その後1800年に、最初の電池であるボルタ電堆を作り上げた。

ボルタの電堆には2つの大きな問題があった。 積み重ねた重みによって電解質が布から漏れ出してしまうことと、材料の特定の化学的性質により、寿命が非常に短かった(およそ1時間程度)ことである。 その後の200年間は、ボルタの設計を改良し、これらの問題を解決することに費やされることになる。

ボルタ電堆の改良

スコットランドのウィリアム・クルックシャンクは、ボルタ電堆を横向きに寝かせることで「トラフ電池」を考案し、漏れの問題を解決した。

もうひとつの問題である短い寿命は、不純物による亜鉛の劣化と、銅の表面に水素の泡が蓄積することが原因だった。 1835年、ウィリアム・スタージャンは、亜鉛を水銀で処理することでこの劣化を防げることを発見した。

イギリスの化学者ジョン・フレデリック・ダニエルは、水素と反応する2つ目の電解質を使うことで、銅のカソード表面での水素の蓄積を防いだ。 ダニエルの2種類の電解質を使う電池は「ダニエル電池」として知られ、誕生したばかりの電信網に電力を供給する非常に普及した解決策となった。

最初の充電式電池

1859年、フランスの物理学者ガストン・プランテは、硫酸に浸した2枚の鉛のシートを丸めて使う電池を作り出した。 電池を流れる電流の向きを逆にすることで、化学的な状態を元に戻すことができ、これが最初の充電式電池となった。

その後1881年、カミーユ・アルフォンス・フォールは、鉛のシートを板状に成形することでプランテの設計を改良した。 この新しい設計により電池の製造が容易になり、鉛蓄電池は自動車で広く使われるようになった。

乾電池

1800年代後半までは、電池の電解質は液体の状態だった。 そのため電池の輸送には細心の注意が必要であり、たいていの電池は一度回路に接続したら動かすことを想定されていなかった。

1866年、ジョルジュ・ルクランシェは、亜鉛のアノード、二酸化マンガンのカソード、そして電解質として塩化アンモニウム溶液を使う電池を作った。 ルクランシェ電池の電解質はまだ液体だったが、この電池の化学方式は乾電池の発明にとって重要な一歩となった。

カール・ガスナーは、塩化アンモニウムと石膏(プラスターオブパリ)からペースト状の電解質を作る方法を編み出した。 彼は1886年、ドイツでこの新しい「乾電池」の特許を取得した。

これらの新しい乾電池は「マンガン乾電池(亜鉛-炭素電池)」と一般に呼ばれ、大量生産され、1950年代後半まで絶大な人気を誇った。 炭素は化学反応そのものには関与していないが、亜鉛-炭素電池の中で電気伝導体としての重要な役割を果たしている。

1950年代、ユニオン・カーバイド社(のちに「エバレディ」、さらに「エナジャイザー」として知られるようになる)のルイス・アーリー、ポール・マーサル、カール・コルデシュは、1899年にヴァルデマール・ユングナーが考案した電池の化学方式をもとに、塩化アンモニウムの電解質をアルカリ性の物質に置き換えた。 アルカリ乾電池は、同じ大きさのマンガン乾電池よりも多くのエネルギーを蓄えることができ、保存期間も長かった。

アルカリ電池は1960年代に人気を高め、マンガン乾電池を追い抜き、それ以来、消費者向けの標準的な一次電池となっている。

20世紀の充電式電池

1970年代、COMSATは通信衛星向けにニッケル水素電池を開発した。 この電池は、加圧された気体の状態で水素を蓄える。 国際宇宙ステーションをはじめ、多くの人工衛星が今もニッケル水素電池に頼っている。

1960年代後半から複数の企業が行ってきた研究の成果として、ニッケル水素電池(NiMH)が生まれた。 NiMH電池は1989年に消費者市場に投入され、充電式のニッケル水素セルよりも小型で安価な代替品となった。

日本の旭化成は1985年に最初のリチウムイオン電池を製作し、ソニーは1991年に最初の商用リチウムイオン電池を作り出した。 1990年代後半には、リチウムイオン電池向けに柔らかく柔軟な外装が開発され、これが「リチウムポリマー」あるいは「LiPo」電池の誕生につながった。

もちろん、これ以外にも実に多くの電池の化学方式が発明され、製造され、そして時代遅れになっていった。 現代の主流となっている電池の技術についてさらに読みたい場合は、電池の技術のチュートリアルを確認してほしい。

構成要素

電池はアノードカソード電解質という3つの基本的な要素で構成されている。 電解質だけでは不十分な場合、アノードとカソードが接触しないようにするためにセパレータが使われることも多い。 これらの構成要素を収めるため、電池にはたいてい何らかの外装がある。

アノードとカソードはどちらも電極の一種である。 電極とは、回路の中の部品に電気が出入りする際に通る導体のことである。

アノード

回路に接続された機器の中では、電子はアノードから外へ流れ出る。 つまり、従来の意味での「電流」はアノードへ流れ込むということである。

電池の中では、アノードと電解質の間の化学反応によって、アノードに電子が蓄積される。 これらの電子はカソードへ移動したがるが、電解質やセパレータを通り抜けることはできない。

カソード

回路に接続された機器の中では、電子はカソードへ流れ込む。 つまり、従来の意味での「電流」はカソードから流れ出るということである。

電池の中では、カソードの内部や周辺で起きる化学反応が、アノードで生み出された電子を消費する。 電子がカソードに到達する唯一の経路は、電池の外部にある回路を通ることである。

電解質

電解質とは、たいてい液体やゲル状の物質で、アノードとカソードでそれぞれ起きる化学反応の間でイオンを運ぶことができる。 また電解質は、アノードとカソードの間を電子が直接流れるのを妨げる役割も持っており、そのおかげで電子は電解質の中ではなく外部の回路を通って流れやすくなっている。

電解質は電池の動作にとって非常に重要である。 電子は電解質を通り抜けられないため、アノードとカソードをつなぐ回路という形の電気的な導体を通らざるを得なくなる。

セパレータ

セパレータは、アノードとカソードが接触して電池内で短絡(ショート)が起きるのを防ぐ、多孔質の素材である。 セパレータには、綿、ナイロン、ポリエステル、厚紙、合成ポリマーフィルムなど、さまざまな素材が使われる。 セパレータは、アノード、カソード、電解質のいずれとも化学的に反応しない。

電解質中のイオンは正に帯電しているものも負に帯電しているものもあり、大きさもさまざまである。 特定のイオンだけを通し、他は通さないように作られた専用のセパレータも存在する。

外装

たいていの電池には、内部の化学成分を封じ込めておく何らかの方法が必要である。 外装は「ハウジング」や「シェル」とも呼ばれ、電池の内部構造を保持するための単純な機械的構造にすぎない。

電池の外装には、プラスチック、鋼鉄、柔らかいポリマーラミネートのパウチなど、ほぼどんな素材でも使うことができる。 一部の電池は、いずれかの電極に電気的に接続された導電性の鋼鉄製外装を使っている。 一般的な単3形アルカリ電池の場合、鋼鉄製の外装はカソードに接続されている。

動作の仕組み

電池が動作するには、たいてい複数の化学反応が必要である。 少なくとも1つの反応がアノードの内部または周辺で起こり、1つ以上の反応がカソードの内部または周辺で起こる。 いずれの場合も、アノードでの反応は酸化と呼ばれる過程で余分な電子を生み出し、カソードでの反応は還元と呼ばれる過程でその余分な電子を消費する。

つまり本質的には、ある種の化学反応、すなわち還元酸化反応(レドックス反応)を2つの部分に分離しているのである。 レドックス反応は、化学物質の間で電子が移動する際に起こる。 この反応における電子の動きを、電池の外へと導くことで、私たちは回路に電力を供給することができる。

アノードでの酸化

レドックス反応の最初の部分である酸化は、アノードと電解質の間で起こり、電子(e-と表記される)を生み出す。

酸化反応の中には、リチウムイオン電池のようにイオンを生み出すものもあれば、一般的なアルカリ電池のようにイオンを消費するものもある。 いずれの場合も、イオンは電子が通れない電解質の中を自由に移動できる。

カソードでの還元

レドックス反応のもう半分である還元は、カソードの内部または周辺で起こる。 酸化反応によって生み出された電子は、還元の過程で消費される。

リチウムイオン電池のように、酸化反応によって生じた正に帯電したリチウムイオンが還元の過程で消費される場合もあれば、アルカリ電池のように、還元の過程で負に帯電したイオンが生み出される場合もある。

電子の流れ

たいていの電池では、回路に接続されていない状態でも、一部またはすべての化学反応が起こりうる。 これらの反応は、電池の保存期間に影響を与えることがある。

たいていの場合、これらの反応が最大の勢いで進むのは、アノードとカソードの間で電気を通す回路が完成しているときだけである。 アノードとカソードの間の抵抗が小さいほど、より多くの電子が流れることができ、化学反応もより速く進む。

これは、電池内で短絡(意図しないものも含む)を起こすことが、いかに危険であるかを示している。 リチウムイオン電池は、短絡が起きると過熱し、煙を出したり発火したりすることが知られている。

このように動いている電子を、「負荷」と呼ばれるさまざまな電気部品に通すことで、私たちは何か役に立つことを実現できる。

電池切れ

電池内の化学物質は、最終的に平衡状態に達する。 この状態になると、化学物質はもはや反応しようとしなくなり、その結果、電池はそれ以上電流を生み出せなくなる。 この時点で、電池は「切れた」と見なされる。

一次電池は、切れたら廃棄しなければならない。 二次電池は、電池に逆方向の電流を流すことで充電できる。 充電は、化学物質が一連の反応を経て元の状態に戻ることによって行われる。

用語集

電池の電圧、容量、電流供給能力などについて語るとき、よく使われる共通の用語がある。

セル

セルとは、電解質によって隔てられた1組のアノードとカソードのことで、電圧と電流を生み出すために使われる。 電池は1つ以上のセルから構成される。 たとえば単3形電池1本は1つのセルである。 自動車用バッテリーは、それぞれ2.1Vの6個のセルを含んでいる。

一次電池

一次電池は、元に戻すことのできない化学反応を利用している。 そのため、電池が切れたら廃棄しなければならない。

二次電池

二次電池は充電することができ、化学的な状態を元に戻すことができる。 「充電式電池」とも呼ばれ、これらのセルは何度も使うことができる。

公称電圧

電池の公称電圧とは、メーカーが表示している電圧のことである。

たとえば、アルカリ単3形電池は1.5Vと表示されている。 実際にテストされたアルカリ電池は、およそ1.55Vから始まり、放電が進むにつれて徐々に電圧が下がっていくことが分かっている。 この例では、「1.5V」という公称電圧は、電池の最大電圧、つまり使い始めの電圧を指している。

一方、クアッドコプター用のあるLiPoバッテリーパックでは、放電曲線がおよそ4.2Vから始まり、放電が進むにつれておよそ2.8Vまで下がっていくことが示されている。 たいていのリチウムイオン電池やLiPo電池に表示されている公称電圧は3.7Vである。 この場合、「3.7V」という公称電圧は、放電サイクル全体を通じた電池の平均電圧を指している。

容量

電池の容量とは、特定の電圧でその電池が供給できる電荷の量を示す指標である。 たいていの電池は、アンペア時(Ah)またはミリアンペア時(mAh)で定格が示される。

たいていの電池の放電グラフは、電圧を容量の関数として示している。 自分の回路に十分な容量の電池かどうかを判断するには、許容できる最低電圧を見つけ、それに対応するmAhまたはAhの定格を確認するとよい。

Cレート

多くの電池、特に高出力なリチウムイオン電池では、電池の特性をより明確に示すため、放電電流を「Cレート」として表す。 Cレートとは、電池の最大容量に対する放電速度の比率である。

1Cとは、電池を1時間で放電しきるのに必要な電流量である。 たとえば、400mAhの電池が1Cの電流を供給する場合、それは400mAを意味する。 同じ電池での5Cは2Aになる。

たいていの電池は、大きな電流を取り出すほど容量が減少する。

Note

一般的な助言として、LiPo電池は1C以下で充電すべきとされている。

MITには、この概要よりもさらに踏み込んだ、電池の仕様と用語についての優れたガイドがある。

使い方

単セル

一部の回路は単セルの電池だけで動かせるが、その電池が十分な電圧と電流を供給できることを確認しておこう。

電圧が回路にとって高すぎる、あるいは低すぎる場合は、たいていDC/DCコンバータが必要になる。

直列

電池の端子間の電圧を高めるには、セルを直列に接続するとよい。 直列とは、セルを端から端へと積み重ね、あるセルのアノードを次のセルのカソードに接続することを意味する。

電池を直列に接続すると、合計の電圧が増加する。 動作電圧を求めるには、すべてのセルの電圧を足し合わせればよい。 容量は変わらない。

アルカリ電池を使うたいていの消費者向け電子機器では、電池は直列に積み重ねられている。 たとえば、単3形電池2本用のホルダーを使えば、プロジェクトの公称電圧を3Vまで高めることができる。

Note

リチウムイオン電池やLiPo電池を直列に接続して充電する場合は、セル間の電圧を均等に保つため、「バランサー」と呼ばれる専用の回路を必ず使う必要がある。バランサーを内蔵し、安全な充電を可能にする充電器もある。

並列

単セルの電圧が負荷にとって十分であれば、電池を並列に追加することで容量を増やすことができる。 これは同時に、取り出せる電流(Cレート)も増加させることに注意してほしい。

電池を並列に接続する際は注意が必要である。 すべてのセルは同じ公称電圧、同じ充電レベルでなければならない。 電圧に差があると、短絡が起きて過熱し、最悪の場合は発火する可能性がある。

直列と並列の組み合わせ

電圧と容量の両方を増やしたい場合は、直列と並列を組み合わせることができる。 この場合も、短絡を防ぐため、並列に接続する電池どうしの電圧レベルが同じであることを必ず確認すること。

特にリチウムイオン電池を使った大型のバッテリーパックでは、直列と並列の構成を「S」と「P」を使って表すことがよくある。 上の回路の構成は2S2Pである。 実際の例として、現代の電気自動車は、直列と並列に接続された膨大な数の電池群を使っている。

まとめ

これで、電池がどのように発明され、どのように動作するかについて理解できたはずである。 電池はプロジェクトに電気エネルギーを供給する方法のひとつであり、持ち運び可能な電源が必要な場合には非常に役立つ。

電池についてさらに詳しく知りたい場合は、次のようなチュートリアルも参考になる。

タグ: 概念、電気工学、電力


出典:What is a Battery?(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

電池の技術

電池の技術には実に多くの種類がある。 電池の化学的な仕組みの細かい話については、優れた資料がすでにたくさんある。 特にWikipediaの「電池」のページは充実しており、網羅的である。 このチュートリアルでは、組み込みシステムやDIYの電子工作でよく使われる電池に焦点を当てる。

参考になるチュートリアル:

用語

電池について語るときによく使われる用語をいくつか紹介する。

容量:電池には、どれだけの電力を蓄えられるかを示す定格がある。 電池が満充電のとき、その容量がその電池に蓄えられている電力量にあたる。 同じ種類の電池どうしは、時間あたりに出力できる電流量で定格を表すことが多い。 たとえば1000mAh(ミリアンペア時)や2000mAhの電池がある。

公称セル電圧:充電されたセルが出力する平均的な電圧である。 電池の公称電圧は、その背後にある化学反応によって決まる。 鉛蓄電池を使った自動車用バッテリーは12Vを出力し、リチウムコイン電池は3Vを出力する。

ここで重要なのは「公称」という言葉である。 実際に測定される電圧は、放電が進むにつれて下がっていく。 満充電のLiPo電池はおよそ4.23Vを出力するが、放電しきった状態ではおよそ2.7V程度まで下がることがある。

形状:電池にはさまざまな大きさや形がある。 「単3形」という呼び方は、特定の形状と規格のセルを指す。 形状には非常に多くの種類がある

一次電池と二次電池:一次電池は使い切りの電池とほぼ同じ意味である。 一次電池は一度完全に使い切ると、(安全かつ確実には)再充電できない。 二次電池は充電式の電池としてよく知られている。 満充電にするには別の電源が必要になるが、寿命が尽きるまで何度も充放電を繰り返せる。 一般に一次電池は放電速度が遅く長持ちするが、充電式の電池ほど経済的でないこともある。

電池の形状化学的方式公称電圧充電式か
単3、単4、単2、単1形アルカリまたはマンガン1.5Vいいえ
9V形アルカリまたはマンガン9Vいいえ
コイン電池リチウム3Vいいえ
シルバーフラットパックリチウムポリマー(LiPo)3.7Vはい
単3、単4、単2、単1形(充電式)ニッケル水素またはニッケルカドミウム1.2Vはい
自動車用バッテリー6セル鉛蓄電池12.6Vはい

エネルギー密度:電池の容量と、形状や大きさを組み合わせることで、エネルギー密度を計算できる。 技術によって実現できる密度は異なり、たとえばリチウム系の電池は、アルカリ電池やコイン電池に比べて同じ体積でより多くのエネルギーを詰め込めることが多い。

自己放電率:6か月放置していた車のエンジンをかけようとしたことはないだろうか。 電池は、棚に置いたまま使わずにいても放電していく。 時間の経過とともに電池自身が放電していく速さを、自己放電率と呼ぶ。

安全性:電池はエネルギーを蓄えているため、基本的にはごく小さな爆発物のようなものである。 危害を防ぐため、電池はできる限り安全に設計されている。 たいていの電池技術は、誤った使い方をされた場合でも安全に放電するように設計されている。 アルカリ電池を間違った向きに接続すると、熱くなることはあっても、発火することはないはずである。 たいていのリチウムポリマー電池には、電池を保護し、危険な使い方を防ぐための保護回路が内蔵されている。

用語の一覧や技術的な概要については、Wikipediaが優れた資料)になる。

リチウムポリマー

リチウムポリマー(LiPoと略されることが多い)電池は、組み込み電子工作にとって非常に有用な電池である。 市場で手に入るものの中でも最高水準のエネルギー密度を持つ。 携帯電話の多くにこのタイプの電池が使われているため、手頃な価格で入手しやすい。 専用の充電が必要なので、必ず適切な充電器を使うこと。 SparkFunでは3.7Vのリチウムポリマーバッテリーをさまざまなサイズで扱っている。 どの容量を選ぶかは、プロジェクトの想定稼働時間やサイズの制約など、さまざまな要因によって決まる。

公称電圧

LiPoの1セルの公称電圧は3.7Vである。 満充電時には4.3V近くまで達するが、通常の使用ではすぐに3.7Vまで下がる。 使い切った状態では、セルの電圧はおよそ3V程度になる。 つまり、セルから直接電源を取るプロジェクトでは、さまざまな電圧に対応できる設計にする必要がある。 5Vが必要な場合は、2本のLiPoを直列につないで7.4Vのパックを作り、そこから5Vまで降圧する必要がある。

コネクタ

小型電子機器の世界では、たいていのLiPo電池は何らかの2ピンコネクタで終端されている。 SparkFunではJSTコネクタを採用している。 これにより、電池を間違った向きに接続してしまうことを防げる。 このコネクタは摩擦だけで固定されているため、電池を取り外すときはペンチなどを使って優しく引き抜くのが一般的である。

充電と放電

LiPo電池を充電するための安価な充電器は数多く販売されている。 たいていUSB経由で充電する。 専用の充電器なしでLiPo電池を充電しようとしてはいけない。 LiPo電池は過充電によって傷んでしまうことがあるので、必ずLiPo専用に設計された充電器を使うこと。

リチウムイオン電池を充電する前に、電池の容量と、充電器が供給する充電電流を必ず確認しておくこと。

LiPo電池は、放電しすぎることでも傷んでしまう。 これを防ぐため、ほとんどのLiPo電池にはセルの上部に小さな安全回路が内蔵されており、電圧が一定のしきい値(たいてい3V)を下回ると電池を遮断するようになっている。 この保護回路の基板は、たいてい配線が接続されている黄色いカプトンテープの下に隠れている。

LiPo電池は自己放電率が非常に低い。 そのため、消費電力が少なく、何日も、あるいは何か月も動作させ続ける必要があるプロジェクトに適している。

エネルギー密度には注意すること: これらの電池は大きな力を秘めており、連続して数アンペアもの電流を供給できる。 ショート保護機能はショートを検知すると電池を遮断してくれるが、これらの電池を使うプロジェクトでは常識的な注意を払うべきである。

Note

メーカーが提供するデータシートの中には、定格容量を「C 5 A」のような単位で表記しているものがある。 これはLiPo電池の測定に使われる標準的な表記であり、たとえば850mAhのLiPo電池が「0.2C 5 A」という定格容量を持つ場合、これは容量850mAに0.2を掛けた電流を、5時間にわたって流し続けたときの値であることを示している。 この電流値を負荷にかけ続け、その時間内に電池の電圧が最低値に達するかどうかを見て容量を測定している。

ほぼすべての携帯用途において、LiPoをおすすめする。 そこそこ頑丈であり、安全に使えば優れた電源になる。

その他の種類のリチウムイオン電池

円筒形の大容量リチウムイオン電池

この種の電池は主に懐中電灯用途で使われてきたが、扱いやすく取り付けも簡単で、大きな電力を蓄えられる。

  • 公称電圧:これらの電池も3.7Vの公称電圧を持つが、平型のLiPo電池とは異なり、これらの円筒形セルには保護回路が内蔵されていない。傷めないようにするには、充放電時に特別な注意が必要である。
  • コネクタ:専用の電池ホルダーを使えば、プロジェクトに簡単に組み込める。
  • 充電と放電:これらの電池には保護回路がないため、過充電や過放電によって電池が傷まないよう、使う側が注意する必要がある。汎用の充電器を使うことをおすすめする。

高放電リチウムイオン電池

高放電リチウムイオン電池は、大きな力を必要とする小型のR/C、ロボット、携帯用プロジェクトの電源として優れている。

  • 公称電圧:これらは7.4Vの公称電圧を持ち、円筒形セルと同様に保護回路は内蔵されていない。傷めないようにするには、充放電時に特別な注意が必要である。
  • コネクタ:充電用コネクタは3ピンのJST-XHプラグである。放電にはディーンズコネクタのリード線を使う。
  • 充電と放電:これらの電池には保護回路がないため、過充電や過放電によって電池が傷まないよう、使う側が注意する必要がある。たいてい2セル構成のパックであるため、専用の充電器が必要であり、単セル用の充電器は使えない。専用の充電器の使用をおすすめする。

ニッケル水素

ニッケル水素(NiMHと略されることが多い)電池は、実績のある充電式の技術である。 他の化学方式に比べて安価なことが多いが、LiPoに比べるとエネルギー密度で劣る。 NiMH電池は充電カーブがそれほど厳密でなくてよいため、充電器のコストも抑えられる。 NiMHは、出力電圧がそれほど重要でない電動歯ブラシやコードレスシェーバーのような、比較的安価な電子機器でよく使われている(電池が減ってくると歯ブラシの動きが遅くなるが、それでも動き続けるのに気づくだろう)。

それぞれのセルは公称1.2Vを出力する。 これは、同じサイズで1.5Vを出力するアルカリ電池とよく似ている。 単3形のNiMHを4本組み合わせれば4.8Vのパックになり、たいていの5V系システムを動かせるが、放電が進むにつれて電圧は下がっていく。

充電と放電

NiMH電池自体には放電保護回路が内蔵されていない。 放電保護回路は、電池が一定の電圧を下回って放電するのを防ぎ、電池が傷むのを防ぐ役割を持つ。

一般的な消費者向け電池とよく似た性質を持つことから、NiMH電池の充電には壁のコンセントに直接差し込むタイプの充電器がよく使われる。 すでに単3形の電池を使う前提で設計された機器には、NiMHをおすすめする。

コイン電池

コイン電池は、非常に小型で消費電力の少ないプロジェクトに適している。 安価であり、大量に必要なら、まとめ買いするとよい。 LEDのテストにも重宝する。 リモコン電子キャンドルなど、多くの使い捨て小型機器の内部にこのタイプの電池が隠れているのを見つけられるだろう。

これらの電池は充電できない。 複雑な仕組みを持つ充電可能なバージョンも一部にはあるが、コイン電池の大半は使い切ったら捨てることを前提としている。

コイン電池を支える化学的方式や技術はさまざまである。 アルカリ系のものもあれば、リチウム系のものもある。 アルカリ系のコイン電池の公称電圧は1.5Vであり、リチウム系のコイン電池の公称電圧は3Vである。

コイン電池にはいくつかのサイズがあり、それぞれサイズと化学方式を示す専用のコード名が付けられている。 アルカリ系のコイン電池はすべて「L」で始まり、リチウム系のコイン電池はすべて「C」で始まる。 たとえば人気のCR2032はリチウム電池(公称3V)で、直径20mm、厚さ3.2mmである。 LR1154(LR44とも呼ばれる)はアルカリ電池(1.5V)で、直径11mm、厚さ5.4mmである。

コイン電池は、ATtinyのような小型マイコンとLEDを使ったプロジェクトの電源にも適している。

アルカリ電池

私たちは皆、この使い切りタイプの電池とともに育ってきた。 何十年も前から存在するため、どこでも見つかる。 単3形や9V形の電池ホルダーやアクセサリーも数多くある。

これらの電池は安価で、安全に使え、どこでも手に入るが、残念ながら充電はできない。 アルカリという化学方式のおかげで、これらの電池は特に扱いを間違えにくい(安全な)設計になっている。

単3形と単4形がもっとも一般的なアルカリ電池であり、公称1.2Vを出力する(使い始めはおよそ1.5V程度になる)。 単3形は1.2Vしか出力しないため、3.3Vや5V系のシステムを動かすには3本または4本を組み合わせる必要がある。 9V形の電池は、当然ながら公称9Vである。

接続ケーブル付きの9V電池は、プロジェクトを手早く携帯用にするのに優れた方法だが、あまり長持ちするとは期待しないほうがよい。 9Vを出力するとはいえ、9V電池の容量自体はかなり小さい。

私たちは初心者向けにこのタイプの電池をよく使っている。 初心者はこの種の電池に慣れており、簡単に手に入れられることが多い。 電池を逆向きに取り付けてしまっても、熱くなる程度でほとんど問題は起きない。 基礎を身につけた生徒には、より長持ちし、充電もできるLiPoへの移行を勧めることが多い。

まとめ

電池の技術について少し詳しくなったところで、次のような関連するチュートリアルやプロジェクトも確認してみてほしい。

  • コネクタの基礎:コネクタは、電子工作を始めたばかりの人にとって混乱のもとになりやすい。さまざまな選択肢や用語、名称があるため、必要なものを選んだり見つけたりするのは大変である。このチュートリアルで、コネクタの世界への足がかりをつかめる。
  • How to Power a Project(プロジェクトへの電源供給):プロジェクトに必要な電源の条件を見極める手助けになるチュートリアルである。
  • テスターの使い方:テスターを使って導通、電圧、抵抗、電流を測定する基本を学べる。

タグ: 部品、電気工学、電力、技術


出典:Battery Technologies(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

加速度センサーの基礎

加速度センサー(アクセロメータ)とは、物体の速度がどれだけの割合で変化しているかを表す加速度を測定する装置である。 単位は毎秒毎秒メートル(m/s²)、あるいはG(重力加速度)で表される。 地球上での1Gは9.8m/s²に相当するが、これは標高によってわずかに変化する(また、重力の強さが異なる他の惑星では値も変わってくる)。 加速度センサーは、システムの振動を検知したり、姿勢を検出したりする用途に役立つ。

参考になるチュートリアル:

以下の話題に馴染みがなければ、加速度センサーに進む前に目を通しておくとよい。

加速度センサーの仕組み

加速度センサーは、静的または動的な加速度の力を検知する電気機械式の装置である。 静的な力には重力があり、動的な力には振動や動きなどがある。

加速度センサーは1軸、2軸、あるいは3軸の加速度を測定できる。 開発コストが下がるにつれて、3軸タイプが一般的になりつつある。

一般に、加速度センサーは内部に静電容量式のプレートを持っている。 一部のプレートは固定されており、他のプレートは非常に小さなバネに取り付けられ、加速度の力がセンサーに加わると内部で動くようになっている。 これらのプレートが互いに動くと、その間の静電容量が変化する。 この静電容量の変化から、加速度を求めることができる。

このほかに、圧電材料を中心に構成された加速度センサーもある。 これらの小さな結晶構造は、機械的な力(加速度など)が加わると電荷を出力する。

加速度センサーの接続方法

たいていの加速度センサーでは、動作に必要な基本的な接続は電源と通信線である。 いつものように、正しく接続するためにデータシートを確認すること。

通信インターフェース

加速度センサーは、アナログ、デジタル、あるいはパルス幅変調のいずれかの接続インターフェースで通信する。

  • アナログ:アナログインターフェースを持つ加速度センサーは、電圧レベルの変化を通じて加速度を示す。この値はたいてい、グラウンドと供給電圧の間で変動する。マイクロコントローラのADCを使えば、この値を読み取ることができる。これらはたいてい、デジタル式の加速度センサーよりも安価である。
  • デジタル:デジタルインターフェースを持つ加速度センサーは、SPIまたはI2Cの通信プロトコルで通信する。これらはたいてい、アナログ式の加速度センサーよりも機能が豊富で、ノイズの影響を受けにくい。
  • パルス幅変調(PWM):パルス幅変調でデータを出力する加速度センサーは、周期は一定だが、加速度の変化に応じてデューティ比が変化する矩形波を出力する。

電源

加速度センサーは一般に低消費電力の装置である。 必要な電流はたいていマイクロ(µ)アンペアからミリアンペアの範囲に収まり、供給電圧は5V以下であることが多い。 消費電流は設定(省電力モードか通常動作モードかなど)によって変わる。 こうした複数の動作モードがあることから、加速度センサーは電池駆動の用途にも適している。

特にデジタルインターフェースを使う場合は、適切なロジックレベルが一致しているかを必ず確認すること。

加速度センサーの選び方

どの加速度センサーを使うかを選ぶ際には、先に述べた消費電力や通信インターフェースをはじめ、いくつかの重要な特徴を考慮する必要がある。 このほかに考慮すべき特徴を以下に挙げる。

測定範囲

たいていの加速度センサーには、測定できる力の範囲を選択できるようになっている。 この範囲は±1gから±250gまでさまざまである。 一般に、範囲が小さいほど、加速度センサーの読み取り値の感度は高くなる。 たとえば、テーブルの上の小さな振動を測定したい場合、250gレンジ(ロケットの測定などに向いている)よりも、小さいレンジの加速度センサーを使うほうが詳細なデータが得られる。

そのほかの機能

加速度センサーの中には、タップ検出(低消費電力用途に便利)、自由落下検出(ハードディスクの衝撃保護機能に使われる)、温度補償(デッドレコニングの精度向上に役立つ)、0g検出といった機能を備えたものもあり、購入時に考慮すべき点となる。 こうした機能が必要かどうかは、加速度センサーを組み込むアプリケーションの用途によって決まる。

また、加速度センサーだけでなく、ジャイロセンサー、さらには磁力センサーまでも1つのICパッケージや基板にまとめたIMU(慣性計測装置)というものもある。 その例として、MPU6050やMPU9150が挙げられる。 これらは、物体の位置や姿勢が重要になるモーショントラッキングの用途や、UAV(無人航空機)の誘導システムなどでよく使われている。

まとめ

これで、自分のプロジェクトに加速度センサーを組み込むために必要な基本的な道具とスキルが身についたはずである。

加速度センサーについてさらに学びたいなら、次のようなチュートリアルも確認してみてほしい(いずれも英語)。

タグ: 概念、モーション、センサー、技術


出典:Accelerometer Basics(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

ジャイロスコープとは何か

ジャイロスコープ(略してジャイロ)とは、回転運動を測定したり、維持したりする装置である。 MEMS(微小電気機械システム)ジャイロは、角速度を測定する小型で安価なセンサーである。 角速度の単位は、1秒あたりの角度(°/s)や1秒あたりの回転数(RPS)で表される。 角速度とは、単純に回転の速さを測ったものである。

ブレイクアウトボードに搭載されたLPY503ジャイロ。

上の写真のようなジャイロは、姿勢を判断するために使われ、ほとんどの自律航法システムに搭載されている。 たとえばロボットのバランスを取りたい場合、ジャイロスコープを使ってバランスの取れた姿勢からの回転を測定し、モーターへ補正指令を送ることができる。 SparkFunのカタログにある、いくつかの製品も確認してみてほしい。

このチュートリアルで扱う概念

このチュートリアルを読み進める前に、なじみのない概念があれば、次のトピックに目を通しておくとよい。

ジャイロの仕組み

物体がある軸を中心に回転しているとき、それには角速度と呼ばれる量がある。 回転する車輪は、1秒あたりの回転数(RPS)や1秒あたりの角度(°/s)で測定できる。

以下のジャイロのz軸が、車輪の回転軸と一致していることに注目してほしい。

上の図のようにセンサーを車輪に取り付ければ、ジャイロのz軸まわりの角速度を測定できる。 他の2つの軸では回転は測定されない。

車輪が1秒間に1回転すると想像してみよう。 その角速度は1秒あたり360度になる。 車輪の回転方向も重要な要素である。軸を中心に時計回りなのか、反時計回りなのかということである。

上の図に写っているような3軸のMEMSジャイロスコープ(ITG-3200など)は、x軸、y軸、z軸という3つの軸まわりの回転を測定できる。 ジャイロには単軸や2軸のものもあるが、1つのチップに収まった3軸ジャイロは、年々小型化と低価格化が進み、普及しつつある。

ジャイロは、それほど速く回転していない物体にもよく使われる。 航空機は(願わくば)回転はしないが、代わりに各軸でわずかに数度ずつ姿勢が傾く。 ジャイロはこのようなわずかな変化を検知することで、航空機の飛行を安定させる助けになる。 また、航空機の加速度や直線方向の速度は、ジャイロの測定値に影響しないことにも注意してほしい。 ジャイロが測定するのは、あくまで角速度だけである。

では、MEMSジャイロは、どうやって角速度を検知しているのだろうか。

MEMSジャイロセンサーの内部の動作を示した図。

MEMSの中にあるジャイロスコープのセンサーは非常に小さく(1〜100マイクロメートル程度で、人間の髪の毛ほどの大きさである)。 ジャイロが回転すると、角速度の変化に応じて、内部の小さな共振質量体(レゾネーター)がわずかに動く。 この動きは非常に微弱な電流の電気信号に変換され、増幅されてホストのマイコンによって読み取られる。

ジャイロの接続方法

ジャイロを使うために必要な主なハードウェア接続は、電源通信インターフェースである。 仕様や接続例についての詳しい情報は、必ずセンサーのデータシートを参照してほしい。

通信インターフェース

ジャイロにはデジタルインターフェースとアナログインターフェースのいずれかが搭載されている。

デジタルインターフェースを持つジャイロは、通常SPIまたはI2C通信プロトコルのいずれかを使用する。 これらのインターフェースを使えば、ホストのマイコンに簡単に接続できる。 デジタルインターフェースの制約の1つが、最大サンプルレートである。 I2Cの最大サンプルレートは400Hzである。 一方でSPIは、はるかに高いサンプルレートを実現できる。

アナログインターフェースを持つジャイロは、回転速度を、通常はグラウンドと供給電圧の間で変化する電圧として表す。 マイコンのADCを使えば、この信号を読み取ることができる。 アナログジャイロは、アナログ信号の読み取り方によっては、より安価で、時にはより高精度になることもある。

電源

MEMSジャイロは、一般に低消費電力の部品である。 動作電流はmA、時にはμAのオーダーである。 ジャイロの供給電圧は、通常5V以下である。 デジタルジャイロには、ロジック電圧を選択できるものや、供給電圧のまま動作するものがある。 デジタルインターフェースを使う場合は、必ず5Vラインどうし、3.3Vラインどうしを接続するようにすること。 また、デジタルインターフェースを持つジャイロには低消費電力モードやスリープモードが備わっているものがあり、バッテリー駆動のアプリケーションで使いやすくなっている。 これは、アナログジャイロに対する利点になることがある。

ジャイロの選び方

どの種類のジャイロを使うべきかを判断する際に考慮すべき仕様は数多くある。 ここでは、特に重要でよく使われるものをいくつか紹介する。

レンジ(測定範囲)

測定範囲、つまりフルスケールレンジとは、そのジャイロが読み取れる最大の角速度のことである。 自分が何を測定したいのかを考えてみてほしい。 レコードプレーヤーのような非常に遅い回転を測定したいのか、それとも非常に速く回転する車輪を測定したいのか、ということである。

感度

感度は、1秒あたりの角度に対するmV数(mV/°/s)で表される。 この見慣れない単位に戸惑う必要はない。 これは、与えられた角速度に対して出力電圧がどれだけ変化するかを示す値である。 たとえば、あるジャイロの感度が30mV/°/sと指定されており、出力に300mVの変化が見られた場合、そのジャイロは10°/sで回転させられたことになる。

覚えておくとよい原則がある。感度が上がるほど、レンジは狭くなる。 たとえば、LPY503ジャイロのデータシートや、レンジを選択できる他のジャイロのデータシートを見てみるとよい。

レンジが大きくなるほど感度は低下し、得られる分解能も小さくなることが分かる。

バイアス

どんなセンサーでも、測定値にはある程度の誤差やバイアスが含まれる。 ジャイロが静止しているときの出力を測定すれば、このバイアスを確認できる。 静止しているときは0°が出力されると思うかもしれないが、実際には常にわずかにゼロからずれた誤差が出力される。 この誤差は、バイアスドリフトやバイアス不安定性と呼ばれることもある。 センサーの温度は、このバイアスに大きな影響を与える。 この誤差の原因を最小限に抑えるため、ほとんどのジャイロには温度センサーが内蔵されている。 これにより、センサーの温度を読み取り、温度に依存する変化を補正できるようになっている。 こうした誤差を補正するには、ジャイロを較正する必要がある。 これは通常、ジャイロを静止させた状態にして、コード上ですべての読み取り値をゼロ点に合わせることで行われる。

さらに学ぶために

ここまで読めば、ジャイロの仕組みが理解でき、自分のプロジェクトでジャイロを使い始めるための土台ができたはずである。

ジャイロを使った次のようなチュートリアルも確認してみてほしい(いずれも英語)。

  • Analog Gyro + Arduino(アナログジャイロとArduino)
  • Gyro Buying Guide(ジャイロの選び方ガイド)
  • Balancing Robot(バランスを取るロボット)

タグ: 概念、センサー、技術


出典:Gyroscope(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

RFID基礎

はじめに

数か月前、近所の図書館でキオスク端末に本を置くだけで、5冊すべての貸し出し手続きができたことがある。 同じ頃、父は5万人以上が参加するBolder Boulderというロードレースに出場した。 このレースでは、電子システムがランナーに紙のゼッケンを着けさせるだけで、父を含む数千人のタイムを記録していた。 迷子になったペットも、首元をスキャンするだけで身元を特定し、飼い主のもとへ返すことができる。 これらは、いったいどのようにして実現しているのだろうか。

その答えがRFIDRadio Frequency IDentification、無線周波数識別)である。 このチュートリアルでは、RFIDがどのように機能するかという基礎を扱い、RFIDを使い始めるための手引きとする。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。RFIDの基本的な理解に役立つはずである。

基礎知識

基本的な仕組み

リーダーモジュールの中に、X線の目を持ったごく小さいハムスターが入っている、と考えたくなるかもしれないが、実際の仕組みはもう少し単純である。

RFIDは、リーダーが発する電波を使って、RFIDタグの存在を検出し、そこに記録されたデータを読み取る。 タグはカードやボタン型のケース小さなカプセルのような小型の物体に埋め込まれている。

画像提供:EPC RFID

一部のシステムでは、これらのリーダーが電波を使ってタグに新しい情報を書き込むこともできる。

RFIDシステムの種類

RFIDシステムには、パッシブ(受動型)とアクティブ(能動型)の2種類がある。 どちらの方式かは、タグの電源のとり方によって決まる。

パッシブ

パッシブ型のRFIDシステムでは、タグは電池を使わない。 その代わり、動作に必要なエネルギーをリーダーから受け取る。 リーダーは数フィート程度の範囲にエネルギー場を発生させ、その範囲内にあるタグすべてにエネルギーを供給する。 タグはカードリーダーから電磁エネルギーを集めて起動し、「こんにちは」と自分の識別情報を返す。

パッシブタグには、高速(1秒間に10回以上)で読み取れるという利点がある。 非常に薄いため紙の層の間に挟むこともでき、非常に安価である(1万個以上の単位で1個0.05ドル未満)。

一般に、タグが小さいほど読み取り可能な距離は短くなる。

アクティブ

アクティブ型のRFIDシステムでは、タグが読み取り距離を伸ばすための独自の電源を内蔵している。 アクティブタグは電池を持ち、たいていより大きなSMD部品を搭載している。 あらかじめ決められた時間が経過するたびに、タグは電波の「チャープ(短い信号)」を発する。 近くにあるリーダーは、このチャープを受信できる。 アクティブタグは、パッシブタグよりもはるかに長い距離(数十フィート)で読み取ることができる。

アクティブタグの欠点としては、電池を内蔵する分だけ大きくなること、電池が切れるとタグ自体が使えなくなるため寿命が限られること、タグ1個あたりのコストが高くなること、レポートの頻度がまちまちになることが挙げられる。

RF Code社のm130アクティブRFID資産管理タグ。

RFIDの周波数帯

アクティブ・パッシブの区別に加えて、RFIDシステムは周波数帯によっても分類できる。

周波数帯やシステムによって、一度に1個のタグしか読み取れないものと、複数のタグを同時に読み取れるものがある。 リーダーの価格も、モジュールの周波数によって大きく変わる。 以前は、複数タグを同時に読み取れるリーダーは数千ドル、時には数万ドルもした。 このようなシステムは、ほとんどのホビイストや試作者にとって手の届かないものだった。 しかし状況はようやく変わりつつあり、複数タグ同時読み取り対応のリーダーはずっと手頃な価格になってきている。

次の表に、周波数帯とそれぞれの特性の概要をまとめる。

周波数帯別名到達距離読み書き複数タグの同時読み取りタグの平均価格
低周波(120〜150kHz)「チップ/マイクロチップ」(動物用)、近接カード、HIDカード(いずれも商標)最大20cm(1フィート未満)読み取り専用不可0.50ドル
高周波(13.56MHz)MiFare、NFC最大1メートル読み書き可能不可1ドル
極超短波(433MHz、860〜920MHz)長距離RFID、給電式RFID最大100メートル読み書き可能可能0.05ドル

出典:Wikipedia: Radio-frequency identification

タグのメモリ

RFIDタグはメモリに多くのデータを保存でき、これがRFIDの大きな利点の一つになっている。 タグに保存される識別情報の種類は業界によってさまざまで、その詳細はこのチュートリアルの範囲を超える。 タグの記憶容量に関するより詳しい情報は、Tag Data StandardTag Data Translation Standardを参照してほしい。

Note

一部のRFIDタグ(広く使われている「HID ProxCard II」ブランドのIDカードや、一部のペット用タグなど)は独自形式を採用している。学生証や商用の入退室管理システムのカードは、すべてのRFIDリーダーで読み取れるとは限らない。

Gen2 UHF RFIDのメモリ規格

EPCglobalが策定したv2.0.1規格は、Gen2 RFIDタグに関するあらゆる要件を定めている。 おおまかに言えば、タグのメモリはTID、EPC、ユーザーメモリの3つに分かれている。

タグ識別子メモリ(TID)

TID(Tag Identifier)は20バイト、つまり160ビットである。 これは、1,460,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000通り(1.46×1048)ものタグIDが存在しうることを意味する。 人体を構成する原子の数よりも多い。さすがに宇宙全体の原子の数には及ばないが。 すべてのRFIDタグは固有のTIDを持ち、TIDを書き換えることはできない。

Electronic Product Codeメモリ(EPC)

TIDは絶対的な識別には適しているが、Gen2 RFID規格は本来、多くの小売現場でバーコードを置き換えるために作られたものである。 食料品を買うとき、レジはそのタグのTIDが0xE242F3であるかどうかは気にしない。牛乳1ガロンなのか、ピーナッツバター1瓶なのかを気にする。 そこで登場するのがEPC(Electronic Product Code)である。 たいてい12バイトで、ユーザーが書き換えられ、UPC(バーコード)の代替として書き込むことを想定している。 牛乳のボトルにRFIDタグを貼り、EPCを0 7874203641 0と設定すれば、レジはそれを「Great Value社製の低脂肪・無乳糖牛乳 ハーフガロン」として識別する(出典例)。 タグ自体はその12バイトに何を書き込んでもかまわないので、ASCIIでRufusTheDogと書き込んでも構わないが、12バイト以内に収める必要がある。

ユーザーメモリ

ユーザーメモリの容量は0バイトから64バイトまで幅がある。 安価なタグほど、ユーザーメモリのバイト数は少ない傾向にある。 64バイトで何ができるだろうか。 先ほどの牛乳の例で言えば、ユーザーメモリは本来、賞味期限のような情報を記録することを想定していた。 EPCが「これは牛乳である」というグローバルな識別子であるのに対し、ユーザーメモリはその1本固有の情報(「8月15日までに販売」など)を記録する場所である。 ここでも、タグ自体は何を書き込むかを気にしないので、ユーザー設定(「このユーザーはパイロットシートを10度傾けるのを好む」など)を記録したり、世界最小のデッドドロップとして使ったりすることもできる。

パスワード

このほかにも、Accessパスワード、Killパスワードと呼ばれる書き込み可能なメモリ領域がある。 Accessパスワードは、タグの設定を無断で変更されるのを防ぐために使える(「見た目はサーロインステーキだが、レジではガムのパックと表示される」といった不正を防ぐ)。 Killパスワードは、タグを永久かつ不可逆的に無効化するために使う。

トラブルシューティング

RFIDシステムを動作させる筐体や環境によっては、リーダーがタグのデータを正しく読み書きできない問題に遭遇することがある。 システムの動作を改善するために覚えておくとよいポイントを、いくつか紹介する。

  • 電波干渉を避ける:システムの近くに他の電波を発する機器があると、特に同じ周波数帯を使っている場合、RFIDシステムの性能に悪影響を及ぼすことがある。複数のRFIDリーダーを近くに置くと、システム同士が干渉し合うこともある。
  • クリーンな電源を使う:他の多くの電子システムと同様、ノイズの多い電源や汚れた電源はRFIDシステムに異常な動作を引き起こすことがある。クリーンで安定化された電源の使用をおすすめする。
  • 見通しを確保する:リーダーとタグの間を遮る物がない、見通しの良い状態での読み取りは、結果を改善できる。
  • 外部アンテナを使う:どのシステムでも読み取り距離を伸ばせる。基板上のアンテナは出力と到達距離に限りがある。
  • タグを手で持たない(UHFシステムの場合):人間の体は基本的に水の袋のようなものである。タグを手に持つと読み取り距離が大きく低下する。金属や水分を含まない物にタグをテープで貼り付けるとよい。
  • タグの種類を変えてみる:一般に、タグが小さいほど読み取り距離は短くなる。ガラスカプセル型を使っているならボタン型を、ボタン型を使っているならカード型を試してみるとよい。

まとめ

RFIDの概念がわかったところで、次は自分のプロジェクトに組み込んでみる番である。

RFIDについてさらに詳しい情報は、次のリンクも参考にしてほしい(いずれも英語)。

タグ: 概念、RFID、無線


出典:RFID Basics(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

GPSの基礎

GPSの基本

おそらく誰もが、GPS受信機を使ったり、その恩恵を受けたりしたことがあるだろう。 GPSはほとんどのスマートフォンや多くの新しい自動車に搭載されており、世界中の物流の追跡にも利用されている。 この小さな装置は、地球上のほぼどこにいても、瞬時に無料で正確な位置情報と時刻を教えてくれる。 必要なのはGPS受信機だけであり、しかも受信機は日に日に安く小さくなっている。

一般的なGPS受信機、あるいはGPSモジュール。

このように小さく安価なモジュールを、当たり前のものだと思わないでほしい。 いつでもどこでも正確な位置を提供できるようになるまでには、何十年にもわたる工学の積み重ねがある。 1970年代後半から、非常に正確な原子時計を搭載したGPS衛星が数十機打ち上げられ、現在も打ち上げは続いている。 これらの衛星は、専用の無線周波数を使って絶えずデータを地球に送り続けている。 私たちのポケットサイズのGPS受信機は、小さなプロセッサとアンテナを使って衛星から送られてくるデータを直接受信し、その場で位置と時刻を計算している。 実に驚くべきことである。

参考になるチュートリアル

このチュートリアルは、いくつかの概念の上に成り立っている。 始める前に、次のトピックを知っておくとよい。

GPSはどうやって動作するのか

GPS受信機は、衛星と地上局からなる測位システムを利用して、地球上のほぼどこでも位置と時刻を計算する。

地球上を動く点と、見える衛星の数に注目してほしい。

どの瞬間においても、地球の上空12,000マイル以上を周回する、少なくとも24機の稼働中の衛星が存在する。 これらの衛星の配置は、地球上のどの地点からでも、上空に常に最大12機の衛星が見えるように設計されている。 見える12機の衛星の主な役割は、無線周波数(1.1〜1.5GHz程度)を使って地球へ情報を送信することである。 この情報といくらかの計算があれば、地上の受信機であるGPSモジュールは、自分の位置と時刻を計算できる。

GPS受信機はどうやって位置と時刻を計算するのか

それぞれの衛星から地球に送られるデータには、GPS受信機が位置と時刻を正確に計算するために必要な、いくつかの情報が含まれている。 各GPS衛星に搭載されている重要な機器の1つが、非常に正確な原子時計である。 原子時計の時刻は、その衛星の軌道上の位置や、空の中でのさまざまな地点への到達時刻とともに、地球へ送信される。 言い換えれば、GPSモジュールは見えている衛星それぞれからタイムスタンプを受信し、あわせて各衛星が空のどこに位置しているかというデータ(その他のデータとともに)も受信する。 この情報から、GPS受信機は見えている各衛星までの距離を知ることができる。 GPS受信機のアンテナが少なくとも4機の衛星を捉えられれば、正確な位置と時刻を計算できる。 これはロック(lock)あるいはフィックス(fix)とも呼ばれる。

ここまでの内容をすべて理解できただろうか。 もし理解できなかった場合や、さらに詳しく知りたい場合は、Dan Doberstein著『GPS Fundamentals』の第1巻に、はるかに詳細な説明が載っている。 第1巻は無料で公開されているが、第2巻を読むには著者を支援する必要がある。

コントロールセグメントを描いたイラスト。

測位システムには、もう1つ説明していない要素がある。 衛星とGPS受信機に加えて、衛星ネットワークや一部のGPS受信機と通信できる地上局が存在する。 このシステムは正式にはコントロールセグメントと呼ばれ、GPS受信機の精度を向上させる役割を持つ。 コントロールセグメントを利用して精度を高める一般的なシステムには、WAASDGPSがある。 WAASはほとんどのGPS受信機で利用でき、精度をおよそ5メートルまで向上させる。 DGPSは特定の種類のGPS受信機を必要とし、センチメートル単位の精度が得られる。 DGPSの機器は追加のアンテナが必要になるため、高価で大型になりがちである。

GPSの精度

GPSの精度は、信号対雑音比(受信ノイズ)、衛星の位置、天候、建物や山などの障害物といった、さまざまな要因に左右される。 これらの要因は、実際の位置とのずれを生み出す。 信号ノイズは通常、1〜10メートル程度の誤差を生む。 山や建物など、受信機と衛星の間を遮る障害物は、信号ノイズの3倍もの誤差を生むことがある。 GPS受信機が位置を計算するには、4機の衛星をロックできなければならない。 最初のロックによって受信機はアルマナック情報を取得し、その後どの衛星を探せばよいかが分かるようになる。 4機未満の衛星からでも位置を得ることは可能だが、その場合の誤差はかなり大きくなりうる。 もっとも正確な位置情報が得られるのは、障害物のない開けた空が見え、かつ4機を超える衛星が見えている場合である。 このような誤差に対処するため、いくつかの補助的な仕組みが作られてきた。

アシステッドGPS

その補助的な仕組みの1つが、Assisted GPS、通称AGPSである。 この方式は、GPS信号が弱い場合や受信できない場合に、衛星と受信機の間を中継するために無線の地上ネットワークを利用する。 AGPSが役立つ方法は2つある。 1つ目は、受信機に正しいアルマナックデータと正確な時刻を提供することである。 2つ目は、地上局の高い計算能力と良好な衛星信号を利用して、受信機が受け取った断片的な情報を補完し、より正確な位置情報を提供することである。 AGPSは主に、携帯電話の基地局に搭載されたGPS受信機によって実現されている。 これらの受信機と通信することで、GPSはより速く衛星をロックでき、より正確な情報も得られる。 この方式は携帯電話のGPSで使われており、単体のGPS受信機よりも正確になることがある理由でもある。 とはいえAGPSは携帯電話だけでなく、カメラや一部の車両など、より多くの機器にも搭載されている。 特に、建物が密集した都市部でGPS信号が届きにくい状況で効果を発揮する。

ディファレンシャルGPS

もう1つの方式が、Differential GPS、通称DGPSである。 DGPSも地上の固定GPS局を使って位置を求める点はAGPSと同じだが、衛星からの読み取り値と地上局での読み取り値の差分を求める点が異なる。 これらの地上局は受信機から最大200海里ほど離れていることがあり、地上局から離れるほど精度が落ちる点に注意が必要である。 DGPSでは、実際の疑似距離(pseudorange)と測定された疑似距離との誤差を示す信号を、地上局が送信することで実現されている。 この値は、光速に、衛星から受信機まで信号が伝わるのにかかった時間を掛け合わせることで計算される。 一例として、DGPSの一種にWide Area Augmentation System、通称WAASがある。

(画像提供:ASMA)

もともとFAA(アメリカ連邦航空局)によって航空機のGPSを補助するために開発されたWAASは、専用に建てられた地上局のネットワークを利用する。 WAASには、地上局の測定値が満たすべき、明確な精度基準が定められている。 水平方向と垂直方向のいずれについても、WAASは95%の確率で7.6メートル以内の精度を保証しなければならない。 これらの地上局は測定値をマスターステーションに送り、マスターステーションは5秒ごと、あるいはそれより短い間隔でWAAS衛星に補正情報を送る。 衛星から地上の受信機へ信号が送信され、その補正情報を使ってGPSの精度が向上する。 場所によっては、WAASは水平方向1メートル、垂直方向1.5メートルという精度を実現できる。 WAASは北米地域だけのシステムだが、世界の他の地域にも同様の仕組みが存在する。

Note

さらに精度を高める技術を探しているなら、GPS RTKについてのチュートリアルを確認してほしい。GPS RTKとは何か。最新世代のGPS受信機やGNSS受信機を使って、14mmの位置精度を実現する方法を学べる。

メッセージフォーマット

GPSのデータは、シリアルインターフェースを通じて、さまざまなメッセージフォーマットで出力される。 標準的なフォーマットと、非標準(独自仕様)のフォーマットが存在する。 ほとんどすべてのGPS受信機はNMEA形式のデータを出力する。 NMEA規格は、センテンスと呼ばれるデータの行で構成される。 それぞれのセンテンスには、カンマ区切り形式(つまりデータがカンマで区切られている形式)で、さまざまなデータが含まれている。 以下は、衛星をロックしている(4機以上の衛星が見えており、正確な位置が得られている)GPS受信機から得られる、NMEAセンテンスの例である。

$GPRMC,235316.000,A,4003.9040,N,10512.5792,W,0.09,144.75,141112,,*19
$GPGGA,235317.000,4003.9039,N,10512.5793,W,1,08,1.6,1577.9,M,-20.7,M,,0000*5F
$GPGSA,A,3,22,18,21,06,03,09,24,15,,,,,2.5,1.6,1.9*3E

たとえばGPGGAセンテンスには、次のような情報が含まれる。

  • 時刻:235317.000は、グリニッジ標準時で23時53分17.000秒を表す
  • 緯度:4003.9040,Nは度.10進分形式の緯度で、北緯を表す
  • 経度:10512.5792,Wは度.10進分形式の経度で、西経を表す
  • 見えている衛星の数:08
  • 高度:1577メートル

このデータがカンマで区切られているのは、コンピュータやマイコンが読み取ったり解析したりしやすくするためである。 このデータは、更新レートと呼ばれる間隔でシリアルポートに送信される。 ほとんどの受信機は1秒に1回(1Hz)この情報を更新するが、より高性能な受信機は1秒間に複数回更新できる。 最新の受信機では5〜20Hzでの更新も可能である。

GPSデータの読み取り

ほとんどのGPSモジュールにはシリアルポートが搭載されており、マイコンやパソコンへの接続に適している。

マイコンへの接続

EM-506 GPSおよびGP-735 GPSとGPS Breakout。

GPSモジュールに電源が入ると、ロックの有無にかかわらず、シリアル送信ピン(TX)から特定のボーレート更新レートでNMEAデータ(あるいは別のメッセージフォーマット)が出力される。 マイコンにNMEAデータを読み取らせるには、GPSのTXピンをマイコンのRX(受信)ピンに接続するだけでよい。 GPSモジュールを設定するには、GPSのRXピンもマイコンのTXピンに接続する必要がある。

マイコン側でNMEAデータを解析(パース)するのが一般的である。 パースとは、NMEAセンテンスから必要なデータの塊を取り出し、マイコンがそのデータを使って何らかの処理を行えるようにすることである。

たとえば、マイコンがGPSの高度だけを読み取りたい場合を考えてみよう。

$GPGGA,235317.000,4003.9039,N,10512.5793,W,1,08,1.6,1577.9,M,-20.7,M,,0000*5F

このテキスト全体を扱う代わりに、マイコンはGPGGAセンテンスを解析して、高度(メートル単位)だけを取り出せる。

1577

必要なデータをマイコンが取得できるようになれば、その情報を使ってマイコン上でさまざまな処理を行える。

Arduinoは、Tiny GPSライブラリの助けを借りることで、NMEAデータを簡単に解析できる。 ArduinoとGPSモジュールを接続してNMEAセンテンスを解析する手順を実際に確認したい場合は、GPS Shield Getting Started Guideを参照してほしい。

パソコンへの接続

NMEAデータを直接確認する簡単な方法は、GPSモジュールをパソコンに接続することである。 配線としては、FTDI Basicを使ってGPSに電源を供給し(この場合は5VとGND)、GPSのTXピンをFTDI BasicのRXピンに接続するだけでよい。

EM-506 GPS、GPS Breakout、5V FTDI Breakoutの接続。GP-735 GPSでも同様に接続できる。

次に、GPSモジュールと同じボーレートでシリアルターミナルプログラムを開く。 GPSがロックしていなくても、NMEAセンテンスが次々と流れてくるのが見えるはずである。

$GPRMC,235316.000,A,4003.9040,N,10512.5792,W,0.09,144.75,141112,,*19
$GPGGA,235317.000,4003.9039,N,10512.5793,W,1,08,1.6,1577.9,M,-20.7,M,,0000*5F
$GPGSA,A,3,22,18,21,06,03,09,24,15,,,,,2.5,1.6,1.9*3E

GPS受信機の設定

GPS受信機を設定するには、使用しているチップセットの種類を把握しておくことが非常に重要である。 GPSのチップセットには強力なプロセッサが搭載されており、ユーザーインターフェース、各種計算処理、そしてアンテナ用のアナログ回路までを担っている。 このチップセットには、更新レートやボーレート、出力するセンテンスの選択といったパラメータを設定するためのデータを送ることもできる。

シリアルインターフェースを通じてGPS受信機にコマンドを送るには、コマンド一覧やリファレンスマニュアルが必要になる。 特定のモジュール向けのコマンド体系に深入りする前に、必ずベンダーに確認すること。 多くのチップセットベンダーは、シリアルポート経由でGPSモジュールと簡単に通信し、設定を行えるソフトウェアを提供している。

以下は、代表的なチップセットのデータシートとコマンド一覧である。

  • SiRFチップセット
    • SiRF NMEA Reference Manual
    • SiRF Binary Reference Manual
    • SiRF Demo Software
  • U-Bloxチップセット
    • u-blox6 NMEA and UBX Reference Manual
    • u-center Demo Software
  • SkyTraqチップセット
    • Skytraq Reference Manual
    • SkyTraq Demo Software

チップセットによっては、SiRFバイナリ(SiRFチップセット)やUBX(ubloxチップセット)、あるいは独自のメッセージ形式といった、別のプロトコルにも対応している。 これらのプロトコルは同じ内容の情報を含んでいるが、通信を高速化するためにASCIIではなくバイナリでやり取りする点が異なる。

GPS受信機と通信する際、ほとんどのコマンドはチェックサムで終端する必要がある。 多くの場合、送信するセンテンスの各バイトをXOR演算する必要がある。 簡単なXORオンライン計算ツールも存在する。

GPS用語集

精度(Accuracy):GPSはどれくらい正確なのだろうか。多少のばらつきはあるが、通常は世界中どこにいても30秒以内に、±5メートル程度の誤差で自分の位置を知ることができる。 実に驚くべきことである。 「±」が付くのは、モジュールや時間帯、受信状況の良し悪しなどによって精度が変動するためである。 ほとんどのモジュールはWAASを有効にすれば±3m程度まで精度を高められるが、サブメートルやセンチメートル単位の精度が必要な場合は、非常に高価になり、DGPSと呼ばれる仕組みが必要になる。

全体として、GPSから最良の精度を得るには、空が開けた場所にいて、かつ移動していることが重要である。

旧SparkFun本社の周辺で記録し、プロットしたGPSのウェイポイント。それぞれの軌跡は異なる種類のGPSモジュールに対応する。

SparkFunの建物周辺の軌跡の例を見ると分かるように、「ロック開始」と「ロック終了」の地点ではGPSの位置が跳ね回っている。 これは、GPSモジュールが静止しているときに起こる現象である。 GPSにはおよそ5メートル程度の誤差があり、静止しているときにはその誤差がそのまま見えてしまう。 モジュールが動き始めると、軌跡は比較的正確になり、GPSは進行方向を「推測」できるようになる。 ただし、高い建物に挟まれたアーバンキャニオンに近づくと、精度が悪化することに注意してほしい。 GPS信号は、必ずしも真上にあるとは限らない衛星から送信されており、地平線に近い位置にある衛星もある。 また、電波は建物や物体で反射し、マルチパス干渉と呼ばれる現象を引き起こすことがある。 GPSは、空が開けた場所でもっともよく機能するということを、常に覚えておいてほしい。

アンテナ(Antenna):忘れてはならないのは、あの小さなGPSモジュールが、頭上だけでなく空のあらゆる方向にある、およそ12,000マイル彼方の衛星からの信号を受信しているという点である。 最良の性能を得るには、アンテナと空の大部分との間に遮るもののない経路が必要である。 天候や雲、雪嵐は信号にほとんど影響しないはずだが、木々や建物、山、頭上の屋根などは望ましくない干渉を生み、GPSの精度を低下させる。

アンテナにはさまざまな選択肢があるが、代表的なものをいくつか紹介する。

もっとも小型で一般的な形状のアンテナが、セラミックパッチアンテナである。

このアンテナは薄型で安価、かつコンパクトだが、他の種類のアンテナに比べると受信感度は劣る。 良好な信号を得るには、このアンテナを空に向けて上向きに設置する必要がある。つまり利得(ゲイン)は上向きのときに最大になる。

GPSモジュールの中には、ヘリカルアンテナを使用するものもある。

このアンテナはセラミックパッチよりも場所を取るが、その形状のおかげでどの向きでも比較的良好な信号が得られる。ただし、特定の1方向における利得はやや低くなる。

モジュールによっては、SMAアンテナを取り付けられるものもある。

SMA接続を使えば、メイン基板とは別の場所にアンテナを設置できる。 これは、メインシステムが空を見渡せない場所(建物の内部や車の中など)にある場合に有用である。

ボーレート(Baud Rate):GPS受信機は、送信ピン(TX)から特定のビットレートでシリアルデータを出力する。 もっとも一般的なのは1Hzの受信機で使われる9600bpsだが、57600bpsも一般的になりつつある。 詳しくは、受信機のデータシートを確認してほしい。

チャンネル数(Channels):GPSモジュールが処理できるチャンネル数は、最初の測位までの時間(TTFF)に影響する。 モジュールはどの衛星が見えているかをあらかじめ知らないため、一度に確認できる周波数やチャンネルの数が多いほど、より速く測位できる。 モジュールがロックやフィックスを得たあと、消費電力を抑えるために余分なチャンネルのブロックを停止するものもある。 ロックまで多少時間がかかってもかまわないのであれば、追跡用途には12〜14チャンネルで十分である。

チップセット(Chipset):GPSのチップセットは、計算処理からアンテナ用のアナログ回路の提供、電源管理、ユーザーインターフェースに至るまで、あらゆる処理を担っている。 非常に多くの仕事をこなしているが、これらの小さなGPSユニットはまさにそれをやってのけている。 チップセットはアンテナの種類とは独立しているため、特定のチップセットを搭載したGPSモジュールにさまざまな種類のアンテナを組み合わせることができる。 一般的なチップセットにはublox、SiRF、SkyTraqなどがあり、いずれも高速な測位と高い信頼性を実現する強力なプロセッサを搭載している。 チップセットごとの違いは、たいてい消費電力、測位にかかる時間、ハードウェアの入手のしやすさのバランスによって決まる。

DGPS(ディファレンシャルGPS):DGPSは特定の種類のGPS受信機である。 DGPS受信機には追加のアンテナが搭載されており、衛星からだけでなく、地上局からも直接信号を受信する。 DGPS機器には通常2本のアンテナが必要である。 これらは標準的なGPS機器よりもはるかに大きく高価だが、センチメートル単位の位置精度を実現できる。

利得(Gain):利得とは、特定の向きにおけるアンテナの効率を表す。 これは送信用アンテナにも受信用アンテナにも当てはまる。

ロックまたはフィックス(Lock or Fix):GPS受信機がロックまたはフィックスを得ている状態とは、少なくとも4機の衛星が良好に見えており、正確な位置と時刻が得られている状態を指す。

NMEA:ほとんどのGPSモジュールが使用する、一般的なデータフォーマットである。 NMEAデータはセンテンスの形で表され、GPSモジュールのシリアル送信(TX)ピンから出力される。 NMEAセンテンスには、位置や時刻など、有用なデータがすべて含まれている。

電力(Power):GPSモジュールは電力を大量に消費するわけではないが、衛星からのデータを計算処理し、ロックを得るためにはある程度の電力が必要である。 一般的なGPSモジュールは、ロックを得ている状態で平均して3.3Vで約30mAの電流を消費する。 また、起動時間を短く保つことも、消費電力の節約につながる。

PPS:1秒あたりのパルス(Pulse per second)の略である。 一部のGPSモジュールに搭載されている出力ピンで、通常このピンが1秒に1回切り替わり、これを使ってシステムクロックをGPSのクロックに同期できる。

起動時間(ホットスタート、ウォームスタート、コールドスタート):GPSモジュールの中には、電源を切ったあとも、スーパーキャパシタやバッテリーバックアップによって、以前の衛星データを揮発性メモリ上に保持できるものがある。 これにより、次回起動時のTTFFを短縮できる。 また、起動時間が短くなることは、全体としての消費電力の削減にもつながる。

コールドスタート(Cold Start):モジュールの電源を長時間切ったままにし、バックアップ用のキャパシタが放電してしまうと、データは失われる。 次に電源を入れたとき、GPSは新しいアルマナックデータとエフェメリスデータをダウンロードし直す必要がある。

ウォームスタート(Warm Start):バックアップ電源がどれくらい持続するかにもよるが、アルマナックデータとエフェメリスデータの一部が保持された状態で起動することもある。この場合、ロックの取得には多少余分に時間がかかることがある。

ホットスタート(Hot Start):ホットスタートとは、すべての衛星のデータが最新で、前回の電源投入時とほぼ同じ位置に衛星がある状態を指す。 ホットスタートであれば、GPSはすぐにロックできる。

トライラテレーション(Trilateration、三辺測量):複数の基準点を使って位置を計算する数学的な手法である。 GPS受信機が正確な位置と時刻を計算するには、空にある少なくとも4機の衛星を良好に捉えられている必要がある。 この状態がGPSのロックまたはフィックスと呼ばれる。 2つの基準点(x, y)を使って対象物までの距離を計算する三角測量についてはよく知られているが、GPSの場合は緯度、経度、高度、時刻という4つの値を求める必要がある。

TTFF:最初の測位までの時間(Time to first fix)の略である。 電源投入後、少なくとも4機の衛星を使って正確な位置と時刻を計算するまでにかかる時間を指す。 空の見通しが悪い場所にいる場合、TTFFは非常に長くなることがある。

更新レート(Update Rate):GPSモジュールの更新レートとは、位置を計算して報告する頻度のことである。 ほとんどの機器の標準は1Hz(1秒に1回)である。 UAV(無人航空機)など高速で移動する機体では、より高い更新レートが必要になることがある。 低価格なモジュールでも、5Hzや10Hzといった更新レートが利用できるようになりつつある。 更新レートが高いほど、モジュールから送出されるNMEAセンテンスの量も増えることに注意してほしい。

WAAS:WAAS(広域補強システム)は、北米にある地上局のネットワークであり、衛星に補正データを送り返す。 WAASは位置精度をおよそ5メートルまで高める。 他の国にも同様のシステムがあり、たとえばヨーロッパのEGNOS、日本のMSAS、インドのGAGANなどがある。 ほとんどのGPS受信機はデフォルトでWAASが有効になっており、EGNOS、MSAS、GAGANにも対応している。

トラブルシューティング

ロックに関する問題

Mikal Hart氏のTinyGPS++ライブラリは、GPSをすばやく動かし始めるのに非常に優れている。 とはいえ、アーバンキャニオンの間にいる場合や、コンクリート製の建物の中、あるいはおよそ無線信号を通さない暗闇のような場所にいる場合は、うまくいかないこともある。 実際に問題になったのは、屋内でGPSを使う場合であり、SparkFunの建物のようにコンクリートや金属の梁、大きな太陽光パネルが数多くあると、GPS信号(ついでに言えばほとんどの携帯キャリアの電波も)が大きく乱れ、GPSのロックを得るのが非常に難しくなる。

GPSモジュールのデータがライブラリを使ってもうまく見えない場合や、出力が不完全な場合は、より多くの衛星が見える別の場所に移動する必要があるかもしれない。 GPSモジュールを数歩動かしたり、建物の周辺部に移したりするだけで改善することもある。 見えている衛星数を確認するには、GPGGAセンテンスの6番目と7番目のフィールドを見て、ロックに問題がないか確認できる。 以下は、GPSモジュールが衛星をロックできていないときのGPGGAセンテンスの例である。 見てのとおり、GPSのフィックスがなく、見えている衛星もないため、出力は無効であることを示している。

$GPGGA,105317.709,8960.0000,N,00000.0000,E,0,0,,137.0,M,13.0,M,,*4C

ボーレートの不一致

GPSモジュールのシリアルUARTからシリアルモニタにデータを流したときに、以下の画像のような「文字化け」しか表示されない場合は、ボーレートの設定が正しいかどうかを確認してほしい。 GPSモジュールによってボーレートは異なることがあるため、使用しているGPSモジュールのデータシートを確認し、ボーレートが一致しているか確かめること。

この節で説明したような、ボーレートの不一致(いわゆる文字化け)の例。

まとめ

これで、GPSユニットがどのように動作するか、そして次のプロジェクトにどう組み込めばよいかが、はっきりと理解できたはずである。 さらに優れたプロジェクトのアイデアを探しているなら、次のようなSparkFunのチュートリアルも確認してほしい。

  • ジャイロスコープとは何か:ジャイロスコープは軸を中心とした回転の速さを測定するもので、空間内での姿勢を判断するうえで欠かせない部品である。
  • 加速度センサーの基礎:加速度センサーとは何か、どのように動作するのか、なぜ使われるのかについての簡単な入門である。
  • プロジェクトへの電源供給:プロジェクトに必要な電源要件を見極めるためのチュートリアルである。
  • 電力:電力、つまりエネルギー伝達の速さについての概要である。電力の定義やワット、計算式、定格出力について解説する。
  • ブレッドボードの使い方:ブレッドボードの世界へようこそ。ブレッドボードとは何か、それを使って最初の回路を組み立てる方法を学べる。

タグ: GPS、技術、無線


出典:GPS Basics(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

オシロスコープの使い方

回路のトラブルシューティングをしていて、テスターだけでは足りない情報が必要になったことはないだろうか。 周波数、ノイズ、振幅など、時間とともに変化する特性を知りたければ、オシロスコープが必要になる。

オシロスコープ(O-スコープ)は、電気系エンジニアの実験室に欠かせない道具である。 電気信号が時間とともにどう変化するかを目で見えるようにしてくれるため、555タイマー回路がうまく点滅しない原因や、ノイズメーカーの騒々しさが最大レベルに達しない原因を突き止める際に大きな助けになる。

このチュートリアルで扱う内容

このチュートリアルでは、オシロスコープの概念、用語、制御系を紹介する。次のセクションに分かれている。

  • O-スコープの基礎 — オシロスコープとは何か、何を測定するのか、なぜ使うのかを紹介する
  • オシロスコープ用語集 — オシロスコープに関するよく使われる用語をまとめた用語集
  • O-スコープの構成 — 画面、水平・垂直コントロール、トリガー、プローブといった、オシロスコープの最も重要な各系統の概要
  • オシロスコープの使い方 — オシロスコープを初めて使う人向けのコツと手順

このチュートリアルでは、扱いやすい中級クラスのデジタルオシロスコープであるGratten GA1102CALを例に説明する。 他のオシロスコープでは見た目が異なることもあるが、いずれも似たような制御系とインターフェースの仕組みを備えているはずである。

参考になるチュートリアル

このチュートリアルを読み進める前に、次の概念に馴染んでおくとよい。詳しく知りたい場合はそれぞれのチュートリアルを参照してほしい。

O-スコープの基礎

オシロスコープの主な目的は、電気信号が時間とともにどう変化するかをグラフに描くことである。 ほとんどのオシロスコープは、横軸に時間縦軸に電圧を取った二次元のグラフを描画する。

オシロスコープの表示例。この場合は黄色の正弦波の信号が、横軸の時間と縦軸の電圧のグラフとして描かれている。

画面の周囲にあるコントロール類を使い、グラフの縦・横それぞれのスケールを調整できる。これにより信号を拡大・縮小して見ることができる。 また、トリガーを設定するコントロールもあり、表示の焦点を合わせて安定させるのに役立つ。

オシロスコープで測定できること

こうした基本的な機能に加えて、多くのオシロスコープには測定ツールが備わっており、周波数、振幅、その他の波形の特性を素早く数値化できる。 一般に、オシロスコープは時間に関する特性と電圧に関する特性の両方を測定できる。

時間に関する特性:

  • 周波数と周期 — 周波数とは、波形が1秒間に繰り返される回数のことである。周期はその逆数(波形が1回繰り返すのにかかる秒数)にあたる。オシロスコープが測定できる最大周波数は機種によって異なるが、多くは数百MHz(1E6 Hz)の範囲に達する。
  • デューティ比 — 波が正、あるいは負である期間が、1周期に占める割合のこと(正のデューティ比と負のデューティ比がある)。デューティ比は、信号が1周期のうちどれだけの時間「オン」で、どれだけの時間「オフ」かを示す比率である。
  • 立ち上がり時間と立ち下がり時間 — 信号は瞬時に0Vから5Vへ変化するわけではなく、滑らかに立ち上がる必要がある。波が低い点から高い点へ移るのにかかる時間を立ち上がり時間、その逆を立ち下がり時間と呼ぶ。回路が信号にどれだけ速く応答できるかを考える上で重要な特性である。

電圧に関する特性:

  • 振幅 — 振幅は信号の大きさを表す尺度である。振幅の測り方にはいくつかの種類があり、信号の最高点と最低点の絶対的な差を測るピークツーピーク振幅もその一つである。一方、ピーク振幅は、信号が0Vからどれだけ高く、あるいは低くなるかだけを測る。
  • 最大電圧と最小電圧 — オシロスコープは、信号の電圧がどこまで高くなり、どこまで低くなるかを正確に示してくれる。
  • 平均電圧 — オシロスコープは信号の平均値を計算でき、信号の最小電圧と最大電圧の平均を示すこともできる。

O-スコープを使う場面

O-スコープは、次のようなさまざまなトラブルシューティングや研究の場面で役立つ。

  • 信号の周波数と振幅を調べる。回路の入力・出力・内部の系統をデバッグする上で重要な情報であり、これによって回路のどの部品が誤作動しているかがわかることもある。
  • 回路にどれだけのノイズが乗っているかを調べる。
  • 波の(正弦波、方形波、三角波、のこぎり波、複雑な波形など)を特定する。
  • 2つの異なる信号の間の位相差を数値化する。

オシロスコープ用語集

オシロスコープの使い方を学ぶということは、専門用語のひとまとまりを覚えることでもある。 このセクションでは、電源を入れる前に押さえておきたい、重要なオシロスコープ関連の用語をいくつか紹介する。

オシロスコープの主な仕様

オシロスコープには機種による性能差がある。 次の特性は、そのオシロスコープがどれだけの性能を発揮できるかを示す目安になる。

  • 帯域幅 — オシロスコープは、明確な周波数を持つ波形の測定に最もよく使われる。とはいえ完璧なオシロスコープは存在せず、信号の変化をどれだけ速く捉えられるかにはいずれも限界がある。オシロスコープの帯域幅は、確実に測定できる周波数の範囲を示す値である。
  • デジタルとアナログ — 電子機器の多くと同様に、オシロスコープにもアナログ式とデジタル式がある。アナログ式のオシロスコープは、電子ビームを使って入力電圧を直接表示にマッピングする。デジタル式のオシロスコープはマイクロコントローラーを内蔵し、アナログ-デジタル変換器で入力信号をサンプリングし、その読み取り値を表示にマッピングする。一般にアナログ式は歴史が古く、帯域幅が狭く機能も少ないが、応答が速いことがある(そして見た目もかっこいい)。
  • チャンネル数 — 多くのオシロスコープは、一度に複数の信号を読み取り、画面に同時に表示できる。オシロスコープが読み取る各信号は、それぞれ別のチャンネルに入力される。2〜4チャンネルのオシロスコープが一般的である。
  • サンプリングレート — この特性はデジタル式オシロスコープに固有のもので、信号を1秒間に何回読み取るかを示す。複数チャンネルを持つオシロスコープでは、複数チャンネルを同時に使うとこの値が下がることがある。
  • 立ち上がり時間 — オシロスコープの仕様に記載される立ち上がり時間は、測定できる最も速い立ち上がりパルスを示す。オシロスコープの立ち上がり時間は帯域幅と密接に関係しており、立ち上がり時間 = 0.35 / 帯域幅という式で計算できる。
  • 最大入力電圧 — あらゆる電子機器には、高電圧に対する限界がある。オシロスコープにも必ず最大入力電圧の定格がある。信号がこの電圧を超えると、オシロスコープが損傷する可能性が高い。
  • 分解能 — オシロスコープの分解能は、入力電圧をどれだけ精密に測定できるかを表す。この値は垂直方向のスケールの調整によって変化する。
  • 垂直感度 — 垂直方向、つまり電圧スケールの最小値・最大値を表す値である。1目盛りあたりのボルト数で示される。
  • タイムベース — タイムベースは通常、水平方向、つまり時間軸の感度の範囲を示す。1目盛りあたりの秒数で示される。
  • 入力インピーダンス — 信号の周波数が非常に高くなると、回路にごくわずかなインピーダンス(抵抗、静電容量、インダクタンス)が加わるだけでも信号に影響が出ることがある。オシロスコープは、読み取る回路に対して必ず一定のインピーダンスを付加しており、これを入力インピーダンスと呼ぶ。入力インピーダンスは通常、大きな抵抗性インピーダンス(1MΩ超)と、小さな静電容量(pFの範囲)が並列(||)に接続されたものとして表される。入力インピーダンスの影響は、非常に高い周波数の信号を測定する際に顕著になり、使用するプローブがその補正を担うこともある。

GA1102CALを例に、中級クラスのオシロスコープに期待できる仕様を示す。

特性
帯域幅100MHz
サンプリングレート1GSa/s(1秒あたり1E9サンプル)
立ち上がり時間3.5ns未満
チャンネル数2
最大入力電圧400V
分解能8ビット
垂直感度2mV/div〜5V/div
タイムベース2ns/div〜50s/div
入力インピーダンス1MΩ±3%

これらの特性を理解すれば、自分のニーズに最も合ったオシロスコープを選べるようになるはずである。 とはいえ、使い方も知っておく必要がある。次のセクションに進もう。

O-スコープの構成

まったく同じオシロスコープというものは存在しないが、いずれも似た働きをする共通点をいくつか備えている。 このセクションでは、オシロスコープでよく見られる系統、すなわちディスプレイ、水平系、垂直系、トリガー系、入力系について説明する。

ディスプレイ

オシロスコープは、テストしたい情報を表示できなければ意味がない。そのためディスプレイは、オシロスコープの中でも特に重要な部分の一つである。

すべてのオシロスコープのディスプレイには、水平線と垂直線が格子状に交差しており、これを目盛り(division)と呼ぶ。 この目盛りのスケールは、水平系と垂直系のコントロールで変更する。 垂直系は「1目盛りあたりのボルト数」、水平系は「1目盛りあたりの秒数」で測られる。 一般的なオシロスコープには、縦(電圧)方向に8〜10目盛り、横(時間)方向に10〜14目盛りが用意されている。

古いオシロスコープ(特にアナログ式のもの)は、たいていシンプルなモノクロ表示だが、波の輝度は変化することがある。 より新しいオシロスコープはカラーのLCD画面を備えており、複数の波形を同時に見やすく表示するのに大いに役立つ。

多くのオシロスコープの画面の隣(横または下)には、5個程度のボタン群が配置されている。 これらのボタンを使ってメニューを操作し、オシロスコープの設定を制御できる。

垂直系

オシロスコープの垂直セクションは、ディスプレイの電圧スケールを制御する。 一般に、垂直位置とvolts/divを個別に制御できる2つのつまみが用意されている。

より重要なvolts per divisionのつまみは、画面上の垂直スケールを設定するものである。 つまみを時計回りに回すとスケールが小さくなり、反時計回りに回すと大きくなる。 スケールが小さい(画面上の1目盛りあたりのボルト数が少ない)ほど、波形をより「拡大」して見ていることになる。

たとえばGA1102のディスプレイには8つの垂直目盛りがあり、volts/divのつまみは2mV/divから5V/divの間でスケールを選べる。 つまり、2mV/divまで拡大すると、画面の上端から下端までで16mVの波形を表示できる。 最大まで「縮小」すると、40Vを超える範囲の波形を表示できる(後述するように、プローブによってこの範囲をさらに広げることもできる)。

位置のつまみは、画面上での波形の垂直方向のオフセットを制御する。 つまみを時計回りに回すと波は下に、反時計回りに回すと上に移動する。 位置つまみを使えば、波形の一部を意図的に画面の外にずらすこともできる。

位置つまみとvolts/divつまみを組み合わせて使うことで、最も注目したい波形のごく一部だけを拡大して見ることができる。 たとえば5Vの方形波があり、そのエッジのリンギング(振動)だけが気になる場合は、両方のつまみを使って立ち上がりエッジを拡大表示すればよい。

水平系

オシロスコープの水平セクションは、画面上の時間スケールを制御する。 垂直系と同様に、水平系のコントロールにも位置とseconds/divという2つのつまみがある。

**seconds per division(s/div)**のつまみは、水平方向のスケールを増減させる。 s/divのつまみを時計回りに回すと、1目盛りが表す秒数が小さくなり、時間軸を「拡大」することになる。 反時計回りに回すと時間スケールが大きくなり、画面によりの長い時間を表示できる。

再びGA1102を例にすると、ディスプレイには14の水平目盛りがあり、1目盛りあたり2nSから50sの間で表示できる。 つまり水平スケールを目一杯拡大すると28nSの波形を、目一杯縮小すると700秒にわたる信号の変化を表示できる。

位置のつまみは、波形を画面の左右に動かし、水平方向のオフセットを調整する。

水平系を使うと、波形の何周期分を表示するかを調整できる。 縮小して、信号の複数の山と谷を表示することもできる。

あるいは大きく拡大し、位置つまみを使って波のごく一部だけを表示することもできる。

トリガー系

トリガーのセクションは、オシロスコープの表示を安定させ、焦点を合わせるためのものである。 トリガーは、信号のどの部分で「トリガー」をかけて測定を開始するかをオシロスコープに指示する。 波形が周期的であれば、トリガーを調整することで表示を静止させ、揺れのない状態に保つことができる。 トリガーの設定がうまくいっていない波は、次のように目が回りそうなほど画面上を流れ続けてしまう。

オシロスコープのトリガーセクションは通常、レベルつまみと、トリガーのソースと種類を選ぶための一連のボタンで構成される。 レベルつまみを回すことで、特定の電圧の点にトリガーを設定できる。

トリガー系の残りの部分は、一連のボタンと画面上のメニューで構成されている。 その主な役割は、トリガーのソースとモードを選択することである。 トリガーがどのように動作するかを変えるトリガーの種類にはいくつかある。

  • エッジトリガーは最も基本的なトリガーの形式である。信号の電圧が特定のレベルを超えたときに、オシロスコープが測定を始めるきっかけとなる。エッジトリガーは、立ち上がりエッジ、立ち下がりエッジ(またはその両方)で検出するよう設定できる。
  • パルストリガーは、指定した電圧の「パルス」でオシロスコープをトリガーさせるものである。パルスの持続時間と方向を指定できる。たとえば0V→5V→0Vというごく短い変化の場合もあれば、5Vから0Vへ数秒かけて下がり再び5Vに戻るような場合もある。
  • スロープトリガーは、指定した時間内での正または負のスロープ(傾き)でトリガーをかけるよう設定できる。
  • さらに複雑なトリガーとして、NTSCPALのような、映像データを運ぶ標準化された波形に焦点を当てるものもある。これらの波形は、フレームの先頭ごとに独特の同期パターンを使う。

たいていの場合、トリガーモードも選択できる。これは実質的に、トリガーをどれだけ厳密に扱いたいかをオシロスコープに伝えるものである。 自動トリガーモードでは、トリガーが検出されなくても波形の描画を試みる。 ノーマルモードは、指定したトリガーを検出した場合にのみ波形を描画する。 シングルモードは、指定したトリガーを検出すると波形を一度だけ描画し、そこで停止する。

プローブ

オシロスコープは、実際に信号に接続できて初めて役に立つ。そのために必要なのがプローブである。 プローブは、回路からオシロスコープへ信号を送る単一入力のデバイスである。 先端は鋭いチップになっており、回路上の一点に当てて測定する。 チップには、回路に固定しやすくするためのフック、ピンセット、クリップを取り付けられることもある。 どのプローブにもグラウンドクリップが付属しており、これを被測定回路の共通グラウンドポイントに確実に固定する必要がある。

プローブは、回路に固定して信号をオシロスコープに送るだけの単純な装置に見えるかもしれないが、実際にはその設計と選定には多くの検討事項がある。

理想的には、プローブは「見えない」存在であるべきである。つまり、測定対象の信号に何の影響も与えないことが望ましい。 残念ながら、長いワイヤーにはどれもインダクタンス、静電容量、抵抗が本質的に存在するため、(特に高周波では)どうしてもオシロスコープの読み取り値に影響を与えてしまう。

プローブにはさまざまな種類があるが、最も一般的なのは、ほとんどのオシロスコープに付属するパッシブプローブである。 市販の「標準」パッシブプローブの多くは減衰型である。 減衰型のプローブは、意図的に組み込まれた大きな抵抗と、それを分流する小さなコンデンサを持ち、長いケーブルが回路の負荷に与える影響を最小限に抑える役割を果たす。 オシロスコープの入力インピーダンスと直列に接続されることで、この減衰プローブは信号とオシロスコープの入力の間に分圧回路を作り出す。

多くのプローブは、減衰用に9MΩの抵抗を備えており、これがオシロスコープの標準的な1MΩの入力インピーダンスと組み合わさることで、1/10の分圧回路を形成する。 このようなプローブは一般に10倍減衰プローブと呼ばれる。 多くのプローブには、10倍と1倍(減衰なし)を切り替えるスイッチが付いている。

減衰プローブは高周波での精度向上に優れているが、信号の振幅も小さくしてしまう。 非常に低電圧の信号を測定したい場合は、1倍プローブを使う必要があるかもしれない。 また、減衰プローブを使っていることをオシロスコープ側に設定する必要がある場合もあるが、多くのオシロスコープはこれを自動的に検出できる。

パッシブな減衰プローブ以外にも、さまざまな種類のプローブが存在する。 アクティブプローブは電源を必要とするプローブ(別途電源が必要)で、信号を増幅したり、オシロスコープに届く前に前処理したりできる。 ほとんどのプローブは電圧を測定するために設計されているが、交流や直流の電流を測定するために設計されたプローブもある。 電流プローブは独特で、ワイヤーの周りにクランプするだけで回路に直接触れることなく測定できることが多い。

オシロスコープの使い方

信号の種類は無限にあるため、まったく同じ手順でオシロスコープを操作することは二度とないだろう。 とはいえ、回路をテストするたびにほぼ毎回行うことになる、いくつかの共通の手順がある。 このセクションでは、サンプルの信号を例に、それを測定するために必要な手順を示す。

プローブの選定と設定

まず、プローブを選ぶ必要がある。 ほとんどの信号には、オシロスコープに付属するシンプルなパッシブプローブで十分に対応できる。

次に、オシロスコープに接続する前に、プローブの減衰設定を行う。 最も一般的な減衰率である10倍は、たいてい最もバランスのよい選択肢である。 ただし、非常に低電圧の信号を測定したい場合は1倍が必要になることもある。

プローブを接続し、オシロスコープの電源を入れる

プローブをオシロスコープの1チャンネル目に接続し、電源を入れる。 少し辛抱してほしい。オシロスコープの中には、古いパソコンと同じくらい起動に時間がかかるものもある。

起動すると、目盛り、スケール、そしてノイズの乗った平らな波形の線が表示されるはずである。

画面には、以前設定した時間とvolts/divの値も表示されているはずである。 これらのスケールはひとまず置いておき、次の調整を行ってオシロスコープを標準的な設定にする。

  • チャンネル1をオンにし、チャンネル2はオフにする。
  • チャンネル1をDCカップリングに設定する。
  • トリガーソースをチャンネル1に設定する(外部ソースや別チャンネルによるトリガーは使わない)。
  • トリガーの種類を立ち上がりエッジに、トリガーモードをシングルではなく自動に設定する。
  • オシロスコープ側のプローブ減衰設定が、プローブ自体の設定(1倍、10倍など)と一致していることを確認する。

これらの調整方法がわからない場合は、オシロスコープの取扱説明書を参照してほしい(一例としてGA1102CALのマニュアルを挙げておく)。

プローブをテストする

このチャンネルを、意味のある信号に接続してみよう。 多くのオシロスコープには内蔵の周波数発生器があり、安定した既知の周波数の波を出力できる。GA1102CALの場合、前面パネル右下に1kHzの方形波出力がある。 この周波数発生器の出力には、信号用とグラウンド用の2本の独立した導線がある。 プローブのグラウンドクリップをグラウンドに、プローブ先端を信号出力に接続する。

プローブの両方の接続を終えると、すぐに画面上で信号が揺れ動き始めるはずである。 水平系・垂直系のつまみをいろいろ動かし、画面上で波形を操作してみるとよい。 スケールのつまみを時計回りに回すと波形が「拡大」され、反時計回りに回すと「縮小」される。 位置つまみを使えば、波形の位置をさらに調整できる。

波形がまだ不安定な場合は、トリガー位置のつまみを回してみるとよい。 トリガーが波形の最も高いピークより高い値に設定されていないか確認すること。 デフォルトでは、トリガーの種類はエッジに設定されているはずで、この方形波のような信号には通常これがよい選択となる。

これらのつまみをいろいろ調整して、波の1周期分を画面に表示させてみよう。

あるいは、時間スケールを大きく縮小して、方形波を何十個も表示させてみてもよい。

減衰プローブの補正

プローブが10倍に設定されており、上のようなきれいな方形波にならない場合は、プローブの補正が必要かもしれない。 多くのプローブには奥まった位置にねじ頭があり、これを回すことでプローブのシャント容量を調整できる。

小さなドライバーを使ってこのトリマーを回し、波形がどう変化するか見てみるとよい。

プローブハンドルのトリミングキャパシタを調整し、エッジがまっすぐな方形波になるようにする。 補正が必要になるのはプローブが減衰型(10倍など)に設定されている場合だけだが、その場合は極めて重要な作業になる(特に、そのオシロスコープを直前に誰が使ったのかわからない場合はなおさらである)。

プロービング、トリガー、スケーリングのコツ

プローブの補正が終わったら、いよいよ実際の信号を測定する番である。 信号源(周波数発生器や、Terror-Minのようなもの)を用意して戻ってきてほしい。

信号をプロービングする際の最初の要点は、しっかりと信頼できるグラウンドポイントを見つけることである。 グラウンドクリップを既知のグラウンドに固定する。場合によっては、グラウンドクリップと回路のグラウンドポイントの間を短いワイヤーで中継する必要があるかもしれない。 続いて、プローブの先端を測定対象の信号に接続する。 プローブ先端にはばね式クリップ、細い針、フックなど、さまざまな形状がある。常に手で押さえていなくても済むものを選ぶとよい。

⚡ 注意: 絶縁されていない回路(電池駆動でない、あるいは絶縁型電源を使っていない回路)をプロービングする際は、グラウンドクリップをどこに接続するか十分に注意すること。商用電源のアースに接続された回路をプロービングする場合は、グラウンドクリップを回路の商用電源のアースに接続されている側につなぐこと。これはほとんどの場合、回路のマイナス・グラウンド側にあたるが、別の点になることもある。グラウンドクリップを接続した点に電位差があると、そこで直接ショートが発生し、回路、オシロスコープ、そして自分自身を傷つける恐れがある。商用電源につながった回路をテストする際は、安全のため絶縁トランスを介して電源を供給することを推奨する。

信号が画面に表示されたら、まずは水平・垂直のスケールを信号の「おおよその見当」がつく程度に調整するとよい。 たとえば5V、1kHzの方形波をプロービングしているなら、volts/divはおよそ0.5〜1V、seconds/divはおよそ100µsに設定するとよいだろう(14目盛りで1.5周期程度が表示される)。

波形の一部が画面の上下からはみ出している場合は、垂直位置を調整して上下に動かすことができる。 信号が純粋な直流であれば、0Vのラインを画面下部付近に調整するとよいこともある。

スケールのおおよその見当がついたら、波形にはある程度のトリガー調整が必要になる。 エッジトリガー(電圧が設定した点を超えて上昇、あるいは下降したときにオシロスコープが走査を始めようとする方式)は、最も使いやすいトリガーの種類である。 エッジトリガーを使う場合は、トリガーレベルを、1周期に一度だけ立ち上がりエッジを検出するような点に設定するとよい。

あとは、必要な表示になるまでスケール調整、位置調整、トリガー調整を繰り返すだけである。

二度測って一度で決める

信号にスコープを合わせ、トリガーをかけ、スケールを調整できたら、いよいよ過渡現象や周期、その他の波形特性を測定する番である。 オシロスコープによって測定ツールの充実度は異なるが、どの機種にも少なくとも目盛りは備わっており、これだけでも振幅と周波数のおおよその見当をつけることができる。

多くのオシロスコープは、さまざまな自動測定ツールに対応しており、周波数のような重要な情報を常時表示できる機種もある。 オシロスコープを最大限に活用するには、対応している測定機能をひととおり確認しておくとよい。 たいていのオシロスコープは、周波数、振幅、デューティ比、平均電圧など、さまざまな波形特性を自動的に計算してくれる。

オシロスコープの測定ツールを使い、VPP、VMax、周波数、周期、デューティ比を求める。

多くのオシロスコープが備える3つ目の測定ツールがカーソルである。 カーソルは画面上で移動できるマーカーで、時間軸または電圧軸の上に配置できる。 カーソルは通常2本組で提供され、片方ともう片方の差を測定できる。

カーソルを使い、方形波のリンギングを測定する。

求めたい量を測定できたら、回路に調整を加えてさらに測定を続けることができる。 オシロスコープの中には、波形の保存印刷記録に対応しているものもあり、後からその波形を呼び出して、あの信号をスコープで見たときの様子を思い出すこともできる。

自分のオシロスコープがどんなことをできるのか、詳しくは取扱説明書を確認してほしい。

オシロスコープの購入

この便利な道具の機能と利点を学んだところで、いよいよ作業台にオシロスコープを置く番である。 用途に応じたオシロスコープの選び方については、SparkFunの検索結果から探してみてほしい。

まとめ・参考資料

このチュートリアルで紹介した道具を身につければ、自分自身で信号をスコープにかける準備が整っているはずである。 オシロスコープの特定の部分が何のためにあるのかまだよくわからない場合は、まず取扱説明書を確認してほしい。 その他、次の資料も参考になる。

  • The XYZs of Oscilloscopes(PDF) — オシロスコープについて詳しく解説した優れた入門資料
  • How to Use an Oscilloscope(YouTube) — オシロスコープのメーカーであるTektronixによる、わかりやすい解説動画
  • GA1102CALユーザーズマニュアル — AttenのGA1102CAL(100MHzオシロスコープ)のユーザーズマニュアル。この機種固有の内容だが、同種のオシロスコープが何をできるか、どう動作するかの概要をつかむのに役立つ

さらに、オシロスコープに習熟してきたら、次はどんな回路をデバッグしてみたいだろうか。 ヒントが欲しい場合は、次の関連チュートリアルもおすすめである。

  • PCB設計ツールEagleの使い方 — 信号レベルで回路のトラブルシューティングをする段階に来ているなら、PCB設計に一歩踏み出す準備ができているのかもしれない。無料で使えるソフトウェアEAGLEで自分の基板を設計する方法を、一連のチュートリアルで解説している
  • Recreating Classic Electronics Kits — スコープでトラブルシューティングする回路を探しているなら、自分だけの「50-in-1電子工作キット」を作ってみるのはどうだろうか
  • パルス幅変調(PWM) — PWM信号は、LEDの調光やサーボモーターの駆動の基礎となる。この信号の種類を学んだら、身につけたスキルでスコープにかけてみよう

信号の確認にオシロスコープを使っている、次のようなチュートリアルも参考になる。

タグ: 電気工学、スキル、ツール


出典:How to Use an Oscilloscope(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

サーボモーター入門

サーボモーターは、電子工作プロジェクトに動きを加える手軽な方法である。 もともとはラジコンカーやラジコン飛行機で使われていたが、今ではさまざまな用途で使われるようになった。 サーボが便利なのは、モーターの位置決めを正確に制御できる点にある。 どこを指すか指示すれば、そのとおりに動いてくれる。

典型的なホビーサーボ

一般的なDCモーターには接続用のワイヤーが2本あり、電力を加えると単に回転し続ける。 逆方向に回したい場合は、電源の極性を反転させる必要がある。 どれだけ回転したかを知りたい場合は、それを測定する方法を自分で考える必要がある。

DCモーター(左)とホビーサーボ

対照的に、サーボモーターにはどこまで回転させるかを、精密にタイミングを合わせたパルスで指示する。 サーボには3本のワイヤーがあり、電源、グラウンド、そしてコマンドパルスを伝える3本目のワイヤーで構成される。

参考になるチュートリアル

サーボモーターの背景

最も一般的な意味では、「サーボメカニズム」(略してサーボ)とは、フィードバックを使って望ましい結果を得るための装置である。 フィードバック制御は、速度、位置、温度など、さまざまな分野で使われている。

ここで扱っているのは、ホビー用あるいはラジコン用のサーボモーターの文脈である。 これらは、主にラジコン車両のステアリングに使われる小型モーターである。 位置決めが簡単に制御できるため、ロボット工学やアニマトロニクスにも使われる。 ただし、産業機械で使われる大型のサーボモーターなど、他の種類のサーボモーターと混同しないよう注意してほしい。

さまざまなホビーサーボ

RC(ラジコン)用サーボはかなり標準化されている。どれも似た形をしており、両端に取り付け用のフランジがあり、ウルトラナノからジャイアントまで、段階的なサイズで販売されている。 サーボには、車輪やレバーなど「ホーン」と呼ばれる複数の取り付けパーツが付属していることが多く、これを軸に取り付けて、動かしたい装置に合わせられる。

サーボホーンの例

電気的な接続

ほとんどのホビーサーボは、同じ制御信号方式を使う標準的な3ピンプラグを採用しており、これによりRC用サーボはある程度互換性がある。

コネクタは、0.1インチピッチのメス3ピンヘッダーである。 少し紛らわしいのは、配線の色分けが常に一貫しているわけではなく、いくつかの色分け方式が存在する点である。 幸い、ピンの並び順はたいてい同じで、色だけが異なることが多い。

サーボケーブル

下の表は、よくある配色の方式をまとめたものである。 覚えやすい目安として、最も地味な色(黒や茶)はたいていグラウンド、赤はたいてい電源であることが多い。

ピン番号信号名配色1(Hitec)配色2(JR)配色3(Futaba)
1グラウンド
2電源
3制御信号オレンジ

サーボ接続の配色

注意! 配色に確信が持てない場合は、必ずドキュメントを確認すること。逆に接続してはいけない。

制御信号

サーボコネクタの3番目のピンは、モーターにどこまで動くかを指示する制御信号を伝える。 この制御信号は特定の種類のパルス列である。 パルスは20msec(50Hz)間隔で発生し、パルス幅は1〜2msecの間で変化する。 マイクロコントローラーで利用できるパルス幅変調(PWM)のハードウェアは、サーボの制御信号を生成するのに適した方法である。

一般的なサーボは、パルス幅が1〜2msecの間で変化するのに応じて90°の範囲で回転する。パルス幅が1.5msecのとき、可動範囲の中央に位置するはずである。

パルスと位置

サーボへの給電

RC車両では、公称の電池電圧は4.8Vである。 充電直後はこれよりやや高くなり、電池が消耗するにつれて電圧は下がっていく。 電圧が下がると、得られるトルクも下がる。RC車両を運転したことがあれば、電池が弱ってくるにつれて操作性が失われていく感覚はおなじみだろう。 止まる直前には動きが鈍く感じられるようになる。

電池を使わない場合は、一般的な電源から得られる5VDCがよい選択肢になる。 Arduinoや他のマイクロコントローラー(SparkFunのServo Triggerなど)でモーターを制御する場合、供給できる絶対最大電圧は5.5VDCである。

給電方法にかかわらず、モーターが消費する電流は機械的な負荷が増えるほど増加する点に注意してほしい。 軸に何も取り付けていない小型サーボはおよそ10mAしか消費しないかもしれないが、重いレバーを回す大型サーボは1アンペア以上を消費することもある。 電源がこの負荷に対応できないと、無理をしているサーボやストールしているサーボによって電源の電圧が下がり、マイクロコントローラーがリセットされるなど、予測できない影響が出ることがある。

さらに、複数のサーボを使う場合や、モーターが軽視できない負荷を動かす用途では、電源からそれぞれのサーボに直接、太めのゲージのワイヤーで配線する方がよい。あるサーボから次のサーボへ電源をデイジーチェーンでつなぐよりも確実である。 この構成は一般に「スターパワー」と呼ばれる。 それぞれが電源に直接つながっていれば、あるサーボが電源レールを下げてしまっても、他のサーボに影響が及びにくくなる。

スターパワー

迷ったときは、マルチメータを手に取り、消費電流を測定し、サーボが動いているときにVCCが下がっていないか確認するとよい。

中身を見てみよう

サーボモーターの内部では、回転軸に取り付けられたポテンショメータを使って位置を検知する仕組みになっている。 入ってくるパルスの幅を測定し、ポテンショメータの示す位置が入力パルス幅に対応するまで、モーターに電流を流して軸を回転させる。 これはフィードバック制御の一形態である。 モーターはパルス幅から望ましい位置を受け取り、実際の軸の位置はポテンショメータを介して回路にフィードバックされる。 回路は望ましい値と実際の値を比較し、実際の値が望ましい値に一致する方向にモーターを駆動する。

分解したサーボの内部を見てみよう。 ギア、DCモーター、位置検出用のポテンショメータ、そして小さなPCBが確認できる。 PCBの片面にはチップが一つあり、おそらく小型のマイクロコントローラーか、サーボ専用のICと思われる。

分解したRC用サーボの内部

PCBのもう一方の面には、個別のトランジスタがいくつかあり、おそらくHブリッジの構成になっている。これにより、コントローラーは時計回り・反時計回りのどちらの回転にも対応できるよう、モーターに流す電流の向きを切り替えられる。

PCBの裏面

いくつかの違い

プロジェクト用にサーボを探す際、いくつか意識しておきたいパラメータがある。

可動範囲の制約

1〜2ミリ秒というパルス範囲は、厳密な規格というより慣習に近い。 サーボによっては、さらに短い、あるいは長いパルスにも反応し、より広い可動範囲を持つものもある。

ただし注意が必要である。この拡張された可動範囲は、すべてのサーボに当てはまるわけではない。 機械的に90°の回転に制限されているサーボもある。 その限界を超えて駆動しようとすると、ギアが欠けるといった損傷を引き起こすことがある。 ここで分解したサーボも、まさにこの理由で壊れてしまったものである。

ギアの突起が、回転範囲を制限するために使われている。

位置決めと連続回転の違い

90°の範囲からさらに離れると、フルローテーション連続回転、あるいは単に**360°**サーボと呼ばれるものもある。 その名のとおり、軸は連続的に回転し続けるため、駆動用モーターとして便利である。 見た目は通常のサーボとほとんど変わらない。

よく見ると、パッケージに「360°」の表記があることに気づくはずである。

連続回転サーボは、位置を制御する代わりに、20msecのパルス列信号を軸の回転速度と方向に変換する。 それ以外の点では通常のRC用サーボとよく似ている。同じ電源、同じ制御信号、同じ3ピンコネクタを使い、RC用サーボと同じサイズで販売されている。

全体の速度は比較的遅く、最大でおよそ60RPM程度が一般的である。 より速い回転速度が必要な場合、サーボは最適な選択肢ではない。DCギアモーターやブラシレスDCモーターの方が適していることが多いが、これらはサーボの制御信号にそのまま対応しているわけではない。

ヌリングトリムポット

よく見ると、連続回転サーボには通常のサーボとの小さな違いが一つある。多くの場合、制御信号への応答を調整するための「ヌリング」トリムポットを備えている。 これは通常、1.5msecのパルスでモーターが停止するように設定されている。 それより短いパルスでは反時計回りに、長いパルスでは時計回りに回転する。

アナログとデジタルの違い

ここで扱っているパルス制御式のサーボはアナログである。 高速なパルス列を使い、シリアル通信インターフェースを介してより詳細な設定ができる、デジタル制御のサーボもある。こちらは通常、RC車両向けに調整されたパラメータを持つ。

プラスチックギアと金属ギアの違い

サーボを検討する際に見ておきたい最後の点が、内蔵されているギアの種類である。

安価なサーボ(ここで分解したものもそうである)には、たいてい成形プラスチック製のギアが使われているのに対し、より高価なサーボには金属製のギアが使われている。 プラスチックギアは、モーターが詰まったり過負荷になったりした際に欠けやすい。 古くからの格言のとおり、値段相応というわけである。

内側のギアの3時の方向あたりに、歯が欠けているのに注目してほしい。

サーボの使いどころ

従来のRC用途

冒頭で述べたとおり、ホビーサーボモーターの一般的な用途は、ラジコン車両のステアリングである。

RC送信機(左上)、受信機、ステアリング用サーボ

RC車両は、ジョイスティックとアンテナが付いた箱である送信機ユニットで制御する。 送信機は、サーボモーターに接続された受信機モジュール(上の写真のオレンジ色の箱)へ制御情報を送る。 送信機のスティックを動かすと、受信機はそれに対応するパルスを生成し、モーターに動作を指示する。

古いRC機体の設定にはかなりの忍耐が必要だった。 サーボを調整するには、サーボホーン、機械的なリンク、送信機のトリム調整を丁寧に手作業で行う必要があったためである。 現代の送信機・受信機はマイクロコントローラーをベースにしており、送信機のLCD画面や、あるいはコンピュータのインターフェースから調整できる。

Arduinoでサーボを制御する

サーボモーターは指示に応じて動くため、あらゆるプロジェクトに動きを加える手軽な方法である。 Arduino互換のプラットフォームを使っている場合、Arduinoのservoライブラリを使えば、サーボのパルス生成をすぐに利用できる。

推奨する部品

この例を作るには、次の部品が必要になる。

  • SparkFun RedBoard - Programmed with Arduino
  • サーボ - 汎用(サブマイクロサイズ)
  • USB Micro-Bケーブル(6フィート)
  • ジャンパー線
  • ACアダプタ電源(5VDC、2A、USB Micro-B)

ハードウェアの接続

サーボをRedBoardに接続するのはかなり簡単である。必要な接続はたった3つだけである。

サーボをRedBoardに接続する

特に、サーボモーターへの電源はVINピンから供給されており、オンボードのレギュレータを経由していない点に注意してほしい。 オンボードのレギュレータでは、最も小型のサーボ以外を駆動するには力不足である。 また、このプロジェクトは5VのACアダプタで給電されていることにも気づくはずである。 筆者の作業台では、USBポートから給電した場合、性能がぎりぎりだった。

ファームウェア

回路を接続したら、次のスケッチを読み込む。

注意: この例は、デスクトップ版Arduino IDEの最新版を使っている前提で進める。Arduinoを初めて使う場合は、Arduino IDEのインストールのチュートリアルを確認してほしい。 Arduinoライブラリを一度もインストールしたことがない場合は、インストールガイドを確認してほしい。

/******************************************************************************
servo-skatch.ino
Example sketch for connecting a hobby servo to a sparkfun redboard
  (https://www.sparkfun.com/products/9065)
  (https://www.sparkfun.com/products/12757)
Byron Jacquot@ SparkFun Electronics
May 17, 2016

**SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT).**

Development environment specifics:
Arduino 1.6.5
******************************************************************************/

#include <Servo.h>

Servo testservo;

uint32_t next;

void setup()
{
  // the 1000 & 2000 set the pulse width 
  // mix & max limits, in microseconds.
  // Be careful with shorter or longer pulses.
  testservo.attach(9, 1000, 2000);

  next = millis() + 500;
}

void loop()
{
  static bool rising = true;

  if(millis() > next)
  {
    if(rising)
    {
      testservo.write(180);
      rising = false;
    }
    else
    {
      testservo.write(0);
      rising = true;
    }

    // repeat again in 3 seconds.
    next += 3000;
  }

}

このスケッチは、サーボを左右に動かし続ける。

26行目のattach()の呼び出しに特に注目してほしい。 ここでは任意のminmaxパラメータを使い、パルスを1000〜2000マイクロ秒(1〜2ミリ秒)の範囲に制限している。 上記の「可動範囲の制約」の節で述べたとおり、この範囲を超えてサーボを駆動すると、サーボを損傷する恐れがある。

Servoオブジェクトは、範囲と位置の扱いが少しわかりにくいことがある。特にattach()の呼び出しで最小・最大パルスを指定している場合はなおさらである。 最小値と最大値が定義されている状態では、write()メソッドに渡すパラメータ(本来は度数で表される)は、その制約された範囲に再変換される。 この例では、write(0)は1ミリ秒のパルスになり、write(180)は2ミリ秒のパルスになる。 一般的なサーボでは、これはおよそ90°の動きに相当し、呼び出しのパラメータが示すような180°にはならない。

servoライブラリには他にもいくつか制約がある。 特に注意すべき点として、ピン9とピン10のanalogWrite()を上書きしてしまう。 このライブラリについて詳しくは、Arduinoのリファレンスページを確認してほしい。

うまく動作しないようであれば、後述のトラブルシューティングの節を確認してほしい。

Servo Triggerを使う

前のセクションではサーボの例をゼロからプログラムしたが、まったくプログラミングを必要としないサーボの使い方もある。

Servo Trigger

SparkFun Servo Triggerは、ホビーサーボの駆動に特化した小さな基板である。 トリムポットでサーボの位置を設定でき、スイッチを操作することでその位置同士を切り替えられる。 標準版と連続回転版が用意されている。 Servo Triggerについてさらに詳しくは、それぞれのHookup Guide(標準)Hookup Guide(連続回転)を参照してほしい。

トラブルシューティング

どんな方法でサーボを駆動している場合でも、動作させるにはちょっとした注意が必要になることがある。 いくつかトラブルシューティングのヒントを紹介する。

  • 負荷がかかっていないサーボでも、かなりの電力を消費することがある。フルパワーを出すには、電源が各サーボにつき最低1アンペアを供給できることを確認する必要がある。
    • 電源がその負荷に対応できていない場合、サーボの動作は悪くなる。適切に電力を供給されたサーボよりも動きが遅くなる。
    • 電力不足のサーボはハンチング(目的の位置にきれいに動かず、その位置付近で前後に揺れ続ける現象)を起こしやすい。可聴域でうなり音を発したり、繰り返しリセットしたりすることもある。
    • サーボとプロセッサが同じ電源を共有している状況では、サーボが電流を大量に消費したり(あるいはラインに大きなノイズを乗せたり)することで、プロセッサがリセットしたり誤動作したりすることがある。この問題への最も単純な解決策は、プロセッサとサーボを別々の電源で動かすことである(ただし、両者の間には共通のグラウンドを必ず用意すること)。より複雑な解決策としては電源のノイズフィルタリング技術があるので、詳しくは検索してみてほしい。
    • USB経由でプロジェクトに給電する方法は、最も小型のサーボモーターにしか向かない。中型のサーボは、USBポートから得られる100mAを簡単に超えてしまう。
    • サーボを動かそうとしたときに電源LEDがちらつく場合は、危険な状態にある。
  • サーボには最大速度がある。サーボの動きが不規則な場合、ある位置から別の位置へあまりに速く切り替えようとしている可能性がある。コマンドの間に一時停止を入れることで、サーボが反応する時間を確保できる。
  • 「可動範囲の制約」の節で述べたとおり、サーボによって可動範囲が異なることがある。
    • サーボを可動範囲の端を超えて駆動すると、うなり音を発したり、ギアがきしんだりすることがある。サーボがカチカチと音を立て始めたら、ギアが引っかかっているサインなので注意すること。
    • これがプロジェクトに影響する場合は、180°の回転に対応していると仕様に明記されたサーボを探すとよい。また、Servoライブラリのattach()コマンドでは、各サーボの最小・最大位置を細かく調整でき、限界を超えて駆動してしまうのを防ぐのに役立つ。

よいサーボライフを。

まとめ・参考資料

参考資料

さらに詳しく知りたい場合

  • サーボの詳しい情報や歴史については、WikipediaのRadio control Servosの記事を参照してほしい。
  • uArmは、サーボモーターで駆動するロボットアームである。
  • 通常のサーボを改造して、連続回転サーボに変えることもできる。
  • 制御基板を取り外して、サーボを小型のDCギアモーターに変えることもできる。

さらにサーボを楽しみたい場合は、次のようなSparkFunのチュートリアルも参考になる。

タグ: Arduino、部品、機構、モーション、モーター、電源


出典:Hobby Servo Tutorial(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

サーボモーターの基本的な制御方法

物体を単純に左右へ振らせる用途から、ロボットやラジコンカーのステアリングを追加する用途まで、ホビーサーボは次のプロジェクトに動きを加えるのに適した部品である。 サーボを使えば、出力軸の速度、方向、位置1を、たった3本のワイヤーで簡単に制御できる。

このチュートリアルでは、サーボを制御するいくつかの方法と、外部入力からサーボを制御する方法を示すプロジェクトを紹介する。 まず、まったくプログラミングを必要としない例を使って、サーボ制御の基本をいくつか説明する。 続いて、Arduino IDEとPythonを使ってコードでサーボを制御する。 自分が使いたい部品やコーディング環境に応じて、好きな例に読み進めてもらって構わない。

参考になるチュートリアル

このチュートリアルを進める前に、次の関連ガイドで、例の中で使う概念や部品について確認しておくとよい。

サーボモーターの基本

このチュートリアルの例に入る前に、サーボモーターの基本をいくつか確認しておこう。 サーボの詳しい背景や動作原理について詳しくは、サーボモーター入門を参照してほしい。

標準サーボと連続回転サーボ

SparkFunでは、標準(standard)と連続回転(continuous rotation)という2種類のホビーサーボを扱っている。 両者にはいくつかの違いがあるが、このチュートリアルの目的においては、標準サーボと連続回転サーボの主な違いだけを確認しておけば十分である。

標準サーボは、回転弧(通常は0〜90°または0〜180°)の範囲で動作し、コントローラーに位置のフィードバックを返す。 これにより、回転弧上の特定の位置までサーボを動かし、サーボ側がその位置をコントローラーに報告できる。 標準サーボは、ラジコンでのステアリング制御、ロボットグリッパーの制御、あるいはこのチュートリアルで後述するパン・チルトブラケットの制御など、位置決めが必要な用途に適している。

連続回転サーボ(フルローテーションサーボ、あるいは単に360°サーボと呼ばれることもある)は、通常のDCモーターにより近い動作をする。 サーボの位置を制御する代わりに、コントローラーはモーターの速度と方向を設定する。 連続回転サーボは、駆動用モーターや、わずかなワイヤーだけでモーターの速度と方向を制御したい用途に適している。

それぞれの種類に長所と短所があるため、自分のサーボプロジェクトに最も合った種類を検討するとよい。

コネクタのピン配置

どのサーボを使う場合でも、配線を間違えないよう、コネクタのピン配置を確認しておくことが特に重要である。

ほとんどのサーボは、電源(VCC)、グラウンド(GND)、制御信号について、特定の色分けの規則に従っている。 下の表は、よく使われる3種類のサーボコネクタタイプの色分けを示している。 ピン番号の並びはほぼどのメーカーでも共通だが、ワイヤーの色はメーカーによって異なることがある。 自分のサーボがこの表と一致しない場合や確信が持てない場合は、必ずサーボのドキュメントで確認すること。

ピン番号・名称配色 - Hitec配色 - Futaba配色 - JR
1. グラウンド(-)
2. 電源(+)
3. 制御信号黄または白オレンジ

一般的なサーボのピン配置の表

電圧範囲と電源

続いて、サーボプロジェクトの電源を選ぶ必要がある。 電源が供給する電圧が、そのサーボの電圧範囲(一般には4.8〜6Vだが、必ずサーボのデータシートで確認すること)に収まっていることを確認する。 また、電源がサーボを駆動するのに十分な電流を供給できることも確認する。 ここでも、サーボのデータシートを見れば、電源から流れうる最大電流を把握する手がかりが得られる。 通常、サーボモーターの最大消費電流を知るには、データシートに記載されているストール電流(記載がある場合)を確認すればよい。

制御信号の範囲

最後にもう一つ確認しておきたいのが、サーボの制御信号の範囲である。 このチュートリアルでは制御信号の範囲についてのみ扱う。 サーボの制御信号がどう機能するかについてより詳しく知りたい場合は、サーボモーター入門の「制御信号」を参照してほしい。

ここで覚えておきたい最も重要な点は、サーボの制御信号のパルス幅(持続時間)の範囲である。 これは通常1〜2msの間だが、メーカーやサーボの種類によって異なることがある。 モーターやギアボックスを傷めないよう、必ず自分のサーボの仕様でパルス範囲を確認すること。 これは特に、ArduinoやPythonのセクションで示すように、マイクロコントローラーやシングルボードコンピュータからPWM値を送る場合に重要である。

SparkFun Servo Triggerによるサーボ制御

最初の例では、SparkFun Servo Triggerを使ってサーボモーターを動かす方法を示す。 この例ではコーディングもコンピュータへの接続も不要だが、推奨する方法で組み立てるにはスルーホールのはんだ付けが必要になる。 スルーホール部品のはんだ付けに馴染みがない場合は、まずはんだ付けの基本(スルーホール編)を確認してほしい。

Servo Triggerは、基板にあらかじめ書き込まれたファームウェアが、基板上の3つのポテンショメータの位置を解釈することで動作する。 これらのポテンショメータは、サーボの開始位置・停止位置(「A」「B」とラベル付けされている)と、開始位置から停止位置まで移動するのにかかる時間(「T」とラベル付けされている)を決定する。 この移動シーケンスは、**INピンとGND**ピンを接続することで開始される。 この例では、コンケーブボタンを使ってこの接続を行う。

これはSparkFun Servo Triggerの動作についてのごく簡単な概要である。 基板の全体像と使い方について詳しくは、Servo Trigger Hookup Guideを参照してほしい。

必要な部品

この例を進めるには、ウィッシュリストにある部品が必要になる。 すでに持っている部品や使いたいサーボに応じて、カートの内容を自由に追加・削除してほしい。

注意: この例では標準のServo Triggerと標準サーボを使っているが、SparkFun Servo Trigger - Continuous RotationHigh Torque Continuous Rotation Servoのようなサーボに置き換えれば、連続回転タイプのプロジェクトにも簡単に応用できる。

必要な道具

上記の部品に加えて、回路を組み立てるには次の道具・材料を推奨する。

  • はんだ
  • はんだごて
  • はんだ吸い取り線
  • ワイヤーストリッパー

ハードウェアの接続

次の接続を行う必要がある。 下に、Servo Triggerに接続する部品のFritzing図を示す。 部品同士をどう接続するか、順を追って説明する。

回路が見づらい場合は、画像をクリックすると拡大表示できる。

必要な部品と道具がすべて揃ったら、いよいよ回路の組み立てを始める。 まず、Servo Trigger上のサーボ用ピンにはんだ付けする。 選んだブレイクアウェイヘッダーから3ピン分を切り出し、SIGVCC、**GND**とラベル付けされたサーボ用の3ピンの列にはんだ付けする。 オスヘッダーを使うことで、サーボモーターをトリガー基板に簡単に着脱できるようになる。 サーボのワイヤーハーネスが短すぎる場合は、サーボ延長ケーブルで延長できる。

次に、ボタンへの接続を行う。 2本のスペードコネクタを用意し、被膜を剥いた側の端を、サーボの接続とは反対側にあるServo Triggerの**INピンとGNDピンにはんだ付けする。 マイクロスイッチのないボタンを使いたい場合は、ジャンパー線など他の材料で制御入力(プッシュボタンなど)を接続してもよい。 はんだ付けが終わったら、INにはんだ付けしたワイヤーのスペードコネクタ側を、ボタンのマイクロスイッチのNOとラベル付けされたコネクタに、GNDにはんだ付けしたもう一方のスペードコネクタをCOM**コネクタに接続する。

回路の組み立ての最後の部分は、電源の接続である。 サーボの接続と同様にヘッダーをはんだ付けしてジャンパー線で電源に接続することもできるが、これは電源に直接つながる部分なので、確実な接続にするため、Servo Trigger側面の**VCCピンとGND**ピンにワイヤーを直接はんだ付けする。

電源用の電源ラインとグラウンドライン用に、2本のワイヤーを用意する。 それぞれのワイヤーの片端の被膜を剥き、下の写真のようにServo Trigger側面の**VCCピンとGND**ピンにはんだ付けする。

続いて、DCバレルジャックアダプタを使う場合、Servo Triggerにはんだ付けしたワイヤーのもう一方の端の被膜を少し剥き、アダプタ端のねじ端子に差し込んで、ドライバーで固定する。 VCCピンにはんだ付けしたワイヤーは「+」とラベル付けされた端子に、GNDにはんだ付けしたワイヤーは「-」とラベル付けされた端子に対応させること。

⚡ 注意! VCCとGNDを、DCバレルジャックアダプタの対応する接続(「+」「-」とラベル付けされている)に必ず接続すること。逆に配線すると回路がショートし、Servo Trigger、サーボ、電源を損傷する恐れがある。

Servo Triggerへのはんだ付けがすべて終わり、ボタンとサーボが接続されたら(まだ接続していなければ)、電源を接続してボタンを押してみる。 サーボが片側からもう片側へ振れる動きが見えるはずである。 Servo Trigger上の3つのポテンショメータを調整し、サーボの方向、動作角度、動作時間を切り替えてみてほしい。

トラブルシューティングのヒント

サーボが動かない、または電源が入らない

サーボが動かない、あるいはボタンを押しても反応しない場合、最もよくある原因ははんだ付け不良である。 サーボの電源が入らない、あるいはボタンを押しても動かない場合は、はんだ付けがピンやワイヤーとはんだパッドを完全に接続しているか、ワイヤーやはんだ付け部分同士が触れ合っていないか確認すること。 また、電源がDCバレルジャックアダプタとコンセントにしっかり差し込まれており、サーボとServo Triggerを駆動するのに十分な電圧を供給しているかも確認すること。 はんだ付け不良の修正のコツについては、SparkFunのトラブルシューティングのコツを参照してほしい。

不規則な動き

これは、ポテンショメータがサーボのパルス範囲を超えて設定されているか、ボタンの配線が逆になっている可能性がある。 「A」と「B」のポテンショメータを調整して、不規則な動きを直してみてほしい。 電源を入れた直後にサーボがすぐに動いてしまい、その後ボタンを押しても予期しない反応をする場合は、ボタンのワイヤーのどちらかが誤って接続されている可能性がある。 INピンがボタンのNOコネクタに、GNDピンがCOMコネクタに接続されているか確認すること。

ArduinoとServoライブラリによるサーボ制御

2つ目のサンプル回路は、組み立てはずっと簡単ではんだ付けも不要だが、Arduino IDEでコードをアップロード・使用する必要がある。 Arduinoに馴染みがない、あるいはコンピュータにインストールしていない場合は、まず下記のガイドでIDEをインストールし、Arduinoを始めてみてほしい。

SparkFun RedBoard Qwiicを、パルス幅変調(PWM)を使ったサーボモーターのドライバー・コントローラーとして使う。

必要な部品

この例を進めるには、下記の部品が必要になる。 すでに持っている部品や、別の開発ボード・サーボを使いたい場合に応じて、カートの内容を調整してほしい。

ハードウェアの組み立て

この回路で必要なのは、下の図のようにサーボモーターをRedBoardに接続することだけである。

この回路のセットアップは、RedBoard Qwiicの3本のピンだけを使うためとても簡単だが、サーボの電源ピンは5VではなくVINに接続する点に注意してほしい。 5Vピンは最大250mAまでしか供給できず、ほとんどのサーボを駆動するには不十分なため、代わりにVINピンを使う。

注意! この例のように、コンピュータからUSB経由でRedBoard Qwiicに給電している限り、VINからサーボに給電する方法でうまく動作する。ただしVINピンは電源に直接つながっているため、バレルジャックコネクタなど他の方法でRedBoardに給電する場合は、その電圧がサーボの電圧範囲に収まっていることを確認すること。

Arduinoのコード

回路の配線が終わったら、いよいよコードをアップロードする番である。 RedBoard(または他の開発ボード)をUSBケーブルでコンピュータに接続し、表示されるポートを確認する。 続いてArduino IDEを開き、下のコードをコピーして新しいスケッチに貼り付ける(デフォルトのコードテンプレートを必ず削除すること)。

次に、Toolsメニューでボードの種類(この場合はArduino/Genuino Uno)と、ボードが列挙されたCOMポートを選択する。 続いて「Upload」ボタンをクリックする。 コンパイルとアップロードにエラーがなければ、サーボが左右に振れる動きが見えるはずである。

/******************************************************************************
servo-sketch.ino
Example sketch for connecting a servo to a SparkFun RedBoard
  Servo Motor: (https://www.sparkfun.com/products/11965)
  SparkFun RedBoard: (https://www.sparkfun.com/products/13975)
Byron Jacquot@ SparkFun Electronics
May 17, 2016

**SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT).**

Development environment specifics:
Arduino 1.6.5
******************************************************************************/

#include <Servo.h>

Servo my_servo;

uint32_t next;

void setup()
{
  // the 1000 & 2000 set the pulse width 
  // mix & max limits, in microseconds.
  // Be careful with shorter or longer pulses.
  my_servo.attach(9, 1000, 2000);

  next = millis() + 500;
}

void loop()
{
  static bool rising = true;

  if(millis() > next)
  {
    if(rising)
    {
      my_servo.write(180);
      rising = false;
    }
    else
    {
      my_servo.write(0);
      rising = true;
    }

    // repeat again in 3 seconds.
    next += 3000;
  }

}

コツとトラブルシューティング

コンパイル・アップロードのエラー

コンパイルやアップロードでエラーが出た場合、最もよくある原因はポートの選択間違いである。 RedBoardが接続されているポートを再確認し、もう一度試してみてほしい。 「Port」メニューに複数のポートが表示される場合は、RedBoardを接続する前にどのポートが利用可能か確認しておき、接続後にそのメニューに新しく表示されたポートを選択するとよい。

もう一つ考えられる問題は、コードが正しくコピーされていない場合である。 よくある原因は、デフォルトのコードテンプレートがサンプルコードで完全に削除・上書きされていないことである。 自分のコードをざっと確認し、重複したvoid loop();void setup();、あるいはデフォルトテンプレートの残骸が残っていないか確認すること。 画面下部に表示されるエラーの詳細を見れば、エラーの内容や、コード中のコンパイルエラーの箇所についてより詳しい情報が得られる。

サーボの動作の問題

サーボがまったく動かない場合は、おそらくワイヤーの配線を間違えている。 RedBoard上の正しいピンにサーボが接続されているか、配線をやり直して確認してみてほしい。

サーボがガタガタ動く、あるいは固まっているように見える場合は、サーボのパルス範囲を超えて駆動している可能性がある。 サーボのデータシートを確認し、setup内のservo.attach(9, 1000, 2000);関数の2番目と3番目の値を調整してほしい。

PythonとPi Servo pHATによるサーボ制御

3つ目の例では、Raspberry PiSparkFun Servo pHAT for Raspberry Piを、SparkFun PiServoHAT Pythonモジュールとともに使い、サーボを駆動する方法を示す。 Servo pHATは最大16個のPWMデバイスを制御できるため、複数のサーボやLEDなど他のPWMデバイスを組み合わせるプロジェクトに適している。 Raspberry Piは、前の例で使ったRedBoardのような開発ボードよりもはるかに高い処理能力を持つため、複雑なプロジェクトに向けてさまざまな処理をバックグラウンドで実行できる。

Raspberry PiやServo pHATを使ったことがない場合は、続ける前に次のチュートリアルを読むことを強く推奨する。 「Getting Started with the Raspberry Pi」のチュートリアルは、Raspberry Piをセットアップする上で最も重要であり、これを先に済ませておかないとこの例を進めることはできない。

必要な部品

この例を進めるには、次の部品が必要になる。 すでに持っている部品や、別のRaspberry Piサーボを使いたい場合に応じて、カートを調整してほしい。

これらの部品に加えて、Raspberry Piを設定・操作するためのキーボード、マウス、モニタも用意しておくとよい。 あるいは、別のコンピュータを使ってRaspberry Piのヘッドレスセットアップを行うこともできる。 また、すでに使いたいSDカードがある場合は、Raspberry Pi FoundationのSetting up your Raspberry Piガイドの手順に従い、Raspbian OSをダウンロード・インストールすることもできる。

ハードウェアの接続

Servo pHATの接続自体はかなり単純だが、いくつか注意点がある。 すべての電源を切った状態で、下の写真のような向きになるよう注意しながら、pHATをPiの2×20 GPIOヘッダーに取り付ける。

Raspberry Pi 3(左)とRaspberry Pi Zero W(右)に正しく接続されたPi Servo pHAT。画像をクリックすると拡大表示できる。

続いて、サーボのピンとServo pHATのシルクスクリーンのラベルを合わせながら、3ピンのチャンネルヘッダーのいずれかにサーボを接続する。 今回使う例ではデフォルトでチャンネル0を使うので、別のチャンネルを使う場合はコードもそれに合わせて調整すること。 Piの電源が入っている状態でサーボを接続してはいけない。急激な電流の変化により、Raspberry Piがリセットされることがある。

続いて、Piを接続する。 そして電源を入れれば、プログラミングに進む準備は完了である。 下の写真は、Raspberry PiとPi Servo pHATへの給電方法の2つの選択肢を示している。

さまざまな電源の選択肢のうち、2つの例。

Pythonパッケージ

ハードウェアの組み立てがすべて終わり、Piの設定も準備できたら、いよいよPythonモジュールをインストールし、サンプルの一つを実行する番である。 今回は、Example 2 - Full Sweep with 180 deg. Servoを使う。

まず、Piにパッケージをインストールする必要がある。 このチュートリアルを簡潔にするため、ここではSparkFun Qwiic Pythonパッケージ一式をインストールする方法だけを扱う。 パッケージの一部だけをインストールしたい場合や手動でインストールしたい場合は、Pi Servo pHAT (v2)の使い方の「Pythonパッケージの概要」で詳しい手順を確認してほしい。

SparkFun Qwiic Pythonパッケージは、SparkFunのQwiic製品向けに利用可能なPythonパッケージをすべてインストールし、必要なI2Cドライバーパッケージも含んでいる。 pip3(Python 2の場合はpip)経由でPyPiに対応しているシステムでは、次のコマンドで簡単にインストールできる。

すべてのユーザー向け(sudo権限が必要な点に注意)には、コマンドプロンプトから次のコマンドを入力する。

sudo pip3 install sparkfun-qwiic

現在のユーザーだけにパッケージをインストールしたい場合は、コマンドプロンプトで次のコマンドを入力する。

pip install sparkfun-qwiic

SparkFun Qwiicパッケージのインストールが終わったら、いよいよコードを作成して実行する番である。 下のコードをダウンロードするか、コピーしてファイルに貼り付ける。 続いて、ファイルを開いて(あるいは保存して)、好みのPython IDEでコードを実行する。 たとえば、Raspbianのデフォルトの開発環境であるIDLEでこの例を実行するには、Run > Run Moduleをクリックするか、F5キーを使う。 サンプルを止めるには、Ctrl + Cのキーの組み合わせを使う。

このサンプルを実行している間、サーボが180度の弧を左右に動く様子が見えるはずである。

#-----------------------------------------------------------------------
# Pi Servo Hat - Example 2
#-----------------------------------------------------------------------
#
# Written by  SparkFun Electronics, June 2019
# Author: Wes Furuya
#
# Compatibility:
#     * Original: https://www.sparkfun.com/products/14328
#     * v2: https://www.sparkfun.com/products/15316
#
# Do you like this library? Help support SparkFun. Buy a board!
# For more information on Pi Servo Hat, check out the product page
# linked above.
#=======================================================================

"""
This example should be used with a 180 degree (range of rotation) servo
on channel 0 of the Pi Servo Hat.

The extended code (commented out), at the end of the example could be
used to test the full range of the servo motion. However, users should
be wary as they can damage their servo by giving it a position outside
the standard range of motion.
"""

import pi_servo_hat
import time

# Initialize Constructor
test = pi_servo_hat.PiServoHat()

# Restart Servo Hat (in case Hat is frozen/locked)
test.restart()

# Test Run
#########################################
# Moves servo position to 0 degrees (1ms), Channel 0
test.move_servo_position(0, 0, 180)

# Pause 1 sec
time.sleep(1)

# Moves servo position to 180 degrees (2ms), Channel 0
test.move_servo_position(0, 180, 180)

# Pause 1 sec
time.sleep(1)

# Sweep
#########################################
while True:
    for i in range(0, 180):
        print(i)
        test.move_servo_position(0, i, 180)
        time.sleep(.001)
    for i in range(180, 0, -1):
        print(i)
        test.move_servo_position(0, i, 180)
        time.sleep(.001)

#########################################
# Code below may damage servo, use with caution
# Test sweep for full range of servo (outside 0 to 180 degrees).
# while True:
#     for i in range(-45, 200):
#         print(i)
#         test.move_servo_position(0, i, 180)
#         time.sleep(.001)
#     for i in range(200, -45, -1):
#         print(i)
#         test.move_servo_position(0, i, 180)
#         time.sleep(.001)

トラブルシューティングのヒント

サーボが動かない、あるいはPi側でServo pHATが認識されない場合は、次のヒントを参考にしてほしい。

デバイスが見つからない

OSError: [Errno 121] Remote I/O errorというエラーが表示される場合は、GPIOヘッダーへの接続を再確認してほしい。

また、Raspberry Pi上でI2Cハードウェアが有効になっているかも確認すること。 有効になっていない場合、おそらくFailed to connect to I2C bus 1.というエラーが表示される。 PiでI2Cを有効化する方法については、Raspberry PiのSPIとI2Cチュートリアルの「PiでのI2C」を参照してほしい。

I2C接続を確認する

Raspberry PiがI2C経由でServo pHATと通信できているかを確認する簡単な方法は、I2Cバスにpingを送ることである。 最新版のRaspbian Stretchでは、i2ctoolsパッケージがあらかじめインストールされているはずである。 入っていない場合は、ターミナルで次のコマンドを実行する。

sudo apt-get install i2ctools

i2ctoolsパッケージがインストールされたら、ターミナルで次のコマンドを実行してI2Cバスにpingを送れる。

i2cdetect -y 1

ターミナルに表が表示されるはずである。 Servo pHATが正しく接続され動作していれば、0x40のアドレス空間が40とマークされているはずである。

電流消費の問題

サーボが電源の許容範囲を超える電流を消費している場合、Servo pHATは正しく動作せず、Raspberry Piが再起動したり、電圧不足で断続的に不安定になったりすることがある。

特に大型のサーボを使っている場合や、多数のサーボで重い負荷を駆動している場合、PiのUSBポートでPiとServo pHATの両方に給電していると、Piが再起動したり電圧不足になったりすることがある。 pHAT上のUSB-Cコネクタから直接PiとServo pHATに給電するよう切り替えることもできるが、より良い解決策は、Power Isolationジャンパーを切断し、それぞれのデバイスに個別に給電することである。 このジャンパーの場所と変更方法については、Pi Servo pHAT (v2)の使い方の「ジャンパー」で説明している。

Qwiic Joystickによるサーボの直接制御

ループでサーボを制御する方法は、電源が入っている間ずっと何かを動かし続けたいプロジェクトには適しているが、サーボをもっと直接的に制御したい場合はどうすればよいだろうか。 このプロジェクトでは、まさにその方法を示す。

このプロジェクトでは、Qwiic Joystickを入力として使い、RedBoard Qwiicに取り付けたパン・チルトブラケット上の2つのサーボを制御する。 Qwiic Joystickについて詳しくは、Qwiic Joystick Hookup Guideを確認してほしい。

必要な部品

このサンプルプロジェクトを進めるには、次の部品が必要になる。 すでに持っている部品に応じて、カートの内容を更新するとよい。

ハードウェアの接続

このプロジェクトでまず組み立てるのは、2つのサブマイクロサーボを使ったパン・チルトブラケットである。 サーボを使ってパン・チルトブラケットを組み立てる基本的な手順は、組み立てガイドを参照してほしい。

組み立てのコツ: サーボを正しく位置合わせしておくと、可動範囲をフルに活用でき、配線が終わった後でサーボを付け直す手間を避けられる。

フィット感によっては、ガイドで示されている2枚ではなく3枚のワッシャーで間隔を調整する必要があるかもしれない。

パン・チルトブラケットを組み立てたら、サーボの信号線をRedBoard上の指定されたI/Oピンに接続し、Qwiic CableでQwiic JoystickをRedBoardに接続する。 サンプルコードでは、デフォルトで水平方向のサーボにD9、垂直方向のサーボにD10を使っているが、必要であればservoH.attach(9);servoV.attach(10);の関数を変更して別のピンに接続することもできる。

最後に、サーボの電源ピンを接続する必要がある。 先ほどのArduino Servoライブラリの例と同様に、RedBoardのVINピンを使う。 5Vピンは最大250mAまでしか供給できず、パン・チルト用サーボはブラケットに何も取り付けていない状態でも350mAを超える電流を消費することがあるためである。

パン・チルトブラケットには2つのサーボがあるため、ブレッドボードを使って両方のサーボの電源ピンをまとめて接続する。

注意: ブレッドボードを使ったことがない場合は、ブレッドボードの使い方を確認することを推奨する。

各サーボの電源ピンとグラウンドピンをブレッドボードの「+」「-」レールに接続し、続いてRedBoardの電源を切った状態で、RedBoardのVINピンとGNDピンも同じブレッドボードのレールに接続する。 すべての電源・グラウンドピンを正しく接続したら、RedBoardをUSBで接続する。

注意! シンプルなArduinoの例と同様に、VINピンはUSBポートに接続されている場合5Vを出力するため、サーボの駆動に問題なく使える。ただし、回路に別の電源を使う場合は、サーボの電圧範囲内で給電するよう注意すること。このプロジェクトで使うサーボ(および他のほとんどのホビーサーボ)の場合、4.8〜6Vである。

回路が見づらい場合は、写真をクリックすると拡大表示できる。

Arduinoのコード

配線がすべて終わったら、いよいよコードをアップロードする番である。 まず、Qwiic Joystickライブラリがまだインストールされていなければインストールする。 上記のリンクからダウンロードして手動でインストールすることもできるが、Library Managerツールからインストールすることを推奨する。 Library Managerを開き、「SparkFun Qwiic Joystick」を検索してインストールをクリックするだけでよい。 Arduinoのライブラリをインストールしたことがない場合は、Installing an Arduino Library Tutorialで手順全体を確認できる。

ライブラリのインストールが終わったら、下のコードをコピーして新しいスケッチに貼り付ける。 ボードとして「Arduino/Genuino Uno」(あるいは別の開発ボードを使っている場合はそれ)を選択し、ボードが接続されている「Port」を選んでコードをアップロードする。

/*
 Example code to control two servos using the SparkFun Qwiic Joystick.
 Code takes the readings of the Vertical (Y) and Horizontal (X) axes of the joystick
 and maps them to values between 0 and 180 degrees.

 Based off of the Arduino "Knob" example:

 Controlling a servo position using a potentiometer (variable resistor)
 by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>

 modified on 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Knob
*/

#include <Servo.h>
#include "SparkFun_Qwiic_Joystick_Arduino_Library.h"

JOYSTICK joystick; // create joystick object to send position values


Servo servoH;  // create servo object to control a servo
Servo servoV;

int h;    // variable to read the horizontal values from the Qwiic Joystick
int v;    // variable to read the vertical values from the Qwiic Joystick

void setup() {
  servoH.attach(9); // attaches servo1 on pin 9 to the servo object
  servoV.attach(10);  // attaches servo2 on pin 10 to the servo object
  Serial.begin(9600);
  Serial.println("Qwiic Joystick Servo Control");

  if(joystick.begin() == false)
  {
    Serial.println("Joystick not connected. Check wiring. Freezing...");
    while(1);
  }
}

void loop() {
  h = joystick.getHorizontal();   // reads the value of the Qwiic Joystick's horizontal axis (between 0 & 1023)
  h = map(h, 0, 1023, 0, 160);     // scale it to use it with the servo (value between 0 and 180)
  servoH.write(h);                  // sets the horizontal servo position according to the scaled value
  v = joystick.getVertical(); // reads the value of the Qwiic Joystick's vertical axis (between 0 & 1023)
  v = map(v, 0, 1023, 0, 165);
  servoV.write(v);
  delay(15);    // waits for the servo to get there
  /*Serial.print("X: ");  //uncomment these lines to view the serial print of the x and y axes of the Qwiic Joystick 
  Serial.print(joystick.getHorizontal());   //these can be helpful for debugging or identifying any drift on your joystick
  Serial.print("Y: ");
  Serial.print(joystick.getVertical());
  Serial.println();*/
}

コードのアップロードが終わったら、ジョイスティックを動かしてみてほしい。 下のGIFのように、9番ピンに接続したサーボが水平方向の動きに、10番ピンに接続したサーボが垂直方向の動きに反応するはずである。

トラブルシューティングのヒント

この例でよくあるつまずきポイントについて、いくつかヒントを紹介する。

コンパイル・アップロードのエラー

avrdude stk500_recv() programmer is not respondingや、対象デバイス(つまりRedBoard)に関する類似のエラーが出た場合は、RedBoardの正しいポートと正しいボードの種類を選択しているか確認してほしい。

SparkFun_Qwiic_Joystick_Arduino_Library.h: No such file or directoryのようなエラーが出た場合は、Qwiic Joystickライブラリが正しくインストールされていない。 Arduino Library Managerツールで、ライブラリがインストールされていて最新版になっているか確認してほしい。

電源の問題

この例ではブレッドボードを使っているため、電源関連の問題(たとえばUSBを接続しても回路全体の電源が入らないなど)でよくある原因は、ワイヤーの配線ミスである。 ブレッドボード上のすべての電源線とグラウンド線が正しく接続されているか確認すること。 よくあるミスは、ワイヤーの一部が逆になっている(電源とグラウンドが入れ替わっているなど)ことである。 ブレッドボードの正しいレールに差し込まれ、サーボとRedBoardの両方としっかり接続されているか確認してほしい。

まとめ・参考資料

さまざまな方法でサーボを制御する基礎がしっかり身についたところで、次はこれらをプロジェクトにどう組み込むか考える番である。 パン・チルトブラケットには、カメラやLEDアレイなど、いろいろなものを追加できる。 先ほどのプロジェクトのQwiic Joystickを、IMUのような別のセンサーに置き換えることもできるし、ジョイスティックのデータを無線接続で送信すれば、自分だけのラジコンカーやロボットを作る道も開けてくる。

サーボをプロジェクトに組み込むアイデアが欲しい場合は、サーボを使った次のようなチュートリアルも参考にしてほしい。

自分のサーボプロジェクトのヒントとして、次のようなブログ記事も参考になる。

タグ: Arduino、Hookup、モーター、Python、Qwiic、Raspberry Pi


出典:Basic Servo Control for Beginners(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。


  1. 出力軸の位置フィードバックは、標準(クローズドループ)サーボでのみ利用できる。この点については次のセクションで詳しく説明する。

ペーパー回路総合ガイド

ペーパー回路は、趣味の電子工作の世界でますます人気を集めている。 クラフト用の材料が手に入りやすくなり、新しい製品も次々と登場したことで、電子工作に踏み出そうとするクラフターにとって独特のエコシステムが生まれた。 このガイドでは、ペーパー回路の制作に使える材料と技法の全体像を紹介する。

ペーパー回路とは何か

ペーパー回路とは、PCBではなく紙の上に組み立てられた、実際に機能する電子回路のことである。 グリーティングカードや折り紙から、絵画やデッサンといった伝統的なアート作品まで、題材の幅は広い。 ペーパー回路の特徴は、伝統的なファインアートの技法を使い、美しさと機能性を兼ね備えた回路を作り上げる点にある。

参考になるチュートリアル

制作を始める前に、次の概念に馴染んでおくとよい。

トレースを作る:概要

トレースとは、配線の代わりとなる経路のことで、プリント基板でよく目にするものである。 ペーパー回路では、紙の表面で部品同士をつなぐ配線の代わりとして導電性の材料を使う。 このチュートリアルでは、塗料、テープ、インクという3種類のトレースを扱う。

このPCBの緑色の線が、基板の各部をつなぐトレースである。

導電性テープのトレース

導電性テープは、ペーパー回路の制作を始める上で最も手軽な方法の一つである。 台紙をはがして、回路を通したい場所に貼り付けるだけでよい。 銅テープははんだ付けにも対応しており、塗料やインクの手法では得られない、部品とトレースの間の強固な接続を作ることができる。

銅テープとSparkFunのテンプレートを使ったプロトタイピング

難易度: 初心者向け コスト: 材料による(銅テープは1フィートあたり約0.06ドル、ファブリックテープは約0.79ドル) 汚れやすさ: 最小限

長所

  • 乾燥時間が不要
  • はんだ付け可能(銅テープのみ)
  • 地元で手に入れやすい。銅テープはナメクジよけとしても使われるため金物店で売られていることが多く、ステンドグラス制作にも使われるため手芸店や趣味用品店にも置かれていることがある。ただし、すべてのテープが同じ品質とは限らない。手芸店のテープは扱いにくく、粘着面自体が導電性でないこともある。

短所

  • 銅テープで紙のように指を切ることがあるため、扱いには注意が必要である。
  • 滑らかな線や形を作るのが難しい。テープを細く切ることである程度対応できる。
  • 導電性ファブリックテープは高価になりがちである。

銅テープ

ペーパー回路で最も一般的な導電性テープは、薄い銅のシートの片面に粘着剤を塗り、ロール状にしたものである。 メーカーによって幅にいくつかの種類があるが、5mm幅のテープは小さなクラフト作業でも扱いやすく、よく使われている。

ニッケル・銅・コバルト製 幅1インチのファブリックテープ

画像:LessEMF.com

銅テープほど一般的ではないが、ニッケル、銅、コバルトでできた導電性ファブリックテープもある。 このテープは曲げやたわみに強く、折り目のあるプロジェクト(中央の折り目をまたいでトレースを通す必要のあるカードなど)に向いている。

手順

  • 台紙をはがし、トレースを通したい場所に貼り付ける。その際、部品を配置する箇所にはテープの隙間を残すようにする。最も信頼性の高い回路にするには、部品同士の間はできるだけ一続きのテープでつなぐとよい。角を曲げる際は折りたたむ技法を使うか、必要に応じてテープ片同士をはんだ付けする。
  • 銅テープの場合、曲げたリード線の上に透明テープを貼ってトレースに固定する。より確実に固定するにはんだ付けを使うとよい。ファブリックテープの場合は、導電性の接着剤を使うか、導電性の糸で縫い付けることを推奨する。

LEDのために隙間を空けて銅テープを切っている様子に注目してほしい。

制作例

Chibitronicsによるこの赤面ロボットカードは、薄い銅テープでカード内側のメッセージの文字を形作りつつ、表面のLEDの回路も同時に作っている。

Jie Qi氏のCircuit Sketchbookは、本の綴じ部分に導電性ファブリックテープを、表紙の内側に銅テープを使っている。

さらに参考になる資料

  • Paper Circuits with Copper Tape — MITのHigh-Low Tech LabでJie Qi氏が開発した、銅テープを使ったペーパー回路のもとになった資料の一つ。印刷用のテンプレートや技法も掲載されている。
  • Getting Started with Copper Tape for Electronics — 銅テープの扱い方、接続の作り方、角やカーブの折り方を紹介する動画。
  • Soldering Conductive Fabric — KobakantのHannah Perner-Wilson氏による、さまざまな種類の生地へのはんだ付けの検証記録。

導電性塗料のトレース

導電性塗料は、電子工作をアート作品として仕上げるのに適した手法である。 筆や絞り出しボトルを使い、曲線や渦を描くように部品同士をつなぐトレースを作ることができる。 導電性塗料は、部品をトレースに「接着」するのにも使える。 この手法は、汚れやすさと乾燥にかかる時間の長さから、扱いに最も苦労することが多い。 慣れないうちは、根気よく練習を重ねることを推奨する。

難易度: 初心者〜中級者(複雑さによって変わる)。滑らかな線を引くのに苦労することがある。 コスト: 材料による。ほとんどの導電性塗料は10ドル程度から。 汚れやすさ: 中程度

Bare Conductive Paintを筆で塗っている様子。画像:Instructables.com

長所

  • 他の水性塗料と同じように扱える。
  • 乾燥後にアクリルなど他の塗料を重ね塗りでき、継ぎ目のないアート作品に仕上げられる。
  • 既存のトレースの上に塗料を重ねやすく、接続不良のトラブルシューティングや修正がしやすい。

短所

  • 完全に乾くまでは導電性を持たない。塗りの厚みや塗料の種類によっては、一晩かけて乾かす必要がある。ヘアドライヤーやヒートガンを使えば乾燥を早められる。
  • 均一な線やトレースを引けるようになるには、ある程度の練習が必要になることがある。
  • 銅ベースの塗料は酸化が早く、保存期間が短いことがある。
  • 力が加わるとひび割れやすい。平らな面での使用に最も向いている。折り目や曲げの必要なプロジェクトに塗料でトレースを描くと、繰り返しの動きでたいてい壊れてしまう。

Bare Conductive Electric Paint

Bare ConductiveのElectric Paintは、無毒で溶剤を含まない、水溶性のカーボンベース塗料である。 細い線を引くための絞り出しチューブと、筆やステンシルで使うための容器入りの両方が用意されている。

CuPro-Cote Paint(LessEMF製)

CuPro-Cote Paintは、ラテックス塗料に似た、銅を含む水性塗料である。 4オンスからガロン単位まで容量がある。 開封後は保存期間・作業可能時間が短いため、4オンスサイズを推奨する。

手順

  • 回路のデザインを考える際は、まずトレースを通す場所を下書きする。塗る前に鉛筆やマーカーで経路を描いておくと、作業がずっと楽になる。
  • 使用する部品を紙に接着しておく。小さな部品は、ピンセットで正確に配置するとよい。
  • 筆や絞り出しボトルを使い、トレースに沿って、また回路上の部品のワイヤーやパッドの上に、慎重に塗料を塗っていく。テストする前に完全に乾かすこと。

MITで開催された塗装式電子工作のワークショップで、線に沿って慎重に導電性塗料を塗るアーティスト。

制作例

Electronic Popablesは、導電性塗料と電子部品で作られたインタラクティブな飛び出す絵本である。

Hannah Perner-Wilson氏によるPaper Piano

さらに参考になる資料

導電性インクのトレース

導電性インクは、あらかじめインクを充填したペンとして販売されており、線を描くだけでトレースを作れるようになった。 ほとんどの導電性インクペンは、導電性塗料よりも速く乾く。 この手法は塗るのが最も簡単な一方、部品の接続にはやや苦労することがある。

難易度: 初心者〜中級者(インクにどんな部品を接続するかによる) コスト: やや高め。ほとんどのペンは20ドル程度から。 汚れやすさ: 最小限

Circuit Scribeペンで描いている様子。画像:Circuit ScribeのKickstarterページより。

長所

  • 導電性塗料より速く乾く。
  • 精密な線を引ける。
  • 直感的に使える。

短所

  • 部品の接続がやや難しいことがある(技法については「接続の作り方」の節を参照)。
  • 使う紙の種類によっては、インクが定着しないことがある。写真用紙が最も相性がよい。
  • 通常のペンやマーカーと見間違えて、電子工作以外のプロジェクトで誤って使ってしまうことがある。

Circuit Scribe

Circuit Scribeは、ゲルインクペンのような書き心地の、無毒な銀の導電性インクペンである。 回路を精密な線で描いて見せる(そして光らせる)のに適している。

AgIC Circuit Marker

AgICは、マーカー形式で販売されているもう一つの銀ベースのインクである。 EPSON製の光沢写真用紙にしか使えないため、それに合わせてプロジェクトを計画する必要がある。

手順

  • 鉛筆で回路を下書きする(導電性インクキットにステンシルが付属している場合はそれも使う)。インクはプリンタのトナーにうまく定着しないため、コンピュータで回路をデザインする場合は、直接なぞる線ではなく、塗りつぶす輪郭線として出力しておくこと。
  • 導電性インクペンで慎重に線をなぞり、部品同士の間で経路が途切れないようにする。部品がトレースに接続する箇所には、大きめの円やパッドを残しておく。
  • インクの線の上にテープ、導電性接着剤、あるいはサーキットステッカーを使って部品を取り付ける。

制作例

Paperduino 2.0 — Circuit Scribeのインクと部品だけで作られた、丸ごと一つのArduino。画像:Instructables

SparkFunの教育チームが制作した、Circuit Scribeのモジュールとインクを使ったインタラクティブアート。

さらに参考になる資料

  • ElectronInks Resources — Circuit Scribeの開発元が提供する、無料でダウンロードできるワークブックなど、導電性インクを使うための情報。
  • 123D Circuits: Circuit Scribe — AutoDeskによる、Circuit Scribeのテンプレート作成・シミュレーション用の無料オンラインエディタ。
  • Circuit Scribe Handouts — SparkFun Educationによる、Circuit Scribeを使った制作用テンプレート。
  • AgIC Getting Started Guide — AgICマーカーでの描き方と、いくつかのサンプルテンプレート。

部品の選び方

トレースを作る方法をひととおり見てきたところで、回路に使う部品について見ていく。 すべての部品が、ペーパー回路のトレース材料とうまく組み合わせられるわけではない。 たとえばはんだ付けで接続したいなら、導電性インクよりも銅テープの方が適している。 プロジェクトに使う部品の候補をいくつか紹介する。

スルーホール部品

リード線の長いスルーホール部品(LEDなど)は、ペンチで曲げて紙の上に平らに置ける形にすれば、トレースとの接触面積も増やせる。 ATtiny85のようにリード線が短い部品も、指やペンチで慎重に曲げれば平らにできる。

組み合わせる材料:

  • Bare Conductive Electric Paint — 塗料を冷はんだ接合のように使う。この工程についてはチュートリアルを参照してほしい。
  • 銅テープ — リード線の上に透明テープを貼ってすばやく部品を固定するか、銅テープに直接はんだ付けする。
  • 導電性ファブリックテープ — リード線の上から導電性の糸で縫うか、導電性接着剤で固定する。

SMD部品

やや扱いにくいものの、表面実装部品(SMD)は薄型で、グリーティングカードのような小型・平面のプロジェクトに向いている。 部品を配置するにはピンセットが必要で、部品自体に書かれたラベルを読み取る目の良さも求められる。 SMD部品は、銅テープにはんだ付けする、パッドに導電性塗料を塗って接続する、あるいは銅テープにテープで貼り付けるといった方法で取り付けられる。 The ExploratoriumのTinkering StudioによるThis チュートリアルでは、SMD LEDの取り付け方として、はんだ付けと透明テープの2種類の方法を紹介している。

組み合わせる材料:

  • 銅テープ — はんだ付けするか、導電性接着剤で取り付ける。部品によってはテープで銅の上に貼るだけでも固定できる。
  • 導電性塗料 — 瞬間接着剤で紙に固定し、部品のパッドの上から塗料を塗って接続する。High-Low Techによる優れたチュートリアルが、その工程を丁寧に解説している。
  • 導電性インク — 瞬間接着剤で紙に固定する。その際、インクのパッドと部品のパッドの間に接着剤が入り込まないよう注意する。導電性接着剤やZ軸テープでインクに接続する。この手法は、Circuit ScribeのPaperduino 2.0プロジェクトで使われている。

LilyPad部品

もともとe-textile用途向けに作られたLilyPadの部品は、薄型で大きな導電パッドを持つため、ペーパー回路との相性がよい。 LilyPad部品は銅テープにはんだ付けするのが最も確実だが、Z軸テープで取り付けたり、パッドの上に透明テープを貼ってトレースに固定したりすることもできる。 なお、透明テープの手法を使う場合、十分な大きさのパッドを持ち確実に接触できるのはボタンスイッチの基板だけである。

組み合わせる材料:

  • 銅テープ — はんだ付けが最も確実だが、導電性テープ、接着剤、透明テープも選択肢になりうる。
  • ファブリックテープ — 縫い付けるのが理想的だが、Z軸テープも使える。

Chibitronics サーキットステッカー

Chibitronicsのステッカーには導電性の粘着剤が使われており、ペーパー回路のプロジェクトに適している。 ほとんどすべてのペーパー回路用トレースと組み合わせられるが、既製の部品を使うより高価になることがある。

組み合わせる材料:

  • 銅テープ
  • 導電性ファブリックテープ
  • 導電性塗料

Circuit Scribe モジュール

Circuit Scribeのモジュールは、ここまで紹介してきた他の部品とは動作原理が異なり、磁石で接続する。 トレースに取り付けるには、紙の裏側に金属製のシートや面を用意する必要がある。 このチュートリアルで紹介してきた他のより恒久的な接続方法とは異なり、これは一時的な接続である。 小さなプロジェクト(グリーティングカードなど)には向かないサイズだが、壁掛けアートや構成を変えられる作品を作るのには面白い選択肢になる。

組み合わせる材料:

  • 銅テープ
  • 導電性ファブリックテープ
  • 導電性インク

接続の作り方

トレースの作り方と、プロジェクトに使う部品を選べたところで、いよいよそれらを接続する番である。 ここでは、部品とトレースの間に電気的な接続を作るためのさまざまな技法を紹介する。

テープ方式

透明テープは、ペーパー回路に部品を取り付ける手軽な方法だが、他の手法ほど確実ではない。 部品のリード線やパッドの上から慎重にテープを押さえ、銅テープに押し当てて固定する。 SMD部品の場合は、部品全体をテープで覆ってしまってもよい。

SMD LEDをテープで覆う様子。画像:Jie Qi氏のFlickrより。

組み合わせる材料:

  • 銅テープ
  • スルーホール部品またはSMD部品

Z軸テープ

Z軸テープは、フレキシブル回路やPCBの接続・接合・接地のために設計された、扱いやすい感圧式の両面テープである。 小さく切ったテープを使い、部品を導電性トレースに取り付けることができる。

組み合わせる材料:

  • 銅テープ
  • タブのように表面積の広い部品(ワイヤーをらせん状や四角形に曲げると、接着剤がつかみやすい面を作れる)
  • 広い面積の導電性インク(部品用のパッドを描き、そこにテープで取り付ける)

導電性塗料

画像:Bare Conductiveの冷はんだ付けの方法より。

導電性塗料は、接着剤や冷はんだ接合のように使い、部品をトレースに取り付けることができる。 まだ濡れている塗料に部品を押し込んで接続し、通電する前に完全に乾かす。

組み合わせる材料:

  • 導電性塗料のトレース — 元のトレースがまだ濡れているうちに部品を取り付けると、最も確実な接続になる。
  • 曲がらない面 — 塗料は繰り返し力が加わるとひび割れたり壊れたりすることがある。塗る前に部品のリード線を紙に貫通させておくと、ある程度ひずみを逃がせる。
  • スルーホール部品とSMD部品

導電性接着剤・エポキシ

Atom Adhesivesによる導電性エポキシの例。

導電性の接着剤やエポキシも、部品を接続するもう一つの選択肢である。 これらの製品は、ペーパー回路に部品を取り付ける方法の中でも比較的高価で、扱いも難しいことがある。 乾燥に時間がかかったり、加熱による硬化が必要だったりすることも多い。 汚れを抑え、位置合わせを正確に行うには、シリンジ入りのエポキシを探すとよい。 この種の接着剤を使う際は、必ずMSDS(安全データシート)を読み、パッケージの指示に従うこと。

組み合わせる材料:

  • 銅テープ
  • 導電性インク
  • スルーホール部品とSMD部品
  • LilyPad部品

はんだ付け

はんだ付けは、ペーパー回路で作れる接続の中でも特に強固なものの一つである。 唯一の欠点は、銅テープにしか使えないことである。導電性塗料、インク、ほとんどのファブリックには、はんだ付けできない。 はんだ付けの方法がわからない場合は、はんだ付けの基本(スルーホール編)を参照してほしい。

銅テープに部品をはんだ付けする例(左から順に):Tinkering StudioによるSMD LED、SparkFunによるLilyPad LED、High Low Techによる3mm LED。

組み合わせる材料:

  • 銅テープ
  • スルーホール部品とSMD部品
  • LilyPad部品
  • サーキットステッカー

プロジェクトへの電源供給

ペーパー回路のプロジェクトには、3Vのコイン型電池で手軽に電源を供給できる。 グリーティングカードのような小さなプロジェクトには、直径20mmまたは12mmの電池を推奨する。

一般的なコイン型電池の多くは、上面と側面がプラス極、テクスチャのある底面がマイナス極になっている。 このため、トレースへの取り付けが少し厄介になることがあるので、いくつかの手法を紹介する。

安全上の注意: コイン型電池に直接はんだ付けしてはならない。電池を取り付ける際は、はんだ付け専用のタブ付き電池か、電池ホルダーを選ぶこと。

電池の使い方や電源についての参考になる例は、次のチュートリアルにもある。

自分で電池ホルダーを作る

手元にある材料で電池ホルダーを作るのは、手早く簡単にできる。 自作の電池ホルダーを作るいくつかの方法を紹介する。

銅テープ式ホルダー:

SparkFunでは、ポップアップカードのチュートリアルすべてでこの銅テープの手法を使っている。

紙と銅テープ式ホルダー:

画像:Chibitronics

Chibitronicsには、銅テープと紙で電池用のポケットを作るチュートリアルがある。

紙と導電性塗料式ホルダー:

画像:Bare Conductive

Bare Conductiveには、紙の電池ホルダーについていくつかのチュートリアルがある(スイッチ付き、四角形、折りたたみ式、スリット式、三角形、露出型)。

電池ホルダーモジュール

電池ホルダーのモジュールは、銅テープにはんだ付けするか、導電性の接着剤や塗料で接着できる。 はんだ付けの前には、必ずホルダーから電池を取り外しておくこと。

タブ付き電池

はんだ付け用のタブが付いた電池を購入することもできる。 これらははんだ付け、導電性接着剤での接着、場合によっては透明テープで押さえるだけでも回路に取り付けられる。 タブ付き電池を選ぶ際は、側面に絶縁材のあるものを探し、意図しないショートを避けるようにするとよい。

タブ付き電池の例。

LED用のステッカー、基板、モジュールなど、ペーパー回路専用の部品の多くには、抵抗があらかじめ内蔵されている。既製のLEDを使って自分でペーパー回路用の部品を作る場合は、電圧要件の違いに応じて回路に抵抗を追加する必要があるかもしれない。

まとめ・参考資料

このチュートリアルでは、実にさまざまな概念を扱った。 どこから始めればよいかわからない場合は、まず紙の切れ端で小さく試作し、自分のプロジェクトのアイデアにどの手法が向いているかを探ってみるとよい。 もう少し手順の決まったプロジェクトを探している場合は、次のチュートリアルも参考にしてほしい。

ペーパー回路のデザインを探しているなら、次のような資料も参考になる。

  • Paper Circuits Pin — 銅テープを配線代わりに使い、LEDを光らせる着用可能なe-craftアートの手早い制作プロジェクト
  • Paper Circuits: Lotus Flower Pop Up Card — GESTEMで2014年5月9日に開催されたワークショップ「Have Fun with Paper Circuitry」で使われたテンプレート

紙だけにこだわる必要もない。段ボールでも回路を試してみてほしい。

タグ: E-Craft、LED、光、LilyPad、ペーパー回路、スキル、はんだ付け、プロジェクトを始める


出典:The Great Big Guide to Paper Circuits(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

折り紙で作るペーパー回路

ペーパー回路は実に楽しい。教えやすく、しかも作り方のバリエーションが実に豊富である。 このチュートリアルでは、折り紙にペーパー回路を組み込む方法を紹介する。

必要な部品

このチュートリアルでは折り紙用の紙を使う。 普通の紙でも構わないが、何度か折り曲げても破れない程度の丈夫さと、光が透けて見える程度の薄さを兼ね備えたものを選ぶこと。

電子部品には、銅テープLEDステッカーを選んだが、通常のLED、LilyPad LED、その他のLEDと接着剤・抵抗の組み合わせでも問題なく作れる。

接続には、銅テープの代わりにBare Conductive塗料Circuit Scribeペン、通常のワイヤーも使える。 銅テープとLEDステッカーを選んだのは、あらかじめ粘着性があり、紙との相性がよく、手元の折り紙用紙にもよく貼り付き、必要であれば銅テープにはんだ付けしてより確実な接続を作れるからである。 部品を選ぶ際は、すべてが問題なく組み合わせられるかどうかを必ず確認すること。 たとえばBare Conductive塗料とCircuit Scribeペンのインクは、光沢のある折り紙用紙の上ではうまく機能しない。これらを使いたい場合は、別の種類の紙を検討する必要がある。

今回、折り紙の花に使った材料は次のとおりである。

なお、折り紙用の紙(あるいは他の種類の紙)も別途必要になる。 また、電源の選択肢として電池とACアダプタの2つが挙げられているが、プロジェクトの電源にはどちらか一方だけで足りる。

道具

今回使った道具は次のとおりである。

  • はんだごて(任意)
  • はんだ(任意)
  • 瞬間接着剤(選ぶ花のデザインによっては必要になる)
  • 透明テープ(選ぶ花のデザインによっては必要になる。またははんだ付けをしたくない場合)

参考になるチュートリアル

ペーパーエレクトロニクスを扱うのが初めてだったり、それぞれの選択肢とその長所・短所についてもっと詳しく知りたい場合は、ペーパー回路総合ガイドを参照してほしい。

他にも参考になりそうなチュートリアルを挙げておく。

花のデザインを選ぶ

折り紙の花にはさまざまなデザインがある。 選ぶ際に考慮すべき点がいくつかあるので、以下で順に説明する。

LEDを見せたいかどうか

次のように開いた形の花では、

折り紙のくす玉フラワー

内側のLEDが見える。ほとんどの人にとってこれは問題にならない。 ただし、LEDを見せたくない場合は、開かない構造で、LEDを裏側に隠せる層が少なくとも一つあるデザインを探すとよい。

折り紙の川崎ローズ

LEDの置き場所

花のデザインを検討する際は、中央付近にLEDを置ける面があるかどうかも考える必要がある。 ここが面白いところで、多少の創意工夫が必要になることもある。 筆者は、花を閉じて完成させる前にできるだけ組み立てを進め、仕上げる直前にLEDを差し込むようにしている。 LEDを置くのにちょうどよい場所がない場合もある。 その場合は少し「ずる」をして、LEDをつないだ紙片を中央に差し込み、テープで固定するという手もある。 この方法は、次の蓮の花でうまくいった。

折り紙の蓮の花、最後の折りをする前の内側

完成した折り紙の蓮の花

気に入った花を見つけたら、自由に工夫を凝らして折ってみてほしい。

今回筆者が実際に作った花と、その折り方は次のとおりである。

  • 5枚花びらのくす玉フラワーの折り方は、Origami Instructionsによるこちらの動画が詳しい。
  • 蓮の花の折り方は、ProudPaperOfficialによるこちらの動画がすばらしい。
  • 折り紙のバラの折り方は、Carolzjh1氏のチャンネルによるこちらの動画を参照してほしい。この種の折り紙バラには数多くのバリエーションがあるので、自分にとって一番きれいに見える、あるいは一番作りやすいと感じるものを探してみるとよい。

難易度を易しい順に並べると、5枚花びらのくす玉フラワーが最も簡単で、正方形の紙5枚をそれぞれ閉じて糊付けし、さらに互いに貼り合わせて作る。 中程度の難易度は蓮の花で、正方形の紙6枚を半分に切った12枚を輪ゴムでまとめてから最後の折りを行う。 最も難しいのはバラ(正確には川崎ローズ)である。 正方形の紙1枚だけを使い、すべての折り目をあらかじめ付けてから押しつぶすようにして形を作る。 バラの制作にはテープも糊も輪ゴムも使わないため、このデザインを選ぶ場合は、動画を何度か見返し、いくつか失敗を重ねながらコツをつかむ心構えをしておくとよい。

LEDを追加する

導電性テープは、ペーパー回路の制作を始める上で最も手軽な方法の一つである。 台紙をはがして、回路を通したい場所に貼り付けるだけでよい。 銅テープははんだ付けにも対応しており、塗料やインクの手法では得られない、部品とトレースの間の強固な接続を作ることができる(この点についても、ペーパー回路総合ガイドでさらに詳しく選択肢を確認しておくと、プロジェクトに合った部品選びの助けになる)。

筆者が使ったのと同じ花・部品で作りたい場合に向けて、先に挙げた3種類の花それぞれで、LEDステッカーと銅テープをどう組み込んだかを説明する。

5枚花びらの花では、まず花びらの下側の角を切り落とし、ワイヤーがLEDまで通る道を作った。 続いて、折り作業をすべて終えた後、糊を使う前にLEDを差し込んだ。

糊付け前のくす玉フラワーの花びらの内側

蓮の花では、折り終えたすべてのパーツを輪ゴムでつなげてから、LEDを付けた紙を花びらの内側に差し込み、その後で花びらを折り上げた。

輪ゴムでつないだ別の紙にLEDステッカーを付けた、折り紙の蓮の花の内側

バラでは、すべて折り終えた後、最後の一手順だけをほどき、4つの突起のうちの一つにLEDを配置した。

最後の折りをする前の折り紙バラの内側

仕上げ

最後のステップでは、銅テープにワイヤーをはんだ付けする。

警告: はんだごての温度をかなり低めに設定するとよい。そうしないと、銅テープ裏側の粘着剤が焼け落ちてしまうことがある。はんだごてが手元にない場合は、セロハンテープなど透明なテープでワイヤーをテープに接続してもよい。ただし、この接続方法は不安定で、電気の通りが悪くなることがある点に注意してほしい。

銅テープに直接ワイヤーをはんだ付けする

上の写真のように5Vとグラウンドの両方に同じ色のワイヤーを使う場合は、花を閉じた後でも見分けられるよう、どちらか一方に印を付けておくこと。

5Vとグラウンドの銅線が、どの箇所でも決して触れ合わないようにすること。 銅線は表面が導電性であるため、どこか一箇所でも接触すると回路がショートし、たいていLEDが焼けてしまう。

接続を再確認し、ショートがないことを確認したら、ワイヤーをグラウンドと5Vに接続する。 筆者はワイヤーをよじって花の茎に見立てたが、折り紙フラワーのアートインスタレーションのように、磁石と金属シートを使ってさらに大掛かりな作品に発展させることもできる。

今回使ったLEDには色付きのものと白色のものがあった。 色付きの紙を使う場合はどちらの色が好みか両方試してみるとよいし、白い紙の中に意外な色が隠れているという楽しみ方も面白い。

これで完成である。かわいらしく光る花のできあがりだ。

明るい場所でも楽しい花束……

……そして暗闇の中でも。

まとめ・参考資料

紙に電子部品を組み込むコツがつかめたところで、折り紙のアートインスタレーションにも挑戦してみてほしい。

電子工作をもっと多くのプロジェクトに取り入れたい場合は、他のクラフト系チュートリアルも参考にしてほしい。

  • ELasto-Nightlight — ELastoLiteのナイトライトで、もう暗闇を恐れる必要はない
  • Twinkling Trick or Treat Bag — 導電性の糸、LED、LilyTwinkleを使って光るお菓子袋を作る
  • サウンドページの作り方 — LilyPad MP3プレーヤーとBare Conductive塗料を使い、シルエットに触れると音が鳴るファンダム風のページを作る方法

タグ: E-Craft、LED、光、ペーパー回路、プロジェクト


出典:Origami Paper Circuits(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

サウンドページの作り方

インタラクティブなアート作品を作る準備はできただろうか。

準備ができたなら、さっそく始めよう。

Bare Conductive Paintのチューブを使い、形やシルエット、模様を描いていく。 インクをLilyPad MP3ボードに接続してさえおけば、作品にタッチして反応させることができる。 シルエットの一つに触れると、スピーカーから音が鳴る。 塗料は確かに電気を通すが、心配は要らない。流れる電流はごくわずかで、感電することはない。

このチュートリアルは、ElectriCute!で紹介されたBare Conductive Paint Wallをもとにしている。

必要な部品

このチュートリアルに沿って進めるには、いくつかの部品が必要になる。

さらに、次のものも用意する。

  • スポンジブラシ
  • キャンバス(紙、厚紙など)
  • ステンシル(シルエットを作りたい場合。もちろん自由に手描きしても構わない)

以降のガイドで参照しやすいよう、必要な部品には写真にラベルを付けてある。

参考になるチュートリアル

サウンドページキットに取りかかる前に、そこで使われている技術について読んでおくとよい。

  • Arduinoとは何か — LilyPad MP3ボードはArduinoで動作する。ボードを別の用途にプログラムし直したい場合に役立つ
  • Getting Started with the LilyPad MP3 Player — LilyPad MP3ボードがどんなものかを学べる。本来は導電性の糸を使い、ボード周囲のパッドに縫い付けて使うものだが、このチュートリアルでは代わりに導電性塗料を使う

電子部品を取り付ける

重要: 作業を始める前に、まずこの節の説明をすべて読んでおくこと。 塗料が完全に乾いてしまわないうちに電子部品を取り付ける必要があるため、比較的手早く作業を進めなければならない。 塗料が乾いてしまった場合は、電子部品を取り付ける際にあらためて塗料を足せばよい。

このチュートリアルでは印刷済みの厚紙を使うが、壁のようなどんな面でも使うことができる。

印刷済みの厚紙が手元にない場合は、アートワークをダウンロードできる。 ファイルをダウンロードし、厚紙や紙に印刷するだけでよい。

印刷済みの厚紙

このチュートリアルと同じ方法でステンシルを作りたい場合は、粘着力が強すぎないラベル用紙を購入する必要がある。 ここではonlinelabels.comのラベル用紙を使った。 あわせて、こちらで用意したステンシルをダウンロードし、ラベルシートに印刷する。 ステンシルを切り抜くにはX-Actoナイフを使えばよい(今回はたくさん作るためレーザー彫刻機を使った)。

電子部品用ステンシル

LilyPadのフットプリントを作る

最初に行うのは、電子部品を貼り付ける場所として、導電性インクでLilyPadボードのフットプリントを作ることである。

LilyPad MP3のフットプリント用ステンシルを、他のステンシルから切り離す。 フットプリントステンシルの台紙をはがし、輪郭に重ねて配置する。 トレースがページの上側を向くようにすること。これがシルエットとつながることになる。

ステンシルの上に導電性インクを絞り出し、スポンジブラシでステンシルの内側を塗りつぶす。 ステンシルの隙間が完全にインクで覆われていることを確認すること。 むらがあると、電気の通りが悪くなってしまう。

塗料がまだ濡れているうちに、ステンシルを慎重にページからはがす。

LilyPadボードを配置する

塗料が乾いてしまっている箇所があれば、LilyPad MP3ボードを置く各丸印に導電性塗料を一滴ずつ足しておくとよい。

LilyPad MP3ボードの端にある穴が、ステンシルで作った塗料の丸印に重なるよう、慎重に配置する。

重要: SDカードスロット(「RIGHT SPEAKER」とラベル付けされた穴の近くにある)が下向きに、ヘッドホンジャックが上向きになっていることを確認すること。 「LEFT SPEAKER」というラベルは、厚紙上の「LEFT SPEAKER」の文字と向かい合うようにする。

塗料を穴の中に少し押し込むようにする。 これにより、ボードから触れられるアートワークまで電気が流れるようにする。

先ほど導電性インクで作ったトレースと、ボードとの間に良好な電気的接続を作りたい。 そこで、LilyPadボード周囲の12個の穴それぞれに、導電性塗料を一滴ずつ足す。

スピーカーを追加する

本格的な音を出したい場合は、LilyPadボード上部のヘッドホンジャックに大型のスピーカーセットを接続することもできる(この場合、以下のステップは読み飛ばして構わない)。 LilyPad MP3ボードに小型スピーカーを追加して音を出すこともできる。

小型スピーカーを追加したい場合は、「LEFT SPEAKER」の各穴に導電性塗料を一滴ずつ足す。

LilyPadの穴の中の塗料がまだ濡れているうちに、スピーカーのピンを「Left Speaker」とラベル付けされた穴に挿す。 スピーカーの+と-が穴の+と-に合っているかどうかは気にしなくてよい。

注意: スピーカーを固定したい場合は、スピーカーの下にホットボンドを一滴垂らしてもよい。電子部品には影響しないので心配は要らない。

注意: スピーカーは穴の中で少しぐらつく。次にスピーカーに触れる前に、塗料が完全に乾く(数時間かかる)まで待つこと。チュートリアルの残りの作業は進めてよいが、スピーカー周りの取り扱いには注意すること。

重要: スピーカーのピンが、LilyPadボード上の「5V FTDI」とラベル付けされたピンに触れないようにすること。

抵抗を追加する

ペンチ、ピンセット、あるいは指を使い、2本の抵抗のリード線の端を慎重に丸めて小さならせん状にする。

丸めた端を下向きに曲げ、平らにつぶして、抵抗本体が少し浮いた状態になるようにする。

印刷済みの厚紙に赤色で示されている抵抗の設置位置を見つける。 抵抗の設置位置を囲む円形のパッドそれぞれに、塗料を一滴足す。

抵抗の一本を、T1のトレースとT2のトレース(このラベルはLilyPad MP3ボード上で確認できる)をつなぐように配置する。 印刷済みの厚紙を使っている場合、抵抗の設置位置は赤色で示されている。 2本目の抵抗は、T2のトレースとT4のトレースをつなぐように配置する。

LilyPadボードのときと同様に、丸めた抵抗のリード線それぞれの上にも塗料を一滴足し、その場に固定されるようにする。

待つ: 次のステップに進む前に、塗料が乾くまで少なくとも15分待つこと。

アートワークを作る

シルエットを作る

次に行うのは、サウンドページに使う2つのステンシルを選ぶことである。 自分でステンシルを印刷したり、好きな絵を自由に作ったりしても構わない。何しろこれはアートなのだから。 ただし、次の点は必ず守ること。

  1. 作成するものは、すべてインクで完全に塗りつぶされていること。むらのある部分は電気を通さない。
  2. 作った形や絵は、先ほど作ったフットプリントから伸びるインクのトレースにつながっていること。つながっていなければ電気が通らず、タッチしても反応しない。

電子部品用のステンシルと同様に、シルエット用のステンシルもラベルシートで作った。 こちらで用意したものを印刷してもよいし、自分でステンシルを作っても構わない。

シルエット用ステンシル

ステンシルを一つ選び、シートから切り離して台紙をはがす。 ページ上の好きな位置に貼り付ける(LilyPadのフットプリントから伸びるトレースのどれかに近い位置にするとよい)。

フットプリント用ステンシルのときと同様に、スポンジブラシでインクを塗り、ステンシルを完全に塗りつぶす。

塗料がまだ濡れているうちに、すぐに(ただし慎重に)ステンシルをページからはがす。 ステンシルの一部が破れて残ってしまった場合は、ピンセットで慎重に取り除くとよい。

自分のステンシルアートを眺めて楽しんでほしい。

同じ手順を繰り返し、2つ目のシルエットを追加する。

塗り残しを埋める

導電性塗料の一部がLilyPad MP3ボードにつながっていないと、そこに触れても音は鳴らない。

筆や導電性塗料のチューブを使い、シルエットの中の黒い部分(少なくとも、タッチできるようにしたい部分)をすべてつなげる。

待つ: 次のステップに進む前に、塗料が乾くまで少なくとも15分待つこと。

シルエットをトレースにつなげる

シルエットが、LilyPad MP3ボードにつながるトレースに(もちろん導電性塗料で)接続されていることを確認する。 たとえば下の画像のシルエットでは、顔の周りの塗料は導電性塗料でつながっている(目の上の部分を除く。ここは塗料でつなげない限りタッチしても反応しない)。 しかし、シルエット全体はまだトレースにつながっていない。

トレースとシルエットをつなぐために導電性塗料で線を引く必要がある場合は、直線用のステンシルを使うとよい。

待つ: ここでもう一度、次に進む前に塗料が乾くまで少なくとも15分待つこと。その間、自分の作品を眺めて楽しんでほしい。

作品を保護する

作品を保護するために、透明のスプレー塗料のようなシーラーを使うことができる。 ただし、電子部品にかけすぎないよう注意すること。 たとえばSDカードの接点にかかってしまうと、LilyPad MP3ボードがカードを読み取れなくなることがある。 心配は要らない。透明なコーティングの上からでも、サウンドは問題なく起動できる。

さらに、作品を額装すれば端を保護しつつ、きれいに飾ることもできる。

サウンドを読み込む

作ったシルエットのステンシルに対応するサウンドクリップをいくつか用意した。 自分でサウンドクリップを作る方法を知りたい場合は、「キットを改造する」の節を参照してほしい。

カードにサウンドを追加する

サウンドクリップのファイルをダウンロードする。

ファイルを展開する。

各サウンドクリップをダブルクリックして再生し、内容を確認する。 LilyPad MP3ボードが読み取りやすいよう、ファイル名は短く(4文字)してある。参考までに一覧を示す。

ファイル名内容
_bots.wavAutobots
_dlel.wavDalek
_mkjy.wavMockingjay
_shld.wavS.H.I.E.L.D
_shlk.wavSherlock
_wntr.wavWinter is coming

マイクロSDカードリーダーを使い、カードをコンピュータに挿す。 再生したい2つのサウンドクリップを選び、SDカードにコピーする。

ここが重要である。2つのサウンドクリップの名前を変更し、先頭に番号を追加する必要がある。 LilyPad MP3ボードのT1に接続されたシルエットに対応させたいクリップの名前の先頭には「1」を、T4に接続されたシルエットのクリップの名前の先頭には「2」を追加する。

サウンドクリップのファイル名の先頭に「1」と「2」を追加し、ページ上のシルエットと対応づける

コンピュータからSDカードを取り出す。

SDカードを挿入する

コンピュータからSDカードを取り外し、LilyPad MP3ボードに挿入する。

作品で遊ぶ

電源をつなぐ

バレルジャックからJSTへの変換ケーブルを、LilyPad MP3ボードのJSTコネクタに接続する。

ACアダプタをJSTケーブルのバレルジャックに接続し、コンセントに差し込む。

電源を入れる

LilyPad MP3ボード上の電源スイッチを見つけ、ONに切り替える。

遊んでみる

シルエットの一つに触れてみる。 指を離すとすぐに、小さなスピーカーからすばらしいサウンドが聞こえてくるはずである。

音が聞こえない場合

こういうこともある。 シルエットに触れて指を離しても小さなスピーカーから音が聞こえない場合は、次の点を確認してほしい。

  • スピーカーの下を慎重に確認し、スピーカー自体や塗料が「5V FTDI」とラベル付けされたポートのグラウンドピンに触れていないか確認する。スピーカーを一度取り外し、「5V FTDI」ピンにまで達している塗料の塊を取り除き、「LEFT SPEAKER」のパッドに塗料を追加してからスピーカーを戻す必要があるかもしれない。
  • ヘッドホンをヘッドホンジャックに接続し、音が出るか確認してみる。
  • 抵抗を揺らしてみて、導電性塗料のトレースにしっかり接続されているか確認する。

キットを改造する

シルエット2つだけの音出しにはもう飽きただろうか。それなら続きを読んでほしい。 ここでは、キットをさらに活用するための改造方法を簡単に紹介する。

もっと大きな音で

小型スピーカーが小さすぎる、頼りない、あるいは単に音量が足りないと感じる場合は、自分でスピーカーを用意することもできる。 LilyPad MP3ボード上部にある1/8インチのオーディオジャックは、標準的なヘッドホンやスピーカーのオーディオプラグに対応している。

音量を上げよう。

3つ目のシルエットを追加する

実は、LilyPad MP3ボードは3つ目のシルエットにも対応している。 このチュートリアルではシンプルにするためシルエットを2つにとどめているが、3つ目を追加することもできる。 問題は、3つ目のシルエットを導電性塗料のトレースでT5に、さらに抵抗を挟んでT2につなぐ必要がある点である。 紙に穴を開けて他のトレースの裏側を通す方法と、下の画像のように2つ目のシルエットを迂回する方法のどちらかを選べる。

注意: 3本目の1MΩ抵抗が必要になる。

さらに、3つ目のサウンドクリップをSDカードにコピーし、ファイル名の先頭の文字が「3」になるよう変更する必要がある。

新しいサウンドを作る

自分だけのサウンドを作りたくなっただろうか。その方法を紹介する。

まず、何らかの音源を見つける、作る、あるいは録音する。 形式は何でも構わないが、この例ではWAVファイルをダウンロードすることにする。

Audacityをダウンロードしてインストールする。 Audacityの使い方を学びたい場合は、こちらのチュートリアルを参照してほしい。

特にスピーカーを1つしか使わない場合は、音声をモノラルにすることを推奨する。 これは「Tracks → Stereo Track to Mono」から行える。

ファイルサイズを小さく抑えたい場合は、サンプリングレートを変更するとよい。 Audacityウィンドウの左下にある「Project Rate」から新しいサンプリングレートを選択する。 サンプリングレートが48000Hz以下であれば、そのクリップはLilyPad MP3で動作するはずである。

Audacityでは、音量の調整、フィルタの追加、オーディオクリップの任意の部分の切り出しも行える。

作業が終わったら、「File → Export Audio」または「Export Selected Audio」を選択する。 Exportウィンドウで「WAV (Microsoft) Signed 16 bit PCM」を選択する。 LilyPad MP3ボードはさまざまなファイル形式を再生できる。対応形式について詳しくはGetting Started with the LilyPad MP3 Playerを参照してほしい。 新しいファイル名は、先頭が番号(1〜3、シルエットの番号に対応)で始まり、6文字以内になるようにすること。

「Save」をクリックすると、ファイル情報を尋ねる別のウィンドウが表示されることがある。 入力してもよいし、「OK」をクリックしてそのまま保存しても構わない。 ファイルをマイクロSDカードにコピーし、LilyPad MP3ボードに挿入する。これで自作のサウンドが再生できるようになる。

コードをカスタマイズする

LilyPad MP3ボードを再プログラムするには、5V FTDIブレイクアウトボードが必要になる。

Arduino IDEをダウンロードしてインストールする。方法についてはArduino IDEのインストールのチュートリアルを参照してほしい。

Sound Page Kitのソースコードをダウンロードする。

ファイルを解凍し、Sound_Page_Kit/Librariesにある3つのライブラリ(CapacitiveSensor、SdFat、SFEMP3Shield)をインストールする。 Arduinoライブラリのインストール方法については、こちらのチュートリアルを参照してほしい。

Sound Page Kitに付属するコードは、Sound_Page_Kit/Firmware/Sound_Page_Kit/Sound_Page_Kit.inoにある。 このSound_Page_Kit.inoファイルをArduino IDEで開き、自由に改造してほしい。

LilyPad MP3ボードについてさらに詳しく知りたい場合は、Getting Started with the LilyPad MP3 Playerを参照してほしい。

注意: T4とT5のパッドを使うには、FTDIボードをLilyPad MP3ボードから外しておく必要がある。

まとめ・参考資料

これがインタラクティブアートの世界への最初の一歩だったなら、この先はもっと面白くなっていく。

さらに参考になる資料

他のチュートリアル

次はどんなインタラクティブアート作品を作ってみたいだろうか。ヒントとして、次のチュートリアルも参考にしてほしい。

  • Dungeons and Dragons Dice Gauntlet — LilyPad Arduino、LilyPad用加速度センサー、7セグメントディスプレイを使い、4面・6面・8面・10面・12面・20面・100面のダイスを仮想的に振れるレザーブレーサーを作る、遊び心あふれるオタク向けチュートリアル
  • ELasto-Nightlight — ELastoLiteのナイトライトで、もう暗闇を恐れる必要はない
  • Light-Up Father’s Day Card — 電子式の飛び出すカードでお父さんの日を照らそう
  • LilyTiny Plush Monster — あらかじめプログラムされたLilyTinyマイクロコントローラーを使いながら、ぬいぐるみのモンスターを作る。MITのHigh-Low Tech LabでEmily Lovell氏、Jie Qi氏、Natalie Freed氏が制作したPlush Monster Activityをもとにしたプロジェクト

タグ: Arduino、E-Craft、LilyPad、ペーパー回路、プロジェクト


出典:Sound Page Guide(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

プロジェクトへの電源供給

このチュートリアルでは、電子工作プロジェクトに電源を供給するさまざまな方法を紹介する。 検討すべき電圧や電流の考え方についても解説する。 また、プロジェクトが持ち運び可能だったり、遠隔地に置かれたりする場合、つまり壁のコンセントのそばに置けない場合に必要となる追加の検討事項についても触れる。

はじめて電子工作プロジェクトに取り組むのであれば、このチュートリアルを読み進めるか、あるいは選んだプロジェクトや開発ボードで推奨されている電源をそのまま使うという選択肢もある。 SparkFun Inventor’s KitにはUSBケーブルが同梱されており、キット内のすべてのプロジェクトはもちろん、より高度なプロジェクトの多くにも十分対応できる。 迷っているなら、まずはこのキットから始めるのがよい。

参考になるチュートリアル:

プロジェクトへの電源供給の方法

プロジェクトに電源を供給するもっとも一般的な方法には、次のようなものがある。

  • USB電源
  • 可変DCベンチトップ電源
  • AC-DCウォールアダプタ(パソコンやノートパソコンで使われるようなもの)
  • 電池

どの方法を選べばよいか

この問いへの答えは、プロジェクトごとの要件に大きく左右される。

USB電源

SparkFun Inventor’s Kitや、その他の基本的な開発ボードから始めるのであれば、たいていはUSBケーブルだけで十分である。 Arduino Unoは、キット内のサンプル回路を動かすのにUSB A-Bケーブルしか必要としない例のひとつである。

可変DCベンチトップ電源

継続的にプロジェクトを製作したり回路をテストしたりする仕事をしているなら、可変DCベンチトップ電源を用意することを強くおすすめする。 プロジェクトに応じて電圧を特定の値に設定できるほか、最大許容電流も設定できるため、ある程度の保護にもなる。 プロジェクト内で短絡(ショート)が起きた場合、ベンチ電源が停止することで、部品への被害を防げる可能性がある。

AC-DCウォールアダプタ

回路の動作確認が済んだあとは、専用のAC-DC電源がよく使われる。 同じ開発ボードを何度もプロジェクトで使い回す場合にも、この選択肢は優れている。 ウォールアダプタはたいてい決まった電圧と電流を出力するため、電源を供給したいプロジェクトの仕様に合ったアダプタを選び、その仕様を超えないようにすることが重要である。

電池

プロジェクトを持ち運びできるようにしたい場合や、電力網から電源を取れない遠隔地に設置したい場合は、電池が解決策になる。 電池には非常に多くの種類があるため、どれを選ぶべきかはこのチュートリアルの後半で詳しく扱う。 よく選ばれるものとして、アルカリ電池、充電式のニッケル水素単3形、リチウムポリマー電池などがある。

プロジェクトに特定の電圧や、もう少し多くの電流が必要な場合は、ブーストコンバータやスイッチングレギュレータを追加するとよい。 電池から得られる変動する電圧を、5Vなどの一定の電圧に変換して出力できる。 使用するボードや部品によっては、構成次第で9Vや10Vを出力することも可能である。 5Vより高い電圧を出力するには、そのために必要な部品を揃えて回路を組む必要がある。

電圧と電流の検討事項

プロジェクトXにはどのくらいの電圧が必要か

これは回路によって大きく異なるため、簡単には答えられない問いである。 とはいえ、Arduino Unoのようなたいていのマイクロプロセッサ開発ボードには、オンボードの電圧レギュレータが搭載されている。 これにより、レギュレータが出力する電圧より高い、特定の範囲内の電圧を供給できるようになっている。 開発ボード上の多くのマイクロプロセッサやICは3.3Vや5Vで動作するが、電圧レギュレータ自体は6V〜12V程度まで対応できることが多い。

電源から得られた電力は電圧レギュレータによって細かく調整され、電流の消費量が変動する場面でも各チップに一定の電圧が供給されるようになっている。 SparkFunでは、3.3V〜5V系で動作する製品の多くに9V電源を使っている。 ただし、どの電圧が安全かを確認するには、開発ボードに搭載されている電圧レギュレータのデータシートを見て、メーカーが推奨する電圧範囲を確認することをおすすめする。

プロジェクトXにはどのくらいの電流が必要か

この問いも、使用する開発ボードやマイクロプロセッサ、そしてそこに接続する回路によって変わってくる。 電源がプロジェクトの必要とする電力を供給しきれない場合、回路が不安定で予測できない動作をすることがある。 これはブラウンアウトとも呼ばれる。

電圧の場合と同様に、データシートを確認し、回路の各部分が必要とする電流を見積もっておくことをおすすめする。 また、必要な電流を少なめに見積もるよりも、多めに見積もっておくほうが良い習慣である。 モーターや大量のLEDなど、大きな電流を必要とする要素が回路に含まれる場合は、大容量の電源が必要になったり、マイクロプロセッサ用とモーター用で電源を分ける必要が出てきたりすることもある。 そうしないと、電力の落ち込みによってマイクロプロセッサがリセットしてしまったり、モーターの出力が足りなくなったり、LEDが十分な明るさで点灯しなくなったりすることがある。 電流に余裕のある電源を選び、足りなくなるよりは余らせるほうが、常に得策である。

プロジェクトが消費する電流が分からない場合

しばらく回路を扱っていれば、プロジェクトに必要な電流量を見積もるのも徐々に簡単になってくる。 とはいえ、実験的に電流を調べる一般的な方法としては、電流の読み取り機能を備えた可変DCベンチトップ電源を使うか、テスターを使って動作中の回路に流れる電流を測定するという方法がある。 これにより、プロジェクトにどのような電源を選べばよいか、おおまかな見当がつく。

テスターでの電流の測り方が分からない場合は、テスターのチュートリアルを参照してほしい。 デジタルマルチメーター(DMM)は電子工作の道具箱に必ず入れておくことをおすすめする。 電流や電圧を測定するのに非常に役立つ。

接続方法

電池や電源をどうやって回路に接続するか

電源をプロジェクトに接続する方法は数多くある。

可変ベンチトップ電源は、バナナジャック配線を使って回路に直接接続するのが一般的である。 これはテスターのプローブケーブルに使われているコネクタともよく似ている。

多くのプロジェクトは、まずブレッドボードの上で配線を使って試作されたのち、最終的な製品になっていく。 ブレッドボード回路への電源供給には数多くの方法があり、その多くはここで紹介したコネクタを利用するものである。

プロジェクトが試作段階を終えたあとは、たいていPCB(プリント基板)に落とし込まれる。 一度か二度しか製作しない予定であれば、プロトタイピング基板に回路を移し、手作業で配線して固定するという方法もある。 何度も製作する予定であるか、回路全体を小型化したい場合は、EagleのようなCADソフトウェアで回路を設計することを検討するとよい。 配線にかかる時間を節約できる。

完成したPCBでもっともよく使われる電源コネクタのひとつが、バレルコネクタ(バレルジャックとも呼ばれる)である。 バレルコネクタにはさまざまなサイズがあるが、いずれも同じ仕組みで動作し、シンプルで信頼性の高い電源供給手段を提供する。 設計によっては、パソコンやウォールアダプタのUSBポートから電源を取ることもできる。

電池は、電池を収める電池ケースに入れて使い、配線やバレルジャックを通じて回路に接続するのが一般的である。 リチウムポリマー電池のような一部の電池は、JSTコネクタを使うことが多い。

コネクタについてさらに詳しく知りたい場合は、コネクタのチュートリアルを参照してほしい。

遠隔地や持ち運び用の電源

どの電池を選べばよいか

遠隔地の回路に電源を供給する場合も、必要な電圧と電流を供給できる電池を見つけるという課題は変わらない。 電池の寿命、つまり容量は、電池に蓄えられている総電荷量を示す指標である。 電池の容量はたいていアンペア時(Ah)またはミリアンペア時(mAh)で表され、満充電の電池が1時間にわたって供給できる電流量を示している。 たとえば2000mAhの電池であれば、2A(2000mA)を1時間供給できる。

プロジェクトを持ち運び可能にする場合、電池の大きさ、形状、重さも考慮すべき点である。 特に小型のクアッドコプターのような、空を飛ぶものに搭載する場合は重要になる。 Wikipediaの一覧を見れば、電池のサイズがいかに多様であるかがおおまかに分かる。 電池の種類についてさらに詳しく知りたい場合は、電池の技術のチュートリアルを参照してほしい。

電池の直列接続と並列接続

プロジェクトに必要な電圧や電流を得るために、電池を直列または並列に接続することができる。 2つ以上の電池を直列に接続すると、電池の電圧が合算される。 たとえば鉛蓄電池を使った自動車用バッテリーは、実際には2.1Vのセル6個を直列につないだものであり、合計で12.6Vになる。 電池を直列に接続する際は、同じ化学方式の電池を組み合わせることが推奨される。 また、直列接続した電池を充電する場合は注意が必要である。 充電器の多くは単セルの充電にしか対応していない。

2つ以上の電池を並列に接続すると、容量が合算される。 たとえば単3形電池4本を並列に接続した場合、電圧は1.5Vのままだが、容量は4倍になる。

プロジェクトに必要な電池容量はどのくらいか

この問いは、回路が通常どのくらいの電流を消費するかが分かれば、答えやすくなる。 以下の例では見積もりによる計算を行うが、実際にはテスターを使って回路の消費電流を測定し、正確な値を得ることをおすすめする。

例として、ある回路を用意し、その消費電流を見積もったうえで電池を選び、電池でどのくらいの時間動かせるかを計算してみよう。 回路の頭脳としてATmega328マイクロコントローラを使うとする。 これは通常時ではおよそ20mAを消費する。 これに赤色LED3個と、電流制限用の標準的な330Ω抵抗をマイクロコントローラのデジタル入出力ピンに接続する。 この構成では、LEDを1個追加するごとに、消費電流がおよそ10mA増える。 さらに、マイクロメタルモーターを2個マイクロコントローラに接続するとする。 それぞれのモーターは、動作時におよそ25mAを消費する。 これらを合計すると、回路全体の消費電流は次のようになる。

ここでは標準的なアルカリ単3形電池を選ぶことにする。 十分な電流供給能力(最大1A程度)を持ち、容量もそこそこ大きく(1.5Ah〜2.5Ah程度)、非常に入手しやすいためである。 この例では平均的な容量として2Ahを想定する。 単3形の欠点は出力電圧が1.5Vしかないことであり、残りの部品はすべて5Vで動作するため、電圧を昇圧する必要がある。 これには5V昇圧ブレイクアウトを使う方法もあれば、単3形電池を3本直列にしておおよそ必要な電圧に近づけるという方法もある。 単3形電池を3本直列にすると、電圧は4.5V(1.5V×3)になる。 電池をもう1本追加して合計6Vにし、必要な電圧までレギュレータで降圧するという方法もある。

回路が電池でどれくらいの時間動作するかを計算するには、次の式を使う。

単3形電池3本を並列に接続し、常に100mAの電流を消費する回路の場合、次のようになる。

(3 × 2Ah) / 100mA = 6000mAh / 100mA = 60h

この並列構成のアルカリ単3形電池3本からは、理想的には60時間の駆動時間が得られる計算になる。 とはいえ、電池は「ディレーティング」、つまり理想値より少なめに見積もっておくのがよい習慣である。 控えめに見て理想値の75%が得られると仮定すると、このプロジェクトの駆動時間はおよそ45時間になる。

電池の駆動時間は、実際の消費電流量によっても変動する。 次のグラフは、エナジャイザーの単3形電池について、一定の電流を消費し続けた場合に予想される駆動時間を示したものである。

これは、プロジェクトに遠隔から電源を供給するための、数ある構成のひとつに過ぎない。

Note

LEDを使ったLilyPadプロジェクトの消費電力の計算例も、参考になるだろう。 プロジェクトが何個のLEDをどれだけの時間点灯させられるかを見積もる方法を学べる。

ストレステスト

電源とコネクタを選んだら、実際にプロジェクトを動かして動作を確認しておくこと。 メーカーによって電源の性能にはばらつきがある。 ウォールアダプタは、一定の期間動かし続けてもマイクロコントローラがブラウンアウトを起こさないか、電源が負荷によってリセットしないかを確認すること。 静電容量式のタッチセンサーを使うプロジェクトでは、電源のノイズによって遅延が生じていないかも確認しておくとよい。

プロジェクトを遠隔地で動かす場合は、必ず実際の電池を使ってテストすること。 電池は、接続されている負荷や電池の化学方式によって出力が変動することがある。 これによってもマイクロコントローラがブラウンアウトを起こしたり、電源供給が止まったりすることがある。

まとめ

これで、回路への電源供給によく使われる方法と、プロジェクトの要件に応じてどの方法を選べばよいかが分かったはずである。 電流、電圧、コネクタ、持ち運びのしやすさといった観点から、プロジェクトに合った判断ができるようになったことだろう。 プロジェクトの監視、制御、電源供給についてさらに学びたいなら、次のチュートリアルもおすすめである。

回路の試作についてさらに学びたいなら、ブレッドボードのチュートリアルを確認してほしい。 PCBの設計や製作についてさらに知りたいなら、次のチュートリアルもおすすめである。

タグ: 電気工学、LED、電力、スキル、プロジェクトを始める


出典:How to Power a Project(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

LiPo USB充電器の使い方

私たちはLiPo電池が大好きである。 小さく平たいパッケージの中に、驚くほどの電力を詰め込んでいる。 そして、充電が必要になったときにも非常に簡単に充電できる。 プロジェクトを持ち運び可能にし、なおかつ手軽に充電できるようにしたいなら、850mAhのLiPo電池と、基板に組み込めるUSB LiPo充電器の組み合わせを強くおすすめする。

このチュートリアルでは、USB LiPo充電器を、あらゆる単セルLiPo電池と組み合わせて使う方法を説明する。 ここでは主にLiPo充電器と電池のリテールキットを例に説明するが、この情報はその充電器と互換性のあるどんな電池にも応用できる。

必要なもの

  • USB LiPo充電器
  • 単セルLiPo電池

充電器は、40mAh、110mAh、400mAh、850mAh、1000mAh、2000mAh、6000mAhの大容量パックまで、あらゆる容量の電池と組み合わせて使える。

さらに、5Vの電源が必要である。次のような選択肢がある。

  • パソコンのUSBポートとミニB USBケーブル
  • USBウォールアダプタとミニBケーブル
  • 5Vのウォールワート電源

参考になるチュートリアル:

入力と出力

このセクションでは、USB充電器を分解し、基板のすべての入力、出力、仕様を確認していく。

充電器の入力:電源

まず、充電器に電力を供給する何かが必要である。それによって充電器が電池への電力を調整できるようになる。 電源は、次の2つの入力のどちらかに接続する。バレルジャック(外径5.5mm、中心ピン径2.1mm、中心が正極)か、ミニB USBコネクタである。

電源の供給電圧4.75V〜6Vの間にする必要がある。 パソコンのUSBポートやウォールアダプタに接続したミニBケーブルから得られる5VのUSB電源は、理想的な電源になる。 バレルジャック入力を使いたい場合は、5Vのウォールアダプタをおすすめする。

電源に必要な電流は、基板上で充電電流をどう設定しているかによって変わる。 デフォルトでは、充電電流は500mAに設定されているため、使用する電源がそれに対応できることを確認しておこう。 特に注意すべきなのがパソコンやノートパソコンのUSBポートである。500mAはUSBポートが供給できる規定の最大値であり、実際にはそれより低い出力(たとえば100mAなど)に制限されていることも多い。

5Vのウォールワート供給とUSB供給の両方を、この基板に安全に同時接続することができる。 基板上には逆流防止のための保護回路(ダイオード)が搭載されている。 より高い電圧を供給している側から、チップへ電力が供給される。

Note

警告:チップは最大6Vまでの電圧に対応しているが、電流については最大1500mAまでしか対応していない。電源として6V/2Aの電源を使うと、基板上のチップを焼き切ってしまう可能性が非常に高い。バレルジャック付きのウォールアダプタが必要な場合は、5V/2Aの電源をおすすめする。

充電器の出力:単セルLiPo電池

充電器に電源を接続したら、次は電池を接続する番である。 この基板は、非常に限られた種類の電池しか充電できないため、次の条件を満たしているか必ず確認すること。

  • 単セル電池のみ:LiPo電池の公称電圧はおよそ3.7Vで、満充電時にはおよそ4.2Vまで上がる。つまり、対応するのは単セルのLiPoだけである。公称電圧が7.4V以上の複数セルの電池を使っている場合、この充電器は使えない。

  • 電池の化学方式:この充電器はリチウムポリマーまたはリチウムイオン電池にのみ対応している。
  • 容量に関する注意:(ほんの一瞬だけ楽しい)爆発を避けるため、これらのLiPo電池は1C(公称容量と同じ数値のアンペア数)を超える電流で充電すべきではない。つまり、500mAhの電池には500mAを超える充電電流を与えるべきではなく、100mAhの電池には100mAを超える充電電流を与えるべきではない。この基板は工場出荷時には500mAで充電するように設計されているが、その速度を変更するのも簡単である。電池の容量が500mAh未満の場合は、後述の充電電流の設定を確認してほしい。

対応するすべての電池は、白いJSTコネクタで終端されており、*BATT IN→*のラベルの隣にある対になった黒いコネクタに直接差し込める。 もし電池が見慣れない非JST系のコネクタで終端されている場合は、JSTコネクタのすぐ後ろにある未実装の0.1インチピッチのヘッダーを使うこともできる。 必要であれば、このヘッダーに配線や他のコネクタをはんだ付けすることもできる。

システム出力

LiPo USB充電器は、プロジェクトの中に簡単に組み込めるように設計されている。 ←SYS OUTコネクタを使えば、電池の出力をプロジェクトの残りの部分に接続できる。

電池の接続と同じように、プロジェクトへの接続にはJSTコネクタか、近くにある0.1インチピッチのヘッダーのどちらかを使える。

SYS OUT出力は、プロジェクトを電池に直接接続する。 つまり、電池の供給電圧(3.6V〜4.2V程度)がそのままプロジェクトに供給されるということである。 必要に応じて、その電圧を適切にレギュレートすること。

充電状態LED

基板上の赤いChargingLEDは、電池の充電状態を確認するために使える。

充電状態LEDの状態
電池なしフローティング(OFFになるはずだが、点滅することもある)
シャットダウンフローティング(OFFになるはずだが、点滅することもある)
充電中ON
充電完了OFF

もっと大きな独自のLEDを追加したい場合は、未実装のフットプリントが用意されており、小さな(しかし明るい)赤色LEDの代わりに3mmまたは5mmのLEDをはんだ付けできる。 ただし、極性を正しく合わせることを忘れないように。

充電電流を設定する

電池を充電器に接続する前に、電池の容量と充電器が供給する充電電流を把握しておく必要がある。 安全のため、充電電流は電池の1C以下に抑えておくべきである。 つまり、850mAhの電池は850mA以下、100mAhの電池は100mA以下で充電すべきということである。

充電電流は、電池がどれだけ速く充電されるかを決める。 1000mAhの電池を1000mAで充電すれば、1時間で満充電になる。 500mAで充電すれば、満充電までに2倍の時間、つまり2時間かかる。 つまり充電電流は大きいほうがよいが、電池の仕様を超えない範囲に限られる。

LiPo USB充電器基板の主要部品であるMCP73831には、プログラム可能な充電電流という機能がある。 15mAから500mAの間で、電池に供給する電流を設定できる。 この値を設定するには、PROGピンからグラウンドへ抵抗を接続する。 基板上にはすでに2つの抵抗があり、充電電流を500mAまたは100mAに設定できるようになっている。 小さなジャンパーを使って、どちらかを選択する。 独自の抵抗を追加して、任意の充電電流を設定することもできる。

ジャンパーによる選択

充電状態LEDの隣に、2択のジャンパーを構成する3つの露出したパッドがある。 中央のパッドはMCP73831のPROGピンに接続されており、外側の2つのパッドはそれぞれ抵抗器に接続されている。 外側のパッドの隣にあるラベルは、それぞれが設定する充電電流を示している。

このジャンパーをよく見ると、中央のパッドと「500mA」とラベル付けされた外側のパッドをつなぐ小さな配線パターンが見えるはずである。 そのため、この基板はデフォルトで500mAの電流を供給するように設定されている

充電電流を100mAに変更するには、そのパッド間の小さな配線パターンを切断し(ホビーナイフの使用をおすすめする)、「100mA」とラベル付けされたピンと中央のパッドをはんだの塊でつなぐ必要がある。

独自の充電電流を設定する

100mAでも500mAでも都合が悪い場合は、独自の充電電流を設定できる未実装の抵抗フットプリントが用意されている。

抵抗を追加する前に、前のセクションで説明した両方のジャンパーを切り離しておくこと。 そのうえで、次の式を使って抵抗値を選ぶ。

Rprog = 1000 / 目標の充電電流(A)

たとえば、400mAhの電池をちょうど400mAで充電したい場合は、2.5kΩの抵抗をはんだ付けする(2.2kΩと330Ωを直列にする必要があるかもしれない)。

Note

たいていの電池には、電流を供給しすぎたときに電池が破裂しないよう保護する、過電流保護機能が(黄色いテープの下の小さな回路基板に)内蔵されている。とはいえ、その回路をあてにしないほうがよい。そのほうが電力も、あなたの精神的な安らぎも守られる。

まとめ

さらに詳しく知りたい場合は、次のような情報源も参考になる(いずれも英語)。

  • LiPo Battery Care Tutorial(LiPo電池のお手入れ):やや古いチュートリアルだが、内容の多くは今でも通用する。ストレインリリーフについての情報や、充電器から電池を安全に取り外すためのヒントが得られる。
  • USB LiPo Charger Schematic(USB LiPo充電器の回路図):回路レベルの疑問があれば、回路図を確認してほしい。
  • MCP73831 Datasheet(MCP73831のデータシート):単セルLiPo充電管理ICであるMCP73831についての詳細情報。
  • USB LiPo Charger GitHub Repository(USB LiPo充電器のGitHubリポジトリ):最新の設計ファイルが公開されている。

補給可能な電源が手に入ったところで、次はどう使うか考えてみよう。 アイデアが必要なら、次のようなチュートリアルも確認してみてほしい(いずれも英語)。

  • Uh-Oh Battery-Level Indicator Hookup Guide(電池残量インジケーターの使い方):電池電圧が下がりすぎると通知してくれるキットの組み立てと使い方を学べる。
  • MYST Linking Book(MYSTのリンキングブック):LiPo電池を使って、あの名作コンピュータゲーム『MYST』に登場するリンキングブックを自作するプロジェクト。
  • Sunny Buddy Solar Charger Hookup Guide(Sunny Buddyソーラー充電器の使い方):LiPo USB充電器をソーラー充電器に置き換えたい場合は、Sunny Buddyを確認してみてほしい。

タグ: 接続ガイド、電力


出典:LiPo USB Charger Hookup Guide(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

はんだ付け対応ブレッドボードの使い方

はんだ付け不要のブレッドボードは試作にとても便利である。 しかし、機械的な頑丈さという点では今ひとつである。 どこかしらのパーツが、いつも緩んでしまうものである。 同じ配線パターンを持つはんだ付け対応の基板を使えば、専用のPCBを設計しなくても、試作をより頑丈な形にすることができる。

一見すると、はんだ付け対応の大型ブレッドボードは、通常のはんだ付け不要の大型ブレッドボードと同じ穴の配置になっている。 しかし、よく見てみると、はんだ付け不要の基板からの移行をスムーズにするための、いくつかの追加機能があることに気づくはずである。

このチュートリアルでは、このはんだ付け対応ブレッドボードの特徴を紹介し、もっとも基本的な使い方を示したうえで、より高度な使用例も紹介する。

参考になるチュートリアル:

概要

これまで長年にわたって、似たようなはんだ付け対応ブレッドボードをいくつも使ってきたが、そのほとんどには物足りなさが残っていた。 よくあるものは、もろいフェノール樹脂製のPCB素材でできている。 銅の配線パターンは薄く、接着も弱いため、基板をやり直すと剥がれてしまいがちである。 そしてもっとも問題なのは、配線パターンがはんだ付け不要のブレッドボードと必ずしも一致していない点である。電源レールの位置が合わなかったり、中央部が5つ穴ではなく4つ穴になっていたりする。 回路をはんだ付け基板に移すには、余計な変換作業が必要になっていた。

この大型のはんだ付け対応ブレッドボードは、こうした問題を解決するために作られている。 本物のFR4ガラス繊維基板であり、ソルダーマスクとめっきスルーホールを備え、レイアウトははんだ付け不要のブレッドボードの接続をそのまま再現している。

このブレッドボードの中央部は、はんだ付け不要のブレッドボードと同じ接続パターンを再現しており、0.3インチ間隔で5つ穴が2列並んだ構成になっていて、DIP ICを取り付けられるようになっている。 対応するはんだ付け不要の基板と同じく、このはんだ付け対応の基板にも63列ある。 行と列の座標ラベルは、はんだ付け不要のブレッドボードと一致している。

はんだ付け不要のブレッドボードと比べて、このはんだ付け対応の基板は電源の配線方法にも柔軟性がある。

電源についての基礎知識

一般的な電源は、接続された回路にいくつかの電圧を供給する。 それぞれの電圧はレールと呼ばれることが多い。 必要な電源レールの数と、それぞれのレールが供給する電圧は、実際に使う回路の種類によって異なる。

  • まず、どの電源にも「グラウンド」レールがある。グラウンドは0Vの基準点として使われ、他の電圧はこの基準点を基に測定される。実際に大地に接続されているとは限らない。
  • 長年にわたり、デジタル回路は単一の5Vレールを使ってきた。近年ではより低い供給電圧、主に3.3V、時にはさらに低い1.8Vなどが一般的になっている。
  • アナログ設計では、正負が対になったバイポーラ電源がよく使われ、正と負の鏡像のようなレールを供給する。±12Vや±15Vがよく使われる。
  • ミックスドシグナル設計は、アナログとデジタルの両方のセクションを含み、それぞれの供給電圧の要件を併せ持つ。よい例がパソコンの電源であり、デジタルロジック用に3.3Vと5Vを、ディスクドライブのモーターや冷却ファンのようなもの用に±12Vを供給している。

はんだ付け不要のブレッドボードでは、たいてい基板の両端に沿って1組ずつの電源レールがある(ただし、途中で分断されていて完全には連続していないこともある)。 これらはたいてい「+」「-」の記号が付けられ、赤と青の色分けがされていることもある。 ブレッドボード自体は、レールがどう使われるかについて何も想定していない。電圧をレールに供給するのは利用者の役目である。

それでは、このブレッドボードの電源レールをどう設定するかを見ていこう。

「rail」という用語の由来を確実に特定するのは難しいが、1880年代にさかのぼる、電気鉄道に電圧を供給するための「第三軌条(サードレール)」の用法に由来していると考えられる。

任意のジャンパー

追加の設定をしなければ、この基板には基板の長さ全体にわたって伸びる5本の配線パターンがある。 そのうち4本は、基板の上端と下端にある「+」と「-」の配線であり、はんだ付け不要の基板の対応する箇所を再現している。 5本目の配線パターンは基板中央の「溝」に沿って伸びており、グラウンドとして使うことを意図している。

これらの5本の配線パターンは、基板の両端にある5ピンの5mmネジ端子とつながっている。 端子の並び順は、基板を横切る配線パターンの並び順と一致している。 下の図のように、一番上のネジ端子のピンは上側の「-」レールに、その次のネジ端子は上側の「+」レールに、というようにつながっている。

この基板は、配線用のジャンパーを使うことで、さまざまな電圧レールの組み合わせに対応できるようになっている。

ジャンパーは次のとおりである。

  • JG1、JG2、JG3、JG4は、取り付け穴をグラウンドの配線パターンに接続するために実装できる。基板を金属製の筐体に取り付ける場合、筐体をグラウンドに落とし、回路のグラウンドを筐体に結線しておくのがよい習慣である。
  • JG5とJG6は、基板の端にある「-」レールを、基板中央のグラウンド配線に接続するために使える。
  • TIE+とTIE-は、それぞれ基板の両側にある「+」レールどうし、「-」レールどうしを接続する。はんだ付け不要のブレッドボードと同じく、これらはデフォルトでは接続されていないが、この基板ではそれらを簡単につなげられるようになっている。

この基板は、電源接続用の5mmネジ端子も取り付けられるようになっており、レールの構成に合わせて実装できる。 ネジ端子よりもしっかりした接続を好む場合は、パッドに配線を直接はんだ付けすることもできる。

電源の接続部とジャンパーは、基板の両端にそれぞれ用意されている。 たいていの用途では、どちらか一方の端の接続だけを使えば十分である。

いくつかの例

単一の電源レールを持つデジタル回路

単一の電源レール(たいてい3.3Vまたは5V)を使うデジタル回路を組む場合は、次のように接続する。

  • TIE+とTIE-のジャンパーをブリッジする。
  • JG5またはJG6のジャンパーをブリッジする。
  • 2極の5mmネジ端子を取り付ける(上の図のとおり)。
    • 赤い配線が供給電圧である。
    • 黒い配線がグラウンドである。

部品を取り付ける際は、どちらかの「+」レールから供給電圧を、「-」レールまたは中央のグラウンド配線からグラウンドを取ることができる。

バイポーラレールを持つアナログ回路

バイポーラ電源を使うアナログ回路の場合は、次のようにジャンパーを設定する。

  • TIE+とTIE-のジャンパーをブリッジする。
  • 3極の5mmネジ端子を取り付ける(上の図のとおり)。
    • 赤い配線が「+」の供給電圧である。
    • 青い配線が「-」の供給電圧である。
    • 黒い配線がグラウンドである。

部品は、どちらかの「+」レールから正の供給電圧を、どちらかの「-」レールから負の供給電圧を、そして中央の配線からグラウンドを取ることができる。

複数の基板を使う場合

この基板を複数使ってより大きな回路を組む場合、それらの基板で1つの電源を共有することができる。 もっとも一般的な構成は「スター型電源配電」として知られている。 電源をシステムの中心に据え、それぞれの基板を電源に直接接続する。

シンプルに描き直すと、次のようになる。

この構成では、電源とそれぞれの基板の間が直接つながる。

まとめ

この基板を手元に置いておくだけで、何かをはんだ付けしたくなってくる。 小さな試作には、30行のはんだ付け不要ブレッドボードと組み合わせて使える小型版の中型はんだ付け対応ブレッドボードもある。

この大型はんだ付け対応ブレッドボードについてさらに詳しく知りたい場合は、GitHubリポジトリを確認してほしい。

試作についてさらに学びたいなら、次のようなチュートリアルもおすすめである。

タグ: 接続ガイド、プロトタイピング、はんだ付け


出典:Large Solderable Breadboard Hookup Guide(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

はんだ付けの基本(スルーホール編)

はんだ付けは、電子工作の世界に足を踏み入れるうえでもっとも基本的なスキルのひとつである。 はんだごてを持たずに電子工作を学んだり作ったりすることも可能だが、このひとつのスキルを身につけるだけで、まったく新しい世界が開けることにすぐ気づくはずである。 SparkFunでは、はんだ付けはすべての人が身につけておくべきスキルだと考えている。 技術に囲まれる世界が広がるにつれて、日々使っている技術を理解するだけでなく、それを自分で作り、改造し、修理できることが重要になってきている。 はんだ付けは、それを可能にしてくれる数あるスキルのひとつである。

このチュートリアルでは、スルーホールはんだ付け(めっきスルーホールはんだ付け、PTHとも呼ばれる)の基本を扱い、必要な道具、正しいはんだ付けの技法を解説し、そこから先にどう進めばよいかを紹介する。 また、スルーホールはんだ付けに関するリワーク(やり直し)についても触れ、電子機器の修理を楽にするコツも紹介する。 このガイドは初心者にも熟練者にも役立つ内容になっている。

参考になるチュートリアル:

はんだごてに触れずに電子工学の理論から先に学びたい場合は、次のチュートリアルから始めることをおすすめする。

はんだごてを使わずに回路を組みたい場合は、ブレッドボードのチュートリアルを確認してほしい。

このチュートリアルはいくつかの既存のチュートリアルの内容の上に成り立っているため、先に次の話題を読んで理解しておくことをおすすめする。

はんだとは何か

はんだ付けの方法を学ぶ前に、はんだそのものについて、その歴史や用語を少し知っておくとよい。

はんだ(solder)という単語には2通りの使い方がある。 名詞としての「はんだ」は、スプールやチューブに入った長く細い線として売られている合金(2種類以上の金属からなる物質)を指す。 動詞としての「はんだ付けする(solder)」は、2つの金属をはんだ接合と呼ばれる形でつなぎ合わせることを意味する。 つまり、はんだ(を使って)はんだ付けするというわけである。

鉛入りはんだと鉛フリーはんだ:簡単な歴史

はんだについて知っておくべきもっとも重要なことのひとつは、伝統的なはんだの多くが、鉛(Pb)、スズ(Sn)、そのほか微量の金属でできていたという点である。 このはんだは鉛入りはんだとして知られている。 よく知られているように、鉛は人体に有害であり、大量にさらされると鉛中毒を引き起こすことがある。 とはいえ鉛は非常に有用な金属でもあり、融点が低く優れたはんだ接合を作れることから、はんだ付けの定番の金属として選ばれてきた。

鉛入りはんだの悪影響が知られるようになると、一部の団体や国は、鉛入りはんだをもう使わないほうがよいと判断した。 2006年、欧州連合は特定有害物質使用制限指令RoHS)を採択した。 簡単に言えば、この指令は、電子機器や電気機器における鉛入りはんだ(をはじめとする一部の材料)の使用を制限するものである。 これにより、電子機器の製造では鉛フリーはんだの使用が標準となった。

鉛フリーはんだは、名前のとおり鉛を含まない点を除けば、鉛入りはんだとよく似ている。 その代わりに、主にスズと、銀や銅といった微量の金属で構成されている。 このはんだには、規格に適合していることを示すRoHSマークが付けられていることが多い。

用途に合ったはんだの選び方

電子機器を製造する場合、製品の安全性を確保するために鉛フリーはんだを使うのが望ましい。 とはいえ、自分自身のプロジェクトで使うはんだの種類は、自分で選ぶことができる。 多くの人は、接合材としての優れた性能から今でも鉛入りはんだを好んで使う。 一方で、機能性よりも安全性を優先し、鉛フリーを選ぶ人もいる。 SparkFunでは両方の種類を扱っており、それぞれが自分で選べるようにしている。

鉛フリーはんだにも欠点がないわけではない。 先に述べたように、鉛が選ばれてきたのは、はんだ付けのような用途において最良の性能を発揮するからである。 鉛を取り除くと、2つの金属をつなぎ合わせるという目的にとって理想的だった、はんだのいくつかの特性も失われてしまう。 そのひとつが融点である。 スズは鉛より融点が高いため、流動させるにはより多くの熱が必要になる。 スズはそれでも役目を果たすが、時には少し助けが必要になる。 多くの鉛フリーはんだにはフラックスコアと呼ばれるものが入っている。 フラックスとは、鉛フリーはんだの流動を助ける化学物質だと考えておけばよい。 フラックスなしで鉛フリーはんだを使うことも可能だが、フラックスがあれば鉛入りはんだと同じような効果をずっと簡単に得られる。 また、鉛フリーはんだは製造コストが余分にかかるため、鉛入りはんだより高価になることもある。

鉛入りか鉛フリーかを選ぶこと以外にも、はんだを選ぶ際に考慮すべき要素がいくつかある。 まず、鉛とスズ以外にも実に多くのはんだの組成が存在する。 次に、はんだにはさまざまなゲージ(太さ)がある。 小さな部品を扱うときは、細いはんだを使うほうがよいことが多い(番号が大きいほどゲージは細くなる)。 大きな部品には、太い線のほうがおすすめである。 最後に、はんだは線状以外の形でも売られている。 表面実装のはんだ付けに取り組むようになると、はんだペーストという形が主流になる。 ただしこのチュートリアルはスルーホールはんだ付けのチュートリアルであるため、はんだペーストについては詳しく扱わない。

用途に合ったはんだの選び方が分かったところで、道具とさらなる用語の話に進もう。

はんだごて

はんだ付けを助ける道具は数多くあるが、はんだごてほど重要なものはない。 最低限、作業をこなすには、こてとはんださえあればよい。 はんだごてにはさまざまな形状があり、単純なものから複雑なものまであるが、いずれもおおむね同じように機能する。 ここでは、こての各部の名称と、こての種類について見ていく。

はんだごての構造

はんだごてを構成する基本的な部品は、次のとおりである。

  • こて先:こて先のないはんだごては存在しない。こて先は、はんだごての中で熱くなり、接合する2つの部品の周りにはんだを流し込む部分である。はんだを当てるとこて先にくっつくため、こて先がはんだを運んでいると誤解されがちだが、実際にはこて先が伝えているのは熱であり、金属部品の温度をはんだの融点まで上げることで、はんだが溶けるのである。たいていのこては、古くなったこて先を交換したり、別の形状のこて先に切り替えたりできるようになっている。こて先にはさまざまな大きさや形があり、あらゆる部品に対応できる。

こて先の交換は簡単で、ワンド(こて本体)のネジを緩めるか、こて先を押し込んで引き抜くだけでよい。

Note

こて先から接合部への熱伝達の効率は、使っているはんだごてのこて先の大きさによって左右される。一般に、はんだ付けするパッドと同じくらいの幅のこて先を使うのがよいとされる。

  • ワンド:ワンドは、こて先を保持し、作業者が手に持つ部分である。ワンドはたいてい、こて先の熱が外側に伝わらないよう、ゴムなどの絶縁材料でできているが、内部には、ベースやコンセントからこて先へ熱を伝えるための配線や金属の接点が収められている。加熱と火傷防止という2つの役割を両立させているからこそ、質の高いワンドが重宝される。

こての中には、ワンドだけをコンセントに直接差し込むタイプもある。 これらはもっともシンプルなこてであり、温度を変える機能はない。 このタイプでは、発熱体がワンドに直接組み込まれている。

  • ベース:はんだごてのベースは、温度を調整できるコントロールボックスである。ワンドはベースに接続され、内部の電子回路から熱を受け取る。温度をダイヤルで調整するアナログベースと、ボタンで温度を設定し、現在の温度を表示するデジタルベースがある。中には、さまざまな部品をはんだ付けする際にこて先への熱量をすばやく切り替えられる、ヒートプロファイル機能を備えたベースもある。

ベースの内部にはたいてい大きなトランスと、こて先の熱を安全に調整するための各種制御回路が収められている。

  • スタンド(クレードル):アイアンスタンド(クレードルとも呼ばれる)は、使っていないときにこてを置いておく場所である。些細なことのように思えるかもしれないが、加熱されたこてを机の上に放置しておくのは、やけどや、最悪の場合は火災につながる潜在的な危険がある。シンプルな金属製のスタンドから、ワンドをクレードルに置くとこて先の温度を下げて摩耗を防ぐ、自動オフ機能付きの複雑なものまでさまざまである。
  • 真鍮製スポンジ:はんだ付けをしていると、こて先は酸化しやすくなる。つまり黒ずんで、はんだがのりにくくなる。特に鉛フリーはんだには不純物が含まれており、それがこて先に蓄積して酸化を引き起こす。そこで登場するのがスポンジである。時々、こて先をこのスポンジで拭って汚れを落とす必要がある。伝統的には濡らした普通のスポンジが使われてきたが、これはこて先の寿命を大幅に縮めてしまう。冷たく濡れたスポンジでこて先を拭くと、温度変化によってこて先が膨張と収縮を繰り返し、それが摩耗の原因になり、時にはこて先の側面に穴があいてしまうこともある。穴があいたこて先は、もうはんだ付けには使えない。そのため、こて先の掃除には真鍮製スポンジが標準になっている。真鍮製スポンジは、こて先の現在の温度を保ちながら余分なはんだを取り除いてくれる。真鍮製スポンジがない場合は、普通のスポンジでもないよりはましである。

はんだごての選び方

初心者であれ熟練者であれ、用途に合ったはんだごてを見つけることができる。 シンプルな固定温度タイプの安価なもの、調整可能な温度のもの、より高機能なデジタルソルダリングステーションまで、幅広い選択肢がある。 SparkFunのカタログのはんだ付けカテゴリーで、自分に合った1本を探してみてほしい。

はんだ付けの補助道具

はんだごての細部が分かったところで、はんだ付け作業を助けるそのほかの道具についても紹介する。

  • はんだ吸取り線:はんだ付けの「消しゴム」のような存在である。ジャンパーの問題や部品の取り外し(取り外しはんだ付け)を扱うときに非常に役立つ。はんだ吸取り線は、細い銅線を編み込んで作られており、はんだを銅線に染み込ませることで、余分なはんだの塊を「消す」ことができる。
  • チップティナー:はんだごてのこて先を掃除するための化学ペースト。穏やかな酸が含まれており、こびりついた汚れ(部品にこて先を誤って溶かしてしまったときなど)を取り除いたり、使っていないときにこて先に蓄積する酸化(あの黒い汚れ)を防いだりする。
  • はんだ吸取り器(はんだシュッ太郎のようなもの):部品を取り外す際に、スルーホールに残ったはんだを取り除くのに便利な道具である。
  • フラックス:フラックスは、鉛フリーはんだの流動を助ける化学物質である。フラックスペンを使えば、扱いにくい部品に液体フラックスを塗って、より見た目のよいはんだ接合を作ることができる。水溶性フラックスを使った場合は、基板に残った残留物を洗浄して除去することが推奨される。ノークリーンフラックスの場合は洗浄の必要はないが、除去したい場合はイソプロピルアルコール(IPA)が必要になる。
  • シリコン製はんだ付けマット:机を保護し、清潔に保つためのマット。
  • はんだディスペンサー:スプールが転がっていかないようにし、はんだを取り出しやすくする道具。

そのほかおすすめの道具

以下の道具は必須ではないが、あるとはんだ付けがずっと楽になる。

  • サードハンド(第三の手):はんだ付けの間、PCBや配線、部品を固定しておくのに便利である。
  • パナバイス Jr.:真空ベース付きのバイスで、PCBや配線、部品を固定するのに役立つ。
  • スティックバイスPCBバイス:低床タイプのPCBバイスで、はんだ付けやテスト、配線の際に基板を平らに保つのに適している。顕微鏡の下でも扱いやすい。
  • PCBiteキット:ステンレス製のバネ式ジョーでPCBの端を挟み込む固定具。柔軟なアームこそないが、平らな机の上でPCBをしっかり固定してはんだ付け、取り外し、リワークを行うのに適している。
  • ラジオペンチ:ブレッドボードに部品を挿したり、ピンを曲げたりするのに欠かせない。
  • 斜めニッパー:PCBにはんだ付けした部品の脚を切りそろえるのに使う。コネクタやケーブルをつかんだり、こじ開けたりするのにも使える。
  • フラッシュカッター:はんだ接合部のすぐ近くで、リード線をきれいに切るための道具。
  • 保護メガネ:切ったリード線や溶けたはんだが飛んでくることがあるため、目を保護する。SparkFunの生産ラインでも使用している。
  • モノクル(拡大鏡):PCB上のはんだ接合部やSMD部品を検査するのに便利。LEDが作業距離で十分な明るさを提供してくれる。

はじめてのはんだ付け

これらの道具を実際に使ってみよう。 基本のルールは次のとおりである。

  • 熱いこてを扱うときは注意する
  • サードハンドやバイスを使って、はんだ付け中は基板を固定する
  • こての温度は適度な中温(325〜375℃)に設定する
  • はんだから煙が出ているようなら、温度を下げる
  • 接合部を準備するため、はんだ付けのたびにこて先にはんだを馴染ませておく(予備はんだ)
  • こての先端そのものではなく、こての側面(スイートスポットと呼ばれる部分)を使う
  • パッドとはんだ付けしたい部品の両方を、同時に均等に加熱する
  • はんだを離してから、こてを離す
  • よいはんだ接合は、ボールや塊ではなく、火山やハーシーのキスチョコレートのような形になる

次の図は、よいはんだ接合がどのようなものかを理解する助けになるはずである。

作業が終わったら、はんだごての電源を切る前に、こて先を予備はんだしておくと寿命が延びる。

コツと裏技

サードハンドを使う以外にも、部品を基板にはんだ付けする方法はいくつかある。 完璧なはんだ接合を作るために、状況に応じたさまざまな技法が必要になることもある。 いくつか追加のコツを紹介しよう。

テープや粘着タックで部品を固定する

テープや粘着タックがあれば、配線やヘッダーを基板に押さえつけておくのに使える。

シリコンや厚紙のかけらを断熱材として使う

部品を押さえておきたいが、熱くて指では触れられないという場合は、シリコンや厚紙のかけらを使って数秒間押さえておくとよい。

古いシールドや開発ボード、ブレッドボードを補助として使う

手がそれほど器用でない場合は、古いシールドや開発ボードを使ってヘッダーをはんだ付け前に位置合わせすることができる。 シールドやブレイクアウト基板がブレッドボードに収まる場合は、ブレッドボードを使ってピンを固定しながらはんだ付けすることもできる。 2列のヘッダーを持つ基板におすすめの方法だが、熱をかけすぎるとブレッドボードが溶けてしまうことがあるので注意すること。

グラウンドプレーンと大きなスルーホール

設計によっては、めっきスルーホールのパッドがグラウンドプレーンに接続されていたり、通常より大きかったりすることがある。 これらにはより多くの熱が必要である。 はんだが「くっついている」ように見えても、実際にはただ玉になって盛り上がっているだけということがある。 次のような対策が必要になる場合がある。

  • より大きなこて先を使う
  • はんだ付けステーションの温度をより高く(およそ380℃程度)設定する
  • フラックスを追加する
  • こてを接合部に少し長く当てておく

フラックスを足し、こてを少し長く当てておくと、たいていうまくいく。 出力の大きい、温度調整可能なはんだ付けステーションを使うと、冷たいものに触れたあとのこて先の温度回復が速くなる。 友人やもう1本のはんだごてがあれば、2本のこてで同時に接合部を温めるという方法もある。

高度な技法とトラブルシューティング

高度なPTH技法

よいはんだ接合の基本を身につけたら、より高度なPTHの技法を学ぶ番である。 フラックスの使い方、はんだブリッジの除去、部品の取り外しなどが含まれる。

PTHはんだ付けに関するそのほかのコツを紹介する。

  • 取り外し(デソルダリング)は、はんだ付けを学ぶのに最適な方法であることが多い。修理、アップグレード、部品の再利用など、部品を取り外す理由はさまざまである。
  • スルーホールからはんだを取り除くもうひとつの方法として、「スラップ法」と呼ばれる方法もある。
  • 作ったはんだ接合が本当に電気的な接続を作っているか分からない場合は、テスターの導通モードを使って確認できる。

ヘッダーを基板に押さえつけて固定する

手先が器用であれば、ピンを基板に指で押さえつけながらヘッダーの列を取り付けることもできる。 先述のテープや粘着タックを使う方法も試してみてほしい。

ヘッダーを取り付ける際は、片手ではんだ付けする手を使い、もう片方の手の人差し指と親指でヘッダーを基板の端に向かって引き寄せ、中指で押さえながら固定する。 はんだごてが触れる予定のヘッダーピンには触れないように注意すること。

はんだ付けする手でこてを持ち、各ヘッダーにつき1本のピンを仮止めしていく。 すべてのヘッダーに1本ずつ仮止めが終わったら、ピンがまっすぐで基板に対して垂直になっているか確認する。 そうでなければ、ヘッダーピンを再加熱して位置を調整できる。

位置合わせができたら、残りのすべてのヘッダーピンをはんだ付けして完成させる。

高度なSMD技法

はんだごてだけでできる、より高度なテクニックについては、SMD部品のリワークに関する専用のチュートリアルも参考になる。

フラックスの残留物を洗浄する

鉛フリーはんだを扱っていると、はんだに含まれるフラックスや、作業者が外部から塗布したフラックスがあちこちに付着しがちである。 一部のフラックスは時間の経過とともにPCBや部品を腐食させることがあるため、フラックスの残留物を除去する洗浄方法を知っておくことが重要である。 これは、空気中の湿気によって微細な樹枝状の析出物ができ、ピン間に高抵抗の短絡を引き起こすこともある。

水溶性フラックスの残留物は、はんだ接合部やその周辺に黄色や茶色のコーティングとして現れることが多い。 ノークリーンフラックスは、基板上に白くベタついたものとして残ることが多いが、非導電性なので基板上に残しておいてもかまわない。

基板に水溶性フラックスの残留物がある場合は、除去する必要がある。 ノークリーンフラックスの場合は、基本的に除去は不要である。 水溶性フラックスを洗浄するもっとも簡単な方法は、毛先の硬い小さなブラシ(歯ブラシでもよい)や綿棒を使い、熱い純水ではんだ接合部をこすることである。 水の代わりにイソプロピルアルコールを使うこともできる。 ノークリーンフラックスをどうしても除去したい場合は、水ではなくイソプロピルアルコールを使うのが最善である。 使っているはんだのドキュメントを確認し、正しい洗浄方法を確かめること(アセトンが必要なフラックスもある)。

複数の基板をはんだ付けする場合は、まとめて洗浄する必要が出てくることもある。 その場合は、蒸留水を入れたスロークッカー(クロックポット)を使うことをおすすめする。 蒸留水を使えば、回路に不純物が付着するのを防げる。 ただし、すべての基板を水に浸けられるわけではないため、手作業で洗浄しなければならない場合もある。 熱い純水を満たしたスロークッカーがあれば、この作業を速く進められる。

水に濡れると困るセンサーや部品には十分注意すること。 特定の部品は水に弱いため、そうした基板を水に浸けたり濡らしたりしないように気をつけよう。 以下は水との接触を避けるべき部品の一例である。水がこれらの内部に入り込んだまま電源を入れると、部品を損傷する可能性が高い。

  • キャラクターLCD
  • 7セグメントLEDディスプレイ
  • 電池
  • GPSモジュール
  • 無線モジュール
  • 気圧センサー
  • スライド式ポテンショメータ
  • マイク
  • スピーカー
  • 心拍センサーIC

洗浄が終わったら、基板の余分な水分を取り除く。 エアダスターを使えば、自然乾燥を待たずに済む。 紙タオルで拭くこともできるが、繊維くずが残ることがあるため、リントフリーのワイプを使うほうがよい。 ヒートガンがあれば、それを使って基板を温めることもできるが、基板上の部品を溶かさないよう注意すること。

基板の洗浄は必須ではないが、回路の寿命を大きく伸ばしてくれる。 また、基板がきれいであれば、シリアル通信で送られるデータの信頼性も高まる。

はんだ接合のテストとトラブルシューティング

洗浄が終わったら、先ほど述べたとおり、テスターの導通モードではんだ接合を確認してみるとよい。 問題が起きて、あるピンが基板に正しくはんだ付けされているかを確認したいときに役立つ。

まとめ

はんだ付けの世界の入り口に立ったところである。 PTHはんだ付けを習得したら、次のようなスキルやチュートリアルにも挑戦してみてほしい。

castellated(お城の縁のような形状の)取り付け穴をパッドにはんだ付けする方法については、専用のガイドも確認してほしい。 表面実装部品(SMD)をブレイクアウト基板にはんだ付けする方法についても、関連チュートリアルが参考になる。

タグ: スキル、はんだ付け、プロジェクトを始める、道具


出典:How to Solder: Through-Hole Soldering(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

電子部品の組み立て

SparkFunでは、電子機器を組み立てるにあたって、かなり型破りな方法を採用している。 DIYによるPCBA(プリント基板の組み立て)に取り組んできたこの10年間で得られたステップと教訓の一部をここにまとめた。 今では自宅の地下室でやるようなことではなくなった部分もあるが、私たちがどうやって(毎月8万個以上のガジェットを)作っているのか気になるなら、ぜひ読み進めてほしい。

まずは生産の最初の段階から見ていこう。 つまり、設計はすでに検証、試作、レビューを経て「赤い基板に進む」段階にある(緑色の試作基板が量産の準備が整うと、赤色でPCBを作る)ことを前提としている。 あとは実際に作るだけである。

電子工作にまったく初めて触れるなら、まずPCB基板の基礎を確認しておくとよい。

参考になるチュートリアル:

SparkFunでの電子部品の組み立ては、たいてい次の7つの工程を経る。

  • ペーストステンシリング
  • 部品の配置
  • リフロー
  • 手作業でのはんだ付け
  • 検査とテスト
  • 洗浄
  • パッケージング

それでは、それぞれの工程を順番に見ていこう。

ステンシリング

はんだペーストのステンシリングは、Tシャツにシルクスクリーンで印刷するのとよく似ている。 インクを塗りたいものの上にマスクを重ねるのと同じように、私たちはPCB(プリント基板)の特定の部分にだけペーストを塗るために、金属製のステンシルを使う。

SparkFunでは、まずPCBパネルから作業を始める。 パネルとは、同じ設計を何枚も繰り返し並べた、扱いやすくするための大きな基板である。 この例では、EL Escudo Dosを16枚まとめている。 このような大きなパネルを使うのは、複数の基板を同時にステンシリングできるようにするためである。 もちろん、1枚ずつステンシリングすることも同じように可能である。

部品が乗る予定のそれぞれのパッドに、少量のはんだペーストを乗せていく。 この作業を速くするため、基板の上にステンシルを重ね、金属製のスキージーでステンシルの上からペーストを塗り広げる。

これが実際のはんだペーストの姿である。 金属合金の混合物であり、スズ(Sn)96.5%、銀(Ag)3%、銅(Cu)0.5%で構成されている。 たいていのペーストには使用期限があり、涼しい場所で保管する必要がある。 これは、ペーストの粘度を作り出すために金属に加えられているフラックスに関係している。 フラックスは、金属が液体になったときの表面張力を変化させ、接合部への流れ込みを助ける役割を持つ。

SparkFunでは鉛フリーのはんだペーストを使っているが、ヨーロッパで製品を販売する予定がないのであれば、鉛入りのペーストのほうが多少扱いやすく、失敗にも寛容である。

すべての基板はEagle PCBで設計している。 このソフトウェアは、PCBメーカーが実際の基板を作るために使うさまざまなレイヤーファイルを出力する。 このほかにも(表面用と裏面用の)2つのペーストレイヤーがあり、これをステンシル製造業者に送っている。 彼らは高出力のCO2レーザーを使い、薄いステンレス板からステンシルを切り出している。

ステンシリングは手作業でも行える。 ペーストをぐいっと塗りつけるのに魔法のようなコツがあるわけではない。 市販のパテナイフをそのまま使うことが多い。

SparkFunにはステンシリング用の機械もある。 機械を設定するのはかなり手間がかかるが、非常に大量(500個以上)に生産する場合には、ステンシリングがいくらか楽になる。

ピックアンドプレース

基板にペーストを塗り終えたら、その上に部品を配置していく。 これは手作業でも機械でも行える。 ピンセットを使うのは、部品を配置するのによい方法である。 電子機器を作るには大きくて高価な機械が必要だという思い込みがよくあるが、それは事実ではない。 人間は部品の配置がかなり速く、液体金属の表面張力のおかげで、たいていの部品はリフローの過程で正しい位置に収まっていく。 とはいえ、人間には体力の限界がある。 数時間もすると、部品を素早く配置するのが難しくなってくる。 部品の小ささは目にも負担をかける。

電子機器を作るのにピックアンドプレース機は必要ないが、大量の電子機器を作るにはピックアンドプレース機が必要になる。

SparkFunは、すべての部品を手作業で配置することから始まり、今もそれは変わっていない。 とはいえ、100個以上作る必要がある場合は、ピックアンドプレース機を使って大量の基板を組み立てている。

ピックアンドプレース(PNP)機とは、真空を使ってテープから部品を持ち上げ、正しい向きに回転させてから基板に配置する、ロボット式の組み立て装置である。 組み立てのために機械をセットアップするのには数時間かかるが、いったん動き出せば非常に速い。

大きな工場では、コンベアベルトが自動ペースト塗布機から直接ピックアンドプレース機へと基板を運ぶことが多いが、SparkFunでは生産フロアの中を基板を手作業で運んでいる。

リフロー

ピックアンドプレースのあとは、しっかりしたはんだ接合を作るためにペーストをリフローする必要がある。 基板はコンベアベルトに乗せられ、大きなオーブンの中をゆっくりと通過しながら、はんだを溶かすのに十分な熱(およそ250℃)にさらされる。 基板がオーブンの中を進むにつれて、さまざまな温度ゾーンを通過し、制御された速度で温度が上下する。

ペーストは、お皿にくっついたバターのように、ねばつく質感をしている。 基板がリフロー炉の中をゆっくり通過する間、部品はその場に固定されたままになる。

リフロー炉は、いわばピザ窯のようなものである。 基板の温度はおよそ250℃(約480°F)まで上げられ、その時点でペーストは液体状の金属に変わる。 基板がリフロー炉から出てくると急速に冷え、すべての部品がその場ではんだ付けされる。

DIYのトースターオーブンを使ったリフローの各段階の様子を見てみると分かりやすい。 最初は、さまざまなパッドの上に灰色のはんだペーストの小さな塊が見える。 このペーストはステンシルではなく手作業で塗られたものと思われるが、この程度の雑さがあとになってもさほど問題にならないことがすぐに分かるはずである。 やがて最初の節目が訪れる。ペースト内のフラックスがサラサラになり、水たまりのように広がり始める。 金属のはんだはまだ溶けていない。 そのあと、はんだが溶け始め、溶けたはんだの表面張力によって、パッドの中心にできるだけ小さな塊にまとまろうとする。

部品がリフローの過程でどれほど動かされるかも見て取れる。 一部の部品は位置がずれてしまい、あとでやり直しが必要になる。 とはいえ、この収縮して動こうとする性質のおかげで、わずかな位置ずれやはみ出したはんだは、たいてい自然と修正される。 ただし、非常に小さな部品では、片側だけが強く引っ張られると、部品が縦に立ち上がってしまうことがある。 これは「トゥームストーニング(墓石現象)」と呼ばれ、基板の機能的な不良の原因になる。

触っても冷たいこの基板には、すべてのSMD部品がPCBに完全にはんだ付けされている。 これで次の工程に進む準備が整った。

両面基板はどう作るのか

一部の組み立て品(たとえばArduino Fio)は、基板の両面に部品を持つ。 このような場合、まず部品数が少なく、部品も小さいほうの面にステンシリングとリフローを行う。 リフロー炉から出てきたら、反対側にもステンシリングと部品配置、リフローを行う。 金属の表面張力は非常に高く、すべてをその場に固定してくれる。 より複雑な組み立て品を扱う大規模な工場では、リフローの間に部品が動かないよう、ピックアンドプレースの段階で基板の各部を接着剤で固定することもある。

手作業でのはんだ付け

リフローのあと、技術者が基板を受け取り、PTH(めっきスルーホール)部品を手作業ではんだ付けする。 より大規模な生産施設では、スルーホール部品のはんだ付けに「波はんだ付け」と呼ばれる技法が使われることもある。 これは、溶けたはんだの定常波の上に基板を通過させ、部品のリード線や基板上の露出した金属にはんだを付着させる方法である。

SparkFunでは、設計や数量が非常に多岐にわたるため、できるだけ多くの部品をSMD(表面実装部品)に寄せ、PTH部品は手作業ではんだ付けするほうが効率的だと分かった。 生産フロアではHakko FX-888Dのはんだごてを使っている。 これは非常によく機能するが、より低価格なAtten 937bも、はんだ付けを始めたばかりの人にはちょうどよい。

検査とテスト

次の工程は光学検査である。 光学検査では、部品に関する問題(間違った抵抗値、コンデンサの欠品など)を見つけ出す。 AOI(自動光学検査)機は非常に高速で、ほぼリアルタイムに近い速度で動作する。 AOIは、異なる角度から複数の高性能カメラを使い、はんだ接続部(「フィレット」と呼ばれることもある)のさまざまな部分を確認する。 良好なはんだフィレットと不良なはんだフィレットとでは光の反射のしかたが異なるため、AOIは異なる色のLEDで照らしながら、すべての接続を高い精度と速度で検査している。

自分の基板にも光学検査が必要かというと、おそらくそうではない。 SparkFunでも、月に3万枚を超える基板を生産するようになり、すべてのエラーを見つけるのがだんだん難しくなってきてから、ようやく導入した。

たいていの基板は、自動光学検査(AOI)機に通される。 光学検査では、正しい部品が正しい位置に配置されているか、はんだフィレットが正しいか、隣接するピンの間にはんだブリッジがないかを確認する。

基板の検査が終わったら、次はそれが意図どおりに動作するかをテストする。

1枚の基板をテストするのに15秒かかると想像してみてほしい。 10枚テストするなら、およそ3分である。 1500枚だとしたら、6時間を超える気の遠くなるようなテスト作業になる。 私たちは、テスト手順とプログラムをできるだけ迅速にするために、多大な時間を費やしている。

この工程を速くするため、技術者たちは「ポゴベッド」と呼ばれることもあるテスト治具を使っている。 ポゴピンは、バネ仕掛けの先端を使って、基板上のさまざまな電源やデータのポイントに一時的な電気的接続を作る。 基板やパネルがポゴベッドに載せられると、基板が電気的に完全に機能しているかを確認するためのさまざまなテストが行われる。 これには、レギュレータの出力電圧のテスト、特定のピンで期待される電圧の確認、テスト対象の基板にさまざまなコマンドを送って正しく応答するかを確かめる作業などが含まれる。 プログラム書き込みや校正が必要な基板では、コードを書き込んで出力を検証する追加の手順も行われる。

より大規模な施設では、電源を入れる前に基板上のすべての接続の導通をテストするために、フライングプローブやベッドオブネイルズと呼ばれる治具が使われることもある。 これらのより大がかりな治具は、より複雑で高価な製品に向いているが、製作には数万ドルかかることも珍しくない。

洗浄

製造工程のさまざまな段階で、基板には残留物が残る。 SparkFunのはんだ付けキットを組み立てたことがあれば、はんだ付けによって基板にわずかなフラックスが残ることを知っているはずである。 数か月が経過すると、このフラックスの残留物はべたつき、見た目も悪くなり、わずかに酸性になってはんだ接合を弱めてしまうことがある。 これを防ぐため(そしてお客様に一番きれいな基板を届けるため)、SparkFunでは生産するすべての基板を洗浄している。

基板をきれいにするため、私たちは「食器洗い機」と呼んでいる装置にまとめて基板を入れる。 この高温かつ高圧のオールステンレス製食器洗い機は、脱イオン水を使って製造工程で付着した残留物を取り除く。

この洗浄機は閉じたループのシステムを採用している。 洗浄が終わると、排水はいったん洗浄機の下にある槽に集められ、自動的に電気伝導度がテストされる。 電気伝導度が非常に低ければ(つまり抵抗が非常に高ければ)、洗浄工程は完了しており、排水は非常に高品質なフィルターを通して再利用される。

そう、私たちは高価な電子機器を丸ごと水に浸けているのである。 秘密は水の種類にある。 脱イオン水は、イオンをまったく含まない非常に純粋な水である。 携帯電話をトイレに落としても壊れないのは水そのもののせいではなく、機器のさまざまな部分をショートさせるのはイオンのほうである。 DI水(脱イオン水)にはイオンが含まれていないため、実は人体にとってはかなり有害である。 DI水を扱うこと自体は安全だが、DI水を飲んでしまうと、体内に取り込む過程で体からイオンを奪ってしまい、深刻な害を及ぼすことがある。 DI水はイオンに対する「渇き」が非常に強いため(うまいことを言ったつもりである)、食器洗い機の内部はすべてステンレス製になっている。 他の金属ではあっという間に腐食してしまうだろう。

高価な洗浄機を持っていない場合はどうすればよいだろうか。 脱イオン水を入れた安価なスロークッカーと歯ブラシがあれば、十分にうまくいく。 数枚の基板だけを洗浄したいなら、イソプロピルアルコールを含ませた綿棒でもよく機能する。

扇風機や圧縮空気を使えば、残った水分をうまく取り除ける。

パッケージング

基板は、その旅の終わりに近づいている。

洗浄が終わり乾燥したバッチの基板は、パッケージング工程へと進み、それぞれの基板が個別にESD対応のプラスチックに熱圧着される。

ピッキングや注文の梱包作業をできるだけ速く行えるようにするため、すべての製品が出荷部門にとって「すぐ取り出せる」状態になるようにしている。 たいていの製品では、両端にバーコードラベルを付けた10個1組の連なりを作る。 このバーコードラベルには、製品名、SKU、そして問題が起きたときに追跡できるようにするためのバッチ識別子が含まれている。

製品の梱包が完全に終わると、出荷フロアへと送られる。 出荷される在庫を記録し、「仕掛品」の数量をすべて差し引き、新しい数量を店頭の在庫に加える。 そこから製品は、あなたの手元へと届くまったく新しい旅を始めることになる。 そのチュートリアルはまた別の機会に譲ろう。

まとめ

SparkFunでの電子機器の作り方を紹介した。 ここまで読んでくれたなら、次のようなチュートリアルもおすすめである。

タグ: 記事、はんだ付け、道具


出典:Electronics Assembly(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

PCB基板の基礎

電子工学における重要な概念のひとつが、プリント基板(PCB)である。 あまりにも基本的な存在であるため、PCBとはそもそも何なのかを説明することを忘れられがちである。 このチュートリアルでは、PCBがどのように構成されているか、そしてPCBの世界でよく使われる用語のいくつかを解説する。

これから、プリント基板の構成、用語、組み立て方法、そして新しいPCBを設計する際の設計プロセスについて簡単に紹介していく。

参考になるチュートリアル:

始める前に、このチュートリアルが前提としているいくつかの概念について読んでおくとよい。

PCBとは何か

プリント基板(printed circuit board)というのがもっとも一般的な呼び方だが、「プリント配線板」や「プリント配線カード」と呼ばれることもある。 PCBが登場する以前、回路は配線を1本ずつ手作業でつなぐ、非常に手間のかかるポイントツーポイント配線という方法で作られていた。 このため、配線の接合部でよく故障が起きたり、被覆が経年劣化してひび割れると短絡(ショート)が起きたりしていた。

大きな進歩となったのがワイヤーラッピングの登場である。 これは、細い配線を各接続点のピンに文字どおり巻きつける方法で、気密性が高く、非常に丈夫でありながら簡単に配線をやり直せる接続を作り出せた。

電子機器が真空管やリレーからシリコンや集積回路へと移り変わるにつれて、電子部品の大きさとコストは低下し始めた。 電子機器が消費者向け製品に広く使われるようになると、電子製品の小型化と製造コスト削減への圧力から、メーカーはより優れた解決策を模索するようになった。 こうして生まれたのがPCBである。

PCBとはprinted circuit board(プリント基板)の略である。 これは、さまざまな地点どうしをつなぐ配線パターンとパッドを備えた基板である。 上の写真では、配線パターン(トレース)がさまざまなコネクタや部品を電気的に接続している。 PCBを使うことで、物理的な部品間で信号や電力をやり取りできる。 はんだは、PCBの表面と電子部品の間に電気的な接続を作る金属である。 金属であるはんだは、強力な機械的接着剤としての役割も果たす。

構成

PCBは、いわば層状のケーキやラザニアのようなもので、異なる材料の層が熱と接着剤によって積層され、ひとつの物体としてまとめられている。

中心から外側に向かって順番に見ていこう。

FR4

基材、つまり土台となる素材には、たいていガラス繊維が使われる。 このガラス繊維の呼び名として歴史的にもっとも一般的なのが「FR4」である。 この固い芯材が、PCBに剛性と厚みを与えている。 Kapton(あるいは同等品)のような柔軟な耐熱プラスチックの上に作られた、柔軟なPCBもある。

PCBの厚さにはさまざまな種類があり、SparkFun製品でもっとも一般的な厚さは1.6mm(0.063インチ)である。 一部の製品(LilyPad基板やArduino Pro Micro基板など)では、0.8mm厚の基板が使われている。

より安価なPCBやパーフボード(穴あき基板)には、エポキシ樹脂やフェノール樹脂のような、FR4ほどの耐久性はないがずっと安価な素材が使われることがある。 このタイプの基板にはんだ付けをすると、非常に特徴的な嫌な臭いがするため、すぐに見分けがつく。 このような基材は、低価格帯の家電製品でもよく見られる。 フェノール樹脂は熱分解温度が低いため、はんだごてを基板に長く当てすぎると、層が剥離したり、煙が出たり、焦げたりすることがある。

次の層は薄い銅箔であり、熱と接着剤によって基材に積層される。 一般的な両面PCBでは、基材の両面に銅が貼られる。 より低コストな電子機器では、片面にしか銅が貼られていないPCBが使われることもある。 両面基板2層基板と呼ぶとき、それはこのラザニアの中にある銅の層の数(2層)を指している。 これは1層だけのこともあれば、16層以上に及ぶこともある。

銅の厚さはさまざまだが、1平方フィートあたりのオンス数で規定される。 たいていのPCBは1平方フィートあたり1オンスの銅を使っているが、非常に大きな電力を扱うPCBでは2オンスや3オンスの銅が使われることもある。 1平方フィートあたり1オンスは、およそ35マイクロメートル(0.0014インチ)の銅の厚さに相当する。

ソルダーマスク

銅箔の上に重ねられる層は、ソルダーマスク層と呼ばれる。 この層が、PCBに緑色(あるいはSparkFunの場合は赤色)を与えている。 これは銅の層の上に重ねられ、銅の配線パターンが他の金属やはんだ、導電性のものにうっかり触れてしまわないよう絶縁する役割を持つ。 この層のおかげで、使う人は正しい場所にはんだ付けしやすくなり、意図しないはんだブリッジを防げる。

下の例では、緑色のソルダーマスクがPCBの大部分に施され、細い配線パターンを覆い隠しつつ、はんだ付けできるように銀色のリングやSMDパッドの部分だけを露出させている。

ソルダーマスクにもっともよく使われる色は緑だが、ほぼどんな色でも可能である。 SparkFunではほぼすべての基板に赤を、IOIO基板には白を、LilyPad基板には紫を使っている。

シルクスクリーン

白いシルクスクリーン層は、ソルダーマスク層の上にさらに重ねられる。 シルクスクリーンは、PCBに文字、数字、記号を印刷し、組み立てをしやすくしたり、人間が基板を理解しやすくしたりする役割を持つ。 それぞれのピンやLEDの機能を示すために、シルクスクリーンのラベルがよく使われる。

シルクスクリーンにもっともよく使われる色は白だが、どんなインクの色でも使うことができる。 黒、灰色、赤、さらには黄色のシルクスクリーンも広く使われているが、1枚の基板の上に複数の色を使うのはあまり一般的ではない。

用語集

PCBの構造についてのイメージがつかめたところで、PCBを扱う際によく耳にする用語をいくつか定義しておこう。

  • アニュラーリング:PCB上のめっきされたスルーホールの周りにある銅のリング。

  • DRC:デザインルールチェック。誤って接触している配線パターン、細すぎる配線パターン、小さすぎる穴など、設計上のエラーがないかを確認するソフトウェアによる検査。
  • ドリルヒット:設計上で穴をあけるべき場所、あるいは実際に基板上に穴があけられた場所のこと。切れ味の悪いドリルビットによる不正確なドリルヒットは、製造上よくある問題である。

  • フィンガー:基板の端に沿って露出した金属パッドで、2枚の基板の間を接続するために使われる。よくある例として、コンピュータの拡張基板やメモリ基板、古いカートリッジ式ビデオゲームの端の部分がある。
  • マウスバイト:パネルから基板を切り離すための、Vスコアに代わる手法。多数のドリルヒットを近くに密集させることで、あとから簡単に折り取れる弱い部分を作り出す。SparkFunのProtoSnap基板がよい例である。

  • パッド:部品をはんだ付けするための、基板表面に露出した金属部分。

  • パネル:使用前に切り離す、多数の小さな基板をまとめたより大きな基板。自動化された基板取り扱い装置は小さな基板をうまく扱えないことが多いため、複数の基板を一度にまとめることで工程を大幅に速められる。
  • ペーストステンシル:基板の上に重ねる薄い金属(あるいはプラスチック)製のステンシルで、組み立ての際に特定の場所にはんだペーストを塗布できるようにする。
  • ピックアンドプレース:基板に部品を配置するための機械、あるいはその工程のこと。
  • プレーン:経路ではなく境界線によって定義される、基板上の連続した銅の塊。「ポア(pour)」とも呼ばれる。

  • めっきスルーホール:アニュラーリングを持ち、基板を貫通してめっきされた穴。スルーホール部品の接続点、信号を通すためのビア、あるいは取り付け穴として使われる。

  • ポゴピン:テストやプログラム書き込みのために一時的な接続を作る、バネ仕掛けの接点。

  • リフロー:パッドと部品のリード線の間にはんだ接合を作るために、はんだを溶かすこと。
  • シルクスクリーン:基板上の文字、数字、記号、図柄のこと。たいてい1色しか使えず、解像度も比較的低い。
  • スロット:基板上にある、丸くない穴のこと。めっきされている場合もされていない場合もある。切り抜きに余分な時間がかかるため、基板のコストを押し上げる要因になることがある。

  • はんだペースト:ジェル状の媒体の中に小さなはんだの粒を分散させたもので、部品を配置する前に、ペーストステンシルを使ってPCBの表面実装用パッドに塗布する。リフローの過程で、ペースト内のはんだが溶け、パッドと部品の間に電気的にも機械的にも接合を作り出す。

  • はんだポット:スルーホール部品を使った基板を素早く手作業ではんだ付けするための容器。少量の溶けたはんだが入っており、そこに基板を素早く浸すことで、露出したすべてのパッドにはんだ接合を作る。
  • ソルダーマスク:短絡、腐食、その他の問題を防ぐために金属の上に敷かれる保護材料の層。たいてい緑色だが、他の色(SparkFunの赤、Arduinoの青、Appleの黒など)も可能である。「レジスト」と呼ばれることもある。

  • はんだブリッジ:基板上の部品の隣接する2本のピンをつなぐ、小さなはんだの塊。設計によっては、2つのパッドやピンをあえて接続するために使われることもあるが、意図しない短絡の原因になることもある。
  • 表面実装:部品のリード線を基板の穴に通す必要がなく、基板の上にそのまま置くだけで済む実装方式。現在もっとも主流の組み立て方法であり、基板への部品実装を素早く簡単に行える。
  • サーマル:パッドをプレーンに接続するための小さな配線パターン。パッドが適切にサーマルリリーフされていないと、良好なはんだ接合を作るのに十分な温度までパッドを上げるのが難しくなる。適切にサーマルリリーフされていないパッドは、はんだ付けしようとすると「ねばつく」ように感じられ、リフローに異常に長い時間がかかる。

  • 銅箔ハッチング(thieving):プレーンや配線パターンが存在しない基板上の領域に残される、格子状の網目や点状の銅。エッチング液に浸す時間を短縮でき、不要な銅を取り除く作業が楽になる。
  • トレース(配線パターン):基板上の連続した銅の経路。

  • Vスコア:基板に入れる部分的な切り込みで、その線に沿って基板を簡単に折り取れるようにする。
  • ビア:ある層から別の層へ信号を通すために基板にあけられた穴。テンテッドビアはソルダーマスクで覆われ、はんだ付けされてしまわないよう保護されている。コネクタや部品を取り付けるビアは、簡単にはんだ付けできるよう、たいていテントされていない(覆われていない)。

  • 波はんだ付け:スルーホール部品を使った基板に使われるはんだ付け方法で、基板を溶けたはんだの定常波の上に通過させ、露出したパッドや部品のリード線にはんだを付着させる。

自分でPCBを設計する

自分でPCBを設計するには、どうすればよいのだろうか。 PCB設計の細部はここで語り尽くせるものではないが、本当に始めてみたいなら、次のようなポイントを押さえておこう。

  1. CADソフトを見つける。市場には低価格または無料のPCB設計用ソフトウェアが数多くある。ソフトウェアを選ぶ際に考慮すべき点は次のとおりである。
    • コミュニティの充実度:そのソフトウェアを使っている人は多いか。使っている人が多いほど、必要な部品のライブラリがすでに用意されている可能性が高くなる。
    • 使いやすさ:使うのが苦痛であれば、結局使わなくなってしまう。
    • 機能面での制約:一部のソフトウェアは、レイヤー数、部品数、基板サイズなどに制限を設けている。たいていはライセンス料を払うことで機能を拡張できる。
    • 移植性:無料のソフトウェアの中には、設計データのエクスポートや変換を許可しておらず、特定の1社にしか発注できなくなるものもある。それが利便性や価格に見合った代償かどうかは、場合によるだろう。
  2. 他の人の基板レイアウトを見て、どのように設計されているかを参考にする。オープンソースハードウェアのおかげで、これはかつてないほど簡単になっている。
  3. とにかく練習を重ねる。
  4. 期待しすぎないこと。最初に設計する基板には、たくさんの問題があるはずである。20枚目の基板になれば問題は減るだろうが、それでもいくつかは残る。問題を完全になくすことは決してできない。
  5. 回路図は重要である。しっかりした回路図を用意せずに基板を設計しようとするのは、徒労に終わる試みである。

最後に、自分で基板を設計することの有用性について触れておこう。 あるプロジェクトを2枚以上作る予定があるなら、基板を設計する見返りはかなり大きい。 プロトボード上でポイントツーポイント配線をするのは面倒であり、専用に設計された基板に比べて壊れやすい傾向がある。 また、その設計が人気を博せば、それを販売することもできる。

まとめ

PCBはほんの入り口にすぎない。 ここからさらに、次のようなチュートリアルを探求していくことをおすすめする。

自分のPCB作品を世界に発信したいなら、次のようなチュートリアルも確認してみてほしい(いずれも英語)。

タグ: 概念、電気工学、ProtoSnap


出典:PCB Basics(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

PCB設計ツールEagleの使い方

プリント基板(PCB)は、あらゆる電子ガジェットの背骨とも言える存在である。 マイクロプロセッサのような華やかさはなく、抵抗器のようにありふれてもいないが、回路の中のすべての部品を正しくつなぎ合わせるためには欠かせない存在である。

SparkFunでは、PCBの設計が大好きである。 その愛を広めたいと思っている。 これは、あらゆるレベルの電子工作愛好家にとって役立つスキルである。 このチュートリアルとそれに続くシリーズでは、私たちがすべてのPCBを設計するのに使っているのと同じソフトウェアであるEAGLEを使って、PCBを設計する方法を解説していく。

この最初のチュートリアルでは、ソフトウェアのインストール方法と、インターフェースやサポートファイルを自分好みに調整する方法を扱う。

なぜEAGLEなのか

EAGLEは、数あるPCB CADソフトウェアのひとつにすぎない。 では「EAGLEの何がそんなに特別なのか」と思うかもしれない。 私たちが特にEAGLEを気に入っている理由は、次のとおりである。

  • クロスプラットフォーム:EAGLEはWindows、Mac、さらにはLinuxまで、あらゆる環境で動作する。これは、他の多くのPCB設計ソフトウェアにはあまりない特徴である。
  • 軽量:EAGLEは、PCB設計ソフトウェアの中でもかなりスリムな部類に入る。必要なディスク容量はおよそ50〜200MB程度である(より高度なツールでは10GB以上必要になることもある)。インストーラー自体もおよそ25MBしかない。そのため、ダウンロードからインストール、実際にPCBを作り始めるまで、あっという間である。
  • 無料または低コスト:EAGLEのフリーウェア版は、SparkFunのカタログにあるほぼすべてのPCBを設計できるだけの機能を備えている。上位のライセンスにアップグレードする場合(自分の設計で利益を得たい場合)も、多くのハイエンドツールに比べて2桁は安く済む。
  • コミュニティのサポート:こうした理由から、EAGLEはホビイストのコミュニティにおけるPCB設計の定番ツールのひとつになっている。Arduino基板の設計を研究したい場合でも、人気のセンサーを自分の設計に取り込みたい場合でも、たいてい誰かがすでにEAGLEでそれを作り、共有してくれている。

もちろん、EAGLEにも弱点はある。 より高機能なPCB設計ツールの中には、より優れた自動配線機能や、シミュレータ、プログラマー、3Dビューアといった気の利いた道具を備えたものもある。 とはいえ私たちにとっては、EAGLEは初級から中級レベルのPCBを設計するのに必要なものをすべて備えている。 これまでPCBを設計したことがないなら、始めるのにうってつけのツールである。

参考になるチュートリアル:

この沼にはまる前に、次のようなチュートリアルや概念に慣れておくとよい。

ダウンロード、インストール、起動

EAGLEはAutodeskから提供されており、Fusion 360ソフトウェアパッケージの一部として、あるいはEAGLE単体の無料版として入手できる。 自分のOSに合ったバージョンを入手しよう(Windows、Mac、Linux向けが用意されている)。 ダウンロードサイズは比較的軽く、およそ125MBほどである。

EAGLEのインストールは、たいていのソフトウェアと同じである。 ダウンロードされるのは実行ファイルであり、それを開いてインストール手順に従うだけでよい。

EAGLEのライセンスについて

EAGLEのお気に入りの点のひとつは、無料で使えるということである。 無料版はホビイスト向けの制限付きバージョンで、個人が個人的かつ非営利の目的で利用できる「パーソナルラーニングライセンス」となっている。 無料版を使う際に知っておくべき制限がいくつかある。

  • PCBの設計面積は最大80cm²(12.4平方インチ)までに制限されているが、これでもかなり大きい。大きめのArduinoシールドを設計する場合でも、余裕でこの上限を下回るはずである。
  • 使用できる信号層は2層まで。それ以上のレイヤーが必要な場合は、シングルユーザーのFusion 360ライセンスへのアップグレードを検討するとよい。
  • 回路図エディタで使えるシートは2枚まで。
  • パーソナルラーニングライセンスは、個人による個人的かつ非営利の利用に限られる。自分の設計を販売するつもりであれば、Fusion 360ライセンスに含まれるシングルユーザーEAGLEライセンスを確認する必要がある。

こうした制限があっても、EAGLEは依然として素晴らしいソフトウェアである。 SparkFunのエンジニアたちも、あの非営利という制約さえなければ、フリーウェア版だけで自分たちの基板の99%を設計できるだろう。 自動配線機能を含め、EAGLEソフトウェアのすべての機能に無料版でもアクセスできる。

コントロールパネルを探索する

初めてEAGLEを開くと、コントロールパネルという画面が表示されるはずである。 コントロールパネルはEAGLEの「本拠地」であり、ソフトウェア内の他のすべてのモジュールをここから開くことができる。

コントロールパネルには6つのツリーがあり、それぞれソフトウェアの異なる機能を表している。

  • ライブラリ:ライブラリには部品が保存されている。部品とは、回路図記号とPCBフットプリントの組み合わせのことである。ライブラリにはたいてい関連する部品のグループが含まれており、たとえばatmel.lbrにはAtmel社のAVRデバイスが数多く収められており、74xx-us.lbrライブラリにはほぼすべてのTTL 74xxシリーズのICが収められている。
  • デザインルール(DRU):デザインルールとは、基板の設計データを製造業者に送る前に満たしておくべき一連のルールである。このツリーには、あらかじめ定義されたルールの集合であるDRUファイルが収められている。
  • ユーザー言語プログラム(ULP):ULPは、EAGLEのユーザー言語で書かれたスクリプトである。部品表の生成(bom.ulp)や、画像のインポート(import-bmp.ulp)といった作業を自動化するのに使える。
  • スクリプト(SCR):スクリプトファイルは、EAGLEのユーザーインターフェースをカスタマイズするのに使える。ワンクリックで配色やキー割り当てを設定できる。
  • CAMジョブ(CAM):CAMジョブは、ガーバーファイルの作成を助けるCAMプロセッサで開くことができる。
  • プロジェクト:それぞれのプロジェクトが1つのプロジェクトフォルダにまとめられている場所である。プロジェクトには回路図、基板設計、場合によってはガーバーファイルが含まれる。

ツリーの中のファイルを選択すると、ウィンドウの右側にそのファイルについての情報が表示される。 これは、ライブラリやプロジェクトの設計例(EAGLEには楽しいサンプルがいくつか同梱されている)を探索したり、スクリプトの目的を大まかに把握したりするのに便利な方法である。

SparkFunのライブラリを使う

EAGLEには、コントロールパネルから確認できる充実した部品ライブラリのリストが同梱されている。 何百ものライブラリがあり、抵抗器やNPNトランジスタのような特定の部品に特化したものもあれば、特定のメーカーに特化したものもある。 これは素晴らしいリソースだが、少々圧倒されてしまうこともある。 単純なスルーホール型の電解コンデンサを1つ追加したいだけでも、正しいものを見つけるために何十ものライブラリや部品をふるいにかける必要がある。

デフォルトの何百ものライブラリを使う代わりに、SparkFun EAGLEライブラリを使うという方法もある。 これは、SparkFun自身の設計で実際に使用した部品だけに絞り込んだライブラリであり、新しく見つけた部品が発見されるたびに継続的に更新されている。

デフォルトのライブラリの代わりに(あるいは追加で)SparkFunのライブラリをインストールして使う方法を紹介する。

ステップ1:SparkFunライブラリをダウンロードする

最新版のライブラリは、常にGitHubリポジトリで公開されている。 GitHubの使い方について助けが必要な場合は、Using GitHubのチュートリアルを参考にしてほしい。 基本的には、リポジトリのメインページで**「Download ZIP」をクリックする**だけでよい。

ZIPファイルを分かりやすい場所に保存し、フォルダを展開する(場所を忘れないように)。

ステップ2:ディレクトリウィンドウを更新する

EAGLEのコントロールパネルウィンドウに戻り、「Options」メニューから**「Directories」を選択する**。 これは、EAGLEがライブラリを含む6つのツリーの内容を表示する際に参照する、コンピュータ上のディレクトリの一覧である。

「Libraries」ボックスに、SparkFun EAGLEライブラリが保存されているディレクトリへのリンクを追加する。 デフォルトのライブラリを残したままSparkFunのライブラリを追加したい場合は、「$EAGLEDIR\lbr」の後ろにセミコロン(;)を追加し、その後にSparkFun EAGLEライブラリのディレクトリのパスを貼り付ける。

Note

MacとLinuxのユーザーは、セミコロンの代わりにコロン(:)でディレクトリを区切ること。

ステップ3:ライブラリを「使用する」

コントロールパネルの「Libraries」ツリーに戻ると、2つのフォルダが表示されているはずで、そのうちの1つがSparkFun EAGLEライブラリになっているはずである。 最後の手順は、(少なくとも今のところは)デフォルトのライブラリを使わないようEAGLEに伝えることである。 そのためには、「lbr」フォルダを右クリックし、「Use none」 を選択する。

次に、「SparkFun-Eagle-Libraries-master」フォルダを右クリックし、「Use all」 を選択する。 それぞれのフォルダ内のライブラリを確認すると、隣に灰色または緑色の点が表示されているはずである。 緑色の点はそのライブラリが使用中であることを、灰色の点は使用されていないことを示す。

自分で作ったライブラリの部品をSparkFunのEAGLEライブラリに追加してもらいたい場合は、専用のチュートリアルを参照してほしい。

プロジェクトを開いて探索する

EAGLEには、いくつかの気の利いたPCB設計のサンプルが同梱されている。 「Projects」ツリーを展開し、そこから「examples」フォルダの中の「arduino」プロジェクトを、赤いフォルダをダブルクリックして開いてみよう(あるいは右クリックして「Open project」を選択する)。 この画面では、プロジェクトフォルダは赤色で、通常のフォルダは標準の黄色で表示されることに注意してほしい。

プロジェクトを開くと、さらに2つのEAGLEウィンドウが立ち上がるはずである。基板エディタと回路図エディタである。 これらはEAGLEにおける陰と陽のような関係にあり、機能するPCB設計という完成品を作るために、両方を組み合わせて使う必要がある。

回路図エディタ(上の画像の左側)は、緑色のネット(配線)で相互に接続された、赤色の回路記号の集まりである。 プロジェクトの回路図は、プログラムのコードにおけるコメントのようなものである。 その基板設計が実際に何をするのかを説明するのに役立つが、最終製品そのものにはあまり影響を与えない。 回路図の中の部品は正確な寸法で配置されているわけではなく、あなたや他の人がその基板設計で何が起きているかを理解しやすいように、読みやすい形で配置され、接続されている。

基板エディタでは、実際の魔法が起きる。 ここでは色分けされた層が重なり合い、交差しながら、正確な寸法のPCB設計が作られていく。 2つの銅層(上が赤、下が青)は、異なる信号どうしが交差してショートしないよう、戦略的に配線される。 黄色い円(この設計では黄色だが、たいていは緑色)は「ビア」と呼ばれ、信号を片面からもう片面へと通す役割を持つ。 より大きなビアは、スルーホール部品を挿入してはんだ付けできるようにするためのものである。 このほかにも、現時点では隠れている層があり、部品をはんだ付けできるように銅を露出させている。

両方のウィンドウを開いたままにしておくこと

これら2つのウィンドウは、互いに連携して動作する。 回路図に加えた変更は、自動的に基板エディタにも反映される。 設計を修正する際は、常に両方のウィンドウを開いたままにしておくことが重要である。

たとえば、基板ウィンドウを閉じたまま回路図を修正し続けたとしよう。 回路図に加えた変更は、基板設計には反映されない。 これはよくない事態である。 回路図と基板設計は、常に一致していなければならない。 あとから整合性を取り戻そうとして変更をさかのぼるのは、非常に骨の折れる作業である。 常に両方のウィンドウを開いたままにしておこう

ウィンドウ間の整合性が取れていないかどうかを見分ける方法がいくつかある。 まず、両方のウィンドウの右下隅に「ドット」がある。 このドットが緑色であれば問題ない。 マゼンタ色であれば、閉じるべきでないウィンドウが閉じられている可能性が高い。 もうひとつ、より分かりやすいサインとして、どちらか一方のウィンドウを閉じると、もう一方に大きな警告が表示される。 この警告が表示されたら、すぐに作業を止めて、閉じてしまったウィンドウを開き直そう。 基板エディタや回路図エディタのウィンドウを再度開く簡単な方法は、「Switch to board/schematic」アイコンをクリックすることである(「File」メニューの中にもある)。

画面の操作方法

見過ごされがちな話題だが、これら2つのウィンドウの中をどう操作するかを知っておくことは重要である。

エディタウィンドウの中を移動するには、スクロールホイール付きのマウスが非常に役立つ。 ホイールを前後に回すことで拡大したり縮小したりできる。 ホイールを押し込んだままマウスを動かすと、画面をドラッグして動かせる。 3ボタンマウスがない場合は、表示オプションを使ってエディタ内を移動する必要がある。 これらのツールはツールバー上部の中央付近、あるいは「View」メニューの中にある。 拡大や縮小のツールはもちろん便利であり、選択範囲に合わせて表示を変える「Zoom select」ツールも便利である。 とはいえ、本気でEAGLEを使うつもりなら、やはりマウスを用意することをおすすめする。

UIを設定する

EAGLEのユーザーインターフェースは非常に細かくカスタマイズできる。 背景色からレイヤーの色、キー割り当てまで、好みに合わせて変更できる。 インターフェースを自分好みに調整しておくと、PCBの設計がずっと楽になる。 ここでは、SparkFunで好んで行っているUIのカスタマイズ方法を紹介する。 これらの手順は必須ではなく、自分の好みに合わせてUIをカスタマイズしてかまわない。 あくまで私たちが慣れ親しんでいる設定にすぎない。

背景色を設定する

私たちがいつも最初に行うUIの調整は、基板エディタの背景色である。 標準の白い背景は、基板設計に必要なさまざまな色のレイヤーとあまり相性がよくないことが多い。 そのため、たいてい黒い背景を選んでいる。

背景色を変更するには、「Options」メニューから「User interface」を選択する。 「Layout」ボックスの中で、背景を黒、白、あるいは特定の色に設定できる。 このボックスには他にも設定項目があるが、ソフトウェアにもう少し慣れるまでは、あまり手を加えないほうがよいかもしれない。

グリッドを調整する

基板エディタでもうひとつよく行うUI改善が、グリッドを表示することである。 PCB設計では寸法とサイズが非常に重要であるため、サイズを視覚的に確認できる目印があると非常に役立つ。 グリッド表示を有効にするには、基板ウィンドウの左上付近にあるアイコンをクリックする(あるいは「View」メニューから「Grid」を選択する)。

「Display」のラジオボタンを「On」に切り替える。 また、「Size」を100mil(0.1インチ)、「Alt」を50mil(0.05インチ)に設定して、グリッドの目を少し粗くしておくとよい。

スクリプトを実行する

スクリプトを使えば、インターフェースをもっと手早く設定できる。 ボタンを1回クリックするだけで、色やキー割り当てをすべて自動的に設定できる。 スクリプトファイルは共有することもでき、誰でも実行できる。 SparkFunのEAGLEスクリプトを実行すれば、私たちとまったく同じUIになる。

まず、専用のスクリプト(ZIPフォルダに入っている)をダウンロードする。 spk.scrファイルを、あとで分かりやすい場所に展開する。

次に、そのスクリプトを実行する。 基板ウィンドウでScriptアイコンをクリックする(あるいは「File」から「Execute Script」を選択する)。 ファイルブラウザで、先ほどダウンロードして展開したspk.scrファイルを選択する。

これで、次のような配色に自動的に設定されるはずである。

このUI設定は、レイヤーを見やすく論理的に表示してくれる。 重要な銅の層は非常に見やすく、かつ区別しやすい色になっており(上が赤、下が青、ビアが緑)、シルクスクリーンはたいていのPCB設計と同じように白になっている。

これらの色分けされたレイヤーの意味は、EAGLEを使い続けて探索していくうちに、より理解が深まっていくはずである。

SparkFunのカスタムEagle設定

SparkFunの最新のスクリプトやその他の便利なファイルは、GitHub上のEAGLE設定リポジトリで公開されている。

まとめ

EAGLEのセットアップが終わり、いよいよPCBの設計を始めたくてうずうずしているなら、次はEAGLEの使い方を扱う2部構成のチュートリアル、Using EAGLE: SchematicUsing EAGLE: Board Layoutに進むとよい。 この2つのチュートリアルでは、回路図の設計から、基板のレイアウトと配線、ガーバーファイルの生成、製造業者への送付までの流れを説明している。

このほかにも、EAGLEシリーズの次のようなチュートリアルがある(いずれも英語)。

  • How to Create SMD PCBs(SMD PCBの作り方):論理的にはPTH(スルーホール)のEAGLEチュートリアルの次に読むとよい内容である。もう少し高度で、テンポも速い。
  • How to Create SMD Footprints(SMDフットプリントの作り方):ライブラリの中に独自の部品を作りたい場合は、このチュートリアルを確認してほしい。
  • Making Custom Footprints in EAGLE(EAGLEでカスタムフットプリントを作る):もうひとつのフットプリント作成チュートリアルで、独自の1:1フットプリントを作るための特有の手順を詳しく解説している。

タグ: Eagle、スキル、プロジェクトを始める


出典:How to Install and Setup EAGLE(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Arduinoとは何か

Arduinoは、電子工作プロジェクトを作るためのオープンソースのプラットフォームである。 Arduinoは、物理的にプログラム可能な回路基板(しばしばマイクロコントローラと呼ばれる)と、パソコン上で動作するソフトウェア(統合開発環境、IDE)の2つから構成される。 このソフトウェアを使って、コードを書き、それを実際の基板に書き込む。

Arduinoプラットフォームは、電子工作を始めたばかりの人たちの間で非常に人気があり、それには理由がある。 これまでのプログラム可能な回路基板の多くとは異なり、Arduinoは新しいコードを基板に書き込むのに別売りの専用機器(プログラマー)を必要としない。USBケーブルを使うだけでよい。 さらに、Arduino IDEはC++を簡略化したような言語を使うため、プログラミングを学ぶのが簡単である。 そして最後に、Arduinoはマイクロコントローラの機能を扱いやすい形に引き出した、標準的なフォームファクタを提供している。

Unoは、Arduinoファミリーの中でも特に人気の高い基板であり、初心者にとってすばらしい選択肢である。 Unoに何が載っているか、それで何ができるかについては、このチュートリアルの後半で説明する。

信じられないかもしれないが、Arduino基板上のLEDを点滅させるには、わずか10行ほどのコードで十分である。 今の時点ではコードの意味が完全には分からなくても心配は要らない。 このチュートリアルと、このサイトに用意されている数多くのArduino関連チュートリアルを読み進めていけば、あっという間に理解できるようになるはずである。

このチュートリアルで扱う内容:

  • Arduinoで実現できるプロジェクトにはどのようなものがあるか
  • 一般的なArduino基板に何が載っているか、そしてそれがなぜ必要か
  • Arduino基板のさまざまな種類
  • Arduinoとあわせて使うと便利な部品

参考になるチュートリアル:

Arduinoは、あらゆるスキルレベルの人にとってすばらしい道具である。 とはいえ、基本的な電子工学の知識をあらかじめ理解しておくと、Arduinoでの学習がずっと楽しくなる。 Arduinoのすばらしい世界に飛び込む前に、少なくとも次のような概念をある程度理解しておくことをおすすめする。

Arduinoで何ができるのか

Arduinoのハードウェアとソフトウェアは、アーティスト、デザイナー、趣味人、ハッカー、初心者、そしてインタラクティブなモノや空間を作りたいと考えるあらゆる人のために設計されている。 Arduinoは、ボタン、LED、モーター、スピーカー、GPSユニット、カメラ、インターネット、さらにはスマートフォンやテレビとまでやり取りできる。 この柔軟性に加え、Arduinoのソフトウェアが無料であること、ハードウェア基板が手頃な価格であること、ソフトウェアとハードウェアの両方が学びやすいことから、非常に大きなユーザーコミュニティが生まれ、Arduinoを使った実に多種多様なプロジェクトのコードや作り方が公開されてきた。

ロボットや、暖かい手袋型のヒーティングパッド、正直すぎる占いマシン、さらにはダイスを振るガントレット型のデバイスまで、Arduinoはほぼどんな電子工作プロジェクトの頭脳としても使うことができる。

これはまだほんの入り口にすぎない。 Arduinoを使ったプロジェクトの例をもっと見てみたいなら、次のようなリソースが参考になる。

  • Instructables
  • Arduino Playground
  • The ITP Physical Computing Wiki
  • LadyAda
  • Make: Projects
  • もちろん、learn.sparkfun.comにも数多くのArduinoチュートリアルが用意されている

基板には何が載っているのか

Arduino基板にはさまざまな種類があり(異なる用途に応じて使い分けられる)、下の写真とは見た目が少し異なるものもあるが、たいていのArduinoは次のような部品の大部分を共通して備えている。

電源(USB/バレルジャック)

すべてのArduino基板には、電源に接続する何らかの方法が必要である。 Arduino UNOは、パソコンから伸びるUSBケーブルからでも、バレルジャックで終端された壁面電源からでも電源を取ることができる。 上の写真では、USB接続が**(1)、バレルジャックが(2)**とラベル付けされている。

USB接続は、Arduino基板にコードを書き込む手段でもある。

注記: 20ボルトを超える電源は絶対に使用しないこと。Arduinoに過大な電圧がかかり、破損してしまう。たいていのArduinoモデルで推奨される電圧は6〜12ボルトである。

ピン(5V、3.3V、GND、アナログ、デジタル、PWM、AREF)

Arduinoのピンは、回路を組み立てるために配線を接続する場所である(たいていブレッドボード配線と組み合わせて使う)。 たいてい黒いプラスチックの「ヘッダー」が付いており、配線をそのまま差し込むだけで接続できる。 Arduinoにはいくつかの種類のピンがあり、それぞれ基板上にラベルが付けられ、異なる機能を持つ。

  • GND (3):「グラウンド(Ground)」の略。Arduinoには複数のGNDピンがあり、どれを使って回路をグラウンドに接続してもよい。
  • 5V (4) と 3.3V (5):想像どおり、5Vピンは5ボルトの電力を、3.3Vピンは3.3ボルトの電力を供給する。Arduinoと組み合わせて使う単純な部品の多くは、5Vまたは3.3Vで問題なく動作する。
  • アナログ (6):「Analog In」というラベルの下にあるピン(UNOではA0からA5まで)はアナログ入力ピンである。これらのピンは、温度センサーのようなアナログセンサーからの信号を読み取り、コード側で扱えるデジタルの値に変換できる。
  • デジタル (7):アナログピンの反対側にあるのがデジタルピン(UNOでは0番から13番まで)である。これらのピンは、ボタンが押されたかどうかを調べるデジタル入力にも、LEDを点灯させるデジタル出力にも使える。
  • PWM (8):一部のデジタルピン(UNOでは3、5、6、9、10、11番)の横にチルダ(~)が付いていることに気づいたかもしれない。これらのピンは通常のデジタルピンとしても使えるが、パルス幅変調(PWM)と呼ばれる機能にも使える。今のところは、これらのピンがアナログ出力のようなふるまい(LEDを徐々に明るくしたり暗くしたりするなど)をシミュレートできる、と考えておけばよい。
  • AREF (9):アナログリファレンス(基準電圧)の略。たいていの場合、このピンには手を触れなくてよい。アナログ入力ピンの上限として、外部の基準電圧(0〜5ボルトの間)を設定するために使われることがある。

リセットボタン

Arduinoにはリセットボタン**(10)**が付いている。 これを押すと、リセットピンが一時的にグラウンドに接続され、Arduinoに書き込まれているコードが再起動する。 コードが繰り返し実行されない場合でも、何度もテストしたいときにとても便利な機能である。

電源LEDインジケーター

回路基板の「UNO」という文字の下、少し右側に、「ON」という文字の横に小さなLED**(11)**がある。 このLEDは、Arduinoを電源に接続すると点灯するはずである。 もしこのランプが点灯しなければ、何かがおかしい可能性が高い。回路をもう一度確認してみよう。

TXとRXのLED

TXは送信(transmit)、RXは受信(receive)の略である。 これらの表記は電子工学の世界でよく見かけるもので、シリアル通信を担当するピンを示している。 Arduino UNOでは、TXとRXの表記はデジタルピンの0番と1番の横、そしてTXとRXのインジケーターLED**(12)**の横という2か所に現れる。 これらのLEDは、Arduinoがデータを受信または送信しているとき(新しいプログラムを基板に書き込んでいるときなど)に、視覚的な手がかりを与えてくれる。

メインIC

金属製の脚がたくさん付いた黒い部品が、IC(集積回路)**(13)**である。 これはArduinoの頭脳だと考えればよい。 Arduinoに搭載されているメインICは基板の種類によって多少異なるが、たいていATMEL社のATmegaシリーズのICが使われている。 新しいプログラムをArduinoソフトウェアから書き込む前に、基板の種類とあわせてICの種類を知っておく必要がある場合があるため、この点は覚えておくとよい。 この情報はたいていICの上面に印字されている。

電圧レギュレータ

電圧レギュレータ**(14)**は、Arduino上で実際に操作する部品ではないが、それが何のためにそこにあるのかを知っておくとよい。 電圧レギュレータは、その名のとおり、Arduino基板に取り込む電圧の大きさを制御している。 一種の門番のようなもので、回路を傷める恐れのある過大な電圧をはじいてくれる。 もちろん限界はあるので、20ボルトを超える電源をArduinoに接続してはいけない。

Arduinoファミリー

Arduinoにはさまざまな基板があり、それぞれ異なる能力を持っている。 また、オープンソースハードウェアであることの利点として、他の人々がArduino基板を改造したり派生版を作ったりすることで、さらに多くのフォームファクタや機能が生まれている。 Arduinoの世界に入ったばかりの人に向いている選択肢をいくつか紹介する。

Arduino Uno (R3)

Unoは、最初のArduinoとしてすばらしい選択肢である。 始めるのに必要なものはすべて揃っており、余計なものは何もない。 14本のデジタル入出力ピン(うち6本はPWM出力として使える)、6本のアナログ入力、USB接続、電源ジャック、リセットボタンなどを備えている。 マイクロコントローラを動かすために必要なものはすべて内蔵されており、USBケーブルでパソコンに接続するか、AC-DCアダプタや電池で電源を供給するだけで使い始められる。

LilyPad Arduino

これはLilyPad Arduinoのメイン基板である。 LilyPadは、Leah Buechleyによって開発され、LeahとSparkFunが共同で設計したウェアラブルなe-テキスタイル技術である。 それぞれのLilyPadは、大きな接続パッドと平らな背面を持つように工夫されており、導電糸を使って布に縫い付けることができる。 LilyPadには、e-テキスタイル専用に作られた入力、出力、電源、センサー用の基板ファミリーもある。 水洗いすらできるものもある。

RedBoard

SparkFunでは数多くのArduinoを使っており、常にもっともシンプルで安定した基板を探し求めている。 どの基板も少しずつ違い、私たちが求めるすべての機能を備えたものはなかったため、お気に入りの機能をすべて組み合わせた独自バージョンを作ることにした。

RedBoardは、Arduino IDEを使ってUSB Mini-Bケーブル経由でプログラムできる。 Windows 8でもセキュリティ設定を変更する必要なく動作する(UNOとは異なり、署名済みのドライバーを使っているため)。 使用しているUSB/FTDIチップのおかげで安定性が高く、背面が完全に平らなためプロジェクトへの組み込みも簡単である。 基板を接続し、ボードメニューから「Arduino UNO」を選ぶだけでコードを書き込む準備が整う。 RedBoardはUSB経由でもバレルジャック経由でも電源を供給でき、基板上の電源レギュレータは7〜15VDCの範囲に対応している。

Arduino Mega (R3)

Arduino Megaは、いわばUNOの兄貴分である。 非常に多くの(なんと54本もの)デジタル入出力ピン(うち14本はPWM出力として使える)、16本のアナログ入力、USB接続、電源ジャック、リセットボタンを備えている。 マイクロコントローラを動かすために必要なものはすべて内蔵されており、USBケーブルでパソコンに接続するか、AC-DCアダプタや電池で電源を供給するだけで使い始められる。 ピンの数が多いため、大量のデジタル入出力を必要とするプロジェクト(多数のLEDやボタンを使うものなど)にとても便利である。

Arduino Leonardo

Leonardoは、USB機能を内蔵した単一のマイクロコントローラを採用した、Arduinoとして初めての開発ボードである。 これにより、より安価でシンプルな構成が可能になった。 また、基板自体がUSBを直接処理するため、コンピュータのキーボードやマウスなどをエミュレートできるコードライブラリも利用できる。

Arduinoを拡張する仲間たち

Arduino基板そのものは見た目こそかっこいいが、単体ではあまり多くのことができない。何かと組み合わせる必要がある。 このサイトには数多くのチュートリアルが用意されているが、Arduinoに簡単に組み合わせられる一般的な種類のものについてはあまり語られてこなかった。 このセクションでは、プロジェクトに命を吹き込むためのもっとも便利な道具として、基本的なセンサーとArduinoのシールドを紹介する。

センサー

簡単なコードを書くだけで、Arduinoは実に多種多様なセンサーを制御し、やり取りできるようになる。 光、温度、曲げ具合、圧力、近接、加速度、一酸化炭素、放射線、湿度、気圧など、あらゆるものを測定できるセンサーが存在する。

シールド

さらに、シールドと呼ばれるものもある。 これは基本的に、Arduinoの上に重ねて装着できる、あらかじめ作られた回路基板であり、モーターの制御、インターネットへの接続、セルラー通信やその他の無線通信、LCD画面の制御など、さまざまな追加機能を提供してくれる。

シールドについてさらに詳しく知りたい場合は、次のようなリソースを参照してほしい。

  • ShieldList.org
  • ShieldStravaganza!!!(SparkFunが扱うシールドを簡単に紹介する動画シリーズ)

まとめ

これでArduinoファミリーについて、プロジェクトにどの基板を使えばよいか、そしてプロジェクトをさらに一歩進めるためのセンサーやシールドが数多く存在することが分かったはずである。 Arduinoについてさらに詳しく知りたいなら、次のようなチュートリアルもおすすめである(いずれも英語)。

ハードウェア関連のチュートリアルとしては、次のようなものもおすすめである。

タグ: Arduino、シールド、プロジェクトを始める、技術


出典:What is an Arduino?(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

シリアルグラフィックLCDの使い方

はじめに

Serial Graphic LCD Backpack(シリアルグラフィックLCDバックパック)の使い方ガイドへようこそ。 このチュートリアルでは、このバックパックの機能をフルに活用する方法を学ぶ。 まずハードウェアの基本概要から始め、続いてマイコンへの接続方法へと進む。 最後まで読めば、バックパックのすべての機能と、任意のホスト機器での実装方法が分かるはずである。

参考になるチュートリアル

このガイドを最大限に活用するには、事前に次のトピックを理解しておくことをおすすめする。 なじみのない概念があれば、目を通しておいてほしい。

バックパックの概要

Serial Graphic LCD Backpackは、大型のグラフィック液晶ディスプレイ(LCD)に対して、シンプルなシリアルインターフェースを提供するために設計された。 文字の描画に加えて、直線や円、四角形を描いたり、個々のピクセルを設定したり解除したり、画面の特定のブロックを消去したり、バックライトを制御したりできる。 ピクセルの色と背景色を入れ替える反転モードも備えている。

SparkFunではこのバックパックを単体でも販売しているが、128x64ピクセルのグラフィックLCD160x128ピクセルのグラフィックLCDとセットになった製品も存在する。 このチュートリアルでは、両方のLCDを使ってバックパックの機能を紹介する。

バックパックは、5V/16MHzで動作するATmega168マイコンによって制御されている。 この製品は主に組み込み用途を想定しているが、パソコンに接続してターミナルエミュレータから書き込むことも簡単にできる。 このチュートリアルでは両方の方法を扱う。

電源についての要件

バックパックには最大7Vまで電圧をかけて電源供給できるが、その場合はバックパック上の電圧レギュレータへの負荷を減らすため、バックライトのデューティ比を下げるように注意する必要がある。 電圧レギュレータまわりの問題を避けるには、バックパックを6Vで駆動するのが最も無難である。 別の5V電源から給電しても問題ない。 ただし5V未満の電圧では、バックライトやディスプレイに不具合が生じることに注意してほしい。 パソコンのUSBポートやマイコンから電源を取る場合は、出力が確かに5Vであり、4.5Vのような低い値になっていないかを確認すること。

その他のハードウェアの特徴

コントラスト用ポテンショメーター(左)とはんだジャンパー(右)を強調した写真。

コントラスト用ポテンショメーター

バックパックには、コントラストを調整するための小さなポテンショメーターが搭載されている。 出荷時にすでに調整済みだが、文字がはっきり見えない場合や好みに合わない場合は、自由に調整してかまわない。 LCDの文字が読めなくなった場合は、必ず最初にこのコントラスト用ポテンショメーターを確認すること。 非常に感度が高く、わずかにぶつけただけでもLCDのコントラストが崩れ、読めなくなることがある。

はんだジャンパー

バックパックには、どちらのディスプレイを使うかを決めるはんだジャンパーがある。 このジャンパーが閉じている(はんだ付けされている)場合は128x64ディスプレイ用のコードが動作し、開いている場合は160x128ディスプレイ用のコードが動作する。 このジャンパーは、どちらのLCDが取り付けられているかに応じて、製造時にはんだ付けされる。 ただし、自分の持っているLCDでこのバックパックを使いたい場合は、このジャンパーを適切に扱う必要がある。

TXライン

バックパックのTXラインは、将来のコード改訂やデバッグ、ユーザー開発のために最終設計に残されているが、執筆時点では利用されていない。

LCDの概要

このチュートリアルの後半で使うファームウェアの仕組みをよりよく理解するために、これらのLCDがどう動作するかを簡単に説明しておこう。 まずは、LCD上のピクセルがどのようにマッピングされているかについてである。

グラフィックLCDは、次の図のようにデカルト座標でマッピングされている。

160x128ピクセルのLCDを使う場合は、次の図のようになる。

ASCII文字は、ユーザーが変更可能な2つの設定値であるx_offsetとy_offsetにもとづいて画面に表示される。 この2つの設定値は、6x8ビットの文字用スペースの左上隅のビット位置を定義する。 x_offsetとy_offsetを変更することで、画面上の任意の場所に文字を配置できる。

文字用スペースに描かれた大文字の「B」。

x_offsetとy_offsetを調整しない限り、文字は左から右へ、上から下へと表示されていく。 さらに、オフセットを変更すると文字全体の基準枠が変わる。 つまり、あるフォームの端まで書き込んで次の行に移る処理は、あらかじめ書き込み可能な位置と不可能な位置が決まっているわけではないため(画面の左端や下端に近い位置を除く)、シームレスに行われる。

バックスペースキーも機能し、ユーザーが設定した基準枠をできる限り維持しようとする。

バックパックには416バイトの入力バッファがあり、これは画面いっぱいに表示できる文字数に相当する。 一度に416文字を超えるデータを送信すると、バッファオーバーランが発生する可能性がある。 また、ファームウェアがバッファ全体を処理するのにかかる時間は、送信する文字と特殊コマンドの組み合わせによって変わる。 最適な動作を見つけるには、多少の試行錯誤が必要になるかもしれない。

ASCIIコマンド

Graphic Serial LCD Backpackは、さまざまな方法で制御できるように設計されている。 その1つがシリアルターミナルを使う方法である。 パソコンを制御機器として使いたい場合に便利である。 また、ASCIIコマンドを使ってリアルタイムにバックパックへコマンドを送ることもできる。 これは、プロジェクトに組み込む前にLCDをテストしたい場合に役立つ。 以下に、ASCIIコマンドの一覧をすべて示す。

注記: キーボードから特殊なキー操作が必要になるASCII値を送る場面がいくつかある。 < control 何らかの値 >という表記が出てきたら、それはControlキーとその文字を同時に押す必要があるという意味である。 Macを使っている場合、これらのコマンドの一部はやや異なる方法で入力する必要がある。 Controlキーを使ってもうまくいかないコマンドがあれば、そのキャラクタのUnicode版を試してみてほしい。

すべてのコマンドの先頭には「|」(ASCIIの10進数で124、16進数で0x7C)を付ける必要がある。 これは、続けてコマンド列が送られてくることをディスプレイに知らせるものである。 以下のコマンドの前には、必ず「|」を付けなければならない。 実際の「|」という文字そのものが画面に表示されることはない(また、表示することもできない)。

画面のクリア

「@(0x00)」を送信すると、書き込まれていたすべてのピクセルを画面から消去する。 通常モードで動作している場合はすべてのピクセルがリセットされ、反転モードで動作している場合はすべてのピクセルがセットされる。 「画面のクリア」コマンドの例としては、0x7C 0x00を送信するか、キーボードから「|」と@を送信する。

デモモード

「\d(0x04)」を送信すると、デモ用のコードが実行される。 これはディスプレイの機能を示す一例として、ファームウェアに組み込まれている。 デモを見るには、0x7C 0x04を送信するか、キーボードから「|」と\dを送信する。

反転モード

「\r(0x12)」を送信すると、160x128ピクセルディスプレイでは白地に青と青地に白、128x64ピクセルディスプレイでは黒地に緑と緑地に黒の間で表示が切り替わる。 反転モードを設定すると、新しい背景色で画面が即座にクリアされる。 反転モードを設定するには、0x7C 0x12を送信するか、キーボードから「|」と\rを送信する。 この設定は電源の入れ直しをまたいで保存される。 反転モードのままディスプレイの電源を切った場合、次に電源を入れたときも反転モードのままで起動する。

スプラッシュ画面

「\s(0x13)」を送信すると、電源投入時にSparkFunのロゴを表示するかどうかを切り替えられる。 このスプラッシュ画面には2つの役割がある。 1つは製品に自分たちの刻印を残すことであり、もう1つは、電源投入時に短い時間を確保し、ボーレートの誤った変更からディスプレイを復旧できるようにすることである(詳しくはボーレートの変更の項を参照)。 スプラッシュ画面を無効にするとロゴの表示は抑制されるが、遅延自体は残る。 スプラッシュ画面を無効にするには、0x7C、0x13を送信するか、キーボードから「|」と\sを送信する。

バックライトのデューティ比の設定

「\b(0x02)」に続けて0から100までの数値を送信すると、バックライトの明るさ(したがって消費電流)が変わる。 値を0に設定するとバックライトはオフになり、100以上に設定すると完全に点灯し、その中間の値では明るさもその中間になる。 コマンド列の中の数値は8ビットのASCII値である。 たとえばデューティ比を50に設定するには、0x7C 0x02 0x32を送信するか、キーボードから「|」、\b、「2」を送信する。

ボーレートの変更

「\g(0x07)」に続けて「1」から「6」までのASCII文字を送信すると、ボーレートが変更される。 デフォルトのボーレートは115,200bpsだが、バックパックはさまざまな通信速度に設定できる。

文字ボーレート
“1”4800
“2”9600
“3”19200
“4”38400
“5”57600
“6”115200

たとえばボーレートを19,200bpsに設定するには、0x7C 0x07 0x33を送信するか、キーボードから「|」、\g、「3」を送信する。 ボーレートの設定は電源の入れ直しをまたいで保持されるため、19,200bpsの状態で電源を切った場合、次に電源を入れたときもその設定のままになる。

万一の場合は、ボーレートを115,200に戻すこともできる。 電源投入時の1秒間の遅延の間に、115,200bpsで任意の文字をディスプレイに送信すればよい。

X座標とY座標の設定

「\x(0x18)」または「\y(0x19)」に続けて新しい基準座標を表す数値を送信すると、X座標またはY座標が変更される。 X座標とY座標の基準値(ソースコード上ではx_offsetとy_offset)は、テキストジェネレータが画面上の特定の位置に文字を配置するために使われる。 先に述べたとおり、この座標は文字用スペースの左上のピクセルを指す。 オフセットが画面の右端から6ピクセル以内、あるいは下端から8ピクセル以内にある場合、テキストジェネレータは文字を部分的にではなく丸ごと表示できるよう、次の行に自動的に移る。 たとえばx_offsetを80(160x128ピクセルディスプレイの水平方向の中央)に設定するには、0x7C 0x18 0x50を送信するか、キーボードから「|」、\x、「P」を送信する。 各軸の長さを超える値を設定しようとした場合は、それぞれのオフセットの最大値に丸められる。

ピクセルの設定と解除

「\p(0x10)」に続けてxとyの座標、およびそのピクセルを設定するか解除するかを表す0か1を送信する。 画面上の任意のピクセルを、このコマンドで個別に設定したり解除したりできる。 たとえば座標(80, 64)のピクセルを設定するには、0x7C 0x10 0x50 0x40 0x01を送信するか、キーボードから「|」、\p、「P」、「@」、\aを送信する。 ピクセルを「設定する」とは、必ずしもそこに1を書き込むという意味ではなく、背景色の反対の色を書き込むという意味であることに注意してほしい。 つまり反転モードで動作している場合、ピクセルを設定すると実際にはそのピクセルはクリアされ、白い背景の中で目立つようになる。 そのピクセルを解除すると、背景と同じ白色に戻る。

直線の描画

「\l(0x0C)」に続けて、線の始点と終点を表す2組の(x, y)座標を送信し、さらに直線を描くか消すかを表す0か1を送信する。 たとえば(0,10)から(50,60)まで直線を描くには、0x7C 0x0C 0x00(x1)0x0A(y1)0x32(x2)0x3C(y2)0x01を送信するか、キーボードから「|」、\l、@、\j、「2」、「<」、\aを送信する。 その直線を消す(周囲の文字や図形はそのまま残す)には、同じコマンドの最後の\aを@に変えて送信する。

円の描画

「\c(0x03)」に続けて、円の中心を表すxとyの座標、円の半径を表す数値、さらに円を描くか消すかを表す0か1を送信する。 たとえば中心(80, 64)、半径10の円を描くには、0x7C 0x03 0x50 0x40 0x0A 0x01を送信するか、キーボードから「|」、\c、「P」、「@」、\j、\aを送信する。 その円を消す(周囲の文字や図形はそのまま残す)には、同じコマンドの最後の\aを@に変えて送信する。 円は画面の外側にはみ出して描くこともできるが、実際に表示されるのはディスプレイの範囲内に収まるピクセルだけである。

四角形の描画

「\o(0x0F)」に続けて、四角形の対角の2つの角を表す2組の(x, y)座標を送信し、さらに四角形を描くか消すかを表す0か1を送信する。 このコマンドは直線を描くコマンドと全く同じ形式だが、線の代わりに、指定した座標間の直線をちょうど囲む四角形が描かれる。 たとえば(0,10)から(50,60)までの直線を囲む四角形を描くには、0x7C 0x0F 0x00(x1)0x0A(y1)0x32(x2)0x3C(y2)0x01を送信するか、キーボードから「|」、\o、@、\j、「2」、「<」、\aを送信する。 その四角形を消す(周囲の文字や図形はそのまま残す)には、同じコマンドの最後の\aを@に変えて送信する。

ブロックの消去

「\e(0x05)」に続けて、消去したいブロックの対角の2つの角を表す2組の(x, y)座標を送信する。 これは四角形を描くコマンドとほぼ同じだが、四角形の中身が背景色に消去される点が異なる。 たとえば(0,10)から(50,60)までの直線を囲む矩形ブロックを消去するには、「0x7C 0x05 0x00(x1)0x0A(y1)0x32(x2)0x3C(y2)」を送信するか、キーボードから「|」、\e、@、\j、「2」、「<」を送信する。

例1:FTDI Basicを使う

LCDを制御するコマンドが分かったところで、実際に試してみよう。 この例では、FTDI Basicを使ってLCDと通信し、制御を行う。

必要なもの

ハードウェア

LCDに接続して表示を行う、もっとも簡単で手早い方法は、FTDI BasicやFTDI Cableを使うことである。 ジャンパー線を使って、次のようにFTDIとLCDを接続する。

FTDIグラフィックLCD
5VVin
GNDGND
TXORX

LCDを正しく配線できたら、FTDI機器をパソコンに接続する。 ターミナルウィンドウを開こう。 設定が正しいことを確認すること(ボーレート:115200、8-N-1-NONE)。 接続できたら、文字を入力してみよう。 入力した内容がすべてLCDに表示されるはずである。 画面のクリア、円の描画、特定のx, y座標への文字の表示といった特定のコマンドを実行するために押すべきキーについては、ASCIIコマンドの項を振り返って確認してほしい。

パソコンからLCDに話しかけるのも楽しいが、組み込み機器からLCDに情報を表示できるようになると、本当の面白さが始まる。 次の例では、Arduinoを使ってLCDに情報を表示する。

ファームウェアの概要

ArduinoにLCDを接続する前に、少しファームウェアについて説明しておこう。 ファームウェアとは、バックパック上で動作するコードのことである。 LCDと、それと通信するマイコンとの間の橋渡し役、いわば翻訳者としての役割を果たす。 このファームウェアの上に、バックパックをさらに使いやすくするためのArduinoライブラリを用意した。

バックパックのファームウェア

バックパックに付属するファームウェアは刷新されており、以前よりも滑らかに動作し、どんなプロジェクトにも素晴らしいグラフィック表示をもたらしてくれる。 特に凝ったことをしたいのでなければ、デフォルトのファームウェアだけでLCDに必要な機能はほぼ満たせるはずである。 とはいえ、内部の仕組みを理解しておく価値はある。 ファームウェアを見るには、Serial Graphic LCD BackpackのGitHubリポジトリを訪れてほしい。 zipファイルをダウンロードするか、リポジトリをパソコンにクローンするか、あるいはGitHub標準のエディタで内容を確認することもできる。

Firmwareフォルダの中には、多数の.cファイルと.hファイルがある。 これらは、受け取った入力に応じてバックパックがLCDとどうやり取りするかを定めているファイルである。 ソースコードの改変はこのチュートリアルの範囲を超えるため、ここでは詳しく扱わない。 内部の機能を追加、削除、変更したい場合は、ここが該当する場所だということだけ覚えておいてほしい。

なお、バックパックのファームウェアを書き換えるにはプログラマが必要になる。 バックパックに搭載されているICは、多くのArduinoボードに使われているものと同じATmega328であるにもかかわらず、Arduino互換ではない。 ファームウェアの再書き込み方法についての詳細は、トラブルシューティングの項を参照してほしい。

Arduinoライブラリ

Serial Graphic LCD Backpackをできるだけ簡単に使えるように、Arduinoライブラリを用意した。 このライブラリはGitHubリポジトリから入手できる。 このライブラリは、前述のASCIIコマンドの一覧にある各コマンドに対応する関数を提供している。 ライブラリに付属するサンプルスケッチでは、各関数の使い方が示されており、LCD上でさまざまな用途にどう実装するかが分かる。 Arduinoライブラリのインストール方法について復習が必要な場合は、Installing an Arduino Libraryのチュートリアルを参照してほしい。

以下では、それぞれの関数を簡単な説明とともに紹介する。 ただし、これらの関数はいずれもASCIIコマンドの項で紹介したコマンドの上に成り立っている。 それぞれの詳細については、その項を参照するか、ライブラリファイル内のコメントを読んでほしい。

表示用コマンド

  • printStr(char Str[78]) - 文字列をLCDに表示する。バッファのデフォルトサイズは78だが、ヘッダファイルで変更できる。
  • printNum(int num) - 1つの数値をLCDに表示する。
  • nextLine() - 文字表示における改行として機能する。

これら3つの関数が用意されているのは、バックパックとの通信にSoftware Serialライブラリのインスタンスがライブラリファイル内で宣言されているためである。 そのため、このライブラリを使っている間は、通常のserial.print()コマンドではLCDに文字を送信できない。

LCDの機能

  • clearScreen() - LCD上のすべてのピクセルを消去する。
  • toggleReverseMode() - 反転モードを切り替える。160x128ディスプレイでは白地に青、128x64ディスプレイでは黒地に緑になる。
  • toggleSplash() - SparkFunのスプラッシュ画面のオンとオフを切り替える。スプラッシュ画面が有効か無効かにかかわらず、起動時の1秒間の遅延は残ることに注意。
  • setBacklight(byte duty) - バックライトの明るさを設定する。引数として1つのint値を取る。範囲は0〜100で、0はオフ、100は最大輝度である。100を超える値を指定しても、最大値の100として扱われる。
  • setBaud(byte baud) - バックパックのボーレートを設定する。引数として1つのint値(範囲は49〜54)を取る。
  • restoreDefaultBaud() - LCDのボーレートをデフォルトの115200bpsに戻す。

カーソル位置の指定

  • setX() - 画面上で文字が表示されるx位置を設定する。
  • setY() - 画面上で文字が表示されるy位置を設定する。
  • setHome() - xとyの両方を位置(0, 0)に戻す。

描画

  • setPixel(byte x, byte y, byte set) - LCD上の任意のピクセルを設定したり解除(背景色に戻す)したりする。
  • drawLine(byte x1, byte y1, byte x2, byte y2, byte set) - 2つのx, y座標の間に直線を描く。
  • drawBox(byte x1, byte y1, byte x2, byte y2, byte set) - 2つのx, y座標の間に四角形を描く。
  • drawCircle(byte x, byte y, byte rad, byte set) - 指定したx, y座標を中心とし、指定した半径まで広がる円を描く。
  • eraseBlock(byte x1, byte y1, byte x2, byte y2) - 指定した2つのx, y座標にまたがるブロックを消去する。
  • demo() - ファームウェアに組み込まれた内部デモを起動する。

例2:Arduinoを使う

まずは、Arduinoから手早くLCDに文字を表示するシンプルな方法を紹介し、続いてLCDのファームウェアに組み込まれた特殊文字を活用する、より本格的な方法を紹介する。

必要なもの

シリアルのパススルー

最初の例では、Arduinoに内蔵されているUARTを利用する。 そのため、LCDを接続したままArduinoにコードを書き込む際には注意が必要である。両者が同じラインを共有することになるからである。 ここでは少し順番を変えて、先にコードを書き込んでから、LCDを接続することにする。

わずか数行のコードで、Arduinoを経由してターミナルウィンドウに文字を送ることができる。 次のコードを新しいスケッチにコピーし、Arduinoに書き込む。

void setup() {
  Serial.begin(115200);
}
void loop() {
  if(Serial.available() > 0){
    Serial.write(Serial.read());
  }
}

このコードは、ArduinoがRXラインで受信した内容を、そのままTXラインからSerial Graphic LCDへ送信する。 ASCIIの数値ではなく実際の文字をLCDに表示したい場合は、Serial.printではなくSerial.write()を使う必要がある。

ハードウェア

次に、以下のようにLCDをArduinoに接続する。

配線が次のようになっていることを確認する。

ArduinoグラフィックLCD
5VVin
GNDGND
TXRX

LCDのTXラインには接続する必要がない。LCDに対してデータを送るだけだからである。

ここで、ターミナルウィンドウを(同じく115200で)開き、文字を入力してみよう。 今度もLCDに文字が表示されるはずである。バックスペースも問題なく機能する。

Arduinoライブラリを使った例

最後の例では、Serial Graphic LCDライブラリを使ってすべての処理を任せてしまう。 このライブラリの重要な特徴の1つは、Software Serialライブラリを使って、ArduinoがLCDと通信するための別のシリアルポートを作り出している点である。 先ほどの例の問題点は、内蔵のUARTを使っているため、コードを書き込むたびにLCDを取り外す必要があったことである。 開発中に何度も書き込みを行う場合、これはかなり面倒である。

ハードウェア

このセットアップは、先ほどの例のものをそのまま使い、ジャンパー線を1本だけ変更すればよい。 ArduinoのTXピンに接続していたジャンパー線を、Arduinoのデジタルピン3に移動する。 これは、Serial Graphic LCDライブラリがSoftware Serialライブラリを初期化する際に使用するピンである。

配線は次のようになるはずである。

ArduinoグラフィックLCD
5VVin
GNDGND
Pin 3RX

図で確認したい場合は、以下の配線例を参考にしてほしい。

ファームウェア

まだの場合は、Arduinoライブラリをダウンロードしてインストールするか、パソコンにクローンしてほしい。 ライブラリのインストール方法については、前述のファームウェアの詳細の項を参照すること。 インストールが済んだら、Arduino IDEを開き、ライブラリのサンプルスケッチへ移動する。

適切なシリアルポートとボードを選択し、サンプルスケッチをArduinoに書き込む。 書き込みが完了すると、ライブラリのデモが開始される。 ライブラリに含まれるほぼすべての関数の使用例が、一通り実行される。 あとは座って眺めているだけでよい。

トラブルシューティング

表示に関する問題

  • 文字が全く見えない場合は、バックパック上のコントラスト用ポテンショメーターが適切に調整されているか確認すること。調整には精密ドライバーが必要である。このトリムポットを調整する際は注意すること。回しすぎたり、強く力を加えすぎたりすると、トリムポットが壊れることがある。
  • バックパックに少なくとも5Vを供給していることを確認すること。それより低いとコントラストに問題が生じることがある。USBポートの中には4.7〜4.8V程度しか出力しないものもあり、LCDとバックパックを完全に駆動するには電圧が足りないことがある。LCDには6〜7Vで電源供給することをおすすめする。
  • コントラストを適切に調整しても文字が全く見えない場合は、ボーレートに問題がある可能性がある。ボーレートを変更して、何に変更したか忘れてしまった場合は、ArduinoライブラリのrestoreDefaultBaud()コマンドを使って、デフォルトの115200bpsに戻すことができる。Graphic Serial LCDライブラリをインポートするスケッチを作成し、setup内でこの復元用の関数を呼び出せばよい。

次のコードをArduinoにコピー&ペーストし、LCDのRXピンがArduinoのデジタルピン3に接続されていることを確認したうえで書き込む。 画面に「Baud restored to 115200!」と表示されるはずである。

#include <SparkFunSerialGraphicLCD.h> // Serial Graphic LCDライブラリをインクルードする
#include <SoftwareSerial.h>
LCD LCD;
void setup()
{
delay(1200); // 1秒間のスプラッシュ画面を待つ
LCD.restoreDefaultBaud();
}
void loop()
{
// loop内では何もしない
}

ファームウェアの再書き込み

バックパックの動作がおかしいと感じたら、ファームウェアが原因である可能性がある。 その場合は、最新のファームウェアに更新することをおすすめする。 適切な道具があれば自分自身で行える方法を、ここで簡単に説明する。

最新版のファームウェアはGitHubにある。 リンク先のリポジトリを訪れ、クローンするかzipファイルをダウンロードし、その保存場所を覚えておく。

ファームウェアをバックパックに書き込む何らかの手段が必要になる。 Atmel AVR MKIIプログラマの使用をおすすめするが、MKIIを持っていない場合は、Pocket AVR Programmerのような類似の製品を使うこともできる。 プログラマをパソコンに接続する。 Arduinoボードをプログラマとして使うこともできる。 これについての詳細や、ファームウェアの再書き込み全般については、Installing an Arduino Bootloaderのチュートリアルを参照してほしい。

この例では、Atmel AVR Studio(v4.18)を使って.hexファイルをバックパックに書き込む。 コマンドラインからAVRDudeを使って同じことを行うこともできる。 MacやLinuxを使っている場合は、それぞれのOS上でAVRコードを書き込む方法を調べるか、WineやVMWareのような仮想マシンを使ってWindows上でAVR Studioを動かす必要がある。

AVR Studioを起動する準備ができたら、プログラムを起動しよう。 使用しているプログラマを選択するよう求めるプロンプトが表示されるはずである。 AVR MKII、あるいは自分が使っているプログラマを選択する。

次に、書き込み先のチップを選択する。ATmega168Pを選択する。

Programタブをクリックする。「Flash」の項目で、3つの点が描かれたボタンをクリックし、GitHubからダウンロードしたhexファイルを参照する。

GitHubからダウンロードした際に付属する.hexファイルを参照する。

AVR Studioにhexファイルの場所を指定したら、プログラマをバックパックのISPヘッダーに接続し、「Program」をクリックする。

プログラムの下部に成功のメッセージが表示されるはずである。 表示されれば、新しいファームウェアがバックパックに書き込まれ、使用できる状態になっている。

まとめ

これでひととおり完了である。 Serial Graphic LCDの仕組みと、さまざまな方法でLCDを制御する方法について理解できたはずである。 あとは実際に、洗練されたユーザーインターフェースを持つ素晴らしいプロジェクトを作ってみてほしい。 S-G-LCDバックパックについてのさらなる情報は、以下のリンクを確認してほしい。

タグ: ディスプレイ、接続ガイド


出典:Serial Graphic LCD Hookup(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

双方向ロジックレベルコンバータの使い方

3.3VのI2CセンサーやSPIセンサーを5VのArduinoに接続して、煙を出してしまいそうで心配になったことはないだろうか。 あるいは、5Vのデバイスを3.3VのRaspberry Pi 4やRaspberry Pi Zero、RedBoard Turbo、Arduino Dueと組み合わせるために、何らかの回避策が必要になったことは。

この壁を乗り越えるには、3.3Vを5Vに、あるいは5Vを3.3Vに変換できる装置が必要になる。 これはロジックレベルシフトと呼ばれる。 レベルシフトはあまりにもよくある悩みであるため、SparkFunでは機器どうしのインターフェースを少し簡単にするシンプルなPCB基板、双方向ロジックレベルコンバータを設計した。

形と大きさは同じだが、この双方向ロジックレベルコンバータは、より単純な“単方向“バージョンとは区別する必要がある。 このコンバータは、すべてのチャンネルにおいて、高い電圧から低い電圧へ、あるいはその逆の両方向にデータを通すことができる。 I2Cやワンワイヤーインターフェースのように、データ線を共有する機器どうしのレベルシフトに最適である。

このチュートリアルで扱う内容:

このチュートリアルでは、双方向ロジックレベルコンバータについて詳しく見ていく。 回路図と基板のレイアウトを確認し、それぞれのピンの役割を説明する。 最後に、さまざまなインターフェースに合わせてこの基板をどう接続するか、いくつかの接続例を紹介する。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

基板の概要

この基板の回路図を見てみると、双方向ロジックレベルコンバータ(以下BD-LLCと略す)は実はとても単純な装置であることが分かる。 基板上には基本的に1つのレベルシフト回路があり、それが4回繰り返されて4つのレベルシフトチャンネルを作り出している。 この回路は、1個のNチャンネルMOSFETと2、3個のプルアップ抵抗を使って、双方向のレベルシフトを実現している。

半導体のちょっとした魔法によって、この回路は低電圧信号を高電圧に、あるいは高電圧信号を低電圧に変換できる。 片側で0Vの信号は、もう片側でも0Vのままである。 この回路の完全な解析については、優れたPhilips Application Note AN97055を参照してほしい。

ピン配置

BD-LLCには合計12本のピンがあり、6本ずつ2列に並んだヘッダーになっている。 一方の列には高電圧側(たとえば5V)の入出力がすべて、もう一方の列には低電圧側(たとえば3.3V)のものがすべて配置されている。

ピンは基板の表と裏の両方にラベル付けされており、いくつかのグループに分かれている。 いくつかのピングループを詳しく見ていこう。

電圧入力

HVLV、そして2つのGNDというラベルの付いたピンは、基板に高電圧と低電圧の基準電圧を供給する。 この両方の入力に安定したレギュレート済みの電圧を供給することが必須である。

HVGNDの入力に供給する電圧は、LV側に供給する電圧よりも高くなければならない。 たとえば5Vから3.3Vへ変換する場合、HVピンの電圧は5V、LVの電圧は3.3Vにする。

データチャンネル

BD-LLCには4つの独立したデータチャンネルがあり、それぞれ高電圧と低電圧の間でデータを双方向にシフトできる。 これらのピンはHV1LV1HV2LV2HV3LV3HV4LV4とラベル付けされている。 それぞれのラベルの末尾の数字はピンのチャンネルを示し、HVまたはLVという接頭辞は、そのチャンネルの高電圧側か低電圧側かを示している。

たとえばLV1に入力された低電圧信号は、より高い電圧にシフトされてHV1から出力される。 HV3に入力されたものは、低電圧にシフトされてLV3から出力される。 プロジェクトに必要な数だけこれらのチャンネルを使えばよく、すべてのチャンネルを使う必要はない。

これらのレベルシフターは純粋にデジタルである点に注意してほしい。 あるアナログの最大電圧を別の最大電圧に対応付けるような使い方はできない。

接続例

組み立て

コンバータをシステムに接続する前に、何かをはんだ付けする必要がある。 ここにはさまざまな選択肢がある。 まっすぐなオスヘッダーをはんだ付けしてブレッドボードにそのまま挿すこともできるし、配線を直接はんだ付けすることもできる。 自分の使い方に合った組み立て方法を選ぼう。

BD-LLCのはんだ付けが終わったら、いよいよ接続する番である。 接続方法は、使う通信インターフェースによって変わってくる。 以下では、もっともよく使われる3つの通信プロトコルについて、レベルコンバータの接続方法を紹介する。

BD-LLCをシリアル通信に使う

BD-LLCの双方向という機能を活かしきることにはならないが、シリアル通信のレベルシフトにこの基板を使ってもまったく問題ない。 シリアル通信にはたいていRX(受信)とTX(送信)という2本の信号線が必要であり、どちらも決まった方向を持つ。 これらの信号は、BD-LLCの4つのチャンネルのどれを使って通してもよい。

たとえば、最大入力電圧が3.6VのElectric Imp Breakout Boardを、UART経由でArduino Unoに接続したいとしよう。 接続方法の一例は次のとおりである。

この例では、ArduinoとElectric Impの両方がそれぞれ独自の電源を持っていることに注意してほしい。

LVが3.3Vで、HVが5Vで電源供給されていることを確認しよう。 チャンネルの対応が合っているか再確認すれば、あとはレベルシフトが行われるだけである。 残りの2チャンネルは好きなように使うことができる。

BD-LLCをSPI通信に使う

BD-LLCの4つのチャンネルは、たいていのSPI通信にちょうどよく対応する。 SPIにはたいてい4本の配線、MOSI(コントローラ出力/ペリフェラル入力)、MISO(コントローラ入力/ペリフェラル出力)、SCLK(シリアルクロック)、CS(チップセレクト)が必要である。 これら4本の配線は、それぞれBD-LLCのチャンネルに通すことができる。

たとえば、動作範囲が2.0V〜3.6VのADXL345 Breakout Boardに、Arduinoを接続したい場合、BD-LLCを次のように組み込むことができる。

BD-LLCの各チャンネルはすべて双方向であるため、SPIの4本の線のどれを、BD-LLCの4つのチャンネルのどれに通してもかまわない。

BD-LLCをI2C通信に使う

I2Cは、BD-LLCが真価を発揮する通信規格である。 なぜなら、データ線とクロック線の両方、つまりSDAとSCLの両方が双方向でなければならないからである。 これらの線はそれぞれ、BD-LLCのレベルシフトチャンネルのどれかに通すことができる。

この例でも引き続きADXL345 breakoutを使うが、今度はI2Cインターフェースに切り替えてみよう。 さらに別のI2Cデバイス、たとえばL3G4200D Gyroscope Breakoutを追加することもできる。 I2Cは2本の配線だけのインターフェースなので、BD-LLCにはそれぞれの基板の割り込み出力のような、追加の信号を通す余裕がある。

2つの3.3VのI2Cデバイスは、どちらも同じレベルシフトされたSDAとSCLの線を共有できる。 それぞれが固有のアドレスを持っている限り、さらに多くのI2Cデバイスを追加することもできる。

まとめ

LLCとレベルシフト全般に関連するリソースをいくつか紹介する。

LLCの使いどころを探しているなら、次のようなチュートリアルもヒントになるかもしれない(いずれも英語)。

タグ: 通信、部品、接続ガイド


出典:Bi-Directional Logic Level Converter Hookup Guide(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

バイナリブラスターの組み立てガイド

Binary Blaster(バイナリブラスター)は、2進数での数え方や、10進数(や16進数)と2進数の間をすばやく変換する方法を学べるゲームである。 7セグメントディスプレイに値が表示され、プレイヤーはそれに対応する2進数を表すようにボタンを押すことに挑戦する。 ボタンを押せばそのビットが「立ち」、押さなければそのビットは「0のまま」になる。 ボタンは4つあり、それぞれが1ビットを表す。 つまり15通りの組み合わせがある。 15問すべてに正解すればクリアである。 経過時間のスコアも表示されるので、自分の最速記録を追いかけながら、より速くなるよう練習できる。

この製品はスルーホールはんだ付けキットとして販売されており、自分で組み立てる必要がある。

はんだ付けが初めてであれば、Binary Blaster PTHキットは始めるのにうってつけの製品である。 このガイドでは、キットに含まれる部品を1つずつ説明し、それぞれをどうはんだ付けするかを紹介する。

必要な道具

  • はんだごて
  • はんだ
  • ニッパー

あるとよい追加の道具

  • 保護メガネ
  • フラックスペン
  • はんだ吸取り線
  • 洗浄用のブラシ(古い歯ブラシで十分)
  • 洗浄用の脱イオン水(水道水でも代用可能)

参考になるチュートリアル:

スルーホールはんだ付けについてさらに一般的な知識を得たい場合は、次のようなチュートリアルもおすすめである。

クイックスタート:最初の部品

10kΩの抵抗器を見つけよう。 茶、黒、橙、金という特定の縞模様が入っている。

なお、この模様は逆順になっていることもあるが、それでも正しい抵抗器である。

抵抗器のカラーコードについてさらに理解を深めたい場合は、抵抗器のカラーバンドの読み方を参照してほしい。

脚を下向きに曲げる。

基板上の10kΩ抵抗器の位置を確認する。

抵抗器をPCBに挿入する。 この部品には極性がないため、どちらの脚をどちらの穴に入れても構わない。 このキットの一部の部品には極性があり、その際には正しい向きで挿入するよう特に注意を払う。

抵抗器を、ほぼ基板に密着するまで押し込む。

脚を少しだけ外側に曲げて、抵抗器を固定する。

基板を裏返す。 はんだごての「スイートスポット」を、脚と金属のリングの両方に触れるように当てる。 2秒間そのまま保持する。

接合部にはんだを流し込む。

まず、はんだを離す。

次に、こてを離す。

はんだ接合部は、次のような見た目になっているはずである。

余分な脚を切り落とす。

コンデンサ

0.1µFのコンデンサを2つ見つけよう。 これらは抵抗器とは少し見た目が異なる。 部品の底面から2本のリード線が伸びており、「104」という表記がある。 底面には「K5M」のような別の文字が書かれていることもある。

PCB上のそれぞれの位置を確認する。

コンデンサがPCBの表面に密着し、まっすぐ立っていることを確認する。 はんだ付けし、余分なリード線を切り落とす。

マイクロコントローラ

マイクロコントローラを見つけよう。 このマイクロコントローラはATmega328である。 この部品には極性があるため、基板に正しく取り付けるよう特に注意する必要がある。 切り欠きに注目してほしい。

次に、PCB上の対応する位置を確認する。 ここでも、PCBの白い印刷の中に同じような切り欠きの記号があることに注目してほしい。

切り欠きの向きを正しく合わせながら、ATmega328をPCBに配置する。 最初の1本の脚をはんだ付けする際(どの脚からでもよい)、部品がPCBに密着した状態を保つようにする。

この部品のはんだ付けが終わると、基板の裏面は、きれいに並んだ火山のような形のはんだ接合になっているはずである。

ブザーとスイッチ

ブザースライドスイッチを見つけよう。

PCB上のそれぞれの位置を確認する。

部品をPCBに配置する。 裏返してはんだ付けする。 終わったら、PCBは次のような見た目になっているはずである。

Note

ブザーには極性を示すマークが付いているが、基板にはんだ付けする向きはどちらでも問題ない。ブザーは向きにかかわらず正常に動作する。このガイドに沿って作業したい場合は、画像で示されているように「BIT 0」のシルクスクリーンに近い側に「+」が来るようにブザーを挿入するとよい。もし向きを間違えてはんだ付けしてしまった場合は、はんだごとで両方のスルーホールを加熱し、部品を慎重に取り外すことでやり直せる。はんだ吸取り器やスラップ法を使って、PTHパッドに残ったはんだを取り除こう。ピンから余分なはんだを取り除いたら、ガイドどおりの向きでブザーをスルーホールに戻し、ピンを再びはんだ付けする。PTH部品をやり直す際は、パッドが剥がれてしまう危険があるため、はんだ接合部を十分に加熱するよう気をつけよう。

光るボタン

4個のLED付きタクトボタンを見つけよう。

これらのボタンには極性がある。 白いプラスチックの脚の上面にある小さな「+」の印に注目してほしい。

PCB上の4か所の位置を確認する。

PCB上の極性マークに注目する。 ボタンの「+」側が、PCBの「+」マークと揃っていることを確認する。

はんだ付けする。 終わったら、基板は次のような見た目になっているはずである。

7セグメントディスプレイ

2個の7セグメントディスプレイを見つけよう。

これらのディスプレイには極性がある。 数字の下にある小数点の位置に注目してほしい。

PCB上の2か所の位置を確認する。

PCB上の極性マークに注目する。 ディスプレイの小数点が、PCBの小数点マークと揃っていることを確認する。 はんだ付けする。 終わったら、基板は次のような見た目になっているはずである。

電池クリップ

4個の電池クリップを見つけよう。

PCB上の4か所の位置を確認する。

これらの部品には極性があり、裏面が外側を向くようにはんだ付けする必要がある。 向きを間違えると、電池が収まらなくなる。 基板に密着し、裏面が外側を向いていることを確認する。

はんだ付けする。 終わったら、基板は次のような見た目になっているはずである。

スタンドオフ

4個のプラスチック製スタンドオフと4本の金属ネジを見つけよう。

なお、これらをPCBに取り付けるのにドライバーは必要ない。 手で締めるだけで十分である。

スタンドオフを取り付けると、Binary Blasterはテーブルの上に平らに置けるようになる。

電池

2本の単3形電池を見つけよう。

これらには極性があるため、「+」と「-」の向きを正しく合わせること。

電池をクリップに入れ、電源を入れて正しく取り付けられているか確認する。 電池が正しく入っていれば、LEDタクトボタンが点灯し、Binary Blasterに電源が入ったことを確認できるはずである。

ゲームの遊び方

まず、Binary Blasterの電源を入れる。 電源用のスライドスイッチはPCBの左上にある。 「ON」の位置(左側)にスライドさせる。

サウンドスイッチも確認しておくとよいだろう。 音を鳴らしたいかどうかに応じて、左右どちらかにスライドさせる。

何も反応がない場合、電池の向きが間違っている可能性がある。 極性をもう一度確認してほしい。

電源を初めて入れると、ボタンが右から左へ素早く点灯し、その後ディスプレイが円を描くように点滅を始める。 この点滅は、LEDとディスプレイが正しく動作しているかを確認するための「起動処理」の一部である。

ディスプレイが円を描くパターンで点滅している間、Binary Blasterは新しいゲームを開始する準備ができている。

新しいゲームを始めるには、いずれかのボタンを押すだけでよい。

ディスプレイに最初の値が表示される。 これは毎回異なる値になりうる。

その値に対応する2進数を、4つのボタンで入力する必要がある。 参考になる対応表を示す。

10進数2進数
10001
20010
30011
40100
50101
60110
70111
81000
91001
101010
111011
121100
131101
141110
151111

ボタンの使い方を示すいくつかの例を紹介する。

例1

ディスプレイに「1」と表示された場合、対応する2進数「0001」を入力する必要がある。 つまり、「BIT 0」ボタン(一番右のボタン)を押すということである。 残りの3つのボタンには触れてはいけない(押さないこと)。 こうすることで、「BIT 0」だけを立てる(0のままにせず1にする)ことになる。

例2

ディスプレイに「2」と表示された場合、対応する2進数「0010」を入力する必要がある。 つまり、「BIT 1」ボタン(右から2番目のボタン)を押すということである。 こうすることで、そのビットを立てる(0のままにせず1にする)ことになる。

例3

ディスプレイに「5」と表示された場合、対応する2進数「0101」を入力する必要がある。 つまり、「BIT 0」と「BIT 2」のボタンを同時に押すということである。

数秒以内に正しい値を入力できなければ、Binary Blasterはタイムアウトし、そのラウンドは失敗となる。 もう一度挑戦するには、いずれかのボタンを押すだけでよい。

正しい2進数を入力すると、次のランダムな値に進む。 全部で15問ある。 タイムアウトすることなく15問すべてを変換できればクリアである。

新しいゲームを始めるたびに、出題順序は変わる。 これは、パターンを筋肉記憶で覚えるのではなく、変換そのものを学べるようにするための工夫である。 また、15問すべてを終えると、ディスプレイに「スコア」が表示される。 これは、クリアするのにかかった秒数である。 変換の練習を重ねるにつれて、この数字をどんどん小さくできるはずである。 健闘を祈る。

標準の遊び方(10進数変換)を極めたら、16進数表記から2進数への変換にも挑戦してみるとよい。 16進モードでは、Binary Blasterは10〜15の値を16進数で表示する。 なお、小さい値(1〜9)はどちらの表記でも同じであるため、10進数のまま表示される。

16進モード

16進モードで遊ぶには、次の3つの手順に従う。

  1. Binary Blasterの電源を切る。
  2. 「BIT 0」ボタンを押したままにする。
  3. 「BIT 0」ボタンを押したまま、Binary Blasterの電源を再び入れる。ディスプレイに「A b C d E F」と表示されるはずである。これで16進モードに入った。標準の10進モードに戻すには、ボタンを何も押さずに電源を入れ直すだけでよい。

参考になる16進数の対応表を示す。

10進数/16進数2進数
10001
20010
30011
40100
50101
60110
70111
81000
91001
A1010
b1011
C1100
d1101
E1110
F1111

Binary Blasterを楽しんでもらえたら幸いである。

ボタンのトラブルシューティング

ボタンのひとつが点灯しない場合でも、心配は要らない。簡単な直し方がある。 LEDが点灯しない原因としてもっとも多いのは、極性の間違いである。 Binary BlasterのPCBには、これを直すための特別な工夫が施されている。 2本の配線パターンを切断し、2つのジャンパーを閉じるだけで、ボタンを取り外すことなく極性を入れ替えられる。

まず、問題のあるボタンの隣にあるはんだジャンパーを見つける。 それぞれのボタンには2つのジャンパーがあり、PCBの裏面、各ボタンの近くにある。

それぞれのジャンパーには、中央のパッドとデフォルトの極性設定をつなぐ小さな配線パターンがある。 この小さな配線パターンは見えにくいことがあるが、明るい赤色をした細い金属の筋として見えるはずである。 ホビーナイフ(Xactoナイフとも呼ばれる)を使って、デフォルトの配線パターンを切断する。

はんだごてを使って、中央のパッドともう一方の外側のパッドの間にジャンパーを作る。

これで、そのLEDにつながる配線パターンの極性が入れ替わり、LEDが点灯するようになるはずである。

まとめ

Binary Blasterの設計をさらに理解したい場合は、まず設計ファイルを確認してみるとよい。 ハードウェアとファームウェアのファイル一式は、GitHubリポジトリで公開されている。

Binary BlasterのゲームはArduinoで再プログラムできる。 つまり、ゲームのルールを変えたり、機能を追加したり、まったく別のプロジェクトに作り変えたりすることもできるということである。 Arduinoでの再プログラムについて詳しくは、次のチュートリアルを参照してほしい。

タグ: オーディオ、ゲーム、接続ガイド、プログラミング、はんだ付け


出典:Binary Blaster Assembly Guide(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

LilyPadの基礎:導電糸で縫う

縫えるエレクトロニクスとは何か

縫えるエレクトロニクス(sewable electronics)は、伝統的な手芸の工程(裁縫、ファッションデザイン、テキスタイルデザイン)と、電気工学、コンピュータサイエンス、ハードウェアのスキルを組み合わせたものである。

縫えるエレクトロニクスを使えば、e-テキスタイル(電子繊維)を作ることができる。 これは、従来の電子工作というよりも手芸やアート作品に近い見た目をした、身に着けられる柔軟なプロジェクトであることが多い。 多くのe-テキスタイルプロジェクトでは、配線の代わりに導電糸や導電性の布のような柔軟な導電性の素材を使う。 このガイドで扱うプロジェクトでは、導電糸を使って回路を縫い合わせていく。

参考になるチュートリアル:

回路という概念に初めて触れるなら、続きを読む前に次のチュートリアルにも目を通しておくとよい。

LilyPadとは何か

LilyPadシステムは、柔らかく、縫うことができ、インタラクティブなe-テキスタイルプロジェクトを作るために設計された、縫い付け可能な電子部品の集まりである。 LilyPadの部品を使うことは、手芸というレンズを通して電子工作を実験する優れた方法である。 それぞれのLilyPadの部品には、縫いやすいように大きな導電性の縫い付けタブが付いており、布を引っかけたり糸を切ったりしないよう、丸みを帯びた形をしている。

LilyPadシステムは、コロラド大学ボルダー校でコンピュータサイエンスの博士号を取得する過程にあった、Leah Buechleyによって設計された。 2007年に発売された商用版キットは、LeahとSparkFun Electronicsが共同で設計したものである。

一部のLilyPadの部品は、ProtoSnapという構成で提供されている。 これは、LED、電池ホルダー、スイッチ、ボタンといった個々の部品が、あらかじめひとつの機能する回路基板としてつながっている構成である。 これにより、プロジェクトに組み込む前に、その回路を思いどおりにプログラムして試すことができる。 ProtoSnap基板は、LilyPadプロジェクトの制作を始める準備が整ったら、個々の部品に簡単に切り離せるように設計されている。

これは、パネル構成で提供されているLilyPad製品とは少し異なる。 LilyPadのLEDはひとつながりになってはいるものの、機能する回路としてつながっているわけではない。 回路に縫い込む前に、それぞれを切り離す必要がある。

導電糸とは何か

導電糸は、ステンレス鋼の繊維で作られた特殊な糸である。 銅線の代わりに使うことで、LilyPad(あるいは他のe-テキスタイル)の部品どうしをつないで回路を作ることができる。

LilyPad Sewable Electronics Kitのようなキットを使っているなら、導電糸のボビンが同梱されているはずである。

Note

このチュートリアルでは、手縫いの技法を中心に扱うが、導電糸はミシンや刺しゅうミシンでも使うことができる。

導電糸で縫う

Note

このチュートリアルの例では、LilyPadコイン電池ホルダーとLilyPad LEDを手縫いの導電糸回路でつなぐ手順を紹介する。ここで紹介する技法は、どのLilyPadの部品どうしをつなぐ場合にも応用できる。

たいていのLilyPadプロジェクトでは、導電糸を使って電気回路を完成させる。 以降のセクションでは、基本的な縫い方の技法と、導電糸を使って動作する回路を作るためのちょっとしたコツを紹介する。 針と糸の扱いにすでに慣れている場合でも、特にLilyPadの部品を縫う際に役立つ内容が含まれているはずである。

部品を固定する

それぞれのLilyPadの部品には、縫い付けタブと呼ばれる、導電性の銀色のパッドが付いた大きな穴がある。 これらのタブは、針と糸を穴に何度も通せるよう、十分な余裕を持って設計されている。 回路を縫い始める前に、つなぎたい縫い付けタブを確認し、デザインの中で扱いやすい位置になるよう向きを調整しておこう。 SparkFunのテンプレートに沿って作業する場合、各部品は縫いやすさと見た目の両方を考慮した、決まった位置に配置されている。

縫っている間にLilyPadの部品がずれないよう、少量のホットグルー(推奨)または布用接着剤で布に固定しておくことをおすすめする。 その際、縫い付けタブの穴を誤ってふさいでしまわないように注意すること。

ステッチをどこに通すか計画するために、マーカーで部品どうしを結ぶ線を描いておくとよい。

針に糸を通す

導電糸を60cmほど(およそ2フィート)切り取る。 糸の片端を針の穴(目)に通し、5インチ(約13cm)ほど糸端を残して引き抜く。

プロジェクトを縫い始める前に、糸が布から完全に抜けてしまわないよう、糸の長いほうの端に結び目を作っておく必要がある。 単純な片結びや本結びでもよい。 次のセクションでは、他にいくつかの結び方も紹介する。

スターターノット

スターターノットは、布の上に直接結び目を作って縫い始める方法である。

キルターズノット

キルターズノットは、もう少し高度な結び方で、糸に手早くしっかりとした結び目を作る方法である。 何度か練習すれば、非常に素早く結べるようになる。

Note

プロジェクトに取り組んでいる間は、部品を傷めないよう、必ず電池を外しておくこと。

LilyPadの縫い付けタブへの接続

回路の中でLilyPadの部品どうしをつなぐには、縫い付けタブの周りに導電糸を巻きつけるように縫っていく。 空の縫い付けタブに糸を巻きつけるときは、必ず3〜4回ループさせ、そのたびに糸をしっかりと締めることが重要である。 これにより、糸と縫い付けタブの間に、電気的にも物理的にもしっかりとした接続が生まれる。 次のステッチに進む前に、ループをしっかり締めておくこと。

縫い方の基本

縫い付けタブの周りにループを縫ったら、ランニングステッチ(並縫い)を使って、1本の連続した導電糸でLilyPadの部品どうしをつないでいく。 次の手順で行う。

  1. 針を、縫い進めたい方向へ布の中を約6mm(1/4インチ)進めて刺す。
  2. 布にぴったり沿うように、糸のたるみを引いて締める。
  3. 縫い進める方向にさらに約6mm、針を布の下から上へ刺す。
  4. 布にぴったり沿うように、糸のたるみを引いて締める。

この工程を繰り返しながら、つなぎたい次のLilyPadの部品まで、ステッチの間隔を均一に保ちながら進んでいく。

ランニングステッチと隠しステッチ

基本的なランニングステッチでは、布の表と裏の両方に均等にステッチが現れる。

プロジェクトの表面にステッチを見せたくない場合は、プロジェクトの裏側では長めのステッチを、表側では非常に小さなステッチを作るとよい。 この方法は「隠しステッチ」と呼ばれる。

縫っている間は、導電糸が絡まったり結び目ができたりしていないか確認するため、ときどき布を裏返してチェックしよう。 裁縫を始めたばかりであれば、心地よく縫えるようになるまでに多少の練習が必要かもしれない。 焦らず、時間をかけて縫うようにしよう。 もし糸が切れてしまっても、既存の導電糸の上から重ねて縫うことで、電気的な接続を保ちながら続けることができる。

両方のステッチ方法を使えば、1本の導電糸でLilyPadの部品どうしをつなぐことができる。 2つのLilyPadの部品をつなぐには、縫い付けタブの周りに3〜4回ループさせたあと、そのまま縫い続ければよい。

複数のLilyPadの部品をつなぐ

3つ以上のLilyPadの部品をつなぐには、糸を切って新しく縫い始めるのではなく、そのまま次の部品まで縫い進め、3〜4回ループさせ、必要な分だけこれを繰り返す。 部品どうしが接続を共有する場合、新しい糸に取り替える必要はない。

接続を仕上げる

すべての部品の接続を終えたら、仕上げの結び目を作る。 糸の切れ端が電気的なショートを引き起こすことがあるため、結んだあとは必ず余分な糸を切り取ること。

導電糸による短絡(ショート)のチェック

プロジェクトの中に、ほつれた糸や結び目の切れ端が残っていないか注意しよう。 回路の正極(+)側にある導電糸の切れ端が、うっかり負極(-)側に触れてしまうと、短絡(ショート)が起きることがある。 短絡が起きると、電池が自分自身に接続された状態になり、プロジェクトの残りの部分をバイパスして、電池から望ましくない量の電流が流れ出してしまう。 回路の別の部分のステッチの真上を縫ってしまうことでも、ショートが起きることがある。

Note

e-テキスタイルでもっともよくある短絡のひとつは、電池ホルダーの負極タブの近くにあるほつれた糸の切れ端が、電池に触れてしまうことで起きる。プロジェクトに電源を入れる前に、必ず縫い目を確認しよう。

ステッチどうしが交差したり、回路の他の部分に触れたりしないようにすることが重要である。 これらのプロジェクトで使う電池は、短絡しても発火したり感電したりする心配はまずない(熱くなることはある)が、より高い電圧のプロジェクトや電源では危険を伴うこともある。

電池を入れて完成した回路をテストする

すべての部品を導電糸でつなぎ終えたら、完成した回路には電源が必要である。 コイン電池を、正極(+)側を上にして電池ホルダーに入れる。

Note

プロジェクトの作業を続ける必要がある場合は、部品を傷めないよう、必ず電池を取り外しておくこと。

導電糸での接続が終わったら、回路のスイッチを入れて、何が起こるか確認してみよう。 もし回路が動作しない場合は、どこかがショートしているか、接続が緩んでいるか、部品が逆向きになっているか、あるいは単に電池切れかもしれない。

電池ホルダーのスイッチを入れると、導電糸を通じて電流が回路の他の部分へと流れる。

電流と電気についてさらに知りたい場合は、次のチュートリアルも参考になる。

トラブルシューティング

e-テキスタイルのプロジェクトに取り組んでいると、接続が緩んでLEDが点灯しなかったり、回路が誤動作したりする問題に出会うことがある。

回路がときどきしか動かない場合:接続の緩みを確認する

導電糸がLilyPadの部品の縫い付けタブにしっかりと接続されていないと、電流が安定して流れなくなる。 プロジェクトを動かすと、導電糸が縫い付けタブから離れて、回路が切断されてしまうことがある。 対処法としては、可能であればピンセットや針でステッチをしっかりと引き締める。 既存の糸の上から重ねて縫うことで、より強い張力を作り、縫い付けタブにしっかりと糸を固定することもできる。

回路が動かない場合:極性を再確認する

一部のLilyPadの部品には極性があり、電流が一方向にしか流れない。 回路に誤って縫い込んでしまうと、その部品は機能しない。 縫う前に、縫い付けタブのラベルを再確認し、向きが正しいかどうかを確かめよう。

そのほか確認すべきこと:

  • 電池ホルダーのスイッチがONの位置になっているか確認する
  • 電池切れになっていないか確認する。テスターを使って確認できる。予備の電池を試してみるのもよい
  • プロジェクトのテンプレートに沿っている場合、部品が正しい構成でつながっているか再確認する

それでも問題が解決しない場合は、テスターを使って導通を確認したり、回路の問題を調べたりすることができる。 テスターの使い方のチュートリアルが助けになるはずである。

プロジェクトを大切に扱う

被覆のある銅線とは異なり、導電糸には絶縁がされていない。 そのため、糸はむき出しの配線のようにふるまい、はぐれた繊維どうしが触れ合うと誤って短絡してしまうことがある。

縫い終えてテストが済んだあとに誤った短絡が起きないようにするため、糸の上に布用接着剤や布用塗料を薄く塗るか、もう1枚布を重ねることをおすすめする。 これは、身に着けるプロジェクトや立体的なプロジェクトでは特に重要である。 導電糸を扱うときは、金属製の作業台の上で作業しないこと。

プロジェクトの手入れ

プロジェクトが汚れた場合は、電池を取り外し、中性洗剤を使って手洗いすること。 プロジェクトは自然乾燥させること。乾燥機を使うとLilyPadの部品や縫い目を傷める可能性がある。

まとめ

これで、導電糸を使った縫い方の基本が身についたはずである。 LilyPad Sewable Electronics Kitに含まれる、次のようなプロジェクトにもぜひ挑戦してみてほしい(いずれも英語)。

タグ: 概念、e-テキスタイル技法、e-テキスタイル、LilyPad、スキル、ウェアラブル


出典:LilyPad Basics: E-Sewing(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

LilyPadの基礎:プロジェクトへの電源供給

このガイドでは、LilyPadプロジェクト(e-テキスタイルとArduinoベースの両方)への電源供給の選択肢、電池の安全な取り扱いとお手入れ、そしてプロジェクトの消費電力を計算し考慮する方法について解説する。 ウェアラブルや布を使ったプロジェクトには独自の注意点があるため、導電糸による接続から配線による接続へ切り替えたほうがよい場面についても扱う。

LilyPadプロジェクトは身に着けたり持ち運んだりできることが多く、そのため完成したプロジェクトを持ち歩くには電池を使うことになる。 とはいえ、単に電池をつなぐ以外にも、プロジェクトに電源を供給する方法はいくつかある。 以降のセクションで、さまざまな電源とLilyPadシステムで使える選択肢を詳しく見ていこう。

Note

警告:LilyPadのエコシステムは3.3Vで動作するように設計されており、このシリーズのたいていの電源基板は3VのCR2032コイン電池か3.7Vのリチウムポリマー電池のどちらかに対応している。一部のLilyPad基板には電圧レギュレータが搭載されており、使用できる電源にもう少し柔軟性がある。代替の電源の選択肢については、このガイド全体を通して解説していく。

どの電源を使うべきか、電池でどれだけの時間動かせるか、そのほかの注意点を判断する助けになるよう、いくつかのコツをまとめた。 プロジェクトに必要な電圧、プロジェクトで使うLilyPad基板の合計消費電流、そして電池容量を把握しておくことが、最適な動作を実現する電源を選ぶ助けになる。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

消費電力の計算:動作電圧

たいていのLilyPadプロジェクトは、3.7Vの充電式リチウムポリマー電池で問題なく動作する。 それぞれのLilyPad基板の中核となるマイクロコントローラや主要なセンサー、部品には、それぞれ固有の動作電圧が定められており、データシートに記載されている。 製品のデータシートは、SparkFun.comのカタログページのDocumentsタブから見つけられる。

データシートを読む際は、Operating Voltages(動作電圧)の項目を探そう。 たいていのドキュメントには最小電圧と最大電圧の範囲が示されている。 製品にデータシートが添付されていない場合は、回路図を確認するという方法もある。

基板に十分な電圧を供給しないと、正しく動作しないことがある(LilyPad Arduino上のコードの動きが不安定になったり、シリアルポートに表示されるセンサーの値がおかしくなったり、LEDが暗くなったりすることがある)。 逆に、推奨範囲を超える電圧をプロジェクトに供給すると、基板を損傷したり、動作時間を大幅に縮めたりする可能性がある。 プロジェクトに選ぶ電源が、基板の推奨範囲に収まっていることを必ず確認しよう。

よく使われるLilyPad基板と、その必要条件の一覧を示す。 中央の列は、入力電圧から基板上で調整された(レギュレートされた)電圧を示している。 内蔵レギュレータのない基板を選ぶ場合は、電源がプロジェクトと互換性があるかどうかに特に注意を払う必要がある。 最後の列は、それぞれの基板が受け付けられる入力電圧を示しており、これはLilyPadプロジェクトの推奨動作電圧である3.3Vを上回ることもある点に注目してほしい。

基板電圧レギュレーション入力電圧
LilyTinyなし1.8V〜5.5V
LilyTwinkle / LilyTwinkle ProtoSnapなし1.8V〜5.5V
LilyMini ProtoSnap3.3V1.62V〜3.63V、USB経由で5.0V
LilyPad Arduino Simpleなし2.7V〜5.5V
LilyPad Arduino SimpleSnap3.3V2.7V〜5.5V
LilyPad Arduino USB - ATmega32U4 Board3.3V2.7V〜5.5V
LilyPad USB Plus3.3V1.8V〜5.5V
LilyPad Arduino 328 Main Boardなし2.7V〜5.5V
LilyPad XBee3.3V1.8V〜9V
LilyPad Simblee BLE Board - RFD771013.3V1.8V〜3.6V
LilyPad MP33.3V3.7V〜6V

Note

プロジェクトの中の一部の部品が動作に3.3V以上を必要とする場合、それでもLilyPad Arduinoと組み合わせて使えるだろうか。LilyPadシステムのたいていの基板はシステム電圧(3.3V)で動作するように設計されているが、他の縫い付け可能な製品や縫い付けできない製品を組み合わせる場合、5Vを必要とするセンサーや基板に出会うこともある。その場合、まずはその基板の3.3V版を探してみよう。必要であれば、双方向ロジックレベルコンバータを使って接続することもできる。

消費電力の計算:消費電流

プロジェクトで使うLilyPad基板の動作電圧を確認するのに加えて、プロジェクトが消費する電流と、マイクロコントローラや電池が供給できる電流も比較しておく必要がある。

プロジェクトの消費電流は、プロジェクトで使用するLilyPad基板の総数によって決まり、これはLilyPad Arduinoで制御する回路にもe-テキスタイルのプロジェクトにも当てはまる。 電源や電池がプロジェクトに必要な電流を供給できない場合、回路が不安定で予測できない動作をすることがある。

電圧と同じように、それぞれのLilyPad基板のデータシートを確認することで、プロジェクトがどれだけの電流を消費するか見積もることができる。

LilyPad Arduinoを使うプロジェクトでは、それぞれのI/O(入出力)用の縫い付けタブがどれだけの電流を供給できるかを確認しておこう。LEDのようなLilyPad基板の数は、この値によって制限される。 たいていのLilyPad Arduinoでは、これはI/O用縫い付けタブ1つあたり40mAである。

また、必要な電流を少なめに見積もるよりも、多めに見積もっておくほうが良い習慣である。

モーターや大量のLEDのように大きな電流を必要とする部品をプロジェクトで使う場合、電源の選び直しが必要になったり、LilyPad Arduino用と電力を大きく消費する基板用とで別々の電源を用意する必要が出てきたりすることもある。

LilyPad基板を扱う経験を積んでいくにつれて、各基板のデータシートを確認して計算するだけで、プロジェクトに必要な電流量を簡単に見積もれるようになるはずである。 デジタルマルチメーターや、電流を表示できる可変DC電源を使って、プロジェクトが実際に消費する電流を正確に測定することもできる。

実例:LilyPad LEDとLilyTiny

LilyPadプロジェクトについてよく寄せられる質問の例をひとつ見てみよう。 LilyTiny(あるいはLilyTwinkle)基板には、LEDを何個まで接続できるだろうか。

典型的なLilyPad LEDは、最大輝度でおよそ20mAの電流を消費する。 これに使用するLEDの個数を掛け、全体を動かすLilyPad自身の消費分として10mAを加えれば、おおよその平均消費電流が見積もれる。

例:

LilyTiny基板に10個のLilyPad LEDを接続したプロジェクトの場合

20mA × 10 + 10mA = 210mA

LilyPad LEDの扱いについてさらに詳しい情報は、Powering LilyPad LED Projectsのチュートリアルを参照してほしい。

導電糸の抵抗を考慮する

ここまでの計算が終わったところで、もうひとつ考慮すべき要素がある。導電糸の抵抗である。 抵抗がほとんどない銅線とは異なり、導電糸の抵抗は、糸を作る金属の種類や糸の太さによって変わってくる。 多くの導電糸は、抵抗値をΩ/フィートという単位で表示している。 この数値は小さいほどよい。抵抗が小さいほど、プロジェクトで使う部品により多くの電気を届けられるからである。

プロジェクトが完璧に動作すると期待していても、接続の距離による抵抗が、回路にさらなる問題を引き起こすことがある。

オームの法則という基本的な電気の性質によれば、抵抗の高い素材に電流を流すと電圧が降下する。 電流が大きいほど、電圧の降下も大きくなる。 つまり、LilyPadに電力を供給するLiPo電池が3.7ボルトを出力していても、糸を通って部品に届くころには3.0ボルト以下まで下がっていることがあるということである。 LEDのような多くの電気部品は、正しく動作するために一定の電圧を必要とする。 電圧降下を最小限に抑えるには、電源となる接続部分の抵抗を減らす必要がある。 方法はいくつかある。

  • 電源用の接続部分の長さをできるだけ短くする。抵抗は長さに比例して増えるため、長さを短くすれば抵抗も小さくなる。
  • 糸自体の抵抗を減らす。太い糸は細い糸よりも抵抗が小さく、複数本をまとめて使うことでさらに抵抗を減らせる。

Note

ヒント:複数本の糸を束ねた(あるいは編んだ)ものを基布に縫い付けるには、非導電性の糸を使うとよい。部品を接続する際に、その太い糸の束に導電糸を縫い付けられるよう、縫い目の間に十分な余白を残しておこう。

導電糸の代替手段

導電糸を長い距離にわたって這わせる必要がある大きなプロジェクトや、LilyPad Pixel基板を大量に使うような電力消費の大きいプロジェクト、あるいは糸が負荷で切れやすい箇所には、ウェアラブル向けによく機能する次のような代替手段がある。

導電性リボン

柔軟なより線がナイロンリボンに織り込まれた専用のリボンは、抵抗の低い導電糸の代替品として優れている。 リボンの中にある金属糸にはんだ付けする必要がある。

導電性ファブリックトレース

薄い導電性の布の帯を使って、独自の低抵抗トレースを作ることもできる。 布やリボンに貼り付けるにはアイロン接着剤を使い、そのトレースに部品を接続するには導電糸で手縫いすることをおすすめする。

導電糸と同じように、ファブリックトレースの絶縁も忘れないようにしよう。

より線

もうひとつの代替手段は、導電糸から従来型の配線に切り替えることである。 配線は糸よりもはるかに抵抗が小さいため、導電糸の回路よりも多くのLEDを使うことができる。 縫うのではなくはんだ付けに切り替える必要があるが、通常糸を接続するのと同じ縫い付けタブに配線をはんだ付けするのは簡単である。

配線は、繰り返し曲げられると切れやすい。 高い柔軟性が必要なウェアラブルプロジェクトには、単線ではなくより線を使い、非常に柔軟なシリコン被覆の配線を探すとよい。 洗濯するプロジェクトでは、むき出しのより線に水が染み込み、時間の経過とともに腐食してしまうことがある。 これを防ぐには、配線の切り口に少量のシリコンシーラントを塗るとよい。

Note

はんだ付けする際は、近くの布を溶かしたり焦がしたりしないよう注意すること。熱を加える前に、LilyPad基板の裏側を裏地の布から浮かせるか、絶縁しておこう。

はんだ付けや配線の扱いが初めての場合は、次のチュートリアルを確認することをおすすめする。

プロジェクトの消費電力と注意点を把握できたら、次はプロジェクトの電源を選ぶ番である。

電源の選択肢:内蔵USBコネクタを使う

LilyPad Arduinoプロジェクトのプログラミング作業中は、LilyPad ArduinoとパソコンをつなぐUSBケーブルから供給される電力を使うことができる。 試作中にコードを書き込み、基板に電源を入れるには、LilyPad Arduinoのスライドスイッチが必ずONの位置になっていることを確認しよう。

この方法は、内蔵のマイクロUSBポートを持つLilyPad Arduinoにも、プログラミング用ヘッダーとLilyPad FTDI Basic Breakoutを使うタイプにも使える。

マイクロUSBコネクタを持つLilyPad基板は、Spectacleシリーズや携帯電話の充電バックアップに使われるような、5Vのリチウムイオン電池パックでも電源を供給できる。

プロジェクトが持ち運び可能でもウェアラブルでもない場合(壁掛けや常設展示など)は、5Vのウォールアダプタ電源を使うという選択肢もある。 専用の電源に接続すれば、プロジェクトの電池を絶えず交換したり充電したりする必要がなくなる。

Note

マイクロUSBコネクタが付いたウォールアダプタや電池パックを見つけたが、LilyPadプロジェクトに使えるだろうか。マイクロUSBだからといって、その電池パックが必ずしもプロジェクトに適しているとは限らない。SparkFunのカタログ以外から電池パックを調達する場合は、パッケージや製品のラベルを必ず確認し、5V電源であることを確かめよう。

LilyPad Simple Powerは柔軟性のある基板であり、充電式電池にもマイクロUSBケーブル経由のウォールアダプタにも対応できるため、電池コネクタが内蔵されていないLilyPadプロジェクトに使うことができる。

電源の選択肢:充電式リチウムポリマー電池

Note

LilyPadのJSTポートには、必ず3.7VのLiPo電池を接続すること。同じコネクタを使っていても、LiPo以外の電池をこれらのJSTポートに接続してはいけない。充電回路が電池を損傷する可能性がある。電池の電源線とグラウンド線の向きは、メーカーによって逆になっていることがあるため、必ず確認すること。SparkFunが扱うすべてのLiPo電池は標準的な構成になっている。

多くのLilyPad製品には、3.7Vのリチウムポリマー(LiPo)電池を接続するためのJSTコネクタが搭載されている。 これらの基板には充電回路が内蔵されており、USB接続でパソコンやウォールワートにつなぐとLiPoを充電できる。

SparkFunでは、LilyPadシステムと互換性のある3.7Vリチウムポリマー電池を各種取り扱っている。 どの容量の電池を選ぶかは、プロジェクトの想定稼働時間やサイズの制約など、さまざまな要因によって決まる。

LiPo電池の使用と充電

Note

LilyPadプロジェクトは手洗いできるが、洗う前には必ず電池を取り外し、電池を戻す前に数日間しっかりと自然乾燥させること。

充電機能を備えたそれぞれのLilyPad基板には、デフォルトの充電レートが設定されている。 このデフォルトの充電電流が100mAに設定されている場合、100mAhの電池は1時間で、1000mAhの電池は10時間で充電できるということになる。 基板が100mAで充電するように設定されているため、それより低い容量のLiPo電池(たとえば40mAhのLiPo電池)を接続して充電することはおすすめしない。

Note

充電回路を内蔵するたいていのLilyPad製品は100mAに設定されているが、LilyPad MP3とLilyPad Simple Powerのデフォルトの充電レートは500mAである。設定された充電レートより容量の小さいLiPo電池を使う場合は、SparkFun Adjustable LiPo Chargerを使って別途充電することをおすすめする。

接続した電池を充電するには、基板をUSB電源に接続する。 電池の充電中は「CHG」LEDが点灯する。 電池が満充電になると、このLEDは消灯する。

USB電源を接続したままの状態でも、LiPo電池を基板に恒久的に接続しておいて問題ない。 電池が過充電になることはない。 とはいえ、充電中の電池をそのまま放置しないことをおすすめする。

Note

電池を挿抜する前は、必ずLilyPad基板の電源を切ること。

電池のコネクタはきつくはまっていることがあり、取り外しにくいことがある。電池を取り外す際は、決して配線を引っ張らないこと。 ラジオペンチやニッパーをプラスチックの部分に添えて、コネクタからプラグを優しく引き抜こう。

ヒント:プラスチック製の電池コネクタの上部には小さな「突起」が2つあり、ホビーナイフで削り取ると電池を取り外しやすくなる。

Note

JSTコネクタが付いたかっこいい電池パックを見つけたが、LilyPadプロジェクトに使えるだろうか。JSTコネクタはよく使われる種類のコネクタであり、それが付いているからといってLilyPadと互換性があるとは限らない。SparkFunのカタログ以外から電池を調達する場合は、必ず次の点を確認しよう。3.7Vか。充電式のリチウムポリマー/リチウムイオン電池か。

LiPo電池の安全な取り扱いとお手入れ

Note

警告:LiPo電池は、扱いを誤ったり損傷したりすると、発火や爆発の恐れがある。穴があいたり高温にさらされたりすると、不安定になり危険な状態になることがある。

LiPo電池は充電式の電源としてプロジェクトに優れた選択肢だが、いくつかの安全上の注意点がある。 このセクションでは、プロジェクトでLiPoを安全に扱い、使用するためのコツを紹介する。

保管

  • 電池は必ず、鋭利なものがない収納場所に保管すること。プロジェクトに電池を組み込む際は、電池を挟んだり、突き刺したり、負荷をかけたりする可能性のある部分から離しておくこと。
  • ヘアピンやネックレスなど、金属製あるいは導電性のある物と一緒にLiPo電池を運んだり保管したりしないこと。
  • プロジェクトに組み込んだ状態でも保管中でも、電池は涼しく乾燥した場所に保つこと。プロジェクトを長期間使わない予定であれば、電池を取り外して別に保管すること。

熱と湿気を避ける

  • LiPo電池を傷める恐れのある環境から遠ざけること。LiPo電池を液体に浸さないこと。プロジェクトを洗う必要がある場合は、電池を取り外すこと。
  • 熱源の近くで電池を使ったり保管したりしないこと。プロジェクトに電池を固定するには、面ファスナーを使うか、ポーチに縫い付けるか、プラスチックの収納ケースに入れるとよい。LiPo電池の上や周囲に直接アイロンをかけたりホットグルーを使ったりしないこと。

ストレインリリーフ

これらのLiPo電池を使う際の欠点のひとつが、電源接続部分の脆弱さである。 このタイプの電池は機器への恒久的な組み込みを想定して作られており、ウェアラブルでよくあるように頻繁に取り外すことは想定されていない。 電池に内蔵された保護回路の端子から、うっかり配線を引っ張って壊してしまうことがある。

配線を横に寄せて絶縁テープで固定することで、ストレインリリーフ(負荷の分散)を施すことができる。これにより、取り外す際に電池への接続部分にかかる負荷を和らげられる。

使用前に毎回電池を点検する

  • LiPo電池の短絡や損傷は、必ずしも見た目で分かるとは限らない。膨らみ、発熱、その他の変化がないか確認すること。電池が損傷しているように見えたら、すぐに取り外すこと。
  • 使用中、充電中、保管中に電池から異臭がしたり、発熱したり、変色や変形が見られたり、少しでも異常な様子が見られたりした場合は、すぐにプロジェクトや充電器から取り外し、使用をやめること。電池は必ず適切な方法で廃棄すること。ゴミ箱に捨ててはいけない。地域の電子廃棄物処理団体に、電池の廃棄方法について問い合わせること。

電源の選択肢:コイン電池

LilyPadシステムには、3VのCR2032コイン電池を1枚収める基板もある。 これらの電池はたいてい使い切りだが、充電式のコイン電池がホルダーに収まる場合もある。

CR2032という電池の名前には、いくつかの重要な情報が含まれている。

  • Cはリチウム電池の種類を示す

電池を選ぶ際は電圧(3V)を確認するのに加えて、名前の末尾2桁の数字にも特に注意を払おう。互換性がありそうに見えても、LilyPadの電池ホルダーに対してわずかに大きすぎたり小さすぎたりする電池もある。

LilyPad製品ラインには、カスタムプロジェクトに接続できるスイッチ付きの単体電池ホルダーがあるほか、LilyMini基板に内蔵されているものや、一部のProtoSnap製品にも用意されている。 SparkFunでは、小さなフットプリントが必要なプロジェクトや、はんだ付けを好むユーザー向けに、縫い付けタブのないLilyPad以外のコイン電池ホルダーも扱っている。

Note

LilyPadの電池ホルダーを2つ直列につないだり、見つけてきた2電池パックを使ったりしてもよいだろうか。これは、電源を供給するLilyPad基板によって異なる。3Vの電池を2つ直列にすると6Vが供給されるが、一部のLilyPad基板にはオンボードのレギュレーション回路がなく、3Vを超える電圧を供給すると損傷する可能性がある。たとえばLilyTinyやLilyTwinkle基板は2.4V〜5.5Vの範囲でもっともよく動作する。このような場合は、リチウムイオン電池やリチウムポリマー電池のほうがプロジェクトに適しているかもしれない。プロジェクト固有のニーズに合った電池を選ぶコツについては、消費電力の計算のセクションを参照してほしい。

電池の安全な取り扱いとお手入れ

Note

リチウム金属電池は、扱いを誤ったり損傷したりすると、発火や爆発の恐れがある。穴があいたり高温にさらされたりすると、不安定になり危険な状態になることがある。

このセクションでは、プロジェクトでコイン電池を安全に扱い、使用するためのコツを紹介する。

保管

  • ヘアピンやネックレスなど、金属製あるいは導電性のある物と一緒にコイン電池を運んだり保管したりしないこと。複数のコイン電池をばらばらのまま一緒に保管しないこと。電池どうしが接触して短絡し、放電してしまうことがある。
  • プロジェクトに組み込んだ状態でも保管中でも、電池は涼しく乾燥した場所に保つこと。プロジェクトを長期間使わない予定であれば、電池を取り外して別に保管すること。

熱と湿気を避ける

  • コイン電池を傷める恐れのある環境から遠ざけること。コイン電池を液体に浸さないこと。プロジェクトを洗う必要がある場合は、電池を取り外すこと。
  • 熱源の近くで電池を使ったり保管したりしないこと。プロジェクトに電池を固定するには、専用の電池ホルダーを使うか、ポーチに縫い付けるか、プラスチックの収納ケースに入れるとよい。コイン電池に直接はんだ付けしないこと。プロジェクトにはんだ付けする必要がある場合は、専用の電池ホルダーを使うか、はんだ付け用のタブが付いた電池を購入すること。

使用前に毎回電池を点検する

  • コイン電池の短絡や損傷は、必ずしも見た目で分かるとは限らない。膨らみ、発熱、その他の変化がないか確認すること。電池が損傷しているように見えたら、すぐに取り外すこと。
  • 使用中、充電中、保管中に電池から異臭がしたり、発熱したり、変色や変形が見られたり、少しでも異常な様子が見られたりした場合は、すぐにプロジェクトや充電器から取り外し、使用をやめること。電池は必ず適切な方法で廃棄すること。ゴミ箱に捨ててはいけない。地域の電子廃棄物処理団体に、電池の廃棄方法について問い合わせること。

プロジェクトは電池でどれだけの時間動くのか

プロジェクトが電池でどれだけの時間動くかを知るには、次の2つを把握する必要がある。

  • プロジェクトが消費する電流
  • 電池の容量

電池の容量はミリアンペア時(mAh)で表される。 これは、満充電の電池が空になるまでに1時間あたり何ミリアンペア(mA)供給できるかを示す数値である。 たいていのLilyPad Arduinoキットに付属するe-Textiles Batteryの容量は110mAhである。 LEDなど多数の部品を使うプロジェクトなど、多くのプロジェクトでは、より長い稼働時間を得るためにより大容量の電池を使いたくなるだろう。

電池がどれくらい持つかを求めるには、次の式を使う。

時間 = 電池のmAh ÷ プロジェクトのmA

つまり、e-Textiles Batteryではプロジェクトをおよそ30分程度しか動かせないことになる。 イベントや展示会のように長時間の稼働が必要な場合は、より大容量の電池を選ぶのが理にかなっている。 そのトレードオフとして、大容量の電池は物理的にも大きくなる。プロジェクト上での電池の収納方法や固定方法をあらかじめ計画し、配線や布への負荷を減らすようにしよう。

* 注:コイン電池は充電式ではない。

Note

注意:カタログにあるそのほかの電池は、e-テキスタイル専用に作られたものではない。代替の電池を使う場合は、導電糸のトレースを短絡させないよう注意すること。

まとめ

LiPo電池やウェアラブルプロジェクトについてさらに情報が必要な場合は、次のような関連チュートリアルも確認してみてほしい(いずれも英語)。

タグ: Arduino、記事、概念、E-Craft、e-テキスタイル、LilyPad、電力、プロトタイピング、ウェアラブル


出典:LilyPad Basics: Powering Your Project(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

ELワイヤーで光るズボンを作る

このプロジェクトの設計・製作にかかる時間は、手縫いの経験、使うELワイヤーの長さ、どこに縫い付けるかによって変わる。ズボンの側面に沿って縫う場合、おおよそ1〜3時間程度である。

注意: このチュートリアルで使ったズボンはキッズMサイズで、標準的なELワイヤーを脚の側面に縫い付けている。使用したワイヤーの長さは3メートルである。ズボンのサイズによっては、以下で説明するとおり、必要なELワイヤーの長さが変わってくる。あらかじめ計画を立てておくとよい。

このチュートリアルでは、標準的なELワイヤーをズボンに縫い付ける。

必要な部品

このチュートリアルを進めるには、次の材料が必要になる。 ズボンには標準的なELワイヤーを使う。 手元にあるものや自分の環境によっては、すべてが必要とは限らない。 カートに入れてガイドを読み進め、必要に応じて調整してほしい。

  • 単三形アルカリ電池
  • ELワイヤー(白 3m)
  • ELインバータ(電池パック式)

注意: ELワイヤーにはさまざまな色がある。標準的なELワイヤーの色の選択肢には、赤、黄、オレンジ、緑、青、紫、白、青緑、蛍光グリーンなどがある。

チェイシング(流れるように光る)タイプや曲げやすいタイプのELワイヤーを探している場合は、SparkFunのカタログでさらに多くの色・種類のELワイヤーを確認できる。

道具

最低限、針が必要になる。 延長ケーブルを作る場合は、はんだごて、はんだ、一般的なはんだ付け用アクセサリーも必要になる。

  • 針セット

その他に必要なもの

  • ズボン
  • 透明糸またはテグス
  • ダブルクリップ、まち針、あるいはテープ
  • はさみ

参考になるチュートリアル

以下の概念に馴染みがない場合は、先に次のチュートリアルを読んでおくとよい。

ELワイヤーの準備

注意: 以下の画像は、キッズサイズのズボンに標準的なELワイヤーを使用している。使用したワイヤーの長さは3メートルである。ズボンのサイズによっては、以下で説明するとおり、必要なELワイヤーの長さが変わってくる。あらかじめ計画を立てておくとよい。

ELワイヤーとELインバータをテストする

ELワイヤーを衣類に縫い付ける前に、正常に動作するか必ずテストしておくこと。 テストするには、ELワイヤーをインバータに接続する。 今回は、単三形電池と3VのELインバータ電池パックを使用する。

ELインバータ電池パックに電池を入れた状態で、ボタンを押してテストする。 ELワイヤーが光れば、ELワイヤーとELインバータの両方とも問題なく使える。

経路を計画する

ELワイヤーをどこに取り付けるか計画する。 縫っている間ELワイヤーを固定するため、ダブルクリップを使う。 手元にあるものによっては、まち針やテープを試してもよい。 ELワイヤーをダブルクリップに挟み、生地に押さえつけて固定する。 ダブルクリップが挟む部分にELワイヤーを挟まないよう注意すること。コロナワイヤー(芯線を覆う細い導線)を傷める恐れがある。

今回は、3メートルのELワイヤーすべてを使い、左のポケットから始めて脚の側面を下り、ウエストまで戻ってくる経路にした。 続いてELワイヤーは背面のウエストに沿って進み、右脚の側面を下ってから再び右のポケットまで戻ってくる。 左右対称になるよう、各側の長さを調整した。

注意: コットンのような緩い生地は、糸を押さえる何かがないと縫いにくいことがある。このチュートリアルで使ったズボンはポリエステル製で、扱いやすかった。素材はよく考えて選ぶこと。

針と糸を用意する

このチュートリアルでは、透明糸を二重にして使う。 透明糸の端を針の穴(目)に通し、引き抜いて針と糸を用意する。 作業しやすい長さ(両腕を広げたくらい、約60cm)に糸を切る。 テグスの両端を結んで玉止めする。 糸の端近くまで結び目を寄せるのに、針を使うとやりやすいことがある。

同じ手順をもう一度繰り返し、2つ目の結び目を作る。 余った糸の端は切り落とす。

ヒント: 透明糸は非導電性である。結び目の作り方について他の選択肢を知りたい場合は、導電性の糸で縫うの節も参考になる。

ELワイヤーを縫い付ける

注意: 以下の画像は、キッズサイズのズボンに標準的なELワイヤーを使用している。使用したワイヤーの長さは3メートルである。ズボンのサイズによっては、以下で説明するとおり、必要なELワイヤーの長さが変わってくる。あらかじめ計画を立てておくとよい。

⚡ 注意: 縫っている間は、ELワイヤーが電源から外れていることを必ず確認すること。また、縫っている最中に自分自身やELワイヤーを針で刺さないよう注意すること。

ELワイヤーの熱収縮チューブの近くから縫い始め、ELワイヤーの周りに結び目を作る。 ELワイヤーを固定するため、ワイヤーの周りにループを作り続ける。 透明糸で縫う際は、生地によっては糸が滑りやすいため、糸を最後までしっかり引き抜くこと。 ズボンの前面と背面を一緒に縫い合わせてしまわないよう注意すること。 また、各縫い目の間隔を空けすぎないようにする。0.5〜1インチ(約1.3〜2.5cm)程度がちょうどよい間隔である。 縫い目の間隔が長すぎると、ELズボンを着用した際にELワイヤーが引っかかったり緩んだりする原因になる。

5回ほど縫ったら、最後の縫い目に糸をくぐらせて片結びを作り、糸を固定して滑らないようにする。

糸が残り少なくなってきたら、透明糸を生地に結びつけて固定する。 続いて、別の透明糸で上記の手順を繰り返す。

ELワイヤーを縫い終えたら、ワイヤーの端でループを作り、ひずみ防止のためにそのワイヤーも縫い付ける。 このループは、熱収縮チューブより先の位置にすること。熱収縮チューブのある接続部分は曲げに弱いためである。

ELワイヤーをELインバータに再び接続してテストする。 点灯すれば準備は完了である。 ELインバータをポケットに入れるか、ベルトにクリップで留めて楽しんでほしい。 ELインバータの電池パックを使っている場合は、延長ケーブルを自作するのもよいだろう。

ELワイヤーは、暗い場所で最もよく映えることを覚えておいてほしい。 日中や、光源のある部屋では見えにくいことがある。

明るい場所でのEL

暗い場所でのEL

ズボンのサイズによる違い

先ほど触れた、ズボンのサイズについての話を思い出してほしい。 ズボンのサイズが変われば、必要なELワイヤーの長さも変わる。この違いにより、ELワイヤーの始点・終点が想定した位置にならないことがある。 キッズサイズのズボンと比較した画像の違いに注目してほしい。 ELワイヤーの始点は脚のさらに下の方に縫い付けられており、ウエストに向かって戻る際も細い経路をたどっている。

まとめ・参考資料

次のプロジェクトのヒントとして、次のような関連チュートリアルも参考になる。

  • EL Wire Light-Up Dog Harness — 暗い中で愛犬を散歩に連れて行くときのために、ELワイヤーで光る犬用ハーネスを作る方法
  • Heartbeat Straight Jacket — ある人の心拍を、別の人の衣装に表示するELプロジェクト
  • Sound Reactive EL Wire Costume — ELワイヤーの衣装を音に反応させる方法を学ぶプロジェクトチュートリアル
  • Prototype Wearable LED Dance Harness — 振り付けを踊るダンサーに追加の演出効果を加えるプロジェクトチュートリアル。衣装の下に手早く装着できるハーネス
  • EL Wire Hoodie — 標準的なEL(エレクトロルミネセンス)ワイヤーをパーカーに縫い付ける

さらにアイデアが欲しい場合は、次の関連ブログ記事も参考になる。

タグ: ELワイヤー、E-Textiles、ハロウィン、光、プロジェクト、ウェアラブル


出典:EL Wire Pants(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

自分だけのFritzingパーツを作る

Fritzingは、電子工作プロジェクトの指導、共有、プロトタイピングに使える優れたオープンソースツールである。 回路図を設計でき、その回路図をもとにパーツを作って、本格的な見た目の配線図に組み込むことができる。 自分で設計したPCBを、そのファイルから実際に製造してもらうことすらできる。 SparkFunでも、教室での指導、ハンドアップガイド、その他ボードと他のハードウェアとの接続方法を示す必要があるあらゆる場面でFritzingを使っている。

INA169をArduinoに接続したFritzingの例

Fritzingの素晴らしい点は、自分のプロジェクト用に独自のFritzingパーツを作り、コミュニティと共有できることである。 このチュートリアルでは、Fritzing(New)Parts Editorでカスタムパーツを作る方法を、最初から順を追って説明する。

カスタムFritzingパーツを作る必要はあるか

Fritzingには、ソフトウェアに最初から数多くの電子部品が同梱されている。 SparkFunにも、Fritzingにまだ収録されていない自作パーツを収めたFritzingのGitHubリポジトリがある。 自分でパーツを作る前に、この2箇所にすでにパーツが存在しないか、あるいはFritzingフォーラムで別のFritzingユーザーがすでに必要なパーツを作っていないか、必ず確認してほしい。 すでに作られていれば、かなりの時間を節約できる。 とはいえ、必要なパーツがFritzingの世界にまだ存在しないと確信できたなら、続きを読み進めてほしい。

参考になるチュートリアル

このチュートリアルは、Adobe IllustratorかInkscape、あるいはその両方にすでに馴染みがあることを前提としている。 これらのソフトウェアの使い方自体は、このチュートリアルの範囲外である。 どちらかの使い方についてより詳しい情報が必要な場合は、それぞれの公式サイトにベクターグラフィックスの始め方に関するチュートリアルやガイドが数多く用意されているはずである。 それでも見つからなければ、検索してみるのもよいだろう。

このチュートリアルを読む前に、次の関連チュートリアルにも目を通しておくとよい。

ダウンロードとインストール

自分だけのカスタムFritzingパーツを作るには、次のソフトウェアをダウンロード・インストールしておく必要がある。

注意: シンプルなICを作りたいだけであれば、Fritzing(New)Parts Editorで簡単にカスタムICを作成できるため、ベクターグラフィックスエディタをダウンロードする必要はない。それでもこのチュートリアルには沿って進められる。Fritzing(New)Parts Editorでカスタムのicを土台に組み立てていく流れになっているためである。

Fritzing

Fritzingのサイトのダウンロードページに行き、自分のOSに合った最新版のFritzingをダウンロードする。 ハードドライブ上でFritzingアプリケーションを置きたい場所を決め、そこにFritzingフォルダを解凍する。

ベクターグラフィックスエディタ

ベクターグラフィックスエディタにはさまざまな種類がある。 SparkFunで使っているのはAdobe IllustratorとInkscapeである。 自分が最も使い慣れていて扱いやすいものを選んでほしい。 ベクターグラフィックスエディタを持っていない場合は、無料で使えるオープンソースのInkscapeがよい選択肢になる。

Inkscape

Inkscapeのダウンロードページへ行き、自分のコンピュータに合った公式リリースパッケージをダウンロードする。

Windowsユーザー: 実行ファイルをダブルクリックし、Inkscapeセットアップウィザードの指示に従う。

Mac OS Xユーザー: Inkscapeのサイトにある最新の手順に従う。

Adobe Illustrator

Adobe Illustratorは無料ではないが、すでにAdobeのCreative Cloudを契約している場合はダウンロードできる。 Illustratorの月額プランを購入することもできる。

注意: SparkFunはAdobeと提携関係にはなく、このチュートリアルで必要な用途によく合う優れたソフトウェアであるという理由だけでIllustratorを紹介している。

その他のダウンロード

Fritzingのフォントとテンプレート

FritzingはICの表記にOCR-Aフォントを使っている。 それ以外のパーツには、OCR-AとDroid Sansフォントのどちらも使える。 Fritzingのサイトでは、フォントとテンプレートをダウンロードできる。 このチュートリアルを進めるには、Fritzingのグラフィック標準をダウンロードしておく必要がある。 テンプレートのダウンロードページへ行き、Fritzing’s Graphic Standardsフォルダをダウンロードする。 zipファイルをダウンロードしたら、フォルダを解凍し、コンピュータの好きな場所に置く。 フォントはコンピュータにインストールしておくこと。

SparkFun Fritzingサンプルテンプレート

このチュートリアルでは、SparkFun Fritzingサンプルテンプレートを何度も参照する。 SparkFunのボード用にFritzingパーツを作りたい場合や、出発点となるものが欲しい場合は、SparkFun Fritzing PartsのGitHubリポジトリからこのテンプレート一式をダウンロードしてほしい。 SparkFunのFritzingテンプレートには、このチュートリアルの例であるSparkFun T5403 Barometer BreakoutのSVGファイルが含まれており、比較したり参考にしたりできる。

ブレッドボードビュー

Fritzingを起動すると、まずWelcomeビューが表示される。 そこからBreadboardビューに移動する。

ブレッドボードビューで行う必要のある主な作業は2つある。 まず、ブレッドボード用のSVGを作成してアップロードする。 FritzingはSVG形式を推奨しており、拡大縮小しても画像がきれいに見えるようになっている。 次に、コネクタピンを変更する必要がある。

注意: シンプルなICだけを作りたい場合は、このチュートリアルの「ブレッドボードビューの編集」の節まで読み飛ばしてよい。

Fritzingのグラフィック標準

Fritzingのウェブサイトには、従うべきグラフィック標準が数多く用意されている。 このグラフィック標準に従っておくと、自分の作ったパーツが他のFritzingパーツと見た目をそろえられるのでおすすめである。

テンプレート

パーツを作る際は、テンプレートから始めることを推奨する。 参考にできるパーツの画像を手元に用意しておくと、SVGファイルを作る作業が速く進む。

ヒント: EAGLEで作ったボード用にカスタムFritzingパーツを作りたい場合は、ボードをSVGに変換するULPをダウンロードできる。これを使えば、EAGLEのボードを正確に反映したSVGを参考資料として用意できる。EAGLE用のULPはCadsoftのサイトで見つかる。

いよいよブレッドボードビュー用のグラフィックを作る番である。

新しいパーツを作成する

このチュートリアルでは、SparkFun T5403 Barometer Breakout用のFritzingパーツを作る。

SparkFun T5403 Barometer BreakoutのEAGLE画像

Fritzingアプリケーションを開く。 プログラム上部にWelcome、Breadboard、Schematic、PCBのタブが表示されるはずである。 Breadboardボタンをクリックし、Breadboardビューにいることを確認する。

既製のパーツを確認する

Fritzing上のボードを更新するだけの場合は、まず、作ろうとしているパーツに近いものがすでにないか確認する。 検索バーにパーツの名前を入力して探せる。

検索バーはPartsウィンドウの上部にある

Fritzingの各セクションを見て回り、似たパーツがないか確認することもできる。

SparkFunの炎マークを探すと、SparkFunのFritzingパーツの一大セクションが見つかる

ICを出発点にする

作りたいパーツに似たものが見当たらない場合、ICを土台にするのがよい出発点になる。 PartsウィンドウのCOREタブをクリックする。 下にスクロールしてICのセクションを探す。 ICセクションの下にあるICアイコンをクリックし、Breadboardウィンドウにドラッグ&ドロップする。

カスタムICは、Fritzingでピン数とICパッケージを変更できるためシンプルに作れる

ICの名前を変更する

右側のInspectorウィンドウにあるICのプロパティを探す。 ICの名前を自分のパーツの名前に変更する。 続いて、pinsのセクションで、ボードやパーツに必要なピン数に変更する。 SparkFun T5403 Barometer Breakoutの場合、8ピンが必要である。 Breadboardビューで、ICの表示が自分のパーツの名前に変わっているのがわかるはずである。

Fritzing(New)Parts Editor

Breadboardウィンドウ内のICを右クリックし、「Edit(new parts editor)」を選択する。 Fritzing(New)Parts Editorが開くはずである。

Fritzing(New)Parts Editorには、変更を加える必要のある主なセクションが6つある。次のとおりである。

  • Breadboard
  • Schematic
  • PCB
  • Icon
  • Metadata
  • Connectors

これらを進める順序に決まりはない。 何回かカスタムパーツを作っていくうちに、他よりも先に着手したくなるビューが出てくるはずである。 このチュートリアルでは、単純にこのリストの順番どおりに進めていく。

著者の補足: ピン数が多いボードの場合、Connectorsビューから始めた方が、コネクタピンの名前を上から順に手早く付けられるので、少し時間の節約になると気づいた。

作業を続ける前に、まず新しいパーツとして保存しておくとよい。 カスタムパーツの制作を途中で中断する必要がある場合、後で作業に戻ってこられる。 Fileに行き、Save as new partを選択する。

好みでプレフィックスの名前を付けることもできる。


続けてBreadboardビューに進もう。

カスタムブレッドボードSVG

ファイルを作成する

ベクターグラフィックスエディタを開き、新しいファイルを作成する。 ファイルの画像サイズは、自分のボードと同じサイズにする。 SparkFun T5403 Barometer Breakoutのサイズは1インチ×0.650インチである。 Fritzingパーツを作る際には最終的に3種類のSVGファイルが必要になるため、わかりやすい命名規則でファイルを保存しておくとよい。

Illustratorユーザー向け: File → Save Asと進み、SVGとして保存し、Saveをクリックする。

この例では、Breadboard用のSVGをSFE_T5403_Barometer_Breakout_breadboard.svgという名前にしている。

テンプレートを参考にする

各レイヤーとグループを比較するには、先ほどダウンロードしたFritzing Fonts and TemplateフォルダにあるFritzingのBreadboardViewGraphic_Template.svgファイルを開くとよい。 SparkFun Fritzing PartsのGitHubリポジトリから、SparkFun T5403 Barometer Breakoutのブレッドボード用SVGテンプレートファイルのサンプルを開くこともできる。

このサンプルテンプレートを見ると、レイヤーをどう整理しておけばよいかがわかる。 SparkFun T5403 Barometer Breakoutの場合、「breadboard」というグループがある。 そのbreadboardグループの中に、部品のグループ、銅箔レイヤー、シルクスクリーンのグループ、ボードのパスが含まれている。

カスタムブレッドボードグラフィックを作るコツ

これで、自分のパーツのブレッドボード用グラフィックを作成できるようになった。 ここでいくつか役立つコツを紹介する。

Fritzingのグラフィック標準に従う

ブレッドボード画像の主な配色標準を紹介する。

Fritzingのグラフィック標準に従うため、銅の接点は銅・すず色にしたい。

HEX: 9A916C, RGB: 154 145 108

ボード上の部品にリード線(脚)がある場合は、グレー色を使う。

HEX: 8C8C8C, RGB: 140 140 140

SparkFunレッドは次の色である。

HEX: E62C2E, RGB: 230 44 46

シンプルに保つ

Fritzingのすばらしい点は、ボードをシンプルにもできれば複雑にもできることである。 SparkFunは常に製品をリビジョンによって改良し続けており、扱うボードの数も多いため、トレースやすべての部品といった細かな要素を含めない方が、作業が速く簡単になる。 そうしておけば、ボードに変更(たとえば抵抗の値の変更)があっても、Fritzingパーツの中の抵抗をいちいち変更しに行く必要がない。 ICのような重要な部品に絞って時間を使う方が、よい選択かもしれない。 それでも見た目はきちんとしたものになり、しかも作業量は少なくて済む。

既存のコンポーネントを活用する

ボードに使いたいSMD LEDがすでにFritzingに存在するなら、遠慮なくそれを使ってほしい。 時間の節約になり、すべてのFritzingパーツの見た目や使用感を統一しておくことにもなる。 他の人も使えるコンポーネントを含むカスタムボードを作った場合は、Fritzingのサイトで共有すれば、他の人にも使ってもらえる。 使っているベクターグラフィックスエディタの中で部品のグラフィックをきちんと整理しておくと、将来別のボードで使う際に見つけやすくなる。

銅箔グループの中でコネクタピンに名前を付ける

コネクタに名前を付けておくと、大幅な時間の節約になる。 SparkFun T5403 Barometer Breakoutの例では、銅箔グループの下で、各コネクタにconnector#padという名前を付けている。

Illustratorでの例。Inkscapeを使っている場合も、コネクタに適切な名前を付けておくようにすること。

OCR-AまたはDroid Sansフォントを使う

すべてのFritzingパーツの見た目をそろえるため、Fritzingのフォントを使い続けること。 標準のフォントサイズは5ptを推奨する。 とはいえ、小さなボードではそのスペースが取れないこともある。 3pt未満にはしない方がよい。それより小さいと、拡大しないと見えにくくなってしまうからである。 Fritzingのサイトではフォントの色は黒を使うよう案内されているが、実際にはシルクスクリーンの色に合わせた方が見栄えがよい傾向がある。 この例では、白がブレイクアウトボードのシルクスクリーンの色であり、赤い背景の上でも読みやすいため、白を使っている。

コンパウンドパスを作ってボードの穴を透けさせる

Illustratorユーザー向け: 自分のPCBのサイズでパスを作る。SparkFun T5403 Barometer Breakoutの場合、長方形ツールを使って1インチ×0.650インチの長方形を作れる。続いて、ボードに開口部がある箇所にパスを作る。たとえば長方形ツールの下にある楕円ツールを使い、スタンドオフやコネクタピン用の開口部にきれいな円を作ることができる。すべての穴の開口部レイヤーと、一番下のPCBレイヤーを選択する。

一番下のPCBレイヤーが選択されていることを確認する

続いて、ObjectCompound PathMakeに進む。 これでコンパウンドパスができ、Fritzing上で開口部を透けて見えるようになる。

完成したブレッドボードグラフィック

Inkscapeユーザー向け: Inkscapeを使う場合も、長方形ツールで長方形を作成する。Fillに色を設定し、StrokeUnsetのままにする。Objectsタブで、Ctrlキーを押しながら長方形とボードのレイヤーを選択する。続いてPathDifferenceに進む。2つのレイヤーが一つに結合され、透けた穴のあるレイヤーになる。Fritzingでボードを設計した場合と同じ効果が得られるはずである。詳しくは、ブール演算を使ったInkscapeのチュートリアルを参照してほしい。

保存する

カスタムボードの作成が終わったら、必ずもう一度SVGとして保存すること。 これで、ブレッドボードビューの編集に進める。

ブレッドボードビュー:Parts Editor

画像を読み込む

カスタムのブレッドボード画像を作成したら、それをFritzing(New)Parts Editorで読み込む。 まず、Fritzing(New)Parts Editorに戻り、Breadboardボタンをクリックしてブレッドボードビューに入る。 File→Load image for viewに進む。

続いて、先ほど作成したブレッドボード用SVGを選択し、Openをクリックする。 これでFritzing(New)Parts Editorにグラフィックが表示されるはずである。

コネクタ

Fritzingのメインアプリケーションで作業する際は、色付きのワイヤーで異なるFritzingパーツをつなぎ、パーツ同士がどう接続されているかを示す。 Fritzingがボードやパーツ上のコネクタピンの位置を把握できるよう、そのコネクタがどこにあるかを教えてやる必要がある。

コネクタピンの名前と説明

Breadboardビューでは、Connectorsウィンドウは Fritzing(New)Parts Editorの右側にある。 ピンを選択すると、そのピンの名前を変更したり、説明を追加したりできる。

編集したいコネクタピンをクリックして選ぶ

コネクタピンのグラフィックを選択する

コネクタピンの名前の右にある「Select graphic」ボタンをクリックする。 続いて、そのコネクタピンのグラフィックをクリックする。 これでアンカーポイントが設定される。 アンカーポイントとは、ワイヤーがそのコネクタに接続される位置のことである。 デフォルトでは、選択したグラフィックの中央にTerminalポイントが表示される。 Terminalポイントを動かしたい場合は、クリックしたまま押さえて移動できる。 Connectorsウィンドウの「Center」「W」「N」「S」「E」のいずれかをクリックして変更することもできる。

Terminalポイントを変更すると、ワイヤーの配置がどう変わるか確認できる

コネクタの種類を変更する

Connectorsウィンドウで、コネクタの種類を変更する。 male、female、padのいずれかから選べる。 SparkFun T5403 Barometer Breakoutの場合、すべてのコネクタピンはfemaleである。

下の画像では、コネクタの種類をmaleに設定した場合とfemaleに設定した場合の違いを確認できる。

上のボードはコネクタの種類がmaleに設定されている。下のボードはfemaleに正しく設定されている。

すべてのコネクタピンで繰り返す

すべてのコネクタピンについて、名前を付け、適切なグラフィックを選択し、コネクタの種類を変更する。 Connectorsウィンドウでは、Internal Connections(内部接続)も設定できる。

Schematicビュー

カスタムSchematic SVG

IllustratorやInkscapeなど、使っているベクターグラフィックスエディタに戻る。 ダウンロードしたFonts and Templatesフォルダにある、FritzingのSchematicViewGraphic_Template.svgを開く。 SparkFun Fritzing PartsのGitHubリポジトリから、SparkFun T5403 Barometer BreakoutのSchematic用SVGテンプレートファイルのサンプルを開くこともできる。

自分のボードに合わせてSchematicを編集する際は、すべてのコネクタピンが表示されていることを必ず確認する。 ピンのラベルは、コネクタピンの名前と一致するよう変更する。 パーツによっては、テンプレートのSchematicのサイズを変更する必要があるかもしれない。 パーツのシンボルとなる四角形と、外側のピンの端の間には0.1インチのスペースを確保しておくこと。

0.1インチの寸法を示す補助ボックスは、最終的なFritzingのSchematicグラフィックに表示されないよう、必ず削除しておくこと

SVGを保存する

新しいSVGとして必ず保存すること。 Fritzingパーツ用に作成する他のSVGファイルと区別しやすいよう、命名規則を決めておくとよい。

Parts EditorでSchematicビューを編集する

SVGを読み込む

Parts Editorに戻り、Schematicボタンをクリックしてschematicビューに移動する。 File→Load image for viewに進む。 続いて、先ほど作成したSchematic用SVGを選択し、Openをクリックする。 これでFritzing(New)Parts Editorにパーツが表示されるはずである。

コネクタピンを設定する

右側のConnectorsウィンドウを見ると、ピンの名前がすでに反映されていることに気づくはずである。 Breadboard、Schematic、PCB、Connectorsのいずれかのビューでコネクタピンの名前や説明を変更すると、Parts Editorが他のビューにも自動的にその変更を反映する。 コネクタの種類(male、female、pad)も同じ設定が保たれる。

Breadboardビューのときと同様に、各ピンにグラフィックを選択する必要がある。 「Select graphic」ボタンをクリックし、そのピンに適したグラフィックを選ぶ。 Schematicビューでは、ワイヤーが最も外側の点で接続されるよう、Terminalポイントを変更するとよい。

これを行う最も簡単な方法は、コネクタピンのグラフィックを選択したまま、Connectorsウィンドウ内でTerminalポイントを変更することである。 GNDのグラフィックの場合、「S」をクリックしてTerminalポイントを南端に移動している。

すべてのコネクタで繰り返す

すべてのコネクタピンを更新したら、PCBビューの編集に進める。

PCBビュー

カスタムPCB SVGの作成

IllustratorやInkscapeなど、使っているベクターグラフィックスエディタに戻る。 カスタムPCB用のSVGを作る際、必要になる主な画像グループは、copper(すべてのコネクタパッドを含む)とsilkscreenである。

PCBグラフィックを作る

PCB用SVGは、まっさらな状態から作り始めてもよいし、カスタムブレッドボードSVGを改変してもよいし、ダウンロードしたFonts and TemplatesフォルダにあるFritzingのPCBViewGraphic_Template.svgを編集してもよい。 この例では、カスタムブレッドボードSVGを改変し、SFE_T5403_Barometer_Breakout_PCB.svgという新しいSVGとして保存した。

copperグループを2つ用意する

レイヤーを設定する際は、必ずcopperグループを2つ用意すること。 すべてのコネクタレイヤーは、このcopperグループの中に入れる。 そうしておくと、Fritzingは、そのコンポーネントがPCBの両面に銅のコネクタを持っていると認識する。

Illustratorでcopperグループを2つ用意した例

コネクタピンの間隔を正確にする

PCBのコネクタピンが自分のボードと正確に一致していること、ピン同士の間隔が適切であることが重要である。 FritzingはPCB Fabサービスを提供している。 自分や他のFritzingユーザーがカスタムパーツでこのサービスを利用したい場合は、PCBビューが正確であることを確認しておく必要がある。

グラフィック標準

PCBビューのコネクタピンは、銅・すず色の緑色ではなく、次の「銅」色を使う。

Hex: F7BD13 RGB: 247 189 19

カスタムブレッドボードSVGからの主な変更点は、主なグループがcopperとsilkscreenになることである。 silkscreenは引き続き白のままでよい。

完成したPCBグラフィック

Parts EditorでPCBビューを編集する

Parts Editorに戻り、PCBボタンをクリックしてPCBビューに移動する。 File→Load image for viewに進む。 続いて、先ほど作成したPCB用SVGを選択し、Openをクリックする。 これでFritzing(New)Parts Editorにパーツが表示されるはずである。

コネクタピンを更新する

BreadboardビューやSchematicビューのときと同様に、各コネクタピンに適したグラフィックを選択する。

Iconビュー

過去のグラフィックを再利用する

Fritzing(New)Parts Editorに行き、Iconボタンをクリックしてiconビューに移動する。 Iconビューのよいところは、アイコン画像として、ブレッドボード、Schematic、PCBのいずれかのSVGを再利用できる点にある。新しく画像を作る必要はない。 Fileに行き、再利用したい画像を選ぶだけでよい。 SparkFun T5403 Barometer Breakoutの場合、Iconビューではブレッドボード画像を再利用している。 ブレッドボード画像が表示されるはずである。

これでIconビューは完了である。

Metadata

Metadataビューに移動する

Parts Editorに行き、Metadataボタンをクリックしてmetadataビューに移動する。 Metadataは、自分のパーツに関する重要な情報をすべて追加する場所である。

Metadataビューの各セクション

Title: 説明するまでもないだろう。パーツの名前になる。

Date: 日付の項目はFritzing側でロックされている。作成日が表示される。後日パーツを更新すると、最後に更新した日の日付に変わる。

Author: ここに自分の名前を入れておくと、Fritzingコミュニティにパーツを共有した際、誰が作ったパーツかがわかる。

Description: 動作電圧など、そのボードについて重要な情報を含めておくとよい。

Label: LabelはSchematicビューに表示され、どのパーツを選択しているかがわかりやすくなる。SparkFun T5403 Barometer Breakoutの場合、Labelは「Part」に変更している。Partという表記はかなり小さく、SparkFun T5403 Barometer Breakoutという名前自体がすでにSchematicのグラフィック上にあるためである。ラベルの内容は自由に決めてよい。

URL: 自分のパーツについてより詳しい情報を得られるよう、パーツのURLを掲載しておくことを検討するとよい。

Family: 色違いやチップパッケージ違いのバリエーションを持つパーツの場合、それらを同じFamilyにまとめておくとよい。たとえば、色違いのスルーホールLEDがある場合、同じLEDの色違いはすべて同じfamilyに入れる。

Variant: 新しいパーツを作成する際は、Variantを1にしておく。同じfamilyの中で後日リビジョンを行うと、次のリビジョンがVariant 2に変わる。

Properties: 部品番号やピン間隔など、重要な詳細情報を記載する場所である。

Tags: 見つけやすく、なるべく少ない言葉で自分のパーツをよく表せるタグを使う。

情報がやや少ないと感じるだろうか。書く内容が増えたら後からいつでも更新できる。

Connectorsビュー

Connectorsビューに移動する

Parts Editorに行き、Connectorsボタンをクリックしてconnectorsビューに移動する。 Connectorsビューでは、次のことができる。

  • コネクタの数を変更する
  • コネクタの種類を設定する
  • コネクタピンをスルーホールかSMDかに設定する
  • コネクタピンに名前を付ける
  • コネクタピンの説明を追加する

他のビューですでに情報を入力し終えているため、Connectorsビューで新たに変更する必要はないはずである。 最後の調整が必要な場合はここで行える。 ここでコネクタの数を変更した場合は、Breadboard、Schematic、PCBの各ビューに戻って更新する必要がある点に注意すること。

保存する

これでパーツを保存できる。File→Saveに進む。

続けてパーツのエクスポートに進もう。

新しいパーツをエクスポートする

Fritzingアプリケーションでの品質チェック

いよいよ、Fritzingのメインアプリケーションで新しいFritzingパーツを確認する番である。 先ほどFritzing(New)Parts EditorでSave as new partをした際、そのパーツはメインのFritzingアプリケーションのMINEタブにある「My Parts」ラベルの下に自動的に表示される。

新しいカスタムパーツをエクスポートする前に、各ビューの見た目を確認しておくとよい。 Fritzing(New)Parts Editorではなく、メインのFritzingアプリケーションにいることを確認する。 上部のBreadboardボタンをクリックしてBreadboardビューに移動する。 右側のPartsウィンドウで、MINEタブにいることを確認する。 自分の新しいパーツが表示されるはずである。 ボードをクリックしてBreadboardビューにドラッグする。

ピンの名前が正しく、正常に動作しているか再確認する。 SchematicビューとPCBビューでも同様に確認する。 品質チェックが済んだら、パーツをエクスポートできる。

パーツをエクスポートする

My Partsウィンドウ内の新しいパーツのアイコンを右クリックし、「Export Part」を選択する。 Fritzingパーツを保存する。

おめでとう。これで自分だけのFritzingパーツができあがった。

まとめ・参考資料

必要なパーツがすでに作られていないか、FritzingソフトウェアやFritzingフォーラムで確認することを忘れずに。 あるいは、SparkFunのリポジトリにあるパーツライブラリを確認してもよい。 また、他の人々がFritzingでどのようにパーツを作っているか、グラフィック標準、テンプレート、命名規則、ファイルの整形方法を知るために、Fritzingのカスタムパーツ作成に関するランディングページも確認しておくとよい。

Fritzingに貢献する

自分のパーツが完成すれば、他のFritzingパーツと接続できるようになる。 Fritzingのサイトで、自分のパーツやプロジェクトのチュートリアルを共有することもできる。 Fritzingコミュニティへの貢献方法は他にもたくさんある。 Fritzingへの支援方法についてさらに詳しくは、Support Usのページを確認してほしい。

大量のFritzingパーツを作りたい場合

EAGLEを使う開発者や、Fritzingパーツの制作にかなりの時間をかけている場合、Fritzingチームは、EAGLEの.brdファイルからSVGファイルを生成するツールキットをオープンソースで公開している。 Fritzing向けのSVGボードファイルをまとめて用意する場合は、ぜひ確認してみることを強く推奨する。 EAGLEからFritzingへの変換ソースコードは、FritzingのGitHubリポジトリで公開されている。

さらに参考になる資料

SparkFunでは、Learnチュートリアルの中でFritzingを多用している。 異なるパーツ同士の接続方法を示すために、さまざまなチュートリアルでFritzingがどう使われているか確認してみてほしい。 Hookupのセクションでfritzingを使っているチュートリアルの例を挙げる。

他のソフトウェアで自分だけのPCBを設計する方法について詳しく知りたい場合は、次のチュートリアルを参照してほしい。

Fritzingについてさらに情報が欲しい場合は、次の関連ブログ記事も参考になる。

パーツをゼロから作らずに済むよう、ベクター画像が必要な場合はElectronic Graphics Resourcesも試してみてほしい。

  • Electronic Graphics Resources — bildr.orgのAdam Meyer氏が作成した、さまざまな電子部品の画像やアイコンを収めたIllustratorファイル

タグ: 電気工学、スキル


出典:Make Your Own Fritzing Parts(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

12V/5V電源の使い方

12V/5V(2A)電源は、マイクロコントローラーとLEDに電力を供給するのに適している。 このチュートリアルでは、この電源のMolexコネクタを、2本のオスのバレルジャックアダプタに置き換える。

必要な部品

このチュートリアルを進めるには、次の材料が必要になる。 手元にあるものによっては、すべてが必要とは限らない。 カートに入れてガイドを読み進め、必要に応じて調整してほしい。 最も簡単に接続できるのは前者のキットで、電源を改造したい場合には後者のリストが向いている。

道具

はんだごて、はんだ、一般的なはんだ付け用アクセサリーに加え、次の道具が必要になる。

  • 各種ワイヤー
  • デジタルマルチメータ
  • はんだ
  • 斜めニッパー
  • はんだ付けステーション
  • ワイヤーストリッパー
  • フラッシュカッター

参考になるチュートリアル

以下の概念に馴染みがない場合は、先に次のチュートリアルを読んでおくとよい。

ハードウェア概要

電源のピン配置を下に示す。 コネクタの成形部分には、接続を識別しやすいよう出力に対応する番号が刻まれているはずである。 また、コネクタの両角が斜めにカットされており、極性を間違えないようになっていることにも気づくはずである。

ピン配置表

警告! メーカーによっては、被膜内部のワイヤーの色が異なることがある。負荷につないで回路の電源を入れる前に、必ずマルチメータで接続を確認すること。

次の表は、ATXコネクタのピン配置と、想定されるワイヤーの色を示している。

ATXピン配置(4ピン)12V/5V電源備考
1+12V「赤」
2N/C接続されていないことがある
3GND「黄」
4+5V「黒(または白)」

ハードウェアの接続

ブレイクアウト基板

4ピンコネクタに簡単に接続するには、ATXパワーコネクタ(4ピン)の使用を推奨する。詳しくはATX Power Connector (4-Pin) Breakout Hookup Guideを確認してほしい。


それ以外の方法として、ケーブルを改造し、好みの極性付きコネクタを使うこともできる。 こちらはより多くの時間と手間がかかる。 以下の画像では旧型の12V/5V電源を使っているため、メーカーによってはワイヤーの色が異なることがある。 4ピンのATXコネクタから1〜2インチほどの位置でケーブルを切断する。

フラッシュカッターで被膜に切り込みを入れる。 ワイヤーを扱うのに十分なスペースができる程度まで被膜を引き戻す。 手を切らないよう注意すること。

電源の3本のワイヤーの被膜を剥く。 これらのワイヤーはより線なので、先端にはんだを流し込んで予備はんだをしておくとよい。

続いて、ジャンパー線を切って被膜を剥く。それをグラウンドのワイヤーにはんだ付けする。

ワイヤーをより合わせ、バレルジャックコネクタに差し込む。 プラスドライバーでねじ端子にワイヤーを固定する。 この段階で、熱収縮チューブや絶縁テープを接続部に加えても構わない。

注意: ねじ端子を使うのは、12V/5V電源を改造する一つの方法である。より確実な接続にしたい場合は、ワイヤーを極性付きコネクタに直接接続し、熱収縮チューブを加えるとよい。好みに応じて、5V側にはUSBコネクタを使うこともできる。

出力をテストする

バレルジャックコネクタでケーブルを改造した場合は、電源を入れてマルチメータで電圧を確認する。 通常、電源はセンタープラスであることが多いため、ワイヤーが正しく挿入されているか確認すること。 自分のシステムに合わせて必要に応じて調整する。

出力にラベルを付ける

バレルジャックコネクタでケーブルを改造した場合は、油性ペンでそれぞれのバレルジャックコネクタに対応する出力電圧を明確にラベル付けしておくことを推奨する。 使わないときのために、追加のバレルジャックを用意しておいてもよい。

回路に電源を入れる

電源を回路に接続し、電源を入れよう。 筆者は個人的に、この電源を基本的な動作テスト用のツールとして使っている。 通常、12V側はArduinoのバレルジャックに接続し、5V出力は、RGB LEDマトリクスや数メートル分のアドレサブルLED(WS2812B、APA102など)といった、より電力を必要とする負荷に使っている。

12V/5V電源で駆動するArduino Mega 2560と32x64 RGB LEDマトリクス

トラブルシューティング

電源によっては、ノイズがかなり多いものもある。 12V/5V電源はマイクロコントローラーとLEDストリップの組み合わせでは問題なく動作するが、メーカーによっては、そこに静電容量式のタッチセンサーを組み合わせると期待どおりに動作しないことがある。 2電圧出力の電源の中には、適切なフィルタリングが不足しているものがあり、静電容量式タッチポテンショメータに大きな遅延を引き起こすことがある。 使っている電源にノイズが多い場合は、追加の回路を組んで対策することもできる。

新しい12V/5V電源(TOL-15664)では、この問題は見られないはずである。 以前のバージョンより信頼性が高い。 それでも問題が出る場合は、電源を2つに分けて使う、あるいはMeanwellのようなより堅牢な電源を使うことも検討してほしい。

警告! メーカーによっては、2電圧出力の電源に適切なフィルタリングが備わっておらず、Touch Potentiometerの動作を大きく乱すことがある。以前の12V/5V電源(TOL-11296)でこの現象を確認している。旧型の電源をTouch Potentiometerと組み合わせて使うことは推奨しない

Touch Potentiometer Hookup GuideによるPWM照明コントローラーの例

まとめ・参考資料

12V/5V電源を無事に動かせたら、次は自分のプロジェクトに組み込む番である。

より詳しい情報は、以下の資料を参照してほしい。

次のプロジェクトのヒントとして、12V/5V(2A)電源を使った次のようなチュートリアルも参考になる。

  • RGB Panel Hookup Guide — 32x16、32x32、32x64のRGB LEDマトリクスパネルを使い、明るくカラフルなディスプレイを作る。これらのパネルの接続方法とArduinoでの制御方法を解説している
  • Large Digit Driver Hookup Guide — Large Digitディスプレイドライバー基板の使い始め方。大型の7セグメントLEDディスプレイの裏にモジュール(バックパック)をはんだ付けし、Arduinoからサンプルコードを実行する方法を説明する
  • How to Build a Remote Kill Switch — 事態が「自我に目覚めた」ときに電源を落とせる、ワイヤレスコントローラーの作り方
  • Building a Safe Cracking Robot — 未知の金庫を1時間以内に開錠する方法

電源についての、次のようなブログ記事も参考になる。

タグ: Hookup、電源


出典:12V/5V Power Supply Hookup Guide(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

KiCad入門

EAGLE PCBからKiCadへの移行を決めた人にとって、その変化はかなり戸惑うものになりうる。 EAGLEには数々の癖や粗さがあり、筆者自身2005年に初めて学んだときにはきっと悪態をついていたはずである。 それ以来、EAGLEは筆者にとって第二言語のようなものになり、苦労した部分はすっかり忘れてしまった。 KiCadへ移行する際は、休憩を取り、深呼吸することを忘れないでほしい(そして頭の中で「キー・キャド」と発音してみてほしい)。 すぐにKiCadの夢を見るようになるはずである。

このチュートリアルでは、回路図の作成からPCBレイアウトまで、KiCadのサンプルプロジェクトを一通り説明する。 ライブラリのリンク、編集、作成にも触れる。 さらに、ボードを製造できるようPCBをガーバーファイルとしてエクスポートするところまで扱う。

このチュートリアルは初心者向けだが、「回路図コンポーネント」や「ポリゴンポア」といった用語もそのまま使う。 意味がわからなくても問題ない。少し検索してみてほしい。 本当に行き詰まった場合は、右側のコメント欄を利用してほしい。 チュートリアルをよりわかりやすくするため、常に改善に努めている。

KiCadのプロジェクトウィンドウ

KiCadのダウンロードとインストール

注意: このチュートリアルはWindows 10上のKiCad 4.0.6を使って書かれている(つまり、このバージョンを使うと同じ手順で進められる)。

v5での回避策: より新しいバージョンのKiCadを使ってこのチュートリアルを手順どおりに進めようとすると、必ず何らかの問題に突き当たる。とはいえ、ある顧客が親切にもv5向けのさまざまな回避策を提供してくれており、同じ道をたどる人には参考になるはずである。詳しくはコメント欄を確認してほしい。

KiCad(v5)については、次のような他のチュートリアルも参考になる。

それでは始めよう。KiCadのダウンロードページへ行き、自分のプラットフォーム向けの最新版ソフトウェアをダウンロードする。

警告: KiCadソフトウェアをダウンロードする際は、ドメインが必ずkicad.orgであることを確認すること。KiCadをインストールする際は、必ずインストーラーの署名を確認してほしい。KiCadバージョン5.99以降、すべてのインストーラーはKiCad Services Corporationによって署名されている。

詳しくは、KiCad開発者の一人によるKiCadフォーラムの注意喚起や、Hackadayの記事を参照してほしい。

KiCadを実行する

インストールが終わったら、KiCadを実行する。 メインのナビゲーションウィンドウが表示され、そこから回路図キャプチャやPCBレイアウトといった周辺プログラムをすべて開けるようになる。

画像をクリックすると拡大表示できる

KiCadのプロジェクトウィンドウは、かなり空っぽで寂しく見える。 さっそくサンプルを開いてみよう。

プロジェクトのセットアップ

もともとSparkXで設計されたZOPT2201 UVセンサーは、優れたI2C UVインデックスセンサーであり、このチュートリアルの出発点として使う。 KiCad用のZOPT220x UV Sensor Breakoutの設計データをダウンロードし、4つのファイルをローカルディレクトリに解凍する。

注意: 筆者は...\Dropbox/Projectsフォルダを中心に作業しているため、画像の多くにこのファイル構造が写っている。この構成のおかげで、ノートパソコンと仕事用パソコンの間を面倒なく同期できる。

4つのファイルがローカルディレクトリに置かれたら(ダウンロードフォルダの...\ZOPT220x_UV_Sensor_Breakout-Tutorialを探してみてほしい)、File → Open Projectをクリックし、ZOPT220x UV Sensor Breakout.proファイルを開く。

画像をクリックすると拡大表示できる

これらのファイルはいったい何だろうか。

  • *.pro — ファイル構造を管理するメインのプロジェクトファイル。
  • *.cmp — どのフットプリントがどの回路図コンポーネントと対応するかを定義する。
  • *.kicad_pcb — PCBレイアウト。
  • *.sch — 回路図。

この4つのファイルさえあれば、共同作業者とKiCadの設計データを共有できる。 フットプリントファイルの共有も必要になることがあるが、これについてはこのチュートリアルの後半で説明する。

ここで最初の「本当にこれでいいのか」という疑いの目を向けたくなったかもしれない。 なぜ、どのフットプリントがどの回路図コンポーネントと対応するかを定義する専用のファイルがあるのだろうか。 これはKiCadの根本的な仕組みであり、EAGLEの動作とはまったく異なる。 悪いことではなく、単に違うだけである。

回路図コンポーネントライブラリのセットアップ

回路図ファイルを、KiCadのEeschema回路図エディタでダブルクリックする。 おそらくエラーが出るはずである。

今は無視してよい。Closeをクリックする。

回路図が読み込まれると、数多くのコンポーネントにクエスチョンマーク(??)が表示される。 KiCadは、この回路図内のデバイスへのリンクを見失っている。 これをリンクさせよう。

Eeschemaでコンポーネントライブラリをリンクする

EeSchemaの中で、Preferences → Component Librariesをクリックする。 新しいウィンドウが開く。 下の画像を見ると、プロジェクトファイルには「コンポーネントライブラリファイル」をどこで探すべきかという情報が含まれていることがわかる。 プロジェクトごとに、異なるファイル構造への接続情報を個別に持っている。 このプロジェクトに、この回路図で使うシンボルの場所を教える必要がある。

SparkFun_SchematicComponents.libファイルが必要になる。ダウンロードしてローカルディレクトリに保存する。

KiCadのウィンドウで、上部のAddボタンをクリックする。 自分だけの回路図シンボルを作る方法については、この後すぐに説明する。

SparkFun_SchematicComponents.libファイルを保存したディレクトリに移動し、Openをクリックする。 このファイルには、すべての回路図コンポーネントが含まれている。

SparkFunの回路図コンポーネントライブラリファイルを追加すると、リストに追加されているのが確認できるはずである。

注意深い人は、ウィンドウ内のディレクトリ構造がわずかに異なることに気づくかもしれない。

C:\Users\Nathan...

C:\Users\nathan.seidle...

これは、筆者の自宅のPCと仕事用のPCの違いである。 この回路図を開く際に将来のエラーを避けるため、有効なライブラリファイルの一覧からこのエントリを削除しておこう。 リストからC:\Users\Nathan...のエントリをハイライトし、Removeボタンをクリックする。

OKをクリックし、Component Librariesマネージャーを閉じる。 これで、回路図を一度閉じて再度開き、更新する。

おめでとう。**??**のボックスがなくなった。 複数のコンピュータをまたいで回路図コンポーネントライブラリを使う方法について詳しくは、次の「ユーザー定義の検索パス」の節を確認してほしい。 そうでなければ、いよいよ回路図の編集に進もう。

ユーザー定義の検索パス:複数のコンピュータでコンポーネントライブラリを使う

回路図コンポーネントライブラリは、KiCadのComponent Library Managerを使って割り当てられる。 筆者のように、複数のコンピュータで回路図ライブラリを共有している場合は、「ユーザー定義の検索パス」を追加しておくと便利である。

画像では、筆者は「....\SparkFun-KiCad-Libraries」を定義している。 これは、Dropboxフォルダへのローカルな相対パスである。 これらのコンポーネントライブラリのパスは、このプロジェクトと*.pro*ファイルに固有のものである。 このプロジェクトをノートパソコンで開くと、まず「C:\Users\nathan.seidle...」の場所を探しに行く。 それが失敗すると、続けて「..\SparkFun-KiCad-Libraries」という相対パスを探し、そこでファイルを見つける。 これにより、コンピュータやGitHubリポジトリをまたいでライブラリを共有でき、別のコンピュータでプロジェクトを開くたびにライブラリを再割り当てする必要がなくなる。

とりあえず今はこのままチュートリアルを進めてよい。 複数のコンピュータでKiCadを使うようになったら、後で見直すとよいだろう。

回路図の編集

他に何も伝えられなかったとしても、キーボードショートカットだけは覚えてほしい。 もちろん対応するボタンをクリックしてもよいが、KiCadの速さと効率のよさは、体が動きを覚えたときに真価を発揮する。ぜひ覚え始めてほしい。 このチュートリアルで頻繁に使う、KiCadのEeschemaのキーボードショートカットを紹介する。

  • a — コンポーネントを追加する。
  • c — カーソルが別のコンポーネントの上にあるとき、そのコンポーネントをコピーする。
  • w — コンポーネント同士を配線する。
  • v — コンポーネントの値を編集する。
  • Esc — 進行中のモードやコマンドを中断し、通常のポインタモードに戻る。
  • ctrl+z — 元に戻す。ミスをしたら遠慮なく使う。
  • ctrl+s — 保存する。こまめに保存すること。

注意: すべてのホットキーの一覧を見る、あるいは編集するには、Preferences → Hotkeysに進む。

このブレイクアウトボードには、(筆者がそう決めたので)より大きな4.7uFのデカップリングコンデンサが必要である。追加してみよう。

回路図にコンポーネントを追加する

aキーを押し、回路図にデバイスを追加する。 これによりコンポーネントウィンドウが開く(別のツールを使っている場合、回路図の方もクリックする必要があるかもしれない)。

数百種類のコンポーネントがある(タイトルバーによれば668項目)。 自由に探し回ってもよいが、必要なものを素早く見つけるには、**Filter:**のフィールドに「cap」と入力する。 deviceライブラリから、C_Smallというラベルのデバイスを選択する。 続けてEnterキーを押すか、OKをクリックする。

0.1uFのコンデンサの隣に、回路図上に配置する。

コンデンサを配置した後も、配置モードのままであることに気づくはずである。 キーボードのEscキーを押し、通常のポインタモードに戻る。 筆者は、確実にデフォルトの状態に戻すため、Escapeを2回押すことがよくある。

コンポーネントをコピーする

デフォルトの状態になったら、マウスポインタを0.1uFのコンデンサの3.3Vマーカーの上に置く。 cキーを押してそのデバイスをコピーし、新しいコンデンサの上に配置する。

グラウンドマーカーについても同じ手順を行う。 ctrl+sキーを押して作業を保存する。

コンポーネントを配線する

これらを配線でつなごう。 予想どおりwキーを押すが、一つ注意点がある。wを押す前に、マウスポインタをどちらかのバブルの上に置いておく必要がある。

マウスをもう一方のバブルに移動し、左クリックしてGNDの配線を完了させる。 もし失敗したら、Escを1〜2回押してデフォルトの状態に戻せることを覚えておいてほしい。 続いて、接続したいバブルにマウスポインタを移動し、wを押して3.3Vの配線を始める。 ショートカットのwはwire(配線)の頭文字である。

何かうまくいかないことがあれば、遠慮なくctrl+zでミスを元に戻してほしい。

これで、電源とグラウンドがコンデンサに接続された。

コンポーネントの値を変更する

値をC_Smallから4.7uFに変更しよう。 マウスポインタをC_Smallの上に置き、vキー(valueの変更)を押す。 TextフィールドのC_Small4.7uFと入力して変更する。 続けてEnterキーを押すか、OKをクリックする。

おめでとう。これで最初の回路図コンポーネントの配線が完了した。 ctrl+sを押して作業を保存する。

回路図コンポーネントに注釈を付ける

しかし、**C?**という記号はどうなるのだろうか。心配は要らない。 KiCadの数多くの利点の一つが、回路図を自動的に注釈付けできる機能である。

Annotate schematic componentsボタンをクリックする。

デフォルトの設定のまま、Annotateボタンをクリックして確定する。

注釈付けを確認するKiCad

KiCadから確認を求められるので、そのままEnterキーを押すか、もう一度OKをクリックする。

正しい値と識別子を持つコンデンサができた。これで準備は完了である。いよいよPCBを編集する番だ。

PCBレイアウトの編集

PCBの編集を始める前に、このチュートリアルで頻繁に使う、KiCadのPcbnewのキーボードショートカットを紹介する。

  • + — 次のレイヤーに切り替える。
  • - — 前のレイヤーに切り替える。
  • m — アイテムを移動する。
  • b — グラウンドのポリゴンポアを更新する。
  • Delete — トレースやコンポーネントを削除する。
  • x — 新しいトラックを配線する。
  • v — スルーホールビアを追加する。
  • n — 次のグリッドサイズに切り替える。慎重に使うこと。50milか25mil以外のグリッドを使うと、後で痛い目にあう。
  • Page Up — 最上位の銅箔レイヤーに戻る。
  • Esc — 進行中のモードやコマンドを中断し、通常のポインタモードに戻る。
  • ctrl+z — 元に戻す。ミスをしたら遠慮なく使う。
  • ctrl+s — 保存する。こまめに保存すること。

注意: すべてのホットキーの一覧を見る、あるいは編集するには、Preferences → Hotkeysに進む。

ネットリストを生成する

回路図はできたので、新しい4.7uFのコンデンサをボードに配置しよう。 回路図からGenerate netlistボタンをクリックする。

次のようなウィンドウが表示される。

KiCadは強力である。そしてその強力さゆえに、膨大な数のオプションが用意されている。 幸い、今回はまだ表面をなぞっているだけなので、これらのオプションをいじる必要はない。 そのままEnterキーを押すか、Generateをクリックしてこの画面を確定する。 KiCadは、ネットリストを**.net**ファイルとしてどこに保存するか尋ねてくる。デフォルトの場所はプロジェクトフォルダである。 ここでも、Enterキーを押すか、Saveをクリックして確定する。

レイヤーの色を設定する

メインのプロジェクトウィンドウに戻り、.kicad_pcbファイルをダブルクリックする。

PCB編集の世界へようこそ。 EAGLEとKiCadの違いの中でも、PCBレイアウト内の見た目には筆者も最も戸惑わされた。 Viewメニューには、他に3種類の表示、DefaultOpenGLCairoがある。 筆者はOpenGLを好んで使っている。 とりあえずSwitch Canvas to OpenGLに切り替えておこう。

マウスホイールは期待どおりに動作する。拡大縮小はホイール、クリックでパンできる。

このレイヤーの色は好きじゃない! そう、筆者も同感である。 レイヤーの色を変更するには、右側のメニューでB.Cu(下面銅箔レイヤー)の隣にある緑色の四角をマウスホイールでクリックする。 筆者は次のレイヤーの色を好んで使っている。

  • F.Cu(上面銅箔):Red 2(デフォルト)
  • B.Cu(下面銅箔):Blue 4
  • F.SilkS(表面シルクスクリーン):White
  • B.SilkS(裏面シルクスクリーン):Yellow 3
  • Edge.Cuts(EAGLEでいうボードの輪郭や寸法レイヤーに相当):Gray 3
  • F.CrtYd(そのコンポーネントが上面で必要とするボード上の総スペースを示す):Gray 2(デフォルト)

**+-**を押すと、上面と下面の銅箔レイヤーを切り替えられる。 特定のレイヤーを確認したいときに便利である。

見た目だけの話ではあるが、こうしたレイヤーの色分けのおかげで、何が起きているかを把握しやすくなる。

(Layerタブの隣にある)Renderタブ、特にValuesReferencesのチェックボックスもぜひ確認してほしい。

筆者は、ValuesReferencesをオンにするとかなり気が散ってしまうため、常にオフにしている。 多くの設計者はこれらの値を頼りに作業しているので、必要に応じて使ってほしい。

フットプリントを追加する

ボードに4.7uFのコンデンサを追加するはずでは? どこにあるのだろうか? 残念ながら、どこにもない。

何が起きているのだろうか。 回路図に追加したコンデンサに、フットプリントを割り当て忘れているのである。 KiCadは、EAGLEのような形で回路図コンポーネントとフットプリントをリンクしないことを思い出してほしい。 追加した回路図コンポーネントそれぞれに、フットプリントを個別に接続する必要がある。

回路図に戻り、Run CvPcbボタンをクリックして、コンポーネントとフットプリントを関連付ける。

CvPcbを初めて実行する場合、次のような警告が出る。

そのままクリックして進めばよい。

インストールされているライブラリの数によっては、これに最大30秒程度かかることがある。 このチュートリアルの後半でこれを速くする方法を紹介するが、今のところは辛抱してほしい。

左側の列には、KiCadに同梱されているすべてのフットプリントライブラリが表示される。 中央には、自分の回路図に含まれるコンポーネントの一覧が表示される。 右側には、中央でハイライトされたコンポーネントに合いそうなフットプリントが表示される。 中央のコンポーネントに対応する、右側のフットプリントをダブルクリックするのが作業の内容である。

作業を楽にするため、View selected footprintボタンをクリックする。

これで、右側のリストをクリックしながらフットプリントをプレビューできるようになる。

Windowsでは、Windowsキーを押したまま左矢印キーを押して離すと、CvPcbウィンドウを画面の片側に固定できる。 続けて、Footprint Previewウィンドウを選択し、右側に固定する。 これにより、左側のウィンドウでフットプリントを切り替えながら、右側でプレビューを確認できる。

中央の列でC2をハイライトする。 続いて、右側の列にあるCapacitors_SMD:C_0603をダブルクリックする。 これでC2にフットプリントが割り当てられるはずである。

ネットリストを再生成する

CvPcbウィンドウを閉じ、Save and Exitをクリックする。 ネットリストを再度エクスポートする必要がある。方法を覚えているだろうか。 もう一度Generate netlistボタンをクリックし、Enterを2回押す。 回路図またはプロジェクトウィンドウのどちらからでもよいので、PCBエディタを開く。

あれ、まだ表示されていない! データを変更したので、ネットリストをインポートし直す必要がある。方法を覚えているだろうか。 Read netlistボタンをクリックすると、次のようなウィンドウが表示されるはずである。

Read Current Netlistをクリックし、確認のためYESをクリックする。 Enterを2回押してもよい。 これで、ボードの近くに新しいコンデンサが表示されるはずである。

これはデカップリングコンデンサなので、すでに配置されている0.1uFのコンデンサの隣に置こう。 まず、新しいコンデンサにマウスポインタを合わせ、m(移動)を押す。

左クリックしてコンデンサを配置する。 続いて、邪魔になっている0.1uFのコンデンサの上でmを押し、左に移動する。

bを押し、GNDのポリゴンポアを更新する。

いくつかトレースを修正する必要があるが、それほど大変ではない。 削除したいトレースの断片にマウスポインタを合わせ、Deleteを押す。 コンデンサの+3v3端子の下にあるトレースとビアを削除しよう。 ポインタが複数のアイテムの上にある場合(下の画像のように、カーソルがトレースとコンデンサの両方の上にある場合)、KiCadはメニューをポップアップ表示し、どちらを選ぶか尋ねてくる。 これは基本的に、どちらを操作したいのかを選ぶよう求めているものである。

何か問題が起きたら、Escを押して通常のポインタモードに戻る。 何か間違って削除してしまった場合はctrl+zを押す。

問題のあるトレースの大半を取り除いたら、xを押して配線を始められる。

なぜ追加した0603フットプリントは、ボード上のものと一致しないのか? SparkFunは、長年にわたり自社の製造工程に合わせてPCBフットプリントを微調整してきた。これには、ピック&プレースや自動光学検査も含まれる。特に不思議なことではなく、私たちの環境ではやや大きめの0603フットプリントが最もうまく機能することがわかっている。KiCad付属のフットプリントと、自社で用意したフットプリントの両方を組み合わせて使っている。このチュートリアルの目的においては、気にする必要はない。このフットプリントで問題なく動作する。

灰色のエアワイヤーがあるパッドをシングルクリックし、接続先のパッドまでドラッグする。 もう一度シングルクリックして、その位置に配線を固定する。 bを押してポリゴンを更新する。

下の画像では、KiCadがこのトレースを妙な形で配線しようとしている。 ここにトレースを置くと鋭角ができてしまい、一般によくない(「アシッドトラップ」について調べてみてほしい)。 このトレースはT字の交点にしたい。グリッドを変更する必要がある。

これは煩わしい!

nを押し、次のグリッドサイズに切り替える。 筆者の場合、この見栄えのよい交点を得るにはnを1回押して0.25milグリッドに切り替えるだけで済んだが、もっと細かいグリッドが必要になることもある。 これはメニューの「Grid: 0.0635mm (2.5mils)」からも確認できる。

強く推奨する。 50mil25mil以外のグリッドは使わないでほしい。そうしないと、後で痛い目にあう。すべてのコンポーネント、ビア、トレース、ボードの輪郭は、必ず50milか25milのグリッドに乗せなければならない(シルクスクリーンは話が別である)。

きれいなT字の交点!

下の画像では、GNDのエアワイヤーを配線している。 ポリゴンポアが2つのパッドをつなげてくれるため、これは本来必要ないが、KiCadの「磁力」による配線支援がどれだけ優れているかがよくわかる。 パッドからパッドへ、非常にすばやく簡単に移動できる。

残るエアワイヤーは2本である。 これらをつなぐには、下面レイヤーへのビアを配置する必要がある。 まずxを押し、コンデンサのGND用エアワイヤーの起点を再度クリックする。

トレースを引き出す。

開けたグラウンドに到達したら、vを押してビアを作成する。 シングルクリックしてビアを配置すると、KiCadは自動的に下面レイヤーでの配線を開始する。 Escを押してトレースの配置を止める。あとはポリゴンポアが処理してくれる。 Page Upを押すと、最上位レイヤーに戻る。

エアワイヤーが残り1本!

最後のエアワイヤーを処理するため、0.1uFコンデンサのGNDパッドをクリックしてみようとしても、なぜかKiCadは配線を始めてくれない。なぜだろうか。 実はこれはよいことである。SDAのトレースが、0.1uFコンデンサのGNDパッドに近すぎる(実際には重なっている)のである。 配線を始めさせないことで、KiCadは、ここにトレースを置くとDRCルールに違反すると教えてくれているのである。 どうすればよいだろうか。SCLとSDAのラインを一度引き剥がしてスペースを作る。

なるほど、これでずっとよくなった。 xを押し、コンデンサのGND端子をクリックしてトレースを引き出し、vを押してこのあたりにビアを落とす。 Escapeを押して配線を止める(あとはポリゴンに任せる)。 最後にPage Upを押して最上位レイヤーの表示に戻る。

Deletexボタンを使ってSDAとSCLのラインを配線し直し、このボードを仕上げる。 続いてbを押してポリゴンを更新する。 ボードは下の画像のような見た目になるはずである。

エアワイヤーなしで配線完了!

おめでとう。フットプリントの配線が完了した。 それでは、法律違反(DRCエラー)がないかDRCを実行してみよう。

コンポーネントのフットプリントをPCBレイアウトから削除する方法

続ける前に、PCBレイアウトからコンポーネントを変更・削除する手順を確認しておこう。 たとえば、設計から余分なコンデンサや抵抗を取り除きたいとする。 その場合、通常は次の手順を行う。

  1. 回路図からデバイスを削除する。
  2. Generate netlistボタンをクリックし、ネットリストをエクスポートする。
  3. Read netlistボタンをクリックし、PCBレイアウトにネットリストをインポートする。

違うのは、いくつかのインポート設定だけである。

ネットリストのインポート時、デフォルト設定では、交換用フットプリントはKeep、余分なフットプリントもKeepになっている。

ここでは、2つの設定を変更する必要がある。

  • Exchange Footprint → Change:フットプリントの変更を許可する
  • Extra Footprints → Delete:残っている余分なフットプリントを削除する

削除したコンポーネントから残った未接続のトラックを片付けるため、Deleteで未接続のトラックも削除しておくとよいだろう。

デザインルールチェックの実行

緑のチェックマークが付いたテントウムシのアイコンをクリックし、Design Rule Check(DRC)ウィンドウを開く。

注意: すべてのDRC設定はミリメートル単位である。インチ単位で見たい場合は、このウィンドウを閉じ、PCBレイアウトウィンドウの左側のツールメニューにあるinボタンをクリックする。これですべての単位がインチに変わる。DRCウィンドウを再度開けば、ヤード・ポンド法の単位で設定を変更できる。

トレース幅、トレース間隔、ビアについて少し話しておこう。 一般に、SparkFunは次の仕様でボードを設計している。

  • 10milのトレース幅
  • 10milのトレース間隔
  • 20milのビア

多くの設計ではこれよりも小さくすることもあるが、初めてPCBを設計するのであれば、4milのトレースと8milのビアで設計してはいけない。 最初のボードで、そこまで小さくする必要はないはずである。

同じ価格でファブハウスが8mil以下に対応しているのに、なぜ10milのトレース・間隔で設計するのか

PCBの製造は繊細な作業であり、許容誤差を一段階削るごとに、(試作かどうかにかかわらず)そのPCBがエラーとともに製造されてしまう可能性が高まる。 そして、そうしたエラーは見つけにくいことがある。 私たちが10milのトレース・間隔で設計しているのは、生産現場でエラーのあるPCBに遭遇する確率を抑えるためである。 不具合のある製品のトラブルシューティングをしていて、「本に書いてあるリワークとはんだ付けの技はすべて試した。まさかPCB自体が不良なのだろうか」と自問するほど嫌なことはない。

とはいえ、多くのPCBファブハウスが、7milのトレース・間隔と12milのビアを低価格で提供するようになってきている。 配置に厳しい制約のある複雑なボードを扱っているなら、より小さいトレース・間隔とビアを使う方がよい。 レイアウトの時間を節約し、ボードを正しく製造する部分はPCBファブハウスに任せてしまおう。

一般に、次のKiCadのデフォルト値を使っている。

  • Clearance: By Netclass
  • Min Track Width: 0.2mm = 7.9mil
  • Min Via Size: 0.4mm = 15.7mil

もう一度Enterを押し、デフォルト設定でDRCを実行する。

ErrType():Via near track

しまった! ボードの何が問題なのだろう? 赤い矢印で示されたビアが、近くのトレースに近すぎる。 エラーメッセージには「Via near track」というエラーが表示される。 ビアの近くにあるトレースを一度引き剥がし(Deleteを押す)、配線し直す(xを押す)ことで修正できる。

問題を起こしていたトレースを調整したら、DRCを再度実行する。 先ほどの3つのフラグが消えているはずである。

DRCマーカーがクリアされた

おめでとう。「Via near track」の問題を修正できた。

ErrType():Pad near pad

しかし、まだ終わりではない。 「Pad near pad」というエラーを示すDRCエラーの矢印がまだ2つ残っている。 KiCadは、このソルダージャンパーのパッド同士が近すぎることを伝えようとしている。 SparkFunはこのフットプリントを長年使っており、この設計に問題がないことを把握しているので、Netclassのクリアランス制約の方を変更しよう。

Design Rulesメニューから、DRCのルールを開く。

ここで、特定のトレースやトレースのクラスごとに固有のルールを作成できる。 ここで起きている問題は、DefaultClearanceが7.9mil(0.2mm)になっていることである。 これを7mil(0.1778mm)に減らし、OKをクリックしてDRCを再実行すると……

DRCエラーが解消された。 とはいえ、ボードをDRCに通すためにDRCのクリアランスを小さくするのは、理想的な解決策とは言えない。 このソルダージャンパーのパッドは、はんだで簡単にジャンパーできるよう近い距離を保っておきたいため、フットプリント上のパッド間の距離を広げるのは逆効果になる。 一般に、DRCのルールはあらかじめ決めておき、それを守り続けるべきである。

エアワイヤーに気を付ける

DRCについて最後にもう一つ。 PCBにエアワイヤーを残したままにしておくと、ほぼ確実に使い物にならないPCB(いわゆる「コースター」)ができあがる。

DRCウィンドウにはList Unconnectedボタンがある。 これをクリックすると、未接続のトレースの位置がすべて表示される(このエラーを表示するため、あえてPCB右下のSDAトレースを引き剥がした)。 PCBを発注する前に、エアワイヤーがないか確認することは非常に重要である。 レイアウトを進める中では、画面下部の(ピンク色で囲んだ)「Unconnected」の数に注目することを推奨する。 配線が終わったつもりでも、見つけられない未接続のワイヤーがいくつか残っている場合、DRCウィンドウがその場所を見つける手助けをしてくれる。

ctrl+sを押して作業を保存する。

よくできた。これでデザインルールチェックを乗り越えた。いよいよボードを発注する番である。

ガーバーファイルのエクスポート

回路図にコンポーネントを追加し、PCBレイアウトを修正し、エラーを確認した。 これで自信を持ってボードを製造してもらう準備が整った。ガーバーファイルをエクスポートしよう。

ドリルファイルとガーバーファイルを生成する

ガーバーファイルは、PCB製造会社がボードを組み立てる際に使う「アートワーク」、つまり各レイヤーのデータである。 PCBの各レイヤーについては優れたチュートリアルがあるので、この内容が初めての場合はぜひ読んでおいてほしい。

上部バーのプリンタアイコンの隣にあるPlotボタンをクリックし、Plotウィンドウを開く。

一般に、PCBを製造してもらうには8種類のレイヤーが必要になる。

  • 上面銅箔(F.Cu)+ ソルダーマスク(F.Mask)+ シルクスクリーン(F.SilkS)
  • 下面銅箔(B.Cu)+ ソルダーマスク(B.Mask)+ シルクスクリーン(B.SilkS)
  • ボードの輪郭(Edge.Cuts)
  • ドリルファイル

Plotウィンドウで、Plot formatをGerberに設定した状態で、次のLayersにチェックが入っていることを確認する。

  • ☑ F.Cu
  • ☑ B.Cu
  • ☑ B.SilkS
  • ☑ F.SilkS
  • ☑ B.Mask
  • ☑ F.Mask
  • ☑ Edge.Cuts

さらに、Generate Drill Fileボタンをクリックする。 ここもデフォルトの設定のままでよい。PTHとNPTHのチェックボックスについては後ほど説明する。 今はDrill Fileをクリックするか、Enterを押してドリルファイルを生成するだけでよい。

「Drill Files Generation」ウィンドウでCloseをクリックする。

Plotをクリックして各レイヤーのガーバーファイルを生成し、続けてCloseをクリックする。

ガーバーファイルを確認する時間

実際のお金を払う前に、エラーを見つけられる最後のチャンスである。 ガーバーの各レイヤーを見直すと、ファブに送る前に潜在的なエラーや問題に気づけることが多い。

メインのKiCadプロジェクトウィンドウに戻り、ボタンをクリックしてGerbViewを開く。

注意: ガーバービューアーには数多くの選択肢がある。筆者はGerbvを好んで使っているが、KiCad付属のビューアーもよくできているので、ここではそちらを扱う。

KiCadのGerbViewが開いたら、File → Load Gerber Fileをクリックする。 表示されたファイルをすべて選択し、Openをクリックする。

続いて、File → Load EXCELLON Drill Fileをクリックする。 表示されたドリルファイルをすべて選択し、Openをクリックしてドリルファイルを読み込む。 同じディレクトリにあるはずである。

レイアウトはかなり異なる見た目になるが、これはよいことである。 自分のデザインを何時間も見続けていると、脳が問題を見落としやすくなる。 筆者は基本的に、必要のない限りレイヤーの色は変更しない。 ガーバーの確認は、普段のレイアウト作業とは違う、目に刺さるような見た目にしておきたい。その方が問題に気づきやすくなるからである。

この画面から、Top Copper(layer 5)以外のすべてのレイヤーをオフにする。 さらにRenderメニューから、GridDCodesをオフにする。 これで確認作業がすっきりする。

続いて、各レイヤーのオン・オフを切り替えながら順に見ていく。 不規則な部分やおかしく見える箇所を探す。 筆者が確認しているポイントをいくつか紹介する。

  • 妙な配線になっていて改善できそうなトレースはないか
  • ビアは、あるべき場所で上面銅箔と正しく重なっているか
  • 上面のソルダーマスクは、SMD ICのフットプリントと整合しているか
  • ビアはソルダーマスクで覆われている(いわゆる「テンティングビア」)か、それとも露出しているか
  • 上面のシルクスクリーンは見た目がよいか。意味が通っているか。すべて意図どおりに揃っているか。ピン1の目印は明確か

すべてオフにしたら、今度は下面のレイヤーについて同じことを繰り返す。

気づいただろうか。このサンプルには、いくつか問題がある。

  1. 下面のシルクスクリーンに、GNDの表示が抜けている。
  2. 上面のGNDシルクスクリーンの表示がイタリックになっている。
  3. なぜかドリルファイルが2つある。

シルクスクリーンの表示が一つ抜けていてもボード自体が壊れるわけではないが、こうした小さな不具合を見つけるのが、まさにガーバーの確認作業の目的である。

しまった。下面のGND用シルクスクリーンが抜けている!

演習: 少し時間を取り、PCBレイアウトのウィンドウに戻って次の修正を行ってみてほしい。

  • 下面レイヤーにGND用のシルクスクリーンを追加する。 Pcbnewで下面のシルクレイヤー(B.SilkS)を選択する。Place → Textをクリックし、Text:フィールドに「GND」と入力してOKをクリックする。下面のシルクスクリーンレイヤーのテキストを右クリックしてDuplicateを選択し、GNDパッドの隣にテキストを配置してコピーすることもできる。テキストを右クリックしてPropertiesを選び、内容を変更してGNDに書き換え、OKをクリックすることを忘れずに。
  • 上面のGND表示を、イタリックでないように変更する。 テキストのプロパティを編集し、Style:Normalに変更する。
  • 新しいガーバーファイルをプロットする。
  • GerbViewで修正内容を確認する。

さて、次はドリルファイルが2つある問題に対処しよう。

PTHとNPTH

このデザインのドリルファイルを生成した際、2つのファイルが生成された。

  • *.drl — PCBファブハウスに送る必要がある標準のEXCELLONドリルファイル。
  • *-NPTH.drl — 非めっきスルーホール用のドリルファイル。

非めっきスルーホールとは、穴の垂直な壁面が銅で覆われていない穴のことである。 これは、徹底した電気的絶縁が必要な高度な設計で必要になることがあるが、まれである。 一方でめっきスルーホール(PTH)は一般的で安価だが、NPTHはPCB製造工程に追加のステップが必要になり、しばしば追加コストがかかる。

このデザインにNPTHは不要なのに、なぜこうなったのだろうか。 「STAND-OFF」フットプリント(ボード上部の取り付け穴用のドリル穴に使われるもの)はSparkFunのEagleライブラリからインポートされたもので、なぜかKiCadはこれを非めっき穴だと認識してしまっているようである。

これを修正するには、PCBレイアウトに戻り、Plotterをクリックし、「Generate Drill File」をクリックして、「Merge PTH and NPTH holes into one file」のチェックボックスを選択する。 後のセクションで、「STAND-OFF」フットプリントを通常のPTH穴として使うよう編集する方法を説明する。

ソルダーペーストのステンシル

SMDのリフローはんだ付けを行うだろうか。 ボードにソルダーペーストを塗布するためのステンシルを発注する必要があるだろうか。 Plotウィンドウで F.Paste をオンにすると、上面のペーストレイヤーを生成できる。

この***.gtp**ファイルは、ステンシルの製造業者に送り、ステンレスやマイラー製のソルダーペーストステンシルを作ってもらう。 ソルダーペーストのステンシルに馴染みがない場合は、すばらしいチュートリアルがある。

試作用のステンシルにはOSHStencilsを使っている。 上面のペーストレイヤーは、PCBを製造するだけであれば必要ない。

ボードを発注する

レイアウトに満足したら、PCBを発注しよう。 どのファブハウスもガーバーファイルを理解して扱えるので、KiCadのプロジェクトがあるコンピュータ上のディレクトリに移動する。

次の8個のファイルを選択してZIPにまとめる。

  • *.drl — ドリルファイル
  • *.gbl — ガーバー下面レイヤー
  • *.gbs — ガーバー下面ソルダーマスク
  • *.gbo — ガーバー下面シルクスクリーン(オーバーレイ)
  • *.Edge.Cuts.gm1 — ボードの輪郭(Gerber Mechanical 1)
  • *.gtl — ガーバー上面レイヤー
  • *.gts — ガーバー上面ソルダーマスク
  • *.gto — ガーバー上面シルクスクリーン(オーバーレイ)

ディレクトリ内のすべてのファイルをZIPにしてファブハウスに送ることもできるが、それは推奨しない。 PCBレイアウトソフトウェアは数多くあり、それぞれ異なるファイル名や形式を生成する。 .cmpがガーバーファイルなのか、それとも別のものなのか判断がつきにくいことも多い。 顧客は**.gtp**ファイルを気にするだろうか、それとも余計なファイルだろうか。 ファブハウスには、製造してほしいものだけを渡す方がよい。

最後のステップは、ボードを発注することである。 ガーバーはPCBベンダーとやり取りするための共通言語である。 PCBベンダーは何百、いや何千と存在する。いろいろ探してみてほしい。

ガーバーに加えて、メールやPCBベンダーのサイトを通じて、次のようなPCBの各種仕様を指定する必要がある。

  • PCBの厚さは? 1.6mmが標準だが、0.8mmでも同じくらい剛性があり、50Ωのトレースインピーダンス整合に役立つこともある。
  • ソルダーマスクの色は? 緑がデフォルトだが、赤もかっこいい。
  • シルクスクリーンの色は? 白が最も一般的だが、他の色も選べる。
  • レイヤー数は? この例は2層ボードで、上面銅箔と下面銅箔だけである。ただし、デザインによってはボードを配線するために4層、10層、16層まで必要になることもある。レイヤーが増えるとコストは大幅に上がる。

ソルダーマスクが大きく見える問題

このPCBのソルダーマスクを見て、なぜ変な見た目なのか気になった人もいるだろう。筆者もそうだった。 このPCBのソルダーマスクを、KiCad(緑色で表示)とEagle(ピンク色で表示)で比較してみよう。次の2点に気づくはずである。

  1. KiCadのデザインでは、メインセンサーのパッドの一つが、わずかに位置がずれているように見える。パッド1が他のパッドと揃っていない。妙である。修正が必要な問題だが、ボードが壊れるほどのエラーではない。
  2. より重要な点として、Eagleのデザインではコネクタとセンサー ICのピンの間にソルダーマスクの隙間がある。これにより、ピン間のはんだブリッジを減らせる。KiCad版では、マスクの開口部が大きすぎるように見える。

KiCadのソルダーマスク

Eagleのソルダーマスク

下の画像では、Eagle内のSMD Qwiicコネクタを確認できる。 Eagleのデフォルトのソルダーマスククリアランスは片側0.1mmである。

KiCadのPcbnewで、ZOPT220x Breakoutを開き、Dimensions → Pads Mask Clearanceをクリックする。 KiCadのソルダーマスククリアランスのデフォルトは片側0.2mmである。 この値を0.1mmに変更することを推奨する。 ほとんどのファブハウスも、0.1mmをデフォルトとして使っている。 その後、ガーバーを再エクスポートし、GerbViewに読み込み直す必要がある。

クリアランスを0.1mmより小さくすると、ファブハウスがレジストレーションを正しく合わせるのが難しくなる。

レジストレーションとは何か? 異なるレイヤー同士の位置合わせのことである。ソルダーマスクレイヤーが銅箔レイヤーから2mmずれていたら、はんだ付けしたいSMDパッドがソルダーマスクで覆われてしまう。ファブハウスは、機能するボードを作るためにこれらのレイヤーを高い精度で位置合わせする必要がある。クリアランスを0.1mm未満に減らすと、ファブハウスの許容誤差が小さくなり、遅延や製造コストの増加につながることがある。

カスタムKiCadフットプリントライブラリを作る

このセクションでは、自分だけのローカルなカスタムフットプリントを作成し、CvPcbを使って回路図コンポーネントと接続する方法を説明する。 このチュートリアルの前のセクションをすでに終えており、KiCadがダウンロード・インストール済みであることを前提とする。

KiCadのプロジェクトマネージャーを開き、PCB footprint editorボタンをクリックする。

警告が出ることがある。問題ない、そのままクリックして進めばよい。 これは、KiCadの膨大なGitHubリポジトリにリンクするデフォルトのライブラリ一覧を作成することをKiCadが伝えているだけである。

Preferences → Footprint Libraries Managerをクリックする。 これにより、現在アクセスできるすべてのフットプリントライブラリの一覧が開く。

これは膨大なライブラリのリストである。OKをクリックしてマネージャーを閉じる。

これらのライブラリを少し覗いてみよう。 Load footprint from libraryボタンをクリックし、続けてSelect by Browserをクリックする。 これは、利用可能なフットプリントを閲覧するのに便利なツールである。

LEDs → LED_CREE-XHP50_12Vというフットプリントに移動する。 これはLEDsライブラリ内のフットプリントの一例である。 このフットプリントをダブルクリックし、エディタで開く。

エディタウィンドウのタイトルバーが変わったことに気づくはずである。 アクティブなライブラリは現在LEDsであり、これは読み取り専用である。 当然ながら、KiCadは自分たちのライブラリを管理したいと考えており、誰でも自由にリポジトリに保存できるわけではない。 このフットプリントを編集したい場合は、自分だけのローカルコピーが必要になる。

自分のフットプリントをすべて保管するローカルディレクトリを作ろう。 このチュートリアルでは、C:\KiCadLibs\(あるいは自分のプラットフォームに相当するもの)というローカルフォルダを作成してほしい。

続いて、File → Save Footprint in New Libraryをクリックする。

フットプリントの種類(抵抗、コネクタ、LEDなど)ごとに、異なるディレクトリ名を使うことを推奨する。 先ほど作成したKiCadLibsフォルダを選択し、\LEDsと入力する。 KiCadは新しいLEDs.prettyディレクトリを作成し、C:\KiCadLibs\LEDs.pretty\LED_CREE-XHP50_12V.kicad_modというファイルができる。 これで一件落着かと思いきや、まだそうではない。

Footprint Editorのタイトルバーには、まだアクティブなライブラリがLEDsであり、読み取り専用であると表示されているはずである。 アクティブなディレクトリを、自分のローカルフォルダに切り替える必要がある。 先に断っておくと、File → Set Active Directoryは使えない。KiCadに同梱されているライブラリの一覧しか表示されないためである。おいおい、KiCadよ。

新しいフットプリントディレクトリをアクティブに設定する前に、まずKiCadにその存在を認識させる必要がある。 Preferences → Footprint Libraries Managerを再度開く。

Append with Wizardボタンをクリックする。 追加したいディレクトリを尋ねられる。 今回は*‘Files on my computer’*を追加したい。 **Next >**ボタンをクリックし、先ほど作成したディレクトリ(すなわちC:\KiCadLibs\LEDs.pretty)を選択する。 **Next >**を数回クリックする。 「新しいライブラリをどこに追加したいか」と尋ねられたら、「To Global library configuration(visible to all projects)」を選択し、Finishをクリックする。

「LEDs」というニックネームが二重に使われているというエラーがKiCadから出ることがある。 筆者は**‘LEDs-Custom’**という名前に変更し、OKをクリックしてFootprint Libraries Managerを閉じた。

再度Footprint Editorのツールバーを確認すると、LEDsライブラリがまだアクティブで読み取り専用のままになっているはずである。 ここでFile → Set Active Libraryをクリックする。 ここがKiCadの光る部分で、Filterがよく機能する。 「LED」と入力し、LEDs-Customライブラリを選択する。

ついに、アクティブなローカルライブラリができた。 これで「Save footprint in local library」をクリックするかctrl+sを押すと、KiCadは名前を尋ねるSave Footprintウィンドウを表示する(毎回聞かれるのは少々面倒である)。 Enterを押せば、変更内容が保存される。

警告: KiCadは上書きの警告を出さない。すでに「1206 LED」というフットプリントがある状態で、新しいフットプリントを作って同じ「1206 LED」という名前で保存すると、KiCadは何も言わずに古いフットプリントを上書きしてしまう。

これで、Footprint Editorを使ってフットプリントを作成・編集できるようになった。

最初のフットプリントを1つか2つ作り終えたら、ぜひKiCadのKiCad Library Conventions(KLC)を読んでほしい。 コミュニティで共有できるフットプリントを作るためのよく整理された仕組みである。 思い思いに作っていると、みんな少しずつ異なるものを作ってしまう。KLCは、みんなの認識を揃えるためのものであり、SparkFunもこれに従っている。

今後、フットプリントを大量に作る予定があるなら、gitリポジトリで変更を管理することを検討するとよい。 SparkFunでは、次のような構造を使っている。

  • \SparkFun-KiCad-Libraries — すべてのKiCad回路図コンポーネントファイル(*.lib)を含むgitリポジトリのディレクトリ
  • \SparkFun-KiCad-Libraries\Footprints — フットプリントのディレクトリ群を含む
  • \SparkFun-KiCad-Libraries\Footprints\LEDs.pretty — すべてのLEDフットプリント(*.kicad_mod)を含むディレクトリ
  • \SparkFun-KiCad-Libraries\Footprints\Sensors.pretty — すべてのセンサーフットプリント(*.kicad_mod)を含むディレクトリ
  • 以下同様

gitリポジトリを使うことで、SparkFunのエンジニアやユーザーが回路図コンポーネントやフットプリントを貢献できるようになる。

KiCadライブラリを絞り込む

CvPcbを開いて回路図コンポーネントにフットプリントを割り当てる際、読み込みに非常に時間がかかることがある。 これは、KiCadがすべてのKiCad GitHubリポジトリに問い合わせ、93個のライブラリをダウンロードしているためである。 これを速くするには、非推奨になっているライブラリや、自分が絶対に使わないライブラリを削除することを推奨する。

ライブラリの削除は素早く簡単に行える。Footprint Libraries Managerで行を選択し、「Remove Library」ボタンをクリックするだけである。 何かおかしくなっても慌てる必要はない。マネージャーウィンドウで「Cancel」をクリックすれば、変更を保存せずにライブラリマネージャーが閉じる。 本当に大変なことになった場合は、*‘fp-lib-table’*ファイルを削除してKiCadを再起動すればよい。 これにより、KiCadのデフォルト設定でフットプリントテーブルが再作成される。

フットプリントライブラリテーブルファイルは、(Windows 10の場合)AppDataフォルダにあり、次のような場所になっているはずである。 C:\Users\Nathan\AppData\Roaming\kicad\fp-lib-table

注意: AppDataは隠しディレクトリなので、隠しフォルダを表示する設定が必要になる。

’fp-lib-table’の内容

非推奨のライブラリを削除すると、デフォルトの数は75まで減るが、それでもCvPcbの読み込みには煩わしいほど時間がかかる。 ここからは、厳しい判断をしていく必要がある。 ‘Shielding-Cabinets’ライブラリが必要になることはあるだろうか。あるかもしれないし、ないかもしれない。 もし将来デザインでRFシールドが必要になったとしても、たいていはカスタムパーツになるか、ライブラリにないパーツになるはずである。だから、これは削除してしまう。

SparkFunは、両方を組み合わせたアプローチを取っている。 デフォルトのKiCadライブラリにかなり慣れてきており、意味のある場面ではそのフットプリントを使っている。 気に入ったパッケージを見つけたり使ったりしたときは、それをSparkFun-KiCad-LibrariesのGitHubリポジトリにコピーしている。 同時に、10年以上にわたって使い、作り続けてきたカスタムのEagleフットプリントも活用し続けている。 これらのフットプリントはよく知っていて、信頼できる。 筆者は、他人のフットプリントを信用したせいでPCBを何枚も無駄にした経験があるため、かなり慎重になる傾向がある。 コミュニティのものは活用できるところでは活用しつつも、正しさの確認は非常に厳密に行うようにしてほしい。

一般的な2×5ピンのオスヘッダーが必要なら、KiCadのライブラリを確認すればよい。問題なく使えるはずである。 とはいえ、より特殊な部品を使う場合は、フットプリントをゼロから作った方がよいこともある。 KiCadのライブラリにその部品が含まれている場合でも、データシートと入念に照合し、実寸で試し印刷しておくとよいだろう。

KiCadでEagleのフットプリントを使う

Eagleに慣れている場合、フットプリント作成にかけた時間がKiCadへの移行ですべて無駄になってしまうのではないかと不安になるかもしれない。 心配は要らない。KiCadは元々Eagleのフットプリントを読み込める。そう、標準機能として組み込まれている。 ただし、あまり期待しすぎないでほしい。KiCadはEagleの回路図コンポーネントは読み込めないが、これについては後のセクションで解決策を紹介する。

SparkFunで採っているアプローチは、従来のEagleライブラリすべてのローカルコピーにリンクしておくことである。 Eagleのフットプリントが必要になるたびに、それを最新のKiCadライブラリにコピー&ペーストしている。 フットプリントを一から作り直す必要はなく、KiCadライブラリに移すだけでよい。 そうすれば、必要に応じてそのフットプリントを編集できるようになる。 さらに、新しいフットプリントはすべてゼロから作成し、対応するSparkFunのKiCadライブラリに保存している。

ここまでで、少なくとも一度はPCB Footprint Editorを開いているはずである。 これにより、この後編集する*‘fp-lib-table’*ファイルが作成されているはずである。 それでは始めよう。まずKiCadが閉じていることを確認する。

GitHubからSparkFun Eagle Librariesをダウンロードする。

好きなローカルディレクトリに解凍する。 筆者はEagleライブラリをDropboxフォルダに保存しており、デスクトップとノートパソコンの両方から同じファイル群にアクセスできるようにしている。

Footprint Editor内のFootprint Libraries Managerを使うこともできるが、多数のライブラリを追加・削除するのは面倒である。テーブルファイルを直接編集する方が簡単である。

fp-lib-tableの内容

fp-lib-table」は、KiCadにさまざまなライブラリの場所と、その種類(KiCad、GitHub、EAGLEなど)を教えるファイルである。

このファイルを編集し、SparkFunのライブラリを追加するとともに、非推奨のライブラリやSparkFunが使わないライブラリを削除する。

重要なファイルは次のとおりである。

  • original fp-lib-table — KiCadがデフォルトで作成するもの。ダウンロードする必要は特にない。参考用である。
  • sparkfun fp-lib-table — SparkFunのライブラリの一覧。ダウンロードする必要はなく、参考用である。
  • combined fp-lib-table — 元のテーブルから余分なライブラリを削除し、SparkFunのライブラリを追加したもの。

*‘combined fp-lib-table’をローカルフォルダにダウンロードする。 これを‘fp-lib-table’*という名前に変更する。 続いて、KiCadが想定している場所にこのファイルを移動する。 フットプリントライブラリテーブルファイルは、(Windows 10の場合)AppDataフォルダにあり、C:\Users\Nathan\AppData\Roaming\kicad\fp-lib-tableのような場所になる。 そこにある既存のファイルを上書きすることになる。

注意: AppDataは隠しディレクトリなので、隠しフォルダを表示する設定が必要になる。

ファイルを配置したら、KiCadを再度開き、PCB footprint editorを開き、続けてFootprint Libraries Managerを開く。 新しいSparkFunのライブラリを含む、長いライブラリの一覧が表示されるはずである。

最後のステップは、SparkFunのライブラリへのローカルパスをKiCadに教えることである。 現在、これはSFE_LOCALという変数になっている。これに値を割り当てる必要がある。 Library Managerウィンドウを閉じ、Preferences → Configuration Pathsをクリックする。 Addボタンをクリックし、NameとPathのフィールドを編集する。

下の画像では、**‘SFE_LOCAL’**変数をC:\Users\nathan.seidle\Dropbox\Projects\SparkFun-Eagle-Libraries\というローカルパスに設定している。 この変数は、SparkFun Eagle Librariesをローカルに保存した場所に設定してほしい。

おめでとう。これで、SparkFunのすべてのEagleライブラリを閲覧、使用、コピーできるようになった。

カスタムKiCad回路図コンポーネントを作る

自分だけの回路図パーツやカスタムフットプリントの作り方を学べば、扱える技術の幅に制限がなくなる。さっそく始めよう。

メインのプロジェクトウィンドウから、Schematic library editorを起動する。

この手順は、カスタムフットプリントライブラリを作り始めたときと似ている。 まず、カスタムライブラリの出発点にしたい回路図シンボルを探そう。 フォトセルは非常によくあるパーツである。 deviceライブラリから「R_PHOTO」という回路図コンポーネントを取り込み、これを出発点に新しいカスタム回路図コンポーネントライブラリを作ろう。

左上にある**‘Selecting working library’**(本のアイコン)をクリックすることから始める。 続いて*‘device’*を選択し、作業対象のライブラリに設定する。

‘Load component to edit from current library’ボタンをクリックし、フィルターにr_photoと入力してフォトレジスタのコンポーネントを素早く見つける。 見つかったらOKをクリックする。

**‘Save current component to new library’**ボタンをクリックする。

この*.lib*ファイルは、フットプリントライブラリを保存したのと同じC:\KiCadLibs\ディレクトリに保存することを推奨する。 筆者はこのlibファイルを**‘CustomComponents.lib’**と名付け、自分のものだとわかるようにしている。

Saveをクリックすると、警告がポップアップする。 これは単に、ライブラリにリンクするまではそのライブラリにアクセスできないことをKiCadが丁寧に伝えているだけである。それでは、リンクしよう。

Preferences → Component Librariesをクリックし、現在のライブラリの一覧を確認する。 下の画像では、KiCadに同梱されている標準の回路図コンポーネントライブラリが確認できる。 *‘Component library files’*の隣にあるAddをクリックする。

C:\KiCadLibsディレクトリに移動し、**‘CustomComponents.lib’**を開く。 これで、Component library filesリストの一番下に表示されるはずである。 OKをクリックし、ライブラリエディタに戻る。

再度**‘Select working library’ボタンをクリックするが、今度は自分のカスタムリストまでスクロールするか、「Custom」と入力して‘CustomComponents’**ライブラリを見つける。OKをクリックする。

続いて**‘Load component to edit from the current library’**ボタンをクリックすると、フォトレジスタの回路図コンポーネントだけが表示されるはずである。 R_PHOTOをダブルクリックし、編集を始める。

ここまでくれば、新しいシンボルをライブラリにゼロから追加することも、あるライブラリから別のライブラリへコピーすることもできるようになる。

カスタムKiCadライブラリにコンポーネントをコピーする方法

KiCadは常に進化しており、大きく改善を重ねてきているが、ある回路図コンポーネントを別のライブラリにコピーする作業は、まだ少し荒削りなところがある。

たとえば、silabsライブラリからCP2104を自分のカスタムライブラリにコピーしてみよう。 まず、**‘Select working library’**ボタンをクリックし、コピーしたいパーツが含まれるライブラリをアクティブに設定する。 この例では、silabsをアクティブなライブラリに設定する必要がある。

**‘Load component to edit from the current library’**ボタンをクリックし、CP2104コンポーネントを読み込む。

続いて、CP2104をコピーしたい先のライブラリをアクティブに設定する。 この例では、**‘Select working library’**ボタンをクリックし、アクティブなライブラリを「CustomComponents」に設定する必要がある。

**‘Update current component in current library’**ボタンをクリックし、CustomComponents.libにコンポーネントを保存する。 **‘Save current library to disk’**ボタンが有効になり、このコンポーネントをカスタムライブラリに保存できるようになる。

ライブラリに追加されたことを確認するには、**‘Load component to edit from the current library’**ボタンをクリックする。 新しいCP2104がリストに表示されているはずである。

カスタムKiCadライブラリからコンポーネントを削除する方法

困ったCP2104よ、悪いコンポーネントめ。

コンポーネントを削除するには、まず自分のカスタムライブラリがアクティブになっていることを確認する。 先ほどカスタムライブラリCustomComponents.libに追加したコンポーネントを削除してみよう。 まだ設定していなければ、**‘Select working library’**をクリックしてアクティブなライブラリをCustomComponentsに設定する。 ‘Delete component in current library’(ゴミ箱アイコン)ボタンをクリックする。 どのコンポーネントを削除するか尋ねられる。リストからCP2104を選択する。

OKをクリックし、続けてYesをクリックしてライブラリからコンポーネントを削除する。 **‘Current library to disk’**ボタンをクリックし、Yesをクリックして保存する。

Joan_Sparky氏に感謝を。最高の人物である(血縁関係はない)。

KiCadライブラリ規約

コンポーネントの作成に慣れてきたら、必ずKiCadのKiCad Library Conventionを確認してほしい。 これらの規約には、業界で培われた専門知識の蓄積が反映されており、誰にとっても有益である。

まとめ・参考資料

おめでとう。大きなチュートリアルだったが、最後までやり遂げた。

KiCadに関するさらに詳しい情報は、次の資料を参考にしてほしい。

回路図、PCBレイアウト、ライブラリの編集方法を学んだところで、いよいよ自分だけのカスタムプロジェクトでその腕を試す番である。 ZOPT220x UV Sensor BreakoutのKiCadファイルを次のプロジェクトの出発点として使うことを推奨する。 このサンプルプロジェクトをもとに、白紙の状態から始めるのではなく、必要に応じてデバイスを削除・追加していけばよい。

さらにインスピレーションが欲しい場合は、KiCadに関するSparkFunのEnginursdayやプロジェクトのブログ記事も確認してみてほしい。

EagleからKiCadへ

EAGLEの熟練者でKiCadに足を踏み入れ始めたばかりであれば、EagleのPCBレイアウトをKiCadに変換するためのLachlan氏のEagle to KiCad converterもぜひ確認してほしい。 完璧ではないが、Lachlan氏は膨大な基礎作業をこなしてくれている。

読んでくれてありがとう。コメントや質問があれば、コメント欄で気軽に尋ねてほしい。

Digi-KeyとSparkFunによるKiCad動画シリーズ

あるいは、Digi-KeyとSparkFunによる10部構成のKiCad動画シリーズもおすすめである。 Shawnがバッジ用のシンプルな555タイマー回路を設計し、部品を発注して、バッジを組み立てる様子を追える。 下にリンクした動画は、Digi-KeyによるKiCadの案内が終わり、実際にバッジの製作にそのスキルを応用し始める場面からである。

タグ: スキル


出典:Beginner’s Guide to KiCad(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Pi Servo HATの使い方

SparkFun Pi Servo HATを使うと、Raspberry PiはI2C接続を介して最大16台のサーボモーターを制御できるようになる。 これによりGPIOを節約でき、オンボードのGPIOを他の用途に使えるようになる。 さらに、Pi Servo Shieldにはシリアルターミナル接続も追加されており、モニタやキーボードを接続しなくてもRaspberry Piを起動できる。

必要な部品

このチュートリアルを進めるには、次のものが必要になる。 NOOBS対応のカードにはPi Zero Wに対応するだけの新しいOSが入っていないことがあるため、NOOBS対応カードではなく、まっさらなmicroSDカードを購入することを推奨する。

  • 絶縁GPIOヘッダー(メス、PTH、0.1インチ、2×20ピン)
  • ストレートヘッダー(オス、PTH、0.1インチ、40ピン)
  • Raspberry Pi Zero W
  • ACアダプタ電源(5.1V、2.5A、USB Micro-B)
  • microSDカード(アダプタ付き)
  • SparkFun Pi Servo HAT

さらに、セットアップをテストするための何らかのサーボモーターが必要になる。 このチュートリアルの後半で紹介する例は、まず汎用サブマイクロサーボで試してみるとよい。

必要な道具

この製品の組み立てに特別な道具は必要ない。 はんだごて、はんだ、一般的なはんだ付け用アクセサリーが必要になる。

参考になるチュートリアル

このチュートリアルに取り組む前に、次のチュートリアルも確認しておくとよい。

ハードウェア概要

この基板は使いやすさを最優先に設計されたHATであるため、注目すべき部分はごくわずかである。

USB Micro Bコネクタ — このコネクタは、サーボモーターだけに給電するためにも、サーボモーターとHATに接続されたPiの両方に給電するためにも使える。 また、Piのセットアップにモニタやキーボードを使わずに済むよう、シリアルポート接続経由でPiに接続するのにも使える。

電源絶縁ジャンパー — このジャンパーを(デフォルトでは閉じているが)切断すると、サーボ用の電源レールをPiの5V電源レールから絶縁できる。 なぜそうしたいのかというと、複数のサーボや、重い負荷のかかった大型サーボを使う場合、サーボモーターが電源レールに乗せるノイズによってPiの動作に望ましくない影響が出ることがあり、完全なリセットやシャットダウンに至ることさえあるためである。 なお、このジャンパーの状態にかかわらず、Piに電源が入っている限りシリアルインターフェースは動作し続ける。

サーボモーター用ピンヘッダー — これらのヘッダーは、サーボモーターを取り付けやすいよう間隔を空けて配置されている。 ほとんどのホビー用サーボモーターのコネクタに対応する正しい順序でピンが割り当てられている。

ハードウェアの組み立て

オスヘッダーはPi Zero Wにはんだ付けすることを推奨する。

このような作業でよく使う筆者お気に入りのコツは、まず1本のピンをはんだ付けし、右手に持ったこてでそのピンのはんだを溶かしながら、左手でヘッダーが下の写真のように平らに収まるよう調整するというものである。 ヘッダーの短い側ではんだ付けし、長い方のピンが部品側にくるようにすること。 1本のピンを仮止めしたら、残りのピンをすべてPi Zero Wにはんだ付けする。

メスヘッダーとPi Servo Hatについても同じ手順を繰り返す。

短いピンを基板の下側から挿入し、部品側にはんだを盛ることで、Pi Servo HatをPi Zero Wのオスヘッダーピンの上に積み重ねられるようにすること。 すべてのピンをはんだ付けする前に、ヘッダーが水平になっていることも確認する必要がある。

ヘッダーのはんだ付けが終わったら、Pi Servo HatをPi Zero Wに重ねる。 続いて、使用するサーボに応じて、チャンネル「0」にホビーサーボを接続する。 ホビーサーボのデータシートを確認するか、このチュートリアルに掲載されている標準的なサーボコネクタのピン配置を参考にしてほしい。 十分な容量の5V ACアダプタを使い、Pi Zero Wに給電できる。 ACアダプタをコンセントに差し込み、Pi Zero Wの「PWR IN」とラベル付けされたmicro-Bコネクタに接続する。

ソフトウェア - Python

ここでは、PythonでPi Servo Hatにアクセスし、使う方法を詳しく説明する。 完全なサンプルコードは、製品のGitHubリポジトリで公開されている。

注意: このチュートリアルは、サーボモーターを200HzのPWMで制御する前提で書かれている。「大きな」ブザー音が聞こえる場合や、サーボモーターの制御がうまくいかない場合は、周波数を下げるとよいかもしれない。50Hz用のサンプル一式を確認してみてほしい。

SMBusリソースへのアクセスを準備する

まず一つ目のポイントとして、OSレベルのやり取りのほとんどでは、I2CバスはSMBusと呼ばれる。 というわけで、最初のコードは次のようになる。 これはsmbusモジュールをインポートし、SMBus型のオブジェクトを作成して、Piの各種SMBusのうちバス「1」に接続する。

import smbus
bus = smbus.SMBus(1)

プログラムに部品のアドレスを教える必要がある。 デフォルトでは0x40なので、後で使うために変数にこの値を設定しておく。

addr = 0x40

続いて、PWMチップを有効にし、書き込み後にアドレスを自動的にインクリメントするよう指示する必要がある(これにより、1回の操作で複数バイトの書き込みができるようになる)。

bus.write_byte_data(addr, 0, 0x20)
bus.write_byte_data(addr, 0xfe, 0x1e)

PWMレジスタに値を書き込む

必要な準備はこれですべてである。 ここから先は、PWMチップにデータを書き込めば、それに応じた反応が得られるはずである。次に例を示す。

bus.write_word_data(addr, 0x06, 0)
bus.write_word_data(addr, 0x08, 1250)

最初の書き込みは、チャンネル0の「開始時間」レジスタに対するものである。 デフォルトでは、このチップのPWM周波数は200Hz、つまり5msごとに1回パルスが発生する。 開始時間レジスタは、5msのサイクルの中でパルスがいつハイになるかを決定する。 すべてのチャンネルはこのサイクルに同期している。 一般に、ここには0を書き込む。

2つ目の書き込みは「停止時間」レジスタに対するもので、パルスがいつローになるかを制御する。 この値の範囲は0から4095までで、各カウントはその5msの期間の1コマ分(5ms/4095、約1.2µs)を表す。 つまり、上で書き込んだ1250という値は、5msの期間のうちおよそ1.5msがハイであることを表している。

サーボモーターは、このパルス幅から制御信号を受け取る。 一般に、1.5msのパルス幅はモーターの可動範囲の両端のちょうど中間にあたる「中立」位置になる。 1.0msはおよそ中央から-90度、2.0msはおよそ中央から+90度に相当する。 実際にはこれらの値は90度より多少大きかったり小さかったりすることがあり、モーターがどちらの方向にも90度よりわずかに多く、あるいは少なく動作できることもある。

他のチャンネルにアクセスするには、上記の2つのレジスタのアドレスに単純に4ずつ加算していけばよい。 つまり、チャンネル1の開始時間は0x0A、チャンネル2は0x0E、チャンネル3は0x12というように続き、チャンネル1の停止時間のアドレスは0x0C、チャンネル2は0x10、チャンネル3は0x14というように続く。下の表を参照してほしい。

チャンネル番号開始アドレス停止アドレス
Ch 00x060x08
Ch 10x0A0x0C
Ch 20x0E0x10
Ch 30x120x14
Ch 40x160x18
Ch 50x1A0x1C
Ch 60x1E0x20
Ch 70x220x24
Ch 80x260x28
Ch 90x2A0x2C
Ch 100x2E0x30
Ch 110x320x34
Ch 120x360x38
Ch 130x3A0x3C
Ch 140x3E0x40
Ch 150x420x44

開始アドレスに0を書き込んだ場合、90度からの角度のずれ1度ごとに、停止アドレスへの書き込み値が4.6カウント分変化する。 つまり、中立位置からずらしたい角度の数に4.6を掛け、動かしたい方向に応じてその結果を1250に加算または減算すればよい。 たとえば、中央から45度ずらしたい場合、動かしたい方向に応じて1250より207(45×4.6)カウント多いか少ない値になる。

ソフトウェア - C++

ここでは、C++でPi Servo Hatにアクセスし、使う方法を詳しく説明する。 Pythonよりもかなり難しいので、これを機にPythonを学ぶのもよいかもしれない。 完全なサンプルコードは、製品のGitHubリポジトリで公開されている。

注意: このチュートリアルは、サーボモーターを200Hz PWMで制御する前提で書かれている。「大きな」ブザー音が聞こえる場合や、サーボモーターの制御がうまくいかない場合は、周波数を50Hzに下げるとよいかもしれない。50Hz用のPythonサンプル一式や、C++のコードを50Hz用に調整する際に必要なI2Cレジスタと設定についてはPCA9685のデータシートを確認してみてほしい。

必要なファイルをインクルードする

まず、インクルードする必要のあるファイルから見ていく。

#include <unistd.h> // required for I2C device access
#include <fcntl.h>  // required for I2C device configuration
#include <sys/ioctl.h> // required for I2C device usage
#include <linux/i2c-dev.h> // required for constant definitions
#include <stdio.h>  // required for printf statements

I2Cデバイスファイルを開く

まず、/dev内のi2c-1ファイルを読み書き用に開く。

char *filename = (char*)"/dev/i2c-1"; // Define the filename
int file_i2c = open(filename, O_RDWR); // open file for R/W

open()関数の戻り値を確認し、ファイルが正常に開けたかどうかを確認するとよい。 ファイルが正常に開けた場合は正の整数が返り、そうでない場合は負の値になる。

if (file_i2c < 0)
{
  printf("Failed to open file!");
  return -1;
}

書き込み用にスレーブアドレスを設定する

Python(やArduino)ではトランザクションごとにスレーブアドレスを設定するのに対し、ここでは「次に変更するまで」有効なアドレスを設定する。 これにはioctl()関数を使う。

int addr = 0x40;    // PCA9685 address
ioctl(file_i2c, I2C_SLAVE, addr); // Set the I2C address for upcoming
                                  //  transactions

ioctl()はI2Cに限定されない汎用の関数である。

PCA9685チップを正しく動作するよう設定する

PCA9685チップのデフォルト設定は、そのままでは今回の用途に適していない。 正しく動作させるには、チップ上のいくつかのレジスタに書き込む必要がある。

まず、チップを有効にしてPWM出力をオンにする必要がある。 これは、レジスタ0に値0x20を書き込むことで行える。

buffer[0] = 0;    // target register
buffer[1] = 0x20; // desired value
length = 2;       // number of bytes, including address
write(file_i2c, buffer, length); // initiate write

続いて、複数バイト書き込みを有効にする必要がある。後でPWM値を設定する際に、一度に2バイトずつ書き込むことになるためである。 今回はlength変数はすでに正しく設定されているため、変更する必要はない。

buffer[0] = 0xfe;
buffer[1] = 0x1e;
write(file_i2c, buffer, length);

PWMレジスタに値を書き込む

必要な準備はこれですべてである。 ここから先は、PWMチップにデータを書き込めば、それに応じた反応が得られるはずである。次に例を示す。

buffer[0] = 0x06;  // "start time" reg for channel 0
buffer[1] = 0;     // We want the pulse to start at time t=0
buffer[2] = 0;
length = 3;        // 3 bytes total written
write(file_i2c, buffer, length); // initiate the write

buffer[0] = 0x08;   // "stop time" reg for channel 0
buffer[1] = 1250 & 0xff; // The "low" byte comes first...
buffer[2] = (1250>>8) & 0xff; // followed by the high byte.
write(file_i2c, buffer, length); // Initiate the write.

最初の書き込みは、チャンネル0の「開始時間」レジスタに対するものである。 デフォルトでは、このチップのPWM周波数は200Hz、つまり5msごとに1回パルスが発生する。 開始時間レジスタは、5msのサイクルの中でパルスがいつハイになるかを決定する。 すべてのチャンネルはこのサイクルに同期している。 一般に、ここには0を書き込む。

2つ目の書き込みは「停止時間」レジスタに対するもので、パルスがいつローになるかを制御する。 この値の範囲は0から4095までで、各カウントはその5msの期間の1コマ分(5ms/4095、約1.2µs)を表す。 つまり、上で書き込んだ1250という値は、5msの期間のうちおよそ1.5msがハイであることを表している。

サーボモーターは、このパルス幅から制御信号を受け取る。 一般に、1.5msのパルス幅はモーターの可動範囲の両端のちょうど中間にあたる「中立」位置になる。 1.0msはおよそ中央から-90度、2.0msはおよそ中央から+90度に相当する。 実際にはこれらの値は90度より多少大きかったり小さかったりすることがあり、モーターがどちらの方向にも90度よりわずかに多く、あるいは少なく動作できることもある。

他のチャンネルにアクセスするには、上記の2つのレジスタのアドレスに単純に4ずつ加算していけばよい。 つまり、チャンネル1の開始時間は0x0A、チャンネル2は0x0E、チャンネル3は0x12というように続き、チャンネル1の停止時間のアドレスは0x0C、チャンネル2は0x10、チャンネル3は0x14というように続く。下の表を参照してほしい。

チャンネル番号開始アドレス停止アドレス
Ch 00x060x08
Ch 10x0A0x0C
Ch 20x0E0x10
Ch 30x120x14
Ch 40x160x18
Ch 50x1A0x1C
Ch 60x1E0x20
Ch 70x220x24
Ch 80x260x28
Ch 90x2A0x2C
Ch 100x2E0x30
Ch 110x320x34
Ch 120x360x38
Ch 130x3A0x3C
Ch 140x3E0x40
Ch 150x420x44

開始アドレスに0を書き込んだ場合、90度からの角度のずれ1度ごとに、停止アドレスへの書き込み値が4.6カウント分変化する。 つまり、中立位置からずらしたい角度の数に4.6を掛け、動かしたい方向に応じてその結果を1250に加算または減算すればよい。 たとえば、中央から45度ずらしたい場合、動かしたい方向に応じて1250より207(45×4.6)カウント多いか少ない値になる。

まとめ・参考資料

SparkFun Pi Servo Hatを無事に動かせたら、次は自分のプロジェクトに組み込む番である。

より詳しい情報は、以下の資料を参照してほしい。

PCA9685を使った他のソフトウェアの例については、同じハードウェアを使いコンセプトも非常によく似ている、SparkFun Blocks for Intel Edison - PWMのHookup Guideも参考になる。 あるいは、Pi Servo Hatを使ったパン・チルトカメラの例も確認してみてほしい。

次のプロジェクトのヒントとして、次のような関連チュートリアルも参考になる。

タグ: Hookup、モーション、モーター、Raspberry Pi


出典:Pi Servo Hat Hookup Guide(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Pi Servo pHAT (v2)の使い方

SparkFun Pi Servo pHATは、I2C経由で制御できる16のPWMチャンネルをRaspberry Piに追加する。 これらのチャンネルは、サーボモーターの接続にちょうどよいヘッダーの組み合わせとして引き出されている。 さらに、このPWMチャンネルは他のPWMデバイスの制御にも使える。

さらに、Pi Servo pHATは、モニタやキーボードなしでRaspberry Piをリモート制御するためのシリアルターミナル接続にも使える(このヘッダーはSphero RVRでも使われている)。 おまけとして、Qwiicシステムを使ってI2Cバスに簡単に接続できるQwiicコネクタも用意されている。すべてを兼ね備えているとはこのことである。

必要な部品

このPi Servo pHATを始めるには、ヘッダー付きのRaspberry Pi基板が必要になる。 Raspberry Pi Boardの製品カテゴリにいくつかの選択肢がある。 さらに、これらの基板は各種キットとしても提供されている。

Raspberry Piを動かすには、最低限**microSDカード、電源、USB-Cケーブル(任意)**が必要になる。 microSDカードには2つの選択肢がある。Raspberry Piの実行に必要なOSがあらかじめ書き込まれたNOOBSカードか、Raspberry Pi Foundationのページにあるファイルと手順で書き込むまっさらなSDカードのどちらかである。

自分でSDカードを書き込みたい場合は、microSD USBアダプタも用意しておくとよい。

最後に、Pi Servo pHATの動作を確認するために、サーボモーターが必要になる。 (カタログにある「標準的な」5Vサーボであればどれでも動作するはずである。購入時には、連続回転サーボは通常のサーボとは異なる動作をする点に注意してほしい。

必要な道具

この製品を使うのに道具は必要ないが、ジャンパーをはんだで変更したり、Raspberry Pi基板にヘッダーをはんだ付けしたり(付属していない場合)する場合は、はんだごて、はんだ、その他一般的なはんだ付け用アクセサリーが必要になることがある。

参考になるチュートリアル

このHookup Guideに取り組む前に、次のチュートリアルやHookup Guideに目を通し、内容に馴染んでおくことを推奨する。 補足として、以前のPi Servo HatのHookup Guideも掲載しておく。

Pi Servo pHATには、新しいQwiicシステムを活用するためのQwiicコネクタも用意されている。 これを使う前に、ロジックレベルI2Cのチュートリアルに目を通しておくことを推奨する。 Qwiic製品についてさらに詳しく知りたい場合は、上のバナーをクリックしてほしい。

ハードウェア概要

このHATには、できる限りミスの起きにくい設計を目指したいくつかの機能部分がある。 最もよくあるユーザーのミスを防ぐための対策を講じてはいるが、それでも注意は必要である。 すでにこれらのよくある落とし穴を知っているユーザーも多いだろう。 とはいえ、忘れてしまった場合や、Raspberry Pi(あるいは類似のシングルボードコンピュータ)を使ったことがない場合に備え、このセクションではそれらを一通り紹介する。 このセクションには詳細な内容が多いが、一般にユーザーが特に注意すべき点は次の2つだけである。

  1. 配線の緩みに注意し、Raspberry Piの5Vと3.3Vをショートさせたり橋渡ししたりしないこと。
  2. 消費電流の制約に注意すること。

電源

⚡ 危険: Raspberry Piの5V3.3Vの両方のピンへの接続が用意されているため、配線の緩みには十分注意すること。5Vラインと3.3Vラインの間でショートが起きると、Raspberry Piは永久に使えなくなる

Pi Servo pHATの電源回路は、SparkFunが作る他のほとんどの基板より複雑である。 これは主に、3種類の異なる電源(下記に一覧を示す)と、2種類の異なる電圧レベルの両方に対応する必要があるためである。 以下のサブセクションでは、Pi Servo pHATの電源回路の詳細を説明する。

Pi Servo pHATの電源接続(40ピンのGPIOヘッダーには、5V3.3Vの両方のピンへの接続が用意されている)

3.3V電源

⚡ 危険: Pi用HATの設計要件として、HAT側から3.3Vピンに電力を加えてはならない

可能性は低いが、Servo Pi pHATの3.3Vラインには回路保護が一切ないため、Qwiic接続経由で電力が加わらないようにユーザー自身で必ず二重に確認すること。 主なアクセスポイントであるQwiicコネクタを通じて他のデバイスから3.3Vピンに電力が加わると、Raspberry Piを損傷する可能性が高い。

Pi Servo pHATでは、40ピンGPIOヘッダー上のRaspberry Piの3.3Vピンから3.3Vの電力を取り出し、Qwiicデバイスへの給電とロジックレベル変換に使っている。 3.3Vピンを通じてRaspberry Piに給電することはできない。実際、このピンに別の電源を接続してはならない。 このピンは、Qwiic接続システム専用の電源出力としてのみ使うことを意図している。

Raspberry Piへの40ピンGPIOヘッダー接続

3.3Vラインは、主に接続されたQwiicデバイスへの給電に使われる。 一般的なユーザーはRaspberry Piの電流制限に達することはほとんどないはずである。 とはいえ、大量の電流を消費する用途や、多数のQwiicデバイスを接続する場合は、必ず消費電流と、使っているRaspberry Piの制限値を再確認すること。 一例として、Raspberry Pi Zero WはPAM2306スイッチング3.3Vレギュレータ電源回路の回路図を参照)を使っており、最大1Aの出力電流に対応している。

1アンペアの電流でも熱くなるのか?計算してみよう……

  1. 5Vから3.3Vへの降圧は、ΔVで1.7Vにあたる。 5V − 3.3V = 1.7V
  2. 1Aのとき、これは1.7Wにあたる。 1.7V × 1A = 1.7W
  3. 熱抵抗(ジャンクション-周囲間)を60℃/Wとすると、これは102℃の上昇に相当する。 1.7W × 60℃/W = 102℃
  4. これに室温(27℃)を加えると、129℃になる。 102℃ + 27℃ = 129℃

これは最大ジャンクション温度150℃を十分下回っている。1Aであれば問題なく使えるはずである。

ロジックレベル変換

3.3Vピンは、PCA9685 PWMコントローラーへのMOSFETロジックレベルコンバータの基準電圧としても使われる。 これはすべて、Qwiicコネクタ用のI2Cプルアップ抵抗にもつながっている。

5.0V電源

⚡ 危険: USB-C接続を通じて給電する際は、正しいUSBポート、電源付きUSBハブ、あるいは電源を使うこと。従来のUSBポートは調整済みの5Vを供給するが、(USB 2.0の場合)およそ500mAに制限されている。コンピュータのUSBポート(通常USB 2.0ポート)が供給できる以上の電流を消費すると、コンピュータがエラーメッセージを出したり、リセットしたりする可能性が高い。運が悪ければ、コンピュータの電源コントローラーを損傷することさえある。こうした問題を防ぐため、想定電流と最大消費電流を必ず計算しておくこと。

サーボヘッダーの5Vラインに供給される電源には3種類ある。Raspberry Piの40ピンヘッダーの5VピンRaspberry Piに接続された電源)、RVRシリアル接続ヘッダーの5Vピン、そしてUSB-Cのメスコネクタである。 Pi Servo pHAT上の電源保護・制御回路は、これらを個別にも、あるいは組み合わせても使えるようになっている。

  • 40ピンメスヘッダー: Raspberry Piとの間の電力のやり取りは、この40ピンヘッダーを通じて行われる。このメスヘッダーは、Raspberry Piへのさまざまな接続を提供する。電源には5Vピン3.3Vピンが使われる。

    Raspberry Piへの40ピンGPIOヘッダー接続。クリックすると拡大表示できる。

  • USB-Cコネクタ: このコネクタは、サーボモーターとRaspberry Piの両方への給電に使える。また、シリアルポート接続経由でPiに接続するのにも使える(詳しくは下記のSerial-UARTの節を参照)。

    Pi Servo pHATへのUSB-C接続。クリックすると拡大表示できる。

  • RVRヘッダー: この4ピンヘッダーは、サーボモーターとRaspberry Piの両方への給電に使える。また、シリアルポート接続経由でPiに接続するのにも使える(詳しくは下記のSerial-UARTの節を参照)。

    Pi Servo pHATへのSphero RVRの4ピンヘッダー接続。クリックすると拡大表示できる。

電源の制御と保護

逆流に対する予防措置は講じているが、それでも自分が何をしているか常に意識してほしい。

5V3.3Vのラインの間でショートが起きると、Raspberry Piは永久に使えなくなる。

⚡ Servo Pi pHAT側から3.3Vピン(またはQwiicコネクタ)に電力を加えることはできない。Raspberry Piの3.3Vピンに電力が加わると、損傷する可能性が高い。回路保護は用意されていない。

  • 想定電流と最大消費電流を必ず計算し、問題を防ぐこと。

⚡ USB-C接続を通じて給電する際は、正しいUSBポートや電源を使うこと。USB 2.0ポートは調整済みの5Vを供給するが、およそ500mAに制限されている。コンピュータのUSBポートが供給できる以上の電流を消費すると、コンピュータがエラーになったり、電源コントローラーを損傷したりする可能性が高い。

🔥 3.3Vラインから過剰に電流を引き出すと、3.3Vレギュレータに負荷がかかることがある。Raspberry Pi Zero Wのレギュレータは、1Aでかなり熱くなる。

⚡ USB-C接続のヒューズは、電源保護回路の一部である。ヒューズバイパスジャンパーは、自分が何をしているか十分理解している場合にのみ使うこと。そうでなければ、些細なミスがプロジェクト全体を台無しにしかねない。

逆流保護

Pi Servo pHATは、Raspberry Piの40ピンヘッダーの5Vピン、RVRシリアル接続ヘッダーの5Vピン、そしてUSB-Cのメスコネクタという3つの異なる電源からの5Vを制御している。 逆流保護のため、この基板は理想ダイオードとして動作する回路を使っている。これはRaspberry Pi 3でも使われている設計であり、Raspberry Pi用HATの要件でもある。

この理想ダイオードによる回路保護は、Pi Servo pHATからUSB-C接続やRVR接続への逆流を防ぐ。 Pi Servo pHATに複数の電源を使っている場合、それぞれの電源が矛盾する入力電圧を供給してしまう可能性がある。 電源間の電圧差が十分大きいと、電力の流れが逆転し、電源側に電流が押し戻されることがある。 これはコンピュータを含むデバイスを損傷する可能性がある。 詳しくは、Raspberry Pi Backpowering Guidelinesを確認してほしい。

Pi Servo pHAT上の5V電源保護のブロック図。クリックすると拡大表示できる。

上の機能ブロック図に示すとおり、USB-CとRVRの両方の入力は、Raspberry Piやサーボの電源からの逆流から理想ダイオードで保護されている。 ただし、ヘッドレスセットアップのためにPi Servo pHATからRaspberry Piへ電力を流せるようにする必要があるため、5V GPIOピンには電源保護や絶縁回路が実装されていない。 つまり、電流はRaspberry Piに自由に逆流して給電できるということであり、これは電源に逆流保護が備わっていないRaspberry Pi Zero、Zero W、3B+、3A+の各モデルでは注意が必要になることがある。

これが問題になるのは、Raspberry Pi上の5V電源(micro-B USBコネクタ)が、Pi Servo pHAT上のUSB-CまたはRVR接続経由で供給された外部電力からなんらかの形で電流を吸い込んでしまう場合である。 とはいえ実際には、理想ダイオードには多少の電圧降下があり、Raspberry Piの5Vレールにも多少の許容範囲があり、Raspberry Pi側の電源が電流を吸い込んでしまう可能性自体もそう高くない。 万が一、自らマッドサイエンティストになって基板の限界を試したい場合のために、Pi Servo pHATの5VラインとRaspberry Piの5Vラインの間には回路保護がないため、電源絶縁ジャンパーを手動で切断できるようになっている。

電源制御

上の機能ブロック図には、Raspberry Piからの電力を管理する自動スイッチとして働くMOSFETも示されている。 RVRヘッダーまたはUSB-Cコネクタのどちらかが5Vを供給している場合、Raspberry PiのGPIOヘッダーからの電力はサーボの5Vレールから切り離される。 下の表は、考えられる電源の組み合わせをまとめたものである。

Pi GPIOUSB-CRVRヘッダー説明
×Raspberry Piは主に自身の電源で給電される。サーボはUSB-Cから電力を得る(MOSFETは閉じており、Piからの電力は使われない)。
×Raspberry Piは主に自身の電源で給電される。サーボはRVRヘッダーから電力を得る(MOSFETは閉じており、Piからの電力は使われない)。
Raspberry Piは主に自身の電源で給電される。サーボはUSB-CまたはRVRヘッダーのうち、都合のよい方から電力を得る(MOSFETは閉じており、Piからの電力は使われない)。
×Raspberry Piとサーボは、USB-CまたはRVRヘッダーのうちより適した方から給電される。
××それぞれ個別の電源から給電される。
××同上。
××同上。

(○=その電源が接続されている、×=接続されていない)

この表に示していないのが、サーボの5Vレールに電源が接続される可能性である。

USB-Cヒューズ

Pi Servo pHATには、USB-C接続を通じた消費電流を制限するヒューズ(2.5A保持5Aトリップ)がある。 5Aを超える電流が流れると、負荷が取り除かれるまで自動的に電流を絞る、あるいは電源を切断する。 この制限を取り除きたいユーザー向けにバイパスジャンパーが用意されているが、このジャンパーを使う際は自分が何をしているか十分理解している必要がある。 何をしているかよくわからない場合は、このジャンパーには触れないことを推奨する(詳しくは下記のJumpersの節を参照)。

電源絶縁

Pi Servo pHATの40ピンGPIOヘッダーには、電源絶縁ジャンパーが接続されている。 このジャンパーを切断すると、Raspberry Piの5Vピンを、Pi Servo pHATで使われる5Vから絶縁できる。 これは通常、大きな負荷を使う予定がある場合や、ノイズがRaspberry Piに逆流することで断続的な電源喪失が起きるのを心配している場合に使われる(詳しくは下記のJumpersの節を参照)。

このジャンパーを切断してもシリアルUART接続には影響しない。 とはいえ、Pi Servo pHATから再びRaspberry Piに給電したい場合は、このジャンパーをブリッジし直す必要がある。

PCA9685

PCA9685は、Pi Servo pHAT上の16チャンネル・12ビットのパルス幅変調(PWM)に対するI2C制御を提供する。 PCA9685は主にLED制御向けに設計されているが、サーボのような他のPWMデバイスにも使える。

16チャンネルPWMコントローラーIC、PCA9685

特性説明
動作電圧(VDD)2.3V〜5.5V(ハードワイヤード:5V
動作温度-40℃〜85℃
PWM出力16個のトーテムポール出力(デフォルト:オープンドレイン)/5Vでシンク25mAまたはソース10mA/PWM周波数はすべてのチャンネルで共有/ホットインサーション対応
PWM周波数24Hz〜1526Hz(デフォルト(1Eh):200Hz
PWM分解能12ビット(4096段階の制御)
デューティ比0%〜100%(調整可能)
発振器内部:25MHz(ハードワイヤード)/外部:最大50MHzの入力(利用不可)
I2Cアドレスハードウェアで設定可能な62種類のアドレス(ハードワイヤード:0x40)/複数デバイスをグループでまとめて制御するためのプログラム可能な4つのアドレス(All Callアドレス1個、Sub Callアドレス3個)

すべてのチャンネルでPWM周波数は共有されるが、16チャンネルのPWM出力のデューティ比はそれぞれ個別に制御できる。 これにより、PCA9685は各出力でサーボやLEDを制御できる。 LEDの場合はこれで明るさを制御・駆動でき、サーボの場合は位置を制御できる。

サーボ・PWMヘッダー

Pi Servo pHATはさまざまなPWMデバイスで使えるが、最も典型的な用途はサーボとLEDである。 これらのヘッダーは、サーボモーターを取り付けやすいよう間隔を空けて配置されている。 さらに、ほとんどのホビー用サーボモーターのコネクタに対応する標準的な3ピン構成で引き出されている。

16のPWMチャンネルに接続されたサーボヘッダー

シリアルUART接続

Raspberry Piは、Pi Servo pHATを通じてシリアル接続でやり取りできる。 シリアルUARTへのアクセスポイントは2つあり、Sphero RVR用の4ピンヘッダーと、USB-C接続である。 どちらのインターフェースを使うかは、Pi Servo pHAT上のRXスイッチで制御する。

Pi Servo pHATのRXスイッチは、USB-C接続とSphero RVRの4ピンヘッダーのどちらのTXラインを使うかを制御する。クリックすると拡大表示できる。

どちらの接続が使われているかは、わかりやすくなっている。 スイッチが(黒い突起の)ある側にラベル付けされたインターフェース(USBまたはRVR)が、シリアル通信のためにRaspberry PiのRXピンへ接続されるTXを示している。 上の写真に示すとおり、USB-CインターフェースのTXラインがRaspberry PiのRXピンに接続されている。 Sphero RVRの4ピンヘッダーのTXラインに切り替えるには、矢印に従ってスイッチをRVRの位置にスライドさせるだけでよい。

シリアル通信についてのコツや詳細については、シリアル通信シリアルターミナルの基礎のチュートリアルを参照してほしい。

トラブルシューティングのヒント: SSHやシリアル接続がうまくいかない場合は、このスイッチが正しい位置にあるか、正しいボーレートを使っているか再確認すること。

USB-Cコネクタ

このコネクタは、給電にも、モニタやキーボードを使わずにリモートでRaspberry Piにアクセスするためのシリアルポート接続にも使える(詳しくはHeadless Raspberry Pi Setupのチュートリアルを参照)。

Pi Servo pHATのシリアル通信用USB-Cインターフェース。クリックすると拡大表示できる。

Pi Servo pHATには、USB-C接続を通じた消費電流を制限するヒューズがある。 5Aを超える電流が流れると、負荷が取り除かれるまで自動的に電流を絞る、あるいは電源を切断する。

トラブルシューティングのヒント: USBケーブルの抜き差しの際に、コネクタをこじったり支点にしたりしてはいけない。そうすると基板やコネクタが損傷し、パッドやトレースがちぎれてしまうこともある。ケーブルは、基板からまっすぐ引き抜くようにして外すこと。

CH340C

CH340Cは、WCH製のUSB-シリアル変換アダプタである。 USB-C接続とシリアルターミナルの間でデータを変換するのに使われる。 CH340Cチップのドライバは、コンピュータにインストールしておく必要がある。 Windows 7、Windows 10、Mac OSX High Sierra、Raspberry Pi向けRaspbian Stretch(2018年11月13日リリース版)で動作することを確認済みである。 どのOSでも、以前CH340Gのドライバをインストールしたことがある場合は、新しいCH340Cドライバに更新する前に、まずそのドライバをアンインストールする必要がある。 詳しくは、How to Install CH340 Drivers Tutorialを参照してほしい。

Pi Servo pHATのシリアル通信用USB-Cインターフェース。クリックすると拡大表示できる。

USB-C接続でシリアルデータを送受信すると、RX(黄)とTX(緑)のLEDが点滅するはずである。 RXピンは4ピンのRVRヘッダーと接続を共有しており、データを受信している際に点滅することがある。

RVRヘッダー

Sphero RVRは、Raspberry Piにアクセスするために4ピンヘッダーを必要とする。 Pi Servo pHATでは、Sphero RVRとの手間のかからない統合のため、この接続を引き出している。

Raspberry Piのシリアルターミナルにアクセスするための、Sphero RVR用4ピンヘッダー

Qwiicコネクタ

注意: 非Qwiicデバイスを追加する場合やQwiicジャンパーケーブルを使う場合は注意すること。このコネクタには回路保護が一切ない。

Qwiicシリーズ製品との追加の互換性のため、Qwiicコネクタが用意されている。 Qwiicシステムは、お気に入りのI2Cデバイスを手軽に、手間なく追加できるケーブル・コネクタシステムを目指している。 QwiicコネクタはRaspberry PiのI2Cピンにつながっており、3.3Vピンから直接電力を得ている。

Pi Servo pHAT上のQwiicコネクタ。クリックすると拡大表示できる。

注意: I2Cバス上には、PCA9685向けにロジックレベルを昇圧するためのロジックレベルコンバータが一組ある。

ジャンパー

この基板には、個々の部品を改造しなくても、いくつかのハードウェア接続を簡単に変更できるジャンパーがいくつか引き出されている。 ジャンパーの切断方法がわからない場合は、こちらのチュートリアルを確認してほしい。 変更を加える前に、それぞれのジャンパーが何をするのか必ず確認しておくことを推奨する。 これは特に、重大な結果を招きかねないヒューズバイパスジャンパーについて当てはまる。

電源絶縁

このジャンパーはデフォルトでは閉じている。 Pi Servo pHAT上の電源をPiの5V電源レールから絶縁するには、これを切断・開放すればよい。

Pi Servo pHAT上の電源絶縁ジャンパー。クリックすると拡大表示できる。

注意: このジャンパーの状態にかかわらず、Piに電源が入っている限りシリアルインターフェースは動作し続ける。

ヒューズバイパス

⚡ 危険: このジャンパーは、電源保護回路の一部であるPi Servo pHAT上のヒューズをバイパスするために使う。このジャンパーは、自分が何をしているか十分理解している場合にのみ使うこと。そうでなければ、些細なミスがプロジェクト全体を台無しにしかねない。

バイパスジャンパーは、USB-C接続のヒューズによる電流制限を取り除きたいユーザー向けに用意されているが、このジャンパーを使う際は自分が何をしているか十分理解している必要がある。 このヒューズの定格は2.5A保持5Aトリップである。

Pi Servo pHAT上のヒューズバイパスジャンパー。クリックすると拡大表示できる。

何をしているかよくわからない場合は、このジャンパーには触れないことを推奨する。 USB-Cは非常に大きな電力を供給できるため、ハードウェアを簡単に損傷しうる。

I2Cプルアップ

I2Cジャンパーを切断すると、I2Cバスから10kΩのプルアップ抵抗が切り離される。

Pi Servo pHAT上のI2Cプルアップジャンパー。クリックすると拡大表示できる。

たとえば、プルアップ抵抗を持つQwiicデバイスを複数接続している場合、このジャンパーを切断したくなることがある。 プルアップ抵抗を持つ複数のデバイスがI2Cバス上にある場合、並列合成抵抗の値が強すぎて、バスが正しく動作しなくなることがある。

ハードウェアの組み立て

注意: このチュートリアルは、ユーザーがRaspberry Piに馴染みがあり、Pythonの一般的な知識も持っている前提で進める。これらに馴染みがない場合は、まずRaspberry Piをセットアップし、グラフィカルユーザーインターフェース(GUI)に慣れ、続いてPythonの基礎を学ぶことを出発点として推奨する。始めるための資料を以下に挙げる。

Raspberry Pi

Raspberry PiにPi Servo pHAT(v2)を組み合わせるのはかなり簡単である。 まず、何にも電源が入っていないことを確認する。 続いて、PCB同士が上下に重なるよう、基板をRaspberry Piに積み重ねる。Pi Servo pHATは横に飛び出すような形にはならない

  • Pi Servo pHATのPCBがRaspberry Piの上(あるいは上方)ではなく横に飛び出す形で重ねてしまうと、ピンの接続が誤ってしまい、まず何かを損傷する。
  • 通常はごくわずかなリスクだが、Raspberry Pi用HATを接続する際にも、何かがショートしたり、電圧不足になったり、損傷したりする可能性はある。ベストプラクティスとして、(HAT、サーボ、LED、追加のQwiic基板を含め)何かに電源が入った状態でHATを差し込むことは絶対に避けること。
  • Raspberry Pi 4やDebian Busterイメージは使わないこと。どちらもこの製品での動作確認がまだ済んでいない。
  • Raspberry Piが動作している状態でサーボを差し込んではいけない。サーボへの給電に必要な急激な電流の変化により、Raspberry Piがリセットされてしまう。サーボはすべて先に差し込んでから、電源を入れること。

Raspberry Piに正しく接続されたPi Servo pHAT。画像をクリックすると拡大表示できる。

Sphero RVR

残念ながら、このチュートリアルではSphero RVRとPi Servo pHATを組み合わせて使う方法は扱わない。 とはいえ、組み立てガイドと入門チュートリアルへのリンクを以下に示しておく。

その他のシングルボードコンピュータ

Nvidia JetsonやGoogle Coralなど、他のシングルボードコンピュータ(SBC)でもこのHATを使う手順は似ている。 HATが正しい向きで揃っていることだけ確認すればよい。 たとえばNvidia Jetsonの場合、HATは基板から外側に飛び出す向きにするべきであるHATを収めるためにヒートシンクを取り外そうとしてはいけない。それは間違った向きである)。

Nvidia Jetsonに正しく接続されたPi Servo pHAT

電源

Hardware Overviewの節で説明したとおり、サーボヘッダーへの5V電源は3種類の異なる方法で供給できる。

注意: Sphero RVRキットで使う4ピンヘッダーの例はまだ用意されていない。

さまざまな電源の選択肢の例。

注意: (4未満のモデルの)Raspberry Piでは、PWR INとラベル付けされたmicro-Bコネクタを使う。

サーボ

このチュートリアルでは、チャンネル「0」でホビーサーボをテストする。 使用するサーボに応じて、ホビーサーボのデータシートを確認するか、このチュートリアルに掲載されている標準的なサーボコネクタのピン配置を参考にしてほしい。

Raspberry Piに正しく接続され、サーボが動作しているPi Servo pHAT。

Qwiicデバイス

Qwiic接続システムを使えば、お気に入りのQwiic対応センサーやデバイスを簡単に追加できる。

Qwiicデバイスは、Pi Servo pHATにデイジーチェーンで接続できる。

Pythonパッケージの概要

注意: このセンサーとPythonライブラリは、新しくリリースされたRaspberry Pi 4ではまだテストされていない。まだカタログに取り扱いがないためである。

注意: このパッケージは、最新版のPython 3を使っている前提である。Raspberry PiでPythonやI2Cハードウェアを使うのが初めての場合は、Python Programming with the Raspberry Piのチュートリアルと、Raspberry PiのSPIとI2Cのチュートリアルを確認してほしい。

Raspberry Pi上では、Raspbian OS(デスクトップと推奨ソフトウェア付き)のイメージにPython 2と3の両方が同梱されている。

サポートのヒント: Raspberry Piや他のシングルボードコンピュータで、I2Cハードウェアが有効になっているか必ず再確認すること。

この製品には2つのPythonパッケージがある。 Qwiic_PCA9685_Pyは、PCA9685 PWMコントローラーICの動作を支える基盤パッケージである。 一方、PiServoHat_Pyは、この製品専用に作られた、サーボを制御するためのパッケージである。 これらのパッケージは、Pi Servo pHATでサーボの制御をすぐに始められるよう書かれている。

インストール

この製品用のPythonパッケージをインストールするには、SparkFun Qwiicパッケージをインストールすることを推奨する。 これにより、SparkFunのQwiic製品向けに利用可能なPythonパッケージがすべてインストールされ、必要なI2Cドライバーパッケージも含まれる。 pip3(Python 2の場合はpip)経由でPyPiのインストールに対応しているシステムでは、次のコマンドで簡単にインストールできる。

すべてのユーザー向け(注:sudo権限が必要):

sudo pip3 install sparkfun-qwiic

現在のユーザー向け:

pip3 install sparkfun-qwiic

注意: ユーザーは、この製品用の2つのPythonパッケージを個別にインストールすることもできる(手順は下記を参照)。その場合も、必要なI2Cドライバーパッケージは別途インストールする必要がある。

Qwiic_PCA9685_Py

PyPiでホストされているsparkfun-sparkfun-qwiic-pca9685Pythonパッケージをインストールできる。 GitHubリポジトリから手動でダウンロード・インストールしたい場合は、こちらから入手できる(パッケージの依存関係に注意してほしい。リポジトリのドキュメントページはReadtheDocsでホストされている)。

PyPiでのインストール

このリポジトリは、PyPiにsparkfun-qwiic-pca9685 packageとしてホストされている。 pip3(Python 2の場合はpip)経由でPyPiのインストールに対応しているシステムでは、次のコマンドで簡単にインストールできる。

すべてのユーザー向け(注:sudo権限が必要):

sudo pip3 install sparkfun-qwiic-pca9685

現在のユーザー向け:

pip3 install sparkfun-qwiic-pca9685

ローカルインストール

インストールするには、システムにsetuptoolsパッケージがインストールされていることを確認する。

コマンドラインから直接インストールする(Python 2の場合はpythonを使う)。

python3 setup.py install

pip3用のパッケージをビルドするには、次のようにする。

python3 setup.py sdist

パッケージファイルがビルドされ、distというサブディレクトリに置かれる。 このパッケージファイルはpip3でインストールできる。

cd dist
pip3 install sparkfun_qwiic_pca9685-<version>.tar.gz

Pythonパッケージの動作

これはPCA9685 PWMコントローラーICの基盤となるパッケージであるため、動作の詳細については扱わない。 とはいえ、ReadtheDocsのドキュメントを確認するのは自由である。

PiServoHat_Py

PyPiでホストされているsparkfun-pi-servo-hatPythonパッケージをインストールできる。 GitHubリポジトリから手動でダウンロード・インストールしたい場合は、こちらから入手できる(パッケージの依存関係に注意してほしい。リポジトリのドキュメントページはReadtheDocsでホストされている)。

PyPiでのインストール

このリポジトリは、PyPiにsparkfun-pi-servo-hat packageとしてホストされている。 pip3(Python 2の場合はpip)経由でPyPiのインストールに対応しているシステムでは、次のコマンドで簡単にインストールできる。

すべてのユーザー向け(注:sudo権限が必要):

sudo pip3 install sparkfun-pi-servo-hat

現在のユーザー向け:

pip3 install sparkfun-pi-servo-hat

ローカルインストール

インストールするには、システムにsetuptoolsパッケージがインストールされていることを確認する。

コマンドラインから直接インストールする。

python setup.py install

pip3用のパッケージをビルドするには、次のようにする。

python setup.py sdist

パッケージファイルがビルドされ、distというサブディレクトリに置かれる。 このパッケージファイルはpip3でインストールできる。

cd dist
pip3 install sparkfun_pi_servo_hat-<version>.tar.gz

Pythonパッケージの動作

以下は、このPythonパッケージの基本的な機能の説明である。 パッケージの構成、組み込みメソッド、その入出力を含む。 このPythonパッケージの動作についてさらに詳しくは、ソースコードとセンサーのデータシートを確認してほしい。

依存関係

このPythonパッケージがコード内で必要とする依存関係は、ごくわずかである。

import time             # Time access and conversion package
import math             # Basic math package
import qwiic_pca9685    # PCA9685 LED driver package
デフォルトの変数

このPythonパッケージのコード内にあるデフォルトの変数を以下に示す。

# Device Name:
_DEFAULT_NAME = "Pi Servo HAT"

# Fixed Address:
_AVAILABLE_I2C_ADDRESS = [0x40]

# Default Servo Frequency:
_DEFAULT_SERVO_FREQUENCY = 50   # Hz

# Special Use Addresses:
gcAddr = 0x00       # General Call address for software reset
acAddr = 0x70       # All Call address- used for modifications to
                    # multiple PCA9685 chips reguardless of thier
                    # I2C address set by hardware pins (A0 to A5).
subAddr_1 = 0x71    # 1110 001X or 0xE2 (7-bit)
subAddr_2 = 0x72    # 1110 010X or 0xE4 (7-bit)
subAddr_3 = 0x74    # 1110 100X or 0xE8 (7-bit)
クラス

PiServoHat()またはPiServoHat(address, debug=None) このPythonパッケージはクラスオブジェクトとして動作し、その型の新しいインスタンスを作成できる。 __init__()コンストラクタを使い、デフォルトまたは指定したI2CアドレスでI2Cバス経由のI2Cデバイスへの接続を作成する。

コンストラクタ

コンストラクタとは、オブジェクトの作成時に必要なデータメンバーを初期化する(値を割り当てる)ための特別なメソッドである。

__init__(address, debug)

入力:value デバイスアドレスの値。指定しない場合、このPythonパッケージは_AVAILABLE_I2C_ADDRESS変数に保存されたデフォルトのI2Cアドレス(0x40)を使う。All Callアドレスは0x70である。

入力:value デバッグ用の文を出力するかどうかを指定する。

0: デバッグ用の文を出力しない。 1: デバッグ用の文を出力する。

出力:Boolean

True: デフォルト(または指定した)アドレスのI2Cデバイスに接続できた。 False: デバイスが見つからない、または接続できなかった。

関数

クラスの属性である関数のことで、そのクラスのインスタンスに対するメソッドを定義する。 簡単に言えば、そのクラスの操作(あるいはメソッド)のためのオブジェクトである。

.restart() PCA9685チップをソフトリセットし、MODE1レジスタをクリアしてPWM機能を再起動する。 PWM周波数もデフォルトの50Hz設定に戻る。

.get_pwm_frequency() 出力で使われているPWM周波数を読み取る。

出力:Integer 範囲: 24Hz〜1526Hz

.set_pwm_frequency(frequency) 出力で使うPWM周波数を設定する。50Hzがデフォルトで、ほとんどのサーボに推奨される。

入力:Integer 範囲: 24Hz〜1526Hz

.get_servo_position(channel)または.get_servo_position(channel, swing) サーボアームの向きを度数で推定する。 この推定値は、指定したチャンネルのPWM信号に設定されているタイミングに基づく。

入力:value 対象のチャンネル 範囲: 0〜15

入力:Value 90: アームの可動角が90°のサーボ。 180: アームの可動角が180°のサーボ。

出力:Float 推定されたサーボアームの位置。

.move_servo_position(channel, position)または.move_servo_position(channel, position, swing) サーボを指定した位置(度数)まで動かす。

入力:value 対象のチャンネル 範囲: 0〜15

入力:Float 指定するサーボアームの位置。

入力:Value 90: アームの可動角が90°のサーボ。 180: アームの可動角が180°のサーボ。

.set_duty_cycle(channel, duty_cycle) デューティ比に基づいて、サーボを指定した位置に動かす。

入力:value 対象のチャンネル 範囲: 0〜15

入力:Float デューティ比(パーセント) 範囲: 0〜100(%)(分解能:1/4096

パッケージのアップグレード

今後、Pythonパッケージに変更が加えられることがある。 インストール済みのパッケージの更新は、パッケージごとに個別に行う必要がある(サブモジュールや依存関係は自動的には更新されず、手動で更新する必要がある)。 SomePackageというPythonパッケージの場合、次のコマンドを使う(Python 2の場合はpipを使う)。

すべてのユーザー向け(注:sudo権限が必要):

sudo pip3 install --upgrade SomePackage

現在のユーザー向け:

pip3 install --upgrade SomePackage

Pythonのサンプル

注意: このセクションでは、Pythonパッケージに対応したサンプルを扱う。元のサンプルコードを探している場合は、以下のアーカイブされたセクションに移動している。

この製品のサンプルコードは、Pythonパッケージ用のGitHubリポジトリにあり、ReadtheDocsのドキュメントとしても公開されている。

サンプルを実行するには、コードをダウンロードするか、ファイルにコピーするだけでよい。 続いて、必要であればサンプルファイルを開いて(保存して)、好みのPython IDEでコードを実行する。 たとえば、デフォルトのPython IDLEでは、Run > Run Moduleをクリックするか、F5キーを使う。 サンプルを終了するには、Ctrl + Cのキーの組み合わせを使う。

Example 1

ここでは最初のサンプルだけを扱うが、コードがどう動作するか、その仕組みも詳しく分解して説明する。

依存関係をインポートする

コードの最初の部分では、動作に必要な依存関係をインポートする。

import pi_servo_hat
import time

コンストラクタを初期化する

この行で、デバイス用のオブジェクトをインスタンス化する。

test = pi_servo_hat.PiServoHat()

ソフトリスタート

この行はPCA9685チップをソフトリセットし、MODE1レジスタをクリアして、PWM周波数をデフォルトの50Hzに戻す。

test.restart()

テスト実行

このコードの部分では、1msのPWM信号を出力してサーボアームを0°に動かし、1秒間停止した後、2msのPWM信号を出力して90°に動かし、その位置で1秒間保持する。

# Moves servo position to 0 degrees (1ms), Channel 0
test.move_servo_position(0, 0)

# Pause 1 sec
time.sleep(1)

# Moves servo position to 90 degrees (2ms), Channel 0
test.move_servo_position(0, 90)

# Pause 1 sec
time.sleep(1)

注意: サーボ位置への入力値はあくまで概算であり、PWM信号の分解能に制限される。この点のデモはExample 3で確認できる。

スイープ

コードの最後の部分では、サーボアームを0°から90°まで、そして再び元に戻るという動作を繰り返す。 コードはおよそ1°刻みで反復し、入力した位置を出力する。

while True:
    for i in range(0, 90):
        print(i)
        test.move_servo_position(0, i)
        time.sleep(.001)
    for i in range(90, 0, -1):
        print(i)
        test.move_servo_position(0, i)
        time.sleep(.001)

注意: 完璧なものは存在しないため、サーボの位置は期待した入力値からずれることがある。 この制約はたいていサーボ自体の精度によるものだが、一部はPWM信号のタイミングにも起因する(サーボへのPWM信号は、出力の分解能とPWM周波数の影響を受けるが、これらの要因はサーボの精度と比べれば無視できるほど小さい)。

サーボは値段相応である。高品質・高性能なサーボは、安価な代替品よりもかなり高価になる。 サイズ、トルク、応答速度、位置精度といった性能のさまざまな要素がコストに反映される。 そのため、安価な代替品を使う場合は、ソフトウェア側で補正する必要が出てくることがある。

さらに、サーボによっては、アームの可動範囲が期待される90°や180°を超えて広がっていることがある。 コード末尾のコメントアウトされたセクションはこれを活用するのに使えるが、サーボを永久に損傷または破壊してしまう可能性があるため、慎重に扱うこと。

Pythonのサンプル(アーカイブ)

注意: この製品向けの新しいPythonパッケージの追加に伴い、これらのサンプルは非推奨となり、今後サポートされなくなる可能性がある。とはいえ、アーカイブとして情報はそのまま残している。

ここでは、PythonでPi Servo pHATにアクセスし、使う方法を詳しく説明する。 完全なサンプルコードは、製品のGitHubリポジトリで公開されている。

注意: このチュートリアルは、サーボモーターを200HzのPWMで制御する前提で書かれている。「大きな」ブザー音が聞こえる場合や、サーボモーターの制御がうまくいかない場合は、周波数を下げるとよいかもしれない。50Hz用のサンプル一式を確認してみてほしい。

SMBusリソースへのアクセスを準備する

まず一つ目のポイントとして、OSレベルのやり取りのほとんどでは、I2CバスはSMBusと呼ばれる。 というわけで、最初のコードは次のようになる。 これはsmbusモジュールをインポートし、SMBus型のオブジェクトを作成して、Piの各種SMBusのうちバス「1」に接続する。

import smbus
bus = smbus.SMBus(1)

プログラムに部品のアドレスを教える必要がある。 デフォルトでは0x40なので、後で使うために変数にこの値を設定しておく。

addr = 0x40

続いて、PWMチップを有効にし、書き込み後にアドレスを自動的にインクリメントするよう指示する必要がある(これにより、1回の操作で複数バイトの書き込みができるようになる)。

bus.write_byte_data(addr, 0, 0x20)
bus.write_byte_data(addr, 0xfe, 0x1e)

PWMレジスタに値を書き込む

必要な準備はこれですべてである。 ここから先は、PWMチップにデータを書き込めば、それに応じた反応が得られるはずである。次に例を示す。

bus.write_word_data(addr, 0x06, 0)
bus.write_word_data(addr, 0x08, 1250)

最初の書き込みは、チャンネル0の「開始時間」レジスタに対するものである。 デフォルトでは、このチップのPWM周波数は200Hz、つまり5msごとに1回パルスが発生する。 開始時間レジスタは、5msのサイクルの中でパルスがいつハイになるかを決定する。 すべてのチャンネルはこのサイクルに同期している。 一般に、ここには0を書き込む。

2つ目の書き込みは「停止時間」レジスタに対するもので、パルスがいつローになるかを制御する。 この値の範囲は0から4095までで、各カウントはその5msの期間の1コマ分(5ms/4095、約1.2µs)を表す。 つまり、上で書き込んだ1250という値は、5msの期間のうちおよそ1.5msがハイであることを表している。

サーボモーターは、このパルス幅から制御信号を受け取る。 一般に、1.5msのパルス幅はモーターの可動範囲の両端のちょうど中間にあたる「中立」位置になる。 1.0msはおよそ中央から-90度、2.0msはおよそ中央から+90度に相当する。 実際にはこれらの値は90度より多少大きかったり小さかったりすることがあり、モーターがどちらの方向にも90度よりわずかに多く、あるいは少なく動作できることもある。

他のチャンネルにアクセスするには、上記の2つのレジスタのアドレスに単純に4ずつ加算していけばよい。 つまり、チャンネル1の開始時間は0x0A、チャンネル2は0x0E、チャンネル3は0x12というように続き、チャンネル1の停止時間のアドレスは0x0C、チャンネル2は0x10、チャンネル3は0x14というように続く。下の表を参照してほしい。

チャンネル番号開始アドレス停止アドレス
Ch 00x060x08
Ch 10x0A0x0C
Ch 20x0E0x10
Ch 30x120x14
Ch 40x160x18
Ch 50x1A0x1C
Ch 60x1E0x20
Ch 70x220x24
Ch 80x260x28
Ch 90x2A0x2C
Ch 100x2E0x30
Ch 110x320x34
Ch 120x360x38
Ch 130x3A0x3C
Ch 140x3E0x40
Ch 150x420x44

開始アドレスに0を書き込んだ場合、90度からの角度のずれ1度ごとに、停止アドレスへの書き込み値が4.6カウント分変化する。 つまり、中立位置からずらしたい角度の数に4.6を掛け、動かしたい方向に応じてその結果を1250に加算または減算すればよい。 たとえば、中央から45度ずらしたい場合、動かしたい方向に応じて1250より207(45×4.6)カウント多いか少ない値になる。

サンプル

以下に、参考になるサンプルをいくつか紹介する。

Example 1:50Hz周波数

高周波数に対応できる高性能・現代的なサーボとは異なり、ほとんどのサーボ(多くは古いか安価なもの)は50HzのPWM周波数を好み、200HzのPWM周波数では動作に苦労する。 たいてい、位置を探そう(追従しよう)とする過程でブザー音を発したり、過熱したりしてしまう。

サーボが動作しているExample 1。

以下は、PCA9685を50HzのPWM周波数で駆動するよう設定する方法の例である。 これによりサーボアームの位置決めの分解能は下がるが、ほとんどのサーボにとってはそもそも過熱の原因になっていた分解能なので、問題にはならないはずである。

import smbus, time
bus = smbus.SMBus(1)
addr = 0x40

## Running this program will move the servo to 0, 45, and 90 degrees with 5 second pauses in between with a 50 Hz PWM signal.

bus.write_byte_data(addr, 0, 0x20) # enable the chip
time.sleep(.25)
bus.write_byte_data(addr, 0, 0x10) # enable Prescale change as noted in the datasheet
time.sleep(.25) # delay for reset
bus.write_byte_data(addr, 0xfe, 0x79) #changes the Prescale register value for 50 Hz, using the equation in the datasheet.
bus.write_byte_data(addr, 0, 0x20) # enables the chip

time.sleep(.25)
bus.write_word_data(addr, 0x06, 0) # chl 0 start time = 0us

time.sleep(.25)
bus.write_word_data(addr, 0x08, 209) # chl 0 end time = 1.0ms (0 degrees)
time.sleep(.15)
bus.write_word_data(addr, 0x08, 312) # chl 0 end time = 1.5ms (45 degrees)
time.sleep(.15)
bus.write_word_data(addr, 0x08, 416) # chl 0 end time = 2.0ms (90 degrees)

while True:
     time.sleep(.5)
     bus.write_word_data(addr, 0x08, 209) # chl 0 end time = 1.0ms (0 degrees)
     time.sleep(.5)
     bus.write_word_data(addr, 0x08, 312) # chl 0 end time = 1.5ms (45 degrees)
     time.sleep(.5)
     bus.write_word_data(addr, 0x08, 209) # chl 0 end time = 1.0ms (0 degrees)
     time.sleep(.5)
     bus.write_word_data(addr, 0x08, 416) # chl 0 end time = 2.0ms (90 degrees)

Example 2:関数を作る

このサンプルは、特定のチャンネルの指定したサーボ位置に基づいて、PWM信号の開始・終了時間を設定するシンプルな関数を作成する。 Pythonの知識があまりない場合でも、このサンプルを見れば自分だけのスクリプトを作りやすくなるはずである。

import smbus, time
bus = smbus.SMBus(1)
addr = 0x40

def servo_Init(channel):
     # Mapping Channel Register
     channel_0_start = 0x06
     channel_reg = 4*channel + channel_0_start

     # Write to Channel Register
     bus.write_word_data(addr, channel_reg, 0) 


def servo_Pos(channel, deg_range, deg_position):
     # Mapping Channel Register
     channel_0_end = 0x08
     channel_reg = 4*channel + channel_0_end

     # Mapping Sevo Arm Position
     #   209 = 0 deg
     #   312 = 45 deg
     #   416 = 90 deg
     deg_0 = 209
     deg_max = 416
     pos_end_byte = lambda x: (deg_max-deg_0)/deg_range*x + deg_0

     # Write to Channel Register
     bus.write_word_data(addr, channel_reg, round(pos_end_byte(deg_position)))

## Running this program will move the servo to 0, 45, and 90 degrees with 5 second pauses in between with a 50 Hz PWM signal.

# Configure 50Hz PWM Output
bus.write_byte_data(addr, 0, 0x20) # enable the chip
time.sleep(.25)
bus.write_byte_data(addr, 0, 0x10) # enable Prescale change as noted in the datasheet
time.sleep(.25) # delay for reset
bus.write_byte_data(addr, 0xfe, 0x79) #changes the Prescale register value for 50 Hz, using the equation in the datasheet.
bus.write_byte_data(addr, 0, 0x20) # enables the chip

# Initialize Channel (sets start time for channel)
servo_Init(3)

# Run Loop
while True:
     time.sleep(.5)
     servo_Pos(3, 90, 0) # chl 3 end time = 1.0ms (0 degrees)
     time.sleep(.5)
     servo_Pos(3, 90, 45) # chl 3 end time = 1.5ms (45 degrees)
     time.sleep(.5)
     servo_Pos(3, 90, 0) # chl 3 end time = 1.0ms (0 degrees)
     time.sleep(.5)
     servo_Pos(3, 90, 90) # chl 3 end time = 2.0ms (90 degrees)

トラブルシューティングのヒント

デバイスが見つからない

接続を再確認してほしい。 Raspberry Piでは、これはOSError: [Errno 121] Remote I/O errorという出力で示されることがある。

Raspberry Piでは、I2Cハードウェアが有効になっているかも確認すること。 これは通常、Error: Failed to connect to I2C bus 1.という出力で示される。

I2C接続を確認する

Raspberry PiがI2C経由でPi Servo pHATと通信できているかを確認する簡単な方法は、I2Cバスにpingを送ることである。 最新版のRaspbian Stretchでは、i2ctoolsパッケージがあらかじめインストールされているはずである。 入っていない場合は、ターミナルで次のコマンドを実行する。

sudo apt-get install i2ctools

i2ctoolsパッケージがインストールされたら、ターミナルで次のコマンドを実行してI2Cバスにpingを送れる。

i2cdetect -y 1

ターミナルに表が表示されるはずである。 Servo pHATが正しく接続され動作していれば、0x40のアドレス空間が40とマークされているはずである。

消費電流の問題

サーボが電源の許容範囲を超える電流を消費している場合、Pi Servo pHATは正しく動作せず、Raspberry Piが断続的に再起動したり電圧不足になったりすることがある。

一方、電源絶縁ジャンパーが切断されている場合、Raspberry Piの電源はPi Servo pHATから絶縁されているため、Raspberry Pi自体は動作し続ける。 ただし、PCA9685は断続的にリセットされることがある。 これのよい目安になるのが、接続されたサーボがPCA9685のデフォルト設定に反応する様子が見えたり聞こえたりすることである。 もう一つの方法は、上記の問題で述べたようにServo pHATにpingを送ることである。 十分速くボードにpingを送ると(キーボードの上矢印キーで直前の入力を呼び出すとよい)、Pi Servo pHATのアドレスがアドレステーブルから時折消えることに気づくはずである。

この製品についてまだ質問や問題がある場合は、フォーラムに投稿してほしい。

まとめ・参考資料

より詳しい情報は、以下の資料を参照してほしい。

Raspberry Piの使い始めで助けが必要な場合は、次の資料も確認してほしい。

PythonとI2Cの使い始めで助けが必要な場合は、次の資料も確認してほしい。

次のプロジェクトのヒントとして、次のようなチュートリアルも参考になる。

Raspberry Piのチュートリアル

ロボット工学のチュートリアル

サーボ・モーター制御のチュートリアル

タグ: Hookup、モーション、モーター、プロトタイピング、Python、Qwiic、Raspberry Pi、ロボティクス、Sphero、プロジェクトを始める


出典:Pi Servo pHAT (v2) Hookup Guide(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Raspberry Pi Zero Wirelessを始める

Raspberry Piは、1枚の基板にコンピュータ一式を詰め込んだ、人気の高いシングルボードコンピュータ(SBC)である。 Raspberry Pi 3とその前身のモデルは、すっかりおなじみのフォームファクタとしてすでに広く知られているだろう。 Raspberry Piには、さらに小さなフォームファクタのモデルもある。 Raspberry Pi Zeroの登場により、コンピュータ一式をさらに小さなプロジェクトに組み込めるようになった。 このガイドでは、オンボードのWiFiモジュールを備えたZero製品ラインの最新版、Raspberry Pi Zero - Wirelessを扱う。 ここで説明する内容はほとんどのRaspberry Piのバージョン・フォームファクタに当てはまるが、基本的にはPi Zero Wを軸に進める。

スターターパックを探しているなら、Pi Zero Wを使い始めるのに必要なものがすべて揃ったキットもある。

必要な部品

このチュートリアルを進めるには、次のものが必要になる。

  • Raspberry Pi Zero W Basic Kit
  • モニタ
  • キーボード
  • マウス(任意だが推奨)
  • USBハブ(複数のUSBデバイスを使う場合)

参考になるチュートリアル

このチュートリアルを読み進める前に、次のチュートリアルにも興味があるかもしれない。

  • Single Board Computer Benchmarks — シングルボードコンピュータやコンピューティングモジュール上でさまざまなベンチマークプログラムをセットアップし、実行する方法。世代ごとの結果も掲載している
  • SD Cards and Writing Images — Raspberry Pi、PCDuino、その他好みのSBC向けにSDカードへイメージを書き込む方法
  • Raspberry PiのGPIO — PythonまたはC++でRaspberry PiのI/Oラインを駆動する方法
  • Raspberry PiのSPIとI2C — C/C++用のwiringPi I/OライブラリとPython用のspidev/smbusを使い、Raspberry PiのシリアルI2CバスとSPIバスを利用する方法

ハードウェア概要

Raspberry Pi Zero(およびPi Zero W)とRaspberry Pi 3との間で、特に目立つ違いをいくつか見ていく。

両者は、WがWiFiとBluetoothを内蔵している点を除けば、機能面ではまったく同じである。 Pi Zeroの多くのコネクタは、標準サイズのコネクタに接続するためにアダプタが必要になるため、Pi 3と比べるとセットアップがやや面倒に感じることがある。 とはいえ、始めるのに必要なのは基本的に、Raspberry Piのイメージを書き込んだmicroSDカードと電源だけである。

Mini HDMI

標準的なHDMIコネクタを使っていた従来のRaspberry Piのモデルとは異なり、Zeroはスペースを節約するためミニHDMIコネクタを採用している。 Zeroをモニタやテレビに接続するには、ミニHDMIからHDMIへの変換アダプタかケーブルが必要になる。

USB On-the-Go

Raspberry Pi 3やその他のモデルには、従来、標準サイズのメスUSBコネクタが2〜4個備わっており、マウス、キーボード、WiFiドングルなど、さまざまなデバイスを接続できた。 Zeroでは、こちらもスペースを節約するため、USB On-the-Go(OTG)接続を採用している。 Pi Zeroは、初代Raspberry Pi AおよびA+モデルで使われていたのと同じBroadcom製ICを使っている。 このICはUSBポートに直接接続されており、OTG機能を実現している。 一方Pi B、B+、2、3の各モデルは、オンボードのUSBハブを介して複数のUSB接続を可能にする方式を採っており、この点が異なる。

標準的なオスのUSBコネクタを持つデバイスを接続するには、USB OTGケーブルが必要になる。 マイクロUSB側の端をPi Zeroに差し込み、標準サイズのメスUSB側の端にUSBデバイスを接続する。

その他の標準的なUSBデバイスを使う場合は、電源付きのUSBハブを使うことを推奨する。 ワイヤレスのキーボード・マウスのセットは、1つのUSBドングルで両方に対応できるため、特に相性がよい。

注意: Pi ZeroのUSBポートにアクセスする必要がある場合は、USB-microB変換アダプタを使うこともできる。

電源

他のPiと同様に、電源はマイクロUSBコネクタから供給する。 電源用USBに供給する電圧は5〜5.25Vの範囲にすること。

microSDカードスロット

もう一つのおなじみのインターフェースがmicroSDカードスロットである。 Raspberry Piのイメージファイルが入ったmicroSDカードをここに挿入する。

WiFiとBluetooth

Raspberry Pi 3と同様に、Zero Wも802.11n無線LANとBluetooth 4.0の両方の接続に対応している。 これにより、WiFiドングルや(Bluetoothのキーボード・マウスに置き換えた場合の)USBキーボード・マウスなど、USB経由での接続の多くが不要になる。

カメラコネクタ

Raspberry Pi Zero V1.3以降とすべてのZero Wには、オンボードのカメラコネクタが搭載されている。 これを使ってRaspberry Pi Cameraモジュールを接続できる。 ただし、このコネクタは22ピン0.5mmピッチで、標準のPiとは異なる。 Pi Zero Wにカメラを接続するには、専用のケーブルが必要になる。

GPIO

他のすべてのRaspberry Piモデルと同様に、数多くのGPIOピンが引き出されており、その多くはI2Cなど他の機能も兼ねている。 GPIOヘッダーを使う場合は、ヘッダーをはんだ付けしておくことを検討するとよい。

その他の接続

最後に、TVとRunという2組のスルーホールパッドがあることに気づくかもしれない。 TVパッドを使うと、HDMI出力の代わりにRCAジャックをボードに接続できる。 RunピンはチップのリセットピンにつながっておりRunピンを短絡させると、ボードの電源を切ったり、シャットダウン後に再び起動させたりできる。 ここにボタンを接続しておくと、ボードの電源を入れ直すよい方法になる。


GPIOヘッダーの各ピンとPi Zero上のすべてのコネクタについての完全な説明は、下記のグラフィカルデータシートを参照してほしい。

画像をクリックするとPDFが表示される。

ハードウェアの組み立て

用途によっては、Pi Zeroのセットアップは最小限で済むこともあれば、Zeroの小型コネクタとマウス・キーボード・モニタといった標準的なデバイスを接続するためのアダプタが必要になり、やや面倒になることもある。

モニタ

  1. HDMI入力のあるモニタやテレビにPi Zeroを接続するには、Pi ZeroのミニHDMIコネクタにミニHDMI-HDMIケーブルまたはアダプタを取り付ける。もう一方の端をモニタやテレビのHDMIポートに接続する。
  2. USB OTGケーブルを、マイクロUSBコネクタ経由でPi Zeroに接続する。キーボード・マウスのコンボセットを使う場合は、そのドングルを標準サイズのメスUSB端に取り付ける。別々のマウスとキーボードを使う場合は、両方をUSB OTGケーブルに接続するためのUSBハブが必要になる。
  3. microSDカードに有効なRaspberry Piのイメージが入っていることを確認する(詳しくは後述する)。microSDカードをmicroSDスロットに挿入する。
  4. マイクロUSBの電源入力からPi Zeroに給電する。

他にも、このチュートリアルでは使わないが触れておくべきコネクタがいくつかある。 Pi Zeroには、標準のPi 3と同じピン配置の40ピンGPIOコネクタが基板上にある。 このコネクタにワイヤー、ヘッダー、あるいはPi Hatをはんだ付けすれば、GPIOピンや電源にアクセスできる。 カメラコネクタを使えばRaspberry Pi Cameraを接続できるが、このコネクタは22ピン0.5mmピッチで標準のPiとは異なり、カメラをPiに接続するには専用のケーブルが必要になる点に注意してほしい。

OSのインストール

Pi Zero Wの電源を入れる前に、Basic Kitに付属するmicroSDカードにRaspberry Pi OS(あるいは好みであれば、Raspberry Piに対応したサードパーティ製OS)のイメージを書き込んでおく必要がある。 Raspberry Pi Foundationは、OSイメージのダウンロードとmicroSDカードへの書き込みを簡単にする、Raspberry Pi Imagerという優れたツールを作っている。 このセクションでは、このツールを使ってmicroSDカードにRaspberry Pi OSのイメージを書き込む方法を簡単に説明する。

方法1:Raspberry Pi Imager

Raspberry Pi Imagerツールを使えば、Raspberry Pi対応OSのイメージの選択とmicroSDカードへの書き込みが、以前よりずっと簡単に行える。 必要なのはOSと保存先デバイスを選ぶことだけで、残りはツールが処理してくれる。 ツールはRaspberry Piのソフトウェアページからダウンロードできる。

ツールをダウンロードしてコンピュータにインストールしたら、次の手順でイメージのインストールを完了させる。

  • microSDカードとSDアダプタを、コンピュータの適切なポートに挿入する。
  • Raspberry Pi Imagerを開く。
  • Choose OSボタンをクリックし、好みのOSを選択する(このチュートリアルではデフォルトのRaspberry Pi OSを使う)。
  • Choose Storageボタンをクリックし、microSDカードのドライブの場所を選択する。
  • Writeをクリックする。

OSをmicroSDカードに書き込むには、選択したバージョンやポート・microSDカードの速度によって数分かかることがある。 書き込みが完了すると、ツールが自動的にmicroSDカードのソフトウェア的な取り出し処理を行うため、処理が終わったらそのまま取り外せる。

注意: ソフトウェアページには、手動でダウンロード・インストールしたいユーザー向けに、さまざまな代替OSへのリンクも掲載されている。イメージを手動で書き込み・インストールする方法については、SD Cards and Writing Imagesのチュートリアルを参照してほしい。

注意: 執筆時点では、当初NOOBSの使用を推奨していた。しかし現在、このソフトウェアはサポートされていない。Raspberry Pi Foundationによれば次のとおりである。

NOOBS(New Out Of the Box Softwareの略)は、Raspberry Pi向けのSDカードベースのインストーラーだったが、現在はNOOBSの使用を推奨・サポートしていない。今後はRaspberry Pi Imagerを使ってほしい。

それでもNOOBSに関心がある場合は、GitHubリポジトリを確認してほしい。

方法2:.imgファイル

基本的なRaspbianのインストールやNOOBSにある選択肢以外のものを使いたい場合は、自分でuSDカードにイメージをインストールする必要がある。 この方法は少し手間がかかる。単にファイルをカードに置くだけでなく、カードをブート可能にするなどの設定も行う特別な*.imgファイルが必要になるためである。 Raspberry Pi Foundationは、Ubuntu、OSMC(Open Source Media Center)、さらにはWindows 10 IoT Coreといったイメージをいくつか提供している。 Googleで検索すれば、特定の用途向けの専用イメージも含め、さらに多くが見つかるはずである。 Raspberry Piを使うのが初めてであれば、Raspbianを推奨する。 最新版は下記のリンクからダウンロードできる。

注意: Raspbianをインストールする際、使っているRaspberry Piのモデルを気にする必要はない。 ただし、OSMCやRetroPieなど他のRaspberry Piのイメージファイルには、モデルごとに(多くの場合Pi 2・3と、それより古いモデルを区別して)設計されたイメージがある。 それらのPiはZeroとはわずかに異なるプロセッサを使っているため、こうしたイメージは動作しない。 幸い、Zeroシリーズは古いRaspberry Pi A/A+/B/B+モデルと同じチップを使っているため、Zero向けに使えるイメージはまだ数多くある。 各Piモデルの詳細はこちらのリンクを参照してほしい。

カードに自分でイメージをインストールする際は、Etcherというソフトウェアを推奨する。 Etcherは、必要な手順をすべて一つのソフトウェアにまとめてくれている。 イメージをダウンロードし、プログラムを実行して、イメージを選択し、uSDカードのドライブを選択して、Flashを押すだけでよい。 完了したらカードを取り外せば準備完了である。 イメージのインストールが終わったら、カードをボードに挿入して電源を入れる。

Macユーザーには、ApplePi BakerというソフトウェアがSDカードへの新しいイメージのアップロードに便利である。 起動時に管理者パスワードを求められる。 左側のペインでSDカードを選択し、「Pi Ingredients: IMG Recipe」のセクションで自分のイメージをアップロードする。 「Restore Backup」をクリックし、進行状況バーが完了するまで待てば完了である。 このプログラムはカードの取り出し処理も自動で行ってくれるため、そのままカードを引き抜いてPiに挿入できる。

このチュートリアルの残りの部分では、イメージを直接インストールする方法かNoobsのどちらかでRaspbianをインストールした前提で進める。 このチュートリアルは、グラフィカルユーザーインターフェースを備えたほとんどのLinuxベースのシステムでも問題なく動作するはずだが、項目の場所が多少異なることがある。

Raspberry Pi OSを使う

ボードが起動して動くようになったところで、Raspberry Pi OSの基本をいくつか見ていく。 このセクションでは、HDMI出力でモニタに接続してPiを使う方法を扱う。

Raspberry Pi OS

Raspberry Pi OSはLinuxベースである(正確には、Raspberry Pi Desktopを組み込んだDebian Bullseyeの移植版にあたる)。 とはいえ、あまり身構える必要はない。 数多くのコマンドを覚える必要があったり、テキストエディタを保存して終了するために:wqと入力しなければならなかったりした時代はもう終わっている。 このOSは、WindowsやMacOSに似たデスクトップのグラフィカルユーザーインターフェース(GUI)で動作し、いくつかの基本的なコマンドやショートカットは覚えておきたくなるだろうが、使わなくてもたいてい問題なくやっていける。

初回起動

OSを新規インストールした状態でPiを初めて起動すると数分かかり、Piは少なくとも1回は再起動するはずである。 OSの初期設定が終わると、次の画像のようなデスクトップの設定画面が表示される。

セットアップウィザードの指示に従い、Pi上の地域設定、新しいパスワード、WiFi接続、システムとパッケージの更新など、各種設定を行う。 一部の手順は省略してもよいが、少なくとも地域設定と新しいパスワードの設定は強く推奨する。 設定を後から見直したり更新したりしたい場合は、Raspberry Piのスタートメニュー > Preferences > Raspberry Pi Configurationから開ける。

これにより、地域、モニタ、キーボード、パスワードの更新に加え、SPIやI2Cといった各種周辺機器インターフェースのオン・オフを設定できるポップアップが開く。

警告: Raspberry Piのセキュリティを確保するため、パスワードはデフォルトから変更することを推奨する。保存する前に、パスワードを安全な場所に必ず控えておくこと。ユーザー名も変更できる。

ソフトウェアの更新

セットアップウィザードでこの手順を省略した場合や、今後ソフトウェアパッケージを更新する必要が生じた場合は、コマンドラインインターフェース(CLI)を通じてPi上のソフトウェアパッケージを更新できる。 ターミナルを開き、次のように入力してEnterキーを押す。

sudo apt-get update

このコマンドは、最新のパッケージ情報を取得し、何を更新する必要があるかをパッケージマネージャーに伝えるようPiに指示する。

  • sudo(スーパーユーザーとも呼ばれる)は、特にセキュリティレベルの高いコマンドでよく目にするコマンドである。ユーザー名が(’sudoers’と呼ばれる)許可されたユーザーの一覧に含まれていれば、(まだrootとしてログインしていない場合でも)一時的にそのコマンドを実行する権限をユーザーに与える。
  • apt-getはパッケージマネージャーであり、updateはそれに与えているコマンドである。

これにより、システム上のすべてのパッケージがダウンロードされ、アップグレードされる。しばらく時間がかかることがある。

シャットダウン・再起動

デスクトップのメインメニューには標準のシャットダウンボタンがあるが、CLIから次のコマンドでPiをシャットダウンさせることもできる。

sudo shutdown -h now
  • shutdownは文字どおりマシンをシャットダウンする。nowはその操作をすぐに実行するよう指示するものである(15と指定すれば15分後にシャットダウンするよう指示できる)。

CLIからPiを再起動するには、次のコマンドを送る。

sudo shutdown -r now

⚡ 警告: 適切にシャットダウンする前に電源を切ると、Raspberry Piのイメージが破損する恐れがある。Piから電源を取り外す前には、必ず正しくシャットダウンすること。あるいは、GPIOを使ってPiの電源を切るPythonスクリプトを書くという方法もある。

その他の便利なLinuxコマンド

ターミナルのコマンドラインで使える、その他の便利なコマンドをいくつか紹介する。

  • pwd — Print Working Directoryの略。今どのフォルダにいるかわからない場合、ファイルシステム上の現在位置を教えてくれる。
  • ls — Listの略。フォルダの中身を表示する。隠しファイルを含むすべてのファイルを表示するにはls -aと入力する。ls -alと入力すれば、すべてのファイル・フォルダとその権限設定も表示される。
  • cd — ディレクトリを移動するコマンド。cd foldernameでそのフォルダに移動する。cd ..で一段階上に戻る。cd ~でホームディレクトリに戻る。
  • passwd — パスワードを変更できる。
  • man — manualの略。コマンドの前にmanと付けて入力すると、その使い方の概要が表示される。
  • nano — 使いやすいシンプルなテキストエディタが開く。

トラブルシューティング

Raspberry Piがうまく動かない場合は、Raspberry Pi Foundationのフォーラムにある、基本的なトラブルシューティングについてのこちらの記事を確認してほしい。

Raspberry Pi向けに設計されたSparkFunのハードウェアの接続で困っている場合は、SparkFunフォーラムで力になれないか確認してみてほしい。

まとめ・参考資料

Raspberry Piの参考資料

Raspberry Pi Zero Wをドングルのように使いたい場合は、Pi Zero USB Stemも確認してみてほしい。

Raspberry Piをさらに楽しみたい場合は、次のSparkFunのチュートリアルも参考になる。

タグ: Bluetooth、Hookup、IoT、Raspberry Pi、シングルボードコンピュータ、WiFi、ワイヤレス


出典:Getting Started with the Raspberry Pi Zero Wireless(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Raspberry Pi Zero 2 Wを始める

絶大な人気を誇るRaspberry Piのシングルボードコンピュータ(SBC)カタログにおける最新モデル、Raspberry Pi Zero 2 Wは、クアッドコアの64ビットArm Cortex-A53 CPUを搭載し、Pi Zero Wをそのまま置き換えられるアップグレード版として登場した。 このガイドでは、Pi Zero 2 Wのハードウェア面での改良点、デスクトップ構成でのセットアップ方法、Raspberry Pi OSのインストールと基本的な使い方を紹介する。

  • Raspberry Pi Zero 2 W
  • Raspberry Pi Zero 2 W(ヘッダー付き)

注意: 「Raspberry Pi Zero 2 WH」は、ボードにヘッダーがあらかじめ実装されている点を除けば「Raspberry Pi Zero 2 W」と機能的に同じである。

SparkFun Raspberry Pi Zero 2 W Basic Kitは、Pi Zero 2 Wのセットアップに必要な最小限の構成を提供する。 このキットには、Pi Zero 2 W本体、Raspberry Pi 12.5W micro-USB電源アダプタ、mini HDMIケーブル、USB OTGケーブル、64GBのmicroSDカード(アダプタ付き)が含まれる。

  • SparkFun Raspberry Pi Zero 2 W Basic Kit(廃盤)

必要な部品

このガイドは、ユーザーがPi Zero 2 W Basic Kitを持っている前提で進める。 キットを持っていない場合は、必要なアクセサリー(電源アダプタ、mini HDMIケーブル、USB OTGケーブルまたはUSBハブ、microSDカード)を用意しておくこと。 Basic Kitに加えて、このチュートリアルを進めるにはモニタ(またはテレビ)、キーボード、マウス、USBハブ(複数のUSBデバイスを接続する場合)が必要になる。 キーボード・マウスのセットが必要な場合は、Logitech K400 Plus Wireless Touch Keyboardを検討してみるとよい。

おすすめの読み物

以下のチュートリアルで扱われている概念に馴染みがない場合は、このガイドを続ける前に目を通しておくとよい。

  • Single Board Computer Benchmarks — シングルボードコンピュータやコンピューティングモジュール上でさまざまなベンチマークプログラムをセットアップし、実行する方法。各世代の結果は以降のページに掲載されている
  • SD Cards and Writing Images — Raspberry Pi、PCDuino、お気に入りのSBC向けに、SDカードへイメージをアップロードする方法
  • Raspberry PiのGPIO — PythonまたはC++を使い、Raspberry PiのI/Oラインを制御する方法
  • Raspberry PiのSPIとI2C — C/C++用のwiringPi I/OライブラリとPython用のspidev/smbusを使い、Raspberry PiのシリアルI2CバスとSPIバスを利用する方法

ハードウェア概要

この節では、Pi Zero 2 Wに搭載されているハードウェアを見ていき、関連する箇所では前バージョンや他のRaspberry Pi SBCとの比較も行う。

Raspberry Pi RP3A0 SiP

Pi Zero 2 Wには、クアッドコアの64ビットArm Cortex-A53 CPU(クロック周波数1GHz)を内蔵した、アップグレード版のRP3A0システムインパッケージ(SiP)が搭載されている。 このSiPは、Broadcom BCM2710A1ダイと512MBのLPDDR2 SDRAMを統合している。 このプロセッサにより、Raspberry Pi Zero 2 Wは、オリジナルのシングルコアRaspberry Pi Zeroと比べてシングルスレッド性能が40%向上し、マルチスレッド性能は5倍に向上している。

Mini HDMI

標準サイズのHDMIコネクタを使う従来のRaspberry Piモデルとは異なり、Zeroはスペースを節約するためmini HDMIコネクタを採用している。 Zeroをモニタやテレビに接続するには、mini HDMIからHDMIへの変換アダプタ、またはケーブルが必要になる。

USB On-the-Go

Raspberry Pi 3や他のモデルでは、従来2〜4個の標準サイズのメスUSBコネクタが搭載されており、マウス、キーボード、WiFiドングルなどさまざまなデバイスを接続できた。 Zeroはここでもスペースを節約するため、USB On-the-Go(OTG)接続を採用している。 Pi Zeroは、オリジナルのRaspberry Pi AおよびA+モデルで使われていたのと同じBroadcom ICを使っている。 このICはUSBポートに直接接続されてOTG機能を提供する。これは、オンボードのUSBハブを使って複数のUSB接続を可能にしているPi B、B+、2、3モデルとは異なる点である。

標準的なオスのUSBコネクタを持つデバイスを接続するには、Basic Kitに含まれるUSB OTGケーブルを使う。 micro USB側の端をPi Zeroに差し込み、USBデバイスを標準的なメスのUSB入力に差し込む。

他の標準的なUSBデバイスと組み合わせて使う場合は、電源付きのUSBハブを使うことを推奨する。 ワイヤレスのキーボード・マウスセットは、両方のデバイスに対して1つのUSBドングルで済むため、最も相性がよい。

電源

他のPiと同様、電源はmicro USBコネクタから供給される。 電源用USBに供給する電圧は5〜5.25Vの範囲にすること。

microSDカードスロット

もう一つのおなじみのインターフェースが、microSDカードスロットである。 Raspberry Piのイメージファイルを収めたmicroSDカードをここに挿入する。

WiFiとBluetooth

Raspberry Pi Zero 2 Wは、2.4GHzの802.11 b/g/nワイヤレスLANとBluetooth 4.2を搭載しており、Bluetooth Low Energy(BLE)にも対応し、モジュラー適合認証も取得している。 これにより、WiFiドングルや、Bluetoothキーボード・マウスに置き換えた場合のUSBキーボード・マウスなど、USB経由で必要になっていた接続の多くを解放できる。

カメラコネクタ

Raspberry Pi Zero V1.3以降とすべてのZero Wには、オンボードのカメラコネクタが搭載されている。 これを使い、Raspberry Pi Cameraモジュールを接続できる。 ただし、このコネクタは22ピン0.5mmピッチであり、標準的なPiとは異なる。 カメラをPi Zero Wに接続するには、別のケーブルが必要になる。

GPIO

他のすべてのRaspberry Piモデルと同様、Pi Zero 2 Wには2×20のGPIOピンが引き出されており、SPI、I²C、デジタルI/O、PWMなどの機能を利用できる。 GPIOヘッダーを使う場合は、ヘッダーをはんだ付けしておくとよい。

OSの選択とインストール

Pi Zero 2 Wの電源を入れる前に、Basic Kitに付属のmicroSDカードにRaspberry Pi OS(あるいは好みであれば、Raspberry Piで動作するサードパーティ製OS)のイメージを書き込む必要がある。 Raspberry Pi Foundationは、OSイメージのダウンロードとmicroSDカードへの書き込みを簡単にする、Raspberry Pi Imagerという優れたツールを開発した。 この節では、このツールを使ってRaspberry Pi OSのイメージをmicroSDカードに書き込む方法を簡単に説明する。

Raspberry Pi Imager

Raspberry Pi Imagerツールを使うと、Raspberry Pi対応OSのイメージを選択してmicroSDカードに書き込む作業が、以前よりずっと簡単になる。 必要なのは、OSとストレージデバイスを選択するだけで、あとはツールが処理してくれる。 以下のリンクから、Raspberry Piのソフトウェアページでツールをダウンロードできる。

Raspberry Pi Imagerツールをここから入手する

ツールをダウンロードしてコンピュータにインストールしたら、以下の手順でイメージのインストールを完了させる。

  • microSDカードとSDアダプタを、コンピュータの適切なポートに挿入する。
  • Raspberry Pi Imagerを開く。
  • Choose OSボタンをクリックし、使用したいOSを選択する(このチュートリアルではデフォルトのRaspberry Pi OSを使う)。
  • Choose Storageボタンをクリックし、microSDカードのドライブの場所を選択する。
  • Writeをクリックする。

OSをmicroSDカードに書き込むには、選択したバージョンやポート・microSDカードの速度によって数分かかることがある。 書き込みが終わると、ツールは自動的にmicroSDカードのソフトウェア的な取り出し処理を行うので、処理が完了したら取り外せる。

注意: ソフトウェアページには、手動でダウンロード・インストールしたいユーザー向けに、他のさまざまなOSへのリンクも掲載されている。 イメージの手動書き込み・インストールについて助けが必要な場合は、SD Cards and Writing Imagesのチュートリアルを確認してほしい。

ハードウェアの組み立て

OSをmicroSDカードに書き込んだら、すべてを接続していこう。 このチュートリアルでは、すべての入力デバイスを単一のUSB接続にまとめるため、Logitech K400 Plus Wireless Touch Keyboardを使用した。 なお、このキーボードはSparkFun Raspberry Pi Zero 2 W Basic Kitには含まれていない

microSDカードを挿入する

microSDカードを、Pi Zero 2 WのmicroSDソケットに差し込む。

周辺機器を接続する

次に、周辺機器をPiに接続する。 ほとんどのユーザーは、Piを使い始めるのに少なくともモニタとキーボード・マウスが必要になる。

USB OTGケーブル

USB OTGケーブルを、PiのUSBとラベル付けされたmicro USBコネクタに差し込む。 これにより、キーボードやマウスなどのデバイス用に標準的なUSB接続が提供される。 Pi Zero 2 Wに複数のUSBデバイスを接続する必要がある場合は、USBハブまたは延長ケーブルが必要になる。

キーボードとマウス

USB OTGケーブルを使い、キーボード・マウスを差し込める。 このチュートリアルでは、両方のデバイスに1つのUSBドングルで対応できるLogitech K400 Plus Wireless Touch Keyboardを使用した。 他の標準的なUSBデバイスと組み合わせて使う場合は、電源付きのUSBハブを使うことを推奨する。

注意:ここに写っているLogitech K400 Plus Wireless Touch Keyboardは、Basic Kitには含まれていない

モニタ

Basic Kitに含まれるmini HDMIケーブルを、Pi Zero 2 Wのmini HDMIコネクタに接続する。 ケーブルのもう一方の端を、モニタやテレビのHDMIポートに接続する。

電源

すべてを接続し、microSDカードを挿入したら、電源をPWR INとラベル付けされたmicro USBコネクタに接続する。これでPiが起動を始めるはずである。

セットアップの完成形

すべてを接続すると、下の写真のようなセットアップになるはずである。

ハードウェアの接続を広げる

上記の手順は、Pi Zero 2 Wを立ち上げて動かすための基本にすぎず、この小さなコンピュータの可能性のごく一部しか使っていない。 Pi上の2×20のGPIOヘッダーには、さらに多くの追加機能へのアクセスが用意されているため、それを活用したいユーザーはこちらのようなヘッダーをはんだ付けしておくとよい。

Pi Zero 2 Wでブレッドボードプロトタイピングをしたいユーザーは、Pi Wedgeや、GPIOピンを使うための以下のチュートリアルを活用するとよい。

  • Preassembled 40-pin Pi Wedge Hookup Guide — Preassembled Pi Wedgeを使い、Raspberry Pi B+でプロトタイピングする方法
  • Raspberry PiのGPIO — PythonまたはC++を使い、Raspberry PiのI/Oラインを制御する方法
  • Headless Raspberry Pi Setup — キーボード、マウス、モニタなしでRaspberry Piを設定する方法

Pi Zero 2 WでSparkFunのQwiicデバイスを使いたい場合は、SparkFun Qwiic SHIM、Qwiic SHIM Kit、あるいはQwiic Starter Kit for Raspberry Piを確認してみてほしい。

  • Qwiic SHIM for Raspberry Pi Hookup Guide — PiでI2C部品をプロトタイピングしたいと思ったことはないだろうか。これでできるようになる
  • Qwiic SHIM Kit for Raspberry Pi Hookup Guide — QwiicシステムとPythonを使い、Raspberry Pi上でRGBバックライト付きシリアルLCDと9DoF IMU(ICM-20948)をI2C経由で使い始める。センサーの値を取得し、シリアルターミナルやSerLCDに表示する

最後に、カメラコネクタを使えばRaspberry Pi cameraを接続できる。 ただし、このコネクタは22ピン0.5mmピッチであり、標準的なPiとは異なる。 カメラをPi Zero 2 Wに接続するには、別のケーブルが必要になる。

ヘッドレス

モニタ、キーボード、マウスを使わない「ヘッドレス」なセットアップを好む場合は、以下のチュートリアルが助けになる(ヘッドレスセットアップは通常のセットアップよりかなり高度である点に注意してほしい)。

Raspberry Pi OSを使う

これでボードが立ち上がり動作するようになったので、Raspberry Pi OSの基本をいくつか紹介する。 この節では、HDMI出力でモニタに接続してPiを使う方法を扱う。

Raspberry Pi OS

Raspberry Pi OSはLinuxベースである(正確には、Raspberry Pi DesktopのDebian Bullseye移植版である)。 それほど身構える必要はない。 多くのコマンドを覚えたり、テキストエディタの保存・終了に:wqと入力したりする必要があった時代は終わった。 このOSは、WindowsやMacOSに似たデスクトップのグラフィカルユーザーインターフェース(GUI)で動作しており、いくつか基本的なコマンドやショートカットを覚えておいたほうがよいことは確かだが、たいていはそれらを使わなくても済ませられる。

初回起動

OSを新規インストールした状態でのPiの初回起動には数分かかり、Piはおそらく少なくとも一度は再起動する。 OSが初期セットアップを終えると、下の画像のようなデスクトップのセットアップ画面が表示されるはずである。

セットアップウィザードに従い、地域設定の構成、新しいパスワードの設定、WiFiへの接続、システムやパッケージの更新など、Pi上のさまざまな設定を行う。 これらの手順の一部は飛ばすこともできるが、少なくとも地域設定と新しいパスワードの設定は強く推奨する。 後で設定を見直したい場合は、Raspberry Pi Start Menu > Preferences > Raspberry Pi Configurationから開ける。

これにより、地域、モニタ、キーボード、パスワードを更新したり、SPIやI²Cといった各種周辺機器インターフェースを有効化したりできるポップアップが開く。

警告: Raspberry Piのセキュリティを確保するため、デフォルトのパスワードは変更することを推奨する。 保存する前に、パスワードを必ず安全な場所に控えておくこと。ユーザー名も変更できる。

ソフトウェアを更新する

セットアップウィザードでこの手順を飛ばした場合や、後でソフトウェアパッケージを更新する必要が出てきた場合は、コマンドラインインターフェース(CLI)を使ってPi上のソフトウェアパッケージを更新できる。 ターミナルを開き、次を入力してEnterを押す。

sudo apt-get update

このコマンドは、Piに最新のパッケージ情報を取得するよう指示し、パッケージマネージャーに何を更新する必要があるかを伝える。

  • sudo(スーパーユーザーとも呼ばれる)は、特にセキュリティレベルの高いコマンドでよく目にするコマンドである。 ユーザー名が特定のユーザー一覧(「sudoers」)に含まれていれば、(まだrootとしてログインしていない場合でも)一時的にこれらのコマンドを実行できるようになる。
  • apt-getはパッケージマネージャーであり、updateはそこに与えているコマンドである。

これにより、システム上のすべてのパッケージがダウンロード・更新される。時間がかかることがある。

シャットダウン・再起動

デスクトップのメインメニューには標準的なシャットダウンボタンが用意されているが、次のコマンドを使いCLI経由でPiにシャットダウンを指示することもできる。

sudo shutdown -h now
  • shutdownは、推測できるとおりマシンをシャットダウンする。nowは、その動作を即座に実行するよう指示する(15と指定すれば、15分後にシャットダウンするよう指示できる)。

CLI経由でPiを再起動するには、次のコマンドを送る。

sudo shutdown -r now

⚡ 警告: 正しくシャットダウンする前に電源を取り外すと、Raspberry Piのイメージが壊れてしまう。 Piの電源を取り外す前に、必ず正しくシャットダウンすること。 あるいは、GPIOを使ってPiの電源を切るPythonスクリプトを書くという方法もある。

その他の便利なLinuxコマンド

ターミナルのコマンドラインで使える、他にも便利なコマンドをいくつか紹介する。

  • pwd:Print Working Directoryの略。今どのフォルダにいるかわからないときに、ファイルシステム上の現在位置を教えてくれる
  • ls:List。フォルダの中身を表示する。隠しファイルを含むすべてのファイルを表示するにはls -aと入力する。ls -alと入力すると、すべてのファイル・フォルダに加えてその権限設定も表示される
  • cd:ディレクトリを変更するコマンド。cd foldernameでそのフォルダへ移動する。cd ..で1階層上に戻る。cd ~でホームディレクトリへ戻る
  • passwd:パスワードを変更できる
  • man:manualの略。コマンドの前にmanと入力すると、その使い方の概要が表示される
  • nano:比較的使いやすいシンプルなテキストエディタが開く

トラブルシューティング

Raspberry Piの動作に問題があるだろうか。 基本的なトラブルシューティングについては、Raspberry Pi Foundationのフォーラムにあるこの付箋を確認してみてほしい。

Pi Foundation Forums: Basic Troubleshooting with the Raspberry Pi

Raspberry Pi向けに設計されたSparkFunのハードウェアとのインターフェースで問題が発生しているだろうか。 SparkFunフォーラムを確認し、力になれるかどうか見てみてほしい。

SparkFun Forums

まとめ・参考資料

ここまでくれば、Pi Zero 2 Wは他のコンピュータと同じように動作しているはずである。 ここから先は、Linuxの細かい使い方を独学で学んだり、Pythonを学んだり、GPIOピンをプログラムしたり、Minecraft™サーバーを立てたり、ネットワークストレージシステム、ゲームコンソール、メディアセンターを構築したり、あるいは単にウェブを閲覧したりすることもできる。

Pi Zero 2 WやRaspberry Pi全般について、より詳しい情報は以下のリソースを確認してほしい。

Raspberry Pi Zero Wをドングルのように使いたいだろうか。Pi Zero USB Stemを確認してみてほしい。

インスピレーションが欲しければ、次のようなチュートリアルやプロジェクトも参考になる。

  • Raspberry Pi 3 Starter Kit Hookup Guide — Raspberry Pi 3 Model BおよびRaspberry Pi 3 Model B+スターターキットの使い始め方ガイド
  • Setting Up the Pi Zero Wireless Pan-Tilt Camera — Raspberry Pi Zeroをヘッドレスなワイヤレスパン・チルトカメラとして組み立て、プログラムし、アクセスする方法
  • Raspberry Pi Stand-Alone Programmer — ヘッドレスのRaspberry Piを使い、スタンドアロンのプログラマーとしてAVRマイクロコントローラーにHEXファイルを書き込む方法。プロダクションプログラミングの課題や、SparkFunがこの解決策にたどり着いた経緯、そこで得られた教訓についても紹介する
  • Graph Sensor Data with Python and Matplotlib — matplotlibを使い、Raspberry Piに接続したTMP102センサーの温度データをリアルタイムにグラフ表示する

タグ: Bluetooth、Hookup、IoT(モノのインターネット)、Raspberry Pi、シングルボードコンピュータ、WiFi、ワイヤレス


出典:Getting Started with the Raspberry Pi Zero 2 W(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Raspberry Piの安全な再起動・シャットダウンボタン

Raspberry Piが安全にシャットダウンする前に電源を抜いてしまうのはよくない。 microSDカードやファイルシステムが壊れてしまうことがある。 通常はGUIのメニューバーやターミナルウィンドウでのコマンド入力で安全にシャットダウンできる。 もっと手早い方法が欲しい場合(特にヘッドレスセットアップを使っている場合)は心配ない。 汎用ボタンとPythonスクリプトを使い、Raspberry Piを安全に再起動・シャットダウンできる。

必要な部品

このチュートリアルに沿って進めるには、以下の部品が必要になる。 すでに持っているものやセットアップによっては、すべてが必要になるとは限らない。 カートに追加し、ガイドを読み進めながら、必要に応じてカートを調整してほしい。

おすすめの読み物

これらのチュートリアルに馴染みがない場合は、目を通しておくことを推奨する。

ハードウェアの接続

接続はあっという間である。 まだであれば、Qwiic pHAT v2.0をRaspberry PiのGPIOヘッダーの上に重ねて差し込むだけでよい。 ケースを使っている場合は、確実に接続するために追加のスタッカブルヘッダーが必要になることがある。 下の画像は、スタッカブルヘッダーを使ってpHAT v2.0をPi 3に接続した様子を示している。

このチュートリアルでは、Raspberry Piを手軽に設定できるよう、モニタ・キーボード・マウスを使ったデスクトップセットアップを用いる。 まだであれば、必要な周辺機器を接続し、Piの電源を入れてほしい。

Example 1:安全なシャットダウン

コマンドラインに馴染みがある場合は、次のコマンドでPiをシャットダウンできる。

sudo shutdown -h now

以下のサンプルは、起動時にPythonスクリプトを読み込み、GPIO17に接続したボタンが押されたときにこのコマンドでRaspberry Piを安全にシャットダウンする。

サンプルコード

Raspberry Pi上で、下のボタンを押してPythonスクリプトをダウンロードする。

safe_shutdown_Pi.py」をダウンロード

コードをコピーしてテキストエディタに貼り付けてもよい。 その場合は、ファイル名を必ずsafe_shutdown_Pi.pyとし、保存した場所を覚えておくこと。

# safe_shutdown_Pi.py
#
# Qwiic pHAT v2.0の汎用ボタンを利用し、Piを安全に再起動・シャットダウンする。
#   1.) ボタンを短く押すと、Piはシャットダウンする。

import time
import RPi.GPIO as GPIO

# ピンの定義
shutdown_pin = 17

# 警告を抑制する
GPIO.setwarnings(False)

# "GPIO"のピン番号方式を使う
GPIO.setmode(GPIO.BCM)

# モーメンタリ式プッシュボタンを抵抗なしで使う場合、
# ピンがフローティングにならないよう内蔵の内部プルアップ抵抗を使う。
#GPIO.setup(shutdown_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Qwiic pHATのプルアップ抵抗を使い、ピンがフローティングにならないようにする
GPIO.setup(shutdown_pin, GPIO.IN)

# Piをシャットダウンするモジュール関数
def shut_down():
    print("shutting down")
    command = "/usr/bin/sudo /sbin/shutdown -h now"
    import subprocess
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print(output)


# ボタンが押されたら安全にPiをシャットダウンする
while True:
    # 短い遅延を入れないと、このコードがPiの処理能力を大きく消費してしまう
    time.sleep(0.5)

    # トラブルシューティング用に、コメントを外すとコマンドラインにボタンの状態を出力できる
    #print('GPIO state is = ', GPIO.input(shutdown_pin))
    if GPIO.input(shutdown_pin)== False:
        shut_down()

注意: このコードはQwiic pHATのプルアップ抵抗を使うよう書かれている。 抵抗なしのモーメンタリ式プッシュボタンを使う場合は、ピンがフローティングにならないよう内蔵の内部プルアップ抵抗を使える。 次の行の#を外してコメントを解除する。

#GPIO.setup(shutdown_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

続いて、次の行の先頭に#を追加する。

GPIO.setup(shutdown_pin, GPIO.IN)

調整後は、次のようになるはずである。

# モーメンタリ式プッシュボタンを抵抗なしで使う場合、
# ピンがフローティングにならないよう内蔵の内部プルアップ抵抗を使う。
GPIO.setup(shutdown_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Qwiic pHATのプルアップ抵抗を使い、ピンがフローティングにならないようにする
#GPIO.setup(shutdown_pin, GPIO.IN)

パスを設定する

注意: 以下の手順では、rc.localファイルを変更するため、テキストベースのターミナルを使ってPythonスクリプトを移動する。 Downloadsフォルダから**/home/pi**へファイルをドラッグして移動することもできる。

ダウンロードしたファイルはDownloadsフォルダに保存される。 ダウンロードが終わったら、Pythonスクリプトを**/home/piへ移動する必要がある。 そのためには、コマンドラインを開く。 次のコマンドでDownloads**フォルダへ移動する。

cd Downloads

mv Linuxコマンドを使い、次のコマンドでファイルを目的の場所(この場合は**/home/pi**)へ移動する。

mv shutdown_Pi.py /home/pi

ファイルが正しく移動されたか確認するため、ディレクトリを1階層上に戻るコマンドを使う。

cd ..

続けて、listコマンドでパスの中身を確認する。 上の画像を見ると、これは移動先にあるものを確認するために使われていることがわかる。 その場所にshutdown_Pi.pyファイルがあるはずである。

ls

rc.localを変更する

注意: まだであれば、Raspberry Piを起動時にスクリプトを実行するよう設定するチュートリアルを確認しておくことを推奨する。 このチュートリアルでは、rc.localファイルを変更する方法1を使う。

ターミナルを開いたまま、次のコマンドを入力する。

sudo nano /etc/rc.local

キーボードのキーで下にスクロールし、exit 0の行の直前に、次の行を入力する。

python /home/pi/safe_shutdown_Pi.py &

キーボードのCTRL + Xで保存・終了し、確認を求められたらy、続いてEnterを押す。 変更を反映させるため、次のコマンドを入力する。

sudo reboot

実際に確認できること

再起動後、Qwiic pHAT v2.0のGPIO17ボタンを押す。 これでPiがシャットダウンするはずである。 モニタを接続している場合は接続が切れることに気づくだろうが、電源を取り外す前にシャットダウンが完了するまで数秒待つこと。 Pi上の緑色のステータスLEDは、完全にシャットダウンすると点滅を止める。

これでPiから安全に電源を取り外せる。 再びPiに電源を入れるには、電源コネクタを差し戻すだけでよい。

Example 2:安全な再起動とシャットダウン

すばらしい。しかし、1つのボタンでもっと多くの機能が欲しくなったらどうすればよいだろうか。 ボタンを短く押したときは再起動、一定時間押し続けたときはシャットダウンと区別する条件を追加してみよう。 halt(-h)からreboot(-r)コマンドに切り替えることで、Piを再起動できる。

sudo shutdown -r now

以下のサンプルは、起動時に別のPythonスクリプトを読み込む。 GPIO17に接続したボタンをどれだけの時間押したかに応じて、Raspberry Piは安全に再起動またはシャットダウンする。

サンプルコード

Raspberry Pi上で、下のボタンをクリックしてPythonスクリプトをダウンロードする。

safe_restart_shutdown_Pi.py」をダウンロード

コードをコピーしてテキストエディタに貼り付けてもよい。 その場合は、ファイル名を必ずsafe_restart_shutdown_Pi.pyとし、保存した場所を覚えておくこと。

# safe_restart_shutdown_Pi.py
#
# Qwiic pHAT v2.0の汎用ボタンを利用し、Piを安全に再起動・シャットダウンする。
#   1.) ボタンを短く押すと、Piは再起動する。
#   2.) ボタンを約3秒間押し続けると、Piはシャットダウンする。

import time
import RPi.GPIO as GPIO

# ピンの定義
reset_shutdown_pin = 17

# 警告を抑制する
GPIO.setwarnings(False)

# "GPIO"のピン番号方式を使う
GPIO.setmode(GPIO.BCM)

# モーメンタリ式プッシュボタンを抵抗なしで使う場合、
# ピンがフローティングにならないよう内蔵の内部プルアップ抵抗を使う。
#GPIO.setup(reset_shutdown_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Qwiic pHATのプルアップ抵抗を使い、ピンがフローティングにならないようにする
GPIO.setup(reset_shutdown_pin, GPIO.IN)

# Piを再起動するモジュール関数
def restart():
    print("restarting Pi")
    command = "/usr/bin/sudo /sbin/shutdown -r now"
    import subprocess
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print(output)

# Piをシャットダウンするモジュール関数
def shut_down():
    print("shutting down")
    command = "/usr/bin/sudo /sbin/shutdown -h now"
    import subprocess
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print(output)


while True:
    # 短い遅延を入れないと、このコードがPiの処理能力を大きく消費してしまう
    time.sleep(0.5)

    # トラブルシューティング用に、コメントを外すとコマンドラインにボタンの状態を出力できる
    #print('GPIO state is = ", GPIO.input(reset_shutdown_pin))
    if GPIO.input(reset_shutdown_pin) == False:
        counter = 0

        while GPIO.input(reset_shutdown_pin) == False:
            # トラブルシューティング用に、コメントを外すとカウンタを確認できる。4を超えると再起動する。
            #print(counter)
            counter += 1
            time.sleep(0.5)

            # 長押し
            if counter > 4:
                shut_down()

        # 短押しであれば再起動する
        restart()

注意: このコードはQwiic pHATのプルアップ抵抗を使うよう書かれている。 抵抗なしのモーメンタリ式プッシュボタンを使う場合は、ピンがフローティングにならないよう内蔵の内部プルアップ抵抗を使える。 詳しい手順はExample 1と同様である。

パスを設定する

注意: 以下の手順では、rc.localファイルを変更するため、テキストベースのターミナルを使ってPythonスクリプトを移動する。 Downloadsフォルダから**/home/pi**へファイルをドラッグして移動することもできる。

これもDownloadsフォルダに保存される。 ダウンロードが終わったら、Pythonスクリプトを**/home/piへ移動する必要がある。 そのためには、コマンドラインを開く。 次のコマンドでDownloads**フォルダへ移動する。

cd Downloads

再びmvコマンドを使い、次のコマンドでファイルを移動する。

mv safe_restart_shutdown_Pi.py /home/pi

ファイルが正しく移動されたか確認するため、ディレクトリを1階層上に戻るコマンドを使う。

cd ..

続けて、listコマンドで確認する。

ls

rc.localを変更する

注意: まだであれば、Raspberry Piを起動時にスクリプトを実行するよう設定するチュートリアルを確認しておくことを推奨する。 このチュートリアルでは、rc.localファイルを変更する方法1を使う。

ターミナルを開いたまま、再び次のコマンドを入力する。

sudo nano /etc/rc.local

キーボードのキーで下にスクロールし、exit 0の行の直前で、ファイル名をsafe_restart_shutdown_Pi.pyに合わせて調整する。

python /home/pi/safe_restart_shutdown_Pi.py &

キーボードのCTRL + Xで保存・終了し、確認を求められたらy、続いてEnterを押す。

変更を反映させるため、次のコマンドを入力する。

sudo reboot

実際に確認できること

再起動後、Qwiic pHAT v2.0のGPIO17ボタンを短く押す。 これでPiが再起動するはずである。

GPIO17ボタンをもう少し長めに押し続けると、シャットダウンコマンドが実行される。 Piがシャットダウンするまで数秒待つ必要がある。 モニタを接続している場合は、まず接続が切れることに気づくだろう。 この時点でボタンから指を離してよい。 ここでも、Pi上の緑色のステータスLEDを確認してほしい。 完全にシャットダウンすると、LEDは点滅を止める。 これでPiから安全に電源を取り外せる。

より良くする

改善の余地は常にある。 執筆時点では、このサンプルコードがPi 3で使うと多くのリソースを消費することに気づいていなかった。 サンプルコードは動作するものの、実行時にかなりの量のリソースを消費しているとのユーザー報告があった。 Pi 4でtopコマンドを使ってCPU使用率を確認したところ、このコードはPiの処理能力の90%〜100%を占めていた。

考えられる解決策:遅延か割り込みか

同僚に確認したところ、原因はwhileループがピンの状態を常時チェックし続けていることで一致した。 以下は、PiのCPU負荷を減らすための2つの解決策である。

  • 短い遅延を追加する
  • 割り込みを使う

短い遅延を追加する

一つの提案は、小さな遅延を追加することだった。 Raspberry Piはプログラムをできる限り速く実行し続けるため、遅延を入れることでループ内でピンを高頻度にポーリングするのを防げる。 whileループにシンプルなtime.sleep(0.5)を追加するだけで、Piの再起動・シャットダウンのボタン押下を読み取る機能を保ったまま、CPUを大きく解放できる。

.
.
.

while True:
    # 短い遅延を入れないと、このコードがPiの処理能力を大きく消費してしまう
    time.sleep(0.5)

.
.
.

この遅延は、このチュートリアルのサンプルコードにあらかじめ組み込まれている。 すでにこのサンプルコードをアプリケーションに組み込んでいる場合は、whileループにtime.sleep(0.5)を追加し、変更を保存してPiを再起動すれば反映される。 もちろん、遅延を短くしてスクリプトの反応を速くすることもできる。 ただし、ボタンの状態をより頻繁にチェックすることになるため、CPU使用量は増える点に注意してほしい。

割り込みを使ってシャットダウンする

もう一つの提案は、ボタンが押されたときにだけコードを実行する割り込みを使うようコードを調整することだった。 Raspberry Pi上で、下のボタンを押してPythonスクリプトをダウンロードする。

safe_shutdown_interrupt_Pi.py」をダウンロード

コードをコピーしてテキストエディタに貼り付けてもよい。 その場合は、ファイル名を必ずsafe_shutdown_interrupt_Pi.pyとし、保存した場所を覚えておくこと。 続けて、上で説明した手順に従い、起動時にコードを実行するようrc.localファイルを変更する。

# safe_shutdown_interrupt_Pi.py
#
# Qwiic pHAT v2.0の汎用ボタンを利用し、Piを安全にシャットダウンする。
#   1.) ボタンを短く押すと、Piはシャットダウンする。
#
# このサンプルは割り込みも活用しているため、CPUの消費量はごくわずかである。
# Piの処理能力をすべて占有しないため、より効率的である。

import time
import RPi.GPIO as GPIO # Pythonパッケージリファレンス: https://pypi.org/project/RPi.GPIO/

# ピンの定義
shutdown_pin = 17

# 警告を抑制する
GPIO.setwarnings(False)

# "GPIO"のピン番号方式を使う
GPIO.setmode(GPIO.BCM)

# モーメンタリ式プッシュボタンを抵抗なしで使う場合、
# ピンがフローティングにならないよう内蔵の内部プルアップ抵抗を使う。
#GPIO.setup(shutdown_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Qwiic pHATのプルアップ抵抗を使い、ピンがフローティングにならないようにする
GPIO.setup(shutdown_pin, GPIO.IN)

# Piをシャットダウンするモジュール関数
def shut_down():
    print("shutting down")
    command = "/usr/bin/sudo /sbin/shutdown -h now"
    import subprocess
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print(output)


while True:
    # 短い遅延を入れないと、このコードがPiの処理能力を大きく消費してしまう
    time.sleep(0.5)

    # ボタン押下の立ち下がりエッジをデバウンス付きで待ち、
    # Piを安全にシャットダウンするためにリソースを消費しすぎないようにする
    channel = GPIO.wait_for_edge(shutdown_pin, GPIO.FALLING, bouncetime=200)

    if channel is None:
        print('Timeout occurred')
    else:
        print('Edge detected on channel', channel)

        # トラブルシューティング用に、コメントを外すとコマンドラインにボタンの状態を出力できる
        #print('GPIO state is = ', GPIO.input(shutdown_pin))
        shut_down()

GPIO.wait_for_edge()を使うことで、ボタン押下による立ち上がりまたは立ち下がりエッジを待つだけでよくなり、CPUを解放できる。 この場合は、ピン17の立ち下がりエッジを待っている。 ボタンが押されると、最初のサンプルと同様にPiをシャットダウンするコマンドを実行する。

割り込みを使って再起動とシャットダウンをする

前の節で説明したとおり、遅延を使う以外のもう一つの選択肢は、ボタンが押されたときにだけコードを実行する割り込みを使うようコードを調整することである。 Raspberry Pi上で、下のボタンを押してPythonスクリプトをダウンロードする。

safe_restart_shutdown_interrupt_Pi.py」をダウンロード

コードをコピーしてテキストエディタに貼り付けてもよい。 その場合は、ファイル名を必ずsafe_restart_shutdown_interrupt_Pi.pyとし、保存した場所を覚えておくこと。 続けて、上で説明した手順に従い、起動時にコードを実行するようrc.localファイルを変更する。

# safe_restart_shutdown_interrupt_Pi.py
#
# Qwiic pHAT v2.0の汎用ボタンを利用し、Piを安全に再起動・シャットダウンする。
#   1.) ボタンを短く押すと、Piは再起動する。
#   2.) ボタンを約3秒間押し続けると、Piはシャットダウンする。
#
# このサンプルは割り込みも活用しているため、CPUの消費量はごくわずかである。
# Piの処理能力をすべて占有しないため、より効率的である。

import time
import RPi.GPIO as GPIO # Pythonパッケージリファレンス: https://pypi.org/project/RPi.GPIO/

# ピンの定義
reset_shutdown_pin = 17

# 警告を抑制する
GPIO.setwarnings(False)

# "GPIO"のピン番号方式を使う
GPIO.setmode(GPIO.BCM)

# モーメンタリ式プッシュボタンを抵抗なしで使う場合、
# ピンがフローティングにならないよう内蔵の内部プルアップ抵抗を使う。
#GPIO.setup(reset_shutdown_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Qwiic pHATのプルアップ抵抗を使い、ピンがフローティングにならないようにする
GPIO.setup(reset_shutdown_pin, GPIO.IN)

# Piを再起動するモジュール関数
def restart():
    print("restarting Pi")
    command = "/usr/bin/sudo /sbin/shutdown -r now"
    import subprocess
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print(output)

# Piをシャットダウンするモジュール関数
def shut_down():
    print("shutting down")
    command = "/usr/bin/sudo /sbin/shutdown -h now"
    import subprocess
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print(output)


while True:
    # 短い遅延を入れないと、このコードがPiの処理能力を大きく消費してしまう
    time.sleep(0.5)

    # ボタン押下の立ち下がりエッジをデバウンス付きで待ち、
    # Piを安全に再起動・シャットダウンするためにリソースを消費しすぎないようにする
    channel = GPIO.wait_for_edge(reset_shutdown_pin, GPIO.FALLING, bouncetime=200)

    if channel is None:
        print('Timeout occurred')
    else:
        print('Edge detected on channel', channel)

        # トラブルシューティング用に、コメントを外すとコマンドラインにボタンの状態を出力できる
        #print('GPIO state is = ', GPIO.input(reset_shutdown_pin))
        counter = 0

        while GPIO.input(reset_shutdown_pin) == False:
            # トラブルシューティング用に、コメントを外すとカウンタを確認できる。4を超えると再起動する。
            #print(counter)
            counter += 1
            time.sleep(0.5)

            # 長押し
            if counter > 4:
                shut_down()

        # 短押しであれば再起動する
        restart()

ここでもGPIO.wait_for_edge()を使い、ピン17の立ち下がりエッジを待つ。 ボタンが押されると、2つ目のサンプルと同様にPiを再起動またはシャットダウンするコマンドを実行する。 ボタンは押され続けている間、状態が変化しない。 そこで、ボタンがどれだけの時間押されているかを確認する。 短押しであればPiは再起動する。 カウンタが4を超える長押しであれば、Piはシャットダウンする。

どちらの方法がより良いか

では、短い遅延と割り込みでは、どちらがより効果的だろうか。 短い遅延を追加すると、CPUの消費量はおよそ0.3%まで大幅に削減された。

割り込みを追加した場合も、CPUの消費量は大幅に削減された。 スクリプトはGPIO.wait_for_edge()の行に達すると、CPUの消費をやめた。 コマンドラインでtopを使った後、一覧の上位に表示されなかったため、Lコマンドでpythonという単語を入力してプロセスを検索する必要があった。

短い遅延を追加する方法は手早い修正ではあるが、反応が遅く、ボタンの状態を確認し続けることでPiの処理能力の一部を無駄にしていた。 割り込みを追加する方法はそれほど単純ではないものの、反応が速く、ボタンの立ち下がりエッジを待つだけなのでPiの処理能力を無駄にしない、より効率的な方法だった。 総じて、割り込みを使う方が優れていると言えるが、急いでコードを書きたい場合は遅延を追加する方法が代替案になる。

まとめ・参考資料

より詳しい情報は、以下のリンクを確認してほしい。

次のプロジェクトのアイデアが欲しければ、Pi AVR Programmerを確認してみてほしい。基板のプログラムとテストの後にシャットダウンコードを実装している。

  • Raspberry Pi Stand-Alone Programmer — ヘッドレスのRaspberry Piを使い、スタンドアロンのプログラマーとしてAVRマイクロコントローラーにHEXファイルを書き込む方法。プロダクションプログラミングの課題や、SparkFunがこの解決策にたどり着いた経緯、そこで得られた教訓についても紹介する
  • Pi AVR Programmer HAT Hookup Guide — Raspberry Pi 3とPi AVR Programmer HATを使い、ATMega328Pをターゲットにプログラムする方法。まずSPI経由でArduinoブートローダーをプログラムし、続いてUSBシリアルCOMポート経由でArduinoスケッチをアップロードする

関連するチュートリアルも参考になる。

タグ: 入力デバイス、プロジェクト、Python、Qwiic、Raspberry Pi、シングルボードコンピュータ


出典:Raspberry Pi Safe Reboot and Shutdown Button(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Raspberry PiでNintendo Switchのマクロを記録する

このチュートリアルでは、Joycontrolを改造したバージョンをインストールする。 Joycontrolは、Bluetooth経由でRaspberry Pi上にNintendo Switchのコントローラーをエミュレートできるオープンソースプロジェクトである。 オリジナルのプロジェクトはシンプルなコマンドラインインターフェースでSwitchを操作できるが、もっと機能を追加したいというアイデアがあったため、リポジトリをフォークして作業に取りかかった。

Raspberry PiをNintendo Switchに、Proコントローラーとして接続する

Joycontrol-msには、キーボード操作、マクロの記録・再生機能が追加されており、便利にするためSparkFun Top pHATとも統合されている。 自分だけのカスタムコマンドを書きたい場合のために、すべてを動かしているコードについても掘り下げる。

必要な部品

このチュートリアルに沿って進めるには、以下の部品が必要になる。 持っているものによっては、すべてが必要になるとは限らない。 カートに追加し、ガイドを読み進めながら、必要に応じてカートを調整してほしい。

  • Raspberry Pi
  • SparkFun Top pHAT

他に必要なもの

  • Nintendo Switch本体

おすすめの読み物

Raspberry PiやSparkFun Top pHATに初めて触れる場合は、先に進む前に次のページを確認しておくとよい。

ハードウェアのセットアップ

注意: このチュートリアルは、Pi上にすでにRaspbianをセットアップ済みであることを前提とする。 まだPiをセットアップしていない場合は、Hookup Guideを参照して準備を整えてほしい。

  • Raspberry Pi 4 Kit Hookup Guide — Raspberry Pi 4 Model Bの基本キット、デスクトップキット、ハードウェアスターターキットの接続ガイド

Top pHAT用にすでにPiのセットアップ・設定を終えている場合は、このステップを飛ばして構わない。 Top pHATの組み立てはかなり単純である。 Raspberry PiのGPIOピンに直接差し込むだけでよい。 最も重要な点として、pHATの向きに注意し、ピンが正しく揃っているか必ず確認すること。 以下にいくつかの例を示すので参考にしてほしい。 このプロジェクトではPi 4 Model Bを使っているが、Bluetoothを搭載したほとんどのPiで動作するはずである。 Top pHATとのクリアランスのためにヘッダーが必要なPiを使う場合は、必ずヘッダーを購入しておくこと。

まず、必要であれば下の画像のようにメスヘッダーを接続する。

次に、Top pHATを取り付け、キーボードとマウスを接続する。 最初は、HDMIポートの一つを使って外部ディスプレイにも接続しておくとよい。 最後に、USB-C電源アダプタを接続し、コンセントに差し込む。

Piが起動したら、Top pHAT向けの設定を行い、Joycontrol-msとその依存関係をインストールできる。

OSの設定とJoycontrol-msのインストール

Top pHAT用にすでにPiのセットアップ・設定を終えている場合は、このステップを飛ばして構わない。 この手順は、SparkFun Top pHAT Hookup GuideのOS Configuration part 1(WS2812B LEDと2.4インチTFTディスプレイ)とOS Configuration part 2と同じものである。 このプロジェクトではHATの機能をすべて使うわけではないため、急いでいる場合はこのセットアップ手順だけを完了させれば十分である。

まず、Raspberryロゴ > Preferences > Raspberry Pi Configurationをクリックし、オーバースキャンを無効化する。

「Disable Overscan」のオプションを選択する。

次に、「interfaces」タブをクリックし、SPIとI2Cのインターフェースを有効化する。

これでOKをクリックできるが、まだPiを再起動しないこと。 Raspberry Pi Configurationのウィンドウには後で戻り、そのときに再起動する。

このプロジェクトはオンボードのアドレサブルLEDを利用するため、Adafruit Neopixel Pythonパッケージをインストールする必要がある。 ターミナルを開き、次のコマンドをウィンドウにコピーして、Enterキーを押す。

sudo pip3 install adafruit-circuitpython-neopixel

次に、2.4インチTFTディスプレイを使うために、ドライバーモジュールとモジュール設定を追加する必要がある。 ターミナルに、次の内容をコピー&ペーストしてEnterキーを押す。

sudo nano /etc/modules

nanoが開いたら、ファイルの末尾に次の内容をコピー&ペーストする。

spi-bcm2835
fbtft_device

続いて、キーボードのCtrl+Xを押して終了し、Yで変更を承諾、Enterで変更を書き込んでnanoを終了する。 続いて、モジュール設定についても同じ手順を繰り返す必要がある。 ターミナルに、次をコピー&ペーストする。

sudo nano /etc/modprobe.d/fbtft.conf

nanoが開いたら(今回は画面がほぼ空白のまま表示される)、次の内容をコピー&ペーストし、変更を保存して終了する。

options fbtft_device name=fb_ili9341 gpios=reset:23,dc:24 speed=16000000 bgr=1 rotate=180 custom=1

ここでも、キーボードのCtrl+Xを押して終了し、Yで変更を承諾、Enterで変更を書き込んでnanoを終了する。

次に、Joycontrol-msの依存関係をインストールする。 必要な依存関係は3つある。 ここでは、次のコマンドをターミナルにコピー&ペーストするだけでよい。

sudo apt install python3-dbus libhidapi-hidraw0
sudo pip3 install keyboard

これが完了したら、joycontrol-msをインストールしたいディレクトリにcdで移動し、そこでリポジトリをクローンする。 筆者はデスクトップにクローンした。

cd Desktop
git clone https://github.com/marcus-stevenson/joycontrol-ms.git

続いて、Joycontrol-msにcdで移動し、次を実行する。

sudo pip3 install .

これでセットアップはすべて完了しているはずである。 残る作業は、Raspberry Pi Configurationのウィンドウに戻り、「boot to CLI」を選択することだけである。

これで、Piを再起動できる。 これ以降はTop pHATのディスプレイを使うため、この段階でHDMIディスプレイを取り外しておくのも良いタイミングである。 この目的のためには、再起動ではなく完全なシャットダウンを推奨する (電源ケーブルをバッテリーパックに置き換えれば、このプロジェクトはさらに携帯性を高められる)。

Joycontrolの使い方

プログラムを実行してNintendo Switchに接続するには、Switch側で「Change Grip/Order」メニューを開き、joycontrol-msにcdで移動して次のコマンドを入力する。

sudo python3 ./run_controller_cli.py PRO_CONTROLLER

すべてを正しく設定できていれば、コントローラーがSwitchに接続される様子が表示されるはずである。

Pi側のターミナルには大量の情報が出力される。 これには少し時間がかかることもあるが、最終的にターミナルに「cmd>>」と表示される。 この時点で接続が完了しており、CLIにコマンドを入力する準備ができている。 まず次を試してみてほしい。

cmd>> a

Enterを押し、Switchが反応するまで待つ。 最初の数回のボタン入力は反映されるまで少し時間がかかることがあるため、「cmd>>」のプロンプトが表示されていても、忍耐強く反応を待つこと。 最初の「A」コマンドが認識されると、コントローラーのメニューに戻る。 「A」コマンドを送りすぎると、すぐに「change grip/order」画面に再突入してしまい、Piの接続がSwitchから切断される。 これが起きた場合は、sudo python3 ./run_controller_cli.py PRO_CONTROLLERをもう一度実行して再接続すればよい。

Nintendo Switchのホーム画面に戻ったら、CLIにhelpと入力してEnterを押す。 これで利用可能なすべてのコマンドとその説明が表示されるが、キーボードの方向キーでスクロールして戻らないと全文を読めないことがある。

以下は、すべてのコマンドの一覧である。

ボタンコマンド

画像提供:Nintendo of America

コマンド一覧

  • stick:スティックの位置を設定するコマンド
    • :param side:'l''left'は左スティック、'r''right'は右スティック
    • :param direction:'center''up''down''left''right''h''horizontal'または'v''vertical'を指定すると、値をvalue引数へ直接設定する
    • :param value::水平方向または垂直方向の値
  • test_buttons:「Test Controller Buttons」メニューへ移動し、すべてのボタンを押す
  • keyboard:キーボードにコントロールをバインドする
  • recording:キーボードにコントロールをバインドし、記録を停止するまで入力を記録する。保存した記録はcmd >> recording_playbackで再生できる

キーボードと記録用のキーバインドは次のとおりである。

q = LEFTf = RIGHTg = capture
w = LStickUPi = RStickUPh = home
a = LStickLEFTj = RStickLEFTe = UP
s = LStickDOWNk = RStickDOWNc = DOWN
d = LStickRIGHTl = RStickRIGHTup = X
t = Ly = Rdown = B
r = ZLu = ZRplus = +
left = Yright = Aminus = −
  • playback:保存した記録を選び、再生する
  • delete_rec:保存した記録を選び、削除する
  • mash:指定したボタンを設定した間隔で連打する
    • 使い方:mash <button> <interval>
  • nfc:NFCコンテンツを設定する
    • 使い方:
      • nfc <file_name>:コントローラーの状態にあるNFCコンテンツをファイルから設定する
      • nfc remove:コントローラーの状態からNFCコンテンツを削除する

基本から始めよう。 そのボタンのラベルを入力してEnterを押すだけで、個別のボタン入力をエミュレートできる。 たとえば次のようになる。

cmd>> x
cmd>> y
cmd>> plus
cmd>> capture
cmd>> zl

「&&」を使えば、複数のボタン入力を連結できる。

cmd>> zl&&zr
cmd>>left&&left&&left&&a

ジョイスティックはCLIから使うにはあまり便利ではないが、次のように設定できる。

cmd>> stick left right

このコマンドは、左スティックを最も右の位置に設定する。 次のコマンドを送って中立の「center」位置に戻すまで、この状態を保つ。

cmd>> stick left center

止めるまで単一のボタンを「連打」し続けたい場合は、次のコマンドを使う。

cmd>> mash a 5

これは、Enterを押すまで5秒ごとに「a」ボタンを押し続ける。

マクロの記録

これらのCLIコマンドはどれも試して楽しいものだが、求めていた機能にはまだ足りなかった。 そこで、キーボード操作をコントロールにバインドして直接Switchを操作したり、そのキーボード操作を記録したり、マクロのように再生したり、不要なマクロを削除したりできる、いくつかの追加コマンドを実装した。 マクロは、それぞれのJoycontrolセッションを終了した後も保持される。

まず、Piに接続したキーボードでNintendo Switchを操作するには、次のコマンドを使う。

cmd>> keyboard

<enter>を押してキーボードをコントローラーにバインドするよう促される。 キーボード操作を止めるには、もう一度<enter>を押す。 キーバインドは次のとおりである。

マクロを記録するには、次のコマンドを使う。

cmd>>  recording

記録の名前を入力するよう促されるので、後で再生できるようにしておく。 Enterを押すと、Joycontrolはキーボード操作でSwitchを操作している間の入力を記録し始める(キーバインドは「keyboard」コマンドと同じである)。 記録を止めるには、もう一度<enter>を押す。 記録中は、Top pHATのRGB LEDが赤く点灯する。

記録したマクロを再生するには、次のコマンドを使う。

cmd>> playback

playbackコマンドを送信すると、再生したいマクロの名前を入力するよう促される。 保存されているマクロがあれば、一覧表示される。 記録したマクロを再生している間は、HATのLEDが緑色になるはずである。

あらかじめ「mario」という名前のマクロが1つ用意されているはずである。 このマクロは、オリジナルのスーパーマリオブラザーズのワールド1-1をクリアする。 SwitchにNESのバーチャルコンソールをインストールしている場合は、NESを開いてスーパーマリオブラザーズを選び、「plus」を押してゲームを開始すれば、このマクロを自分で試せる。 ワールド1-1を開始したら、playbackコマンドを使い「mario」を選択する。 マリオがこのゲームの象徴的な最初のステージを進んでいく様子が見られるはずである。 ただし、タイミングはやや難しい。 マクロを開始する前にマリオを動かしてしまうと、再生のタイミングがずれてしまい、マクロが再生を終えるまでマリオが死んだり、隅に引っかかったりしてしまう。

最後に、不要になったマクロは次のコマンドで削除できる。

cmd>> delete_rec

削除したいマクロの名前を入力するよう促される。 delete_recのプロンプトが開いている間は、HATのLEDが青く点灯するはずである。

次の節では、Joycontrol-msのさまざまな機能を使って「あつまれ どうぶつの森」を「プレイ」する方法をさらに探っていく。

Joycontrolとどうぶつの森

あのArduinoを見てほしい!

Amiiboを「なりすます」方法を探しているうちにJoycontrolを見つけたのだが(その詳細はここには書かないが、他の場所にはたくさん情報がある)、このゲームの面倒な部分の一部を「自動化」できる可能性にすぐ気づいた。

ACNH(あつまれ どうぶつの森)の島を自動化する目的以外でこのチュートリアルを読んでいる人のために、少し説明を補っておこう。 馴染みがない場合のために説明すると、どうぶつの森はNintendoによるゲームシリーズであり、擬人化した動物の友人(プレイの仕方によっては敵にもなる)たちと暮らす仮想の村人として、仮想の生活を送るゲームである。 プレイヤーは、虫や魚を捕まえて売るといったさまざまな作業でベル(お金)を稼ぐ。 このゲーム内のさまざまなキャラクターとやり取りするインターフェースは延々と続くテキストメニューであり、プレイし続けるほどうんざりするくらい繰り返しになることが多い。 あまりに繰り返しが多いため、単なる焦れったさやボタン連打で意図しない選択をしてしまうこともよくある。

このゲームは間違いなく心から楽しんでいる。

よくやることの一つに、ポケットをいっぱいにしてから、道具以外の中身をすべてタヌキ商店のたぬきちの息子たち(まめきちとつぶきち)に売る、という作業がある。 これはマクロにうってつけの候補である。 このマクロを記録するには、まずポケットをいっぱいにし(記録中はプレースホルダーとして薪の束を分割して使うので、中身は何でもよい)、まめきちとつぶきちのところへ話しかけに行く。 また、インベントリ内で手袋のカーソルがどこにあるかにも注意しておくこと。これは後で重要になる。 筆者は左上に置くようにしている。

メニューを開いたら、Pi上で記録を開始する。

cmd>> recording

マクロの名前を入力した後、Pi上のキーボードを慎重に使い、再生してほしいとおりに正確に販売の手順を進める。 このマクロでは、ポケットの下3段にあるアイテムをすべて選択して売るように記録した。

記録が終わったらEnterを押す。 マクロを再生するには、playbackコマンドを使い、選んだ名前を入力する。 再生を始める前に、ポケットがいっぱいであること、手袋のカーソルがマクロを記録し始めたときと同じ位置にあること、まめきちとつぶきちの最初のメニューを開いていることを必ず確認しておくこと。

cmd>> playback
(マクロの名前を入力する)

マクロを記録したときとすべての条件が同じであれば、これでこの種の繰り返し作業を「飛ばす」ために再利用できるようになるはずである。 マクロ記録をどう使うかはゲーム内での必要や習慣によって変わるが、筆者が使ってきた例をいくつか挙げておく。

  • 博物館へのアイテムの寄贈
  • フータによる化石の鑑定
  • DIYレシピの連続作成
  • 花への水やり
  • ポケットから収納へのアイテムの一括移動

このゲームには非常に幅広い活動があるため、まだ思いついていない使い道もきっとあるはずである。 このチュートリアルは、Joycontrol-msを他のゲームで使う方法についてはほんの触りにすぎない。 ただし、ベルを一度に使い果たしてしまわないように気をつけてほしい(あるいは、使い果たしてしまってもよいが……)。

前の節で説明したとおり、不要なマクロは次のコマンドで削除できる。

cmd>> delete_rec
(削除したいマクロの名前を入力する)

そして、Joycontrolを使い終えたら、exitコマンドで接続を切断する。

cmd>> exit

トラブルシューティング

製品が期待どおりに動作しない場合や、技術的なサポートや情報が必要な場合は、SparkFun Technical Assistanceのページで初期のトラブルシューティングを確認してほしい。

そこで解決しない場合は、SparkFunフォーラムがヘルプを探したり質問したりするのに適した場所である。 初めて訪れる場合は、製品フォーラムを検索したり質問を投稿したりするためにフォーラムアカウントの作成が必要になる。

まとめ・参考資料

SparkFunには、Raspberry Pi関連のプロジェクトやチュートリアルが幅広く揃っている。 以下のリンクもぜひ確認してほしい。

他にも、次のようなRaspberry Pi関連のチュートリアルがある。

  • Raspberry PiのSPIとI2C — C/C++用のwiringPi I/OライブラリとPython用のspidev/smbusを使い、Raspberry PiのシリアルI2CバスとSPIバスを利用する方法
  • MQTT入門 — IoT(モノのインターネット)で使われる主要な通信プロトコルの一つ、MQTTの入門
  • Computer Vision and Projection Mapping in Python — コンピュータビジョンを使って顔を検出し、その上に画像を投影する
  • Qwiic pHAT Extension for Raspberry Pi 400 Hookup Guide — Raspberry Pi 400のGPIOにすばやく簡単にアクセスし、お気に入りのHATを正しい向きで重ねたり、Qwiic対応デバイスをI2Cバス(GND、3.3V、SDA、SCL)に接続したりする方法

タグ: Bluetooth、Bluetooth 4.0、ゲーム、ゲーミング、LED、プログラミング、プロジェクト、Raspberry Pi、シングルボードコンピュータ、WiFi


出典:Nintendo Switch Macro Recording on the Raspberry Pi(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

micro:bitを始める

micro:bitというものを買った、あるいはさらによいことに、更新版のmicro:bit v2を買ったとしよう。 しかし、これは一体何なのだろうか。

BBC micro:bitは、デジタル技術を使ってクリエイティブなものを作れる、ポケットサイズのコンピュータである。 どこからでもmicro:bitをコード化し、カスタマイズし、制御できる。 micro:bitは、ロボットから楽器まで、あらゆるユニークな作品作りに使える。

micro:bitは、コンピュータサイエンス教育とSTEM分野を英国のすべての生徒に届けることを目指した、BBCによるプロジェクトである。 オンボードのハードウェアコンポーネントと連携して動作するオープンな開発ボードであり、ハードウェアのプログラミングという道を歩み始めるきっかけになる。

クレジットカードの半分ほどのサイズしかないが、各ボードに搭載されているハードウェアの量には驚かされるはずである。 メッセージを点滅表示できる25個の赤色LEDライトもその一つである。 ゲームの制御や、プレイリストの一時停止・スキップに使える、プログラム可能な2つのボタンもある。 micro:bitはモーションを検知し、自分がどの方向を向いているかを教えてくれることさえできる。 Bluetooth Low Energy(BLE)を使い、他のデバイスやインターネットとやり取りすることもできる。

micro:bitには、内蔵のコンパス、加速度センサー、モバイル・Webベースのプログラミング機能が備わっている。 micro:bit v2では、オンボードスピーカーとMEMSマイクロホン、そしてタッチセンシティブなロゴが追加されている。 どちらのボードも、さまざまな言語に対応した多数のオンラインコードエディタと互換性がある。 このガイドでは、Microsoftが開発したブロックまたはJavaScriptベースの環境であるMakeCodeを扱う。

必要な部品

このチュートリアルに沿って進めるには、micro:bitとmicro USBケーブルだけが必要になる。 とてもシンプルである。

おすすめの読み物

以下のチュートリアルも確認しておくことを推奨する。

  • I2C — 現在広く使われている主要な組み込み用通信プロトコルの一つ、I2Cの入門
  • micro:bit Breakout Board Hookup Guide — micro:bitブレイクアウトボードの使い始め方

ハードウェア概要

BBC micro:bitには2つのバージョンがあり、どちらもオンボードの入出力に関して多くの機能を備えている。 実際、これらの小さなボードには非常に多くの機能が詰め込まれているため、プログラミングとハードウェアの基礎を探求するだけであれば、他にはほとんど何も必要とならないはずである。

表面

ボードの表面には、一目で見てわかる部品がいくつも搭載されている。

LEDアレイ

micro:bitには、小さな画面として使い、絵を描いたり、単語・数字・その他の情報を表示したりできる5×5のLEDアレイが搭載されている。

左:micro:bitのLEDアレイ 右:micro:bit V2のLEDアレイ

A/Bボタン

カチッと押せる2つのボタンがある。Aは左側、Bは右側にあり、どちらも自分で設計したゲームの操作にぴったりである。

左:micro:bitのA/Bボタン 右:micro:bit V2のA/Bボタン

エッジ「ピン」

ボードの下部にある金色のタブは、外部部品を接続するためのものである。 穴が大きいタブはワニ口クリップを使えば手早くプロトタイピングできる。 すべてのピンにアクセスするには、エッジコネクタ付きのボードが必要になる。 ブレッドボードでのプロトタイピングには、ヘッダー付きのmicro:bitブレイクアウトが向いている。 micro:bit v2では、ワニ口クリップで接続しやすいよう切り欠きが追加されていることにも気づくはずである。

左:micro:bitのエッジピン 右:micro:bit V2のエッジピン

注意: 大きめのスルーホールへの接続方法は、自由な発想で工夫できる。 一部のボードでは、シャフトに沿ってテーパーのかかった皿ねじやトラスねじ、ナイロンスペーサー、六角ナットを使ってスルーホールにアクセスできる。 下の画像は、皿ねじを使ってmicro:bitをKitronik MI:power Board V2に接続した様子である。

皿ねじを使う方法は、ワニ口クリップの代わりにしっかりとした接続を得られる代替手段でもある。 詳しくは、次のブログ記事を確認してほしい:micro:bit - Hacking the GPIO - Updated!

光センサー

ちょっとした隠れた宝である。LEDアレイは光センサーも兼ねている。

(画像はLEDアレイの節と同じである)

V2限定:マイク入力とLEDインジケーター

マイク入力とLEDインジケーターは、ボード上部にあるタッチセンシティブなロゴの右側にある。

V2限定:タッチセンシティブなロゴ

金色のロゴは静電容量式タッチセンサーであり、携帯電話のタッチスクリーンのように、電気のわずかな変化を測定して動作する。

裏面

裏面では、多くの魔法が起きている。見てみよう。

マイクロコントローラー

このボードの頭脳である。

micro:bitは、256KBのフラッシュメモリと16KBのRAMを備えた16MHzのARM Cortex-M0マイクロコントローラーで動作する。

micro:bit v2は、Nordic SemiconductorのnRF52833チップ(FPU付き64MHzのARM Cortex-M4マイクロコントローラー、512KBのフラッシュメモリ、128KBのRAM)で動作する。

左:micro:bitのnRF51822プロセッサ 右:micro:bit V2のnRF52833プロセッサ

加速度センサー・コンパス

micro:bitには、重力を測定するオンボードの加速度センサーに加え、地球の磁場を使って自身の向きを検出できるコンパス(磁力計)が搭載されている。

左:micro:bitの加速度センサーと磁力計 右:micro:bit v2の加速度センサーと磁力計

Bluetooth・無線

micro:bitにとって通信は非常に重要な機能である。 Bluetooth Low Energy(BLE)を使ってスマートフォンやタブレットと通信したり、標準の2.4GHz「無線」を使って2台以上のmicro:bit同士で通信したりできる。 なお、micro:bit v1はBLE Bluetooth v4.0を、micro:bit v2はBLE Bluetooth v5.0を使う。

左:micro:bitのBluetooth・無線アンテナ 右:micro:bit v2のBluetooth・無線アンテナ

温度センサー

いや、この図の強調表示は間違っていない。マイクロコントローラーは温度センサーも兼ねている。

(画像はマイクロコントローラーの節と同じである)

USBポート

micro:bitへのコードのアップロードや、コンピュータ・ラップトップからの給電に使う。 MakeCodeのシリアルコンソールやシリアルターミナルを使い、シリアルデータの送受信もできる。

左:micro:bitのUSBポート 右:micro:bit v2のUSBポート

USBアクティビティLEDインジケーター

USBピンに通信が発生すると、右側のLEDが点灯する。

V2限定:電源LED

micro:bitのV2には、USBコネクタの隣に、電源が供給されていることを示す電源LEDも搭載されている。

リセットボタン

micro:bitをリセットし、コードを最初からやり直すためのボタンである。

左:micro:bitのリセットボタン 右:micro:bit v2のリセット・電源ボタン

注意: micro:bit V2のリセットボタンは、micro:bitを「オフ」にする電源ボタンとしても機能する。 厳密には、ボタンを5秒間押し続けると、ディープスリープモードになる。 詳しくは、micro:bit V2のリセットボタンに関するMakeCodeの記事を確認してほしい。

JSTバッテリーコネクタ

外部のバッテリーパックをmicro:bitに接続するためのコネクタである。

左:micro:bitのJSTコネクタ 右:micro:bit v2のJSTコネクタ

警告: JST-PHコネクタは通常LiPoバッテリーで使われる。 LiPoバッテリーは、2xAAや2xAAAのバッテリーパックで使う電池とは電池化学・電圧が異なる。 LiPoバッテリーの電圧を調整する電圧レギュレータを持っていない限り、micro:bitのJST-PHコネクタにはAAまたはAAA電池のみを使うこと。

V2限定:マイクロホン

micro:bitのV2には、別のデバイスを接続しなくても音を検知できるMEMSマイクロホンが搭載されている。 ボードの表面をもう一度見ると、マイク入力が裏面のこの部品につながっていることに気づくはずである。

V2限定:スピーカー

micro:bitのV2には、ボード裏面に内蔵スピーカーも搭載されている。 エッジピンに接続した外部スピーカーを使いたい場合は、使用するプログラミング言語で内蔵スピーカーの設定を行う必要がある。

これだけの機能が詰まっている。まさに万能ナイフである。

注意: より詳しいハードウェア情報については、micro:bit Foundationによる公式のHardware Overviewも確認してほしい。 micro:bit Foundation: Hardware Overview

接続する

micro:bitは、コンピュータやChromebookに接続するのにmicro USBケーブルを使う。 ケーブルをmicro:bitに差し込み、もう一方の端を空いているUSBポートに差し込むだけでよい。

ボードを接続すると、micro:bitの裏面にある小さな黄色のLEDが点灯し、数回点滅することがある。 続いて、micro:bitにすでに書き込まれているプログラムが実行され始める。 初めてmicro:bitを接続した場合は、しばらく触ってみてほしい。ボタンを押したり、振ったりすると、ちょっとした隠し要素に出会えるはずである。

micro:bitが起動したら、Macの場合はFinderを、PCの場合はマイコンピュータを確認してほしい。 micro:bitは、2つのファイルが保存された外部ストレージデバイスとして表示されるはずである。

Chromebookを使っている場合は、micro:bitを接続するとドライブを開くダイアログボックスが表示される。 遠慮なく開いて、動作を確認してみてほしい。

さあ、プログラミングを始めよう。

MakeCodeを使う

このガイドと、SparkFunが提供するmicro:bit関連コンテンツのほとんどは、MicrosoftによるMakeCodeを使ってプログラミングを行う。

MakeCodeとは何か

MakeCodeは、micro:bit向けに、そして他のボード向けにもMicrosoftが構築したオープンなプログラミング環境である。 次のリンクから、micro:bit用のMakeCodeへ移動できる。

MakeCodeを起動する

MakeCodeを起動すると、ブラウザのウィンドウを最大化した状態では、左側にシミュレータ、右側にブロックベースの環境が配置された基本レイアウトが表示される。

MakeCodeには、次のような機能が用意されている。

  • プロジェクト:アカウントの設定不要で、コンピュータに接続されたクラウドストレージシステム
  • シェア:さまざまな方法でプロジェクトのコードを友人と共有できる
  • Blocks/JavaScript/Python:ブロック(デフォルト)とJavaScriptのどちらでプログラミングするか、自分で選べる。Microsoftは、後にコードをMicroPythonへ変換する追加オプションも用意した
  • プログラム領域:魔法が起きる場所、プログラムを組み立てる場所、つまり「コードを作る(make code)」場所である
  • ズーム/元に戻す・やり直す:元に戻したり、ズームアウトして全体を見渡したりするためのボタン
  • 名前を付けて保存:プログラムに名前を付けて保存(コンピュータにダウンロード)する
  • ダウンロード:保存と似ているが、プログラムを.hexファイルとしてダウンロードし、micro:bitへドラッグする
  • シミュレータの表示/非表示:好みに応じてシミュレータを表示・非表示にできる
  • ブロックライブラリ:プログラムを組み立てるためのブロックの選択肢一覧。機能ごとに色分けされている
  • シミュレータ:ハードウェアは不要である。MakeCodeにはリアルタイムのシミュレータが用意されている。プログラムを変更すると、この仮想micro:bit上でその動作を確認できる

さて、これで選択肢ができた。ブロックにするか、テキストベースのプログラミングにするか。

ブロックかテキストか

このガイドと、SparkFunが提供するmicro:bit関連コンテンツの大部分では、ブロックベースのプログラミングによるサンプルを使う。

ただし、選びたければJavaScript(およびMicroPython)のオプションも使える。 選択は自由であり、うれしいことに同じプログラムの中で両者を行き来できる。片方を変更するともう片方にも反映されるため、プログラミングに慣れていない場合には特にありがたい機能である。

シミュレータ

MakeCodeにはmicro:bit用のシミュレータが用意されている。 つまり、手元にmicro:bitがなくてもコードを書ける。 あるいは、micro:bitにアップロードする前にアイデアを試してみたい場合にも使える。

コードを組み立てるにつれてシミュレータも更新される。 最初から実行し直したい場合は、停止ボタンと実行ボタンをクリックすればやり直せる。

コードの話が出たところで、さっそく簡単なプログラムを書いてmicro:bitに書き込んでみよう。

Hello, World!

いよいよ本番である。MakeCodeプログラミング環境で、micro:bit向けの最初のプログラムを書いていく。

*「Hello World」*とは、あるプログラミング言語や新しいハードウェアで最初に書くプログラムを指す言葉である。 本質的には、学習の第一歩として、(うまくいけばだが)ちょっとした達成感を与えてくれるシンプルなコードのことである。 また、すべてが正しく動作しているかを確認する機会にもなる。

最初の「Hello World」として、LEDアレイ上に、永遠に繰り返されるシンプルなアニメーションを作成する。 完成したプログラムだけが欲しい場合は、こちらで確認できる。 プログラムをどう組み立てたか、その手順を1つずつ確認したい場合はこのまま読み進めてほしい。

「Hello World」を組み立てる

micro:bitでの「Hello World」は、Arduinoなどのボードでよくあるようなふつうのマイクロコントローラーとは少し違う。 micro:bitには、単体で点滅させられるような単一のLEDはない。 その代わりにmicro:bitが持っているのは、LEDアレイである。 そのため、micro:bitでの「Hello World」は、LEDアレイを使って何かを描くことになる。

MakeCodeを開くと、On Startブロックとforeverブロックという2つのブロックが表示される。 On Startブロックは、プログラムの一番最初に一度だけ実行されるコードすべてを収める。 foreverブロックは、何度も何度も、永遠にループするコードである。

この「Hello World」を組み立てるには、foreverブロックを使う。 ここから、foreverにブロックを追加していく必要がある。

まず、「Basics」のカテゴリをクリックする。 これらのブロックは、MakeCodeプログラムの基本的な構成要素である。 クリックすると、いくつかの選択肢が展開される。 show ledsブロックをクリックしてドラッグし、foreverブロックの中に配置する。 このブロックはforeverブロックの中にぴったりはまるようになっており、コンピュータの音量を上げていれば、ブロックを離したときに気持ちのよい「カチッ」という音が聞こえるはずである。

show ledsブロックには、LEDアレイを表す四角形の並びがある。 四角をクリックすると赤くなり、これはそのLEDが「点灯」していることを意味する。 LEDを個別にオン・オフしてシンプルなピクセルアートの形を描いてみよう。ウィンドウ左側にあるシミュレータで、その結果を確認できるはずである。

この静止画像をアニメーションに変えるには、最初のブロックのすぐ下にもう一つのshow ledsブロックを配置する必要がある。 続いて、この四角形の並びで2枚目の絵を作る。 シミュレータでは、画像が非常に速く切り替わる様子が見られるはずである。これを遅くする必要がある。

アニメーションを遅くするには、Basicのブロックセットにあるpauseブロックを使う。 pauseブロックは、その名前のとおりの働きをする。micro:bitに、一時停止して指定した時間だけ待つよう指示する。 図のように、プログラム内に2つのpauseブロックを配置する。

このプログラムはループになっているため、pauseブロックを2つ使い、そのうち1つを末尾に配置している。 末尾にこのブロックがないと、アニメーションの画像が非常に速く切り替わってしまう。

次の節では、このサンプルを組み立てているので、ファイルをダウンロードして自分のmicro:bitで試すことも、シミュレータを使うこともできる。 コードをいじって変更を加えたい場合は、ウィジェット内のEditボタンをクリックすれば、「Hello World」を改造できるMakeCodeエディタが開く。楽しんでほしい。

プログラムをmicro:bitに書き込む

MakeCodeで最初のプログラムを組み立て、シミュレータでも動作した。 では、これをどうやってmicro:bitに書き込めばよいのだろうか。

プログラムをダウンロードする

プログラムに満足したら、MakeCodeのDownloadボタンをクリックする。

これにより、プログラムファイルが、標準のダウンロード先(おそらくコンピュータのDownloadsフォルダか、ダウンロード設定で指定した場所)にダウンロードされる。

あとは、ダウンロードしたプログラムファイルを、外部デバイスとして表示されているmicro:bitのドライブへクリック&ドラッグするだけでよい。

これで完了である。

micro:bitは数秒間点滅し、その後プログラムが自動的に開始する。よし、成功である。

注意: シミュレートされた回路を表示するには、広告・ポップアップブロッカーを無効化する必要がある場合がある。

MakeCodeエクステンション

注意: 以前、これらのライブラリはMakeCodeパッケージと呼ばれていた。現在はMakeCodeエクステンションと呼ばれている。

以前Arduinoを使ったことがあれば、ライブラリと呼ばれるものをご存じだろう。これは、コアとなるプログラミング言語の機能を拡張するコード群のことである。 MakeCodeエクステンションも同じような働きをする。

ArduinoライブラリとMakeCodeエクステンションには、いくつか大きな違いがある。 その一つが、MakeCodeエクステンションにはJavaScript関数が含まれており、テキストでプログラミングする際にも使える点である。もちろん、ブロック方式でプログラミングするために必要なブロックもすべて揃っている。 これにより、新しいエクステンションの学習・利用が簡単になり、思い描いたプロジェクトを組み立てるまでの時間を短縮できる。

利用可能なMakeCodeエクステンションはいくつもある。 以下の手順では、Controller:bitのMakeCodeエクステンションを例にしているが、他のエクステンションを追加する場合も同じ手順で進められる。

MakeCodeエクステンションをインストールする

MakeCodeのツールボックス(さまざまなブロックグループの一覧)に新しいエクステンションをインストール・追加するには、「Advanced」をクリックし、続いて「Add Extension」をクリックする。

そこから「SparkFun」または「SparkFun gamer-bit」を検索すると、一覧に公開エクステンションとして表示されるはずである。 それをクリックする。

注意: 特定のエクステンションが見つからない場合は、そのエクステンションがまだ承認・公開されていない可能性がある。 エクステンションが名前で検索できるようになるまでには、micro:bit Educational Foundationによる承認に時間がかかる。 この承認プロセスの要件の一部には、稼働中の製品ページが必要という条件も含まれる。 そのため、一部の製品のローンチ時点では、エクステンションがまだ承認されていないことがあり、その場合エクステンションを追加する唯一の方法は、pxt-packageのGitHubリポジトリへのリンクを使い、そのURLをエクステンション検索ボックスに貼り付けることである。 MakeCodeエディタはそれを見つけ出し、誰でもプロジェクトに追加できるようにする。

これで、ツールボックスにすべてのブロックが追加される。 一般に、これはエクステンションがどう書かれているかによって、独自のツールボックスを持つ場合と、既存のツールボックスにブロックを追加するだけの場合があり、少しわかりにくいことがある。 ツールボックスを確認してみよう。gamer:bitの場合は、次のように表示されるはずである。

これで、gamer:bitエクステンションのインストールが完了した。 micro:arcadeキットを購入した場合は、これでボードとキット付属の部品を使う準備が整った。 なお、新しいMakeCodeプロジェクトを作るたびに、エクステンションを毎回読み込み直す必要がある。大した手間ではないが、覚えておく価値はある。

エクステンションを更新する

公開されているサンプルコードや保存された***.hex**ファイルは、アーカイブされたバージョンのエクステンションを使っている。 時折、MakeCodeエディタ側にもエクステンション側にも更新が入ることがある。 コンパイルエラーや新機能のためにエクステンションを最新版に更新する必要がある場合、更新方法は2通りある。 一つは、エクステンションが提供するすべてのブロックを削除し、上で説明した手順どおりにエクステンションを再インストールする方法である。 コードの長さや、ブロックがいくつも組み合わさっている場合には、この方法は面倒になることがある。 もう一つの方法は、JavaScriptビューでバージョン番号を更新することである。 この方法には、組み合わさったブロックを手作業で削除する必要がないという利点がある。

以下は、以前のgamer:bitエクステンションでコンパイルできていた公開サンプルの例である。 MakeCodeエディタの更新により、以前のバージョンのMakeCodeエディタでは見過ごされていたgamer:bitエクステンションのバグが原因で、エラーが発生するようになった。 その後gamer:bitエクステンションにパッチが適用されたため、このエラーを修正するには、サンプルを最新版に更新する必要がある。

上部のJavaScriptボタンを切り替えて、JavaScriptビューに切り替える。 左側にはExplorerメニューが表示される。矢印をクリックしてメニューを展開する。

MakeCodeエクステンションのバージョン番号までスクロールする。 ここで、エクステンションのバージョンを削除したり更新したりできる。 コードがgamer:bitエクステンションに依存しているため、バージョン番号を更新する必要がある。 更新記号とバージョン番号が書かれたボタンをクリックする。

この時点で、クラウドから最新のバージョン番号を取得するまで数秒待つ。 その後、Explorerメニューを再度開く。 更新があれば、エクステンションが更新され、最新版が使われるようになる。 この例では更新があったため、v0.0.8が取得された。 コードの問題数を示す赤いボックスの数字も消えていることに気づくはずである。

すべてが問題なく進んでいるか確認しよう。 Blocksビューに戻ると、三角形で示されていたエラーが消えている。 これで、MakeCodeエクステンションの更新が完了し、コーディングを再開できる。

エクステンションを作る

自分だけのカスタムエクステンションを作ることに興味がある開発者・上級プログラマーは、以下のチュートリアルでさらに詳しい情報を確認してほしい。

micro:bitに電源を供給する

micro:bit上でプログラムが動いているが、まだコンピュータに接続されたままである。 これを解決する方法はいくつもある。電池、電池、そしてさらに電池である。

micro:bitへのリモート電源の追加について、さらに詳しく知りたいだろうか?micro:bit Foundationによるこれらのアプリケーションノートを確認してほしい。

micro:bit Foundation: Power Supply

USBバッテリーパック

USBバッテリーパックは、今やごく一般的なものになってきている。 これを使えば、micro:bitプロジェクトをかなり長時間動かし続けられる。

長いケーブルを引きずり回さずに済むよう、短めのUSBケーブルを用意しておくと便利である。

2xAAバッテリーパック

警告: JST-PHコネクタは通常LiPoバッテリーで使われる。 LiPoバッテリーは、2xAAのバッテリーパックで使うAA電池とは電池化学・電圧が異なる。 LiPoバッテリーの電圧を調整する電圧レギュレータを持っていない限り、micro:bitのJST-PHコネクタにはAA電池のみを使うこと。

教室での利用など、多数のmicro:bitに長時間にわたって電力を供給したい場合には、JST-PHコネクタ付きの2xAAバッテリーホルダーが優れた解決策になる。

これらの電池は、まとめ買いすればかなり安価に購入できる。

2xAAAバッテリーパック

警告: JST-PHコネクタは通常LiPoバッテリーで使われる。 LiPoバッテリーは、2xAAAのバッテリーパックで使うAAA電池とは電池化学・電圧が異なる。 LiPoバッテリーの電圧を調整する電圧レギュレータを持っていない限り、micro:bitのJST-PHコネクタにはAA電池のみを使うこと。

もっと小さなバッテリーホルダーが欲しい場合は、JST-PHコネクタ付きの2xAAAバッテリーホルダーを探してみてほしい。 micro:bit Go bundleにも1つ付属している。

もう一つ、スイッチ付きのJST-PHコネクタ2xAAAバッテリーホルダーもある。 このスイッチが追加されていることで、micro:bitからJST-PHコネクタを揺さぶって外す必要なく、micro:bitプロジェクトの電源を簡単にオン・オフできる。

まとめ・参考資料

注意: micro:bitのファームウェアを改造していて、MakeCodeでコードのアップロードに問題がある場合は、ファームウェアの再インストールを試してみてほしい。

micro:bit Foundation: Updating your micro:bit firmware

micro:bitの基礎に慣れてきたら、さらなるインスピレーションのために以下のリソースも確認してほしい。

micro:bit単体を使った追加のプロジェクトアイデアが欲しければ、micro:climateキットの光量読み取り実験も確認してみてほしい。

micro:climate Experiment 2 - Reading Light Level

その他のSparkFunチュートリアルとして、関連するmicro:bitチュートリアルもいくつか紹介する。

タグ: Bluetooth、教育、Hookup、MakeCode、microbit、micro:bit、モーション、pxt、センサー


出典:Getting Started with the micro:bit(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

micro:bit用のMakeCodeパッケージを作る

Microsoft MakeCodeは、コーディングの入門者向けに設計された、ブロックベースのプログラミング言語である。 MakeCodeが優れているのは、構文やデータ型を気にすることなく、アルゴリズム設計で使う基本的な構造や思考プロセスをそのまま体験できる点にある。 内部的には、MakeCodeは静的型付けのTypeScriptとJavaScriptをベースにしている。 このチュートリアルでは、既存のSparkFun拡張機能をもとに、土壌水分センサー用のMakeCode拡張機能を開発する。

MakeCode for micro:bitにある既存のSparkFun拡張機能の一部

必要なもの

まず、ビルド環境を整える。最初にNode.jsをダウンロード・インストールする。

GitHubのアカウントも必要になる。 コマンドプロンプトを開き、GitHubのファイルを保存している場所に移動する(筆者は**C:**ドライブにGitHubフォルダを作っているので、C:\GitHubになる)。 続いて、次のコマンドを実行する。これにより、使用するいくつかのnpmパッケージがインストールされる。

npm install
npm install jake
npm install typings

続いて、PXTのディレクトリをGitHubフォルダにクローンし、先ほどインストールしたnpmパッケージを実行する。 最後にもう一度GitHubフォルダに戻る。これは次のコマンドで行える。

git clone https://github.com/microsoft/pxt
cd pxt
git checkout
npm install
typings install
jake
cd..

続いて、Micro:Bitのターゲットをクローンし、そこにpxtをインストールする。

git clone https://github.com/Microsoft/pxt-microbit
cd pxt-microbit
npm install -g pxt
npm install
cd..

これでプロジェクトのビルドに必要なものはすべて揃ったはずである。 それでは、既存のSparkFun MakeCodeパッケージをクローンし、編集を始めよう。

git clone https://github.com/sparkfun/pxt-gator-light

何を変更するか

新しいMakeCodeパッケージ用に、新しいGitHubリポジトリを作成しよう。名前はpxt-gator-moistureとする。 このリポジトリをGitHubフォルダにクローンし、pxt-gator-lightリポジトリの中身をコピーする。 主に見ていくのは、gatorlightという名前の2つのファイル、pxt.JSONファイル、README.MD、そして最終的にはicon.pngである。

これらのファイルを変更する必要がある。画像をクリックすると拡大表示できる

まず、すべてをgatormoistureという名前に変更していく。 2つのgatorlightファイルの名前を変更したら、pxt.jsonを開き、lightという単語をすべてmoistureに置き換える。 この**.jsonファイルは、MakeCodeにどのファイルを含めるかを伝えるものであり、ファイル名を変更したので、ここでもその変更を反映する必要がある。 バージョン番号を0.0.1**に戻すことと、説明文をより適切な内容に変更することも忘れないでほしい。 続いて、gatormoistureという名前になった2つのファイルを開き、再びlightをmoistureにすべて置き換える。

ここで、ブロックの裏にあるコードが実際にどこにあるかを見てみよう。 ブロックは**.tsファイルにあり、実際の関数は.cppにある。 まず.cppを確認しよう。 どのパッケージでも必ずpxt.hをインクルードし、pxtという名前空間を使う。 続いて、gatormoistureという名前空間を作り、与えられたADC値からルクスを計算する関数を置く。 かなりシンプルな関数だが、これを.ts**ファイルから呼び出せるようになる。これこそが本当にやりたかったことである。

#include "pxt.h"
#include <cstdint>
#include <math.h>

using namespace pxt;

namespace gatorMoisture {
    /*
    * Calculates the light in Lux based on the ADC value passed in. 1 step in adcVal is equal to .488 uA or .976 lux at 5V
    */
    //%
    uint16_t getLux(int16_t ADCVal) {
        return ADCVal * .976;
    }

}

せっかくなので、getLuxを、ルクス値ではなく0〜1の間のfloat値を返すgetMoisture関数に変更しよう。 そのためには、渡されたADCValをADCのフルスケール範囲(1023)で割るだけでよい。 最終的に、gatormoisture.cppは次のようになる。

#include "pxt.h"
#include <cstdint>
#include <math.h>

using namespace pxt;

namespace gatorMoisture {
    /*
    * Calculates the light in Lux based on the ADC value passed in. 1 step in adcVal is equal to .488 uA or .976 lux at 5V
    */
    //%
    float getMoisture(int16_t ADCVal) {
        return ADCVal / 1023.0;
    }
}

続いて、.tsファイルの中でブロックがどう作られているかを見てみよう。 lightからmoistureへの変更をすべて終えると、次のような内容になっているはずである。

enum gatorMoistureType{
    moisture=1,
    adcVal=2,
}

//% color=#f44242 icon="\uf185"
namespace gatorMoisture {

    // Functions for reading moisture from the gatormoisture in moisture or straight adv value

    /**
    * Reads the number
    */
    //% weight=30 blockId="gatorMoisture_moisture" block="Get moisture on pin %pin | in %gatorMoistureType"
    export function moisture(pin: AnalogPin, type: gatorMoistureType): number{
        let ADCVal = pins.analogReadPin(pin)
        switch(type){
            case gatorMoistureType.moisture: return getMoisture(ADCVal)
            case gatorMoistureType.adcVal: return ADCVal
            default: return -11111111
        }
    }

    /**
     * Function used for simulator, actual implementation is in gatormoisture.cpp
     */
    //% shim=gatorMoisture::getMoisture
    function getMoisture(ADCVal: number) {
        // Fake function for simulator
        return 0
    }
}

ブロックにドロップダウンで選択肢を持たせたい場合は、enumを使ってそれを作る。 今回は、moisture(0〜1の間の値)か、生のadcValのどちらかを選べるようにする。 そこで、名前空間の外側で、可能なデータ型に対応する次のようなenumを作成する。

enum gatorMoistureType{
    moisture=1,
    adcVal=2,
}

続いて、この拡張機能の色とアイコンを選ぶ必要がある。これは名前空間を宣言する直前の行で行う。 色は6桁の16進数値であれば何でもよく、アイコンはFontAwesomeアイコンライブラリの識別子を使う。 色とアイコンの宣言は次のようになる。

//% color=#f44242 icon="\uf185"

続いて、自分のブロックがどんな見た目になり、他のブロックとの相対的な位置がどうなるかを定義する必要がある。 これはweightblockIdblockを設定することで行う。 weightが100のブロックは、weightが100未満のブロックより上に、100より大きいブロックより下に一覧表示される。 これにより、すべてのブロックをどの順序で並べたいかを自分で決められる。 blockIdは必ずmynamespacetitle_functionTitleという形式にする必要があるため、gatorMoisture名前空間にあるmoistureブロックの場合、blockIdはgatorMoisture_moistureになる。 最後に、block文字列を使って、ブロックのテキストに実際に何を表示するかを決める。 ドロップダウンにしたい変数の前には%を付ける。 次のコードは、ピン選択用のドロップダウンと、moistureadcValを選べるドロップダウンを持つブロックを作る。 このブロックは、ドロップダウンで選択された引数を使ってmoisture関数を呼び出す。

//% weight=30 blockId="gatorMoisture_moisture" block="Get moisture on pin %pin | in %gatorMoistureType"

最後に、実際にピンを読み取る関数を書く必要がある。 exportとして宣言された関数は、MakeCode上でブロックとして表示される。 この関数の引数は、ドロップダウンで選択できるようにと宣言した変数になり、通常は型に応じたswitch文を用意し、選択された型ごとに適切な値を返すようにする必要がある。 型がmoistureのとき、.cppに含まれる関数であるgetMoistureをどう呼び出しているかに注目してほしい。 また、この関数が何を返すかも宣言しなければならない。今回の場合は数値である。

export function moisture(pin: AnalogPin, type: gatorMoistureType): number{
    let ADCVal = pins.analogReadPin(pin)
    switch(type){
        case gatorMoistureType.moisture: return getMoisture(ADCVal)
        case gatorMoistureType.adcVal: return ADCVal
        default: return -11111111
    }
}

.cppにある関数はどれも、シミュレータ用のダミー関数が必要になる。 getMoisture関数に対応するダミー関数は次のように作成する。 exportされていないため、MakeCode上には表示されない点に注目してほしい。

//% shim=gatorMoisture::getMoisture
function getMoisture(ADCVal: number) {
    // Fake function for simulator
    return 0
}

最後に、READMEの末尾部分(49行目)を、自分の名前空間とそれに続くGitHubのアドレスに変更する必要がある。 gatorMoisture=github:sparkfun/pxt-gator-soilのような形になり、これによりこのパッケージがMakeCode拡張機能として認識されるようになる。

コードをコンパイルする

これですべてのコードを書き終えたので、いよいよコンパイルしてテストする番である。 コマンドプロンプトウィンドウを開き、自分のMakeCodeパッケージがあるディレクトリに移動する。 そこで、次のコマンドを実行し、コードをビルドするのに必要なPXTツールをリンク・インストールする。

npm install
npm install typings
npm install jake
npm link ../pxt
pxt target microbit
pxt install

続いて、コードをビルドし、変更内容をコミットしてGitHubにプッシュする。

pxt build
git add -A
git commit -m "changing names to gator:moisture"
pxt bump

pxt bumpコマンドを実行すると、リリースにタグ付けするバージョン番号の入力を求められる。 提示されたバージョン以上の番号を入力すればよい。 このコマンドは、コミットにタグを付け、リリースとしてGitHubにプッシュする。

PXT Bump

テストして、やり直して、また試す

コードをテストするため、MakeCodeのウェブサイトを開き、extensionsまで移動する。

Extensions

そこから、トークンを使ってGitHubにログインする。 login to GitHubをクリックした際の指示に従うだけでよい。

GitHubにログインする

ログインしたら、GitHubリポジトリのURLをextensionの検索バーに貼り付け、表示された結果をクリックして取り込む。 結果が表示されない場合は、リポジトリが公開(public)になっているか確認してほしい。

拡張機能を取り込んだら、そのさまざまな機能を確認し、必要に応じてコードを編集して、満足のいくまでGitHubに再アップロードしてみてほしい。

まとめ・参考資料

最終的には、この拡張機能をMicrosoftに承認してもらいたくなるはずである。 MakeCode extension approval checklistを必ず確認してほしい。 続いて、こちらのフォームに記入し、パッケージの承認を申請する。

その他の参考資料も紹介する。

タグ: GitHub、MakeCode、micro:bit、プログラミング、pxt


出典:How to Create a MakeCode Package for Micro:Bit(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

MyoWare 2.0筋電センサー・エコシステムを始める

注意: このチュートリアルは、MyoWare 2筋電センサーとそのエコシステムを対象にしている。MyoWare 2筋電センサーは、MyoWare 2.0筋電センサーと完全な後方互換性がある。スナップが2つしかない「V1」バージョンを使っている場合は、古いMyoWare Muscle Sensor V1のチュートリアルを参照してほしい。

筋肉を使って何かを操作するというのは、私たちの多くにとって馴染み深いやり方である。 ボタンを押し、レバーを引き、ジョイスティックを動かす。 しかし、そのボタンやレバーやジョイスティックを取り払い、筋肉そのもので操作できたらどうだろうか。 MyoWare 2.0筋電センサーは、Advancer Technologies社によるArduino互換のオールインワン筋電図(EMG)センサーであり、まさにそれを可能にする。 MyoWare 2.0筋電センサーはゼロから設計し直され、使いやすくコンパクトなデザインに一新されているほか、最新かつ最良のチップセットにアップグレードされ、センサーの性能と信頼性が向上した。 革新的なスナップコネクタシステムにより、MyoWare 2.0エコシステムの接続に、はんだ付けは一切不要になった。 使い方はとても簡単で、電極パッド(別売)を貼り、出力電圧を読み取り、筋肉を動かすだけでよい。 このチュートリアルでは、センサーの機能と関連するシールドについて紹介し、筋群への接続方法を解説する。

注意: このセンサーは、人間や動物の疾患やその他の症状の診断、あるいは疾患の治療・緩和・予防を目的とした使用は意図していない。

  • MyoWare 2筋電センサー
  • MyoWare 2.0 Link Shield
  • MyoWare 2.0 Cable Shield
  • MyoWare 2.0 Arduino Shield
  • MyoWare 2.0 Power Shield
  • MyoWare 2.0 LED Shield(廃盤)

注意: MyoWare 2.0エコシステムは、Advancer Technologies, LLCの筋電計測の専門家によって設計され、SparkFun Electronicsが基板の製造・販売を担当している。

必要な部品

このチュートリアルに沿って進めるには、以下の部品が必要になる。 持っているものによっては、すべてが必要になるとは限らない。 カートに追加し、ガイドを読み進めながら、必要に応じてカートを調整してほしい。 筋群に接続するたびに、筋電センサー1台につき最低でも3枚の生体医療用センサーパッドが必要になる。

注意: EMGパッドは使い捨てである。筋群に接続するたびに、予備のパッドを用意しておくこと。

最小限の部品構成

筋電センサーを接続・給電するには、最低限次の部品が必要になる。筋肉の信号はENV LEDで確認できる。

  • MyoWare 2筋電センサー
  • Disposable Surface EMG/ECG/EKG Electrode - 24mm(10個入り)
  • MyoWare 2.0 Power Shield
  • Reversible USB A to C Cable - 2m

LEDセグメントで筋肉信号の大きさを表示する

筋電センサーを接続・給電するには、以下の部品が必要になる。筋肉信号の大きさはLEDセグメントで確認できる。

  • MyoWare 2筋電センサー
  • Disposable Surface EMG/ECG/EKG Electrode - 24mm(10個入り)
  • Reversible USB A to C Cable - 2m
  • MyoWare 2.0 LED Shield(廃盤)

注意: これらの部品はBasic Kitとしてもまとめて入手できる。こちらにはReference Cableとドライバーも含まれている(廃盤)。

Arduinoへの接続

基板同士をはんだ付けせずに5V Arduinoへ接続するには、以下が必要になる。Arduinoに接続すると、センサーデータを処理してデバイスを制御したり、Arduino Serial Plotterで信号を確認したりできる。

  • MyoWare 2筋電センサー
  • Disposable Surface EMG/ECG/EKG Electrode - 24mm(10個入り)
  • MyoWare 2.0 Link Shield
  • SparkFun RedBoard Plus
  • MyoWare 2.0 Arduino Shield
  • Reversible USB A to C Cable - 2m
  • Audio Cable TRS - 1m

注意: RedBoard Plusの代わりにArduino Unoを使うこともできる。その場合は、RedBoard PlusとUSBケーブルを次のものに置き換える。

  • Arduino Uno - R3
  • USB Cable A to B - 6 Foot

これらの部品はDevelopment Kitとしてもまとめて入手できる。このキットには、筋電センサー、Cable Shield、Power Shield、LED Shield、Link Shield、Arduino Shield、RedBoard Plus、それぞれのケーブルが含まれる(廃盤)。

ワイヤレスで送信する

Arduino経由でセンサーデータをワイヤレス送信するには、以下が必要になる。 ワイヤレス送信の選択肢の一つがArtemisである。 もちろん、最低でもRedBoard Artemis 2台とUSBケーブル2本が必要になる。 電池で駆動するRedBoard Artemisごとに、電池ホルダー1個と単三電池4本も必要になる。 Example 3に沿って進めるには、以下の部品を推奨する。

  • MyoWare 2筋電センサー
  • Disposable Surface EMG/ECG/EKG Electrode - 24mm(10個入り)
  • MyoWare 2.0 Link Shield
  • MyoWare 2.0 Arduino Shield
  • Battery Holder - 4xAA to Barrel Jack Connector
  • Reversible USB A to C Cable - 2m
  • SparkFun RedBoard Artemis
  • Audio Cable TRS - 1m
  • Panasonic Alkaline Battery - AA

注意: 充電式電池を使いたい場合は、アルカリ電池の代わりにNiMH電池も使える(Tenergy T4s Intelligent Universal Charger - 4-Bay、2500 mAh NiMH Battery - AA〔廃盤〕)。

Artemisの代わりにESP32を使うこともできる。この場合はESP32ボードと電池が必要になる。 ありがたいことに、必要なものがすべて揃ったMyoWare 2.0 Muscle Sensor Wireless Kitも用意されている(廃盤)。

アクセサリー

セットアップによっては、ハードウェアと筋群の間を延長するために以下のアクセサリーが必要になることがある。

  • Sensor Cable - Electrode Pads(3コネクタ)
  • MyoWare 2.0 Cable Shield
  • MyoWare 2.0 Reference Cable

道具

基板同士を簡単に取り外すには、マイナスドライバーの使用を推奨する。 次のドライバーは、積み重ねた基板を互いに取り外すのに使える。 使用するArduinoによっては、ロジックレベル用のジャンパーパッドを変更する際にホビーナイフ、はんだ、はんだごても用意しておくとよい。

  • SparkFun Mini Screwdriver
  • Solder Lead Free - 15-gram Tube
  • Hobby Knife
  • Soldering Iron - 30W (US, 110V)

その他に必要なもの

以下も必要になる。

  • アルコール綿(イソプロピルアルコールと綿球)
  • USBアイソレータ回路(任意)

おすすめの読み物

以下の概念に馴染みがない場合は、続ける前にこれらのチュートリアルを確認しておくことを推奨する。 使用するArduino開発ボードによっては、ドライバーのインストールが必要になることがある。 RedBoardシリーズは、Arduino Unoとは異なるUSB-シリアル変換チップを使っている。 Arduino UnoとRedBoard Plusは、どちらもロジックレベルに5Vを使う。

  • アナログ-デジタル変換 (ADC) — 世界はアナログである。デジタルデバイスが世界を解釈できるよう、アナログ-デジタル変換を活用する
  • ロジックレベル — 3.3Vデバイスと5Vデバイス、それぞれのロジックレベルの違いを学ぶ
  • How to Install CH340 Drivers — Windows、Mac OS X、Linuxで(必要であれば)CH340ドライバをインストールする方法
  • RedBoard Plus Hookup Guide — RedBoard Plusの基本的な機能を扱うチュートリアル。LEDを点滅させる基本的な使い方や、Qwiicシステムの使い方も解説する

センサーデータをBluetooth®接続でワイヤレス送信したいユーザーには、RedBoard Artemisを入手し、ボード定義をインストールすることを推奨する。RedBoard Artemisは、ロジックレベルに3.3Vを使う点に注意してほしい。

  • Hookup Guide for the SparkFun RedBoard Artemis — RedBoard Artemisの使い始め方。おなじみのUno R3のフォームファクタに、SparkFun Artemisモジュールのすべての機能を詰め込んでいる
  • Installing Board Definitions in the Arduino IDE — カスタムのArduinoボード・コアはどうやってインストールするのか。とても簡単である。このチュートリアルでは、Arduino Board Managerを使ってArduinoボード定義をインストールする方法を扱う。SparkFunの開発ボードの多くに必要となるボード定義など、サードパーティ製コアを手動でインストールする方法も扱う

新機能

MyoWare 2.0エコシステムは、これまでの筋電センサーの設計をさらに発展させたものである。エコシステムに加えられた主な変更点は次のとおりである。

  • 回路の刷新:MyoWare 2.0筋電センサーはゼロから設計し直された。回路は最新かつ最良のチップセットに刷新され、センサーの性能と信頼性が向上している。
  • 革新的なスナップコネクタシステム:センサーとそのシールドに内蔵されたオス・メスのスナップコネクタにより、はんだ付けが一切不要になった。表側のコネクタはシールドを電源とセンサーのEMGエンベロープ出力に接続し、裏側のコネクタはCable Shieldの入力電極に接続する。
  • コンパクト:スナップコネクタにより、シールドをMyoWare 2.0筋電センサーに積み重ねたときの高さも低く抑えられている。
  • キー構造:基板上のグラウンドおよびリファレンスのスナップコネクタはわずかにオフセットされ、「キー」として機能するよう設計されている。筋電センサーとシールドにはこのキー構造があるため、基板同士を接続する方法は1通りしかない。
  • 新しいシールド:MyoWare 2.0 LinkとArduino Shieldは、Arduino Uno R3のフォームファクタを持つ開発ボードに、最大6台のMyoWare 2.0筋電センサーを簡単に接続できるよう設計されている。これにより、筋電センサーをArduinoに接続する際のはんだ付けも不要になる。必要なのは、筋電センサーごとに1本のTRS-TRSケーブルだけである。
  • MyoWare Power Shield:以前のバージョンのPower Shieldはコイン電池を使っていた。刷新されたMyoWare 2.0 Power Shieldには、内蔵の充電式LiPoバッテリーが搭載されている。
  • MyoWare Proto Shield(非推奨):はんだ付け不要のシステムを目指したことで、MyoWare Proto ShieldはMyoWare 2.0エコシステムでは非推奨となった。

左:比較のため積み重ねたV1とV2のシールド 右:キー構造により基板の誤った積み重ねを防止できる

筋電図(EMG)とは何か

「MyoWareは、筋肉の電位を通じて筋活動を測定する。これは一般に表面筋電図(EMGまたはsEMGと略される)と呼ばれる。脳が筋肉を収縮させるよう指示すると、電気信号が筋肉に送られ、運動単位(筋肉が発生させる力の元となる筋線維の束)が動員され始める。

強く収縮させるほど、より多くの運動単位が動員され、より大きな筋力が発生する。運動単位の数が増えるほど、筋肉の電気的活動も増加する。MyoWareはこの電気的活動を解析し、筋肉がどれだけ強く収縮しているかを表すアナログ信号を出力する。強く収縮させるほど、MyoWareの出力電圧は高くなる。」――Advancer Technologies

画像提供:Advancer Technologies(MyoWare 2.0 Advanced Guideより)

MyoWare 2.0筋電センサー

注意: このチュートリアルは、MyoWare 2筋電センサーとそのエコシステムを対象にしている。MyoWare 2筋電センサーは、MyoWare 2.0筋電センサーと完全な後方互換性がある。スナップが2つしかない「V1」バージョンを使っている場合は、古いMyoWare Muscle Sensor V1のチュートリアルを参照してほしい。

MyoWare 2.0筋電センサーは、Advancer Technologiesが手がけるArduino互換のオールインワン筋電図(EMG)センサーである。 革新的なスナップコネクタシステムにより、MyoWare 2.0エコシステムの接続にはんだ付けは一切不要になった。 使い方はとても簡単で、電極パッド(別売)を貼り、出力電圧を読み取り、筋肉を動かすだけでよい。 筋電センサーのスナップコネクタシステムにより、シールドを積み重ねるのも簡単になっている。 表側のコネクタは電源とセンサーのEMGエンベロープ出力に接続し、裏側のコネクタは入力電極に接続する。 筋肉の電位を検出して筋活動を測定する手法は、伝統的に医学研究で使われてきた。 しかし、より小型でより高性能なマイクロコントローラーや集積回路の登場に伴い、EMG回路やセンサーはビデオゲーム、ロボット工学、義肢といったさまざまな制御システムにも活用されるようになった。

注意: このチュートリアルは、MyoWare 2筋電センサー(V2.1.0)とMyoWare 2.0筋電センサー(V2.0.1およびV2.0.4)の両方に適用される。

内蔵のスナップコネクタは、生体医療用センサーパッド(10個入り)とよく合う。

ハードウェア概要

注意: 基板の表側にあるオスのスナップコネクタは「スタッド」コネクタ、裏側にあるメスのスナップコネクタは「ソケット」コネクタと呼ばれる。これらのスナップコネクタを扱う技術仕様書やガイドでは、この用語を目にすることがある。

基板の表側には回路とオスのスナップコネクタが配置されている。基板の裏側にはメスのスナップコネクタがある。

左:表側 右:裏側

アンプと可変ゲイン

MyoWare 2.0筋電センサーは、筋群からの微弱なEMG信号を測定する。 この信号はアンプ、バンドパスフィルタ、整流器、エンベロープ検出器を経由するため、ユーザーはマイクロコントローラーのADCピンを通じて筋活動を簡単に読み取れる。

画像提供:Advancer Technologies(MyoWare 2.0 Advanced Guideより)

下の画像で強調表示されているICは、生のEMG信号の処理を助けるアンプである。 MyoWare 2.0 Advanced Guideによると、筋電センサーの技術仕様の一部は次のとおりである。

  • 入力電圧
    • 最小:+2.27V
    • 標準:+3.3Vまたは+5V
    • 最大:+5.47V
  • 入力バイアス電流:250pA、最大1nA
  • 入力インピーダンス:800
  • 同相除去比(CMRR):140dB
  • フィルタ
    • ハイパスフィルタ:アクティブ1次、fc = 20.8Hz、-20dB
    • ローパスフィルタ:アクティブ1次、fc = 498.4Hz、-20dB
  • 整流方式:全波整流
  • エンベロープ検出:リニア、パッシブ1次、fc = 3.6Hz、-20dB

基板には、エンベロープ信号のゲインを手動で調整するためのポテンショメータ(トリムポット)が搭載されている。 調整にはドライバーが必要である。 もちろん、ポテンショメータにアクセスするには上に重ねたシールドを取り外す必要がある。 それぞれの信号のゲイン(G)は次のとおりである。

  • 生信号(RAW): G = 200
  • 整流信号(RECT): G = 200
  • エンベロープ(ENV): G = 200 × (R / 1kΩ)(Rはゲインポテンショメータの抵抗値・kΩ単位)

注意: デフォルトのゲインは、ほとんどの用途で十分なはずである。とはいえ、上級ユーザーはドライバーを使い、ENV出力のトリムポットを希望のゲイン設定に調整できる。トリムポットを時計回りに回すとゲインが上がり、反時計回りに回すとゲインが下がる。トリムポットは回しすぎたり力をかけすぎたりすると破損することがあるため、回すときは注意すること。

下の画像は、生信号・整流信号・エンベロープ出力それぞれの波形を示している。 出力の右側のグラフは、生信号のパワースペクトルを示している。 MyoWare 2.0筋電センサーは、20Hz〜500Hzの範囲を持つ1次バンドパスフィルタを備えている。 この範囲は、生のEMG信号を捉えつつ、モーションアーチファクトのような不要な信号を除去するのに適している。 なお、表示されているデータはあくまで説明用であり、実際のデータではない。

画像提供:Advancer Technologies(MyoWare 2.0 Advanced Guideより)

PTHパッド

基板を裏返すと、ラベル付けされたPTHパッドが見つかる。 配線をはんだ付けしてVIN、GND、ENVを接続する必要があるユーザー向けに、基板には0.1インチ間隔の1×3列のPTHパッドが用意されている。 さらに、RAW、RECT、REF、MID、ENDの各ピンも基板全体に引き出されている。 REF、RECT、RAWピンに配線をはんだ付けする際は、はんだを盛りすぎないよう注意すること。盛りすぎると、MyoWare 2.0 Link ShieldのポゴピンがPTHパッドに正しく接続できなくなることがある。

LED

基板には2つのステータスLEDが搭載されている。

  • VIN:電源スイッチがONの位置に切り替わったときに点灯し、VINスナップピンを通じてMyoWare 2.0筋電センサーに電力が供給されていることを示す。
  • ENV:MyoWare 2.0筋電センサーのENVピンに活動があるときに点灯する。

スナップコネクタ

基板には、MyoWare 2.0筋電センサーの上にシールドを簡単に積み重ねられるスナップコネクタが搭載されている。 基板の上部はわずかにオフセットされており、キーのように働くよう設計されているため、基板同士を接続する方法は1通りしかない。 基板同士を積み重ねる前に、GNDまたはREFのスナップコネクタの位置を揃えること。そうしないと、3つのスナップコネクタがうまく接続できない。

以下のオスのスナップコネクタが基板の表側にある。これらは基板裏側の1×3ヘッダーにも引き出されている。ピンのラベルを確認するには基板をひっくり返す。

  • GND:MyoWare 2.0筋電センサーのグラウンド。
  • VIN:MyoWare 2.0筋電センサーの電圧入力。この電圧は、スナップコネクタを使う際にどのシールドを上に重ねるかによって異なる。2つの電源から矛盾した電圧が加わらないよう、シールドを上に重ねる際はVINピンのPTHパッドを未接続のままにしておくこと。
    • MyoWare 2.0 Power ShieldまたはLED Shieldと組み合わせて使う場合、この電圧はLiPoバッテリーの充電状態によって変わる。充電用の電源に接続すると、充電ICがLiPoバッテリーの充電を開始し、システム電圧はおよそ4.2Vになることがある。安全上の理由から、バッテリーを充電する際は、常にこのシールドをセンサーから取り外しておくことを推奨する。
    • MyoWare 2.0 Link ShieldとMyoWare 2.0 Arduino Shieldと組み合わせて使う場合、この電圧はMyoWare 2.0 Arduino ShieldのPower Jumperの位置によって決まる。これにより、VINは5V(デフォルト)または3.3Vに設定される。
  • ENV:0〜VINの範囲のエンベロープ信号。マイクロコントローラーのADCに接続する。

注意: 上の写真で「E」とラベル付けされたPTHパッドは、END筋肉用スナップコネクタに接続されており、ENVスナップコネクタではない点に注意してほしい。

以下のメスのスナップコネクタが基板の裏側にある。これらは、それぞれのスナップコネクタの隣にあるPTHパッドに引き出されている。

  • REF:リファレンス電極用スナップコネクタ。肘の骨の部分など、筋群に隣接しない体の別の部位に接続する。
  • MID:筋肉中間電極用スナップコネクタ。筋群の中間部分に接続する。
  • END:筋肉端部電極用スナップコネクタ。筋群の端部分に接続する。

注意: REF電極パッドが皮膚にしっかりと安定して接触しているか確認すること。接触が不十分だと動作に問題が生じることがある。

リファレンス電極ポート

注意: 内蔵のリファレンススナップコネクタは、ほとんどの用途で十分なはずである。とはいえ、筋群への接続が難しい場合は、リファレンスケーブルの入手を推奨する。これは主に、大腿四頭筋やハムストリングスなど大きな筋群向けに用意されている。

基板には、リファレンスケーブルのかしめピンを挿入するためのハウジングがある。 このピンをハウジングに挿入し、生体医療用センサーパッドを電極スナップに取り付けることで、内蔵のリファレンスピンが届かない場合に、肘の骨の部分や対象の筋肉に隣接しない体の別の部位にリファレンスケーブルを貼り付けられる。

注意: 基板上のリファレンススナップコネクタは、ケーブルを挿入していても有効なままである。ソケットを無効化するには、センサー表側のジャンパートレースを切断する。ソケットを再度有効化するには、ジャンパーパッドをはんだでブリッジする。ジャンパーの変更について詳しくは、ジャンパーパッドとPCBトレースの扱い方のチュートリアルを確認してほしい。

ジャンパー

リファレンスピンの隣に、「R」とラベル付けされた小さなジャンパーがある。 このジャンパーはデフォルトで閉じており、リファレンス電極コネクタに接続されている。 リファレンスケーブルを使う場合は、このトレースを必ず切断すること。 ジャンパーの変更について詳しくは、ジャンパーパッドとPCBトレースの扱い方のチュートリアルを確認してほしい。

基板寸法

MyoWare 2.0筋電センサーの基板寸法は37.57mm × 35.90mm(1.48インチ × 1.41インチ)である。

MyoWare 2.0 Sensor Cover

MyoWare 2.0 Sensor Coverは、各MyoWare 2.0筋電センサーにあらかじめ取り付けられている。 シールドを上に積み重ねない限り、回路を保護するためこのカバーはセンサーに付けたままにしておくこと。

ハードウェア概要

しゃれたデザイン以外、この基板にはあまり多くの要素はない。 フィジェットスピナーによく似ている。もっとも、基板に組み込まれた圧入式スケートボードベアリングはないが。 基板には回路は実装されていない。 基板の表側にはAdvancer TechnologiesのMyoWareロゴが、裏側にはQRコードがある。 スマートフォンを取り出してQRコードをスキャンし、MyoWareの公式サイトを訪れてみるのも一興である。

基板寸法

Sensor CoverはMyoWare 2.0筋電センサーと同じフォームファクタを使っており、基板寸法は37.57mm × 35.90mm(1.48インチ × 1.41インチ)である。

MyoWare 2.0 Reference Cable

MyoWare 2.0 Reference Cableは、MyoWare 2.0筋電センサーのリファレンスピンを延長するためのものである。 このピンをハウジングに挿入し、生体医療用センサーパッドを電極スナップに取り付けることで、内蔵のリファレンスピンが届かない場合に、肘の骨の部分や対象の筋肉に隣接しない体の別の部位にリファレンスケーブルを貼り付けられる。

  • MyoWare 2.0 Reference Cable
  • MyoWare 2.0 Reference Cable - 10 pack

ハードウェア概要

注意: 内蔵のリファレンススナップコネクタは、ほとんどの用途で十分なはずである。とはいえ、筋群への接続が難しい場合は、リファレンスケーブルの入手を推奨する。これは主に、大腿四頭筋やハムストリングスなど大きな筋群向けに用意されている。

MyoWare 2.0 Reference Cableの一方の端には、タブ付きのかしめピンがある。 これは、MyoWare 2.0筋電センサー上の対応するピンハウジングに挿入するためのものである。 タブによってピンがしっかりと固定される。 もう一方の端には、生体医療用センサーパッドに接続するためのスナップピンがある。 ケーブルの長さはおよそ3インチである。

注意: 基板上のリファレンススナップコネクタは、ケーブルを挿入していても有効なままである。ソケットを無効化するには、センサー表側のジャンパートレースを切断する。ソケットを再度有効化するには、ジャンパーパッドをはんだでブリッジする。

MyoWare 2.0 Cable Shield

MyoWare 2.0 Cable Shieldは、センサーパッドをMyoWare 2.0筋電センサーから離れた場所に取り付けたい場合を想定して設計されている。 これにより、対象の筋肉に基板そのものを取り付けなくても、筋電センサーをテスト・使用できる。 このシールドには、従来型の3電極センサーケーブルを接続できる3.5mmのTRSジャックが用意されている。 基板にはスナップコネクタも搭載されており、簡単に積み重ねられる。 MyoWare 2.0エコシステムの他のシールドとは異なり、このシールドはMyoWare 2.0筋電センサーの裏側にスナップする。 このシールドは、ケースに収めるウェアラブルでないプロジェクトや、内蔵の電極ソケットが適さないほど小さい・配置の難しい筋肉を対象にする場合に使う。

3.5mmのTRSコネクタで中間・端・リファレンスグラウンドの各ピンにアクセスするには、TRSコネクタと、生体医療用センサーパッドが数枚必要になる。 まだ持っていない場合は、次の製品を用意すること。

  • Sensor Cable - Electrode Pads(3コネクタ)
  • Disposable Surface EMG/ECG/EKG Electrode - 24mm(10個入り)

導電性素材でアダプタを自作したい場合は、TRSプラグを入手するという方法もある(TRS Audio Plug - 3.5mm〔Metal〕、廃盤)。

注意: アダプタを作りたい場合は、Advancer Technologiesによる導電性ファブリック電極の作り方のチュートリアルを参考にしてみてほしい。

ハードウェア概要

注意: 基板の表側にあるオスのスナップコネクタは「スタッド」コネクタと呼ばれる。これらのスナップコネクタを扱う技術仕様書やガイドでは、この用語を目にすることがある。

MyoWare 2.0 Cable Shieldの製品ページのデフォルト画像は3.5mm TRSコネクタのある面を最初に表示しているが、この基板の「表側」はオスのスナップコネクタがある面である。 MyoWare 2.0エコシステムの他のシールドと比べ、このシールドだけがMyoWare 2.0筋電センサーの裏側に積み重ねる。

左:表側 右:裏側

ケーブルの配色は、メーカーによって異なることがある。 センサーの読み取り値がおかしい、あるいは筋電センサーが筋群に反応しない場合は、導通測定に設定したテスターでピン配置をテストしてみてほしい。 以下は、オスのスナップピン、TRSコネクタ、ケーブルの間の接続関係をまとめた表である。 オスのスナップピンにより、MyoWare 2.0筋電センサーの裏側に簡単に積み重ねられる。

スナップコネクタTRSピン配置電極ピンの色(CAB-12970)備考
リファレンス [REF]スリーブリファレンス電極の接続。肘の骨の部分など、筋群に隣接しない体の別の部位に接続する。
端部 [END]リング筋肉端部電極の接続。筋群の端部分に接続する。
中間 [MID]チップ筋肉中間電極の接続。筋群の中間部分に接続する。

注意: REF電極パッドが皮膚にしっかりと安定して接触しているか確認すること。接触が不十分だと動作に問題が生じることがある。

⚠ 警告: MyoWare 2.0 Arduino ShieldまたはMyoWare 2.0 Link ShieldからのTRSケーブルを、MyoWare 2.0 Cable Shieldに挿入しないこと。

基板寸法

このシールドはMyoWare 2.0筋電センサーと同じフォームファクタを使っており、基板寸法は37.57mm × 35.90mm(1.48インチ × 1.41インチ)である。

MyoWare 2.0 Power Shield

改訂内容: 改訂版のMyoWare 2.0 LED Shield v2.0.3には、2ピン、1.00mmピッチのJST-SHコネクタが搭載されている。全体的な機能は同じである。

MyoWare 2.0 Power Shieldは、MyoWare 2.0筋電センサーにリモートで簡単に給電できるよう設計されている。 MyoWare Power Shieldには基板上にスナップコネクタが搭載されており、筋電センサーの表側に簡単に積み重ねられる。 スイッチをONの位置に切り替えると、筋電計測の魔法を働かせるのに必要な電力がセンサーに供給される。 MyoWare 2.0筋電センサーをバッテリー電源に接続すると、よりクリーンな信号が得られると同時に、電力網への危険な電流経路が生まれる可能性を排除できる。 携帯用途でのセンサーの給電に利用してほしい。

ハードウェア概要

注意: 基板の裏側にあるメスのスナップコネクタは「ソケット」コネクタと呼ばれる。これらのスナップコネクタを扱う技術仕様書やガイドでは、この用語を目にすることがある。

基板の表側にはLiPoバッテリーとUSBコネクタがある。基板の裏側にはメスのスナップコネクタと電源スイッチがある。

左:表側 右:裏側

USB Cコネクタ

基板にはUSB Type Cコネクタが搭載されている。 USB Cケーブルを5Vの電源に接続すると、単セルのLiPoバッテリーを充電できる。

⚡ 危険: コンピュータやUSB充電器でLiPoバッテリーを充電する際は、必ずMyoWare 2.0 Power ShieldをMyoWare 2.0筋電センサーから取り外すことを推奨する。MyoWare 2.0 Power Shieldは、充電中にMyoWare 2.0筋電センサーと組み合わせて使うようには設計されていない。充電中に電源スイッチがONの位置にあると、出力信号の完全性が損なわれる。シールドがセンサーの上に積み重なった状態でユーザーに装着したまま、LiPoバッテリーを充電しないこと。これにより、ユーザーが電力網(コンピュータの電源装置や、コンセントに接続されたUSB充電器など)に接続された状態にならないようにし、感電を防止する。

電源スイッチ

基板には電源スイッチが搭載されている。 スイッチをONの位置に切り替えると、VINのメススナップコネクタを通じてMyoWare 2.0筋電センサーに電力が供給される。 使わないときは、スイッチをOFFの位置に切り替えること。

LiPo充電回路

基板には、単セルのLiPoバッテリーを安全に充電するMCP73831 LiPo充電IC(5ピンの小さな黒いIC)が搭載されている。 この場合、充電レートは40mAに設定されており、内蔵の40mAh LiPoバッテリーを充電する。 バッテリーの充電状態は、充電中(CHG)と満充電(FULL)のLEDで確認できる。

注意: LiPoバッテリーの適切な取り扱いについては、LilyPad Basics: Powering Your Project - LiPo Battery Safety Careを確認してほしい。

スナップコネクタ

基板には、MyoWare 2.0筋電センサーの上に簡単に積み重ねられる3つのメススナップコネクタが搭載されている。

  • GND:電源用グラウンド。
  • VIN:電源用の電圧入力。この電圧は、LiPoバッテリーがどれだけ充電されているかによって異なる。充電用の電源に接続すると、充電ICがLiPoバッテリーの充電を開始し、電圧はおよそ4.2Vになることがある。安全上の理由から、バッテリーを充電する際は、常にこのシールドをセンサーから取り外しておくことを推奨する。
  • ENV:0〜VINの範囲のエンベロープ信号。マイクロコントローラーのADCに接続する。

LED

基板の表側には4つのLEDが搭載されている。

  • FULL:バッテリーが満充電になったことを示すために点灯する。LiPoが充電中でない場合や充電器が基板に接続されていない場合は消灯する。
  • CHG:LiPoバッテリーが充電中であることを示すために点灯する。LiPoが満充電の場合や充電器が基板に接続されていない場合は消灯する。
  • VIN:電源スイッチがONの位置に切り替わったときに点灯し、VINスナップピンを通じてMyoWare 2.0筋電センサーに電力が供給されていることを示す。
  • ENV:MyoWare 2.0筋電センサーのENVピンに活動があるときに点灯する。

基板寸法

このシールドはMyoWare 2.0筋電センサーと同じフォームファクタを使っており、基板寸法は37.57mm × 35.90mm(1.48インチ × 1.41インチ)である。

MyoWare 2.0 LED Shield

MyoWare 2.0 LED Shieldは、対象の筋肉の信号の大きさを表示すると同時に、内蔵バッテリーでMyoWare 2.0筋電センサーに給電できるよう設計されている。 青色の10セグメントバーグラフは、測定された信号の大きさを示す。 筋肉の活動が大きいほど、より高い位置までLEDが点灯する。 このシールドにより、MyoWare 2.0筋電センサーが提供する信号を視覚的に確認できるようになる。 LED Shieldには基板上にスナップコネクタが搭載されており、MyoWare 2.0筋電センサーの表側に簡単に積み重ねられる。 スイッチをONの位置に切り替えれば、筋電計測の魔法を働かせるのに必要な電力がセンサーに供給される。 MyoWare 2.0筋電センサーをバッテリー電源に接続すると、よりクリーンな信号が得られると同時に、電力網への危険な電流経路が生まれる可能性を排除できる。 トレーニング中に筋肉をどれだけ使えているかを測ったり、教材として使ったり、ハロウィンの衣装に筋電計測の演出を加えたりするのに活用してほしい。

注意: LiPoバッテリーの適切な取り扱いについては、LilyPad Basics: Powering Your Project - LiPo Battery Safety Careを確認してほしい。

ハードウェア概要

注意: 基板の裏側にあるメスのスナップコネクタは「ソケット」コネクタと呼ばれる。これらのスナップコネクタを扱う技術仕様書やガイドでは、この用語を目にすることがある。

基板の表側にはLEDとLiPoバッテリーがある。基板の裏側にはメスのスナップピン、電源スイッチ、USBコネクタがある。

左:表側 右:裏側

USB Cコネクタ

基板にはUSB Type Cコネクタが搭載されている。 USB Cケーブルを5Vの電源に接続すると、単セルのLiPoバッテリーを充電できる。

⚡ 危険: コンピュータやUSB充電器でLiPoバッテリーを充電する際は、必ずMyoWare 2.0 LED ShieldをMyoWare 2.0筋電センサーから取り外すことを推奨する。MyoWare 2.0 LED Shieldは、充電中にMyoWare 2.0筋電センサーと組み合わせて使うようには設計されていない。充電中に電源スイッチがONの位置にあると、すべてのLEDセグメントが最大値まで点灯し、出力信号の完全性が損なわれる。シールドがセンサーの上に積み重なった状態でユーザーに装着したまま、LiPoバッテリーを充電しないこと。これにより、ユーザーが電力網(コンピュータの電源装置や、コンセントに接続されたUSB充電器など)に接続された状態にならないようにし、感電を防止する。

電源スイッチ

基板には電源スイッチが搭載されている。 スイッチをONの位置に切り替えると、VINのメススナップコネクタを通じてMyoWare 2.0筋電センサーに電力が供給される。 使わないときは、スイッチをOFFの位置に切り替えること。

LiPo充電回路

基板には、単セルのLiPoバッテリーを安全に充電するMCP73831 LiPo充電ICが搭載されている。 この場合、充電レートは40mAに設定されており、基板上の40mAh LiPoバッテリーを充電する。 バッテリーの充電状態は、充電中(CHRG)と満充電(FULL)のLEDで確認できる。

LM3914ドット・バードライバー

黒い正方形のICはLM3914ドット・バードライバーである。このICは筋電センサーからの出力を受け取り、2×5セグメントのLEDに出力する。

LED

基板には3つのステータスLEDが搭載されている。

  • FULL:バッテリーが満充電になったことを示すために点灯する。LiPoが充電中でない場合や充電器が基板に接続されていない場合は消灯する。
  • CHRG:LiPoバッテリーが充電中であることを示すために点灯する。LiPoが満充電の場合や充電器が基板に接続されていない場合は消灯する。
  • VIN:電源スイッチがONの位置に切り替わったときに点灯し、VINスナップピンを通じてMyoWare 2.0筋電センサーに電力が供給されていることを示す。

このシールドが「MyoWare 2.0 LED Shield」と呼ばれるのは、もちろん大きなセグメントLEDを搭載しているからである。 バーグラフは、測定された筋肉信号のレベルに応じて点灯する。 最小値はドット・バードライバーICに最も近い位置に対応する。 筋肉の活動が増えるほど、ENVピンからの電圧が上昇する。 その結果、反対側の最後のLEDが点灯するまで、LEDは次々と点灯し続ける。 LEDは明るい場所でも十分視認できるが、暗い場所では特に美しく光る。

スナップコネクタ

基板には、MyoWare 2.0筋電センサーの上に簡単に積み重ねられる3つのメススナップコネクタが搭載されている。

  • GND:電源用グラウンド。
  • VIN:電源用の電圧入力。この電圧は、LiPoバッテリーがどれだけ充電されているかによって異なる。充電用の電源に接続すると、充電ICがLiPoバッテリーの充電を開始し、電圧はおよそ4.2Vになることがある。安全上の理由から、バッテリーを充電する際は、常にこのシールドをセンサーから取り外しておくことを推奨する。
  • ENV:0〜VINの範囲のエンベロープ信号。マイクロコントローラーのADCに接続する。

ジャンパー

基板には、デフォルトで閉じているMODE用のジャンパーが1つある。 MODEはLM3914ドット・バードライバーのV+ピンに直接配線されており、バーグラフモードとして動作する。 このモードでは、反対側の最後のLEDが点灯するまで、筋肉信号の大きさに応じてLEDセグメントが次々と点灯し続ける。 MODEジャンパーを切断すると、基板はドットモードになる。 ドットモードが有効な場合、先頭のLEDバー(「ドット」)が点灯しながらセグメントを移動する。 それより後ろのLEDは、光で埋まる代わりに消灯する。 ジャンパーの変更について詳しくは、ジャンパーパッドとPCBトレースの扱い方のチュートリアルを確認してほしい。

基板寸法

このシールドはMyoWare 2.0筋電センサーと同じフォームファクタを使っているが、基板寸法は他の基板とは異なり、46.15mm × 38.00mm(1.82インチ × 1.50インチ)である。

MyoWare 2.0 Link Shieldは、MyoWare 2.0筋電センサーをArduinoマイクロコントローラーに簡単に接続できるよう設計されている。 このシールドには3.5mmのTRSジャックが用意されており、3.5mmのTRS-TRSケーブルを使って基板同士を接続できる。 MyoWare 2.0 Link Shieldには基板上にスナップコネクタが搭載されており、MyoWare 2.0筋電センサーの表側に簡単に積み重ねられる。 MyoWare 2.0筋電センサーとLink Shieldのスタックをそれぞれリンクするには、MyoWare 2.0 Arduino Shieldと、Arduino Uno R3のフォームファクタを持つ開発ボードが必要になる。

ハードウェア概要

注意: 基板の裏側にあるメスのスナップコネクタは「ソケット」コネクタと呼ばれる。これらのスナップコネクタを扱う技術仕様書やガイドでは、この用語を目にすることがある。

基板の表側にはTRSコネクタ、電源スイッチ、出力スイッチがある。基板の裏側にはメスのスナップコネクタがある。

左:表側 右:裏側

電源スイッチ

電源スイッチは、MyoWare 2.0筋電センサーのオン・オフを切り替える。 電力はArduinoとArduino Shieldから供給される。 デフォルトでは、Arduino Shieldの電源は5Vに設定されている。 スイッチがONの位置に切り替わると、TRS-TRSケーブルのリングピンが5VとVINを接続する。

出力スイッチ

OUTPUTスイッチは、Arduinoのアナログ入力に供給する信号を選択する。

  • ENV:エンベロープ出力
  • REC:整流出力
  • RAW:生出力

3.5mm TRSコネクタ

3.5mmのTRSコネクタは、以下のピンに接続されている。

ピン配置TRSピン
グラウンド [GND]スリーブ
電圧入力 [VIN]リング
ENV/RECT/RAW [OUTPUT]チップ

LED

基板には2つのLEDが搭載されている。

  • VIN:電源スイッチがONの位置に切り替わったときに点灯し、VINスナップピンを通じてMyoWare 2.0筋電センサーに電力が供給されていることを示す。
  • ENV:MyoWare 2.0筋電センサーのENVピンに活動があるときに点灯する。

スナップコネクタ

基板には、MyoWare 2.0筋電センサーの上に簡単に積み重ねられる3つのメススナップコネクタが搭載されている。

  • GND:電源用グラウンド。
  • VIN:電源用の電圧入力。この電圧は、MyoWare 2.0 Arduino Shieldで設定したジャンパーに応じて決まる。この電圧は、MyoWare 2.0 Arduino ShieldのPWRジャンパーの位置に応じて5V(デフォルト)または3.3Vになる。
  • ENV:0〜VINの範囲のエンベロープ信号。マイクロコントローラーのADCに接続する。

ポゴピン

基板の裏側には3つのポゴピンがある。 これらは、SparkFunの店頭で見かける他のポゴピンよりもかなり低い高さになっている。 これらはMyoWare 2.0筋電センサーのPTHパッドに接続される。 MyoWare 2.0 Link Shieldにはこれらのピンにラベルが付いていない点に注意してほしい。 GNDスナップコネクタに最も近いポゴピンがリファレンスピン、スイッチのすぐ隣にあるポゴピンが整流出力ピン、VINスナップコネクタのすぐ上にあるポゴピンが生出力である。

  • REF:リファレンスピン
  • RECT:整流出力ピン
  • RAW:生出力ピン

ジャンパー

基板の表側には3方向ジャンパーが搭載されている。 このジャンパーは、出力とArduinoの相対的なグラウンド基準点を変更できるようにするためのものである。 デフォルトでは、RAW出力はREFと同じであるVIN/2を中心に振れる。 これを0Vを中心とするよう変更したいユーザーもいるかもしれず、その場合は相対的なグラウンド基準点をREFに変更する必要がある。 GNDに接続されたトレースを切断し、REFと中央パッドの間にはんだジャンパーを追加すると、REFポゴピンが筋電センサーのREFに接続される。 ジャンパーの変更について詳しくは、ジャンパーパッドとPCBトレースの扱い方のチュートリアルを確認してほしい。

基板寸法

このシールドはMyoWare 2.0筋電センサーと同じフォームファクタを使っており、基板寸法は37.57mm × 35.90mm(1.48インチ × 1.41インチ)である。

MyoWare 2.0 Arduino Shield

MyoWare 2.0 Arduino Shieldは、3.5mmのTRS-TRSオーディオケーブルを使い、最大6台のMyoWare 2.0筋電センサーLink Shieldを簡単に接続できるよう設計されている。 基板にはあらかじめオスヘッダーが実装されているため、あとはArduinoに重ねてセンサーを接続すれば、最大6つの筋群を読み取れる。 Arduino Shieldのフォームファクタは、Arduino Uno R3の標準フォームファクタを持つ開発ボードにそのまま接続できる。 MyoWare 2.0筋電センサーごとに、MyoWare 2.0 Link ShieldとTRS-TRSケーブルが1つずつ必要になる。

基板同士をリンクするにはTRS-TRSケーブルが必要になる。 もちろん、TRSコネクタに配線をはんだ付けして自作することもできる。 その場合は、正しいピンに配線をはんだ付けすることを忘れないでほしい。

  • Audio Cable TRS - 1m
  • TRS Audio Plug - 3.5mm(Metal、廃盤)

ハードウェア概要

基板の表側にはTRSコネクタとQRコードがある。 スマートフォンを取り出してQRコードをスキャンし、MyoWareの公式サイトを訪れてみるのも一興である。 基板の裏側には、R3フォームファクタを持つArduino開発ボードのメスヘッダーと合わせるためのオスヘッダーがある。

左:表側 右:裏側

3.5mm TRSコネクタ

基板の表側には、6個の3.5mm TRSジャックがある。 それぞれのコネクタは電源と、ArduinoのA0からA5までのアナログピンに接続されている。

3.5mm TRSコネクタは、以下の電極ピンに接続されている。

電極ピンTRSピン
グラウンド [GND]スリーブ
電圧 [VIN]リング
ENV/RECT/RAW [OUTPUT]チップ

⚠ 警告: TRSケーブルをコネクタに挿抜する前に、Arduinoの電源を切ることを推奨する。

予約ピン

5V、3.3V、GNDネット、そしてアナログピン(A0A5)は、このシールド用に予約されている。

注意: Qwiicコネクタが有効なATmega328P搭載のSparkFun RedBoardは、I²C用にアナログピンA4とA5を使う。A4とA5ピンでアナログ値を読み取るには、Qwiicコネクタ用のジャンパーを切断する必要がある。切断しないと、ロジックレベルコンバータのプルアップ抵抗が分圧回路として働いてしまい、低い電圧ではピンが正しい値を読み取れなくなる。ジャンパーの変更について詳しくは、ジャンパーパッドとPCBトレースの扱い方のチュートリアルを確認してほしい。

注意: PTHピンが互い違いのパターンになっていることに気づくはずである。心配は無用で、これは工夫を凝らしたフットプリントを使ったEagle設計の一部である。この千鳥状のPTHホールにより、製造部門ではヘッダーを基板にはんだ付けしやすくなっている。

ジャンパー

基板の裏側にはそれほど多くの要素はない。 裏面にはPWRとラベル付けされたジャンパーがある。 デフォルトでは、この3方向ジャンパーは5Vピンと基板裏面の5Vプレーンを接続している。 中央のパッドはTRSコネクタに接続されており、Link Shield経由でMyoWare 2.0筋電センサーに電力を供給する。 別の電圧を使いたい場合は、トレースを切断し、中央パッドと3.3Vの間にはんだを盛る。 ジャンパーの変更について詳しくは、ジャンパーパッドとPCBトレースの扱い方のチュートリアルを確認してほしい。

基板寸法

このシールドはArduino Uno R3のフォームファクタを使っており、基板寸法は53.34mm × 59.69mm(2.10インチ × 2.35インチ)である。

MyoWare 2.0 Wireless Shield

MyoWare® 2.0 Wireless Shieldは、MyoWare 2.0筋電センサーからの読み取り値を取り込み、ESP32-WROOMでセンサーデータをワイヤレス送信できるよう設計されている。 このシールドには内蔵のLiPoバッテリーも搭載されており、筋電センサーとESP32モジュールの両方にリモートで給電できる。 Wireless Shieldには、スナップコネクタと低背のポゴピンが基板上に搭載されており、MyoWare 2.0筋電センサーの表側に簡単に積み重ねられる。 電源の供給元を選び、電源スイッチをONの位置に切り替えるだけで、筋電計測の魔法を働かせるのに必要な電力がセンサーに供給される。

ハードウェア概要

注意: 基板の裏側にあるメスのスナップコネクタは「ソケット」コネクタと呼ばれる。これらのスナップコネクタを扱う技術仕様書やガイドでは、この用語を目にすることがある。

左:表側 右:裏側

電源

コネクタとスルーホールパッドには、さまざまな電源関連のネットが引き出されている。 Wireless Shieldがどのように給電されるかは、スイッチの設定によって決まる。以下の選択肢を見ていこう。

電源(USB)

USB Type Cコネクタが搭載されており、ESP32への給電とプログラム書き込みに使える。 USBのデータラインにはESD保護ダイオードが接続されており、リセッタブルヒューズと、USB・バッテリーのネット向けの逆極性保護用理想ダイオードも搭載されている。 マイクロコントローラーとコンピュータの間のシリアルデータを確認することもできる。 ただし、MyoWare 2.0筋電センサーに接続する場合は、システムへのノイズの混入を減らし、電力網からの感電を防ぐため、データはワイヤレスで送信することを推奨する。 USBコネクタは、LiPoバッテリーの充電にも使われる。

ESP32に給電するには、スイッチが正しい側に切り替わっていることを確認する必要がある。詳しくは下記のスイッチの節を確認してほしい。

⚡ 危険: コンピュータやUSB充電器でLiPoバッテリーを充電する際や、ESP32へのプログラム書き込み時は、必ずMyoWare 2.0 Wireless ShieldをMyoWare 2.0筋電センサーから取り外すことを推奨する。MyoWare 2.0 Wireless Shieldは、充電中にMyoWare 2.0筋電センサーと組み合わせて使うようには設計されていない。シールドがセンサーの上に積み重なった状態でユーザーに装着したまま、LiPoバッテリーを充電しないこと。これにより、ユーザーが電力網(コンピュータの電源装置や、コンセントに接続されたUSB充電器など)に接続された状態にならないようにし、感電を防止する。

注意: SparkFunのカタログにある電源やコンピュータのUSBポートは、LiPoバッテリーの充電に使えることをテスト済みである。一部の5V電源では、LiPoバッテリーの充電がうまくいかない場合があることもわかっている。

電源(LiPoバッテリー)

基板には、単セルのLiPoバッテリーを安全に充電するMCP73831 LiPo充電IC(5ピンの小さな黒いIC)が搭載されている。 この場合、充電レートは内蔵の40mAh LiPoバッテリーを充電するためおよそ40mAに設定されている。 SparkFunのカタログにある他のLiPoバッテリーと比べ、こちらはより小型の2ピン、1.00mmピッチのJST-SHコネクタを使っている。

注意: LiPoバッテリーの適切な取り扱いについては、Single Cell LiPo Battery Careのチュートリアルを確認してほしい。

スイッチ

基板には2つのスイッチが搭載されている。

  • 電源の供給元(Power Source)
  • 電源のオン・オフ(Power ON/OFF)

Power Sourceは3極双投(TPDT)スイッチである。 スイッチをVBATの位置に切り替えると、電源ネットが3.3Vレギュレータの出力に接続される。 これにより、3.3Vレギュレータの出力がQwiicの3.3Vピンにも接続される。 この位置にスイッチを設定すると、レギュレータの入力が上流の電源(USBまたはLiPoバッテリーからの電圧)に接続される。

スイッチをQWIICの位置に切り替えると、電源ネットがQwiicの3.3Vピンに接続される。 これにより、3.3Vレギュレータの出力はすべてから切り離される。 これにより、Qwiicコネクタ経由でMyoWare 2.0 Wireless Shieldに給電できるようになる。 さらに、レギュレータの入力も上流の電源(USBまたはLiPoバッテリーからの電圧)から切り離される。

注意: POWER SOURCEをQWIICの位置に設定した場合、これだけではLiPoバッテリーを充電できない。LiPoバッテリーを充電する唯一の方法は、USB-Cケーブルを接続することである。

Power ON/OFFとラベル付けされたスイッチは単極単投(SPST)スイッチである。 スイッチをONの位置に切り替えると、電源ネットが3.3Vネットに接続される。

注意: MyoWare 2.0 Wireless Shieldと筋電センサーに初めて電力を入れる際は、対象の筋肉をリラックスさせておくことを推奨する。

スイッチをOFFの位置に切り替えると、電源ネットが3.3Vから切り離される。 これにより、VREGの入力もすべての上流電源から切り離される。 これは、TPDTスイッチの位置にかかわらず、3.3Vレギュレータへの電力を取り除く。

注意: コードをアップロードする際は、POWER SOURCEをVBATの位置に、POWERスイッチをONの位置に切り替えることを推奨する。

3.3V

USBコネクタとLiPoバッテリーからの電圧は、低消費電力のレギュレータ(RT9080)で3.3Vに降圧される。 このレギュレータは、システムに最大600mAの出力電流を供給できる。 Power SourceがVBATTの位置に切り替わっていると、このレギュレータの出力は3.3VのPTHに接続される。 Qwiicコネクタ経由やPTH経由で基板に給電したいユーザーは、Power Sourceのスイッチを必ずQWIICの位置に切り替え、3.3Vに調整された電圧を供給する必要がある。 基板裏側のスナップコネクタも3.3Vに接続されている。これにより、MyoWare 2.0筋電センサーに電力が供給される。

CH340 USB-シリアル変換チップ

基板にはCH340 USB-シリアル変換チップが搭載されている。 このチップは、マイクロコントローラーのハードウェアシリアルUARTとコンピュータのUSBポートの間でシリアルデータを送受信するのに使える。 このチップは、Arduino IDEを使ってESP32にコードをアップロードする際にも使われる。

ほとんどのオペレーティングシステムでは、ドライバが自動的にインストールされるはずである。 とはいえ、オペレーティングシステムには実にさまざまな種類があるため、初めてこのチップをコンピュータのUSBポートに接続する際や、OSの更新後には、ドライバのインストールが必要になることがある。 詳しくは、How to Install CH340 Drivers Tutorialを確認してほしい。

スナップコネクタ

基板には、MyoWare 2.0筋電センサーの上に簡単に積み重ねられる3つのメススナップコネクタが搭載されている。

  • GND:電源用グラウンド。
  • VIN:MyoWare 2.0筋電センサー向けの電圧「出力」。シールドを積み重ねる際に、筋電センサーのシルク印刷にあるVINと一致させるためのものである。この電圧は、スイッチの位置に応じて3.3Vに接続される。安全上の理由から、バッテリーを充電する際は、常にこのシールドをセンサーから取り外しておくことを推奨する。
  • ENV:MyoWare 2.0筋電センサーからの0〜VINの範囲のエンベロープ信号。ESP32のピン39 / A3に接続されている。

ポゴピン

基板の裏側には2つのポゴピンがある。 これらは、SparkFunのカタログで見かける他のポゴピンよりも低背である。 これらはMyoWare 2.0筋電センサーのPTHパッドに接続される。 MyoWare 2.0 Wireless Shieldにはこれらのポゴピンにラベルが付いていない点に注意してほしい。 GNDコネクタに最も近いポゴピンがリファレンスピン、VINの近くのポゴピンが生出力である。

  • REF:MyoWare 2.0筋電センサーからのリファレンスピン。このポゴピンはESP32のピン35 / A5に接続される。
  • RAW:MyoWare 2.0筋電センサーからの生出力ピン。このポゴピンはESP32のピン36 / A4に接続される。

ESP32モジュール

基板の「頭脳」はESP32-WROOMモジュールである。 そのピンは、基板上のさまざまな部品、基板端のPTH、低背のポゴピン、スナップコネクタに引き出されている。

リセットボタンとブートボタン

各基板には2つのモーメンタリボタンが搭載されている。1つはRESET用、もう1つはブートローダーモード(BOOT)用である。 リセットボタンを押すと、ESP32プロセッサが再起動する。 BOOTボタンは、基板をブートローダーモードにするために使う。 基板の起動時やリセット時にこのボタンを押し続けると、基板がブートローダーモードになる。 BOOTボタンは、ユーザー入力用の汎用ボタンとしても機能し、ESP32のピン0に接続されている。 このボタンを使う場合は、ボタン押下後に何らかの処理を行う条件文を書く必要がある。

注意: 汎用ボタンにはプルアップ抵抗が接続されていない。setup()に必ず次のコードを含めること。

pinMode(10, INPUT_PULLUP);

QwiicとI²C

Qwiic接続システムに馴染みがない場合は、こちらの概要を確認しておくことを推奨する。

基板には2つの水平方向のQwiicコネクタが搭載されている。 これらは4ピン、1mmピッチのJST-SHタイプのコネクタである。 これらはESP32モジュールのI²Cピンに接続されている。 I²Cのデータ・クロックラインには、2.2kΩのプルアップ抵抗(画像では強調表示していない)と、絶縁用のトランジスタも接続されている。 「Power Source」スイッチを使い、Qwiic対応デバイス用の電源を必ず選択すること。 これにより、Qwiic対応デバイスを基板に接続できるようになる。 Qwiic対応デバイスを追加して、腕の向きをモニタリングしてみるのもよい。

⚠ 警告: Qwiic対応デバイスを基板にさらに追加すると、LiPoバッテリーの消費が早まり、稼働時間が短くなる。より大きな電源でこれらのデバイスを別途給電することも検討してほしい。その場合、電圧の競合を避けるため、Qwiic対応デバイスとMyoWare 2.0 Wireless Shieldの間の3.3Vを必ず切り離すこと。

LED

基板には4つのLEDがある。

  • PWR:基板に電力が供給されていることを示す。このLEDは3.3Vネットに接続されている。基板裏側のPWRジャンパーを切断すると、このLEDを無効化できる。
  • CHG:バッテリーの充電状態を示すのに使える。充電ICの状態に応じたインジケータの一覧は次のとおりである。
充電状態LEDの状態
バッテリーなしフローティング(通常はOFFだが、点滅することがある)
シャットダウンフローティング(通常はOFFだが、点滅することがある)
充電中ON
充電完了OFF
  • 13:汎用LEDであり、ピン13に接続されている。デフォルトのファームウェアを使っている場合、Bluetoothデバイスに接続されていないときは点滅し、MyoWare 2.0 Wireless ShieldがBluetoothデバイスに接続されると点灯し続ける。
  • ENV:MyoWare 2.0筋電センサーのENVピンに活動があるときに点灯する。

ジャンパー

注意: ジャンパーの扱いが初めての場合は、How to Work with Jumper Pads and PCB Tracesのチュートリアルを確認してほしい。

基板の表側と裏側にジャンパーが用意されている。以下の3つのジャンパーは基板の表側にある。

  • REF:デフォルトでは、このジャンパーはリファレンスピンをESP32のピン35 / A5に接続する。切断すると、リファレンスピンとGPIOピンの接続を断てる。
  • RAW:デフォルトでは、このジャンパーは生のEMG出力をESP32のピン36 / A4に接続する。切断すると、生出力ピンとGPIOピンの接続を断てる。
  • ENV:デフォルトでは、このジャンパーはエンベロープ検出器の出力をESP32のピン39 / A3に接続する。切断すると、エンベロープピンとGPIOピンの接続を断てる。

基板の裏側には3組のジャンパーがある。

  • SHLD:デフォルトで閉じており、基板の裏側にある。このジャンパーは、USB Type CコネクタのシールドピンをGNDに接続する。切断すると、USB Type Cコネクタのシールドを絶縁できる。
  • PWR:デフォルトで閉じており、基板の裏側にある。このトレースを切断すると、3.3Vレギュレータの出力に接続された電源LEDを無効化できる。
  • I2C:デフォルトで閉じている3パッドのジャンパーで、基板の裏側にある。これらは2.2kΩのプルアップ抵抗をI²Cバスに接続する。プルアップ抵抗を有効にした複数のデバイスをバスに接続すると、並列合成抵抗が強すぎるプルアップになり、バスが正しく動作しなくなる。一般的な目安として、複数のデバイスをバスに接続する場合は、1組を除くすべてのプルアップ抵抗を無効化すること。

スルーホール

MyoWare Wireless Shieldには、精密プラスドライバー用の小さなスルーホールがある。 これは、エンベロープ信号のゲインを変更するポテンショメータ(トリムポット)を手動で調整するためのものである。 MyoWare 2.0筋電センサーのハードウェア概要で先述したとおり、デフォルトのゲインはほとんどの用途で十分なはずである。 トリムポットは回しすぎたり力をかけすぎたりすると破損することがあるため、回すときは注意すること。

筋群に合わせてデフォルトのゲインを調整する必要があるユーザーには、シールドのPOWERスイッチをOFFの位置に切り替え、最大努力での筋収縮のピークがVIN / 3.3Vのわずかに下になるようゲインを下げて調整することを推奨する。 その後、シールドを再びオンにし、Bluetoothデバイスを接続し、シリアルデータをワイヤレスでBLEセントラルデバイスに送信してデータを確認する。

基板寸法

基板寸法は63.5mm × 38.000mm(2.50インチ × 1.50インチ)である。

ハードウェアの接続

Advancer Technologiesは、MyoWare 2.0筋電センサー向けにQuick Start GuideとAdvanced Guideを提供している。このガイドと合わせて確認してみてほしい。

筋群を選ぶ

MyoWare 2.0筋電センサーを取り付ける筋群を選ぶ。 筋活動を測定する上で、センサーの配置は非常に重要である。 MID電極を筋腹の中央に、END電極を筋肉の長さの方向に沿うよう位置合わせして接続する必要がある。 REF電極は筋腹に隣接する位置に配置する。

画像提供:Advancer Technologies(MyoWare 2.0 Advanced Guideより)

ここでは前腕を例に使う。 上記のとおり、対象の筋肉に対してセンサーの電極を正しい向きに配置できていれば、どの筋群にもセンサーを接続できる。 下の画像に示す筋群は、実際の縮尺どおりではない点に注意してほしい。

画像提供:Advancer Technologies(MyoWare 2.0 Quick Start Guideより)

他の筋群については、MyoWare 2.0 Advanced Guideを確認してほしい。 筋群をよく確認するには、画像を拡大してほしい。 画像に示されている位置はあくまで目安である。

皮膚の準備

注意: EMGパッドを貼る皮膚に体毛がほとんど、あるいはまったくない状態にしておくこと。必要であれば、余分な体毛を取り除いておく。体毛があると接触不良の原因になるため避けること。

アルコール綿を使い、MyoWare 2.0筋電センサーを取り付ける部分の皮膚を清潔にする。 石けんで皮膚を洗うと皮膚に残留物が残ることがあるため避けること。

EMGパッドを貼る部分の皮膚を、アルコール綿で清潔にする。 イソプロピルアルコールを染み込ませた綿球でも、皮膚の油分や表面の汚れを取り除くのに十分である。 イソプロピルアルコールが蒸発してから、EMGパッドを皮膚に貼ること。

注意: アルコール綿を顔に使うことは推奨しない。皮膚を清潔にする際は、手早く拭き取るだけで十分である。消毒用アルコールを使いすぎると皮膚が乾燥し、皮膚との接触不良によって読み取り値が断続的になることがある。

シールドを積み重ねる

シールドにはキー構造があるため、基板同士を積み重ねる方法は1通りしかない。 GNDまたはREFとラベル付けされたスナップコネクタを探し、位置を揃えるだけでよい。 シールドの電源スイッチが必ずOFFの位置になっていることを確認すること。

親指と人差し指でスナップコネクタを押し込む。 内蔵のLiPoバッテリーを押さないよう注意すること。

筋群への接続

EMGパッドをMyoWare 2.0筋電センサーの裏側にスナップで取り付ける。 MyoWare 2.0 Cable Shieldを使うユーザーは、センサーケーブルのスナップコネクタに取り付けることになる。

電極の裏面を慎重に剥がし、粘着面を露出させる。

対象の筋肉にパッドを取り付ける。ここでは右の前腕を使う。

注意: MyoWare 2.0 Quick Start Guideにあるとおり、皮膚に貼り付けた電極に後からMyoWare 2.0筋電センサーをスナップで取り付けるのは推奨しない。あざの原因になることがある。

注意: デフォルトのゲインは、ほとんどの用途で十分なはずである。とはいえ、上級ユーザーはドライバーを使い、ENV出力のトリムポットを希望のゲイン設定に調整できる。トリムポットを時計回りに回すとゲインが上がり、反時計回りに回すとゲインが下がる。トリムポットは回しすぎや使いすぎで破損することがあるため、回すときは注意すること。

MyoWare 2.0筋電センサーの表側にシールドを積み重ねる際は、電源が切断されていることを確認すること。 すべての接続が終わったら、Power ShieldまたはLED Shieldの電源スイッチをONの位置に切り替える。 センサーをArduinoとコンピュータに接続するユーザーは、コンピュータがコンセントに接続されていないことを確認してから、Link Shieldの電源スイッチをONの位置に切り替える。

シールドをArduino R3開発ボードに接続する

⚡ 危険: MyoWare 2.0筋電センサーをコンピュータに接続してシリアルデバッグを行う際は、入力へのノイズを防ぎ、電力網(コンピュータの電源装置、コンピュータのドック、コンセントに接続された外部モニタなど)に接続された際の感電を防ぐため、USBアイソレータをMyoWare 2.0筋電センサーと組み合わせて使うことを推奨する。下の図は、デスクトップとArduinoのUSBポートの間に接続されたUSBアイソレータ(青い基板として示されている)を示している。

画像提供:Advancer Technologies(MyoWare 2.0 Quick Start Guideより)

USBアイソレータを持っていない場合は、バッテリー駆動のラップトップを使い、コンセントに接続していない状態を確認すること。

ワイヤレスのキーボード・マウスを使うことも推奨する。 筋電センサーは非常に高感度であるため、電源につながった状態のラップトップのトラックパッドやキーボードからの信号を拾ってしまうことがある。 その結果、筋電センサーに誤った読み取り値が生じ、Arduinoのアナログピンが高い値を読み取ってしまうことがある。

3.3VのArduinoを使うユーザーには、デフォルトのトレースを切断し、中央パッドと3.3V側の間にはんだジャンパーを追加してPWRジャンパーを調整することを推奨する。 5VのArduinoを使うユーザーは、ジャンパーを5V側に接続したままにしておいてよい。 ジャンパーの変更について詳しくは、ジャンパーパッドとPCBトレースの扱い方のチュートリアルを確認してほしい。

Arduino Uno R3のフォームファクタを持つ、選んだ開発ボードにArduino Shieldを積み重ねる。

MyoWare 2.0 Link ShieldとArduino ShieldのTRSコネクタの間にTRSケーブルを挿入する。 ここではA0とラベル付けされたコネクタを使う。他のチャンネルを使う場合は、コードを調整することを忘れないでほしい。

リモート用途には、電池パックの使用を推奨する。 ここでは、単三電池(NiMH)と4本用の電池パックでシステムに給電した。

コンピュータに接続する電源を取り外してから、MyoWare 2.0筋電センサーを接続したArduinoをUSBポートに接続すること。 これは、電力網に接続された際のノイズと感電を防ぐためである。これには、コンピュータのドックや外部モニタも含まれる。

準備ができたら、ArduinoとコンピュータのUSBポートの間にUSBケーブルを挿入する。

Bluetooth経由でセンサーデータを送信するユーザーは、Bluetoothペリフェラルデバイスとして動作するRedBoard Artemisに電池パックを取り付ける。 これは、Bluetoothペリフェラル用のサンプルコードがすでにアップロードされている前提である。 Bluetoothセントラルデバイスとして動作するRedBoard Artemisを、コンピュータのUSBポートに接続する。 Bluetoothペリフェラルデバイスは切断されているため、MyoWare 2.0筋電センサーはコンセントに接続されていないので、ラップトップは電源に接続してもよい。 ペリフェラルとして動作するRedBoard Artemisに再度プログラムを書き込む必要があるたびに、電源を必ず抜くようにするだけでよい。

注意: どちらの基板にコードをアップロードしているかわからなくなったら、付箋を用意して、それぞれのRedBoard Artemisに「peripheral」「central」とラベル付けしてみるとよい。

注意: はんだ付けをするユーザーは、筋電センサーのPTHパッドに配線をはんだ付けし、マイクロコントローラーのアナログ入力に接続することもできる。次の画像は、MyoWare 2.0筋電センサーをArduino Uno R3に接続した例を示している。とはいえ、Raspberry PiのRP2040や、アナログ入力を持つ他のマイクロコントローラーに接続することもできる。マイクロコントローラーのシステム電圧が3.3Vの場合は、筋電センサーのVINに3.3Vを接続することを忘れないでほしい。

Wireless Shieldを筋電センサーに接続する

注意: デフォルトでは、MyoWare 2.0 Wireless Shieldにはペリフェラルデバイスとして動作するファームウェアが含まれている。MyoWare 2.0 Wireless Shieldを1台だけ接続するユーザーは、セントラルデバイス側にコードをアップロードするだけでよい。

注意: BLEペリフェラルまたはセントラルデバイスのどちらにファームウェアをアップロードする場合も、MyoWare Arduino Libraryを必ずインストールすること。詳しくは、MyoWare Arduino Libraryの節を確認してほしい。

Wireless Shieldに新しいコードをアップロードする際は、MyoWare 2.0 Wireless Shieldとコンピュータの USBポートの間にUSBケーブルを接続する必要がある。 Wireless ShieldのPOWER SOURCEを選択する(この場合は内蔵のLiPoバッテリーを使うため、スイッチをVBAT側に切り替えた)。 準備ができたら、POWERスイッチをONの位置に切り替え、Arduino IDEを使って改造版のペリフェラルコード(すなわちMyoWareBLEPeripheral.ino)のアップロードを開始する。 これは、内蔵のLiPoバッテリーを充電する方法でもある。

コードのアップロード後、POWERスイッチをOFFの位置に切り替える。 Power ShieldやLED Shieldのときと同様に、MyoWare 2.0筋電センサーの上にシールドを積み重ねる。 続いて、EMGパッドを基板の裏側に取り付ける。

注意: 筋活動を測定するには、Wireless ShieldをMyoWare 2.0 Sensorの上に積み重ねる必要がある。Wireless Shield単体では筋活動を測定できない。

互換性のあるESP32開発ボードをコンピュータのUSBポートに接続する。 これがBluetoothセントラルデバイスとして動作する。 準備ができたら、セントラルデバイス用のコード(すなわちMyoWareBLECentral.ino)をESP32にアップロードする。 ここでは、IoT RedBoard - ESP32を使用した。

この時点で、筋電センサーを筋群に取り付ける前のセットアップは、下の画像のようになっているはずである。 どちらの基板がペリフェラルでどちらがセントラルかを把握しておくため、油性ペンやラベルメーカーで基板にラベルを付けておくとよい。

筋群を選んだら、アルコール綿で皮膚を準備し、電極の裏面を剥がし、スタックを筋群に取り付ける。 ここでは前腕を使用した。

Qwiic対応デバイスをWireless Shieldに接続する

他のQwiic対応デバイスを接続したい場合は、2枚の基板の間にQwiicケーブルを挿入するだけでよい。 あとは、Qwiic対応デバイスを収めるケースを用意するか、取り付ける方法を工夫すればよい。

外部ケーブル

センサーパッドをセンサーから離れた場所に取り付ける必要がある筋肉の場合は、MyoWare 2.0 Cable ShieldをMyoWare 2.0筋電センサーの裏側にスナップで取り付ける。 続いて、センサーケーブルを3.5mmのTRSコネクタに挿入する。

EMGパッドをスナップコネクタに取り付ける。 皮膚を清潔にし、筋肉を選んだら、電極の裏面を剥がして粘着面を露出させる。 続いて、MID、END、REFに応じて対象の筋群にパッドを取り付ける。

スナップコネクタTRSピン電極ピン(CAB-12970)
リファレンス [REF]スリーブ
端部 [END]リング
中間 [MID]チップ

リファレンスケーブル

注意: 内蔵のリファレンススナップコネクタは、ほとんどの用途で十分なはずである。とはいえ、筋群への接続が難しい場合は、リファレンスケーブルの入手を推奨する。これは主に、大腿四頭筋やハムストリングスなど大きな筋群向けに用意されている。

ホビーナイフを使い、GNDピンに最も近いリファレンスジャンパーパッドを切断する。 ジャンパーの近くにトレースがあるため、隣接するトレースを誤って切断しないよう注意すること。 ジャンパーの変更について詳しくは、ジャンパーパッドとPCBトレースの扱い方のチュートリアルを確認してほしい。

続いて、リファレンスケーブルをMyoWare 2.0筋電センサーに挿入する。タブが基板から離れる向きになるよう、ピンをハウジングにスライドさせる。

MyoWare 2.0筋電センサーの上にシールドを積み重ねる際は、ケーブルをシールドのスナップピンから慎重に離しておくこと。

注意: リファレンスケーブルの配線が、MyoWare 2.0 Link Shieldのリファレンスポゴピンの上に重なることに気づくはずである。許容範囲が小さいため、シールドを上に積み重ねる際はケーブルをそっと引き離す必要がある。

リファレンスケーブルを取り外すには、マイナスドライバーの先端でタブをハウジングに押し込み、ピンをそっとハウジングから引き抜く。

ジャンパーパッドを閉じるには、ジャンパーパッドに少量のはんだを加える。

MyoWareシールドの取り外し

プロトタイピングの際には、異なるシールドを試したり、トリムポットを調整したりしたくなることがある。 基板を取り外すには、マイナスドライバーが必要になる。 電源を切った状態で、マイナスドライバーをスナップコネクタの間に挿入し、ドライバーの妨げになる部品がないことを確認する。 マイナスドライバーをスナップコネクタの間にそっと滑り込ませる。

コネクタに対してドライバーを傾け、基板が外れるまで動かす。

片側が外れたら、基板同士を引き離し、残る2つのスナップコネクタも外す。

スタンドアロンExample 0:LED

Arduinoなしで MyoWare 2.0筋電センサーをテストするには、MyoWare 2.0 Power ShieldまたはLED Shieldを使う方法がある。 どちらのシールドにも内蔵バッテリーがあるため、センサーに電源をはんだ付けする必要がない。 基板同士を積み重ねて筋群に貼り付けたら、電源スイッチをONの位置に切り替える。 筋肉を動かし始めて、Power ShieldのENV LEDやLED ShieldのLEDセグメントを点灯させられるか試してみてほしい。

MyoWare 2.0 Power Shieldを使っている場合は、ENV LEDを観察してほしい。 LEDは消灯しているはずである。 筋肉を収縮させると、ENVピンからの電圧が上昇する。 その結果、収縮するにつれてENV LEDが点灯し始め、明るさが増していく。 積み重ねた基板の間をよく見ると、MyoWare 2.0筋電センサー上のENV LEDが点灯していることにも気づくはずである。

MyoWare 2.0 LED Shieldを使っている場合は、LEDセグメントを観察してほしい。 LEDセグメントは消灯しているはずである。 筋肉を収縮させると、ENVピンからの電圧が上昇する。 その結果、LEDセグメントが点灯し始める。 筋肉を収縮させるほど、より多くのLEDセグメントが点灯する。 完全に収縮させると、10個すべてのLEDセグメントが点灯する。

MyoWare 2.0 LED ShieldでMODEとラベル付けされたジャンパーを切断した(すなわちドットモードを有効にした)ユーザーは、異なる効果を目にするはずである。 先頭のLEDバー(「ドット」)が点灯しながらセグメントを移動する。 それより後ろのLEDは、光で埋まる代わりに消灯する。 完全に収縮させると、1つのLEDセグメントだけが点灯するはずである。

Arduino Example 1:アナログ読み取り(単一センサー)

⚡ 危険: MyoWare 2.0筋電センサーをコンピュータに接続してシリアルデバッグを行う際は、入力へのノイズを防ぎ、電力網(コンピュータの電源装置、コンピュータのドック、コンセントに接続された外部モニタなど)に接続された際の感電を防ぐため、USBアイソレータをMyoWare 2.0筋電センサーと組み合わせて使うことを推奨する。USBアイソレータを持っていない場合は、バッテリー駆動のラップトップを使い、コンセントに接続していない状態を確認すること。ワイヤレスのキーボード・マウスを使うことも推奨する。筋電センサーは非常に高感度であるため、電源につながった状態のラップトップのトラックパッドやキーボードからの信号を拾ってしまうことがある。

注意: このサンプルは、デスクトップで最新版のArduino IDEを使っている前提である。Arduinoを初めて使う場合は、Arduino IDEのインストールに関するチュートリアルを確認してほしい。RedBoard Artemisを使う場合は、ボード定義のインストールに関するガイドを確認してほしい。

Example 1:アナログ読み取り(単一)

⚠ 警告: 基板に電源が入っている間は、MyoWare 2.0 Link Shieldの出力(RAW、RECT、ENVの間)を切り替えないこと。出力スイッチを切り替えると電圧スパイクが発生し、筋電センサーを損傷することがある。

以下のサンプルは、Atmega328P搭載のRedBoard Plus上のアナログ入力を使い、筋電センサーのアナログ信号を読み取る。 ただし、Arduino Uno R3のフォームファクタを持つマイクロコントローラーであれば、どれでも使える。

まだであれば、ボード(この場合はArduino Uno)と、対応するCOMポートを選択する。基板にコードをアップロードする。

/*
  MyoWare Example_01_analogRead_SINGLE
  SparkFun Electronics
  Pete Lewis
  3/24/2022
  License: This code is public domain but you buy me a beverage if you use this and we meet someday.
  This code was adapted from the MyoWare analogReadValue.ino example found here:
  https://github.com/AdvancerTechnologies/MyoWare_MuscleSensor

  This example streams the data from a single MyoWare sensor attached to ADC A0.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).

  *Only run on a laptop using its battery. Do not plug in laptop charger/dock/monitor.

  *Do not touch your laptop trackpad or keyboard while the MyoWare sensor is powered.

  Hardware:
  SparkFun RedBoard Artemis (or Arduino of choice)
  USB from Artemis to Computer.
  Output from sensor connected to your Arduino pin A0

  This example code is in the public domain.
*/

void setup() 
{
  Serial.begin(115200);
  while (!Serial); // optionally wait for serial terminal to open
  Serial.println("MyoWare Example_01_analogRead_SINGLE");
}

void loop() 
{  
  int sensorValue = analogRead(A0); // read the input on analog pin A0

  Serial.println(sensorValue); // print out the value you read

  delay(50); // to avoid overloading the serial terminal
}

アップロードが終わったら、Arduino Serial Plotter(Tools > Serial Plotter)を開き、ボーレートを115200に設定する。 MyoWare 2.0 Link Shieldの電源スイッチを切り替えて給電し、筋肉を収縮させ始めてみよう。 下のようなエンベロープ信号の出力が見られるはずである。 ここでは、MyoWare 2.0筋電センサーを右の前腕に取り付けた。 シリアル出力を確認したい場合は、Arduino Serial Monitorを開いて値を確認することもできる。

エンベロープ信号のシリアルプロッター

整流信号や生信号を確認するには、Link Shieldの電源スイッチをOFFの位置に切り替え、OUTPUTスイッチを整流または生の位置に調整してから、電源スイッチを再びONの位置に切り替える。 Serial Plotterを開き直すと、前腕を収縮させたときに、より小さな信号出力が見られるはずである。

以下の画像は、およそ300msの時点で前腕を収縮させ、整流出力ではおよそ22、生出力ではおよそ20の値だけ信号が増加している様子を示している。 なお、生信号はおよそ+VIN/2の電圧オフセットを中心に振れる。 波形の正・負の両方の部分が確認できるよう、+VINをマイクロコントローラーのADCの最大電圧に合わせておくこと。 グラフに示されている出力は値であり、電圧に変換されたものではない。

Arduino Example 2:Bluetooth®経由でセンサーデータを送信する(単一センサー)

注意: コードをアップロードする際は、コンピュータで2台のRedBoard Artemisを使うことになるため、正しいCOMポートを必ず選択すること。混乱を避けるため、アップロードしない側の基板を切断しておくか、テープでラベルを付けておくとよい。時間を節約するには、Arduino IDEを2つ起動し、それぞれの基板に対応するCOMポートを選ぶこともできる。

注意: このサンプルは、デスクトップで最新版のArduino IDEを使っている前提である。Arduinoを初めて使う場合は、Arduino IDEのインストールに関するチュートリアルを確認してほしい。このサンプルではBluetoothにRedBoard Artemisを使うため、ボード定義のインストールに関するガイドを確認してほしい。

以下のサンプルは、1台の筋電センサーからのセンサーデータを送受信するために2台のRedBoard Artemisを必要とする。 これは、クリーンな信号が必要な場合や、センサーデータをワイヤレスで送信したい場合に役立つ。

Bluetoothのペリフェラルデバイスとセントラルデバイスがどのように動作するかについては、ArduinoBLEライブラリのArduinoリファレンスで簡単に確認できる。

Example 2a:Bluetoothペリフェラル「送信」

以下のサンプルは、RedBoard Artemisを使い、アナログ読み取り値をBluetooth経由でワイヤレス送信する。 まだであれば、ボード(この場合はRedBoard Artemis)と、対応するCOMポートを選択する。 下のコードをコピーし、Arduino IDEに貼り付ける。続いて、コードを基板にアップロードする。

/*
  MyoWare Sensor BLE Peripheral SINGLE SENSOR Example
  SparkFun Electronics
  Pete Lewis
  3/17/2022

  This example reads a single MyoWare Muscle Sensor, and then gets that data from this RedBoard Artemis 
  (the peripheral) to a second RedBoard Artemis (the central) over BLE.

  This Artemis, aka the "BLE Peripheral", will read the sensor on A0.
  It will then update the value to the "bluetooth bulletin board."

  Note, in BLE, you have services, characteristics and values.
  Read more about it here:

  https://www.arduino.cc/reference/en/libraries/arduinoble/

  Note, before it begins reading the ADC and updating the data,
  It first sets up some BLE stuff:
    1. sets up as a peripheral
    2. sets up a service and characteristic (the data)
        -Note, Services and characteristics have custom 128-bit UUID,
        -These must match the UUIDs in the code on the central device.
    3. advertises itself

  In order for this example to work, you will need a second Artemis, and it will
  need to be programmed with the provided code specific to being a central device, 
  looking for this specific peripheral/service/characteristic.

  Note, both the service and the characteristic get unique UUIDs 
  (even though they are extremely close to being the same thing in this example)

  The second Artemis, aka the "BLE Central," will subscribe to the first board's 
  characteristic, and check to see if the value has been updated. When it has been 
  updated, it will print the value to the serial terminal.

  Hardware:
  MyoWare Sensor with Link Shield snapped on top.
  TRS cable from Link Shield to A0 port of Arduino Shield.
  Arduino Shield pressed into RedBoard Artemis.
  USB from Artemis to Computer.

  ** For consistent BT connection follow these steps:
  ** 1. Reset Peripheral
  ** 2. Wait 5 seconds
  ** 3. Reset Central
  ** 4. Enjoy BT connection
  **
  ** ArduinoBLE does not support RE-connecting two devices.
  ** If you loose connection, you must follow this hardware reset sequence again.

  This example code is in the public domain.
*/

#include <ArduinoBLE.h>

BLEService sensorDataService("19b10000-e8f2-537e-4f6c-d104768a1214"); // BLE Service named "sensorDataService"

// BLE Data Characteristic - custom 128-bit UUID, readable, writable and subscribable by central
// Note, "BLENotify" is what makes it subscribable
BLEByteCharacteristic dataCharacteristic("19b10001-e8f2-537e-4f6c-d104768a1214", BLERead | BLEWrite | BLENotify); 

const int ledPin = LED_BUILTIN; // pin to use for the LED

void setup() 
{
  Serial.begin(115200);
  while (!Serial); // optionally wait for serial terminal to open, useful with micros that have native USB
  Serial.println("MyoWare Single Sensor Example - BLE Peripheral");

  pinMode(ledPin, OUTPUT); // set LED pin to output mode

  if (!BLE.begin()) { // begin initialization
    Serial.println("starting BLE failed!");
    while (1);
  }
  Serial.println("BLE initiallized successfully");

  BLE.setLocalName("MYOWARE1"); // set advertised local name
  BLE.setAdvertisedService(sensorDataService); // set advertised service UUID
  sensorDataService.addCharacteristic(dataCharacteristic); // add the characteristic to the service
  BLE.addService(sensorDataService); // add service
  dataCharacteristic.writeValue(0); // set the initial value for the characeristic
  BLE.advertise(); // start advertising
}

void loop() 
{
  BLEDevice central = BLE.central(); // listen for BLE peripherals to connect

  if (central) // if a central is connected to peripheral
  {
    Serial.print("Connected to central: ");
    Serial.println(central.address()); // print the central's MAC address

    Serial.println("Reading Sensor and writing BLE characteristic values now...");

    // while the central is still connected to peripheral:
    while (central.connected()) 
    {
      int val_int = analogRead(A0); // Read the sensor attached to Analog Pin A0
      byte val_byte = map(val_int, 0, 1023, 0, 255); // map the int to a byte
      delay(10);
      dataCharacteristic.writeValue(val_byte); // "post" to "BLE bulletin board"
      // Note, because our second Artemis in this example (the central) is subscribed to this characteristic,
      // it can simply call Characteristic.valueUpdated() to see if it has been updated.
      // valueUpdated() will return True if updated, or false if no update has happened.
      // If it has been updated, the central Artemis can read the latest value using Characteristic.readValue();
    }
    Serial.print(F("Disconnected from central: ")); // when the central disconnects, print it out
    Serial.println(central.address());
  }
}

Example 2b:Bluetoothセントラル「受信」

以下のサンプルは、RedBoard Artemisを使い、ペリフェラル側のRedBoard Artemisからアナログ読み取り値をBluetooth経由でワイヤレス受信する。 まだであれば、ボード(この場合はRedBoard Artemis)と、対応するCOMポートを選択する。 下のコードをコピーし、Arduino IDEに貼り付ける。続いて、コードを基板にアップロードする。

/*
  MyoWare Receiver BLE Central SINGLE SENSOR Example
  SparkFun Electronics
  Pete Lewis
  3/17/2022

  This example sets up a SparkFun RedBoard Artemis as a BLE central device,
  Then, it connects to a second Artemis peripheral device that is reading a single MyoWare
  Muscle sensor. It then streams the data on the Serial Terminal.

  Note, in BLE, you have services, characteristics and values.
  Read more about it here:

  https://www.arduino.cc/reference/en/libraries/arduinoble/

  Note, before it begins checking the data and printing it,
  It first sets up some BLE stuff:
    1. sets up as a central
    2. scans for any peripherals
    3. Connects to the device named "MYOWARE1"
    4. Subscribes MYOWARE1's data characteristic

  In order for this example to work, you will need a second Artemis, and it will
  need to be programmed with the provided code specific to being a peripheral device, 
  and advertising as MYOWARE1 with the specific characteristic UUID.

  Note, both the service and the characteristic get unique UUIDs 
  (even though they are extremely close to being the same thing in this example)

  This Artemis, aka the "BLE Central," will subscribe to the peripheral board's 
  characteristic, and check to see if the value has been updated. When it has been 
  updated, it will print the value to the serial terminal.

  Hardware:
  SparkFun RedBoard Artemis
  USB from Artemis to Computer.

  ** For consistent BT connection follow these steps:
  ** 1. Reset Peripheral
  ** 2. Wait 5 seconds
  ** 3. Reset Central
  ** 4. Enjoy BT connection
  **
  ** ArduinoBLE does not support RE-connecting two devices.
  ** If you loose connection, you must follow this hardware reset sequence again.

  This example code is in the public domain.
*/

#include <ArduinoBLE.h>

void setup() 
{
  Serial.begin(115200);
  while (!Serial); // optionally wait for serial terminal to open, useful with micros that have native USB
  Serial.println("MyoWare Single Sensor Example - BLE Central");

  if (!BLE.begin()) // initialize the BLE hardware
  { 
    Serial.println("starting BLE failed!");
    while (1);
  }
  Serial.println("BLE initiallized successfully");

  BLE.scanForUuid("19b10000-e8f2-537e-4f6c-d104768a1214"); // start scanning for peripherals
}

void loop() 
{
  BLEDevice peripheral = BLE.available(); // check if a peripheral has been discovered

  if (peripheral) // discovered a peripheral, print out its info
  {
    Serial.print("Found ");
    Serial.print(peripheral.address());
    Serial.print(" '");
    Serial.print(peripheral.localName());
    Serial.print("' ");
    Serial.print(peripheral.advertisedServiceUuid());
    Serial.println();

    if (peripheral.localName() != "MYOWARE1")
    {
      return;
    }

    BLE.stopScan();

    checkUpdate(peripheral);

    Serial.println("Starting to scan for new peripherals again...");
    BLE.scanForUuid("19b10000-e8f2-537e-4f6c-d104768a1214"); // peripheral disconnected, scan again
    Serial.println("Scan has begun...");
  }
}

// Connect to peripheral
// Then continue to check if the data has been updated,
// If so, print it to terminal
void checkUpdate(BLEDevice peripheral) 
{
  Serial.println("Connecting ..."); // connect to the peripheral

  if (peripheral.connect()) 
  {
    Serial.println("Connected");
  } else {
    Serial.println("Failed to connect!");
    return;
  }

  Serial.println("Discovering attributes ..."); // discover peripheral attributes
  if (peripheral.discoverAttributes()) 
  {
    Serial.println("Attributes discovered");
  } else {
    Serial.println("Attribute discovery failed!");
    peripheral.disconnect();
    return;
  }

  // retrieve the data characteristic
  BLECharacteristic dataCharacteristic = peripheral.characteristic("19b10001-e8f2-537e-4f6c-d104768a1214");

  if (!dataCharacteristic) 
  {
    Serial.println("Peripheral does not have that characteristic!");
    peripheral.disconnect();
    return;
  } else if (!dataCharacteristic.canWrite()) 
  {
    Serial.println("Peripheral does not have a writable characteristic!");
    peripheral.disconnect();
    return;
  } else if (!dataCharacteristic.canRead()) 
  {
    Serial.println("Peripheral does not have a readable characteristic!");
    peripheral.disconnect();
    return;
  } else if (!dataCharacteristic.canSubscribe()) 
  {
    Serial.println("Characteristic is not subscribable!");
    peripheral.disconnect();
    return;
  } else if (!dataCharacteristic.subscribe()) 
  {
    Serial.println("subscription failed!");
    peripheral.disconnect();
    return;
  }

  while (peripheral.connected()) // while the peripheral is connected
  {
    if (dataCharacteristic.valueUpdated()) // Check to see if the value of the characteristic has been updated
    {
      byte received_val = 0;
      dataCharacteristic.readValue(received_val); // note, readValue returns nothing, and needs the variable to be passed by reference
      Serial.println(received_val);
    }
    delay(1);
  }
  Serial.println("Peripheral disconnected");
}

実際に確認できること

それぞれの基板に対応するCOMポートを選んだ2つのArduino IDEを開いた状態で、115200ボーに設定したSerial Monitorに次のような出力が見られるはずである。 Bluetoothの接続がうまくいかない場合は、まずペリフェラル側のリセットボタンを押し、5秒ほど待ってから、セントラル側のリセットボタンを押してみてほしい。 接続できたら、筋電センサーの読み取り値がセントラルへワイヤレス送信される。 腕を収縮させて、値が増加する様子を確認してみてほしい。

グラフィカルな出力を確認したい場合は、セントラルデバイス(センサーデータを受信するRedBoard Artemis)用のArduino Serial Monitorを閉じる。 続いて、Arduino Serial Plotterを開く。 下のような出力が見られるはずである。 ここでは、前腕の筋肉を収縮させると値が増加し、筋肉をリラックスさせると値が減少した。

さらなるサンプル

もっとサンプルを探しているだろうか。 BLE経由で複数のアナログチャンネルを使うGitHubリポジトリも確認してみてほしい。 Tsunami Super WAV Trigger(Qwiic)とスピーカーに接続するプロジェクトのサンプルもある。

GitHubリポジトリ:SparkFun MyoWare Code Examples

異なるマイクロコントローラーを使っているだろうか。 MakeCode_ExamplesフォルダーからMakeCodeとmicro:bitでもこのセンサーを使える。 Python_ExamplesフォルダーにあるRP2040向けのMicroPythonのサンプルも確認してみてほしい。

MyoWare Arduinoライブラリ

注意: このサンプルは、デスクトップで最新版のArduino IDEを使っている前提である。Arduino IDE、ライブラリ、ボードアドオンを初めて使う場合は、以下のチュートリアルを確認してほしい。

  • Installing the Arduino IDE
  • Installing an Arduino Library
  • Installing Board Definitions in the Arduino IDE

注意: CH340デバイスをコンピュータに接続したことがない場合は、USB-シリアル変換チップ用のドライバのインストールが必要になることがある。インストールについては、How to Install CH340 Driversの節を確認してほしい。

Advancer Technologiesは、MyoWare 2.0筋電センサーとそのエコシステム向けのArduinoライブラリを作成している。 このライブラリは、MyoWare 2.0筋電センサーやMyoWare 2.0 Wireless Shieldなどとのやり取りをユーザーが行いやすくする。 MyoWare Arduinoライブラリは、Arduino Library Managerで「MyoWare Arduino Library」と検索してダウンロードできるほか、GitHubリポジトリからZIPファイルを入手して手動でインストールすることもできる。

AdvancerTechnologies / MyoWare Arduino Library(ZIP)

Arduino Example 3:Wireless Shield(ESP32)を使ってBluetooth®経由でセンサーデータを送信する

注意: コードをアップロードする際は、コンピュータでIoT RedBoard - ESP32とMyoware 2.0 Wireless Shieldを使うことになるため、正しいCOMポートを必ず選択すること。混乱を避けるため、アップロードしない側の基板を切断しておくか、テープでラベルを付けておくとよい。時間を節約するには、Arduino IDEを2つ起動し、それぞれの基板に対応するCOMポートを選ぶこともできる。

注意: このサンプルは、デスクトップで最新版のArduino IDEを使っている前提である。Arduinoを初めて使う場合は、Arduino IDEのインストールに関するチュートリアルを確認してほしい。このサンプルではBluetoothにIoT RedBoard - ESP32とMyoWare 2.0 Wireless Shieldを使うため、ボード定義のインストールに関するガイドを確認してほしい。

以下のサンプルは、1台の筋電センサーからのセンサーデータを送受信するために、Wireless ShieldとBLEモジュールを必要とする。 これは、クリーンな信号が必要な場合や、センサーデータをワイヤレスで送信したい場合に役立つ。

Bluetoothのペリフェラルデバイスとセントラルデバイスがどのように動作するかについては、ArduinoBLEライブラリのArduinoリファレンスで簡単に確認できる。

注意: 執筆時点では、Arduino IDE、ESP32ボード定義、ArduinoBLE Arduinoライブラリについて、次のバージョンを使用した。

  • Arduino IDE v2.3.2
  • esp32 by Espressif Systems v2.0.14
  • ArduinoBLE by Arduino v1.3.6
  • MyoWare Arduino Library v1.0.0

Example 3a:Bluetoothペリフェラル「送信」

このサンプルは、MyoWare 2.0 Wireless Shieldのファームウェアを改造しているユーザー向けである。 ペリフェラルデバイスを複数使う場合に便利である。 このサンプルコードは、MyoWare 2.0 Wireless Shieldを使ってアナログ読み取り値をBluetooth経由でワイヤレス送信する。 まだであれば、MyoWare 2.0 Wireless Shieldをコンピュータに接続する。 Power Sourceを選び、電源スイッチをONの位置に切り替える。

このサンプルは、別のGitHubリポジトリにあるMyoWare Arduinoライブラリのコードを使用している。 ライブラリをインストールしたら、メニューからFile > Examples > MyoWare Arduino Library > **MyoWareBLEPeripheral**を選択する。

デフォルトでは、Wireless Shieldにはペリフェラルデバイスとして動作するファームウェアが含まれている。 複数のWireless Shieldをセントラルデバイスに接続するユーザーは、それぞれ固有の名前にBLEペリフェラルデバイス名を変更することを推奨する。 このサンプルでは、追加のペリフェラルデバイスごとに、MyoWareBLEPeripheral.ino内の次の行の番号を変更する。

const String localName = "MyoWareSensor1";  // recommend making this unique for 
                                            // each Wireless shield (e.g. MyoWareSensor1,
                                            // MyoWareSensor2, ...)

2台目のWireless Shieldでは、localnameMyoWareSensor2に変更する必要がある。

const String localName = "MyoWareSensor2";  // recommend making this unique for 
                                                // each Wireless shield (e.g. MyoWareSensor1,
                                                // MyoWareSensor2, ...)

まだであれば、ボードと対応するCOMポート(この場合はCOM10のESP32 Dev Module)を選択する。続いて、改造したコードを基板にアップロードする。

Example 3b:Bluetoothセントラル「受信」

以下のサンプルは、IoT RedBoard - ESP32を使い、ペリフェラル側のMyoWare 2.0 Wireless Shieldからアナログ読み取り値を受信する。 もちろん、Arduino BLEに対応する他のArduinoボードも使える。 まだであれば、IoT RedBoard - ESP32をコンピュータに接続する。

このサンプルも、MyoWare Arduinoライブラリのコードを使用している。 ライブラリをインストールしたら、メニューからFile > Examples > MyoWare Arduino Library > **MyoWareBLECentral**を選択する。

まだであれば、ボードと対応するCOMポート(この場合はCOM10のSparkFun ESP32 IoT RedBoard)を選択する。続いて、コードを基板にアップロードする。

実際に確認できること

注意: MyoWare 2.0 Wireless Shieldと筋電センサーに初めて電力を入れる際は、対象の筋肉をリラックスさせておくことを推奨する。

対象の筋群を選び、アルコール綿で皮膚を準備し、電極の裏面を剥がし、スタックを筋群に取り付ける。 ここでは前腕を使用した。POWERスイッチをONの位置に切り替える。

IoT RedBoard - ESP32をコンピュータに接続したまま、Arduino Serial Monitorを開き、ボーレートを115200に設定する。 Bluetoothの接続がうまくいかない場合は、まずペリフェラル側のリセットボタンを押し、5秒ほど待ってから、セントラル側のリセットボタンを押してみてほしい。

  • ペリフェラルをリセットする
  • 5秒待つ
  • セントラルをリセットする
  • Bluetooth接続を楽しむ

注意: ArduinoBLEは、2台のデバイスの再接続に対応していない。接続が切れた場合は、このハードウェアリセットの手順を再び行う必要がある。

注意: ArduinoBLEは、4台以上のペリフェラルデバイスの接続には対応していない。

接続できたら、筋電センサーの読み取り値がセントラルデバイスへワイヤレス送信される。 筋肉を収縮させて、値が増加する様子を確認してみてほしい。 以下は、前腕の筋肉を収縮させ、その後リラックスさせたときのSerial MonitorとSerial Plotterでの読み取り値である。

グラフィカルな出力を確認したい場合は、セントラルデバイス(センサーデータを受信するIoT RedBoard - ESP32)用のArduino Serial Monitorを閉じる。 続いて、Arduino Serial Plotterを開く。 上記と同様の出力が見られるはずである。 ここでは、前腕の筋肉を収縮させると値が増加し、筋肉をリラックスさせると値が減少した。

さらに多くのサンプル

もっとサンプルを探しているだろうか。 MyoWare Arduinoライブラリの他のサンプルも確認してみてほしい。

GitHubリポジトリ:AdvancerTechnologies / MyoWare Arduino Library

トラブルシューティング

期待どおりに動作せず、助けが必要だろうか。 製品が期待どおりに動作しない場合や、技術的なサポートや情報が必要な場合は、SparkFun Technical Assistanceのページで初期のトラブルシューティングを確認してみてほしい。

そこで解決しない場合は、MyoWareのRedditフォーラムや、Biometrics部門のSparkFunフォーラムがヘルプを探したり質問したりするのに適した場所である。

参考までに、MyoWare 2.0 Quick Start Guideに掲載されているMyoWare 2.0筋電センサーのトラブルシューティングのヒントを以下に示す。

  • センサーに電力が供給されている限り、Vin LEDは常に点灯し続けるはずである。
  • 電源を入れると、ENV LEDが一瞬点灯することがあるが、1〜2秒後には消灯するはずである。それ以降は、センサーが筋肉の収縮を検知したときにだけ点灯するはずである。
  • センサー(あるいは外部ケーブル)が皮膚の電極に接続されていない場合、ENV LEDが不規則に点灯・消灯したり、点灯したままになったりすることがある。これは正常な動作である。
  • 皮膚の電極に接続されている状態でENV LEDが一見無作為に点灯する場合は、通常、電極と皮膚の接触不良を示している。その部分を清潔にし、新しい電極を貼ってみてほしい。
  • 収縮させてもENV LEDが点灯しない場合は、センサーのセットアップにさまざまな問題が考えられる。このガイドの手順とヒントを再確認し、正しくセットアップできているか確認してほしい。
  • ほとんどの場合、センサーのゲインを調整する必要はまったくない。
  • センサーから一貫した高品質の信号が得られるようになるまでは、センサーのゲインを調整しないことを推奨する。

MyoWare Wireless Shield

  • Bluetoothが最初の接続に失敗する場合、ペリフェラルとセントラルが互いを発見できていない可能性がある。まずペリフェラル側のリセットボタンを押し、5秒ほど待ってから、セントラル側のリセットボタンを押すという手順で、2つのBluetoothを再接続してみてほしい。
  • MyoWare 2.0 Wireless Shieldがセントラルデバイスに接続されている際、青色のLEDが点滅していたり、完全には点灯していなかったりするだろうか。LiPoバッテリーを確認し、充電されているか確認してみてほしい。

まとめ・参考資料

MyoWare 2.0筋電センサーの立ち上げに成功したら、いよいよ自分のプロジェクトに組み込む番である。 義肢に組み込んだり、サーボを制御して何かを掴んだり、ハロウィンの衣装やビデオゲームに使ったり、ダンスパフォーマンスでLEDを点灯させたりしてみてほしい。 より詳しい情報は、以下のリソースを確認してほしい。

注:この製品は特許で保護されている。模造基板を防ぐため、MyoWare 2.0エコシステムの基板についてはEagle設計ファイルとGitHubのハードウェアリポジトリは公開されていない。

次のプロジェクトのヒントが欲しければ、Biometricsタグの付いた関連チュートリアルも確認してみてほしい。

タグ: Arduino、Artemis、生体計測、BLE、Bluetooth、ESP32、Hookup、LED、電源、センサー、シールド、ウェアラブル、ワイヤレス


出典:Getting Started with the MyoWare® 2.0 Muscle Sensor Ecosystem(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

DMX入門

はじめに

このチュートリアルでは、DMX512(Digital Multiplex with 512 pieces of information、512個の情報を多重化するデジタル方式)について扱う。 もともとは照明用調光器どうしの通信を標準化する手段として作られたDMX512だが、現在ではインテリジェントライトゴボレーザー霧発生装置など、さまざまなステージ照明・演出機器の制御に使われるようになっている。 DMX512は、建築照明の演出(ラスベガスの街並みを思い浮かべてほしい)にも使われるほどである。 このチュートリアルでは、DMXをどのように、そしてどんな場面で導入すればよいかについて知っておくべきことをまとめる。

歴史

DMX512は1986年、USITT(米国劇場技術協会)の技術委員会によって、照明の調光チャンネルを制御する方式として作られた。 1998年にはESTAがDMXをANSI規格として承認してもらうための作業に着手し、2004年にDMX-512Aは「照明機器およびその周辺機器を制御するための非同期シリアルデジタルデータ伝送規格」としてANSIに承認された。

参考になるチュートリアル:

シリアル通信に馴染みがなければ、先に次のチュートリアルを確認しておくとよい。

基本用語

  • フィクスチャー/スレーブ:DMX入力を受け取るあらゆる機器のこと。DMXパケット全体を受信し、自分に関係するデータだけを取り出して処理する(インテリジェントライトゴボレーザー霧発生装置など)。多くのフィクスチャーには、入力をそのまま複製して出す出力チャンネルが備わっている。
  • ユニバース:同じデータを読み取るフィクスチャーを数珠つなぎにした集合のこと。1つのユニバースは512バイトの情報からなるため、ユニバースに接続できるフィクスチャーの数は、各フィクスチャーがアドレス指定に必要とするバイト数によって決まる。
  • コントローラー:DMXデータを生成し、1つまたは複数のユニバースへ送信する機器のこと。たいていはノブやスライダーが多数並んだ大きな操作卓だが、単純なPCをDMXコントローラーとして使うこともできる。

ハードウェア層

DMX512は、照明ブースとステージの間の距離が長くなりがちなため、比較的長い距離にわたって使われることが多い。 信号を送る距離が長くなるほど、周囲からの電磁的なノイズを拾ってしまう区間も長くなる。 これに加えて、DMXは電気的にノイズの多い環境で使われることが多いという事情もあるため、比較的ノイズに強い方式を選ぶ必要があり、DMXはRS-485を採用している。

この種の信号は、データを乗せた1本の線(D+)と、その反転データを乗せたもう1本の線(D-)の差を読み取ることで解釈される。 差を読み取ることから、これを差動信号と呼ぶ。 RS-485のような差動信号は、2本の信号線にほぼ均等にノイズが乗るため、2つの信号の差そのものは変わらずに保たれる。 2つの信号の差を読み取る方式であるため、長距離での通信がしやすいという利点がある(DMX規格が推奨する最大配線長は1000フィートだが、RS-485自体は4000フィートまで対応している)。

DMXデータはたいていXLR-5ケーブルで伝送されるが、DMX対応のXLR-3ケーブルが使われることもある。 RS-485が必要とする線はグラウンド、Data+、Data-の3本だけであり、多くの用途ではこれだけで十分だった。 しかし将来の拡張に備えてもう一対のデータ線が追加されたため、XLR-5ケーブルが必要になった。 これらのコネクタとそのピン配置を以下に示す。

XLR-3

XLR-5

ピンXLR-3XLR-5
1CommonCommon
2Data 1 -Data 1 -
3Data 1 +Data 1 +
4N/AData 2 -
5N/AData 2 +

長距離での通信で問題になるのが、DMX機器どうしが離れた場所でそれぞれ別々に電源を取っていることが多いという点である。 距離が離れているとグラウンドループ、つまり2台の機器のグラウンド電位の差が生じることがあり、この差が十分大きいと機器間に電流が流れてしまう。 こうした事情から、DMX512規格では、DMXフィクスチャー上のマイクロコントローラ部分とDMX部分の間をオプトアイソレータ(フォトカプラ)で絶縁することも定めている。

また、信号の反射を防ぐため、DMX機器の数珠つなぎの末端にある2本のデータ線の間に120Ωの終端抵抗を入れておくことが望ましい。 スイッチで切り替えられる機器もあれば、終端抵抗付きのXLRケーブルを挿すことを推奨する機器もあり、終端抵抗をまったく備えていない機器もある。 終端されていないDMXラインは、ユニバース全体でちらつきを引き起こすことがあるため、ラインが終端されているか必ず確認すること。

パケット構造

DMXデータは、250kbit/sで送られる非同期シリアルデータであり、ストップビットは2ビット、パリティビットはない。 つまり、送信される1クロックパルス(1ビット)にかかる時間は4µsである。 パケットは、送信されるデータがすべてローになる長いブレークから始まる。 これに続くのが、短いハイの区間であるMAB(Mark After Break)である。 その後、11ビットのシリアルフレーム(ロー1ビット、8ビットのデータバイト、ハイ2ビット)からなるスタートコード(SC)が続き、ここで送られるデータは通常0x00である。 スタートコードには別の値を入れることもでき、パケットに含まれるDMXデータの種類を示すことができる。0x17はテキストパケット、0xCCはRemote Device Managementパケット(後述)、0xCFはシステム情報パケットを表し、さまざまなスタートコードがさまざまな種類のデータを示すために使われる。 スタートコードに続いて、同じ構造を持つフレームが最大512個続く。それぞれスロットと呼ばれ、すべてのDMXデータ(RGB値、CMY値、サーボの位置、霧発生装置の圧力など)を格納する。 各フレームの間には、最大1秒間ハイになるMark Time Between Frames(MTBF)を任意で挟むことができる。 データフレームの送信が終わると、さらに最大1秒間のMark Time Between Packets(MTBP)が続く。 ただし、フレームレートを保つため、これらが実際に使われることはめったにない。 次の表に、DMXパケットを構成する各部分のタイミングと略称をまとめる。

パケット略称クロックパルス数タイミング
BreakBREAK2288µs
Mark After BreakMAB28µs
Start CodeSC1144µs
Mark Time Between FramesMTBFX0〜1秒
SlotSLOT1144µs
Mark Time Between PacketsMTBPX0〜1秒
DMX512パケット全体N/A566723ms

DMXパケット全体の送信にかかる時間(23ms)に注目してほしい。 この逆数を取ると、最大フレームレートは44Hzになる。

データのデコード

これまで説明してきたDMXパケットは、数珠つなぎになった機器の列へ送られるが、それぞれの機器はパケットのどのスロットを読み取ればよいと判断しているのだろうか。 DMXフィクスチャーには、どこかにディップスイッチが備わっていることが多く、これで読み取りを開始するスロット番号を選ぶ。フィクスチャーは、そこから決められた数のスロットを読み取る。 たとえば、単純なRGB調光器は3スロットを使う(各色に1スロットずつ)ので、開始スロットを12に設定すると、スロット12、13、14のデータを読み取ることになる。 DMXフィクスチャーは2つ目のストップビットの時点でスロットのカウンタを進める必要があり、これによって次のフレームが始まったとき、マイクロプロセッサはそのデータがどのスロットのものかを把握できる。 このカウンタは、ブレークとマークを検出するたびにリセットされる。 つまり、DMXパケットは必ずしも512スロット全部を持つ必要はなく、カウンタは可変の間隔でリセットできるということである。 ただし、これによって1つのユニバースに収められるフィクスチャーの数は、各フィクスチャーが必要とするスロット数に応じて制限される。

Remote Device Management(RDM)

Remote Device Management、略してRDMは、DMXを使って照明フィクスチャーから情報を取得するための仕組みである。 このプロトコルでは、RDM用のスタートコード(0xCC)を持つDMX512パケットを送り、続けて通信したいフィクスチャーの固有IDを送信する。 コントローラーはその後データ線を解放し、応答を待つ。 一定時間が過ぎても応答がなければ、コントローラーは失敗したと判断し、再試行することがある。 未知のユニバースに接続した際、それぞれのフィクスチャーが何をできるのかを正確に知りたい場合、RDMは非常に便利な手段である。

まとめ

このガイドが、独自の凝った照明フィクスチャーをDMXで通信させ、誰でも自作の点灯パターンを苦労してコーディングせずに制御できるようにする助けになれば幸いである。 ヒントが欲しければ、DMXを使った次のような実装例も参考にしてほしい(いずれも英語)。

タグ: 通信、概念、DMX


出典:Introduction to DMX(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

LTspice入門

LTspiceの概要

Linear Technology社は、便利な無料の回路シミュレーションツールとデバイスモデルを提供している。 このチュートリアルでは、無料の集積回路シミュレータであるLTspice IVの基本的な使い方を扱う。

使い始める

LTspice IVは、Windows版をこちら、Mac OS X 10.7以降向けをこちらからダウンロードできる。 Linear Technology社はこれらのパッケージを随時更新しているため、最新版は公式サイトで確認してほしい。 このチュートリアルではこの実行ファイルへのリンクを使うが、これは筆者が実際に使用しているバージョンである。

Note

Ubuntu Linuxを使っている場合は、WineベースのPlayOnLinuxというツールを検討してみるとよい。ある顧客がUbuntu上でこれを試しており、そのフォーラムへの投稿に詳しい情報がある。PlayOnLinuxのインストールガイドとしては、PlayOnLinux Ubuntu DocumentationHow does one install PlayOnLinux?も参考になる。

LTspice IVを起動したら、次の動画を見ながら、メニューの操作方法や回路図・波形表示の設定、新しい回路図の追加、部品の配置と整理、そして分圧回路の簡単な直流動作点解析の実行方法を確認してほしい。

Getting Started with LTspice(LTspiceの使い始め方)

覚えておくと便利なこと

ホットキーとシミュレータディレクティブ:ショートカットを使うと作業がはかどる。シミュレータディレクティブは、いわゆるドットコマンドである。LTspiceのHELPメニューでこれらをじっくり確認しておくことをおすすめする。HELPメニューには構文と各コマンドの説明が載っている。個々のコマンドについては、今後の動画で1つずつ扱っていく。うまく動かせない場合は、フォーラムで相談してほしい。

ラベル:23ページを開くと、8000ではなく8kのように値をラベル表記する方法がわかる。

シミュレーション:過渡解析

時間領域の過渡解析とは、電圧や電流といったパラメータを時間の関数としてプロットするものである。 出力波形を見れば、指定した時間内での挙動を確認できる。 この例では、半波整流回路の出力をシミュレートする。 この種の解析を通じて、回路図に交流信号源を追加する方法と、特定のダイオードを選ぶ方法を扱う。

Transient Analysis in LTspice(LTspiceでの過渡解析)

シミュレーション:AC解析

AC解析は、回路の周波数特性を示してくれる。 出力波形はボード線図として表示され、指定した周波数範囲における振幅と位相を確認できる。 AC解析にはいくつかの表示方法がある。ボード線図として見ることもできれば、実数軸と虚数軸を持つ直交座標平面上で見ることも、ナイキスト線図として見ることもできる。

ここでは、受動素子だけで構成された1次のローパスフィルタを作り、そのプロットからどのような情報が読み取れるかを見ていく。

AC Analysis in LTspice(LTspiceでのAC解析)

シミュレーション:DCスイープ

DCスイープは、指定したデバイスの電圧や電流を変化させながらシミュレートする解析である。 SparkFunの部品の回路図にはすべて、その製品が安全に動作する電圧範囲が示されている。 そこで、SparkFunの製品を1つ取り上げ、その電圧範囲がどれだけ正確かを確かめてみることにした。 この例では、エレクトレットマイクブレイクアウトボードを扱う。

DC Sweep in LTspice(LTspiceでのDCスイープ)

シミュレーション:ノイズ

ノイズ解析を使うと、正しくモデル化されていれば、システムに内在するノイズや外部から混入するノイズを確認できる。 ノイズがもっとも問題になりやすいのは、精度がすべてを左右するオペアンプ回路である。 たとえば、オペアンプで電流を検知するバッテリー管理システムを考えてみよう。 充電式電池の充電サイクルや負荷電流は、電池全体の健全性とユーザーの安全にとって非常に重要な監視項目である。 オペアンプ回路にノイズが乗ると電流の読み取り値がずれてしまい、マイクロコントローラ側で過電流や電流不足を正しく検知できなくなるなど、望ましくない影響が出ることがある。 本来ならオーディオ回路を例にするほうがわかりやすかったかもしれないが、要は望まないノイズは悪影響を及ぼしうるということである。

引き続きエレクトレットマイクブレイクアウトボードのプリアンプ回路を使い、ノイズ解析を実行してみる。 LTspiceは、回路のショットノイズ、フリッカーノイズ、熱雑音)をモデル化できる。

Noise Analysis in LTspice(LTspiceでのノイズ解析)

シミュレーション:DC伝達関数

DC伝達関数(DC Transfer)は、回路の低周波ゲインと、入力・出力インピーダンスを計算する。 引き続きエレクトレットマイクブレイクアウトボードを例に、まずは伝達関数を計算してみよう。 出力電圧は入力電圧のちょうど半分にバイアスされていることがわかっている。 伝達関数は出力が入力の関数としてどう振る舞うかを表すものなので、この伝達関数は1/2に等しいはずである。 VCCを5Vとすれば、Voutは2.5Vになる。 オペアンプは理想的な電圧源のように振る舞ってほしいので、この回路の出力インピーダンスは低くなるはずである。 出力インピーダンスが低いほど、出力に最大限の電力が供給され、ADCにとって最良の値が得られる。 出力インピーダンスは、0に近いほどよい。 同様に、入力インピーダンスは、信号源から電流を引き込みすぎないよう高くしておきたい。 実際にシミュレーションを行い、伝達関数が狙いどおりに設計されているか確認してみよう。

DC Transfer Function in LTspice(LTspiceでのDC伝達関数解析)

新しいモデルを作る

LTspiceで独自のモデルを作るには、いくつかの手順を踏む必要がある。 モデルは、サブ回路とシンボルから構成される。 ここでは例として、ポテンショメータのモデルを作ってみる。SparkFunの10kトリムポットをもとにしたモデルである。 数か月前、555タイマーをもとにした個人用のはんだ付けキットを設計したことがある。 LTspiceには標準でポテンショメータが用意されていないため、自分で作ることになった。 たいていの場合、トリムポットを抵抗としてシミュレートするだけで問題ない。 しかし、これから電子工作を学ぶ学生にこのキットを配ることを考えており、抵抗のシンボルとその使い方と、ポテンショメータのシンボルがこの回路でどう使われるかの違いを理解してもらいたかった。

以下の動画で、自分のポテンショメータモデルをLTspiceで作る手順を確認できる。

Creating a Potentiometer Model in LTspice(LTspiceでポテンショメータのモデルを作る)

サードパーティ製モデルを追加する

サードパーティ製のモデルをLTspiceに取り込む方法は複数ある。 その中でも、もっとも速くて簡単だと感じている方法を1つ紹介する。 他の方法についても、いずれフォーラムに別の動画を追加する予定である。 うまくいく方法を見つけたら、ぜひフォーラムで共有してほしい。 特定の方法でうまくいかない場合も、フォーラムで質問してもらえれば動画で回答する。

Adding Third Party Models in LTspice(LTspiceにサードパーティ製モデルを追加する)

まとめ

  • LTspice用のフォーラムもぜひ確認してほしい。質問や解決策の投稿、チュートリアルのサンプル回路の入手、毎週追加される新しい動画の視聴、LTspiceコミュニティへの参加ができる。LTspiceのフォーラムは他にもたくさんあるが、新しいフォーラムには新しいフォーラムなりの良さがある。
  • Linear Technology社による動画チュートリアル集もある。
  • Linear Technology社によるLTspiceのGetting Started Guide
  • このリストは随時更新される予定である。

タグ: 概念、電気工学、ツール


出典:Getting Started with LTspice(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

オペアンプ入門(LTspice編)

はじめに

まだLTspice入門ガイドを見ていない場合は、音質の改善が強く望まれるところなので、少し待ってから見てもらうのがよいかもしれない。 すでに視聴し終えた方には、感謝を伝えたい。 今回は一石二鳥を狙い、LTspiceのチュートリアルを続けながら、オペアンプ(Operational Amplifier、略してop amp)の入門も兼ねることにした。 ここで扱うのはあくまで基礎、すなわちオペアンプとは何か、よく使われる構成、いくつかの実例までであり、最後にはアナログ回路にもう少し取り組んでみたくなるような、簡単なプロジェクトで締めくくる。

始めるにあたって、下のボタンから回路図、シンボル、シミュレーションファイルをダウンロードしてほしい。

LTspice SIMs DOWNLOAD

オペアンプとは何か

オペアンプは電圧を増幅する素子である。 いくつかの外部部品と組み合わせることで、能動素子であるオペアンプは、加算、減算、乗算、除算、微分、積分といった数学的な演算を行うことができる。 定番の741のような一般的なオペアンプのパッケージを見ると、標準的な8ピンDIP(デュアルインラインパッケージ)になっていることがわかる。

画像提供:Learning About Electronics

ここで扱うのは、主に5本のピンである。 オペアンプの回路記号は、下の図のように5本のピンを持つ三角形で表される。

画像提供:Virtual Labs

オペアンプの用途は幅広く、各ピンの接続の仕方によって、次のような回路を組むことができる(これは網羅的な一覧ではない)。

  • コンパレータ(比較器)
  • 加算増幅回路のような反転増幅回路
  • ボルテージフォロワのような非反転増幅回路
  • 差動増幅回路
  • 微分回路または積分回路
  • フィルタ
  • ピーク検出回路
  • アナログ-デジタル変換回路
  • 発振回路

このチュートリアルを通じて、ゲイン、帯域幅、誤差、スルーレート、消費電流、出力振幅など、データシートに載っているような典型的なオペアンプの特性をどう測定するかを紹介していく。

理想オペアンプ

オペアンプは、入力端子(プラス側のv2とマイナス側のv1、パッケージのピン2とピン3にあたる)にかかる電圧の差を検出するように設計されている。 この差は差動入力電圧とも呼ばれる。 出力は、入力で検出された差にある値Aを掛けたもので、このAを開ループゲインと呼ぶ。 オペアンプは電圧制御電圧源として振る舞い、これから実際にモデル化していく。 開ループ構成と閉ループ構成の両方の増幅回路をシミュレートする。

理想オペアンプは、次のような特性を持つ。

  • 開ループゲインが無限大
  • 入力抵抗が無限大
  • 出力抵抗がゼロ
  • 同相利得がゼロ(つまり同相除去比が無限大)
  • 帯域幅が無限大
  • ノイズがゼロ
  • 入力オフセットがゼロ

画像提供:Wikipedia

入力抵抗(Rin)が無限大であることから、キルヒホッフの法則を使って、(+)端子(v2)と(-)端子(v1)に流れる電流はゼロであると推論できる。 出力抵抗(Rout)がゼロであるため、出力での電圧損失もない。 上の図にあるひし形の電圧源は電圧制御電圧源と呼ばれ、この場合の電圧はゲイン(G)と入力端子間の差(Vin)を掛け合わせたものになる。 ゲインは通常、文献では(A)と表記され、出力に関する式は次のようになる。

電圧制御電圧源をモデル化し、その振る舞いを理想オペアンプに近づけられるかどうか見てみよう。

Modeling the Ideal Op Amp(理想オペアンプのモデル化)

増幅回路とフィードバック

オペアンプは、単体で使うことを想定した部品ではない。 先ほどの理想オペアンプの動画では、単にVoutの式を確かめることで、なぜオペアンプが電圧制御電圧源と呼ばれるのかを示しただけである。 ここからは、フィードバック閉ループゲイン、そしてその応用について見ていく。 フィードバックとは何だろうか。 フィードバックは、あるシステムの出力が、そのシステム自身の入力へ戻されるときに生じる。 フィードバックには正(再生的)と負(減衰的)の2種類がある。 フィードバックは、システムの次のような性質に影響を与えるために使われる。

  • ゲインの感度を下げる:トランジスタに対する温度の影響のように、回路部品の値のばらつきに対してゲインの値が受ける影響を小さくする。
  • 非線形歪みを減らす:出力が入力に比例するようにする。
  • ノイズの影響を減らす:出力に乗る望ましくない電気的な干渉(外部由来のものも、回路部品自体から生じるものも含む)を減らす。
  • 入力抵抗・出力抵抗を制御する:適切なフィードバック構成を選べば、入力抵抗と出力抵抗を制御できる。
  • 増幅回路の帯域幅を広げる:ここではゲイン帯域幅積を意識しておく必要がある。帯域幅はある程度まで広げられるが、その代償としてゲインが犠牲になる。ゲイン帯域幅積は一定であり、周波数に対するオペアンプのゲインの振る舞いを表す。

単位についての補足

ゲインについて話すとき、これは出力と入力の比を取ったものである。 出力と入力の両方が電圧で表されている場合、単位はVolt/Voltになる。 .ac解析では、ゲインはデシベルで表される。次にその変換式を示す。

画像提供:Planet Analog

フィードバックにはすべて代償があり、その代償こそがゲインである。 負帰還は、ゲインを差し出す代わりに、より望ましい性質を手に入れる取引である。入力抵抗を大きくすることは、帯域幅を広げることにもつながる。

閉ループゲイン

開ループゲインとは異なり、閉ループゲインはフィードバックがあるために外部の回路構成に依存する。 とはいえ、一般的な形で表すことはできる。

画像提供:https://paginas.fe.up.pt/~fff/eBook/MDA/Teo_realim.html

反転増幅回路

反転構成の一例は、1個のオペアンプと2個の抵抗R1、R2からなる。 R2は、オペアンプの出力端子から、反転(マイナス)端子へ接続される。 R2によって、オペアンプの周りにループが閉じられる。

Inverting Amplifiers(反転増幅回路)

以下の動画では触れていないが、理想オペアンプを前提としているために暗黙のうちに成り立っていることとして、オペアンプ自体には電流が流れないという点がある。 R1を流れる電流(I1)は、そのままR2にも流れる。 もう一つ覚えておきたいのは、R1とR2が同じ値であれば、この回路は通常、-voutを+voutに変換する(位相を反転させる)ために使われるという点である。 これは単位ゲイン反転回路として知られている。

プロジェクト:加算増幅回路

反転増幅回路の典型的な応用例が、加算増幅回路であり、オーディオミキシングで使われることから「バーチャルアースミキサー」とも呼ばれる。 手元にLM741のオペアンプがたくさんあったので、実際に加算増幅回路を組んでみることにした。 まずはLTspiceでモデル化した。

Building a Summing Amplifier in LTspice(LTspiceで加算増幅回路を作る)

Testing the Summing Amplifier(加算増幅回路のテスト)

非反転増幅回路

Non-Inverting Amplifiers(非反転増幅回路)

ボルテージフォロワ

ボルテージフォロワは、非反転増幅回路のわかりやすい例である。 非常に高い入力インピーダンスという性質は、非反転構成ならではの望ましい特徴である。 ボルテージフォロワは、インピーダンスの高い信号源からインピーダンスの低い回路へつなぐ単位ゲインのバッファ増幅回路として使うことができ、駆動側の回路に負荷がかかる影響を避けるのに役立つ。

差動増幅回路

差動増幅回路は、入力にかかる2つの信号の差に反応し、両方の入力に共通する信号は除去する。

オペアンプ1個による差動増幅回路

非反転増幅回路のゲインは正の値であり、次の式で表されることを思い出してほしい。

そして反転増幅回路のゲインは負の値であり、次の式で表される。

この2つのトポロジーを組み合わせることで、2つの入力信号の差を得られる回路の設計に近づいていく。 これを実現するには、まずそれぞれのゲインの大きさ(常に正の値となる絶対値と考えてほしい)をそろえる必要がある。 プラス側の経路のゲインを(1 + R2/R1)から(R2/R1)へ減衰させることで、ちょうどそれを実現できる。 これで抵抗が4個になったが、ゲインをそろえるには、抵抗の比が重要になる。

この回路の問題は、高いゲインを得るためにはR1を比較的小さくする必要があるという点である。 これによって入力抵抗が下がってしまう。 もう一つの問題は、この増幅回路のゲインを変化させるのが容易ではないという点である。 どちらの問題も、計装アンプを使うことで解決できる。 オペアンプを3個使うことで、精密に調整された差動増幅回路を作ることができる。 オペアンプ1個では入力抵抗が低くなる問題があったので、それぞれの入力にボルテージフォロワ(バッファ)を追加する。 さらに都合がよいことに、このバッファ自体にゲインを持たせることもでき、2段目の差動増幅回路にかかる負担を軽くできる。

計装アンプは、反転増幅回路と非反転増幅回路を縦続接続するという、ここまでの内容を見事に組み合わせたものである。

このチュートリアルでは、積分回路、微分回路、発振回路、AD変換回路までは扱わない。 コンデンサやインダクタを回路に加え始めると、計算は抵抗ではなくインピーダンスを使ったより専門的で一般化されたものになる。 これらは別のチュートリアルで扱うことにする。

性能特性

LM386オーディオアンプのデータシートを見ると、そのオペアンプの特性を表す数多くのパラメータが載っている。 これらの多くは、LTspiceでのシミュレーションによって確かめることができる。 そこにたどり着く前に、まずはいくつかの特性を定義しておこう。

同相除去比(CMRR)

同相除去比(CMRR)は、両方の入力に共通する信号のうち、増幅されない成分の量を測る指標である。 同相利得は非常に低い、つまりCMRRは非常に高いことが望ましい。

同相除去比は、差動ゲインの絶対値と同相ゲインの絶対値の比である。 差動ゲインは、たいていメーカーが定めたMOSトランジスタの本来のゲインの半分程度になる。 出力抵抗の高いオペアンプほど、優れたCMRRを持つ傾向がある。

電源電圧除去比(PSRR)

電源電圧除去比(PSRR)は、電源のリップルがオペアンプの出力電圧にどれだけ影響を与えるかを測る指標である。 MOSFETデバイスでは、デジタル回路のスイッチングによって電源リップルが増えやすい混載信号ICに搭載されることが多いため、PSRRが重要になる。 設計において絶対に避けたいのは、そのリップルがオペアンプによって増幅されてしまうことである。

ここで押さえておきたいのは、電源のリップルの影響を最小限に抑えるには、オペアンプに大きなPSRRが求められるということである。 今後のプロジェクトでデータシートを見るときは、この点を意識しておくとよい。

スルーレート

スルーレートとは、オペアンプの出力で起こりうる最大の変化速度を指す。 たいていのオペアンプはスルーレートによって制限されており、これはオペアンプの出力電圧を時間で微分した値の最大値として計算される。

全高調波歪率(THD)

オーディオアンプの役割は、小さな信号を受け取り、増幅すること以外の変化を加えずに増幅することである。 これは難しい作業である。というのも、望ましくない信号(リップルなど)まで、目的の信号と一緒に増幅されてしまうことがあるからである。 線形性からのずれは、すべて歪みとみなされる。 高調波歪みは、オーディオ回路でよく見られる歪みの一種で、出力信号のピークが「クリップ」されることによって生じる。 THDとして示されるパーセンテージは低いほどよいが、ある程度を下回ると人間の耳にはほとんど知覚できなくなる。

Measuring Total Harmonic Distortion, Part 1(全高調波歪率の測定・前編)

Measuring Total Harmonic Distortion, Part 2(全高調波歪率の測定・後編)

LM386オーディオアンプ

「シミュレートし、確かめ、作る」というのが筆者のモットーである。 今回のミニポータブルギターアンプのプロジェクトでは、少しやりすぎてしまった。 LTspiceにインポートできるモデルが見つからなかったため、ゼロから作ることにしたのである。 下のボタンから、これから紹介するプロジェクトファイルをダウンロードできる。 LM386をベースにしたオペアンプを設計したが、BJTの代わりにMOSFETを使っている。 実際、この設計は元にしたLM386よりもわずかに優れた性能になったが、動作するのは2〜6Vの範囲に限られる。 筆者のLM386モデルは、実際のプロジェクトで使った部品とまったく同じというわけではないが、オペアンプの電気的特性を確認し、LTspiceに慣れるという目的には十分実用的である。

プロジェクト:ミニポータブルギターアンプ

LM386と最小限の追加部品を使い、ギターのケースに収まる小さな電池駆動のアンプを作った。 製作費用はおよそ5ドルで、組み立てには1時間もかからなかった。 回路は、データシートのアプリケーション例(ゲイン200)からそのまま採用した。

変更したのは出力コンデンサだけである。 手元に250µFのコンデンサがなかったので、470µFに置き換えた。 また、ギターケーブル用の6.35mm(1/4インチ)モノラルオーディオジャックと、動作確認用のステータスLEDも追加した。 筆者のギターケースにはケーブルやピックを収納する小さなスペースがあったので、そこにアンプを組み込んだ。

回路図:

注:J1は6.35mm(1/4インチ)のモノラルオーディオジャックのメス端子である。

実際に動作している様子:

Mini Portable Guitar Amplifier in Action(ミニポータブルギターアンプの動作例)

まとめ

バーチャルオペアンプラボ

Music from Outer Spaceの制作者であるRay Wilson氏が作ったMFOS Virtual Operational Amplifier Applicationを使うと、シミュレートされたオシロスコープで出力を見ながらオペアンプを試すことができる。

Note

注:リンク先でOperational Amp Applicationが見つからないと表示された場合は、ページ上部の「Synth-DIY」タブをクリックすると正しく表示されるはずである。あるいは、左側のメニューから「MFOS In The Classroom」を検索し、「Virtual Op Amp Lab」を選んでもよい。

Music From Outer Space

DIYシンセサイザーに興味はあるが、何から始めればよいかわからない人には、Music From Outer Spaceがおすすめである。Ray Wilson氏が設計した数百点もの回路図が公開されている。

ホビイスト向け

アナログ電子工作を始めたばかりの人には、Forrest Mims氏のEngineer’s Mini Notebooksを強くおすすめする。

CMRRの測定

EE Timesに、同相除去比と差動増幅回路についての素晴らしい記事が掲載されている。

タグ: オーディオ、部品、概念、電気工学、ツール


出典:Introduction to Operational Amplifiers with LTSpice(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Arduinoにおけるデータ型

はじめに

Arduinoを含むコンピュータは、扱うデータの種類にかなり無頓着にできている。 その中心にあるのは算術論理演算装置(ALU)であり、これはメモリ上の値に対して(比較的)単純な演算、たとえばR1+R2、R3×R7、R4&R5のような処理を行う。 ALUにとって、そのデータがユーザーにとって何を表しているか(テキストなのか、整数値なのか、浮動小数点数なのか、あるいはプログラムコードの一部なのか)はどうでもよいことである。

こうした演算に文脈を与えているのはコンパイラであり、その文脈の指示はユーザーからコンパイラへと伝えられる。 プログラマーであるあなたが、コンパイラに対して「この値は整数であり、あの値は浮動小数点数である」と伝えるのである。 そしてコンパイラは、「この整数とあの浮動小数点数を足す」という指示が何を意味するのかを解釈しなければならなくなる。 これは簡単な場合もあれば、そうでない場合もある。 そして、簡単なはずだと思える場合でも、予想外の結果になることがある。

このチュートリアルでは、Arduinoで使える基本的なデータ型と、それぞれの典型的な用途を扱い、データ型の違いがプログラムのサイズと実行速度に与える影響を明らかにしていく。

参考になるチュートリアル:

始める前に、次の概念に馴染んでおくとよいだろう。

データ型を定義する

Arduinoの開発環境は、実のところライブラリのサポートと対象環境に関する組み込みの前提を備えたC++にすぎない。 C++にはさまざまなデータ型が定義されているが、ここではArduinoで使われるものだけを扱い、油断しているArduinoプログラマーを待ち受ける落とし穴に重点を置いて説明する。

以下は、Arduinoでよく見かけるデータ型の一覧であり、型名の後ろの括弧内にそれぞれのメモリサイズを示している。 なお、符号付き(signed)変数は正負両方の値を扱えるのに対し、符号なし(unsigned)変数は正の値しか扱えない。

  • boolean(8ビット):単純な論理値、真か偽か
  • byte(8ビット):0〜255の符号なし数値
  • char(8ビット):-128〜127の符号付き数値。状況によっては、コンパイラがこのデータ型を文字として解釈しようとするため、予期しない結果になることがある
  • unsigned char(8ビット):byteと同じ。この用途で使いたい場合は、わかりやすさのためbyteを使うべきである
  • word(16ビット):0〜65535の符号なし数値
  • unsigned int(16ビット):wordと同じ。わかりやすさと簡潔さのためwordを使うべきである
  • int(16ビット):-32768〜32767の符号付き数値。IDEに付属するArduinoのサンプルコードで、汎用の変数としてもっともよく使われている型である
  • unsigned long(32ビット):0〜4,294,967,295の符号なし数値。もっともよく使われる用途は、millis()関数の戻り値(現在のコードが実行されてからのミリ秒数)を保存することである
  • long(32ビット):-2,147,483,648〜2,147,483,647の符号付き数値
  • float(32ビット):-3.4028235E38〜3.4028235E38の符号付き数値。Arduinoには浮動小数点数のネイティブサポートがなく、コンパイラがあれこれ工夫してようやく動作させている。避けられるなら避けるべきであり、この点については後で触れる。

このチュートリアルでは、配列、ポインタ、文字列は扱わない。これらはより特殊なデータ型であり、より込み入った概念を伴うため、別の機会に扱う。

時間と容量

Arduinoボードの中枢を担うプロセッサ、Atmel ATmega328Pは、ネイティブな8ビットプロセッサであり、浮動小数点数の組み込みサポートを持たない。 8ビットより大きいデータ型を扱うには、コンパイラは大きなデータの塊を少しずつ処理し、その結果を適切な場所に格納するようなコードの並びを生成する必要がある。

つまり、8ビットの値を処理するときにもっとも効率がよく、浮動小数点数を処理するときにもっとも効率が悪いということである。 この事実を確かめるため、簡単なArduinoスケッチを用意した。ごく単純な計算を行うだけのコードで、データ型を変えるだけで同じ計算を異なる型で試せるようになっている。

unsigned long start_time = 0;
unsigned long end_time = 0;

#define test_type byte
test_type x = 1;
test_type y = 2;
test_type z = 3;

void setup()
{
  Serial.begin(57600);
  Serial.println("SparkFun datatype demo.");
  Serial.println("Addition with bytes: x+y=z");
  Serial.print("x=");
  Serial.println(x);
  Serial.print("y=");
  Serial.println(y);
}

void loop()
{
  start_time = micros();
  z=x+y;
  end_time = micros();
  Serial.print("z=");
  Serial.println(z);
  Serial.print("Start time: ");
  Serial.println(start_time);
  Serial.print("End time: ");
  Serial.println(end_time);
  Serial.print("Elapsed time: ");
  Serial.println(end_time - start_time);
  while(1);
}

まずはこのコードをそのままArduino Unoに書き込み、シリアルコンソールにどんな結果が出るか見てみよう。

いろいろな情報が表示されている。1つずつ見ていこう。

まず、実際に試している場合は、コードのコンパイル後のサイズを確認してほしい。 byteでの加算では、コードサイズは2458バイトになった。それほど大きくはなく、実のところ、そのほとんどはシリアル出力関連のコードが占めている。 とはいえ、この数字は後で重要になってくる。

次に、シリアルポートの出力を見てみよう。 表示された変数の値が数字ではなく四角い記号になっているのはなぜだろうか。 これは、Serial.print()関数が渡されたデータの型によって動作を変えるために起こる。 8ビットの値(charでもbyteでも)の場合、その値をそのまま2進数としてパイプ出力する。 するとシリアルコンソール側は、そのデータをASCII文字として解釈しようとし、1、2、3に対応するASCII文字はそれぞれ「START OF HEADING」「START OF TEXT」「END OF TEXT」になる。 これでは特に役に立たないし、1文字で表示するのも難しい。だから四角い記号になるのである。シリアルコンソールは「これをどう表示すればいいかわからないので、代わりに四角を出しておきます」と言っているようなものである。 というわけで、Arduinoのデータ型に関する教訓その1:Serial.print()から8ビットの値を10進数表記で得るには、次のようにDEC指定をつけて呼び出す必要がある。

Serial.print(x, DEC);

最後に、「Elapsed time」(経過時間)の測定値に注目してほしい。 micros()関数を使って経過時間を測定していることによる誤差は、これから行うすべてのテストで共通して生じるものなので、絶対的な測定値としては不正確でも、相対的な測定値としてはかなり良い比較ができるはずである。それを踏まえたうえで、8ビットの値2つを加算するには、プロセッサの時間がおよそ4マイクロ秒かかっていることがわかる。

データ型のテスト(加算)

ここからは、他のデータ型もいくつか試してみよう。 実際に手元で試している場合は、コードを次のように変更する。

#define test_type int

Arduinoボードにコードを書き込み、コンパイルサイズを確認しよう。intでは2488バイト、byteでは2458バイトだった。 差はそれほど大きくないが、確かに大きくなっている。 これも、8ビットを超える記憶容量を必要とするデータ型(intlongfloatなど)を使うと、加算を実現するためにコンパイラがより多くの機械語コードを生成する必要があるためである。プロセッサ自体には、そもそもより大きなデータをネイティブにサポートする能力がない。 シリアルコンソールを開くと、次のような結果が表示されるはずである。

次に気づくのは、今回は値が正しく表示されている点である。 これは、新しく導入したデータ型intがコンパイラによって正しく数値型として解釈され、Serial.print()もそれに応じて出力データを正しくフォーマットしているためである。 というわけで、Arduinoのデータ型に関する教訓その2:もし数値型のデータをそのままバイナリとして送りたい場合(コンソールで人間が見るためではなく、別のコンピュータ機器とデータをやり取りする手段として)は、Serial.write()関数を使うとよい。

続いて、「Elapsed time」を再び確認してみよう。 今度は12マイクロ秒になっている。およそ3倍の時間である。 これはまだかなり短いが、先ほど触れたとおり、このプロセッサが8ビットプロセッサであるために、int変数どうしの加算に必要な16ビットの演算を行うにはひと工夫必要になるからである。

次に進もう。今度はlong型を試してみる。 先ほどと同様にコードを変更し、intだった箇所を2か所ともlongに置き換える。 コードを書き込み、シリアルコンソールを開いて何が起こるか見てみよう。

シリアル出力の内容に入る前に、コンパイルサイズを振り返っておこう。 今回は2516バイトで、intより28バイト、byteより58バイト大きい。 まだかなり小さな差ではあるが、確かに差はあり、intbyteの代わりにlongで大量の計算を行えば、この差は積み重なっていくだろう。

さて、シリアル出力の結果に話を戻そう。 またしても経過時間が変化している。しかし今回は、12マイクロ秒から8マイクロ秒へと短くなっている。 これはどういうことだろうか。これがArduinoのデータ型に関する教訓その3である。自分が「起きているはず」と思っていることが、実際に起きていることとは限らない。 なぜこうなるのかは筆者にもはっきりとはわからない。コンパイラの最適化によるものかもしれないし、intのコードにはない、小さな値の加算を高速化する実行時の最適化が働いているのかもしれない。 いずれにせよ、「longintより速い」という結論をここから安易に導くのは早計である。乗算や除算を見ていくとわかるように、必ずしもそうとは限らないからである。

最後に、浮動小数点数の演算を見てみよう。 Arduinoにおける浮動小数点演算は厄介である。というのも、Arduinoには浮動小数点演算ユニット(小数点以下の桁数が任意の数値を扱う専用のプロセッサ部分を指す専門用語)が搭載されていないからである。 浮動小数点演算はまた、扱いにくい概念でもある。人間は小数点以下に任意の桁の0が続く数を難なく扱えるが、コンピュータはそうはいかない。 これが、初期のPentiumプロセッサの一部を悩ませた悪名高い「1が1でないバグ」の原因である。

先ほどと同様にコードを変更し、今度は該当する2か所をlongからfloatに置き換える。 コードを書き込み、コンパイルサイズを確認してみよう。3864バイトである。 浮動小数点数のデータ型を含めたことで、コンパイラは浮動小数点演算を処理するコードを含めざるを得なくなった。 これはかなり大きなコードのかたまりであり、サイズをかなり増加させていることがわかる。 データ型に関する教訓その4:本当にどうしても必要な場合を除いて、浮動小数点演算は使うべきではない。 たいていの場合、浮動小数点数が必要になるのは、任意の整数値のままではあまり意味をなさない情報をユーザーに提示するときに限られる。たとえば、ADCが返す536という値は意味がわかりにくいが、これを浮動小数点数に変換して2.62Vとすれば、はるかに役立つ情報になる。

このコードの実行時間を見ると、12マイクロ秒に戻っている。 また、表示される値には小数点以下2桁の0が含まれるようになった点にも注目してほしい。 小数点以下の桁数を増やしたい(あるいは減らしたい)場合は、print命令に桁数を指定できる。

Serial.print(x, 3); // 変数xの浮動小数点数を小数点以下3桁まで表示する

データ型のテスト(乗算・除算)

ここからは、もう少し「重い」計算、つまり乗算と除算で何が起こるかを見ていこう。

まずは乗算のスクリーンショットである。

経過時間を確認してみよう。byteで4µs、intまたはlongで8µs、floatで12µsである。 データ型が大きくなるほど時間がかかっており、「重い」計算ほど時間がかかるという予想どおりの結果になっている。 とはいえ、乗算はまだハードウェアでサポートされている。プロセッサにはネイティブの乗算命令があり、乗算そのものは比較的容易に行える。 では、除算はどうだろうか。

なんということだろう。byteの除算は16µsとそれほど悪くないが、longでは48µsにもなる。 この原因は、Atmegaの命令セットには除算のネイティブ命令が存在しないため、コンパイラが四苦八苦して除算を組み立てる必要があるからである。 というわけで、最後の教訓である。すべての数学演算が同じように作られているわけではない。 除算は乗算や加算(減算も、実質的にはマイナス符号をつけた加算にすぎない)よりもはるかに時間がかかり、平方根や正弦のような計算はさらに時間がかかる。 実際、非常に時間がかかるため、平方根や正弦・余弦・正接の値をその場で計算するよりも、あらかじめ値の一覧を用意しておいて必要な値を参照するほうが簡単なことも多い。

まとめ

ひとまずここまでにしておく。 変数に適したデータ型を使うことの利点を、はっきりと示せていたらうれしい。 次のチュートリアルでは、データ型を混在させたり、不適切なデータ型(扱う可能性のある最大の数値に対して小さすぎるデータ型など)を使ったりすることで潜んでいる、本当に厄介な落とし穴のいくつかを扱う予定である。

データ型についての新しい知識を踏まえて、さらに学びたい場合は次のチュートリアルも参考にしてほしい。

タグ: Arduino、コンピュータ工学、概念、プログラミング


出典:Data Types in Arduino(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

PATH環境変数の設定

はじめに

パスとは、ファイルシステム上の特定の場所を示す、ファイルのディレクトリ名のことである。 一方、PATH環境変数)($PATH)は、実行可能なプログラムが置かれているディレクトリの集合を指定する変数である。 これによって、ソフトウェアはよく使われるプログラムに、いちいちフルパスを指定しなくてもアクセスできるようになる。

PATH$付き)変数を変更する方法は、OSによって異なる。 以下の手順は、それぞれのOSでもっとも一般的な方法に基づいている。 より詳しい情報が必要な場合は、お好みの検索エンジンで「path system variable」と「使用しているOSの名前」を組み合わせて検索してみてほしい。

Windows 10の場合

Windows 10では、PATH環境変数はシステムのプロパティウィンドウから設定する。 このウィンドウを開く方法はいくつかあるが、たとえばタスクバーの⊞ スタートメニューから「システムの詳細設定の表示」を検索する方法がある。

タスクバーの⊞ スタートメニューから「システムの詳細設定」を検索し、システムのプロパティウィンドウを開く。(クリックで拡大)

システムのプロパティウィンドウが開いたら、詳細設定タブから環境変数…ボタンを選択する。

環境変数ウィンドウを開く。(クリックで拡大)

環境変数ウィンドウの中で、**ユーザー環境変数(ユーザー名)**の欄からPath変数を選び、編集…ボタンを選択してPATH環境変数を設定する。

Note

注:ユーザー環境変数は、そのコンピュータの特定のユーザーアカウントに限定される変数である。一方、システム環境変数は、そのコンピュータのすべてのアカウントで利用できる。

PATH環境変数の編集ウィンドウを開く。(クリックで拡大)

PATH環境変数の編集ウィンドウから、参照…ボタンを選択する。 ポップアップダイアログが表示されたら、PATH環境変数に追加したい実行ファイルが入っているフォルダに移動する。

Note

注:以前に設定したファイルパスを選択して上書きしないよう注意すること。何もない黒い領域をクリックすれば、既存のファイルパスが選択された状態になっておらず、誤って上書きされる心配がないことを確認できる。

PATH環境変数にディレクトリを追加する。(クリックで拡大)

Mac OSXおよびLinux系OSの場合

Mac OSXやLinux系OSでは、ターミナルにecho $PATHと入力することで、$PATH環境変数に設定されているパスを表示できる。

Note

注:以下のコマンドではGNU nanoテキストエディタを使用している。好みの別のテキストエディタ(Vim)のviなど)を使ってもかまわない。

変数を変更する手順は次のとおりである。

  1. ターミナルを開き、次のコマンドを実行してパスの設定ファイルを編集する:sudo nano <ファイルパスの場所>
    • $PATH環境変数を変更できる場所としては、次のようなものがある。
      • /etc/paths(Mac OSX - Mountain Lion)
      • /usr/bin
      • /usr/local/bin
      • /usr/local/sbin
      • /usr/sbin
      • ~/.bash_profile
      • ~/.bashrc
      • ~/.profile
  2. 管理者パスワードの入力を求められたら入力する。
  3. 追加したいパスの記述を入力する。
    • 入力欄は、たいていファイルの末尾付近にある。
  4. Ctrl+Xを押して終了する。
  5. 入力を促されたらYを入力し、Enter(またはReturn)を押して変更内容を保存する。

$PATH変数のパスを表示し、~/.profileファイルを開いて変更する様子。(クリックで拡大)

これで完了である。変更が反映されたかを確認するには、ターミナルでecho $PATHと入力する。

Note

注:もう一つよく使われる方法として、ターミナルでexportコマンドを使う方法がある。

例:export PATH=$PATH:<追加したいファイルパス>

まとめ

プログラミング関連のチュートリアルをさらに探しているなら、次のガイドも参考にしてほしい(いずれも英語)。

タグ: 概念、プログラミング


出典:Configuring the PATH System Variable(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

アルゴリズムに学ぶ

はじめに

今年の初め、SparkFunの創業者であるNathan Seidleは、Crowdsourcing Algorithms Challenge(通称「スピードバッグ・チャレンジ」)を企画した。 数多くの見事な応募作の中から、1つが選ばれた。 優勝したBarry Hanniganには、この問題を解いた過程を記事にまとめてもらうよう依頼した。 以下は、Barry Hanniganが実際に優勝した手法をもとに、たとえ問題が目の前に具体的な形で存在していなくても、現実の課題をどう解いていくかを語った記事である。

ファームウェアの参考資料

Barryのコードは、以下のリンクから確認できる。

Barry’s Speed Bag Challenge GitHub Repo


Nateのスピードバッグ・チャレンジの優勝者として、筆者はコロラド州ボルダーにあるSparkFunの本社でNateと直接会うという、素晴らしい機会を得た。 その際の話し合いの中で、非常に短い時間で複雑な問題を解決する方法を説明するチュートリアルを作るのはよい考えだ、ということになった。 このプロジェクトに固有の詳細にも触れるが、ここで語る思考プロセスを、読者の今後のプロジェクト(大きなものでも小さなものでも)に応用してもらえればと願っている。

どこから始めるか

エンジニアの視点から見ると、本格的なソフトウェアプロジェクトには4つの主要な段階がある。

  • 要件定義
  • 設計
  • 実装
  • テスト

正直なところ、誰もが面白いと感じ、創造性を発揮でき、いちばん楽しめるのは設計とコーディングの部分である。 自然な流れとして、解こうとしている問題のある一面に固執し、いきなり設計とコーディングに飛び込みたくなる。 しかし筆者は、最初と最後の段階こそが、プロジェクトの規模を問わず、成功のためにもっとも重要になりうると主張したい。 疑うなら、次のことを考えてみてほしい。筆者のスピードバッグ問題への解法は恐ろしく速く設計できたが、テストに使う実物のバッグは手元になかった。 それでも最終的に正しい修正を加え、機能テストを行って正しい結果を出せることを確かめた。 逆に、美しい設計と洗練された実装であっても、求められる機能を満たさなければ、それは間違いなく失敗作とみなされる。

段階の一覧にプロトタイピングを挙げなかったのは、プロジェクトによってそれが異なる段階で、あるいは複数の段階にまたがって発生しうるからである。 たとえば、問題そのものが十分に理解されていない場合、プロトタイプは要件を明らかにする助けになったり、コンセプトを実証したり、新しい技術の使用を検証したりする役目を果たす。 重要ではあるが、プロトタイピングは実のところ、1つあるいは複数の段階の中で行われる活動にすぎない。

スピードバッグ・チャレンジの話に戻ろう。今回はごく小さなプロジェクトではあるが、それでも4つの領域それぞれに少しずつ時間をかけることを勧める。そうしなければ、何か重要なことを見落とす可能性が高くなる。 何が求められているかを十分に理解するために、まずは手元にあった入力情報をすべて確認してみよう。 チャレンジのWeb記事には5つの明示的な要件が挙げられており、こちらで確認できる。 続いて、記録データのフォーマットとスピードバッグ装置の仕組みについてのごく簡単な説明が載った、Nateのgithubリポジトリへのリンクがあった。

このケースでは、Nateが最初に作ったスピードバッグのカウンター実装は、追加の要件を明らかにするためのプロトタイプだったと位置づけられる。 Nateがシステムをどう構築したかの記述から、スピードバッグの土台に加速度センサーを取り付け、およそ2msごとに得られる振動のサンプルをパンチのカウントに使っていたことがわかる。 また、多項式による平滑化を施してしきい値を超えるピークを探すという方法では、パンチを正確に検出できないこともわかった。

小さなプロジェクトにあまり形式張った進め方をしたくはなかったが、それでも次のような目標(要件)を意識しながら問題に取り組んだ。

  • アルゴリズムは、記録されたデータセットから正しいヒット数を算出できなければならない
  • 解法は8ビットおよび32ビットのマイコン上で動作しなければならない
  • ドキュメントを作成し、他の人がこの解法から学べるようにする
  • コードとドキュメントは公開リポジトリまたはWebサイトに置く
  • 未知(Mystery)のデータセットについて、パンチ数と導き出した解法を公開する
  • 加速度センサーはスピードバッグの土台の上部に取り付けられており、向きは不明。ただし+Zが上、-Zが下であることはわかっている
  • 複雑なデータパターンには多項式フィルタだけでは足りず、入力される振幅の変動に合わせて調整する必要がある。Nateが推測しているとおり、共振が原因である可能性が高い
  • 完成までに与えられた時間は15日間(大変だ!)

解法を作る

どんなプロジェクトでもそうだが、何をすべきかがわかったところで、時間が足りないという現実に直面することになる。 実物のハードウェアがなく、アルゴリズムの出力を視覚的に確認できる手段が必要だったので、まずはPC上のJavaで手早く実装を始めることにした。 波形の結果を画面上にプロットできる仕組みを組み込んだ。 筆者は長年NetBeansを使ってJava開発を行ってきたので、今回も新しいスピードバッグプロジェクトを立ち上げた。 データのプロットにはいつもJFreeChartライブラリを使っており、今回もプロジェクトに追加した。 NetBeansは非常に優れたIDEで、GUIデザイナーも内蔵している。 JFreeChartを表示したい場所に空のパネルを配置したGUIレイアウトを作り、実行時にJFreeChartオブジェクトを生成してそのパネルに追加するだけでよかった。 この記事に登場するオシロスコープ風の図は、すべてこのJFreeChartの表示によって作成したものである。 以下は、急いで作った簡易オシロスコープのGUI設計画面である。

このアルゴリズムは急いで作る必要があったため、最初の実装ではオブジェクト指向を徹底し、Javaが提供するあらゆる近道を活用することにした。 その後、アルゴリズムの流れを固めていく過程で、より C 言語らしい形に近づけていくつもりだった。 早速、記録済みの結果から得られるX、Y、Z軸の波形をそのままプロットしてみた。 生データを確認したところ、まずバイアス(すなわち重力)を取り除き、それぞれの波形の2乗の和を求めてから平方根を取ることにした。 少数の値を平均する平滑化を加え、しきい値を超える回数を数える際にも、スパイクを除去するための最小時間間隔を設けた。 全体としては、これによってプロットのデータはむしろ悪化したように見えた。 どの向きで取り付けられているかわからず、また異なるスピードバッグの台に取り付けたときに同じ向きになるとも限らないため、XとYは捨てることにした。 ところが恐ろしいことに、Z軸だけにしても、依然としてノイズの塊にしか見えなかった。 ピークどうしの間隔が近すぎるのである。 しきい値検出の間の最小時間というゲートだけが、かろうじてパンチ数の辻褄を合わせてくれているだけで、データそのものには確かなものが何もなかった。 何かがおかしい。何を見落としているのだろうか。

以下はrunF1波形の画像である。 青い信号がフィルタ済みのZ軸、赤い線がパンチをカウントするためのしきい値である。 先ほど触れたとおり、パンチ検出の間の250ms最小間隔がなければ、カウンタは暴走してしまっていただろう。 runF1()の処理には5ミリ秒の遅延を2か所導入しており、赤い線を10ミリ秒右にずらせば、しきい値判定はもう少しうまくいくはずである。 信号の時間軸を揃えることについては本記事の後半でさらに触れるが、この画像からも、時間軸を揃えることが正確な結果を得るうえでいかに重要かがわかる。

青い信号がフィルタ済みのZ軸、赤い線がパンチをカウントするためのしきい値である。

仮想オシロスコープの出力を見ると、25,000ミリ秒から26,000ミリ秒の間、つまりわずか1秒の間に、9回ほどの明確な加速度イベントが確認できる。 Nateが1秒間に9発もパンチを繰り出しているはずがない。 そもそも、1秒間に何発のパンチが妥当なのだろうか。 振り出しに戻り、別のアプローチが必要だと悟った。 謙虚さは何よりの味方である。調子に乗って突き進めば、たいていすぐに手痛いしっぺ返しを食らうことになる。

対象領域を理解する

たいてい、要件は解こうとしている問題の領域(ドメイン)を踏まえて策定されるか、あるいはドメイン知識を踏まえた要件から設計上の判断が導かれる。 筆者はボクシングのスピードバッグについて何も知らなかったので、まずはGoogle検索から始めることにした。

そこで見つけた重要な事実は、ボクサーがスピードバッグを打つと、土台に3回接触するということだった。まず前方(パンチの方向)に向かい、それから完全に元の位置(パンチと反対方向)まで戻って土台に当たり、再び前方へ完全に戻って土台に当たる。 そして、バッグがボクサーの方へ戻ってくるところをもう一度打つ。 つまり、土台に動きを生じさせる機会は実質4回ある。ボクサーがバッグに当たった衝撃が1回、そして土台との接触が3回である。

これで、波形に現れていたものの意味がようやく理解できた。 1回のパンチにつき1回だけバッグが土台に当たる衝撃が生じるわけではなかったのである。 次に考えたのは、ボクサーが1秒間に何発スピードバッグを打てるかということだった。 いろいろ調べてみたが、この問いへの明確な答えは見つからなかった。 シャドーボクシングの最大パンチ数や、実際のパンチの最大数を扱うサイトはたくさん見つかったが、スピードバッグに関する最大値は見つからなかった。 自分なりの結論を導き出すしかなかった。1回のパンチでスピードバッグがどれだけの距離を移動する必要があるかを考え、土台に3回接触するだけの距離を移動させるには最低限の力が必要なはずだと考えた。 ボクサーではないので、できるだけゆっくりとバッグを打ち、それでも3回接触するところを頭の中でイメージするしかなかった。 頭の中の映像から判断するに、1秒間に2回未満の頻度でバッグを打つのは難しそうだった。 これが最小値だとして、では最大値はどうだろうか。 再び頭の中で映像を思い描き、今度は拳を動かして想像上のバッグを打ってみた。 バッグが移動しなければならない距離と、拳をバッグの軌道に出し入れするのにかかる時間を考えると、熟練したボクサーであっても、1秒間に4回程度が限界だろうという結論に達した。 これで決まりである。データの中から、2Hzから4Hzの間で起きているイベントを見つければよい。 再びコーディングと開発に戻る時間である。

少し作り、少し試し、多くを学ぶ

人によって考え方は少しずつ違うものだが、特にはっきりと定まった方法論を持たずに問題に取り組む場合は、反復的な戦略を試すことを勧める。 また、アルゴリズムに大きな変更を加える準備ができたと感じたら、変更を始める前にそのアルゴリズムのコピーを作るか、あるいは空の関数から始めて前の反復の断片を少しずつ取り込んでいくとよい。 バージョン管理を使って前の反復を保存することもできるが、筆者はコードの中に前の反復(複数のこともある)を残しておくほうを好む。次の反復に取り組む際に簡単に参照できるからである。 たいてい、10行か20行以上コードを書く前には、少なくともコンパイルが通ることを確認するようにしているが、本当にやりたいのは実際に実行し、何かを出力させて、自分のロジックと前提が正しいことを確かめることである。 これはキャリアを通じてずっとやってきたことであり、実際にコーディング中のものを動かせる対象ハードウェアが手元にないと、たいてい不満を漏らすことになる。 2006年ごろ、ある元海軍少将のこんな言葉を耳にした。

少し作り、少し試し、多くを学べ。

―Wayne Meyers、米海軍少将

この言葉には強く共感する。書いているものを常に動かし、試したいと思う理由を的確に言い表しているからである。 これによって、自分の前提が正しいことを確認できるか、あるいは間違った方向に進んでいることに気づき、多くの作業を無駄にすることなく素早く正しい道に戻ることができる。 これもまた、実物のスピードバッグのハードウェアがない状態でも、素早くコードを実行・テストし、しかも視覚的にグラフ化できるJavaをプロトタイピングのプラットフォームに選んだ理由の一つである。

さらに、6つのrunFx()関数すべての中に、現在時刻をミリ秒単位で追跡し、タイムスタンプの差が経過したかどうかを確認して、経過していなければ1ミリ秒だけスリープするというコードが組み込まれている。 これによって、Javaのプロット画面上でデータが流れていく様子を見ながら、フィルタの出力がどうなっているかを確認できた。 X、Y、Z軸の加速度データに加えて、X、Y、Zそれぞれの平均値も渡すようにしていた。 たいていのアルゴリズムではZ軸のデータしか使わなかったため、途中からはズルをして別の値をプロット対象として渡すようになり、1から5までのグラフを見ると、凡例と一致しない箇所があって少しわかりにくくなっている。 とはいえ、リアルタイムでプロットすることで、データを見ながらヒットカウンタが増えていく様子を確認できた。 パンチのリズムがどう定まっていくか、そして一定のリズムが続くことで生じる共振が加速度データにどう影響するかを、実際に目で見て、体感することができた。 JavaのSystem.out.println()関数による視覚的な出力に加えて、NetBeans IDEのウィンドウにもデータを出力できた。

GitHubリポジトリのJavaサブディレクトリを見ると、MainLoop.javaというファイルがある。 このファイルには、run1()からrun6()という名前の関数がいくつか含まれている。 これらは、スピードバッグアルゴリズムのコードにおける6つの主要な反復である。

それぞれの反復のポイントを紹介する。

runF1

runF1()はZ軸のみを使い、スライディングウィンドウによる弱いバイアス除去と、フィルタ済みZデータの固定の増幅を行った。 入力データを遅延させる「delay」という要素を作り、平均結果の出力と後で時間軸を揃えられるようにした。 これにより、スライディングウィンドウの平均を、以前の値ではなく周囲の値に基づいてZ軸データから差し引くことができた。 パンチの検出には、増幅済みのフィルタデータが5サンプルの平均を上回るかどうかを単純に比較する方法を使い、検出の間隔は最低250ミリ秒とした。

runF2

runF2()もZ軸のみを使い、スライディングウィンドウによる弱いバイアス除去を行ったが、直前のパンチ検出時に除去されたバイアスを超える平均振幅に基づいて、フィルタ済みZデータに動的なベータ増幅を加えた。 また、直前のパンチが検出されてからの経過時間に基づいて、225msから270msの間で動的に変化するパンチ間の最小時間も計算した。 除去したバイアスの量を「ノイズフロア」と呼ぶことにした。 シミュレーションを一時停止・再開できるボタンも追加し、デバッグ出力や波形を確認できるようにした。 これにより、シミュレーションの進行に伴ってベータ増幅がどう使われているかを確認できた。

runF3

runF3()はXとZ軸のデータを使った。 パンチの動作による衝撃がZ軸のデータに加算的に作用し、実際のパンチの位置を特定する助けになるのではないか、という仮説を立てたのである。 基本的にはRunF2と同じアルゴリズムに、X軸を追加しただけのものである。 実際にこれはかなりうまく機能し、X軸の動きとZ軸を相関させることで何かが見えてきたのではないかと感じた。 コード中のコメントアウトされた多数の実験からもわかるとおり、さまざまな調整や工夫を試した。 「コンプレッサー」と呼んでいるものも試し始めた。5サンプルの合計を取ることで、パンチが起きるタイミングの周辺にエネルギーの塊が検出できないか調べるものである。 これはアルゴリズムには使わなかったが、しきい値を超えた回数を出力し、フィルタの要素として使える可能性があるか確認した。 最終的には、このアルゴリズムは自壊し始め、ここで学んだことを持って新しいアルゴリズムに取り掛かる時期だと判断した。

runF4

runF4()では、バイアス除去の平均を50サンプルに増やした。 減衰とサンプル圧縮に加え、整数の減衰済みデータに小数の精度をいくらか保持するための固定小数点LSBを導入し始めた。 要件の一つに8ビットマイコンで動作させる必要があるという条件があったため、最終的なC/C++コードでは浮動小数点や時間のかかる数学関数の使用を避けたいと考えていた。 これについてはコンポーネントの節で詳しく述べるが、ここではその方向性に着手し始めていたことだけ触れておく。 加速度のバーストを見つけるという方向性が正しいと確信するようになった。 この時点で、ZとX両方の軸からバイアスを除去し、それぞれを2乗している。 それぞれを減衰させて足し合わせるが、X軸の値には10倍のスケールをかけている。 加速度のバーストを平滑化するため、フィルタ済みの11個の値を平均する2段目のステージも追加した。 次に、平滑化された値が固定しきい値の100を超えると、平滑化前のZとXの2乗の組み合わせをコンプレッサーに読み込み始め、100サンプルに達するまで続ける。 コンプレッサーの出力(100サンプル分)が5000を超えると、それがヒットとして記録される。 パンチ間の可変時間ゲートも導入したが、コンプレッサーが100サンプルを使ってパンチ検出をひとまとめにしているため、ゲートの時間ははるかに短く、125msから275msの間になった。 ある程度の見込みは見えたものの、まだ敏感すぎた。 あるデータセットではぴったり合うのに、別のデータセットでは10発以上もずれてしまうこともあった。 多くの調整と実験を重ねた末、このアルゴリズムもまた自壊し始め、再び学んだことを持って一からやり直す時期になった。 この頃には、この問題に満足のいく解がそもそも存在しないのではないかと考え始めていたことも触れておくべきだろう。 バッグの接触とは位相がずれているように見える共振振動が、ボクサーが良いリズムに乗ったときに観測される加速度に、ことごとく悪影響を及ぼしているように思えた。 これはすべて時間の無駄なのではないか、とすら思えた。

runF5

runF5()のアルゴリズムは、信号から平均を差し引くのではなく、もっと本格的なハイパスフィルタを導入する必要があるという発想から始まった。 このハイパスフィルタの基本原理は、新しく入力されたサンプルの値の99%と、平均の値の1%を合成するというものである。 runF5の進化の終盤に加えた重要な考え方の一つが、最初の処理段階を独立したファイルに切り出し、後段の処理から分離することでアルゴリズムを単純化するというものだった。 分割統治は昔からある手法だが、何度試してもやはり有効である。 アルゴリズムの中やFrontEndProcessorOld.javaファイルにある多数のコメントアウトされた行からもわかるとおり、さまざまな実験を試した。 最終的には、この新しいフロントエンドプロセッサという考え方を持ち越し、分割統治とより本格的なハイパスフィルタという方針で新たに始める時期になった。

runF6

時間が残り少なくなる中、ここまで学んだことをすべて統合し、JavaコードをC/C++に移植する準備を整え、移動平均ではなく本物のフィルタを実装する時期になった。 runF6()では、フロントエンドでハイパスフィルタを使ってバイアスを除去し、残った信号にローパスフィルタをかけて2Hzから4Hzの周波数で発生する加速度のバーストを見つける、という理論をまとめ上げていた。 締め切りまでの残り時間で、ハイパスフィルタとローパスフィルタを実装するためのフィルタタップの値を自力で計算する方法を学んでいる余裕はとてもなかった。 幸運にも、t-filterのWebサイトを見つけた。 これは一石三鳥どころではなかった。パラメータを入力するだけでフィルタタップの値が得られただけでなく、生成されたCコードをわずかな調整でJavaコードに活用することもできた。 さらに、タップの値を固定小数点に変換までしてくれた。 分割統治の考え方を全面的に取り入れ、この最終版のアルゴリズムでは、フロントエンドプロセッサと検出処理をそれぞれ独立したサブアルゴリズムとして導入した。 これにより、2つの機能を互いに分離できた。一方の出力信号がもう一方の入力になるという関係だけを残し、両方の段階で共有される可能性のある大量の変数をふるいにかける必要もなく、目の前の作業に集中しやすくなった。

このように役割を分担したことで、フロントエンドプロセッサの役割は、バイアス値を除去し、検出プロセッサへの入力として扱いやすいレベルの出力を作ることに明確に絞り込めるようになった。 そして検出プロセッサは、フィルタリングと、1秒間に2回から4回の間で起こるはずのパンチイベントを検出するステートマシンの実装に、はっきりと集中できるようになった。

一つ触れておきたいのは、この最終版のアルゴリズムは、それ以前のアルゴリズムのいくつかよりもずっと小さく、単純だという点である。 ソフトウェアであっても、開発のどこかの段階でマンツィングと呼ばれる手法を行うべきである。 マンツィングとは、機能を壊さない範囲で何を取り除けるかを見直す手法である。 取り除いたコードの1行は、バグを含みうるコードの1行が減ることを意味する。 マンツィングの精神をより深く理解したければ、Earl「Madman」Muntzを調べてみるとよい。

DETの最終出力。

上の図は、runF6の視覚的な出力である。 緑の線はローパスフィルタの出力を45サンプル遅延させたもの、黄色の線はローパスフィルタの出力の99個の値の平均である。 検出プロセッサには、緑の信号が最小値・最大値を横切るタイミングを、黄色の信号を動的なしきい値のテンプレートとして使いながら追跡することでパンチを検出するアルゴリズムが組み込まれている。 それぞれの最小値は赤いスパイク、最大値は青いスパイクとして表示されており、青いスパイクがパンチの検出にあたる。 時間軸の単位はミリ秒である。 予測どおり2〜4Hzの範囲に収まる形で、1秒あたりおよそ3回の青いスパイクが現れていることに注目してほしい。 そして、その後の展開はご存じのとおりである。

アルゴリズムを構成する要素

ここでは、さまざまなアルゴリズムで使った各要素について簡単に紹介する。

ディレイ(遅延)

これは、信号をバッファリングして、他の何らかの処理と時間軸を揃えるために使う。 たとえば、9サンプルの平均を取り、その平均を元の信号から差し引きたい場合、元の信号を5サンプル遅延させておけば、その値自体と、前後4サンプルずつを使って計算できる。

アッテニュエート(減衰)

減衰は単純だが有用な処理であり、フィルタリングなどでゲインを加える前に、信号のスケールを下げておくために使う。 減衰はたいていデシベル(dB)で測られる。用途に応じて、電力を減衰させることも、振幅を減衰させることもできる。 振幅を半分にすると、-6dBの減衰になる。 他のdB値で減衰させたい場合は、dBスケールの一覧を参照してほしい。 スピードバッグのアルゴリズムに関して言えば、これは基本的に信号にはっきりとしたギャップを作るために使った。小さい値をゼロに近づけて押しつぶすことで、後で2乗したときにピークをより高く押し上げつつ、ゼロに近い値への影響は小さく抑えられる。 この手法を使って、スピードバッグの台の背景振動に対して、加速度のバーストを際立たせるようにした。

スライディングウィンドウ平均

スライディングウィンドウ平均は、入力される信号について、あるサンプル数の窓(ウィンドウ)にわたる連続的な平均を計算する手法である。 平均を取るサンプル数のことをウィンドウサイズと呼ぶ。 筆者が好んで実装する方法は、サンプルの合計値を保持しながら、値を追跡するリングバッファを使うというものである。 リングバッファが満杯になったら、もっとも古い値を取り除いて次に入ってきた値に置き換え、リングバッファから取り除いた値を新しい値から差し引く。 その結果を合計値に加える。 必要なときはいつでも、その合計値をウィンドウサイズで割れば現在の平均が得られる。

レクティファイ(整流)

これは非常に単純な考え方で、値の符号をすべて正、あるいはすべて負にそろえて、足し合わせられるようにするものである。 ここでは、すべての値を正にするために整流を使った。 整流には、他の整流と同様、全波整流と半波整流の方法がある。 全波整流は、値を正の値として返すabs()という数学関数を使えば簡単に行える。 値を2乗して正にすることもできるが、その場合は振幅そのものが変わってしまう。 単純な整流であれば、他の影響を与えずに値を正にできる。 半波整流を行うには、0未満の値をすべて0に設定すればよい。

コンプレッション(圧縮)

DSPの世界では、圧縮とはたいてい、振幅を近い範囲に収めることを指す。 ここでの圧縮の手法は、あるウィンドウ内のサンプルの値を合計するというものである。 ウィンドウが満たされるたびに1個のサンプルしか出力されないという意味では一種のダウンサンプリングだが、値そのものは何も捨てていない。 純粋にウィンドウ内の合計値であり、あるいはウィンドウの平均値として使うこともできる。 これは、静かな時間帯から加速度のバーストを見分けようとする目的で、いくつかのアルゴリズムに取り入れた。 実際には、最終版のアルゴリズムでは使わなかった。

FIRフィルタ

有限インパルス応答(FIR)フィルタは、それぞれに割り当てられた多項式係数を持つ、いくつかのタップによって実装されるデジタルフィルタである。 タップの数はフィルタの次数と呼ばれる。 FIRの強みの一つは、フィードバックをまったく使わないため、丸め誤差が累積せず、時間とともに大きくなっていかないという点である。 有限インパルス応答とは、単純に言えば、1の後にすべて0が続くサンプル列を入力すると、フィルタの出力は、多くとも次数+1個分の0値サンプルが入力されるまでの間にゼロに落ち着くということである。 つまり、1という単一のサンプルへの応答は、有限個のサンプルの間だけ存在し、その後は消えてなくなる。 これは基本的に、フィードバックを一切使っていないという性質によって実現されている。 DSPの記事の中には、フィルタのタップ数や係数の計算は簡単だと主張するものもあるが、筆者にとっては簡単ではなかった。 最終的に、tFilterというオンラインアプリを見つけ、多くの時間と苦労を省くことができた。 フィルタの種類(ローパス、ハイパス、バンドパス、バンドストップなど)を選び、入力データの周波数範囲とサンプリング周波数を設定するだけでよい。 浮動小数点演算を避けるため、係数を固定小数点で生成させることもできる。 固定小数点の使い方がわからない、あるいは聞いたことがないという場合は、後の「組み込み向け最適化テクニック」の節で説明する。

組み込み向け最適化テクニック

二乗振幅(Mag Square)

Mag Squareは、平方根の計算にかかる処理コストを省くための手法である。 たとえば、XとZ軸のベクトルを計算したい場合、通常は次のように計算する。val = sqr((X * X) + (Y * Y)) しかし、正確なベクトルの値がどうしても必要な場合を除けば、単純に(X * X) + (Y * Y)の値のままにしておいてもよい。Mag Squareは、後続のサンプルで計算される他のベクトルと比較するのに使える比率を与えてくれる。 数値はかなり大きくなるので、下流の計算でオーバーフローしないよう、減衰によって値を小さくしたくなるかもしれない。

最終的なアルゴリズムでは、背景振動から加速度のバーストを際立たせるためにこの手法を使った。 計算にはZ * Zのみを使ったが、その後すべての値を半分(-6dB)に減衰させ、後続の処理に適した妥当な水準まで下げた。 たとえば、バイアスを除去した後にいくつかの値が2前後、いくつかの値が10前後だったとすると、それぞれを2乗すると4と100になり、25対1の比率になる。 ここで0.5倍に減衰させると2と50になり、比率は25対1のままだが、扱う数値は小さくなる。

固定小数点

固定小数点数を使うことも、特にマイクロコントローラ上で性能を引き出すもう一つの方法である。 固定小数点は基本的には整数演算だが、すべての整数のある特定のビット位置に暗黙の小数点があるものとして扱うことで、精度を保つことができる。 FIRフィルタの場合、tFilterに16ビットの固定小数点値で多項式の値を生成するよう指示した。 これは、32ビットを超える整数を使わないようにするためであり、特に8ビットマイコンでの性能低下を避けたかったからである。

FIRフィルタのコードに立ち入って固定小数点の仕組みを説明する前に、まずは単純な例を使ってみよう。 FIRフィルタのアルゴリズムは多数の多項式を使った複雑なフィルタリングを行うが、ここでは同じ入力信号を、振幅を半分(-6dB)にして出力するだけの単純なフィルタを実装するとしよう。 浮動小数点の世界であれば、これは入力される各サンプルに0.5を掛けるだけの、タップ1個の単純なフィルタになる。 これを16ビットの精度の固定小数点で行うには、0.5を16ビットの固定小数点表現に変換する必要がある。 1.0という値は、1 × (2^16)、つまり65,536で表される。 65536より小さい値は、すべて1未満の値になる。 0.5の固定小数点整数を作るには、同じ式を使って0.5 × (2^16)を計算すればよく、これは32,768になる。 これで、この値を使って入力される各サンプルの振幅を0.5倍に下げることができる。 たとえば、この単純なフィルタに値10のサンプルを入力するとしよう。 フィルタは10 × 32768 = 327,680を計算し、これが固定小数点表現になる。 計算後に精度を保持する必要がなければ、使用している精度のビット数だけ右シフトするだけで、簡単に固定小数点でない整数に戻せる。 つまり、327680 >> 16 = 5である。 このように、フィルタは10を5に変えており、これはもちろん求めていた半分(-6dB)の結果である。 0.5はかなり単純な例だったが、振幅を1/8にしたい場合も同じ手順で、65536 × .125 = 8192となる。 値16のサンプルを入力すると、16 × 8192 = 131072となり、これを整数に戻すと131072 >> 16 = 2になる。 整数に戻す際に精度が失われる様子(浮動小数点数を整数に変換するのと同じ現象)を示すために、この1/8のフィルタに10を入力してみると、10 × 8192 = 81920となり、これを整数に戻すと81920 >> 16 = 1になる。固定小数点表現では実際には1.25だったことに注目してほしい。

FIRフィルタの話に戻ると、16ビットの精度を選んだのは、十分な精度を確保しつつ、扱える整数の範囲とのバランスを取るためである。 通常、符号付き32ビット整数は-2,147,483,648から+2,147,483,647までの範囲を扱えるが、整数部分に使えるビット数が16ビットに制限されると、範囲は-32,768から+32,767になる。 扱える数値の範囲が限られるため、入力される値には注意を払う必要がある。 FEPFilter_get関数を見ると、各タップの値を合計するaccZというアキュムレータ変数があるのがわかる。 通常、タップの履歴値が32ビットであれば、すべてのタップ値の合計を確実に保持できるよう、アキュムレータは64ビットにする。 しかし、入力値がある最大値より必ず小さいことを保証できれば、32ビットの値でも構わない。 最大入力値を計算する一つの方法は、係数の絶対値の合計を、固定小数点方式で扱える整数部分の最大値で割ることである。 FEPのFIRフィルタの場合、係数の合計は131646だったので、正の整数部分に15ビット、小数部分に16ビットを割り当てられるとすると、(2^31)/131646という式から、FEPの最大入力値は±16,312と求められる。 このケースでは、マイクロコントローラに64ビット演算をさせないという、もう一つの最適化も実現できたことになる。

信号処理のチェーンをたどる

フィルタリングによる遅延

処理チェーンをたどる前に、フィルタリングによって生じる遅延について触れておくべきだろう。 多くの種類のフィルタリングは、処理される信号に遅延を加える。 フィルタリングの経験が豊富であれば、この事実はよく知っているだろうが、信号のフィルタリングにあまり慣れていない場合は、意識しておくべきことである。 遅延とは何を意味するのだろうか。 これは単純に、値Xを入力し、値Yが出力されるとき、Xの影響がもっとも大きく現れるまでにYに届く時間、それが遅延であるということである。 FIRフィルタの場合、フィルタのインパルス応答をプロットすれば簡単に確認できる。FIRフィルタの説明を思い出してほしいが、これは0の連なりの中に1つだけ1が挿入された信号である。 T-Filterはこのインパルス応答を表示してくれるので、XがYの出力にどう影響するかを確認できる。 以下は、T-FilterのWebサイトから取得した、FEPのハイパスフィルタのインパルス応答の画像である。 Xへの影響がもっとも大きいのは、画像のちょうど中央にあり、フィルタの各タップに対応する点があることに注目してほしい。

以下は、FEPのハイパスフィルタのいくつかの信号を示した図である。 赤い信号は加速度センサーからの入力、つまりフィルタに入る最新のサンプルであり、青い信号はフィルタのリングバッファの中でもっとも古いサンプルである。 このFIRフィルタには19個のタップがあるため、これはフィルタのウィンドウにおける最初と最後のサンプルのプロットにあたる。 緑の信号は、ハイパスフィルタから出てくる値である。 先ほどのXとYの例に当てはめると、赤い信号がX、緑の信号がYにあたる。 青い信号は、赤い入力信号に対して36ミリ秒遅延している。これはちょうど2ミリ秒間隔の18サンプル分にあたり、これがフィルタが処理対象とするデータのウィンドウ、つまりXがYに影響を与える有限の時間である。

ハイパスフィルタの出力(緑の信号)は、入力の変化を18ミリ秒(2ミリ秒間隔の9サンプル分)遅れて追いかけているように見える点に注目してほしい。 つまり、入力信号からもっとも大きな影響が現れるのはフィルタウィンドウの中央であり、これはインパルス応答のプロットで1の入力による最も強い効果がフィルタウィンドウの中央に現れることとも一致する。

遅延を加えるのはFIRだけではない。 たいてい、あるサンプルのウィンドウに対して行われるフィルタリングはすべて遅延を引き起こし、その遅延はたいていウィンドウの長さの半分になる。 用途によっては、この遅延を設計上考慮する必要がある場合とない場合がある。 しかし、この信号を別のフィルタをかけていない、あるいはあまりフィルタをかけていない信号と時間軸を揃えたい場合は、ディレイという要素を使って、この遅延を考慮に入れる必要がある。

フロントエンドプロセッサ

ここまで、最終的な解に至るまでの過程と、その解を構成するすべての要素について詳しく述べてきたので、ここからは処理チェーンをたどりながら、信号がパンチを明らかにするものへとどう変換されていくかを見ていこう。 FEPの主な目的は、バイアスを取り除き、加速度のバーストにまたがって滑らかにつながる出力信号を作ることである。加速度が高まっているときは振幅が高く、加速度が低いときは振幅が低くなる波形である。 FEPには、ハイパスFIR、アッテニュエータ(減衰器)、レクティファイア(整流器)、そしてスライディングウィンドウ平均による平滑化という、4つの直列の要素がある。

最初の画像は、ハイパスFIRの入力と出力である。 バイアスの分だけずれているため、それほど重なっては見えない。 赤い信号が加速度センサーからの入力、青がFIRからの出力である。 重力による1gの加速度が取り除かれ、信号のゆっくりとした変化がフィルタで除去されていることに注目してほしい。 24,750ミリ秒から25,000ミリ秒の間を見ると、青い信号はスパイクとわずかなリンギングを伴うほぼ直線に近い形になっているのに対し、元の入力にはそのスパイクに加えて、ゆっくりとしたうねりに沿ってさまよう動きが見られる。

次はアッテニュエータの出力である。 この要素は信号全体に作用するが、信号のピークの値を下げる一方で、もっとも重要な役割は、信号の静かな部分をゼロの値に近づけて押しつぶすことである。 以下の画像はアッテニュエータの出力を示しており、入力はハイパスFIRの出力である。 予想どおり、ピークははるかに低くなっているが、静かな時間帯も同様に低くなっている。 これによって、加速度のバーストが少し見やすくなる。

次はレクティファイア要素である。 その役割は、すべての加速度エネルギーを正の方向に揃え、平均化に使えるようにすることである。 たとえば、+1000の正のスパイクの後に-990の負のスパイクが続くと平均は5になるが、+1000の後に+990が続けば平均は995になり、大きな違いが生じる。 以下はレクティファイアの出力の画像である。 加速度のバーストはわずかに見やすくなっているが、まだはっきりとはわかりにくい。 実のところ、この画像はこの問題がこれほど手強い理由をまさに物語っている。台の共振による揺れが、パンチのエネルギーが加わるにつれてパターンをどう変化させるかがはっきりと見て取れる。 左側は低く頻度の高いピーク、右側は高く頻度の低いピークになっている。

49個の値によるスライディングウィンドウは、FEPの最後のステップである。 ここまでの処理では、画像を見る限りパンチがはっきりと浮かび上がるような大きな変化は与えられていなかったが、この最終段階によって、信号が隠れたパンチの情報をまさに引き出そうとしていることが視覚的にわかるようになる。 これまでの信号処理の成果が、まるで魔法のようにこの段階で姿を現す。 以下はスライディングウィンドウ平均の画像である。 青い信号がその入力、つまりレクティファイアの出力であり、赤い信号がスライディングウィンドウの出力である。 赤い信号は、FEP段階の処理における最終的な出力でもある。 これはウィンドウであるため、それに伴う遅延がある。平均するとおよそ22サンプル、44ミリ秒である。 入力信号のスパイクが突然高く現れ、その後に小さなリンギングが続くことがあるため、常にそのとおりに見えるわけではない。 また、大きなスパイクの前に小さなスパイクがいくつか現れることもあり、そのために出力のピークがどこに現れるかによって、スライディングウィンドウ平均の出力の遅延が一定しないように見えることもある。 これらの小さな盛り上がりは小さいものの、パンチによって新たな加速度エネルギーが加わった場所を表すようになっている。

検出プロセッサ

いよいよ検出プロセッサ(DET)に話を進めよう。 FEPは、加速度のバーストがどこで起きているかを示し始めた信号を出力する。 DETの役割は、この信号をさらに強調し、アルゴリズムを使ってパンチがどこで起きているかを検出することである。

DETの最初の段階はアッテニュエータである。 最終的には信号にエクスポネンシャルゲインを加えてピークをしっかりと引き上げたいのだが、その前に、まずは低い値を再びゼロに近づけて押しつぶし、DETチェーンの残りの部分で処理しきれないほど大きな値が生じないよう、ピークも下げておく必要がある。 以下はアッテニュエータ段階の出力の画像である。FEPからの出力信号と似た形に見えるが、FEPではピークが100を超えていたのに対し、今回はピークがわずか50を少し超える程度になっている点に注目してほしい。 縦軸は最大振幅500に拡大表示しており、パンチの情報を含む実用的な信号があることが確認できる。

信号を十分に減衰させたところで、ここからが本領発揮である。 すべてが1つにまとまるのが、二乗振幅(Mag Square)関数のところである。 減衰させた信号には、これから育てていく巨大なセコイアの木の小さな種が眠っている。 以下はMag Squareの出力の画像である。赤い信号が減衰済みの入力、青い信号がMag Squareの出力である。 縦軸の最大値を3,000まで拡大表示する必要があったが、見てのとおり、入力信号はほとんど平坦に見えるにもかかわらず、Mag Squareによって検出アルゴリズムがパンチを見分ける助けとなる、見紛いようのないピークを引き出すことができている。 なぜこの巨大なピークをそのままパンチの検出に使わないのかと思うかもしれない。 この区間の信号を分析対象に選んだ理由の一つは、加速度の大きさがいかに大きく変動しうるかを示すためであり、25,000ミリ秒から25,250ミリ秒の間のピークが周囲のピークよりもかなり小さいことがわかる。これは単純なしきい値判定を難しくする要因である。

次に、2Hzから4Hzの範囲で起きるイベントを探しているので、素早く変化する部分を取り除こうとローパスフィルタを導入することにした。 0〜5Hzの帯域を持つ厳密なローパスフィルタをT-Filterで作るのは大変だった。生成されるフィルタのタップ数が100を超えてしまい、その処理コストは避けたかったし、それだけの合計を保持するには64ビットのアキュムレータが必要になってしまう。 そこで通過帯域を0〜19Hzに、阻止帯域を100〜250Hzに緩和した。 以下はローパスフィルタの出力の画像である。青い信号が入力、赤い信号が遅延させた出力である。 この画像を選んだのは、入力信号と出力信号が互いに干渉せずに見えるようにするためである。 遅延は、ローパスFIRの6サンプル分の遅延によるものだが、この信号にはさらに49サンプルの遅延も加えており、これは処理チェーンの次の段階にある99サンプルのスライディングウィンドウ平均のちょうど中央に位置を揃えるためである。 つまり、合計で55サンプル、110ミリ秒遅延していることになる。 この画像では、緩やかなピークがその高さによってわずかに増幅されており、より速く変化する要素が減衰することで滑らかになっている様子がわかる。 それほど大きな変化ではないが、信号は少しきれいになっている。Earl Muntzなら、このローパスフィルタを回路から取り除いてしまえと言うかもしれないし、実際それでも動作するかもしれない。

信号処理の最終段階は、99サンプルのスライディングウィンドウ平均である。 このスライディングウィンドウ平均には、新しい値が追加されるたびにウィンドウの中央にあるサンプルを返す機能を組み込んでおり、これが先ほどの画像で示した49サンプル遅延の信号を作り出す方法である。 これが重要なのは、検出アルゴリズムには2つの並行した信号、すなわち99サンプルのスライディングウィンドウ平均の出力と、そのスライディングウィンドウ平均への49サンプル遅延した入力が渡されるからである。 これによって、平均化されていない信号を、スライディングウィンドウ平均のちょうど中央に完璧に揃えることができる。 平均化された信号は、検出アルゴリズムの検出処理で使う動的なしきい値として使われる。 ここでもう一度、DETの最終出力の画像を示す。

この画像では、緑と黄色の信号が検出アルゴリズムへの入力であり、青と赤が出力である。 見てのとおり、49サンプル遅延させた緑の信号は、黄色の99サンプルスライディングウィンドウ平均のピークと完璧に位置が揃っている。 検出アルゴリズムは、緑の信号が黄色の信号を横切るタイミングを監視する。 これは、信号が黄色の信号に対して最小または最大の方向に十分動いたことを確認する開始ガードの状態を、最大側と最小側の両方に用意し、その後、緑の信号が最大値または最小値を宣言できるだけの方向転換を示すかどうかを監視する状態へ切り替えることで実現している。 ピークの開始が検出され、かつ直前に検出したピークから少なくとも260ms経過していれば、状態は緑の信号の新しいピークを監視するモードへ切り替わり、画像に見える青いスパイクも生成される。 これがパンチのカウントとして記録されるタイミングである。 新しいピークが検出されると、状態は新しい最小値の開始を探すモードに切り替わる。 そして、緑の信号が黄色の信号よりも50だけ下回ると、状態は緑の信号の新しい最小値を探すモードに切り替わる。 緑の信号の最小値が確定すると、状態は緑の信号の新しいピークの開始を探すモードに切り替わり、この時点で画像に赤いスパイクが表示される。

この時間帯のデータを選んだ理由をもう一度述べておくと、ピークの振幅が大きく変動する状況でも、このアルゴリズムがパンチを追跡できることを示すためである。 興味深いのは、24,750ミリ秒から25,000ミリ秒の間を見ると、緑の信号がわずかに上向きにスパイクしたことで最小値が検出され(赤いスパイク)、ステートマシンがその時点で次のピークの開始を探し始めていることがわかる点である。 しかし、緑の信号は黄色の線を一度も越えなかったため、ピーク開始の状態は信号が底まで下がり続けるのに合わせてそのまま維持され、25,250付近で黄色の線を越えたところでようやく次のピークの開始を宣言した。 さらに、25,250付近のピークは周囲のピークよりもかなり低いにもかかわらず、問題なく検出できている。 このように、動的なしきい値処理とステートマシンのロジックによって、スピードバッグのパンチ検出アルゴリズムは、いわば「パンチに合わせて揺れながらついていく」ことができるのである。

おわりに

まとめると、この記事では多くのことを扱ってきた。 第一に、求められる最終成果物との関係で問題を十分に理解することの重要性と、そこにたどり着くために必要なドメイン知識について。 第二に、この種の問題では、アルゴリズムを組み立てるための足場となる環境を作ることが欠かせないということ。今回の場合は、信号を視覚的に表示できるJavaのプロトタイプがそれにあたる。 第三に、対象環境向けの実装について。PCであれば、大量のキャッシュを備えた強力なCPU向けに最適化してくれる素晴らしいコンパイラがあるが、マイクロコントローラでは最適化は実質的に自分自身の仕事になる。処理をできる限り高速に保つため、知っているあらゆる最適化のテクニックを使うべきである。 第四に、反復的な開発は、この種の問題に取り組む助けになるということ。開発の過程で得た知識を取り込みながら、問題への取り組みを繰り返し練り直していく。

このプロジェクトを振り返り、最終的に何が成功につながったのかを考えると、主に2つのことが思い浮かぶ。 仕事に適したツールを作ったことは、非常に価値があった。 自分が組んだ各処理要素が信号にどう影響するかを見られたことは、本当にかけがえのないものだった。 出力信号をプロットするだけでなく、それをリアルタイムで表示できたことで、生じている加速度を十分に理解できた。 まるでNateが部屋の隅でバッグを打っていて、その波形が画面に流れ込んでくるのを見ているようだった。 しかし、最大の要因は、最終的に自分が探しているものが1秒間に2回から4回起きる現象なのだ、と気づいたことだった。 そこに焦点を絞り、生の入力信号をその現象を示すものへとどう変換するかを、粘り強く追い求め続けた。 その答えを見つけるためにGoogleで検索できるものは何もなかった。 知識というものは、実のところ本から生まれるのではなく、本に記録されるだけなのだということを忘れないでほしい。 まず誰かが決まった筋書きから外れて何かを発見し、それが初めて知識になる。 自分が持っている知識、見つけられる知識は活用しつつも、まだ誰も試したことのない方法を、未解決の問題を解くために想像力を使って試すことを恐れないでほしい。 だからこの先、たとえ話として、舗装された道の終わりにたどり着いたときのことを思い出してほしい。 引き返してすでに舗装された別の道を探すだろうか。それとも、ハブをロックして前へ進み続け、自分自身の発見を切り開くだろうか。 筆者は「加速度センサーでパンチを数える方法」をGoogleで検索することはできなかったが、これからは誰かができるようになる。


さらに読み物として、SparkFunの他の記事も紹介する(いずれも英語)。

  • How Lithium Polymer Batteries are Made:Great Power Battery社の工場を見学する機会があった。LiPoがどのように作られているかを紹介する。
  • Teardown: DDC Mobile X900:Nateが中国で手に入れた、レンガのように分厚い携帯電話を分解してみる。
  • Gas Pump Skimmers:ガソリンスタンドの給油機に仕掛けられたスキマーの分解と、検出・防止の方法。
  • Temperature Sensor Comparison:アナログとデジタルの温度センサーを比較する。どちらが優れているか。

タグ: 記事、概念、電気工学、モーション、プログラミング、科学


出典:Lessons in Algorithms(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

熱抵抗を理解する

はじめに

消費電力の小さいデバイスを扱っているうちは、熱の管理はさほど問題にならない。 しかしモーターやLEDストリップを追加し、プロジェクトの消費電流が増えてくると、部品が熱くなり始めることがある。 熱をきちんと管理しないと、部品が過熱し、寿命を縮めてしまう。 このチュートリアルでは、熱抵抗とは何か、それを熱管理にどう使うか、そしてプロジェクトの寿命を最大限に延ばす方法を扱う。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

熱抵抗

電力損失が発生する熱にどう影響するかを理解するには、まず熱抵抗(Rθ)について理解する必要がある。 電気抵抗がオーム単位で電流の流れに抵抗するのと同じように、熱抵抗はケルビン毎ワット(あるいは摂氏度毎ワット)の単位で熱の流れに抵抗する。 熱抵抗を使えば、熱がある場所から別の場所へどれだけ伝わりやすいかに基づいて、さまざまな負荷のもとで特定の部品がどれだけ熱くなるかを見積もることができる。 電子回路の場合、熱は半導体接合のような発生源から始まり、最終的には周囲の空気へと放散されていく。

半導体の接合部が最大定格温度を超えると、壊れてマジックスモーク(部品を壊したときに出る煙)が出てしまう。 そうならないようにするには、そのデバイスがどれだけ効率よく電力を扱えるかを見ておく必要がある。

オームの法則と熱抵抗

ヒートシンクから接合部まで、そしてその間のあらゆる場所の温度は、オームの法則を使って計算できる。 先ほど触れたとおり、電気抵抗は熱抵抗と非常によく似ている。 V = I×Rというオームの法則の電圧を温度(T)に、電流を電力(P)に置き換えると、次の式になる。

\[ T = P \times R_\theta \]

これに相当する熱回路は、以下のようになる。

  • T_Junction(TJ:接合部の温度
  • RθJC:接合部からケースまでの熱抵抗
  • T_Case(TC:ケースの温度
  • RθCH:ケースからヒートシンクまでの熱抵抗
  • T_Heatsink(TH:ヒートシンクの温度
  • RθHA:ヒートシンクから周囲の空気までの熱抵抗
  • T_Ambient(TA:周囲の空気の温度

熱抵抗がどう使われるかをより深く理解するために、次の例を見てみよう。

  • 消費電力:2W
  • RθJC = 4°C/W
  • RθCH = 0.25°C/W
  • RθHA = 6°C/W
  • TA = 25°C

まず、オームの法則に相当する熱の式から始める。

\[ T = P \times R_\theta \]

ここで求めたいのは接合部の温度上昇なので、TはTJになる。 消費電力Pは2Wである。 熱抵抗は直列につながっているので、回路における直列抵抗と同じように、値を単純に足し合わせることができる。

\[ T_J = P \times (R_{\theta JC} + R_{\theta CH} + R_{\theta HA}) = 2\text{W} \times (4 + 0.25 + 6)\text{°C/W} = 20.5\text{°C} \]

接合部の温度は、周囲温度(この例では25°C)より20.5°C高いということなので、絶対温度は20.5°C + 25°C、つまり45.5°Cになる。

熱抵抗の値はどこで確認すればよいのだろうか。 電圧レギュレータやダイオード、トランジスタなどの半導体部品では、データシートに熱に関する情報の項目があり、ヒートシンクを使わない場合の接合部から空気までの熱抵抗(RθJA)や、ヒートシンクを使う場合の接合部からケースまでの熱抵抗(RθJC)が載っている。ヒートシンク自体にも固有の熱抵抗があり、これは次のセクションで扱う。 典型的な熱抵抗のデータは、以下の画像のような形で示されることが多い。

熱をどう伝えるか

金属フィン型ヒートシンク

ヒートシンクにはさまざまな形やサイズのものがあるが、その目的はただ一つ、熱を空気へ伝えることである。 ヒートシンクの各フィンの役割は、空気と接する表面積をできるだけ大きくし、ヒートシンクから熱を奪うこと、ひいては半導体の接合部から熱を引き離す助けとなることである。 とはいえ、金属フィン型ヒートシンクの熱抵抗は、フィンのそばを流れる空気の量によって性能が変わるため、少しややこしいことがある。 典型的なヒートシンクのデータシートには、部品の寸法だけでなく、次のような熱特性のグラフも掲載されている。

各プロット線の矢印は、それぞれが対応する軸を示している。 たとえば、赤くハイライトした部分は、無風状態(ファンなし)で10Wの電力を放散すると、ヒートシンクの温度が周囲温度よりおよそ78°C高くなることを示している。 一方、フィンに沿っておよそ400ft/minの風を流した場合、緑の線が示すように、同じ10Wの電力を放散したときのヒートシンクの熱抵抗はおよそ1.8°C/W、つまり周囲温度より18°C高くなる。

ビア

設計にヒートシンクを追加する必要がある場合、たとえばスイッチモード電源のように部品をICにできるだけ近づけて配置することが重要な設計では、ビアが基板の片面から反対の面へ信号を伝えるだけでなく、熱を伝える役割も果たせる。

計算を自分でするのが面倒であれば、Saturn PCB Design社のPCB Toolkitには、電気系エンジニアが使うさまざまな式を解いてくれる便利なツールがそろっている。 その中の一つのタブが、ビアの特性を扱うものである。

画像提供:SaturnPCB

ビアの熱抵抗を求めるため、赤くハイライトした欄に、手元の基板の特性を入力した。 レイヤー数を2層に設定し、ビアの穴径を必要に応じて変更する程度で済むはずである。 ビアのめっき厚とビアの高さは、たいていの基板で標準的な値になっている。 「Solve」をクリックすると、右下の青い枠に熱抵抗が表示され、今回はビア1本あたり179.3°C/Wだった。 ビアが10本あれば、ビアの熱抵抗は17.9°C/Wまで下がる。 接合部の温度を計算する際は、ここでビア分の熱抵抗をもう一つ直列に追加し、他の熱抵抗と合わせて計算することになる。

PCBによる放熱

PCB上で熱を伝える話になると、計算はあっという間に複雑になる。これが、ビアの熱抵抗にはSaturn PCBのツールを使うほうが簡単な理由の一つである。 PCB自体をヒートシンクとして使う場合は、さらに複雑になる。 表面積の関数である銅箔の熱抵抗だけでなく、ソルダーマスクや基材そのものの熱抵抗もあり、これらは周囲の孤立した銅箔パターンにも熱を伝えていく。 詳しい説明を読みたい場合は、Texas Instrumentsのアプリケーションレポートを参照してほしい。 もう少し読みやすい情報としては、Paul Bryson氏がこのテーマについて優れたブログ記事を書いており、興味深いヒントや知見がこちらにまとめられている。

おおまかな目安としては、Paul Bryson氏の記事にある次のグラフを使うとよい。

画像提供:brysonics.comのPaul Bryson氏

例:スルーホール実装のリニアレギュレータ

熱抵抗の計算が実際の世界でどれだけうまく機能するか見てみよう。 この例では、リニアレギュレータのLM7805と、DC-DCコンバータという2種類の異なる電圧レギュレータを使う。 データシートから得られる数値と実測値がどれだけ一致するか確認していく。

リニアレギュレータ

低コストかつ低ノイズな電圧レギュレータの何が悪いというのだろうか。 リニアレギュレータは多くの用途に適した優れた選択肢だが、変換効率の面では見劣りする。 リニアレギュレータの基本的な設計は、次のようになる。

画像提供:EE Times

リニアレギュレータがどれだけ熱くなるかを求めるには、まず入力電力と出力電力が等しくなければならないという理解から始めよう。 理想的にはシステムの効率は100%になるはずだが、現実にはいくらか損失が生じ、その電力損失は熱(PD)として放散される。 これは次の式で表せる。

\[ P_{in} = P_{out} + P_D \]

つまり、消費電力は次のように表せる。

\[ P_D = P_{in} - P_{out} \]

電子回路において、電力は電圧と電流の積として表せる。 つまり、最初の式は次のように書き直せる。

\[ P_D = (V_{in} \times I_{in}) - (V_{out} \times I_{out}) \]

リニアレギュレータでは入力電流と出力電流が等しいので、この式は次のように簡略化できる。

\[ P_D = I \times (V_{in} - V_{out}) \]

次に、リニアレギュレータの熱特性を見てみよう。 LM7805には、使用しているTO-220パッケージについて、次のような熱抵抗が示されている。

ヒートシンクなしの場合(RθJA

最初の例として、負荷電流200mAのときにリニアレギュレータがどれだけ熱くなるかを見てみよう。 LM7805の出力電圧は5V、入力電圧はおよそ12Vとする。 これらの値を先ほどの電力損失の式に当てはめると、次のようになる。

\[ P_D = 0.2\text{A} \times (12\text{V} - 5\text{V}) = 1.4\text{W} \]

ヒートシンクなしでどれだけ熱くなるかを求めるには、接合部から空気までの熱抵抗(50°C/W)を使う必要がある。 熱抵抗のセクションの式を使い、周囲温度を23°Cと仮定すると、接合部の温度は次のように計算できる。

\[ T_J = P_D \times R_{\theta JA} + T_A = 1.4\text{W} \times 50\text{°C/W} + 23\text{°C} = 93\text{°C} \]

実際の値と比較するため、入力電圧を測定すると12.1V、負荷をかけた状態での出力電圧は4.90Vだった。 出力には、200mAに設定した定電流ダミー負荷を接続して測定した。 この実測値を使うと、消費電力は次のようになる。

\[ P_D = 0.2\text{A} \times (12.1\text{V} - 4.90\text{V}) = 1.44\text{W} \]

予想される接合部の温度は、次のようになる。

\[ T_J = 1.44\text{W} \times 50\text{°C/W} + 23\text{°C} = 95\text{°C} \]

上のサーモグラフィ画像が示すとおり、負荷をオンにしてレギュレータの温度を上げていくと、およそ98°Cで安定した。 かなり近い値だが、数値には必ず余裕(マージン)を持たせるべき理由がよくわかる例でもある。 測定の精度の限界により、実際の電源電圧は計算に使った値よりわずかに高く、また負荷時の出力電圧の許容誤差は4%あるため、出力電圧は仕様の範囲内でも最低4.8Vまで下がりうる。

ヒートシンクを使う場合(RθJCを使用)

ここでヒートシンクを追加すると、接合部から空気までの熱抵抗の代わりに、接合部からケースまでの熱抵抗、およそ5°C/Wを使う必要がある。 使用しているヒートシンクのデータシートを見ると、無風状態でおよそ1.4Wの電力に対して25°Cの温度上昇が生じることがわかる。

ヒートシンクのデータシートは熱抵抗ではなく温度上昇の形で示されているため、まず接合部からヒートシンクまでの熱抵抗を使って接合部の温度上昇を計算し、そこにヒートシンクの温度上昇と周囲温度を足し合わせて接合部の温度を求める必要がある。 熱伝導コンパウンドを使うと、ケースからヒートシンクまでの熱抵抗は下がる(およそ0.25°C/W)。使わない場合は、熱抵抗はおよそ1°C/Wと仮定する。 したがって、接合部の温度の式は次のようになる。

\[ T_J = P_D \times (R_{\theta JC} + R_{\theta CH}) + T_{heatsink\ rise} + T_A \]

\[ T_J = 1.44\text{W} \times (5 + 1)\text{°C/W} + 25\text{°C} + 25\text{°C} = 56.64\text{°C} \]

実際の電圧はヒートシンクなしのときと同じく、Vin = 12.10V、Vout = 4.90V、Iout = 200mAだった。 これは実際に放散する必要のある電力も同じ1.44Wになることを意味し、これによる接合部温度の計算値はわずかに56.64°Cまでしか上がらなかった。 電源と負荷をオンにしてから、温度が定常状態に落ち着くまで待ち、レギュレータの温度を測定するとおよそ54°Cだった。

今回は、計算値よりも実測温度のほうが低かった。 おそらく誤差の原因は、無風状態でのヒートシンクの温度上昇を読み取った際の値にあり、25°Cではなく23°Cに近かった可能性がある。 最後の例では、表面実装タイプのレギュレータを使い、PCB自体をヒートシンクとして使った場合にどれだけ熱くなるかを見積もってみる。

例:表面実装のDC-DCコンバータ

ここで使う基板はBuck-Boostで、TPS63070 DC-DCコンバータを搭載している。 基板は1.25×1.25インチで、1oz厚の銅箔を使用している。 その他の特徴として、レギュレータは基板の中央に配置されており、基板の95%以上が銅箔で覆われている。 このサイズのため、基板全体の面積を熱抵抗の計算に使い、ビアの熱抵抗の計算には41本のビアすべてを使うという前提を置くことにする。

まず、放散する必要のある電力を求める必要がある。 DC-DCコンバータでは入力電流と出力電流が等しくないため、リニアレギュレータのときと同じ式は使えない。 その代わり、データシートの効率グラフを使って見積もることができる。

この効率グラフは、出力電流の関数として効率をプロットしたもので、入出力電圧によって値は変わる。 このテストでも、先ほどと同じく入力電圧12V、出力電圧5Vという条件を使う。 ただし今回は、負荷電流を1.0Aまで増やす。 上の5V用の効率グラフを使うと、効率はおよそ93%であり、電力損失は出力電力の7%程度になる。

出力電力は\( P_{out} = V_{out} \times I_{out} = 5\text{V} \times 1.0\text{A} = 5\text{W} \)であり、効率を\( \eta \)とすると消費電力は次のように見積もれる。

\[ P_D = P_{out} \times \frac{1-\eta}{\eta} = 5\text{W} \times \frac{0.07}{0.93} \approx 0.38\text{W} \]

熱抵抗については、先ほどのビア計算ツールを使い、ビアによる熱抵抗はツールで得られた値からおよそ4.4°C/Wと概算した。 PCBの熱抵抗を見積もるにあたっては、基板をテーブルから浮かせ、テーブル自体がヒートシンクにならないようにした。 ただし基板の裏面も空気に接することになるため、表面積は10.08cm²から20.16cm²へと2倍になる。 Buck-Boost基板の表面積をもとにすると、PCBの熱抵抗はおよそ65°C/Wと見積もれる。

TPS63070のデータシートには、次のような熱特性が示されている。

(画像をクリックすると拡大表示できる。)

接合部からケースまでの熱抵抗は該当しないが、接合部から基板までの熱抵抗はおよそ13°C/Wとして示されている。 これらの熱抵抗の値を、接合部の温度の式に当てはめてみよう。

先ほどと同じように、ダミー負荷をオンにして、温度の上昇が止まるまで基板を加熱した。 以下に示すとおり、記録された温度はおよそ54°Cだった。

まとめ

同じ計算は、さまざまな電力部品に応用できる。 たとえば、MOSFETのドレインとソース間の抵抗を見れば、さまざまな電流でどれだけ熱くなるかがわかる。 逆流防止用のダイオードであれば、順方向電圧降下と電流を使って計算できる。 これらの部品はすべて多少なりとも熱を発生させるが、これでその量を根拠を持って見積もれるようになったはずである。

身につけたスキルを早速試してみたい場合は、次のチュートリアルもおすすめである(いずれも英語)。

タグ: 概念、電気工学、電力


出典:Understanding Thermal Resistance(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

FPGAはどうやって動いているのか

はじめに

まずは基本から始めよう。FPGAとは何だろうか。 FPGAはField Programmable Gate Array(フィールドプログラマブルゲートアレイ)の略だが、これだけではFPGAが何をするものなのか理解する助けにはならない。とはいえ、まずは言葉の意味を片付けておく必要があった。

FPGAは、プログラマブルロジック(プログラマブルハードウェアと呼ばれることもある)と呼ばれる部類のデバイスに属する。 FPGAそのものは基本的には何もしないが、望みのデジタル回路であればほぼ何にでも設定(コンフィグレーション)できる。 ここでの魔法は、物理的には何も変化しないという点である。 設定をFPGAに読み込ませるだけで、望みどおりの回路のように振る舞い始める。 はんだ付けもジャンパー線も、面倒な作業は一切いらない。 FPGAはその後、また別の回路として、さらに別の回路として、何度でも再設定できる。 この設定はRAMベースであるため、実質的に無制限に再設定が可能である。

Alchitry Cu基板上のLattice iCE40 HX FPGAAlchitry Au基板上のXilinx Artix 7 FPGA

FPGAを使ってデジタル回路を作ると言っても、実際に設計を回路図として描くわけではない。 FPGAに収められる回路の規模と複雑さを考えると、実際に回路図を描いていてはあまりにも扱いづらくなってしまう。 その代わりに、望む回路の振る舞いを記述すれば、ツールがその記述をもとに、その振る舞いに一致する回路を作ってくれる。

この点では、ただテキストを入力するだけという意味でプログラミングに近い感覚がある。 しかし、実際に作っているのはハードウェアであるため、その根本的な実装のされ方はまったく異なる。

テキストでハードウェアを作るというのが魔法のように感じられても、心配はいらない。 その仕組みは概念としてはとても単純であり、このチュートリアルではそれをきちんと分解して見ていく。

参考になるチュートリアル:

このチュートリアルでは、FPGAとは何か、そしてどう動作するのかを扱う。 電気(電圧、電流など)と2進数についてはある程度理解しているものとして進める。 それ以外のことは、この基礎の上にすぐに積み上げていける。 これはFPGAとは何か、その基本的な設計を概観することを目的としており、自分でFPGA設計を行うためのガイドではない。

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

デジタル回路と論理ゲート

デジタル回路

FPGAには、デジタル回路しか作れないという注意点がある。 新しいFPGAの中にはオンボードのアナログ-デジタル変換器を搭載しているものもあるが、それらもアナログ入力をできるだけ早くデジタル信号に変換している。 では、デジタル回路とは何だろうか。

電子工学において、デジタルという言葉は、連続的な電圧値を切り捨てて、離散的な1と0で表す回路を指すのに使われる。 上位レベルの設計にとっては、実際に使われる電圧やそのしきい値そのものはさして重要ではないが、FPGA内部では0Vが0、1.2Vが1として扱われるといった例をよく目にする。 実際の電圧が、たとえば0.8Vだったとしても、1.2Vに十分近ければ1とみなされ、すべて同じように動作する。

デジタル回路は電圧を極端な値へ振り切るように設計されており、そのおかげでノイズやその他の現実世界の干渉に対して驚くほど頑健になる。 デジタルという考え方はまた、下位レベルの設計を気にせずに回路へ複雑な振る舞いを組み込む方法も与えてくれる。理想化された世界の中で作業できるということである。 細々とした部分は、これから使う単純な構成要素の設計の中で処理されている。

この構成要素が論理ゲートである。

論理ゲート

論理ゲートにはいくつかの種類があるが、もっともよく使われるのはANDORXORNOTである。 それぞれデジタル入力を受け取り、その論理演算を行い、デジタル値を出力する。

ANDゲートは2つの入力を受け取り、1つ目の入力かつ2つ目の入力が1のときにのみ1を出力する。 どちらかの入力が0であれば、出力は0になる。 ANDゲートの記号は次のようになる。

ORゲートは2つの入力を受け取り、1つ目の入力または2つ目の入力が1であれば1を出力する。 両方が0のときだけ、出力は0になる。 ORゲートの記号は次のとおりである。

XORゲートはORゲートに似ているが、1つ目の入力または2つ目の入力のどちらか一方だけが1のときに1を出力し、両方が1のときは出力しない。 入力が異なるときに1を出力する、と考えることもできる。 XORのXは「exclusive(排他的)」を意味する。記号は次のとおりである。

NOT)ゲートはもっとも単純なゲートである。 入力は1つだけで、その値を単純に反転させて出力する。 1は0に、0は1になる。

これらの基本ゲートには、NANDNORXNORと呼ばれる派生形もある。 これらは、単に標準的なゲートの出力を反転させたものにすぎない。

参考までに、ANDゲートは他のすべての論理ゲートと同様、トランジスタを使って作ることができる。 以下の画像は、ANDゲートがどう実装されうるかの一例を示している。 この回路図では、NMOSとPMOSのMOSFETトランジスタが使われている。 この種の設計はCMOS(相補型金属酸化膜半導体)と呼ばれ、現代のほとんどの回路で使われている方式である。

上の回路図は、実際にはNANDゲートの後にNOTゲートを続けたものであることに注目してほしい。 これは、CMOS回路が出力を反転させる性質を持つためである。

マルチプレクサ

トランジスタから論理ゲートまでの基本的な構成要素がそろったところで、これらを使ってもっと便利なものを作ることができる。 論理ゲートだけでも、あらゆるデジタル回路を記述できる。 とはいえ、2進数の演算(加算器、乗算器など)に使われるもののように、何度も繰り返し登場する高レベルな機能には、それぞれ専用の記号が与えられている。

ここでは、FPGAの基本的な構成要素の一つである、マルチプレクサを見ていこう。

マルチプレクサは、選択(select)入力の値に基づいて、複数の入力の中から1つを選び出す。 記号は次のとおりである。

selの線にある「/」の記号は、それが6ビット幅であることを示している。

入力の数はさまざまだが、マルチプレクサの出力は常に1つだけである。

選択入力のエンコード方法もさまざまである。 たいていは2進数として表されるが、より単純な回路ではワンホット(one-hot)エンコーディングが使われる。 ワンホットエンコーディングとは、単純に言えば、常にちょうど1つだけ1が立っているビット列のことである。1がどの位置にあるかが重要な情報になる。

デコーダは2進数の値を受け取り、ワンホット信号に変換する。 エンコーダはワンホットの値を2進数に変換する。 これらを使えば、ワンホット方式のマルチプレクサに2進数の値を受け付けさせることができる。

ANDゲートとORゲートだけを使って、ワンホットエンコーディングのマルチプレクサをどう実装できるか見てみよう。

selの値を000010、つまりsel[1]だけが1になるように設定したとしよう。 すると、bを入力に持つANDゲート以外のすべてのANDゲートでは、いずれかの入力が0になっていることがわかる。 つまり、入力a、c、d、e、fが何であっても、それらのゲートは常に0を出力するということである。 関係してくる入力はbだけである。 bが1のとき、1とANDされて、そのANDゲートの出力は1になる。 bが0のとき、1とANDされて、そのANDゲートの出力は0になる。

言い換えれば、そのANDゲートの出力は単純にbそのものである。

sel[1]を1に設定したときのANDゲートの結果

この回路図のORゲートは、3つ以上の入力を持つ形で描かれている。 これは、2入力のORゲートを木構造に組み合わせ、2つの入力をORし、その出力どうしをさらにORするという操作を繰り返すことで作ることができる。 多入力のORゲートは、想像どおりに動作し、いずれかの入力が1であれば出力は1になる。

しかし、この回路では、出力がbであるANDゲートからの入力を除いて、ORゲートへのすべての入力は必ず0になる。 つまり、このORゲートは、bが1のときに単純に1を出力し、bが0のときに0を出力するということである。

言い換えれば、このORゲートの出力は単純にbそのものである。

ORゲートの結果はbになる

このロジックはどの入力についても繰り返すことができ、入力がワンホットである限り、対応する1に応じた入力がそのまま出力に伝わる。

選択(sel)入力をプログラム可能にした、マルチプレクサの大きな行列を思い浮かべてみてほしい。 これを使えば、設計の中で信号を必要な場所へどこへでも配線できる。 これがFPGAにおいて信号を必要な場所へ届ける仕組みであり、汎用配線マトリクス(general routing matrix)と呼ばれる。

もちろん、何千何万もの信号を配線する詳細はかなり込み入ったものになるが、根本的にはプログラム可能なメモリに接続された選択入力を持つ、大量のマルチプレクサを使っているにすぎない。

ルックアップテーブル

これで信号を必要な場所へ動的に配線する方法が手に入ったので、次は任意の論理演算を行う方法が必要になる。 ここでも再びマルチプレクサ、というよりもその派生形であるLUT(ルックアップテーブル)を使う。

4つの入力と2ビットの2進数選択(ワンホットではなく)を持つマルチプレクサを考えてみよう。 主な入力を外部にそのまま出す代わりに、プログラム可能なメモリに接続してみる。 これによって、各入力を任意の定数値にプログラムできるようになる。 これをひとまとめのブロックにすれば、2入力のLUTになる。

LUTへの2つの入力は、マルチプレクサの選択入力にあたる。 マルチプレクサの各入力を望みどおりにプログラムすることで、このLUTを使ってあらゆる2入力1出力の2値関数を実装できる。

たとえば、メモリの内容を次のように設定すれば、単純なANDゲートのように動作させることができる。

アドレス(In[1:0])値(Out)
000
010
100
111

これは単純な例である。通常のLUTは2入力よりもずっと大きく、Alchitry Au搭載のFPGAは5入力LUTを基本としている。

Xilinxでは実際には、2つの5入力LUTを別のマルチプレクサと組み合わせて、6入力LUTとして、あるいは2つの独立した出力を持つ5入力LUTとして使えるようにしている。

FPGA内部のLUTやリソースがどう見えるか本格的に掘り下げたい場合は、Xilinxが公開しているArtix 7に関するこの資料を参照してほしい。 かなり密度の高い資料なので、あらかじめ心の準備をしておくとよい。 とはいえ、20ページ目は一見の価値がある。SLICELの簡略化された回路図が示されている。 スライスはLUTのひとつ上の構成単位である。左側の4つの箱が、上で見たようなLUTである。

参考までに、Alchitry Au搭載のFPGAには20,800個のデュアルLUTが搭載されている。 これはかなりの数のLUTだが、この記事の執筆時点で入手できる最大級のFPGAと比べると、その260分の1程度にすぎない。 想像がつくとおり、これだけの数の信号を配線するだけでも、途方もなく複雑な作業になる。 幸いなことに、FPGAを使う側としては、そのすべてを自分でやる必要はない。 低レベルな配線とLUTのプログラミングはツールがすべて処理してくれる。開発者はただ、望む回路を記述すればよいだけである。

なぜFPGAを使うのか

このチュートリアルを読んで、FPGAが実際にどう動作しているかについて、なんとなく腑に落ちる感覚を持ってもらえていたら幸いである。しかし、そもそもなぜFPGAを使うのだろうか。

たいてい、この問いが出てくるのは、プロセッサを使うかFPGAでカスタム設計を作るかを選ぶ場面である。 コードを書ける人は数多くいるが、FPGA向けの設計ができる人ははるかに少ない。 複雑な振る舞いを作ったり、実装方法を大きく変更したりするには、コードを書くほうがたいてい簡単である。

しかし、FPGAは処理時間の面でも、非常にタイトなタイミング制御の面でも、はるかに効率的になりうる。 これを示すために、ボタンを押したらLEDを点灯させるという簡単な例を見てみよう。 Arduinoのようなもので、これを行うコードを書いたとすると、プロセッサはピンの状態を読み取り、その値に基づいて別のピンの状態を更新する、という小さなループを実行することになる。

コードを最適化すれば、おそらく1秒間に数百万回はこの更新を行えるだろう。 それはすごいことのように聞こえるかもしれないが、これをFPGAで行うとどうなるか見てみよう。 FPGAでボタンとLEDを単純に接続する場合、実際にやることはボタンとLEDをつなぐだけである。 ボタンからの値は、いくつかの入力バッファを通り、配線マトリクスを経由して、出力バッファから出力される。 この処理は、常に絶え間なく続いている。 唯一の遅延は、チップ内のトランジスタのスイッチング遅延によるものであり、これは信じられないほど小さい。

これをさらに発展させて、設計にマイクロフォンを追加してみよう。 マイクロフォンからサンプルを取得し、何らかの処理を行って、収録した音声に含まれる周波数を求めるとする。 筆者自身の経験から言うと、それなりのサンプリングレートで、小さなマイクロコントローラ上でこれをリアルタイムに行うのはかなり大変である。 プロセッサは、マイクロフォンからサンプルを読み取り、何らかのバッファに保存し、大量の計算を行い、その値をLEDのディスプレイなどに出力するという作業を、うまくやりくりしなければならない。 これらのステップにはそれぞれ時間がかかり、プロセッサは実質的に一度に1つずつしか処理できない。

FPGAであれば、設計のごく一部をマイクロフォンからのサンプル読み取り専用に割り当てることができる。 それをバッファに渡し、バッファがいっぱいになったら、計算を行う回路に渡す。 その回路は、結果を別の回路に渡し、その回路がLED群に結果を表示する。

これらの各段階は、単にハードウェアとして存在しているだけなので、互いにまったく独立して動作する。 プロセッサの処理時間を奪い合うコードの行ではないのである。

ここで、依然としてボタンとLEDもつないでおきたいとしよう。 先ほどの100万分の1秒という素晴らしい応答時間は、ボタンをそれほど頻繁に読み取るためのプロセッサ時間を割けなくなるため、今度は5分の1秒という惨めなものになってしまう。 しかしFPGAでは、ボタンとLEDは依然として単純に接続されたままであり、以前とほぼ変わらない即時の速度で応答し続ける。

この独立性のおかげで、FPGAはタイトなタイミング制御が求められるあらゆる用途の制御に最適な候補となる。 たとえば、WS2812B(通称NeoPixel)LEDにデータを書き込むには、厳密にタイミングを制御されたパルスの列が必要である。 マイクロコントローラを使う場合、パルスのタイミングを十分正確にするためだけに、たいていインラインアセンブリを書く必要がある。 また、少しでも処理が止まると信号に悪影響を及ぼすため、割り込みを無効化しておく必要もある。

FPGAであれば、これらのLEDを駆動するための厳密に制御されたパルス列を作るのは簡単であり、設計内の他の何かがタイミングと衝突する心配をする必要もない。

FPGAをいつ使うべきか

ここまでFPGAの利点をいろいろ見てきたので、「それなら何にでもFPGAを使えばいいのでは」と思うかもしれない。良い疑問である。

FPGAの動作の説明からもわかるとおり、もっとも単純な回路を動的に実装するだけでも、たくさんの余計な「仕組み」が必要になる。 これは代償なしには済まない。金銭的な意味でも、設計上のリソースという意味でもである。

FPGAはたいてい高価である。 大きなものになると、1個あたり数万ドルにもなる。 これは、製造に必要なシリコンの量、チップとツールの設計にかかる莫大な研究開発費、そして携帯電話に使われるような小型プロセッサと比べて生産量が相対的に少ないことによる。

もう一つのコストは消費電力である。 回路を直接実装するのに必要な数と比べて、LUTには非常に多くのトランジスタが使われている。 これらすべてのトランジスタは、動作するために電力を必要とする。 このため、FPGAは電池駆動の機器にはあまり向いていない候補になりがちである。 もちろん、回路を省電力に設計することはできるが、まったく何もしていない状態でも、Alchitry Au搭載のFPGAは100mAをわずかに超える電力を消費する。 チップに負荷をかけ始めると、1000mAを超えることも簡単に起こりうる。 比較として、Arduino Leonardoに使われているATmega32U4は、5Vでフルスピード動作時に27mAしか消費しない。 もちろん、Alchitry Auのほうがはるかに高い性能を持っていることは差し引いて考える必要がある。

では、そもそもなぜFPGAを使うのだろうか。 カスタムのデジタル回路を作る方法には、他に2つの主要な選択肢がある。 1つ目は、ディスクリートロジックを使って自分で組み立てる方法である。 これにはかなりの時間がかかり、コストもかなり高くなりやすく、何かを変更する必要が生じたときの柔軟性もほとんどない。

2つ目、そしてより現実的な選択肢は、回路を直接シリコンに実装することである。 これによって非常に高速で非常に効率的な回路ができるが、その代償として柔軟性はゼロになり、費用はトラック何台分にもなる。 カスタムシリコンには、ツールと初期設定にかかる莫大な初期費用がある。 チップ1個あたりの追加コストは個々のFPGAよりも低くなるだろうが、数万個単位で製造するのでない限り、全体としてはこちらのほうが高くつく。 それだけの数を作る場合でも、設計をシリコンに固定してしまうのが得策とは限らないこともある。 FPGAであれば、必要になったときにいつでもペナルティなしに変更できる。

FPGAは、他の選択肢と比べて柔軟性が高く低コストであるため、ほぼどんな設計にもカスタムのデジタル回路を組み込む道を開いてくれる。 しかし、本当にカスタム回路が必要なのだろうか。

FPGAも、他のあらゆる道具と同じだということを忘れないでほしい。 ハンマーは釘を打つのには最適だが、ネジを締めるのにはまったく向いていない。 ドライバーで釘を打とうとしても、まったく無駄な努力に終わるのと同じである。

カスタム回路を作るのは難しいことも多く、もっと良い解決策がないかを自問すべき場面もよくある。 数多くのペリフェラルを備えた非常に高性能なプロセッサがあれば、解決したい問題のほとんどに対応できる。 WiFi経由でデータを送受信するような作業をFPGAでやろうとすれば大変な作業になるが、ESP8266のような数ドルのマイクロコントローラを使えば簡単に実現できる。

筆者はよく、FPGAを組み立てライン(アセンブリライン)にたとえて説明する。 組み立てラインの各工程は互いに独立して動作し、それぞれが設計された仕事に対して驚くほど効率的である。 とはいえ、最初にラインを立ち上げるのは大変な作業になりがちで、大幅な変更を加えたい場合は、一から作り直すほうが簡単なことも多い。

一方、プロセッサは人間のようなものである。 1人の人間でも、十分な時間と訓練があれば、ほぼどんな作業でもこなすことができる。 複雑な逐次処理の作業も、人間にとってはたやすい。

昼食のサンドイッチを1つ作るためだけに、サンドイッチ製造工場をまるごと立ち上げたいと思うだろうか。

FPGAは、それが得意とする作業においては驚異的であり、多くの場合欠かせない存在だが、それでも道具箱に加えるべき道具の一つにすぎない。 非常に強力で、投資する価値のある道具ではあるが、それでもやはり一つの道具なのである。

まとめ

ここまでで、FPGAがどう動作し、何でできているかという基礎を扱った。 Alchitryのウェブサイトには、チュートリアルやプロジェクト、Alchitryフォーラムなど、さらに役立つ資料がそろっている。

FPGAとLucidの世界にさらに深く踏み込みたい場合は、Justin Rajewski氏による“Learning FPGAs: Digital Design for Beginners with Mojo and Lucid HDL”もおすすめである。Amazonで購入でき、FPGAの理解から、最終的に自分で設計するところまでを学べる優れた資料である。

FPGA関連のチュートリアルや製品は今後も充実させていく予定である。次のようなチュートリアルもぜひ確認してほしい(いずれも英語)。

タグ: Alchitry、概念、FPGA


出典:How Does an FPGA Work?(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

磁気浮上

はじめに

光あれ。このチュートリアルでは、基本的な磁気浮上装置を作る。 理論の基礎、磁場センサーの使い方、そしてそれを使った基本的な浮上回路の作り方を扱う。 最後には、もう一歩踏み込んで、ワイヤレス給電で光る浮遊ライトを作る。

必要な部品

このチュートリアルの内容を実際に試すには、次の部品が必要である。

Note

注意:LM358は生産終了が予定されている。汎用オペアンプとしては、同じピン配置でそのまま置き換えられるAS358を推奨する。

SparkFunで扱っていない、その他に使用する部品は次のとおりである。

  • アナログホール効果センサー
  • 1N5401ダイオード
  • 1mHインダクタ

必要な工具

このプロジェクトに必要な工具はマルチメーターとはんだごてだが、オシロスコープがあればテストの助けになる。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

理論の基礎

磁気浮上には、吸引式と反発式の2種類がある。 このガイドでは、動作させやすい吸引式の浮上回路を使う。 ご存じのとおり、磁石にはN極とS極という2つの極がある。 同じ極性の磁場どうしは反発し合い、逆の極どうしは引き合う。 磁気浮上には、永久磁石による固定された磁場と、その永久磁石の位置を制御するために自分で操作できる磁場の両方が必要になる。

画像提供:Geek3、Wikipedia経由、CC BY-SA 3.0

制御可能な磁場を作るには、インダクタを使うことができる。 インダクタはコンデンサと同じようにエネルギーを蓄えるが、コンデンサが電界の形で電圧を蓄えるのに対し、インダクタは磁場を発生させることで電流を蓄える。 ここでは、このインダクタの磁場を使って磁石と相互作用させる。 吸引式の浮上では、インダクタを使って重力に対抗する力を生み出し、磁石をインダクタの方向に引き寄せる。

磁石がインダクタに近づきすぎると、インダクタに流れる電流の大きさにかかわらず、磁石の磁場そのものの強さでインダクタにくっついてしまうほど強くなる。 一方、磁石がインダクタから遠すぎると、磁場の強さが重力に対して弱すぎて引き戻せなくなる。 つまりコツは、磁石が自力では浮き上がれないほど弱く、それでいてインダクタが作る反対向きの磁場の助けを借りれば重力に打ち勝てる、というちょうどよい範囲を見つけることである。 磁石の位置を把握するために、ホール効果センサーと呼ばれる磁場センサーを使う。

ホール効果センサー

ホール効果センサーは、磁場の強さを測定するために使うデバイスである。 センサーの出力は、そこを通過する磁場の強さに正比例する。 ここで使うセンサーはSS496Bであり、アナログ電圧を出力する。 他にも、磁場の有無だけでオン・オフするスイッチのように動作するホール効果センサーもある。 次のセクションでは、このセンサーが磁石に対してどう反応するかを見ていく。

ホール効果センサーをテストする

まずはこのセンサーがどう動作するかテストしてみよう。 ブレッドボードを使い、電源電圧のピンに5V、グラウンドにグラウンドを接続し、出力ピンにはオシロスコープのプローブをつないで電圧の変化を見るか、電圧モードにしたマルチメーターで電圧の変化を確認する。

磁石がない状態では、出力電圧はおよそ2.5Vに落ち着く。 磁石の片面をセンサーに近づけていくと、電圧は下がっていく。 磁石を裏返して近づけると、今度は出力電圧が上がっていくのがわかるはずである。 どちら側の面が電圧を下げるのかを覚えておこう。 油性ペンで印をつけておくと、次のテストで役に立つ。

Note

注:写真で使っている磁石は直径およそ0.5インチ、高さ0.1インチの丸型だが、四角い磁石でも問題なく使える。重要なのは、ネオジム磁石(レアアース磁石とも呼ばれる)であることである。

次のテストに進む前に、センサーのリード線をワイヤーでつなぎ足して延長する必要がある。 各はんだ付け箇所には熱収縮チューブをかぶせておくと短絡を防げるが、リード線に絶縁テープを軽く巻いておくだけでも十分である。 以下の画像では、センサーの電源プラス側に赤、マイナス側に黒、アナログ出力に黄色のワイヤーを使っている。

はんだごてが温まっているうちに、インダクタにもワイヤーをはんだ付けしておくとよい。 インダクタの2本のピンにそれぞれ異なる色のワイヤーを使っておくと、後でトラブルシューティングする際に役立つ。

制御回路を組み立てる

理論の基礎で触れたとおり、磁石はインダクタの磁場と相互作用できるくらい近い位置にありつつ、磁石自身の磁場だけで(電力にかかわらず)インダクタまで引き上がってしまうほど近すぎない位置に置くことが重要である。 必要なのは、磁石が遠すぎるときはインダクタが磁石を引き寄せ、近づきすぎたら電源を切って重力で引き戻せるようにする、インダクタの制御方法である。

配線を始める前に、インダクタを地面から浮かせて保持するためのスタンドを用意する必要がある。 このガイドではスタンドの作り方自体は扱わないが、参考として使用したスタンドの写真を示す。 インダクタはテーブルからおよそ5インチの高さに吊り下げられており、8-32のボルト(長さ約1.5インチ)とナットでスタンドに取り付けている。

Note

ヒント:磁石がボルトにくっつくことを確認しておくこと。ボルトの鉄材が磁力線をインダクタに「集中」させ、磁石がインダクタの中心へ引き上げられるようになる。

インダクタを取り付けたら、次はホール効果センサーをボルトの頭に取り付ける。 センサーの金属部分が露出している場合は、絶縁テープでセンサーとボルトの間を絶縁し、以下のように絶縁テープでセンサーを固定する。センサーの丸みのある面がインダクタとは反対を向くようにすること。

コンパレータ回路

インダクタを制御するには、コンパレータと呼ばれる構成でオペアンプを使う。これは、ホール効果センサーの出力を、もう一方の入力ピンにつながる基準電圧と比較するものである。 基準電圧は、分圧回路として働くポテンショメータで設定し、0Vから5Vの間で調整可能なアナログ電圧を作り出す。 このポテンショメータの電圧は、磁石がどれだけ離れているかに応じて、ホール効果センサーに読み取らせたい電圧を表している。

この回路では、5V12Vという2つの電圧レールを使う。 12Vレールはインダクタとオペアンプへ電力を供給し、5Vレールは基準電圧とホール効果センサーに使う。 2系統の電源を用意するのが望ましい。12Vレールが電流制限モードに入って電圧が下がってしまうと、ホール効果センサーが磁石の接近を検出するのに十分な電圧を確保できなくなるからである。 とはいえ、LM7805リニア電圧レギュレータを使えば、単一の電源系統でも動作させることはできる。 2系統の電源を使う場合は、グラウンドどうしを必ず接続すること。そうしないと回路が正しく動作しない。

Note

注:回路図ではU2をSS494としているが、より感度の高いSS496を使うべきである。ピン配置は同じである。

コンパレータ回路の回路図

コンパレータ回路のFritzing画像

回路を組み立てたら、マルチメーターで非反転入力(オペアンプのピン2)の電圧を測定し、0Vになるまでポテンショメータのつまみを回す。 次に、磁石をセンサーからおよそ2cm、親指の厚みほど離れた位置に置く。 基本的に、磁石は「スイートスポット」、つまり自力でインダクタまで引き上がってくっついてしまう位置より少し遠い位置に置く必要がある。

オペアンプの出力電圧(ピン1)を見ると、9〜12Vになっているはずである。 磁石をその位置に置いたまま、ポテンショメータをゆっくり回して基準電圧を上げていき、電圧が12Vから0Vへ切り替わるところを探す。 磁石を少し上下させると、オペアンプの出力がハイからロー、ローからハイへと切り替わるはずである。

コンパレータは、2つの入力ピンの電圧を等しく保とうとし、センサーの値が基準値と一致するように出力をハイまたはローに駆動する。 次のステップでは、このオペアンプの出力にインダクタを接続し、実際に磁石を浮上させてみよう。

磁石を浮上させる

コンパレータがインダクタをどう制御するか理解できたところで、実際に磁石を浮上させてみよう。 オペアンプは信号の制御には向いているが、このような大電流の用途にはMOSFETを使う必要がある。 前のセクションで組んだ回路の電源を切り、次の回路を配線する。 ダイオードを省略しないよう注意すること。インダクタの電流を切ると、それまで作っていた磁場が崩れることで大きな電圧スパイクが発生し、MOSFETを壊してしまうことがある。 回路図には1N4007ダイオードと記載されているが、フライバックによる電流スパイクへの対策としては1N5401ダイオードのほうがうまく機能するはずである。

Note

注:回路図ではU2をSS494としているが、より感度の高いSS496を使うべきである。ピン配置は同じである。

インダクタを追加したコンパレータ回路の回路図

インダクタを追加したコンパレータ回路のFritzing画像

電源を切ったまま、ポテンショメータのつまみを片方いっぱいまで回し、基準電圧を5Vに設定する。 次に電源を入れ、オペアンプの出力が0Vになっていることを確認する。 以下の画像のように、磁石を親指と中指の間に挟んで持つ。親指はインダクタに引き上げられた磁石を受け止める役目を果たし、中指は磁石のバランスを取り、落ちてきた場合に受け止める役目を果たす。

もう一方の手で、基準電圧をゆっくりと下げていく。 制御回路を組み立てるで確認した切り替わりのポイントに近づくと、磁石が浮き始めるはずである。 磁石が親指に飛びついてしまう場合は、電圧を再び上げてからもう一度試してみる。 少し練習して、小さく正確な調整を重ねれば、磁石を浮上させられるようになるはずである。

Note

ヒント:磁石の印がインダクタとは反対側を向くようにひっくり返ろうとする場合、磁場が同じ極性になっていて反発し合っている状態である。インダクタの配線を逆にすれば、この問題は解決する。

12V電源からの電流を読み取れるようにしておくと、浮上のポイントを見極めるのに役立つ。 磁石が近すぎるときは、電流はたいてい10mA未満になる。 筆者が使っている磁石では、消費電流はおよそ80mAで、インダクタから2〜3cmの範囲で浮上させることができている。 少し練習すれば、自分の磁石でも浮上させられるようになるはずである。

ワイヤレス給電

磁石を浮かせるだけでは物足りない場合は、ワイヤレス給電のLEDを追加して、さらに複雑さを加えることができる。 このステップには、誰もが持っているとは限らない工具がいくつか追加で必要になる。 このセクションでは、次のものが必要である。

送電コイルを作る

磁石を浮上させるために使ったインダクタは、磁石をその位置に保つのに十分な電力しか供給できない。 電力をワイヤレスで伝送するには、マグネットワイヤーを使って自分でもう一つインダクタを巻く必要がある。 マグネットワイヤーは、細い線に非常に薄い絶縁層を施したワイヤーである。 これにより、通常の被覆ワイヤーで同じ巻数にする場合と比べて、コイルの巻線どうしをより近づけられ、生じるインダクタンスも大きくなる。

ワイヤレス電力伝送は、変圧器(トランス)と同じ原理で動作する。一方のインダクタがもう一方のインダクタに電流を誘導するという仕組みだが、鉄芯を使って磁束を結合させる代わりに、テスラコイルと同じように空気を介して結合させる点が異なる。 ワイヤレス電力伝送の問題の一つは、効率が非常に悪いことである。 トランスの一次側は、二次側にわずかな電力を生み出すために、多くの電力を消費することになる。

一次コイルを作る

一次コイルは、中心直径1インチの円形に、30ゲージのマグネットワイヤーを25回巻いて作る。 エンジニアというものは何も捨てられない性分なので、筆者は片端を切り落とした空のワイヤースプールを使い、マグネットワイヤーを巻き付けてから抜き取った。

コイルがほどけないよう、余分なマグネットワイヤーを少し切り取り、一次コイルの2か所に巻きつけて形を保持できるようにする。 ワイヤーのエナメル被覆のせいで、はんだが乗りにくくなっている。 紙やすりでエナメルを少し削り取れば、以下のようにピンをはんだ付けしたり、コイルから直接ワイヤーをはんだ付けしてブレッドボードまで引き出したりできる。

二次コイルを作る

二次コイルも同じように作るが、今回は100回巻きのマグネットワイヤーを使い、さらにダイオードとコンデンサ2個を使って交流をLED用の直流に変換する。 以下の回路図を参考にしてほしい。

ワイヤレス電力伝送の二次コイルを作るための回路図

一次コイルと同じように、余分なマグネットワイヤーの切れ端を使って二次コイルの形をまとめる。 今回は、LEDのヒートシンクの周りに巻きつけて二次コイルの中心に固定できるよう、少し長めの切れ端を用意する。 両面テープを使って、LEDヒートシンクの底に磁石を固定した。 磁石を配置する際は、印がLEDとは反対側を向くようにすること。

組み立てた二次コイル・上面組み立てた二次コイル・底面

一次側ドライバーを作ってテストする

二次コイルに電流を誘導するには、ファンクションジェネレータ(または周波数発生器)を使って交流信号を生成し、今回作ったインダクタに最適な周波数を見つける必要がある。 浮上回路のオペアンプと同じように、ファンクションジェネレータもあまり大きな電流は取り出せないため、一次コイルを駆動するにはもう一つ別のMOSFETが必要になる。 回路自体はいたって単純で、振幅5V、直流オフセット2.5Vの矩形波を入力する(つまり、5Vのハイと0Vのローを行き来する矩形波が欲しいということである)。 このMOSFETはあっという間にかなり熱くなるため、必ずヒートシンクを取り付けること。

最適な周波数を見つけるため、LCRメーターを使って二次コイルのインダクタンスを測定し、回路図のC1についても正確な値を求め、共振周波数をおよそ80kHzと計算した。 周波数と電源からの消費電流の間にはトレードオフがある。 周波数を下げるほどLEDは明るくなるが、効率は極端に低下し、一次コイルを駆動するMOSFETは非常に熱くなる。 この問題への最良のアプローチは、LEDの明るさを十分に保ちながら、どこまで高い周波数を使えるかを見極めることである。

一次コイルを浮上用インダクタに取り付ける

ワイヤレス電力伝送が動作するようになったところで、ワイヤレス給電の一次コイルを浮上用インダクタに取り付ける。 絶縁テープを使い、先ほど作った25回巻きのインダクタを、ホール効果センサーのある浮上用インダクタの底面に貼り付ける。

新しい浮上距離を見つける

ライトと磁石を合わせた重さは、磁石だけのときよりもかなり重くなっている。 ワイヤレス給電の一次コイルを回路の残りの部分から切り離した状態で、基準電圧のポテンショメータを使って浮上距離を調整する。 質量が増えているため、磁石はかなり近く、およそ1cmまで近づける必要がある。 ポテンショメータの電圧を下げると、浮上距離は短くなる。 ライトが浮上したら、一次コイルを再接続し、ファンクションジェネレータの出力をオン・オフしてLEDを制御できる。

先ほど、この方式は効率が悪いと述べた。では、実際どれくらい悪いのだろうか。 電流を測定するとおよそ50mA、LEDにかかる電圧は2.72Vだったので、回路が受け取っている電力はおよそ136mWである。 電源は12Vに設定されており、磁石が浮上しライトが点灯している状態で、回路は886mA、つまり10.6ワットを消費している。これは効率にして1.3%である。 とはいえ公平を期すなら、浮上回路自体がおよそ450mAを消費しているため、ワイヤレス電力伝送そのものの効率は実質およそ2.5%ということになる。 ワイヤレス給電回路がどの周波数で動作するかがわかったので、ファンクションジェネレータを、555タイマーを使って矩形波を生成する新しい回路に置き換えることもできるだろう。

まとめ

このプロジェクトをさらに発展させる方法の一つが、ワイヤレス電力伝送の効率を高めることである。 インダクタンス、静電容量、抵抗を測定できるLCRメーターが手元にあれば、二次巻線のL1とC1の正確な値を求め、LC共振計算ツールにその値を入力できる。 二次側の共振周波数がわかれば、一次コイルのインダクタンスを測定し、その計算ツールに静電容量の値を出させることができる。 そのコンデンサを一次コイルと並列に追加し、信号発生器をその周波数に合わせれば、効率が向上するはずである。 とりあえず今は、以下のリンクも参考にしてほしい。

さらにアイデアが欲しい場合は、SparkFunの他のチュートリアルも参考にしてほしい(いずれも英語)。

  • HID Control of a Web Page:Webページ上のスライダーを動かしてモーターを回す方法。HTMLとHIDを組み合わせてセンサーを読み取り、現実世界とやり取りする。
  • Interactive Hanging LED Array:72個の電球を、会議室用のインタラクティブなLEDアレイに変えた事例。
  • 21st Century Fashion Kit: Inflation:送風機と薄いプラスチックシートを使い、形や体積が変化するデザインを作る方法。
  • Qwiic Pro Kit Project Guide:はんだ付けもブレッドボードも不要でArduinoを始められるQwiic Pro Kitのガイド。

タグ: 概念、光、プロジェクト、科学、センサー


出典:Magnetic Levitation(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

OBD-II入門

はじめに

組み込み電子工作の世界を歩んでいくと、いずれ車両からデータを「ハック」したくなる場面が出てくる。 他の多くの統合システムと同様、車両との対話にも専用の「言語」がある。 このチュートリアルでは、車両やその他の産業機械が外部と通信するために使う*On-Board Diagnostics(OBD)*仕様の基本を紹介する。

Note

警告:OBD-IIシステムを認証されていない状態に改造することは、連邦法違反とみなされる。ここで提供する情報は、あくまでOBD-II仕様からの読み取りを目的としたものである。ハックは自己責任で行うこと。

OBDとは何か

OBD仕様とは実際のところ何であり、なぜ気にする必要があるのだろうか。 米国環境保護庁(EPA)のWebサイトには、次のように説明されている。

On-Board Diagnostics、通称「OBD」は、1990年のClean Air Act Amendments(大気浄化法改正)で義務付けられた、1996年以降のすべての小型車・トラックに搭載されているコンピュータベースのシステムである。OBDシステムは、排出ガスを制御する部品を含む、エンジンの主要部品の性能を監視するように設計されている。

言い換えれば、OBDは**エンジン制御ユニット(ECU)**の言語であり、排出ガスとエンジン故障への対策を助けるために設計されたものである。

地球を守ることは素晴らしいが(市民科学者のみなさんに拍手を)、これは同時に、車の他の機能にもアクセスし、それらの部品から情報を収集できるということでもある。 これらのプロトコルの扱い方を学べば、ダッシュボードの故障表示灯(MIL)(いわゆるチェックエンジンランプ)がエンジンの問題を知らせているとき、それが何を指しているのかを自分で判断できるようになる。 自分やメカニックが車両の**DTC(診断トラブルコード)**を読み取ったことがあるなら、それはOBD-IIを使っているということである。

残念ながら、プロトコルそのものは一般に公開されていないが(オープンソースであればよかったのだが)、できる限りの情報を集めて整理してみた。

ハードウェア

1996年以降に製造されたすべての車両は、法律によりOBD-IIコンピュータシステムの搭載が義務付けられている。 このシステムには、**データリンクコネクタ(DLC)**を通じてアクセスできる。 これは16ピンのコネクタで、どのピンが実装されているかによって、その車がどのプロトコルで通信しているかがわかる。

1998年式Jeep Cherokeeのデータリンクコネクタに、ピン番号のラベルを付けたもの。

車内では、ダッシュボードの下、運転席の近く、灰皿の周辺など、運転席から工具なしで(つまりパネルを外すためのドライバーなどを使わずに)簡単にアクセスできる場所に設置されている。

用語

先に進む前に、これらのプロトコルで使われる用語をひととおり確認しておこう。

エンジン制御ユニット/電子制御ユニット(ECU)

ECUは、単一のモジュールを指すこともあれば、複数のモジュールの集合を指すこともある。 これらは車両の頭脳にあたり、車のさまざまな機能を監視・制御している。 メーカー標準のものもあれば、再プログラム可能なもの、複数の機能のために数珠つなぎにできるものもある。 ECUのチューニング機能を使えば、エンジンをさまざまな性能レベルや燃費レベルで動作させることができる。 新しい車では、これらはたいていマイクロコントローラとして実装されている。

代表的なECUの種類には、次のようなものがある。

  • Engine Control Module(ECM):エンジンのアクチュエータを制御し、点火タイミング、空燃比、アイドル回転数などに影響する。
  • Vehicle Control Module(VCM):エンジンと車両の性能を制御する、別名のモジュール。
  • Transmission Control Module(TCM):トランスミッションを扱い、トランスミッションフルードの温度、スロットル開度、車輪速度などを処理する。
  • Powertrain Control Module(PCM):たいていECMとTCMを組み合わせたもの。パワートレインを制御する。
  • Electronic Brake Control Module(EBCM):アンチロックブレーキシステム(ABS)を制御し、データを読み取る。
  • Body Control Module(BCM):パワーウィンドウやパワーシートなど、車体側の機能を制御するモジュール。

診断トラブルコード(DTC)

これらのコードは、車両のどこに問題が発生しているかを示すために使われ、SAE(Society of Automotive Engineers)によって定義されている(完全な仕様は有料で入手できる)。 これらのコードは、汎用のものと、車両メーカー固有のものがある。

コードは次のような形式になっている。

XXXXX
  • 1文字目は、エラーコードの種類を示す。
    • Pxxxx:パワートレイン
    • Bxxxx:ボディ
    • Cxxxx:シャシー
    • Uxxxx:クラス2ネットワーク
  • 2文字目は、そのコードがメーカー固有かどうかを示す。
    • x0xxx:政府が定めた標準コード
    • x1xxx:メーカー固有のコード
  • 3文字目は、そのトラブルコードがどのシステムを指すかを示す。
    • xx1xx/xx2xx:空気・燃料の測定系
    • xx3xx:点火系
    • xx4xx:排出ガス系
    • xx5xx:速度・アイドル制御系
    • xx6xx:コンピュータ系
    • xx7xx/xx8xx:トランスミッション系
    • xx9xx:入出力信号・制御系
  • 4〜5文字目は、具体的な故障コードを示す。
    • xxx00〜xxx99:3文字目で定義されたシステムに応じたコード

DTCの一覧(不完全なもの)は、こちらこちらで確認できる。

パラメータID(PID)

これこそが、OBD-IIシステムから実際に取り出せる情報の本体である。 PIDは、確認したいさまざまなパラメータを定義したものであり、DTCにおける3文字目のような役割に近い。

すべてのPIDがすべてのプロトコルでサポートされているわけではなく、メーカーごとに独自のPIDが多数存在することもある。 残念ながら、これらもたいてい公開されていないため、各PIDがどのシステムに対応しているかを調べるには、多くの調査や逆解析が必要になることがある。

複数のモードが用意されており、それぞれのモードには、そのモードで使えるいくつかのPIDの選択肢がある。 より一般的な情報については、PIDのWikiページを参照してほしい。

故障表示灯(MIL)

MILは、車に問題があることを示す、ダッシュボードのあの嫌な小さいランプのことである。 いくつかのバリエーションがあるが、いずれもOBD-IIプロトコルによって検出されたエラーを示している。

“Check-Engine-Light” by IFCAR - Own work. Licensed under Public Domain via Commons

ダッシュボードで見かける可能性のある、もう一つのパターンを紹介する。

“Motorkontrollleuchte” by Benutzer:chris828 - Own work by the original uploader. Licensed under Public Domain via Commons

どちらのランプであっても、ハックしたい気分でもない限り、目にして嬉しいものではない。

OBD-IIのプロトコル

OBD-II仕様には、5種類の通信プロトコルが用意されている。 多くのものごとがそうであるように、メーカーにはそれぞれ好みがあり、自社のプロトコルが最良だと考えている。それがこの種類の多さにつながっている。 それぞれについて簡単に紹介し、DLC上で使われるピンの説明も示す。

SAE J1850 PWM

この信号はパルス幅変調で、41.6kbpsで動作する。 このプロトコルは、主にFord車で使われている。

SAE J1850 PWM

項目説明
BUS +ピン2
BUS -ピン10
12Vピン16
GNDピン4、5
バスの状態BUS +がハイ、BUS -がローに駆動されているときアクティブ
最大信号電圧5V
最小信号電圧0V
バイト数12
ビットタイミング「1」ビット:8µs、「0」ビット:16µs、フレーム開始:48µs

SAE J1850 VPW

このプロトコルはVariable Pulse Width(可変パルス幅)で、10.4kbpsで動作する。 GM車では、たいていこちらの方式が使われる。

SAE J1850 VPW

項目説明
BUS +ピン2
12Vピン16
GNDピン4、5
バスの状態アイドル時はロー
最大信号電圧+7V
判定電圧+3.5V
最小信号電圧0V
バイト数12
ビットタイミング「1」ビット:ハイ64µs、「0」ビット:ハイ128µs、フレーム開始:ハイ200µs

ISO 9141-2

Chrysler車や欧州車、アジア車を使っているなら、これがそのプロトコルである。 10.4kbpsで動作する非同期シリアル通信である。

ISO 9141-2

項目説明
Kライン(双方向)ピン7
Lライン(単方向、オプション)ピン15
12Vピン16
GNDピン4、5
バスの状態Kラインはアイドル時ハイ。ローに駆動されるとアクティブ
最大信号電圧+12V
最小信号電圧0V
バイト数メッセージ:260、データ:255
ビットタイミングUART:10400bps、8-N-1

ISO 14230 KWP2000

これはKeyword Protocol 2000と呼ばれ、こちらも最大10.4kbpsで動作する非同期シリアル通信方式である。 こちらも、Chrysler車や欧州車、アジア車で使われている。

ISO 14230 KWP2000

項目説明
Kライン(双方向)ピン7
Lライン(単方向、オプション)ピン15
12Vピン16
GNDピン4、5
バスの状態ローに駆動されるとアクティブ
最大信号電圧+12V
最小信号電圧0V
バイト数データ:255
ビットタイミングUART:10400bps、8-N-1

ISO 15765 CAN

このプロトコルは、2008年以降に米国で販売されるすべての車両で義務化されている。 ただし、2003年以降の欧州車であれば、CANを搭載している場合もある。 2線式の通信方式で、最大1Mbpsで動作する。

ISO 15765 CAN

項目説明
CAN HIGH(CAN H)ピン6
CAN LOW(CAN L)ピン14
12Vピン16
GNDピン4、5
バスの状態CANHがハイ、CANLがローに駆動されるとアクティブ。信号がフローティングのときはアイドル
CANH信号電圧+3.5V
CANL信号電圧+1.5V
最大信号電圧CANH = +4.5V、CANL = +2.25V
最小信号電圧CANH = +2.75V、CANL = +0.5V
ビットタイミング250kbit/秒 または 500kbit/秒

シミュレータを使う

これらのプロトコルは車両からデータを収集するのに役立つが、試作段階でパソコンやさまざまな電子部品、車の前であちこちに這わせたケーブルに囲まれて作業するのは、かなり面倒である。 幸い、OBD-IIシステムの基本的な試作やテストを行えるシミュレータが数多く存在する。

こうしたプロトコルを扱うのに便利なシミュレータをいくつか手元にそろえている。 新しいものを入手したら、このセクションを随時更新していく。

ECUsim 2000

このECUシミュレータは、ScanTool社によって設計・製造されている。 すべての製品情報は、こちらの製品ページで確認できる。

このシミュレータを使い始めるには、次の接続作業が必要である。

  1. USBケーブルをシミュレータとパソコンに接続し、必要なドライバをインストールする。
  2. OBD-IIケーブルをシミュレータに接続する。
  3. 付属の12V電源でシミュレータに電源を入れる。
  4. シミュレータが設定されているシリアルポートに対して、115200bps、8、N、1シリアルターミナルを開く。
  5. テストしたいプロトコルにシミュレータを設定する。
  6. ECUデバイス(OBD-IIボード、CAN-Busシールド、Raspberry Piなど)を接続する。

これで、バス上で送信されているデータが、ECUリーダー側で受信しているデータと一致しているか(またその逆も)を、シミュレータを使って検証できる。

シミュレータの設定には、さまざまなプログラミングオプションが用意されている。 詳しくはプログラミングマニュアルを参照してほしい。 現在手元にあるバージョンのファームウェアは複数のOBD-IIプロトコルに対応しており、注文内容によって対応状況が変わる。

プログラミングマニュアルには、シミュレータで使えるすべてのコマンドも記載されている。

たとえば、シミュレータが現在どのプロトコルに設定されているかを調べたい場合は、SPIコマンドを使う。 ターミナルでは、次のようになる。

ECUsim 2000のプロトコル設定を読み取る様子。

これは、シミュレータが現在ISO 15765-4プロトコル(別名CAN)に設定されており、IDタイプは11ビット、動作速度は500kbpsであることを示している。

続いて、シミュレータからSparkFun OBD-II UARTボードCAN-Busシールドのようなデバイスへテスト用のデータを送りたい場合は、送信コマンドSOMT <header>, <data>を使う。 たとえば、エンジンの燃圧が100kPaであるというコマンドを送りたい場合、SOMTに続けて燃圧のパラメータID(PID)である0Aを指定し、続けて100の16進値(この場合64)を送信する。

ECUsim 2000経由で燃圧データを送信する様子。

接続に問題がある状態をシミュレートするため、あえてDB9コネクタの固定ネジを締め忘れて接続をフローティングにしたままコマンドを送ると、最初の送信でCAN ERRORというメッセージを受け取る。 このシミュレータでは、これはシミュレータとCANリーダーの間に問題があることを意味する。 しかし接続を直せば、シミュレータはデータを送信できるようになり、何を送信したのかを正確に教えてくれる。なかなか気の利いた仕組みである。

まとめ

OBD-IIプロトコルの基礎と、さまざまな通信ツールの扱い方について理解できたところで、いよいよ自分のプロジェクトを作る番である。

さらに参考になる資料を紹介する(いずれも英語)。

タグ: 通信、概念、ツール


出典:Getting Started with OBD-II(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Raspberry PiでVNCによるリモートデスクトップを使う

はじめに

Raspberry Piをヘッドレス構成(キーボードやマウス、モニタを接続しない構成)で使いたいが、それでもグラフィカルなデスクトップ環境全体にアクセスしたい、という場合にちょうどよい方法がある。 Virtual Network Computing(VNC)というプログラムを使えば、ネットワーク越しにリモートデスクトップへアクセスできる。

学校や個人で、特定のアプリケーション(Scratchや、独自のグラフィカルインターフェースの作成など)のためにデスクトップ環境全体が必要な場合、VNCクライアントを使ってRaspberry Piにアクセスするのがよい選択肢になるだろう。

RealVNCを使ってRaspberry Piのグラフィカルデスクトップにアクセスする様子

朗報として、Raspberry Piの推奨OSであるRaspbianには、標準でRealVNCがインストールされている。 一方で厄介なのは、それを別の手段で有効化する必要があるという点である。

必要な部品

このチュートリアルの内容を実際に試すには、Raspberry Pi、電源、microSDカードが必要である。 モニタ、キーボード、マウスは不要である。

Note

注:プロジェクトをより小型にしたい場合は、Raspberry Pi Zero Wでもこのチュートリアルの内容を試せるはずである。

あると便利な部品

とはいえ、キーボードとマウス、モニタを使ってVNCサーバーを有効化することもできる。 一度有効化してしまえば、(本当に使いたい場合を除いて)これらの周辺機器はもう必要なくなる。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

Note

補足:このチュートリアル中の画像が見づらい場合は、遠慮なくクリックして拡大表示してほしい。

OSを書き込む

Raspberry Piにはいくつかの利用可能なOSがあり、初心者にはNOOBSを使って標準のRaspbianイメージをインストールすることがよく勧められる。 このガイドでは、VNCと組み合わせて使うヘッドレス版のRaspbianを設定する方法を紹介する。 Headless Raspberry Pi Setupチュートリアルの一部の手順に沿って進めるが、今回はフル版に付属するLinuxのXサーバーが必要になるため、Raspbian Liteではなくフル版のRaspbianを使う点に注意してほしい。

まず、最新版のRaspbianをダウンロードする。

最新版のRaspbianをダウンロード

Note

注:このチュートリアルはRaspbian Stretch(2018年6月版)を使って作成されている。異なるバージョンを使う場合、このチュートリアルとは異なる手順が必要になることがある。2018年6月版のRaspbianが必要な場合は、以下からダウンロードできる。 Raspbian Stretch(2018年6月版)ダウンロード(ZIP)

SDカードにイメージを書き込むには、Etcherというプログラムをおすすめする。 ダウンロードしてインストールする。 (必要であればmicroSD USBリーダーを使って)SDカードをパソコンに挿し、Etcherを起動する。 OSのイメージファイルを選択し(zipを展開する必要はなく、ダウンロードした.zipファイルをそのままEtcherで選択すればよい)、SDカードリーダーを選択して、**Flash!**ボタンをクリックする。

VNCを有効化する

VNCサーバーを有効化するには、Raspberry Piを直接操作する必要がある。 そのための方法はいくつかある。

(任意)RealVNCをインストールする

標準では、RaspbianにはVNCサーバー(RealVNC)がインストールされているはずである。 別のOSを使っている場合は、RealVNCを自分でインストールする必要があるかもしれない。 たいていのDebian系OS(Raspbianも土台はDebianである)では、apt-getを使ってRealVNCをインストールできる。 ターミナルで、次のように入力する。

sudo apt-get update
sudo apt-get install real-vnc-server
sudo apt-get install real-vnc-client

VNCサーバーを有効化する

VNCサーバーを有効化するには、Raspberry Piの設定ツールを開く必要がある。

sudo raspi-config

Interfacing Optionを選び、続けてVNCを選ぶ。 次の画面でYesを選び、Enterキーを押して変更を保存する。

パスワードの変更やキーボードレイアウトの変更など、他に必要な設定があれば自由に行ってよい。

raspi-configのホーム画面に戻ったら、右矢印キーを2回押してFinishを選び、Enterキーを押す。

ローカルネットワーク経由でVNCを使う

ホストとなるパソコンがRaspberry Piと同じローカルネットワーク上にある場合(たとえば同じWiFiやイーサネットのネットワークに接続している場合)は、Raspberry Piへ直接VNC接続できる。 この方法にはいくつかの利点がある。もっとも簡単な方法であり、RealVNCのアカウント登録も不要で、インターネットに接続していない閉じたネットワークでも行える。 欠点は、Piにアクセスするには同じネットワーク上にいる必要がある(つまり物理的に接続しているか、VPN経由である必要がある)という点である。 これはダイレクト接続と呼ばれる方式である。

インターネット経由でRaspberry Piにアクセスしたい場合は、次のセクションを参照してほしい。

Raspberry Piのターミナルで、次のコマンドを入力する。

ifconfig

inetの隣に4つの数字の並びとして表示される、Raspberry PiのIPアドレスを控えておく。 WiFiで接続している場合はwlan0の設定の下に、イーサネットで接続している場合はeth0の設定の下に表示される。

ホスト側のパソコンで、RealVNC Viewerのダウンロードページにアクセスし、使用しているOS向けのVNCクライアント(VNC Viewer)をダウンロードする。 すべてデフォルトの設定のままインストールする。

VNC Viewerを開く。上部のアドレスバーに、Raspberry PiのIPアドレスを入力する(ホスト側のパソコンとPiが同じネットワーク上にあることをもう一度確認しておくこと)。

Enterキーを押し、「VNC Server not recognized」という警告が出たらContinueをクリックする。 Authenticationウィンドウが表示されるはずである。 Piのログインユーザー名とパスワードを変更していない場合、デフォルトのログイン情報は次のとおりである。

  • ユーザー名: pi
  • パスワード: raspberry

Note

警告:パスワードは必ず変更することを強くおすすめする。同じネットワークにアクセスできる人であれば、デフォルトのユーザー名とパスワードを試すだけで簡単にPiにアクセスできてしまう。

認証に成功すると、Raspberry Piのグラフィカルデスクトップが表示されるはずである。 これで、まるでキーボードとマウス、モニタを備えたPiの前に座っているかのように、あらゆる操作をリモートで行えるようになる。 ウィンドウ上部にマウスを乗せると、ドロップダウンボックスが表示され、セッションを終了するボタンをはじめ、RealVNCのさまざまな設定にアクセスできる。

インターネット経由でVNCを使う

ローカルネットワーク上でリモートデスクトップを使うほうが、はるかに高速で滑らかな体験になりやすいが、必ずしもそのネットワークに直接アクセスできるとは限らない。 幸い、RealVNCを使えば、インターネット経由でも自分のコンピュータにログインできる。

もう一つの朗報は、PiのIPアドレスを探す手間がかからないという点である。

RealVNCアカウントに登録する

Note

注:RealVNCのクラウドサービスを使うには、同社のサイトでアカウント登録が必要になる。また、クラウド接続サービスが無料なのは非商用・教育目的の利用に限られる点にも注意してほしい。詳しくはRealVNCの料金ガイドを参照してほしい。

まず、RealVNCのサイトでアカウントに登録する(すでにアカウントがあればサインインする)。 Accountページに移動し、Home版のVNC Connectの下にあるActivateをクリックする。

PiでVNCクラウド接続を有効化する

Note

注:この次のステップでは、Raspberry Piのグラフィカルデスクトップにアクセスできる状態が必要である。これには、キーボード・マウス・モニタを使う方法や、ローカルネットワーク経由でVNCに直接接続する方法がある。コマンドラインからVNCクラウド接続を有効化できるのは、RealVNCのEnterprise版のみである。

PiでVNCが有効になっていることを前提に、デスクトップ右上のVNCロゴをクリックする。 RealVNCの設定ウィンドウが開く。 そのウィンドウの右上にあるプロパティボタンをクリックし、**Licensing…**を選択する。

Sign in to your RealVNC accountが選択された状態のまま、Nextをクリックする。

RealVNCのメールアドレスとパスワードを入力し、Sign Inをクリックする。 次の画面で、接続方式をDirect and cloud connectivityに変更する。

Nextをクリックする。設定内容を確認し、Applyをクリックする。 パスワードを求めずに権限が付与されたという警告のポップアップが表示された場合は、Closeをクリックする。 次の画面でDoneをクリックする。

Raspberry Piをリモートで操作する

ホスト側のマシンで、RealVNC viewerをダウンロードしてインストールする。 アプリケーションを開き、右上のSign inボタンをクリックする。 メールアドレスとパスワードを入力し、Sign inをクリックする。

右側に、アドレス帳(過去に使用した接続先)と、「Team」(VNCクラウド接続が可能なコンピュータの一覧)が表示されるはずである。 Teamをクリックすると、VNCの準備が整ったRaspberry Piが一覧に表示されているはずである。

Raspberry Piをダブルクリックして接続する。 Raspberry Pi上のVNCサーバーが確認されたことを説明するポップアップウィンドウが表示されるはずである。 Continueをクリックする。 Authenticationウィンドウが表示されるはずである。 Piのログインユーザー名とパスワードを変更していない場合、デフォルトのログイン情報は次のとおりである。

  • ユーザー名: pi
  • パスワード: raspberry

Note

警告:パスワードは必ず変更することを強くおすすめする。同じネットワークにアクセスできる人であれば、デフォルトのユーザー名とパスワードを試すだけで簡単にPiにアクセスできてしまう。

認証されると、Raspberry Piのデスクトップが表示されるはずである。 ウィンドウ上部にマウスを乗せると、ドロップダウンが表示され、セッションを終了するボタンをはじめ、RealVNCのさまざまな設定にアクセスできる。

もう一つ気の利いた機能として、スマートフォンやタブレットからRaspberry Piを操作することもできる。 iTunes StoreまたはGoogle PlayからVNC Viewerアプリをダウンロードする。 アプリを開いてサインインし、Raspberry Piに接続すればよい。

まとめ

RealVNCについてさらに詳しく知りたい場合は、ドキュメントページを確認することをおすすめする。

RealVNCはRaspbianに標準搭載されているが、Linux向けの他のVNCアプリケーションも存在する。代替の選択肢としては、次のようなものがある。

Raspberry Piにネットワークアクセスの手段がまったくない場合、Pi自身をWiFiアクセスポイントにすることで、独自のネットワークをホストさせることもできる。 これによって、ルーターなどの他のネットワーク機器に頼らずに、別のパソコンからSSHやVNCなどでPiに接続できるようになる。

さらに参考になるチュートリアルを紹介する(いずれも英語)。

タグ: 概念、接続ガイド、IoT、Raspberry Pi、シングルボードコンピュータ


出典:How to Use Remote Desktop on the Raspberry Pi with VNC(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

WiFi経由でセンサーデータを送信する

はじめに

WiFiは誰にとっても馴染み深いものである。 家庭のネットワークを支え、お気に入りの映画をストリーミングさせてくれ、コーヒーショップで他人と話さずに済むようにもしてくれる。 しかし、WiFiの使い道は、さまざまなアプリケーションを通じてインターネットにアクセスするだけにとどまらない。 このチュートリアルでは、独自のピアツーピアネットワークを構築し、ある場所でセンサーからデータを取得して、インターネット接続もルーターも使わずに、別の場所にあるLCD画面へそのデータを送る方法を紹介する。 これは、組み込みの物理コンピューティングの応用先から配線をなくしていくための、素晴らしい第一歩になる。

プロジェクトの概要:温度・湿度・気圧をワイヤレスで監視する

このプロジェクトでは、環境センサーからデータを読み取り、別の場所にあるディスプレイへ送信する、単純なポイントツーポイントの閉じたWiFiシステムを作る。 はんだ付けなしでハードウェアを接続できるQwiic Connectシステムを利用し、できるだけ単純な構成にする。 使用するハードウェアは、ESP32 Thing Plus Wroomモジュール2台、Qwiic Environmental Combo BreakoutSparkFun Qwiic Single RelayQwiicケーブル数本である(もちろん、それぞれに電池やACアダプタなどの電源も必要になる)。

ステップ1:MACアドレスを確認する

WiFi経由でデバイスと通信するには、そのデバイスのMedia Access Control Address、いわゆるMACアドレスを知っておく必要がある。 各デバイスのMACアドレスを調べる、短くて簡単なArduinoスケッチを紹介する。I2Cスニファーの隣にある、便利なArduinoユーティリティスケッチ集の引き出しにしまっておくとよいだろう。

/*
 * MAC Address Finder
 * WiFi対応の各基板でこれを実行すると、
 * MACアドレスを取得できる。これを
 * コードに書き込んでおけば、電源投入時や
 * 再起動後に、手動での操作なしで
 * 各部品を接続できるようになる。
 *
 * コードを書き込んだら、シリアルモニタを開き、
 * 基板のリセットボタンを押して、
 * MACアドレスを書き留めておこう。
 * (筆者はラベルライターで、各基板の裏面に
 * MACアドレスを貼り付けている。)
 */

#include "WiFi.h"

void setup(){
  Serial.begin(115200);

}

void loop(){
  WiFi.mode(WIFI_STA);
  Serial.print("The MAC address for this board is: ");
  Serial.println(WiFi.macAddress());
  while(1){     // ループをここで止め、情報が
    }           // 何度も表示されないようにする
}

コードを書き込んだら、シリアルモニタを開き、基板をリセットして、MACアドレスを書き留めておく。

Note

著者からのヒント:WiFi基板を扱い始めたばかりの頃、MACアドレスを調べて付箋に書き、それぞれの基板に貼り付けていた。もちろんその後、それらをまとめてバッグに放り込み、自宅の作業スペースからSparkFun本社へ移動して取り出してみると、付箋はすべてバッグの底で互いにくっついてしまっていた。まったく使い物にならない。それ以来、各基板の裏面にはラベルライターでタグを貼るようにしている。MACアドレスは変更できることがあるので、基板に油性ペンで直接書き込むのはおすすめしない。

ラベルライターを使えば、恒久的に書き込むことなく各基板にMACアドレスを表示できる。

ステップ2:ハードウェアを接続する

先ほど触れたとおり、SparkFunのQwiic Connectシステムを使った作業は非常に簡単で、このプロジェクトで必要な接続は全部で6か所だけである。 片方のESP32 Thing Plusボード(送信側、つまりサーバー側の基板)にはSparkFun Qwiic Environmental Breakoutを、もう片方のESP32 Thing Plusボード(受信側、つまりクライアント側の基板)にはQwiic 20x4 SerLCD RGB Backlight Displayを接続する。 今回はEnvironmental ComboボードのうちBME280センサーしか使わないため、代わりにAtmospheric Sensor Breakout - BME280を使っても、コードを変更することなくそのまま使うことができる。

Qwiic部品を使えば、このようなプロジェクトを驚くほど手早く簡単に組み立てられる。

ステップ3:コードを書き込む

この例では、データ送信用と受信用の2つのArduinoスケッチを使う。

以下のスケッチをコピーし、Qwiic Environmental Comboを接続した送信側の基板に書き込む。 書き込む前に、スケッチの34行目に受信側基板のMACアドレスを入力しておくこと。たとえば、

uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

は、次のようになる。

uint8_t broadcastAddress[] = {0x94, 0x3C, 0xC6, 0x96, 0x38, 0xB4};

送信側の完全なコード

正しい基板(SparkFun ESP32 Thing Plus)が選択されていることと、正しいCOMポートに接続されていることを確認し、次のスケッチを書き込む。

/* WiFi Peer-to-Peer example, Transmitter Sketch
 * Rob Reynolds, SparkFun Electronics, November 2021
 * This example uses a pair of SparkFun ESP32 Thing Plus Wroom modules
 * (https://www.sparkfun.com/products/15663, a SparkFun Qwiic Environmental
 * Combo Breakout (https://www.sparkfun.com/products/14348), and a SparkFun
 * Qwiic 20x4 SerLCD - RGB Backlight (https://www.sparkfun.com/products/16398).
 *
 * Feel like supporting our work? Buy a board from SparkFun!
 * https://www.sparkfun.com/
 *
 * License: MIT. See license file for more information but you can
 * basically do whatever you want with this code.
 *
 * Based on original code by
 * Rui Santos
 * Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files.
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
*/

#include <esp_now.h>
#include <WiFi.h>

#include <Wire.h>            // I2Cバスでのシリアル通信の確立に使う
#include "SparkFunBME280.h"  // BME280用ライブラリをインストールしておくこと
BME280 mySensor;             // センサーを定義する


// 受信側のMACアドレスに置き換えること
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// 送信するデータの構造体の例
// 受信側の構造体と一致させる必要がある
typedef struct struct_message {
  float a;
  float b;
  float c;
} struct_message;

// myDataという名前のstruct_messageを作る
struct_message myData;

// データ送信時に呼ばれるコールバック
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.print("\r\nLast Packet Send Status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}

void setup() {
  Serial.begin(115200);
  Serial.println("Reading basic values from BME280");

  Wire.begin();

  //**********BME280モジュールのセットアップ**********//
  if (mySensor.beginI2C() == false) //I2C経由で通信を開始する
  {
    Serial.println("The sensor did not respond. Please check wiring.");
    while(1); //停止する
  }

  // デバイスをWi-Fiステーションとして設定する
  WiFi.mode(WIFI_STA);

  // ESP-NOWを初期化する
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // ESPNowの初期化に成功したら、送信状態を取得するため
  // 送信コールバックを登録する
  esp_now_register_send_cb(OnDataSent);

  // ピアを登録する
  esp_now_peer_info_t peerInfo;
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;
  peerInfo.encrypt = false;

  // ピアを追加する
  if (esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    return;
  }
}

void loop() {
  // 送信する値を設定する
  //strcpy(myData.a, "THIS IS A CHAR");
  myData.a = (mySensor.readTempF());
  myData.b = (mySensor.readFloatHumidity());
  myData.c = (mySensor.readFloatPressure());

  // ESP-NOW経由でメッセージを送信する
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));

  // 以下はテスト用で、シリアルモニタでデータを確認するためだけに使う
  Serial.print("Temperature in Fahrenheit: ");
  Serial.println(myData.a);
  Serial.print("Humidity: ");
  Serial.println(myData.b);
  Serial.print("Pressure: ");
  Serial.println(myData.c);

  if (result == ESP_OK) {
    Serial.println("Sent with success");
  }
  else {
    Serial.println("Error sending the data");
  }
  delay(2000); // 2秒ごとにデータを送信する
}

このスケッチの核心は、次の1行(103行目)である。

esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));

受信側基板のMACアドレスはすでに変数broadcastAddress[]に設定してあり、myDataの3つの変数もそれぞれ設定済みなので、esp_now_send()はこれらのmyData変数をすべて受信側基板へ送信する。 (もちろん、ここで使っている3つより多くの値を送ることもできるが、わかりやすさとディスプレイのサイズの都合上、少なめに抑えている。)

これらのスケッチのもとになっているRui Santos氏の元のコードでは、受信側がデータを受信したことを送信側に知らせるための応答を返す。 テスト段階では非常に役立つので、このスケッチでもそのまま残してある。 このスケッチを書き込んだら、シリアルモニタを開いてみよう。 記録されているデータと、「Sent with success」というメッセージが表示されるはずである。 その後には、少し不穏な「Last Packet Send Status: Delivery Fail」というメッセージも表示される。 これはデータを受信する側が何もない状態なので問題ない。 それではその状態を解消しよう。 もう1台のESP32 Thing Plusを用意し、Qwiicコネクタ経由でSerLCDを接続し、次のスケッチを書き込む(COMポートを、この新しい基板のものに変更するのを忘れないこと)。

受信側の完全なコード

/* WiFi Peer-to-Peer example, Receiver Sketch
 * Rob Reynolds, SparkFun Electronics, November 2021
 * This example uses a pair of SparkFun ESP32 Thing Plus Wroom modules
 * (https://www.sparkfun.com/products/15663, a SparkFun Qwiic Environmental
 * Combo Breakout (https://www.sparkfun.com/products/14348), and a SparkFun
 * Qwiic 20x4 SerLCD - RGB Backlight (https://www.sparkfun.com/products/16398).
 *
 * Feel like supporting our work? Buy a board from SparkFun!
 * https://www.sparkfun.com/
 *
 * License: MIT. See license file for more information but you can
 * basically do whatever you want with this code.
 *
 * Based on original code by
 * Rui Santos
 * Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files.
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
*/

#include <esp_now.h>
#include <WiFi.h>

#include <SerLCD.h> //ライブラリはこちらから入手できる:http://librarymanager/All#SparkFun_SerLCD
SerLCD lcd; // デフォルトのI2Cアドレス0x72でライブラリを初期化する


// 受信するデータの構造体の例
// 送信側の構造体と一致させる必要がある
typedef struct struct_message {
    float a;
    float b;
    float c;
    float d;
} struct_message;

// myDataという名前のstruct_messageを作る
struct_message myData;



void setup() {
  // シリアルモニタを初期化する
  Serial.begin(115200);

  // デバイスをWi-Fiステーションとして設定する
  WiFi.mode(WIFI_STA);

  Wire.begin();
  //********** LCDディスプレイのセットアップ **********//
  lcd.begin(Wire); //I2C通信用にLCDを設定する

  lcd.setBacklight(50, 55, 255); //バックライトを明るい白に設定する
  lcd.setContrast(5); //コントラストを設定する。コントラストを上げるには0に近づける。

  lcd.clear(); //表示をクリアする(カーソルもホーム位置に戻る)
  lcd.print(" Current Conditions");
  lcd.setCursor(0, 1);
  lcd.print("Temperature: ");
  lcd.setCursor(0,2);
  lcd.print("Humidity: ");
  lcd.setCursor(0,3);
  lcd.print("Pressure: ");

  // ESP-NOWを初期化する
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // ESPNowの初期化に成功したら、受信パケットの情報を取得するため
  // 受信コールバックを登録する
  esp_now_register_recv_cb(OnDataRecv);
}

void loop() {

}



// データ受信時に実行されるコールバック関数
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
  memcpy(&myData, incomingData, sizeof(myData));

  // LCDディスプレイに何も表示されない場合は、シリアルモニタでの確認用にこれを使う
  Serial.print("Temperature F: ");
  Serial.println(myData.a);
  Serial.print("Humidity: ");
  Serial.println(myData.b);
  Serial.print("Pressure: ");
  Serial.println(myData.c);
  Serial.println();
  lcd.setCursor(13, 1);
  lcd.print(String(myData.a) + (char)223 + " F");
  lcd.setCursor(13, 2);
  lcd.print(String(myData.b) + (char)37);
  lcd.setCursor(13, 3);
  lcd.print(String(myData.c, 1)); // カンマの後の1は、小数点以下1桁までの表示に制限する
}

受信側のスクリプトで注目すべきなのは、onDataRecv()関数の中にあるこの行(86行目)である。

memcpy(&myData, incomingData, sizeof(myData));

これは、受信したデータをmyDataにコピーし、表示できるようにする処理である。 受信側スケッチのデータ構造が、送信側スケッチのデータ構造と一致していることだけ確認しておこう(つまり、送信する各変数のデータ型が、受信側スケッチが期待しているデータ型と一致している必要がある)。

両方の基板にコードを書き込んだら、電源を入れると自動的に接続され、数秒後にはデータが届き始めるはずである。

ルーターを使わずにWiFi経由で通信できるのは、速くて簡単である。

トラブルシューティング

LCDディスプレイに何も表示されない場合や、他に問題が起きているようであれば、いくつか確認できる点がある。 まず、送信側の基板(Environmental Sensorを接続したほう)をUSBケーブルでパソコンに接続し、シリアルモニタウィンドウを開いてみよう。 センサーが正しく動作し、WiFiモジュールがパケットを送信できていれば、シリアルモニタには次のような表示が見えるはずである。

Temperature in Fahrenheit: 74.46
Humidity: 22.21
Pressure: 84992.97
Sent with success

受信側の電源が入っていない場合は、次のようにも表示される。

Last Packet Send Status:   Delivery Fail

ここまで問題がなければ、受信側のESP32をパソコンに接続し、送信側を電池やACアダプタで動作させて、結果を確認してみよう。 シリアルモニタには、温度・湿度・気圧の読み取り値が表示されるはずである。 それでも問題が解決しない場合は、サポートチームに問い合わせてほしい。

まとめ

このプロジェクトの狙いは、データをワイヤレスで送信する方法を示すことにあった。 このチュートリアルが単純である利点は、使用したセンサーボードを、比較的簡単に他の多くのセンサーに差し替えられる点である。 SparkFun Ambient Light Sensorのような別のQwiicセンサーを追加すれば、LCDに表示するデータセットをもう一項目増やすこともできる。 使いたいセンサーの使い方ガイドに目を通してみるのがよい出発点になるだろう。

このプロジェクトで使ったSparkFunの部品についてさらに詳しく知りたい場合は、以下の使い方ガイドを参照してほしい(いずれも英語)。

タグ: 概念、ディスプレイ、ESP32、プログラミング、プロジェクト、Qwiic、センサー、WiFi


出典:Sending Sensor Data Over WiFi(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

外部IOとメタ安定性

はじめに

Alchitryの最初の数本のチュートリアルをすでに読んでいれば、トップレベルモジュールの入出力が、基板上のどこに接続されるのかをどうやって知るのか、疑問に思ったかもしれない。 LEDという名前のどこに、FPGAのどのピンを使うべきかという情報が含まれているのだろうか。 もう疑問に思う必要はない。このチュートリアルでは、制約ファイルの基本を説明し、設計の中で外部信号を使うことに潜む危険についても掘り下げていく。

必要な部品

このチュートリアルは主に概念的な内容だが、実際に手を動かしたい場合は、AlchitryのFPGA開発ボード(Alchitry CuまたはAlchitry Au/Au+)が必要になる。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

Note

注意:Alchitryの基板を扱ったことがない場合は、このチュートリアルを続ける前に、Alchitryの公式サイトでセットアップを済ませておく必要がある。

制約ファイル

制約ファイルは、FPGA固有の特定の設計制約を指定するために使う。 制約ファイルの扱い方には現時点で標準規格がなく、FPGAメーカーごとに異なる機能を提供したいという事情がある。

ピンの割り当て

制約ファイルのもっとも一般的な用途は、トップレベルの入力や出力を物理的なピンに割り当てることであり、これを簡単に行えるよう、Alchitry LabsはAlchitry Constraint FileACF)という形式をサポートしている。 これらは非常にシンプルな構文で、AuでもCuでも同じように使える。

どちらの基板でも新しいプロジェクトを作ると、プロジェクトナビゲータのConstraintsという見出しの下に、alchitry.acfというファイルが見つかる。 このファイルには、基板の基本的なピン配置の定義が含まれている。 これは、Alchitry PWMチュートリアルで作成したプロジェクトのAlchitry Constraint Fileである。

PWM Blinkerプロジェクトのacfファイル

このファイルの中身を詳しく見ると、次のような内容(あるいはそれによく似た内容)が確認できる。

pin clk CLOCK;
clock clk 100MHz;

pin rst_n RESET;

pin led[0] LED0;
pin led[1] LED1;
pin led[2] LED2;
pin led[3] LED3;
pin led[4] LED4;
pin led[5] LED5;
pin led[6] LED6;
pin led[7] LED7;

// Tx/Rxのラインを入れ替える
pin usb_rx USB_TX;
pin usb_tx USB_RX;

ピンの割り当てを定義する構文はpin signal PIN;であり、signalはトップレベルモジュールにおける入力または出力の名前、PINは接続する物理ピンを指す。 ピン名の後、セミコロンの前に任意でpullupまたはpulldownというキーワードを付け加えることもでき、オンチップのプルアップ抵抗またはプルダウン抵抗を有効にするかどうかを指定できる。これらは入力に対してのみ有効である。 なお、Cuはプルダウンをサポートしておらず、このキーワードは無視される点にも注意してほしい。

Alchitry Labsは、RESETLED0のような、基板上の信号を表す特別なピン名をいくつか定義している。 これらは、AuとCuで異なる物理ピンに対応しているにもかかわらず、ツール側が使うべきピンを把握してくれるため便利である。

外部に引き出されているすべてのIOピンにも、バンクの文字とピン番号を組み合わせた形式の、わかりやすい名前が付けられている。

Br Elementのピン配置は、次のようになっている。

Br Elementのピン配置。PDFはこちらからダウンロードできる。

USBポートを左側にして基板を見たとき、バンクAは左上のコネクタ、バンクDは右下のコネクタにあたる。基本的に、リファレンスシートと同じレイアウトになっている。

たとえば、バンクAのピン2を使いたい場合、ピン名にはA2を使う。 この名前は、AuでもCuでも同じである。 これらの名前は、ツールによってFPGAチップの物理ピンへとマッピングされる。

各四角形の左上部分はCuのピンの機能、右下部分はAuのピンの機能に対応している。 1つのピンに複数の用途がある場合、これらの半分がさらに分割されて表示されることもある。

たとえば、ピンA20はAuでは差動信号として使えるが、Cuではシングルエンド信号としてしか使えない。 ピンB2は、Auではアナログ入力または差動信号として使えるが、Cuではシングルエンド信号としてしか使えない。

なお、差動IOはすべて、シングルエンドIOとしても使うことができる。

バンクAとBは、AuでもCuでもすべてのピンが実装されているが、バンクCはCuでは一部のピンしか実装されておらず、バンクDはほとんどが特殊信号用になっている。

リファレンスシートの後半は、バンクDの信号マッピングを示している。 たとえば、D14はAuとCuの両方でUSB Tx信号にあたる。

アナログ信号とデュアル電圧セレクト信号はすべてAuにのみ存在し、Cuでは何にも接続されていない(四角形の左上が黒く表示されていることで示されている)。

クロックの定義

設計の中にクロック入力がある場合、そのクロックがどれだけの速さで動作するかをツールに伝える必要がある。 これもAlchitry Constraint Fileの中で、clock signal frequency;という構文で指定できる。

基板に内蔵されたクロックについては、clock clk 100MHz;という記述で100MHzであることを指定している。

これは、設計がどれだけの速さで動作する必要があるかをツールに伝えるために重要である。 これがなければ、ツールは設計を配置する際にどのようなタイミング要件を満たせばよいのか把握できない。

その他の制約ファイル形式

さらに高度な制約を指定したい場合は、Au向けにはXilinx固有、Cu向けにはLattice固有の制約ファイルをプロジェクトに追加することもできる。

Auのプロジェクトを作ると、実際にはau.xdcというXilinx Design Constraintファイルがすでにプロジェクトに含まれている。 このファイルには、使用する電圧に関する情報や、FPGAの設定を保持するフラッシュメモリに関する情報が記載されている。

本格的に踏み込んで理解したい場合は、Xilinxのドキュメントを参照するか、次のリンクからダウンロードできる。

Vivado Design Suite User Guide - Using Constraints

通常、本当に高度なことをしない限り、これらを直接いじる必要はない。

Latticeの制約は、PCFファイルとSDCファイルに分かれている。 PCFはphysical constraint file(物理制約ファイル)の略でピン配置の定義に使い、SDCはclock design constraint(クロック設計制約)の略でクロック周波数の定義に使う。

詳しくは、iCEcube2 User Guide、特に5章と6章を参照してほしい。

Note

注意:Lattice Semiconductors社のiCEcube2は、現在は無料のツールセットではなくなっている。代わりに、Alchitry Labs 2にバンドルされているオープンソースのツールセットYosysを使うことをおすすめする。

繰り返しになるが、Alchitryの制約ファイルを使っている限り、これらを自分で書く必要はないはずである。

メタ安定性

これで設計のピン配置を定義する方法がわかったので、次は外部信号を使うことに潜む危険について見ていこう。

設計の大部分では、信号はFPGAの内部で始まり、内部で終わる。 このような場合、ツールはタイミングを正確に管理し、すべてが期待どおりに動作することを保証してくれる。 しかし外部信号は制御できないため、特別な配慮をしないと、設計全体が予期しない振る舞いをすることがある。

これは、**メタ安定性(metastability)**と呼ばれる現象によって起こる。

メタ安定性とは、きちんとした0と1で動作しているはずのデジタルシステムが、その中間のどこかで止まってしまったり、値の間を発振してしまったりする状態のことである。

これは、DFF(Programming an FPGAチュートリアルで扱った)が前提としている特定の条件に違反したときに起こりうる。

その主な前提は、DFFのD入力が、クロックの立ち上がりエッジの前後、一定時間にわたって安定しているというものである。 立ち上がりエッジの前に必要な時間をセットアップ時間、後に必要な時間をホールド時間と呼ぶ。

このウィンドウの間にD入力が変化すると、DFFはその値を正しく取り込めず、不安定な状態になることがある。

これを図示すると、次のようになる。

クロックの最初の2つのエッジの周辺ではDの遷移が起きていないため、Dの値は正しく保存され、Qに出力される。 しかし最後のエッジでは、立ち上がりエッジの近くで遷移が起きているため、出力が予測できなくなっている。

この問題への一番簡単な解決策は、単純にセットアップ時間とホールド時間のウィンドウを守ることである。 これは、SPIのようなクロック同期のバスを使う場合には実現できる。 しかし、クロックに同期していない信号では、いつ信号が変化するかを予測したり制御したりすることはできない。

ユーザーにボタンを押してもらう際、1秒間に1億回訪れるごく小さなウィンドウを避けてもらおうとするようなものだと想像してみてほしい。それは不可能である。

この問題への回避策は、2個以上のDFFを鎖状につなぐことである。

これによって、2段目のDFFの出力が不安定になる可能性は大幅に減る。 ただし、入力にわずかな遅延が加わることにはなる。 重要なのは、これによってメタ安定性の問題そのものが解決するわけではないという点である。あくまで、問題が実際に発生する確率を劇的に減らしているにすぎない。 チェーンにさらにDFFを追加すれば発生確率はさらに下がるが、その効果はすぐに小さくなっていくため、たいてい2段あれば十分である。

コンポーネントライブラリには、入力を同期させるために使えるpipelineというコンポーネントがある。 Miscellaneousのカテゴリの中にある。 これは、入力をパラメータで指定した段数のDFFに通してから出力するだけのものである。

module pipeline #(
    DEPTH = 1 : DEPTH > 0 // ステージ数
  )(
    input clk,  // クロック
    input in,   // 入力
    output out  // 出力
  ) {

  dff pipe[DEPTH] (.clk(clk));
  var i;

  always {
    // inはパイプの先頭に入る
    pipe.d[0] = in;

    // outはパイプの末尾
    out = pipe.q[pipe.WIDTH-1];

    // それぞれの中間ステージについて
    for (i = 1; i < DEPTH; i++)
      pipe.d[i] = pipe.q[i-1]; // 前段の値をコピーする
  }
}

これまでのチュートリアルで、リセット信号を整える(当然そうだろう)ためにreset_conditionerというコンポーネントが使われていたことに気づいたかもしれない。

このコンポーネントは、2つのことを担っている。 1つ目は、リセットボタンの信号をクロックに同期させること。 2つ目は、リセット信号が最低限の時間ハイの状態を保つようにすることである。 この2つの条件は、信号がクリーンであることと、FPGA全体が同じタイミングでリセットから抜け出すことを保証するために重要である。

module reset_conditioner #(
    STAGES = 4 : STAGES > 1 // ステージ数
  )(
    input clk,  // クロック
    input in,   // 非同期リセット
    output out  // 同期済みリセット
  ) {

  dff stage[STAGES] (.clk(clk), .rst(in), #INIT(STAGESx{1}));

  always {
    stage.d = c{stage.q[STAGES-2:0],0};
    out = stage.q[STAGES-1];
  }
}

この仕組みはなかなか巧妙である。 4個のDFFを鎖状に接続し、最初のDFFのD入力には常に0を与えておく。 生のリセット信号を使って、これら4個のDFFを1にリセットする。 リセットによって強制的に1にされていない間は、最初の4クロックサイクルの間は1を出力し、その後は出力をローに落として、設計の残りの部分が通常どおり動作できるようにする。 つまり、リセット信号は少なくとも4クロックサイクルの長さを持ち、クロックに同期した形で終わることになる。

この設計は、XilinxのホワイトペーパーGet Smart About Reset: Think Local, Not Globalによるものである。 これは一読の価値がある資料で、リセットの設計について論じているだけでなく、リセットを使うことのコストについても触れている。 基本的に、あるDFFをリセットする必要がないなら、そのDFFにリセット信号を接続すべきではない。 余計な配線リソースを消費し、設計を複雑にするだけである。 設計がリセットされたとき、ほとんどすぐに既知の値が代入されるため、値そのものが問題にならないDFFも多い。

複数のクロック

メタ安定性の問題に遭遇するもう一つの場面は、クロックドメインをまたぐときである。 これは、設計の中に周波数の異なる複数のクロックがある場合に起こる。 33MHzで駆動されているDFFの出力を、100MHzで駆動されているDFFへ単純に接続することはできない。 タイミング条件に違反する瞬間が必ず生じ、悪い結果を招く。

クロックドメインをまたぐには、いくつかの方法がある。 1つ目は、先ほどと同じようにチェーンを使う方法である。 これはもっとも簡単な方法だが、複数ビットの信号や急速に変化する信号には向いていない。 単一ビットのフラグに使うのがもっとも適している。

より堅牢だが複雑な解決策は、非同期FIFOを使う方法である。 これは、独立したクロックで動作する読み出しポートと書き込みポートを持つFIFOである。 あるクロックドメインからFIFOに値を書き込み、別のクロックドメインからそれを読み出すことができる。

これはコンポーネントライブラリのMemory/Asynchronous FIFOにある。

これらはクロックドメイン間でデータをやり取りするのに非常に有効だが、オーバーフローしないよう、書き込みと同じくらいの速さでデータを読み出す必要がある。

可能であれば、もっとも良い方法は複数のクロックを使わないことである。 設計の一部を意図的に遅く動作させたい場合、たいていはカウンタを使って何かを行うタイミングを刻めばよいだけである。 これなら、タイミング要件の管理はすべてツールに任せたままにできる。

とはいえ、これが常に可能とは限らず、クロックドメインをまたぐ必要がある場合は、多少の追加の配慮が必要になる。

まとめ

Alchitryのウェブサイトには、チュートリアルやプロジェクト、Alchitryフォーラムなど、さらに役立つ資料がそろっている。

ユーザーガイドとホワイトペーパー:

FPGAとLucidの世界にさらに深く踏み込みたい場合は、Justin Rajewski氏による“Learning FPGAs: Digital Design for Beginners with Mojo and Lucid HDL”もおすすめである。

FPGA関連のチュートリアルや製品は今後も充実させていく予定である。次のようなチュートリアルもぜひ確認してほしい(いずれも英語)。

タグ: Alchitry、概念、FPGA


出典:External IO and Metastability(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

FPGAをプログラムする

はじめに

このチュートリアルでは、FPGA向けの設計を作るとはどういうことか、そしてそこで使う基本的な構成要素について、基礎を扱う。 本題に入る前に、一つだけはっきりさせておきたいことがある。FPGAを「プログラムする」というのは、実は正確な表現ではない。 テキストを書き、そのテキストがバイナリファイルに変換され、そのバイナリファイルがFPGAに読み込まれるという流れが、なんとなくプログラミングのように感じられるため、便宜的に「プログラムする」と言うことが多いだけである。

しかし、実際に書いているのはプログラムではない。作っているのは回路である。 回路を作るのにプログラミング言語は使わない。使うのは**ハードウェア記述言語(HDL)**である。

大規模で複雑な設計を回路図として描いていては、あまりにも複雑になりすぎてしまう。 そこで、回路に望む振る舞いを記述し、それを実際にどう実装するかはツールに任せることになる。

FPGA向けの設計を作る際に忘れてはならないのは、自分が記述しているのはハードウェアであり、書いたものは最終的に物理的な回路になるという点である。 実装が不可能な回路を記述してしまうこともあれば、一見単純に見えて、実装には膨大なリソースを必要とする回路を記述してしまうこともある。

このため、自分が記述しようとしている回路が実際にどう実装されうるかを、しっかりとイメージしておくことが極めて重要である。

必要な部品

このチュートリアルの内容を試すには、AlchitryのFPGA開発ボード(Alchitry CuまたはAlchitry Au/Au+)が必要になる。手元にあるものによっては、すべてが必要になるとは限らない。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

Alchitryの他のチュートリアルも参考になるだろう。

設計の構造

HDLはたいてい、モジュールという考え方を中心に構成されている。 モジュールとは、いくつかの入力と出力を持ち、それらをつなぐ何らかのロジックを含んだ回路ブロックのことである。 モジュールはサブモジュールを含むこともあれば、単独で完結していることもあり、プログラムが関数に分割されるのとよく似ている。

設計全体を1つのモジュールに詰め込むことも不可能ではないが、設計の各部分をそれぞれ小さなモジュールで表すほうが、望ましい設計方法である。 プロジェクトをモジュールに分割することで、ある時点で取り組んでいる部分の複雑さを抑えられる。 中には、よく使われる共通の処理を行うモジュールとして作り、何度も再利用されるものもある。

設計に着手する際は、さまざまなモジュールとそれらがどうつながっているかを示すブロック図を描いておくと役立つことが多い。 これによって設計の範囲が定まり、論理的に分解しやすくなる。

いったん書き始めてしまうと、設計全体の流れを大きく変更するのは難しくなるため、全体のアーキテクチャについては、書き始める前にできるだけ計画を練っておくほうがよい。

Lucid

このチュートリアルの残りの部分では、Lucidを使う。 LucidはFPGA専用に作られたHDLであり、VerilogやVHDLなど他のHDLによくある落とし穴の多く(実際、本当にたくさんある)を取り除くように設計されている。

Note

注意:Alchitryの基板を扱ったことがない場合は、このチュートリアルを続ける前に、Alchitryの公式サイトでセットアップを済ませておく必要がある。

Lucidは、FPGAに触れ始めるのに最適な場所である。 Lucidに縛られてしまうことを心配したり、何らかの理由でいきなりVerilogやVHDLに飛び込みたがったりする人からよく連絡をもらう。 初めて触れるのであれば、Lucidから始めるべきである。他の扱いにくいHDLと格闘する前に、ハードウェア設計の正しい基礎を学べるはずである。

いずれ別の言語に乗り換えたくなったとしても、それほど難しくはない。 Lucidはおおまかにverilogをもとにしており、自分の作った洗練されたモジュールを他の場所で使いたい場合、Alchitry LabsがLucidをVerilogに変換してくれる。

前置きはこのくらいにして、モジュールを構成する要素について見ていこう。

モジュールの構造

どんな設計を作る場合でも、トップレベルモジュールというものが存在する。 これは、その入力と出力が実際にFPGAのピンにおける入出力そのものになる、特別なモジュールである。 Alchitryのプロジェクトでは、使用している基板(CuかAu)に応じて、それぞれcu_top.lucまたはau_top.lucという名前になる。

どちらの基板でも、初期状態のトップレベルモジュールはほぼ同じ見た目である。

module au_top (
    input clk,              // 100MHzクロック
    input rst_n,            // リセットボタン(負論理)
    output led [8],         // ユーザーが制御できる8個のLED
    input usb_rx,           // USB→シリアル入力
    output usb_tx           // USB→シリアル出力
  ) {

  sig rst;                  // リセット信号

  .clk(clk) {
    // reset_conditionerは、リセット信号をFPGAのクロックに同期させるために使う。
    // これにより、FPGA全体が同じタイミングでリセットから抜け出せる。
    reset_conditioner reset_cond;
  }

  always {
    reset_cond.in = ~rst_n; // 反転させた生のリセット信号を入力する
    rst = reset_cond.out;   // 整えられたリセット信号

    led = 8h00;             // LEDを消灯する

    usb_tx = usb_rx;        // シリアルデータをそのまま返す
  }
}

ポート宣言

モジュールの最初のセクションは、ポート宣言である。 ここで、モジュールへの入力と出力を宣言する。

今回はトップレベルモジュールなので、これらは基板そのものの信号である。

    input clk,              // 100MHzクロック
    input rst_n,            // リセットボタン(負論理)
    output led [8],         // ユーザーが制御できる8個のLED
    input usb_rx,           // USB→シリアル入力
    output usb_tx           // USB→シリアル出力

led入力の後ろに角括弧で数字が付いていることに気づいたかもしれない。 これによって、1つではなく8個の個別の入力が、配列としてひとまとめになる。 配列の構文については、後ほど詳しく扱う。

モジュールには、モジュールをカスタマイズするためのパラメータのリストを持たせることもできる。 このリストはここでは省略されている。トップレベルモジュールでは、パラメータは親モジュールがそれをインスタンス化する際に渡すものなので、意味を持たないからである。 インスタンス化(instantiation)という用語は、モジュールや他のリソースを設計に追加することを指す。 つまり、そのモジュールや他のリソースのインスタンスが作られるということである。

コードを書く場合、関数を呼び出すたびに、その関数が何回呼ばれても同じ命令の並びが繰り返し使われる。 しかし、モジュールをインスタンス化するたびに、そのモジュールを構成する回路全体が複製される。 同じリソースを複数のタスクで使い回したい場合、それをどう調整するかは設計者自身の仕事になる。

インスタンス化と言えば、たいてい、モジュールが必要とするものはポート宣言のすぐ後でインスタンス化する。

最初の行では、sigキーワードを使って信号を宣言している。

  sig rst;                  // リセット信号

信号はメモリではない。値を保持することはない。 これはワイヤ(配線)だと考えるとよい。ワイヤには値が乗ることはあるが、実質的にはある点から別の点への接続にすぎない。

この設計では、信号rstを、reset_conditionerモジュールの出力のプレースホルダーとして使っている。 このモジュールをインスタンス化しているのが、次の数行である。

 .clk(clk) {
    // reset_conditionerは、リセット信号をFPGAのクロックに同期させるために使う。
    // これにより、FPGA全体が同じタイミングでリセットから抜け出せる。
    reset_conditioner reset_cond;
  }

何かをインスタンス化するには、単純にそのリソースの名前の後に、この特定のインスタンスの名前を続けて書く。 つまり、reset_conditioner reset_cond;という行は、reset_conditionerモジュールのreset_condという名前のインスタンスを作る。 このインスタンス化を包んでいるブロックは、接続ブロックと呼ばれる。 このブロックを使うと、複数のモジュールが持つ、ある共通の名前の入力やパラメータを、まとめて同じ信号に接続できる。

今回の場合、入力clkを、信号clk(自分のモジュールへの入力)に接続している。 構文は.port(signal)であり、portはインスタンス化するモジュール側の入力の名前、signalはそこに接続する信号である。

reset_conditionerモジュールにはclkという名前の入力があるため、この入力は自分のモジュールの信号clkに直接接続される。

これは、次のようにインスタンス化の行で直接接続することもできる。

reset_conditioner reset_cond(.clk(clk));

ここでそうしなかったのは、入力clkはほとんどすべてのモジュールに共通して存在するため、このようなブロックを用意しておけば、他にもclkに接続する必要のあるインスタンス化を簡単に追加できるようになるからである。

ほとんどすべてのモジュールにはclk入力があり、たいていはリセット用のrst入力もある。 クロックとリセットが具体的に何に使われるかは、後ほど説明する。

同じ接続ブロックに複数の接続を追加することもできる。

.clk(clk), .rst(rst) { … }

ブロックをネストさせることもでき、clkを使うすべてのブロックがrstも使うわけではないため、たいていモジュールの冒頭では次のような形がよく見られる。

.clk(clk) {
    // clkのみを使うインスタンス化
    .rst(rst) {
        // rstとclkの両方を使うインスタンス化
    }
}

alwaysブロック

次のセクションはalwaysブロックである。これがモジュールの核心部分にあたる。

alwaysブロックには、モジュール内で起きるロジックをすべて記述する。 ここには組み合わせ論理と呼ばれるものが含まれる。 組み合わせ論理とは、出力が現在の入力だけの関数になっているデジタル回路のことである。 内部状態やメモリを持たない。 わかりやすい例は加算回路である。出力は、現在入力されている2つの数値だけによって決まる。 以前に入力されていた数値や、何回数値を変更したかは関係ない。出力は常に現在の入力の関数である。

alwaysブロックの中には、文を書いていく。 文は主に4種類ある。代入if文case文forループである。

代入

代入はもっともよく使われるものである。 左側に何らかの信号を置き、等号を挟んで式を書く。

signal = expression;

これらの力の源は、式にある。 ここでは、ビットを操作するためのさまざまな演算子が使える。 +-、***のような数学演算子も含まれる。 特に注意が必要なのは、除算の/で、式が動的な場合は使えないという点である。 これは、除算があまりにも複雑で、ツールが妥当なデフォルトの実装を自動的に用意できないためである。 除算自体は不可能ではないが、少し余計な手間と計画が必要になる。

if文

if文は、典型的な形をしている。

if (expr) { … } else { … }

ifに続く式が真(0以外)であれば、最初の行の並びが有効になる。 偽(0)であれば、elseブロックの行が有効になる。elseの部分は省略できる。

「有効になる」と言ったのであって、「実行される」とは言っていない点に注目してほしい。 if文やforループがあると、つい従来のプログラミングの発想に引きずられてしまいがちである。

if文は、ハードウェア上ではたいていマルチプレクサとして実現される。 何らかの式に基づいて、2つの入力のどちらかを単純に選んでいるだけである。

alwaysブロックの中で信号に値を代入する場合、条件がどうであれ、必ず値が代入されている必要がある。 つまりたいてい、if文の中である信号に値を代入したら、そのelse側にも対応する代入を用意しておく必要がある、ということになる。

この規則の唯一の例外は、dffやfsm型のd入力である。これらについては後述する。

常に値が代入されるようにするもう一つの方法は、alwaysブロックの冒頭で、妥当なデフォルト値を設定しておくことである。 次の疑似コードを見てみよう。

led = 0;
if (button_pressed)
    led = 1;

ボタンが押されていないとき、ledの値は0である。 では、ボタンが押されたときはどうなるだろうか。ledはいったん0が代入され、その後1に更新されるのだろうか。いや、そうではない。

ボタンが押されているとき、ledは常に値1を持つ。alwaysブロックの中で後に書かれた代入は、それより前の代入より優先される。

このブロックは、常に、そして瞬時に評価されていると考えるとよい。

では、if文の前にデフォルト値がなかったとしたらどうなるだろうか。 ボタンが押されていないとき、ledはどんな値を持つだろうか。 以前の値をそのまま保持すると思いたくなるかもしれないが、信号は値を保持できないということを思い出してほしい。信号は単純に2点をつなぐワイヤのようなものである。

デフォルト値を0にしておけば、これをハードウェア上ではマルチプレクサとして実現できる。

この単純な例では、led信号とbutton_pressed信号をそのままつなぐだけでも同じ動作を実現できる。

case文

case文は、次のような構文になる。

case(expr) {
    value: statement;
    value: statement;
    default: statement;
}

これはif文とまったく同じように動作するが、1つの式に対して多くの分岐を持たせる場合に、より単純に書ける方法である。 case文のvalueの部分は、何らかの定数でなければならない。 省略可能なdefault分岐は、それ以外すべてを受け止める役割を果たす。

通常のコードとは異なり、case文はif文を何個も並べる場合と比べて、性能上の利点はない。 あくまでコードのわかりやすさと利便性のためのものである。

forループ

最後にforループである。Lucidのforループは、CやJavaのforループと同じ構文を使うが、いくつか制限がある。

for (init; eval; increment) { … }

たいてい、回路には直接現れないが記述の中で使う値を保持するためのvar型と一緒に使われる。

ハードウェアにおけるforループの大きな制約は、繰り返し回数が定数でなければならないという点である。

これは、ツールがループを展開できる必要があるためである。 forループは、そのコード部分をコピー&ペーストで何度も繰り返し書くのと実質的に変わらないが、読みやすさの点でずっと優れている。 明確な理由がない限り、forループは避けるべきである。 forループを使うと、非常に大きく遅い回路をうっかり作ってしまいやすい。

数値

Lucidには、数値定数を定義する方法がいくつかある。もっとも簡単な方法は、単に14のように数字を書くことである。

単独の数字を見た場合、それは10進数(基数10)として扱われ、負の数でない限り、符号なし形式で表現するのに必要な最小限のビット数が使われる。

使用するビット数をより細かく制御したい場合は、数字の前にxdxは使用したいビット数)を付ける。 たとえば、8d14は、10進数の14を8ビットで表したものになる。

dの代わりにhを使えば16進数(基数16)、bを使えば2進数(基数2)になる。 どちらの形式でも、文字の前にビット数を指定できる。

ビット数を省略した場合、16進数はデフォルトで1桁あたり4ビットが使われる。 たとえば、h08は2桁で書かれているため8ビットが使われる。値8自体は4ビットで表現できるにもかかわらずである。

2進数の場合、ビット数を明示的に指定しなければ、単純に桁数がそのままビット数になる。 つまり、b101001は6ビット幅になる。

10進数をd付きで書きつつビット数を省略した場合、dを省略したときとまったく同じ扱いになる。

配列

トップレベルモジュールのled入力のように、扱う信号の多くは複数ビットの信号になる。

配列内のビットには、signal[bit]という構文で個別にインデックスを付けてアクセスできる(bitは何らかの式)。 これが動的な値の場合、常に配列の範囲内に収まることを保証するのは、自分自身の責任である。

[max:min]という配列構文を使えば、ビットの部分集合にアクセスすることもできる。 ここでは、minからmaxまでの範囲(両端を含む)のビットが選択される。 この構文を使う場合、両方の値とも定数である必要がある。

ビットの部分集合を動的に選びたい場合は、[start+:width]という構文を使うことができる。 ここでstartは選択する最下位ビット、widthはそこから上に向かって選択するビット数(startビット自身を含む)である。 この構文では、widthだけが定数である必要がある。 [start-:width]というわずかに異なる構文も使え、こちらはstartが最下位ではなく最上位ビットになる。

Lucidの配列は多次元にすることもできる。 宣言する際は、次のように次元を追加していくだけでよい。

sig my_array[dim1][dim2][dim3];

配列のすべての次元は、定数値で宣言する必要がある。

その後は、これまでと同じセレクタを使って配列にインデックスを付けられる。 ただし、サブ配列の選択は最後のセレクタとしてしか使えない点に注意してほしい。

順序論理とDFF

ここからが本当に面白いところである。組み合わせ論理は非常に重要だが、状態やメモリをまったく持たないシステムはかなり限られたことしかできない。

では、どうやってメモリを作るのだろうか。基本的には、何らかのフィードバックループが必要になる。 カウンタを作りたい場合、単純に直前の加算結果に1を足せばよい。

問題は、このループをどう制御するかである。 一見すると何の問題もないように思えるかもしれないが、深く考えていくと、次々と問題が明らかになっていく。

カウンタの例を見てみよう。

入力の片方を1に固定した加算器を使えば、これを作ることができる。 わかりやすさのため、これを1つのブロックにまとめておく。 その入力を出力に接続すれば、インクリメントするカウンタが作れるだろうか。

ここでいくつか疑問を投げかけてみよう。このカウンタはどんな値から始まり、どれだけの速さでカウントするのだろうか。

初期値は、回路にどう電源が投入されたか、回路がどうレイアウトされたかによって決まる。 おそらく、温度やその他の環境要因にも左右されるだろう。 天気によって回路の挙動が変わってしまうのは、誰も望まないはずである。

さらに悪いことに、この回路はそもそも正しく動作しない。 これは、加算回路が、複数ビットの出力を持つ他の多くの組み合わせ論理と同様に、途中の結果として誤った値を生成するからである。 加算器の場合、最下位ビットが最初に計算され、それに続く各ビットは、その前のビットの計算結果を使って計算される。

この結果が有効になるのを待つ仕組みが何もないため、途中の誤った値がそのまま加算器にフィードバックされ、さらに多くの誤った値を生み出し続け、最終的にはただのゴミを生成するだけの回路になってしまう。

では、これをどう解決すればよいだろうか。 単純に、フィードバックループのタイミングを制御する方法が必要になる。 ここで役立つのが、DFF、つまりD型フリップフロップである。

DFFが正確に何なのかを掘り下げる前に、クロックとは何かを説明しておこう。 クロックとは、単純に、ある一定の周波数で0と1を繰り返し切り替える信号のことである。

Alchitryの基板上のクロックは100MHz、つまり1秒間に1億回切り替わる。 この規則的な信号を使うことで、回路に時間の感覚を与えることができる。

0から1への遷移は立ち上がりエッジと呼ばれ、たいてい信号の中でもっとも重要な部分である。 これらのエッジは、上の画像では矢印で示されている。

DFFの話に戻ろう。

DFFは一種のメモリである。 入力Dと出力Qを持つ。 クロック入力が0から1に変化すると、その瞬間のDの値が保存され、次のクロックの立ち上がりエッジまでQに出力され続ける。

クロックの立ち上がりエッジとエッジの間でDが変化しても、Qの値は変わらないままである。

上の図では、DFFに任意のイネーブル信号とリセット信号も添えて示している。 イネーブルは、立ち上がりエッジでDFFが新しい値を取り込むのを止めるために使うことができる。 リセット信号は、Qの値を既知の値に強制するために使う。 FPGA上のDFFは、0または1にリセットされるよう設定できる。

このDFFを使って、カウンタのループを制御することができる。

これで、リセット信号を使って初期値を、たとえば0に設定できる。つまり、Qが0であることがわかっている。Qが0であれば、Dは1になる。

クロックの立ち上がりエッジで、QはDの値を取得する。つまりQは1になり、それによってDは2になる。

立ち上がりエッジのたびに、Qは1ずつ増えていく。これこそまさに求めていたものである。

クロックの周波数が、カウンタが増加する速さを決める。

もちろん、これにはいくつかの制約もある。 クロックは、Qが変化した後にDが更新される時間を確保できるくらい、十分に遅くなければならない。 加算器が生成する無効な途中結果の1つを、DFFに保存させたくはない。

加算器の出力値が有効になるまでに必要な時間は、伝播遅延と呼ばれる。 これは、入力の変化から出力が有効かつ安定するまでにかかる時間である。

追加するロジックが増えるほど、この遅延は長くなる。 遅延はまた、回路の製造に使われる技術の関数でもある。 ツールは各FPGAのモデルを持っており、使用するクロック周波数を伝えれば、タイミング要件が満たされるように設計のレイアウトを試みてくれる。

この例では、組み合わせ論理のブロックをループする1組のDFFを使っている。 より一般的なのは、あるDFFの組の出力を組み合わせ論理のブロックに通し、別のDFFの組へ送るという、パイプラインを作る形である。

どんな設計でも、もっとも長い伝播遅延がクロックの最大周波数を決める。 設計をおおむね均等な処理時間の組み合わせ論理ブロックに分割することで、クロック周波数を最適化できる。

タイミングの細かい話はかなり複雑になりうるが、たいていの設計では、設計全体で同じクロックを使い、法外に長い経路さえなければ、あとはツールがうまく処理してくれる。 100MHzであれば、DFFの間でかなり多くのことができる。 問題になりやすいのは、あまりに多くのものを1つの経路に鎖状につないでしまったり、大量の乗算を含めてしまったりした場合である。

FPGAのリソースの限界に近づくにつれて、タイミング要件を満たすのも難しくなっていく。 ツールが同じサイズのFPGAにより多くのものを詰め込む必要が出てくると、レイアウトの選択肢が減っていき、タイミング要件を満たせなくなることがある。

LEDを点滅させる

ここまでの内容をすべて組み合わせて、LEDを点滅させるデモプロジェクトを作ってみよう。

Note

注意:Alchitryの基板を扱ったことがない場合は、このチュートリアルを続ける前に、Alchitryの公式サイトでセットアップを済ませておく必要がある。

新しいプロジェクトを作る

Alchitry Labsで新しいプロジェクトを作り、From Exampleのドロップダウンから「Base Project」を選ぶ。

画像をクリックすると拡大表示できる。

ツールバーの新規ファイルアイコン(一番左のアイコン)をクリックし、blinker.lucという名前で新しいLucidソースファイルを作る。

画像をクリックすると拡大表示できる。

これで、次のような基本的なモジュールが作成される。

module blinker (
    input clk,  // クロック
    input rst,  // リセット
    output out
  ) {

  always {
    out = 0;
  }
}

画像をクリックすると拡大表示できる。

デフォルトのモジュールテンプレートには、クロックとリセットの入力、そして現時点では何もしない出力が追加されている。

LEDを点滅させるには、LEDの状態を切り替えるためのカウンタを作る必要がある。 単純にクロックサイクルごとにLEDの状態を切り替えるだけでは、あまりに速く点滅しすぎて目には見えないだろう。

クロックとリセット用の接続ブロックを設定しておき、その中にDFFを宣言できる。

  .clk(clk) {
    .rst(rst) {
      dff ctr[27];
    }
  }

これによって、ctrという名前の27個のDFFからなる配列が作られる。 これをalwaysブロックの中で使うように配線できる。

  always {
    ctr.d = ctr.q + 1;
    out = ctr.q[26];
  }

モジュールやDFFの信号にアクセスするには、ドット表記を使う。 alwaysブロックの最初の行は、DFFのD入力を、Q出力に1を足したものに接続している。 これによって、ctr.qの値はクロックサイクルごとに1ずつ増えていく。

なお、d信号は書き込み専用、qは読み取り専用である。

2行目は、もっとも上位のビットである26番目のビットを取り出し、出力に接続している。 ctrは27ビット幅なので、インデックスは0から26まである。

ctrはクロックサイクルごとに1ずつ増加するため、27ビットの数は2^27 = 134,217,728通りの値を保持でき、クロック周波数が100MHzなので、ctrはおよそ1.34秒ごとにオーバーフローする。

このサイクルの前半では、最上位ビットは0になる。後半では1になる。 このビットを出力に接続することで、0.67秒ごとに出力を切り替えることになる。

ここでトップレベルモジュールに戻り、新しく作ったモジュールをインスタンス化しよう。 筆者はAuを使っているが、Cuでもモジュールの見た目は同じで、名前だけau_topではなくcu_topになる点に注意してほしい。

module au_top (
    input clk,              // 100MHzクロック
    input rst_n,            // リセットボタン(負論理)
    output led [8],         // ユーザーが制御できる8個のLED
    input usb_rx,           // USB→シリアル入力
    output usb_tx           // USB→シリアル出力
  ) {

  sig rst;                  // リセット信号

  .clk(clk) {
    // reset_conditionerは、リセット信号をFPGAのクロックに同期させるために使う。
    // これにより、FPGA全体が同じタイミングでリセットから抜け出せる。
    reset_conditioner reset_cond;

    .rst(rst) {
      blinker myBlinker;
    }
  }

  always {
    reset_cond.in = ~rst_n; // 反転させた生のリセット信号を入力する
    rst = reset_cond.out;   // 整えられたリセット信号

    led = c{7b0, myBlinker.out};

    usb_tx = usb_rx;        // シリアルデータをそのまま返す
  }
}

ここでは、リセット信号用の接続ブロックを追加し、blinkerモジュールのmyBlinkerという名前のインスタンスを作った。

そして、alwaysブロックの中で、連結構文を使ってそれをled出力に接続している。

c{…}の中の要素は、つなぎ合わされて1つの配列になる。 つまり今回の場合、7個の0とmyBlinker.outのビットを連結している。 これによって、上位7個のLEDは消灯したままになり、blinker信号が最初のLEDに接続される。

これで、ハンマーのアイコンをクリックしてプロジェクトをビルドし、下向きの塗りつぶし矢印アイコンを押して基板に書き込むことができる。

画像をクリックすると拡大表示できる。

これで、一番上のLEDが1秒よりわずかに遅い間隔で点滅しているはずである。

モジュールの改良

このblinkerモジュールは、もっと使いやすくなるように、かなり改良できる。

まず、現状ではLEDの点滅間隔が少し中途半端である。 5000万までカウントしてからLEDを切り替えるようにすれば、これをちょうど1秒にできる。

そのためには、LEDの状態を保持するためのDFFがもう一つ必要になる。

  .clk(clk) {
    .rst(rst) {
      dff ctr[28];
      dff led;
    }
  }

alwaysブロックの中で、ctr.qが49,999,999になったかどうかを確認できるようになった(0から49,999,999までで5000万回のインクリメントになる)。もしそうなら、0にリセットしてLEDを切り替える。

  always {
    ctr.d = ctr.q + 1;
    if (ctr.q == 49999999) {
      ctr.d = 0;
      led.d = ~led.q;
    }

    out = led.q;
  }

ここでは、ビット単位の反転演算子**~**を使っている。これは信号のすべてのビットを反転させる。 led.qは1ビットしかないので、単純にそのビットを反転させるだけである。

先ほど、信号はDFFを除いて、すべての場合に値を代入する必要があると述べたことを覚えているだろうか。 DFFは実際に値を保存できるため、あるクロックサイクルでd入力に値を代入しなければ、そのDFFの値は変化しない。

このモジュールは、ctrに0〜49,999,999の値しか保存しなくなったが、それでも配列は28ビットのままである。 これらの値を保存するには26ビットあれば十分なので、無駄がある。 単純に配列のサイズを26に変更してもよいが、最大値を変更したいたびに、この値を毎回計算し直さなければならなくなる。

その代わり、Lucidの関数を使ってこれを計算させることができる。 *$clog2(50000000)*を使えば、与えられた値の底2の対数の切り上げを計算してくれる。 これは「これだけの組み合わせを保存するには何ビット必要か」という問いに相当する。 今回の場合、これは26と評価される。

dff ctr[$clog2(50000000)];

最大値を変更する話が出たところで、モジュールを編集して、これをパラメータとして受け取れるようにし、インスタンス化の際に指定できるようにしよう。

これは、モジュールにパラメータリストを追加することで実現できる。これはポートリストの前に置く。

module blinker #(
    MAX_VALUE = 50000000 : MAX_VALUE > 0
  )(
    input clk,  // クロック
    input rst,  // リセット
    output out
  ) {

ポートリストは#(param, param, param)という構文で指定する。 各パラメータは、単純な名前(すべて大文字)だけのこともあれば、この例のように複雑になることもある。

この例では、5000万というデフォルト値を設定している。 インスタンス化のたびに値の指定を強制したい場合を除いて、デフォルト値を設定しておくのはたいてい良い考えである。

デフォルト値の代入の後には、そのパラメータが満たすべき条件を指定できる。 この条件では、そのパラメータ自身や、それより前に宣言されたパラメータを使うことができる(そして使うべきである)。 この条件は「真」と評価される必要がある。もしそうならなければ、インスタンス化の際にエラーが報告される。 これによって、パラメータの値についてある程度の前提を置いたモジュールを書きつつ、その前提が必ず守られることを保証できる。

これで、モジュール内の50,000,000という記述をすべてMAX_VALUEに置き換えられる。

module blinker #(
    MAX_VALUE = 50000000 : MAX_VALUE > 0
  )(
    input clk,  // クロック
    input rst,  // リセット
    output out
  ) {

  .clk(clk) {
    .rst(rst) {
      dff ctr[$clog2(MAX_VALUE)];
      dff led;
    }
  }

  always {
    ctr.d = ctr.q + 1;
    if (ctr.q == MAX_VALUE-1) {
      ctr.d = 0;
      led.d = ~led.q;
    }

    out = led.q;
  }
}

ここでプロジェクトをビルドして書き込むと、LEDは1秒に1回のペースで点滅するはずである。

しかし、トップレベルモジュールに戻り、インスタンス化の部分を次のように変更することもできる。

blinker myBlinker(#MAX_VALUE(25000000));

こうしてプロジェクトをビルドして書き込むと、今度はLEDが1秒に2回点滅するようになる。

まとめ

というわけで、ここまでの内容がすべてである。 FPGAの設計は、すべての処理を行う組み合わせ論理のブロックと、値を保持しデータの流れを制御するDFFから成り立っている。

設計そのものはモジュールに分割されている。 モジュールは他のモジュールから使うことができ、パラメータを持たせてインスタンス化のたびにカスタマイズすることもできる。 モジュールがインスタンス化されるたびに、その回路はFPGA内で複製される。

ハードウェアを設計する際は、その設計がどう実装されうるかを考え、効率的な回路を作ることが重要である。

先ほどのblinkerの例で言えば、点滅の間隔を気にしないのであれば、最初のバージョンのモジュールのほうがはるかに少ないリソースで実装できる。 これは、カウンタの値を確認するための比較器が不要だからである。単純に1を足し続け、2進数の加算が自然にオーバーフローする性質を利用してカウンタをリセットしているだけである。

さらに詳しく

うまくいけば、これでFPGA向けの設計に何が関わってくるか、ある程度感覚がつかめたはずである。 Alchitryのウェブサイトには、チュートリアルやプロジェクト、Alchitryフォーラムなど、さらに役立つ資料がそろっている。

FPGAとLucidの世界にさらに深く踏み込みたい場合は、Justin Rajewski氏による“Learning FPGAs: Digital Design for Beginners with Mojo and Lucid HDL”もおすすめである。Amazonで購入でき、FPGAの理解から、最終的に自分で設計するところまでを学べる優れた資料である。

FPGA関連のチュートリアルや製品は今後も充実させていく予定である。次のようなチュートリアルもぜひ確認してほしい(いずれも英語)。

タグ: Alchitry、概念、FPGA


出典:Programming an FPGA(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

最初のFPGAプロジェクト:PWMを使いこなす

はじめに

Alchitry Au+Alchitry AuAlchitry Cuのいずれかの基板を初めて購入すると、デフォルトのFPGA構成によって、LEDに洒落た波のようなエフェクトが表示される。 このチュートリアルでは、これと似たようなものを作るための手順を、一つずつたどっていく。 設計へどう取り組むか、そしてハードウェアを扱ううえで考慮すべきさまざまな点について、素晴らしい概観になるはずである。

さっそく、これがどう動作しているのか見ていこう。

Alchitry LabsですでにLucidを使ってAlchitry AuまたはCuで作業するためのツールをセットアップ済みであることを前提として進める。 また、基礎を押さえるため、前回のチュートリアルFPGAをプログラムするにも目を通しておいてほしい。

必要な部品

このチュートリアルの内容を試すには、AlchitryのFPGA開発ボード(Alchitry CuまたはAlchitry Au/Au+)が必要になる。手元にあるものによっては、すべてが必要になるとは限らない。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

パルス幅変調

FPGA固有の話に入る前に、パルス幅変調(PWM)とは何かを手早く確認しておく必要がある。

PWMは、デジタルシステムがアナログ値を近似するために使う手法である。 特定のデューティ比を持つパルスの列を作ることで、これを実現する。 デューティ比とは、単純に信号がハイである時間の割合のことである。 デューティ比100%は、完全にオンの信号にあたる。デューティ比50%は、ハイとローがちょうど半々になる。

以下は、デューティ比33%のPWM信号の例である。

これらのパルスの周波数が十分に高ければ、用途によっては、ハイとローの中間の値を出力しているかのように見えることがある。 これは、LEDの明るさを変化させるのに便利である。

LEDは実際には非常に高速にオン・オフを切り替えられるため、PWM信号を与えるとちらついて見える。 幸い、十分な速さでちらつかせれば、人間の目はそれを平均化し、暗いながらも点灯し続けているように見える。 この効果は残像現象(persistence of vision)と呼ばれる。

パルスを作る

入力値を受け取り、その値に比例したデューティ比を持つPWM信号を生成するモジュールを作る必要がある。

これは、カウンタを使えば比較的簡単に実現できる。

自由に動作し続けるカウンタ、つまり常にインクリメントし続けるカウンタがあれば、そのカウンタの状態に応じて出力を設定するのに使うことができる。

カウンタと比較しているしきい値がカウンタの現在の値より大きければ1を、そうでなければ0を出力すればよい。図にすると、次のようになる。

ここでは、比較値がカウンタの最大値の1/3になっているため、デューティ比は33%である。

比較値を変えれば、デューティ比も変わる。

比較値を増やしたことで、デューティ比が66%になった。

これを実現する単純なモジュールを作ることができる。

module pwm #(
    COMP_LENGTH = 8 : COMP_LENGTH > 0
  )(
    input clk,  // クロック
    input rst,  // リセット
    input compare[COMP_LENGTH],
    output pwm
  ) {

  .clk(clk) {
    .rst(rst) {
      dff counter[COMP_LENGTH];
    }
  }

  always {
    counter.d = counter.q + 1; // 自由に動作し続けるカウンタ
    pwm = counter.q < compare;
  }
}

このモジュールを使ってLEDの明るさを制御することもでき、それなりにうまく動作するはずである。 とはいえ、いくつか問題がある。

グリッチ

まず、このモジュールはグリッチフリーではない。 LEDの場合、これは問題にならない。 しかし、サーボのように各パルスの幅そのものが重要になる用途では、これは重要な問題になる。

グリッチフリーとはどういう意味だろうか。 現在のカウンタの値が25で、現在の比較値が10だとしよう。 カウンタが比較値より大きいため、出力は現在ローになっている。 では、ここで比較値を30に変更したらどうなるだろうか。5サイクル分の長さのパルスが出力されてしまう。

しかし、5サイクル分のパルスなど、一度も要求していない。要求していたのは、10サイクルのパルス、そして30サイクルのパルスだけである。

これを修正するには、カウンタが最大値に達したときにだけ比較値を更新するようにする必要がある。 それまでは、現在の比較値をDFFに保存しておく必要がある。

 module pwm #(
    COMP_LENGTH = 8 : COMP_LENGTH > 0
  )(
    input clk,  // クロック
    input rst,  // リセット
    input compare[COMP_LENGTH],
    output pwm
  ) {

  .clk(clk) {
    .rst(rst) {
      dff counter[COMP_LENGTH];
      dff last_comp[COMP_LENGTH];
    }
  }

  always {
    counter.d = counter.q + 1; // 自由に動作し続けるカウンタ
    pwm = counter.q < last_comp.q;
    if (&counter.q)
      last_comp.d = compare;
  }
}

見てのとおり、今度は生の入力である比較値ではなく、last_comp.qとカウンタを比較している。 last_compの値は、counter.qがすべて1、つまり最大値になったときにだけ、入力の比較値で更新される。

counter.qが最大値かどうかを確認するために、リダクション演算子と呼ばれるものを使っている。 ここではAND演算のリダクション演算子を使っている。 値の前に&を付けると、その値のすべてのビットが互いにANDされる。 これは、すべてのビットが1のときにだけ1を返す。

同様に、パイプ記号|を使えばOR演算にもできる。これは、いずれかのビットが1であれば1を返す。

XOR版はキャレット^を使い、1の数が奇数個であれば1を返す。

==による比較の代わりにリダクション演算子を使うのが便利なのは、このような場合、counter.qの幅がパラメータとして指定されているためである。 その最大値は幅によって変わるが、最大値は常に「すべてのビットが1」のときになる。

これで、compareをいつどんな値に変更しても、このモジュールは要求どおりの幅のパルスしか出力しなくなる。

プリスケーラ

次の問題は、パルスの周波数を調整できないという点に関わる。 周波数は単純に、クロックの速さとカウンタの幅によって決まってしまう。

これはLEDにとって実際に問題になる。オン・オフを切り替えるたびに、配線上の寄生容量を充放電するのにわずかな電力が無駄になるからである。 周波数が高すぎると、この寄生損失が支配的になり、LEDの明るさが落ちてしまう。 パルスの周波数は、目に見えない程度に十分速くしつつ、必要以上に速くしすぎないようにしたい。 200Hz程度がちょうどよい。

8ビットのカウンタでは、現在の動作周波数は100MHz/256 = 390.6kHzであり、目標よりおよそ2000倍も速い。

これを調整するには、プリスケーラを追加すればよい。 これは、一定の周期数ごとにメインのカウンタをインクリメントさせるための、2つ目のカウンタである。

もっとも単純で効率的な方法は、メインのカウンタに余分なビットをいくつか追加し、その最上位ビットだけを見るようにすることである。 末尾に1ビット追加するだけで、実質的にレートが2分の1になる。2ビットなら4分の1、というように2のべき乗で下がっていく。

module pwm #(
    PRESCALER = 11 : PRESCALER >= 0,
    COMP_LENGTH = 8 : COMP_LENGTH > 0
  )(
    input clk,  // クロック
    input rst,  // リセット
    input compare[COMP_LENGTH],
    output pwm
  ) {

  .clk(clk) {
    .rst(rst) {
      dff counter[COMP_LENGTH+PRESCALER];
      dff last_comp[COMP_LENGTH];
    }
  }

  always {
    counter.d = counter.q + 1; // 自由に動作し続けるカウンタ
    pwm = counter.q[PRESCALER+:COMP_LENGTH] < last_comp.q;
    if (&counter.q)
      last_comp.d = compare;
  }
}

プリスケーラとして使うビット数を表すPRESCALERというパラメータを追加した。 これはCOMP_LENGTHに加算され、カウンタの幅になる。

比較の部分では、start-width形式のビットインデックス構文を使い、PRESCALERから上に向かってCOMP_LENGTHビットを選択している。 PRESCALERが0、COMP_LENGTHが8であれば、これは[0+:8]となり、ビット0〜7が選択される。 PRESCALERが11であれば、[11+:8]となり、ビット11〜18が選択される。

トップ値

プリスケーラを追加することで、周波数を大まかに調整する手段が手に入り、LEDの制御には十分である。 しかし、用途によってはより具体的な周波数が必要になることもある。 そのためには、カスタムのトップ値を設定できるようにする必要がある。

トップ値とは、単純に、カウンタがリセットされる値のことである。 これまでの例では、この値はカウンタが保持できる最大値であり、自動的にリセットされていた。

if文を追加してカウンタの値を確認し、手動でリセットすることで、周波数を上げることができる。

module pwm #(
    PRESCALER = 11 : PRESCALER >= 0,
    COMP_LENGTH = 8 : COMP_LENGTH > 0,
    TOP = $pow(2,COMP_LENGTH)-1 : TOP >= 0 && TOP < $pow(2,COMP_LENGTH)
  )(
    input clk,  // クロック
    input rst,  // リセット
    input compare[COMP_LENGTH],
    output pwm
  ) {

  .clk(clk) {
    .rst(rst) {
      dff counter[COMP_LENGTH+PRESCALER];
      dff last_comp[COMP_LENGTH];
    }
  }

  always {
    counter.d = counter.q + 1; // 自由に動作し続けるカウンタ
    if (counter.q == TOP) {    // TOPに達したら
      counter.d = 0;           // カウンタをリセットする
      last_comp.d = compare;   // そして比較値を保存する
    }

    pwm = counter.q[PRESCALER+:COMP_LENGTH] < last_comp.q;
  }
}

このバージョンでは、TOPというパラメータを追加し、そのデフォルト値を最大値に設定した。

2^COMP_LENGTHの値を計算するために、*$pow()関数を使った。 前回のチュートリアルで使った$clog2()*と同様、この関数は論理合成の際に計算され、実際の設計には含まれない。 そのため、既知の定数値に対してしか使うことができない。

また、last_compの更新タイミングも、「すべて1」のときではなく、カウンタがTOPに達したときに変更した。

これで、本格的なPWMモジュールが完成したが、実のところ、これをわざわざ自分で書く必要はなかった。

コンポーネントライブラリ

Alchitry Labsには、PWMのようなよくある処理を行うための、プロジェクトに追加できる組み込みコンポーネントが数多く用意されている。

Note

注意:Alchitryの基板を扱ったことがない場合は、このチュートリアルを続ける前に、Alchitryの公式サイトでセットアップを済ませておく必要がある。

Project→Add Componentsを選び、コンポーネントライブラリを開く。

ここから、LED EffectsのカテゴリでPWMを選択できる。

Addをクリックして、プロジェクトにこのコンポーネントを追加する。

プロジェクトツリーのComponentsの下に見つかるはずである。

module pwm #(
    WIDTH = 8 : WIDTH > 0, // PWMカウンタの分解能
    TOP = 0   : TOP >= 0,  // カウンタの最大値
    DIV = 0   : DIV >= 0   // クロックのプリスケーラ
  )(
    input clk,          // クロック
    input rst,          // リセット
    input value[WIDTH], // デューティ比の値
    input update,       // 新しい値であることを示すフラグ
    output pulse        // PWM出力
  ){

  .clk(clk) {
    .rst(rst) {
      counter ctr(#SIZE(WIDTH), #DIV(DIV), #TOP(TOP));
      dff curValue[WIDTH];
      dff needUpdate;
    }
    // nextValueにはリセットは不要
    dff nextValue[WIDTH];
  }

  always {
    // ctr.valueが0で、更新が必要な場合
    if (!|ctr.value && needUpdate.q) {
      curValue.d = nextValue.q; // 新しい値を設定する
      needUpdate.d = 0;         // これで更新は不要になる
    }

    // valueが有効な場合
    if (update) {
      nextValue.d = value; // 保存しておく
      needUpdate.d = 1;    // 更新が必要というフラグを立てる
    }

    // カウンタが設定された値未満なら1を、
    // そうでなければ0を出力する
    pulse = ctr.value < curValue.q;
  }
}

このバージョンは、一点を除いて、これまで作ってきたものと非常によく似ている。 比較値として使われる入力valueは、updateが1のときにのみ有効であることを前提としている。

これによって、いつでも新しい値を指定できるようになり、その値は、実際に比較値として使えるようになるまで保存される。

このコンポーネントは実際には別のコンポーネント、つまりカウンタを利用しているという点でも、いくつか違いがある。 このcounterコンポーネントが、プリスケーリングとトップ値でのリセットを代わりに処理してくれている。

LEDをパルス点灯させる

コンポーネントライブラリのPWMモジュールを手に入れたので、LEDをパルス状に点灯させる新しいモジュールを作ることができる。

LEDをパルス点灯させるには、PWMモジュールに与える値を、最小値と最大値の間でゆっくりと振動させる必要がある。 話を単純にするため、三角波を使うことにする。サイン波のような凝った波形を使うこともできるが、はるかに複雑になってしまう。

三角波というのは、最大値まで直線的に増加し、その後最小値まで直線的に減少する、という繰り返しのカウンタ値を生成することを意味する。

では、どうすれば効率よく三角波を作れるだろうか。 自由に動作し続けるカウンタは、鋸歯状波、つまり最大値まで直線的に増加し、そこから一気に最小値へ飛ぶ波形を生成する。

このカウンタを少し手を加えるだけで、目的の波形を作るのに利用できる。 まず、上の画像でグレーに塗られた領域に注目してほしい。これは、カウンタのMSBが1になっている部分である。

カウンタからMSBを取り除くと、次のような波形になる。

周波数が2倍になり、最大値が半分になっていることに注目してほしい。

しかし、この塗られた領域を反転させることができれば、目的の三角波が得られる。

これで理想的な形にはなったが、カウンタの値をどうやって反転させればよいだろうか。 一つの方法は、単純にカウンタの値を最大値/2から差し引くことである。 しかし、これには非常に効率の良い、2進数ならではの近道がある。

値を差し引く代わりに、カウンタのビットを単純に反転させるだけで、同じ結果が得られる。 たとえば0〜7を数えているとき、最初の3つの数は000、001、010である。 ビットを反転させると、これらは111、110、101、つまり7、6、5になる。 各ビットを反転させるだけで、カウントアップからカウントダウンへと変えることができる。

これをモジュールとしてまとめると、次のようになる。

module pulse (
    input clk,  // クロック
    input rst,  // リセット
    output led  // LEDへの出力
  ) {

  .clk(clk) {
    .rst(rst) {
      pwm pwm(#WIDTH(8), #DIV(11));  // PWMコンポーネント
      dff ctr[27];                   // カウンタ
    }
  }

  always {
    led = pwm.pulse;    // PWMの出力をLEDに接続する

    ctr.d = ctr.q + 1;  // カウンタをインクリメントする

    pwm.update = 1;     // 常に更新する

    // 三角波をPWMモジュールに接続する
    pwm.value = ctr.q[ctr.WIDTH-2-:pwm.value.WIDTH] ^ pwm.value.WIDTHx{ctr.q[ctr.WIDTH-1]};
  }
}

反転を行っている行には新しい構文が使われているので、詳しく見ていこう。

まず、PWMの値として使うカウンタのビットを選ぶ必要がある。 これはカウンタの上位8ビットだが、値を反転させるかどうかの判定に使っている最初の1ビットは除く。

Lucidのすべての信号には、WIDTHという定数が関連付けられている。 これを使えば、その信号が何ビットで構成されているかを取得できる。 つまり、この場合ctr.WIDTHは27である。 ctr.WIDTH-2を使えば、2番目のMSBを取得できる。

そしてpwm.value.WIDTHを使えば、pwmのvalue入力の幅を取得できる。 down-to構文を使い、ctr.WIDTH-2から下に向かってpwm.value.WIDTHビット分のctr.qを選択できる。

そして、^演算子を使ってビット単位のXORを行っている。 この演算子は、同じ次元を持つ2つの信号を受け取り、対応するビットどうしをXORする。 これを使う理由は、ある値を0とXORすればその値がそのまま返るが、1とXORすればその値が反転するからである。

カウンタのMSBを、pwm.valueと同じビット数だけ複製する必要がある。 これには複製演算子を使う。これはnum x{ value }という形式を取り、numはvalueを複製する回数である。

numxの間の空白は省略可能だが、たいてい省略して書かれる。

この行は、WIDTHの定数を使わずに、数値を使って次のように書くこともできた。

pwm.value = ctr.q[25-:8] ^ 8x{ctr.q[26]};

しかし、WIDTHの定数を使うことで、コードの他の部分を変更することなく、カウンタやpwmコンポーネントの長さを変更できるようになる。

このモジュールをトップレベルモジュールに追加すれば、LEDを駆動できる。

module au_top (
    input clk,              // 100MHzクロック
    input rst_n,            // リセットボタン(負論理)
    output led [8],         // ユーザーが制御できる8個のLED
    input usb_rx,           // USB→シリアル入力
    output usb_tx           // USB→シリアル出力
  ) {

  sig rst;                  // リセット信号

  .clk(clk) {
    // reset_conditionerは、リセット信号をFPGAのクロックに同期させるために使う。
    // これにより、FPGA全体が同じタイミングでリセットから抜け出せる。
    reset_conditioner reset_cond;

    .rst(rst) {
      pulse pulse;
    }
  }

  always {
    reset_cond.in = ~rst_n; // 反転させた生のリセット信号を入力する
    rst = reset_cond.out;   // 整えられたリセット信号

    led = pulse.led;        // LEDをpulseモジュールに接続する

    usb_tx = usb_rx;        // シリアルデータをそのまま返す
  }
}

これをビルドして基板に書き込むと、最初のLEDがゆっくりとパルス点灯しているはずである。

波を作る

ここからは、8個すべてのLEDを互いにタイミングをずらしてパルス点灯させ、波のエフェクトを作る必要がある。 これは、それぞれのカウンタの初期値を異なる値に設定することで実現できる。

DFFにはINITという名前のパラメータがある。 このパラメータを使うと、FPGAの設定時、あるいはDFFにリセット信号がある場合はリセット時に、DFFへ代入される値を設定できる。 デフォルトでは、INITは0に設定されている。

pulseモジュールにINITIAL_VALUEというパラメータを作り、これをDFFへ渡すことができる。

module pulse #(
    INITIAL_VALUE = 0 : INITIAL_VALUE >= 0 && INITIAL_VALUE < $pow(2,9)
  )(
    input clk,  // クロック
    input rst,  // リセット
    output led  // LEDへの出力
  ) {

  .clk(clk) {
    .rst(rst) {
      pwm pwm(#WIDTH(8), #DIV(11));  // PWMコンポーネント
      dff ctr[27](#INIT(c{INITIAL_VALUE, 18b0}));  // カウンタ
    }
  }

  always {
    led = pwm.pulse;    // PWMの出力をLEDに接続する

    ctr.d = ctr.q + 1;  // カウンタをインクリメントする

    pwm.update = 1;     // 常に更新する

    // 三角波をPWMモジュールに接続する
    pwm.value = ctr.q[ctr.WIDTH-2-:pwm.value.WIDTH] ^ pwm.value.WIDTHx{ctr.q[ctr.WIDTH-1]};
  }
}

PWMのデューティ比を決めるのに9ビットしか使っていないため、INITIAL_VALUEパラメータは9ビットの値しか受け付けないようにした。 そのため、カウンタの27ビット全体に合わせるため、値の後ろに18個の0を埋める必要があった。

8個のLEDに均等にオフセットを与えたいので、それぞれ512/8 = 64ずつ間隔を空けることになる。

トップレベルモジュールを変更し、異なるINITIAL_VALUEを持つ8個のインスタンスを作ることができる。

module au_top (
    input clk,              // 100MHzクロック
    input rst_n,            // リセットボタン(負論理)
    output led [8],         // ユーザーが制御できる8個のLED
    input usb_rx,           // USB→シリアル入力
    output usb_tx           // USB→シリアル出力
  ) {

  sig rst;                  // リセット信号

  .clk(clk) {
    // reset_conditionerは、リセット信号をFPGAのクロックに同期させるために使う。
    // これにより、FPGA全体が同じタイミングでリセットから抜け出せる。
    reset_conditioner reset_cond;

    .rst(rst) {
      pulse pulse1(#INITIAL_VALUE(0));
      pulse pulse2(#INITIAL_VALUE(64));
      pulse pulse3(#INITIAL_VALUE(64*2));
      pulse pulse4(#INITIAL_VALUE(64*3));
      pulse pulse5(#INITIAL_VALUE(64*4));
      pulse pulse6(#INITIAL_VALUE(64*5));
      pulse pulse7(#INITIAL_VALUE(64*6));
      pulse pulse8(#INITIAL_VALUE(64*7));
    }
  }

  always {
    reset_cond.in = ~rst_n; // 反転させた生のリセット信号を入力する
    rst = reset_cond.out;   // 整えられたリセット信号

    led = c{pulse8.led, pulse7.led, pulse6.led, pulse5.led,
      pulse4.led, pulse3.led, pulse2.led, pulse1.led};

    usb_tx = usb_rx;        // シリアルデータをそのまま返す
  }
}

これをビルドして基板に書き込むと、これまで目指してきたLEDの波パターンが現れるはずである。

しかし、まだ終わりではない。この設計にはまだ多くの最適化の余地がある。

まず、動作しているカウンタの数を数えてみよう。 それぞれのPWMコンポーネントは独自のカウンタを持ち、それぞれのpulseモジュールも別のカウンタを持っている。 つまり、合計で16個のカウンタがあることになる。

8個のPWMカウンタは、それぞれまったく同一である。すべて同じサイズ、同じ初期値を持ち、すべて自由に動作し続けている。 pulse側のカウンタも同様だが、初期値だけが異なる。

しかし実は、これも2進数の持つ循環的な性質を利用すれば回避できる。 自由に動作し続けるカウンタに一定の定数値を加えれば、あたかもその値だけオフセットされた別のカウンタであるかのように見える。 つまり、8個のカウンタを、1個のカウンタと7個の加算器で置き換えられるということである。 どのカウンタにもすでに加算器が内蔵されていることを踏まえると、これによって余分なDFFがすべて節約できる。

すべてのカウンタを、1つの自由に動作し続けるカウンタへとまとめることができる。

最後に、PWMコンポーネントのグリッチフリー動作も不要になる。 比較値が更新されるのは、同じカウンタ(より上位のビットを使っているだけ)のPWM用カウンタがオーバーフローするときだけになるよう保証できるからである。

これらすべてが、コンポーネントライブラリのLED EffectsにあるPWM Waveコンポーネントに、きれいにまとめられている。

module wave #(
    CTR_LEN = 25 : CTR_LEN >= 9
  )(
    input clk,     // クロック
    input rst,     // リセット
    output out[8]  // LED出力
  ) {

  // カウンタ
  dff ctr[CTR_LEN](.clk(clk),.rst(rst));

  var i;         // forループ用の変数
  sig acmp[8];   // 中間値
  sig result[9]; // 中間値

  always {
    // カウンタをインクリメントする
    ctr.d = ctr.q +1;

    // 各出力について
    for (i = 0; i < 8; i++) {
      // カウンタの上位ビットを取り出し、
      // それぞれの出力ごとに異なるオフセットを与える
      result = ctr.q[CTR_LEN-1-:9] + i * 8d64;

      // MSBが1なら
      if (result[8])
        // 反転させてカウントダウンにする
        acmp = ~result[7:0];
      else // そうでなければ
        // そのままカウントアップにしておく
        acmp = result[7:0];

      // PWM出力
      out[i] = acmp > ctr.q[7:0];
    }
  }
}

このモジュールは、ここまでコンパクトにするためにいくつかの高度な機能、具体的にはsigvarforループを使っている。

var型は変数を保持するために使う。 これは実際には設計そのものには現れない値であり、ほとんどの場合forループのインデックス値を保持するためだけに使われる。

sig型は信号を保持するために使う。 基本的には、他の何らかの値に別名を付けているだけである。 dffのようにデータを保存することはできないが、コードを整理するための値のプレースホルダーとして使うことができる。

forループは、多くのプログラミング言語で見かけるのと同じ形、for (initialization; check; operation) {...}を取る。 initializationはループ変数を初期値に設定する。 checkは継続条件を設定するために使い、operationは各繰り返しのたびに「実行」される。 なお、インクリメント・デクリメント用の++--という構文は、この文脈ではvar型に対してのみ使える点に注意してほしい。

forループは、繰り返しの多い処理をコンパクトに書くための手段にすぎないということを思い出してほしい。 ツールは必ずこれを展開できなければならないため、繰り返し回数は定数でなければならない。

forループの最初の行は、先ほど触れた循環的な性質を利用し、カウンタの値にi * 64を加えてresultという名前を付けている。

alwaysブロックの中のsig型は読み書きでき、その値は最後に代入された値になる。 つまり、オフセットされたカウンタの値をresultに代入した後は、それを使うことができる。

sig acmpは、PWM信号のためにカウンタと比較する値を保持するために使う。

このモジュールでも、先ほどと同じXORのトリックを使うこともできたが、代わりにif else文を使って同じことを実現している。 実際には、ツールによってどちらも同じように実装されるはずであり、if else形式のほうが読みやすいとも言える。 先ほどXORのトリックを使ったのは、新しい構文を紹介するのにちょうどよかったからである。

最後に、outの各ビットは、カウンタの最初の8ビットとの比較結果に応じて代入される。 このモジュールでは、PWM信号のプリスケーラも省略されているため、先ほどまでほど電力効率は良くないが、その違いはおそらくごくわずかなものだろう。

これをトップレベルモジュールに組み込めば、LEDを波打たせることができる。

module au_top (
    input clk,              // 100MHzクロック
    input rst_n,            // リセットボタン(負論理)
    output led [8],         // ユーザーが制御できる8個のLED
    input usb_rx,           // USB→シリアル入力
    output usb_tx           // USB→シリアル出力
  ) {

  sig rst;                  // リセット信号

  .clk(clk) {
    // reset_conditionerは、リセット信号をFPGAのクロックに同期させるために使う。
    // これにより、FPGA全体が同じタイミングでリセットから抜け出せる。
    reset_conditioner reset_cond;

    .rst(rst) {
      wave wave;
    }
  }

  always {
    reset_cond.in = ~rst_n; // 反転させた生のリセット信号を入力する
    rst = reset_cond.out;   // 整えられたリセット信号

    led = wave.out;         // LEDを波打たせる

    usb_tx = usb_rx;        // シリアルデータをそのまま返す
  }
}

これはまさに、基板に出荷時から入っているデモファイルで使われているパターンそのものである。

このチュートリアルの結末は、少し拍子抜けに感じられるかもしれない。結局のところ、waveコンポーネントをプロジェクトに追加し、それをインスタンス化して接続する2行を書くだけでも、同じことが実現できてしまうからである。 とはいえ、この道のりを通じて、FPGAプロジェクトを作ることについて、もう少し理解が深まっていたら幸いである。

まだまだ扱うべきことはたくさんあるが、ここまでで、いろいろと自分で試してみるための基礎には十分慣れたはずである。

まとめ

Alchitryのウェブサイトには、チュートリアルやプロジェクト、Alchitryフォーラムなど、さらに役立つ資料がそろっている。

FPGAとLucidの世界にさらに深く踏み込みたい場合は、Justin Rajewski氏による“Learning FPGAs: Digital Design for Beginners with Mojo and Lucid HDL”もおすすめである。

FPGA関連のチュートリアルや製品は今後も充実させていく予定である。次のようなチュートリアルもぜひ確認してほしい(いずれも英語)。

  • Programming an FPGA:フィールドプログラマブルゲートアレイを扱う基礎を紹介する。
  • How Does an FPGA Work?:FPGAとは何か、どう動作するのか、なぜ、そしていつ使うのか。
  • 外部IOとメタ安定性:外部信号がメタ安定性を引き起こす理由と、制約ファイルを使ってこれを管理する方法。

タグ: Alchitry、概念、FPGA


出典:First FPGA Project - Getting Fancy with PWM(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

MQTT入門

はじめに

このチュートリアルでは、MQTTメッセージングプロトコルについて知っておくべきことをひととおり学ぶ。なぜこれを使いたくなるのか、そしてどう実装するのかについても扱う。 一言で言えば、MQTTは既存のインターネット接続された家庭内ネットワークを使って、IoTデバイスにメッセージを送り、そのメッセージに応答させる仕組みである。

簡単な歴史

MQTT(Message Queuing Telemetry Transport)は、TCP/IPプロトコルの上で動作する、パブリッシュ/サブスクライブ型のメッセージングプロトコルである。 最初のバージョンは1999年、IBMのAndy Stanford-ClarkとCirrus LinkのArlen Nipperによって開発された。 MQTTがHTTPリクエストをIoTデバイスから送るより高速である理由の一つは、MQTTのメッセージがわずか2バイトほどに収まりうる点にある。一方HTTPでは、他のデバイスにとってはどうでもよい情報を大量に含むヘッダーが必要になる。 また、HTTPで複数のデバイスがリクエストを待っている場合、それぞれのクライアントに個別にPOSTアクションを送る必要がある。 MQTTでは、サーバーが1つのクライアントから情報を受け取ると、それに関心を持つすべてのクライアントへ自動的に配信してくれる。

必要な部品

このチュートリアルの例を実際に試すには、次のハードウェアが必要である。手元にあるものによっては、すべてが必要になるとは限らない。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

基礎知識

MQTTネットワークの構築方法を学ぶ前に、そこで使われる専門用語と、それぞれの要素がどうネットワークを構成するのかを理解しておくと役立つ。

  • ブローカー:サーバーに接続している、関心を持つクライアントに情報を配信する、サーバー側の存在。
  • クライアント:情報を送受信するためにブローカーへ接続するデバイス。
  • トピック:メッセージが何についてのものかを示す名前。クライアントは、あるトピックに対してパブリッシュ、サブスクライブ、あるいはその両方を行う。
  • パブリッシュ(publish):トピック名に基づいて、関心を持つクライアントへ配信してもらうために、ブローカーへ情報を送ること。
  • サブスクライブ(subscribe):クライアントが、自分がどのトピックに関心を持っているかをブローカーに伝えること。あるトピックにサブスクライブすると、ブローカーへパブリッシュされたメッセージはすべて、そのトピックのサブスクライバーに配信される。クライアントはアンサブスクライブして、あるトピックについてのメッセージの受信を止めることもできる。
  • QoS:サービス品質(Quality of Service)。それぞれの接続は、0〜2の整数値でブローカーに対してサービス品質を指定できる。QoSはTCPのデータ伝送自体の扱いには影響せず、あくまでMQTTクライアント間の話である。注:後の例では、QoS 0のみを使用する。
    • 0は「多くとも1回」、つまり配信の確認応答を必要とせず、1回だけ(届かないこともある)送ることを意味する。これは「撃ちっぱなし(fire and forget)」とも呼ばれる。
    • 1は「少なくとも1回」を意味する。確認応答を受け取るまでメッセージを複数回送信する。これは確認付き配信と呼ばれる。
    • 2は「正確に1回」を意味する。送信側と受信側のクライアントは2段階のハンドシェイクを使い、メッセージのコピーがちょうど1つだけ受信されるようにする。これは保証付き配信と呼ばれる。

MQTTの仕組み

はじめに触れたとおり、MQTTはパブリッシュ/サブスクライブ型のメッセージングプロトコルである。 クライアントはネットワークに接続し、あるトピックにサブスクライブしたり、パブリッシュしたりする。 クライアントがあるトピックにパブリッシュすると、そのデータはブローカーへ送られ、ブローカーはそのトピックにサブスクライブしているすべてのクライアントへ配信する。

トピックは、ディレクトリのような階層構造で表される。 トピックは**“LivingRoom”のようなものかもしれないし、その親トピックの中に複数のクライアントがある場合は“LivingRoom/Light”のようになるかもしれない。 サブスクライバー側のクライアントは、サブスクライブしているトピックからの新着メッセージを待ち受け、“on”“off”のようにそのトピックへパブリッシュされた内容に応じて反応する。 クライアントは、あるトピックにサブスクライブしつつ、別のトピックにパブリッシュすることもできる。 たとえば“LivingRoom/Light”にサブスクライブしているクライアントが、他のクライアントがその照明の状態を監視できるよう、“LivingRoom/Light/State”**のような別のトピックにパブリッシュしたい、というようなケースである。

MQTTの動作原理の理論がわかったところで、Raspberry PiESP32 Thingを使って、手早く簡単な例を作り、実際に動く様子を見てみよう。 まずはブローカーをセットアップし、正しく動作しているか手早くテストするところから始める。

ブローカーをセットアップする

リモートサーバー上でも、オフィスのマシンのようなローカル環境でも、あるいはRaspberry Piのような専用のコンピュータでも動作する、数多くのMQTTブローカーが存在する。 このチュートリアルの例では、ローカルネットワークに接続したRaspberry Piで、Mosquittoという無料でオープンソースのブローカーを動かす。

Mosquittoのセットアップは簡単で、ターミナルを開いて次のように入力するだけである。

sudo apt-get install mosquitto -y

インストールが終わったら、Piからテスト用のクライアントを作り、あるトピックを待ち受けさせて、ブローカーが正しく動作しているか確認しよう。 そのために、mosquittoのクライアントをインストールする。

sudo apt-get install mosquitto mosquitto-clients -y

クライアントのインストールが終わったら、次のコマンドで“test_topic“というトピックにサブスクライブする。

mosquitto_sub -t "test_topic"

mosquitto_subと入力することでmosquittoにトピックをサブスクライブしたいことを伝え、-tで示すtest_topicという名前のトピックにサブスクライブしたいことを指定している。 これで、test_topicにパブリッシュするたびに、送信されたメッセージがこのウィンドウに表示されるようになる。

このターミナルはブローカーからのメッセージを待ち受けている状態なので、メッセージをパブリッシュするには2つ目のターミナルウィンドウを開く必要がある。 開いたら、次のコマンドでtest_topicにパブリッシュする。

mosquitto_pub -t "test_topic" -m "HELLO WORLD!"

先ほどと同じように-tでトピックを示すが、今回はmosquitto_pubを使い、-mでパブリッシュしたいメッセージを指定している。 Enterキーを押すと、以下のようにサブスクライバー側のターミナルウィンドウにメッセージが表示されるはずである。 -mの後の文字列を好きな内容に変更すれば、test_topicにサブスクライブしているすべてのクライアントに、そのメッセージを送ることができる。

クライアントをセットアップする

Note

注:この例では、デスクトップに最新版のArduino IDEがインストールされていることを前提としている。Arduinoを初めて使う場合は、Arduino IDEのインストールのチュートリアルを確認してほしい。Arduinoのライブラリをインストールしたことがない場合は、インストールガイドを参照してほしい。

ブローカーが正しく動作していることが確認できたので、次はクライアントを追加していく。 ここでは2つのクライアントを作る。1つ目は、ボタンを押すたびに**“room/light”というトピックへ“on”または“off”というメッセージをパブリッシュする。2つ目は“room/light”**にサブスクライブし、そのメッセージに応じてLEDを点灯・消灯する。

パブリッシュ側のクライアント:スイッチ

スイッチを作るには、ESP32 Thingを使う。 ESPでMQTTを動作させるには、**PubSubClient**というライブラリをインストールする必要がある。以下のリンクからダウンロードできる。

ESP8266/32 MQTT PubSubClient Library(ZIP)

インストールが終わったら、Arduinoを開き、以下のコードを貼り付ける。 自分のルーターのWiFi認証情報と、Raspberry PiブローカーのIPアドレスを必ず入力しておくこと。 ESP32がネットワークに接続すると、ボタンが押されるのを待つ。ボタンが押されると、ESP32は**“room/light”**というトピックへコマンドをパブリッシュする。

/******************************************************************************
MQTT_Switch_Example.ino
Example for controlling a light using an MQTT switch
by: Alex Wende, SparkFun Electronics

This sketch connects the ESP32 to a MQTT broker and subcribes to the topic
room/light. When the button is pressed, the client will toggle between
publishing "on" and "off".
******************************************************************************/

#include <WiFi.h>
#include <PubSubClient.h>

const char *ssid =  "-----";   // WiFiネットワークの名前
const char *password =  "-----"; // WiFiネットワークのパスワード

const byte SWITCH_PIN = 0;           // 照明を制御するピン
const char *ID = "Example_Switch";  // このデバイスの名前(一意である必要がある)
const char *TOPIC = "room/light";  // サブスクライブするトピック

IPAddress broker(192,168,1,-); // MQTTブローカーのIPアドレス(例:192.168.1.50)
WiFiClient wclient;

PubSubClient client(wclient); // MQTTクライアントを設定する
bool state=0;

// WiFiネットワークに接続する
void setup_wifi() {
  Serial.print("\nConnecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password); // ネットワークに接続する

  while (WiFi.status() != WL_CONNECTED) { // 接続を待つ
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

// クライアントに再接続する
void reconnect() {
  // 再接続できるまでループする
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // 接続を試みる
    if (client.connect(ID)) {
      Serial.println("connected");
      Serial.print("Publishing to: ");
      Serial.println(TOPIC);
      Serial.println('\n');

    } else {
      Serial.println(" try again in 5 seconds");
      // 5秒待ってから再試行する
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200); // 115200ボーでシリアル通信を開始する
  pinMode(SWITCH_PIN,INPUT);  // SWITCH_Pinを入力として設定する
  digitalWrite(SWITCH_PIN,HIGH);  // プルアップ抵抗を有効にする(負論理)
  delay(100);
  setup_wifi(); // ネットワークに接続する
  client.setServer(broker, 1883);
}

void loop() {
  if (!client.connected())  // 接続が切れていたら再接続する
  {
    reconnect();
  }
  client.loop();

  // スイッチが押されている場合
  if(digitalRead(SWITCH_PIN) == 0)
  {
    state = !state; //状態を切り替える
    if(state == 1) // ON
    {
      client.publish(TOPIC, "on");
      Serial.println((String)TOPIC + " => on");
    }
    else // OFF
    {
      client.publish(TOPIC, "off");
      Serial.println((String)TOPIC + " => off");
    }

    while(digitalRead(SWITCH_PIN) == 0) // スイッチが離されるまで待つ
    {
      // 必要であれば裏側の処理をESPに行わせる
      yield();
      delay(20);
    }
  }
}

コードを書き込み、ESP32がネットワークに接続したら、ブローカーが正しく動作していて、ブローカーに接続できていることを確認したい。 これを確認するには、Piのターミナルウィンドウから、次のコマンドで**“room/light”**にサブスクライブする。

mosquitto_sub -t "room/light"

GPIOピン0に接続されているESP32のボタンを押してみよう。

GPIOピン0に接続されたESP32のボタンを押すと、以下のようにon/offのコマンドが表示されるはずである。

サブスクライブ側のクライアント:照明

スイッチがブローカーに接続できたところで、次はトピックに新しいメッセージが送られたときに反応するデバイスを接続する必要がある。 そのためには、もう1台のESP32を用意し、以下のように5番ピンに接続したLEDを制御する。 先ほどと同様に、WiFiの認証情報とRaspberry PiブローカーのIPアドレスを必ず入力しておくこと。

/******************************************************************************
MQTT_Light_Example.ino
Example for controlling a light using MQTT
by: Alex Wende, SparkFun Electronics

This sketch connects the ESP8266 to a MQTT broker and subcribes to the topic
room/light. When "on" is recieved, the pin LIGHT_PIN is toggled HIGH.
When "off" is recieved, the pin LIGHT_PIN is toggled LOW.
******************************************************************************/

#include <WiFi.h>
#include <PubSubClient.h>

const char *ssid = "-----";   // WiFiネットワークの名前
const char *password = "-----"; // WiFiネットワークのパスワード

const byte LIGHT_PIN = 5;           // 照明を制御するピン
const char *ID = "Example_Light";  // このデバイスの名前(一意である必要がある)
const char *TOPIC = "room/light";  // サブスクライブするトピック
const char *STATE_TOPIC = "room/light/state";  // 照明の状態をパブリッシュするトピック

IPAddress broker(192,168,1,-); // MQTTブローカーのIPアドレス(例:192.168.1.50)
WiFiClient wclient;

PubSubClient client(wclient); // MQTTクライアントを設定する

// ブローカーからの受信メッセージを処理する
void callback(char* topic, byte* payload, unsigned int length) {
  String response;

  for (int i = 0; i < length; i++) {
    response += (char)payload[i];
  }
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  Serial.println(response);
  if(response == "on")  // 照明を点灯する
  {
    digitalWrite(LIGHT_PIN, HIGH);
    client.publish(STATE_TOPIC,"on");
  }
  else if(response == "off")  // 照明を消灯する
  {
    digitalWrite(LIGHT_PIN, LOW);
    client.publish(STATE_TOPIC,"off");
  }
}

// WiFiネットワークに接続する
void setup_wifi() {
  Serial.print("\nConnecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password); // ネットワークに接続する

  while (WiFi.status() != WL_CONNECTED) { // 接続を待つ
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

// クライアントに再接続する
void reconnect() {
  // 再接続できるまでループする
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // 接続を試みる
    if(client.connect(ID)) {
      client.subscribe(TOPIC);
      Serial.println("connected");
      Serial.print("Subcribed to: ");
      Serial.println(TOPIC);
      Serial.println('\n');

    } else {
      Serial.println(" try again in 5 seconds");
      // 5秒待ってから再試行する
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200); // 115200ボーでシリアル通信を開始する
  pinMode(LIGHT_PIN, OUTPUT); // LIGHT_PINを出力として設定する
  delay(100);
  setup_wifi(); // ネットワークに接続する
  client.setServer(broker, 1883);
  client.setCallback(callback);// コールバック処理を初期化する
}

void loop() {
  if (!client.connected())  // 接続が切れていたら再接続する
  {
    reconnect();
  }
  client.loop();
}

2台目のESP32 ThingのGPIOピン5に接続された内蔵LEDを見つけよう。

2台目のESP32がネットワークに接続すると、自動的に**“room/light”にサブスクライブし、1台目のESP32のボタンを押すと、2台目のESP32のGPIOピン5に接続された内蔵LEDが反応して点灯・消灯するはずである。 トピックを“room/light2”や、単に“room”**に変更してみて、デバイスが新しいトピックにどう反応するか(あるいは反応しないか)を確認することもできる。

まとめ

このチュートリアルが、ホームオートメーションのプロジェクトにMQTTを組み込むための出発点になれば幸いである。 LEDを点灯・消灯させるだけでなく、一歩進んで、IoT Power RelayをESP32に接続し、AC電源で動く機器を制御することもできる。

このチュートリアルでは触れなかったツールとして、Home Assistantがある。 Home Assistantを使えば、MQTTを含む幅広い市販のスマートホームデバイスを制御できる。 つまり、Home Assistantを使えば、既存のスマートホームデバイスを簡単に制御できる独自のMQTTデバイスを作ることもできる。これについては、いずれ別のチュートリアルで扱う予定なので、お楽しみに。 それまでの間、ESP8266とRaspberry Piを使ったMQTTとHome Assistantについてのブログ記事を、以下で読むことができる(いずれも英語)。

MQTTについてさらに詳しく知りたい場合は、以下のリンクも参考にしてほしい(いずれも英語)。

次のプロジェクトのヒントが欲しい場合は、次の関連チュートリアルも参考にしてほしい(いずれも英語)。

タグ: Arduino、通信、概念、ESP32、ESP8266、IoT、MQTT、Raspberry Pi、WiFi、無線


出典:Introduction to MQTT(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

LogicBlocks実験ガイド

はじめに

LogicBlocksの入門チュートリアル(あるいはキットに付属のドキュメント)を読み終え、いよいよ実験の準備ができただろうか。LogicBlocksの出番である。

このXNORのような、大がかりなLogicBlocks回路もあっという間に組めるようになるはずである。

目次

このガイドで扱う実験の一覧を示す。

  1. 2入力ANDゲート
  2. 3入力ANDゲート
  3. NAND、NOR、ド・モルガンの法則
  4. 組み合わせ論理
  5. リングオシレータ
  6. SRラッチ
  7. 2-to-1マルチプレクサ
  8. 1-to-2デコーダ(デマルチプレクサ)
  9. XORゲート
  10. LogicBlocksのその先へ

それぞれの実験には回路図と、それに対応するテスト対象回路のLogicBlocksの配置図が含まれている。

また、各実験には真理値表状態図論理式もちりばめられている。 そして最後には課題や設問、副実験が用意されている。それぞれの実験を最大限に活用するため、ぜひ副実験にも目を通してほしい。

1. 2入力ANDゲート

最初の実験は、できる限り単純なところから始める。2つの入力と1つの出力を持つANDゲートである。

必要なもの

  • ANDブロック × 1
  • 入力ブロック × 2
  • 電源ブロック × 1

回路図

LogicBlocksの配置

特に難しいことはない。ANDブロックの各入力に、それぞれ入力ブロックを挿入する。そして、ANDブロックの出力に電源ブロックをつなぐ。

ANDブロック上の青いLEDが、この回路の出力状態を示す。

実験

考えられる4通りの入力の組み合わせ、0/0、0/1、1/0、1/1をすべて試してみよう。ANDゲートの真理値表は次のようになるはずである。

入力A入力B出力
000
010
100
111
  • 青いANDブロックのLEDは、予想どおりに点灯しただろうか。

副実験

ここまで来たついでに、他の2つの基本ゲートについても見ておこう。2入力ORと、1入力NOTである。

2入力ORゲート

基本的な2入力ORゲートを、LogicBlocksで配置できるだろうか。ANDと似たようなブロックの構成になる。

実際に試してみたら、次のORの真理値表を埋められるだろうか。

入力A入力B出力
00
01
10
11

NOTゲート

続いて、NOTゲートでも同じことをやってみよう。

今回必要な入力ブロックは1個だけである。

NOTの真理値表を埋められるだろうか。

入力A出力
01
10

3つの基本論理ゲートの扱いがわかったところで、入力を増やしてみよう。次の実験に進む。

2. 3入力ANDゲート

3つ以上の入力をANDでまとめたい場面もある。実のところ、3入力・4入力のANDゲートは、2入力タイプと同じくらいよく使われる。2つの2入力ANDゲートから、3入力ANDゲートを作ってみよう。

必要なもの

  • 入力ブロック × 3
  • ANDブロック × 2
  • 電源ブロック × 1

回路図

LogicBlocksの配置

前回の実験の2入力ANDブロックを組み立て、その出力をもう一つのANDの入力に接続する。そして、2つ目のANDのもう一方の入力に、入力ブロックを追加する。

2つ目のANDの出力に電源ブロックを追加して、回路を完成させる。

2つ目のANDゲート上の青いLEDが、この回路の出力を表す。

実験

合計3つの入力があると、何通りの入力の組み合わせが作れるだろうか。8通りである。この数は、入力の数をnとすると2nという指数関数的な増え方をする。つまり、4入力ANDゲートには16通り、5入力なら32通りの組み合わせがある。

考えられるすべての入力の組み合わせを試し、以下の真理値表を埋めてみよう。

入力A入力B入力C出力Y
000
001
010
011
100
101
110
111
  • ある結果が真になるために、3つの条件がすべて満たされる必要がある、という現実の場面を思いつけるだろうか。
  • ANDブロックがもっとたくさんあったら、4入力ANDブロックはどんな形になるか想像できるだろうか。

副実験

2つのORゲートと3つの入力ブロックを使い、3入力ORゲートを作ってみよう。

  • この回路の回路図を描いてみよう。
  • この回路の真理値表を書き出してみよう。3入力ANDの回路と同じく、この回路にも8通りの入力の組み合わせがある。ただし、出力の列にはずっと多くの1が並ぶはずである。

3. NAND、NOR、ド・モルガンの法則

NAND、つまりNOT AND(否定されたAND)は、ANDゲートの出力にインバータを置くことで得られる。 NANDゲートはデジタル論理の世界で非常によく使われている。専用の回路記号まであり、ANDゲートの出力に「泡(バブル)」を付けた形で表される。

LogicBlocksで作ってみよう。

必要なもの

  • ANDブロック × 1
  • NOTブロック × 1
  • 入力ブロック × 2
  • 電源ブロック × 1

LogicBlocksの配置

この配置は実験1の構成に似ているが、ANDブロックの出力と電源ブロックの間にNOTゲートを追加する点が異なる。

この回路の出力は、NOTゲート上の赤いLEDで示される。

実験

入力が2つあるので、考えられる組み合わせは4通りである。すべて試して、2入力NANDゲートの真理値表を埋めてみよう。

入力A入力B出力
000
010
100
111
  • ANDゲートの真理値表と比べて、どう違うだろうか。

副実験

ORゲートも同じように否定すれば、NORを作ることができる。

こちらにも専用の「泡付き」回路記号がある。

  • 2入力NORゲートの真理値表はどうなるだろうか。

ド・モルガンの法則

ここまでNANDとNORの話をしていると、ド・モルガンの法則について語りたくてうずうずしてくる。ド・モルガンの法則を使えば、NANDをORに、NORをANDに変換できる。この法則には2つの部分がある。

  1. 2入力NANDは、2つの反転入力をORしたものと等価である。論理式で書くと次のようになる。

  2. 2入力NORは、2つの反転入力をANDしたものと等しい。論理式では次のようになる。

自分で確かめてみよう。LogicBlocksで以下の回路、つまり2つの反転入力をORゲートに入れた回路を組み、先ほどNANDゲートで埋めた真理値表と比較してみてほしい。

真理値表は一致しただろうか。これで、ド・モルガンの法則の前半部分を自分の手で確かめたことになる。

ここで「それが何の役に立つのか」と思うかもしれない。デジタル論理の大きな目的の一つは、回路を単純化し、できるだけ少ないゲート数で済ませることにある。ド・モルガンの法則のおかげで、NANDゲート1種類だけで他のあらゆるゲートの代わりを務めさせることができる。

たとえば、NOTはNANDから作れる。片方の入力を常にハイに固定するだけでよい。

あるいは、3個のNANDゲートでORを作ることもできる。

あるいは、2個のNANDでANDを作ることもできる。

NANDゲートのこの汎用性こそ、まさに魔法のようなものである。

4. 組み合わせ論理

これまでの実験の回路は、すべて組み合わせ論理回路の例だった。組み合わせ回路では、出力は現在の入力の状態のみに依存する。回路は一方向に流れ、(慣例的に)左側の入力から右側の出力へと向かう。

組み合わせ論理の対極にあるのが順序論理であり、そこでは回路の現在の出力が将来の出力に影響を与える。これについては、後の実験で扱う。

LogicBlocksで組める組み合わせ論理回路の例を紹介する。

回路図に示された入力の名前(AとBがANDゲートに入り、Cが最初のNOTゲートを通る)から、次のような論理式を作ることができる。

出力は、((AとBのAND) または Cの否定)を否定したものである(演算の順序を間違えないように)。この回路をLogicBlocksで組んでみよう。

必要なもの

  • ANDブロック × 1
  • ORブロック × 1
  • NOTブロック × 2
  • 入力ブロック × 3
  • 電源ブロック × 1

LogicBlocksの配置

2つの入力ブロックを持つANDブロックの出力を、ORブロックの一方の入力に接続する。ORブロックのもう一方の入力は、入力ブロックを接続したNOTブロックにつなぐ。最後に、ORブロックの出力をもう一つのNOTブロックに通し、それを電源ブロックに接続する。

この組み合わせ論理回路の出力は、最後のNOTブロック上の赤いLEDで示される。

実験

考えられる8通りの入力の組み合わせをすべて試し、この回路の真理値表を埋めてみよう。

入力A入力B入力C出力Y
000
001
010
011
100
101
110
111
  • これは、先ほどの論理式と一致しているだろうか。
  • もう一度その論理式、あるいは回路図をよく見てみよう。NANDやNORが隠れていることに気づけば、ド・モルガンの法則を使ってこの式を単純化できるだろうか。実はできる。まず、インバータをORゲートの中に押し込んで、NORに変えてみよう。

続けてド・モルガンの法則を適用する。バブルをNORゲートの中に押し込んでANDに変え、両方の入力側にNOTゲートを生み出す。

C入力にある2つのNOTゲートは互いに打ち消し合うので、両方とも取り除いてしまってよい。最初のANDの出力にあるNOTゲートは、そのゲート自体に押し込んでNANDゲートに変えられる。

これで、ORゲートを完全になくすことができた。この回路が、実験の最初に使った回路とまったく同じ真理値表を生成すると信じられるだろうか。自分で試してみよう。

副実験

  • 次の実験では、組み合わせ論理から順序論理へと、かなり大きく話が飛ぶ。ここでいったん、LogicBlocksで自由に遊びながら、自分なりの回路を作ってみることを強くおすすめする。そのうえで、回路図と真理値表を自分で描き出してみてほしい。
  • デジタル論理で解決できそうな、現実の場面を何か思いつけるだろうか。

5. リングオシレータ

オシレータ(発振回路)とは、出力が周期的かつ繰り返し変動する回路のことである。オシレータはほとんどの電子回路にとって欠かせない要素であり、クロックから電波まで、あらゆるものを作り出すのに使われる。発振を作り出す回路にはさまざまな種類があり、オペアンプ水晶振動子555タイマー、そしてもちろん論理ゲートを使うこともできる。

奇数個のNOTゲートを鎖状につなぎ、フィードバックを導入する、つまり最後のインバータの出力を最初の入力へループさせることで、リングオシレータを作ることができる。LogicBlocksで組んでみよう。

必要なもの

  • NOTブロック × 3
  • スプリッターブロック × 1
  • フィードバックケーブル × 1
  • 電源ブロック × 1

回路図

この回路では、これまでちらっとしか触れてこなかった概念、順序回路が登場する。組み合わせ回路とは異なり、順序回路の出力は過去の出力状態に依存する。

リングオシレータの回路は、次のようになる。

3つ目、つまり最後のNOTゲートの出力が、2方向に分岐しているのがわかるだろうか。1つはこれまでどおりそのまま出力へ向かうが、もう1つは最初のNOTゲートの入力へとループして戻っていく。これはフィードバックと呼ばれ、順序回路とほぼ同義の用語である。出力の現在の状態は、過去に何をしていたかに依存する。

LogicBlocksの配置

まず3個のNOTゲートをつなぎ、3個目の出力をスプリッターブロックに接続する。フィードバックケーブルを使い、スプリッターブロックの出力の一方を最初のNOTゲートの入力に接続する。最後に、スプリッターブロックのもう一方の出力に電源ブロックを接続する。

この回路の出力は、3つ目、つまり最後のNOTブロック上の赤いLEDで示される。

実験

この回路の真理値表はどうなるだろうか。いや待ってほしい。そもそも真理値表など存在するのだろうか。入力が一つもないのだから。 標準的な真理値表の代わりに、現在の出力の値が直前の出力に依存することを定義する状態表を作ることができる。

直前の出力現在の出力
01
10
  • インバータの数は奇数でなければならないのだろうか。インバータの数が偶数だとどうなるだろうか。1個取り除いて試してみよう。
  • 最後のNOTブロックのLEDが、どれくらいの速さで点滅しているか計算できるだろうか。それぞれのブロックにはおよそ1秒の遅延がある。インバータの数を5個に増やすと、出力の点滅の速さにどんな影響があるだろうか。

副実験

場合によっては、オシレータにイネーブル入力を持たせておくと便利なことがある。イネーブル入力(多くのデジタル論理回路によく見られる)は、回路全体の動作を制御する。イネーブル入力が1のとき、回路は通常どおり動作するが、0のときは回路の動作が停止する。

ANDゲートを導入することで、リングオシレータにイネーブル入力を追加できる。次の回路図を見てほしい。

(フィードバックケーブルを外して)ANDブロックを最初のNOTゲートに接続して組み立てる。次に、フィードバックケーブルのオス側をANDブロックの一方の入力に、入力ブロック(イネーブル用)をもう一方の入力に接続する。

これで、イネーブル入力のスイッチを切り替えて、オシレータの出力にどう影響するか確認してみよう。

このときの状態表はどうなるだろうか。

イネーブル直前の出力現在の出力
00
01
10
11

6. SRラッチ

ラッチ(フリップフロップとも呼ばれる)は、データ記憶の基本的な構成要素である。1個のラッチは1ビットのデータを保持できるが、この数を何桁も増やしていけば、キロバイト、メガバイト、ギガバイト、さらにはテラバイトのメモリを作ることができる。もちろん、たいていのデジタル回路と同様、ラッチもデジタル論理ゲートから作られている。

ラッチにはさまざまな種類があり、SR、D、JK、Tといった、いささか暗号めいた名前が付いている。ここで扱うSRラッチは、もっとも基本的な形のラッチの一つである。

SRラッチにはいくつかの作り方がある。NORによるSRラッチの例を示す。

フィードバックに気づいただろうか。これもまた順序論理回路である。2つのNORゲートは、それぞれの出力がもう一方の入力へと流れ込んでいる。制御可能な入力は2つ、リセット(R)とセット(S)で、これらが2つの出力QとQ(バーQ、「Qノット」)を生み出す。これが、SRラッチという名前の由来である。セット/リセットラッチというわけである。

SRラッチには、絶対に破ってはならないルールがある。Qは常にQの反対でなければならないというものである。これらの出力は**補数(コンプリメント)**と呼ばれる。実際の用途では、たいていQだけが本当に重要な出力であり、ラッチのデータはたいていここに保存・読み出しされるが、2つの出力が互いに反対であることは重要な性質として押さえておく必要がある。

SRラッチは非常に重要な回路なので、専用の回路記号まで用意されている。

以下が状態表だが、少し変わった形をしている。この回路は順序回路であるため、Qの現在の値はその直前の状態に依存する。

SR直前のQ現在のQ現在のQ
0000(変化なし)1
0011(変化なし)0
0100(変化なし)1
01101
10010
1011(変化なし)0
1100(禁止:QとQが補数にならない)0
1110(禁止:QとQが補数にならない)0

言葉で表すと、出力Qは次のいずれかの状態を取りうる。

  • 保持:SとRがともに0のとき、Qはそのまま変化しない。以前の値を保ち続ける。0だったなら0のまま、1だったなら1のままである。
  • セット:Sを1に変えると、Qの出力を「セット」できる可能性がある。Qが0だった場合、Sを1に変えるとQも1になる。Qがすでに1だった場合、S=1にしても何も起こらない。
  • リセット:R入力を0から1に動かすと、Qを「リセット」できる。Qが1だった場合、Rを1にするとQは0になる。しかし、Qがすでに0だった場合、Rは何の影響も与えない。
  • 禁止SとRの両方が1のとき、禁止領域に入る。QとQは互いに補数でなければならないというルールが破られ、両方とも0になってしまう。そのため、S=1かつR=1という組み合わせを禁止の組み合わせと呼ぶ。たいていのラッチ回路では、これらの入力が両方とも1にならないよう、あらかじめ対策が講じられている。今回のLogicBlock回路にはそこまで賢い仕組みはないので、両方が同時に1にならないよう「回路の安全対策」は自分の手で講じる必要がある(心配はいらない。両方の入力をハイにしても、宇宙がこの矛盾に耐えられなくなることはない)。

Qが取りうる状態は、状態図でまとめることもできる。

概念的な話はこのくらいにして、LogicBlocksでSRラッチを組んでみよう。

必要なもの

  • ORブロック × 2
  • NOTブロック × 2
  • 入力ブロック × 2
  • スプリッターブロック × 1
  • フィードバックケーブル × 1
  • 電源ブロック × 1

LogicBlocksの配置

次のようにLogicBlock回路を組み立てる。

頭の中で、両方の入力に名前を付けておく必要がある。片方をR(リセット)、もう片方をS(セット)としよう。この回路は対称的なので、どちらをどう呼んでもかまわないが、入力の名前によってどちらの出力がどちらになるかが決まる。

この回路で注目すべき出力は2つあり、どちらもNOTゲート上の赤いLEDで示される。Sを直接の入力とするORゲートから続くNOTゲートは、Q出力を示す。Q出力は、Rを入力とするORゲートから続くNOTゲート上の赤いLEDで示される。

実験

次の手順を試し、QとQの両方の出力を観察してみよう。

  1. 最初の状態が必要である。まずS=0R=0に設定する。
  2. 次にR=1にする。Qは「リセット」されるはずで、それまで0でなければ0になる。すでに0だったなら、そのままである。ルールに従い、Qは1になっているはずである。
  3. R=0にする。QもQも変化しないはずである。そのまま保持される。
  4. S=1にする。今度はQが「セット」され、ハイになり、Qはローになる。
  5. S=0にする。QにもQの補数にも、何の影響もないはずである。
  • これがメモリの一部としてどう機能しうるか、想像できただろうか。Q出力に1ビットのデータが保存されていると考えてみてほしい。
  • SとRの両方を1にして、禁止状態に入ってみよう。QとQはどちらも0になるはずである。補数のルールが破られてしまった。これを防ぐため、たいていの場合、入力に安全策(さらなる論理ゲートという形で)が講じられ、禁止の組み合わせが許可された入力値に変換される。

副実験

NANDゲートを使ってラッチを作ることもできる。ORをANDに置き換えるだけである。入力の名前を、それが生み出す結果と一致させるため、SとR(あるいは見方によってはQとQ)の入力も入れ替える。

LogicBlocksでは、次のように配置する(ORブロックをANDブロックに置き換えるだけでよい)。

依然として2つの安定状態を持つが、真理値表は変わる。NAND SRラッチの状態表を書き出し、先ほどのNOR SRラッチと比較してみよう。この場合、どの入力の組み合わせが禁止出力を生み出すだろうか。

SR直前のQ現在のQ現在のQ
000
001
010
011
100
101
110
111
  • ラッチは、SRAM(スタティックRAM)を含む、さまざまな種類のメモリの構成要素になっている。ここまで見てきたとおり、1個のラッチは1ビットのデータを保存できる。1Mb(100万ビット)のSRAMには、いったい何個のラッチが使われていると思うだろうか。それは何個のNORゲートに相当するだろうか。とんでもない数である。

7. 2-to-1マルチプレクサ

マルチプレクサ(マルチプレクサ、略してmux)は、多くの信号を1本にまとめるためによく使われるデジタル回路である。複数のデータソースに、共通の1本のデータ線を共有させたい場合、マルチプレクサを使ってその線へ流し込む。マルチプレクサにはさまざまな形やサイズのものがあるが、どれも論理ゲートで作られている。

すべてのマルチプレクサには、少なくとも1本の選択線があり、どの入力信号を出力へ中継するかを選ぶのに使われる。2-to-1マルチプレクサには、選択線が1本だけある。入力が増えれば、選択線も増える。4-to-1マルチプレクサには選択線が2本、8-to-1には3本、というように増えていく(2n個の入力にはn本の選択線が必要になる)。

マルチプレクサを「デジタルスイッチ」だと考えてみよう。選択線はスイッチの切り替えレバーであり、多数の入力のうちどれが出力になるかを選んでいる。

論理ゲートで2-to-1マルチプレクサを作る方法を紹介する。AとBが2つの入力、Xが選択入力、Yが出力である。

この回路の真理値表は、次のようになる。

選択入力(X)入力A入力B出力Y
0000
0010
0101
0111
1000
1011
1100
1111

LogicBlocksの時間である。

必要なもの

  • ANDブロック × 2
  • ORブロック × 1
  • インバータブロック × 1
  • スプリッターブロック × 1
  • 入力ブロック × 3
  • フィードバックケーブル × 1
  • 電源ブロック × 1

LogicBlocksの配置

以下の配置図に従って、2-to-1マルチプレクサを組み立てる(ヒント:+と−のラベルの組み合わせに、筆者たち以上に注意を払ってほしい)。

それぞれの入力に、頭の中でラベルを付けておく必要がある。選択入力(X)は、NOTゲートに単独でつながっている入力である。残りの2つの入力がAとBであり、これは好きなように名付けてよい。

このマルチプレクサの出力は、ORゲート上の黄色いLEDで示される。

実験

次の手順で試してみよう。

  1. 初期状態:3つの入力すべてを0にする。出力は0になるはずである。
  2. Aを1に切り替える。選択スイッチが0に設定されている間は、B入力が出力に流れているため、出力には何も起こらないはずである。
  3. B入力を1に切り替える。出力を観察し、Bを0に戻す。出力はB入力の切り替えに追従するはずである。
  4. セレクタを1に切り替える。今度は出力がA入力に追従するようになり、Bが何であっても関係なくなる。
  • この回路は組み合わせ回路だろうか、順序回路だろうか(「フィードバック」ケーブルの名前に惑わされないように)。
  • 4-to-1マルチプレクサがどんな形になるか想像できるだろうか。入力線が2倍必要になる。つまり、選択線2本と4通りの入力である。4-to-1マルチプレクサの(色分けされた)回路図を紹介する。

4-to-1のデマルチプレクサには、3入力ANDが4個、NOTが4個、4入力ORが1個必要になる。この回路によって、A、B、C、Dのいずれかを選んでX出力へ送ることができる。X0とX1が選択を担う。

  • 8-to-1マルチプレクサには、何個のゲートが必要になると思うだろうか。

8. 1-to-2デコーダ(デマルチプレクサ)

マルチプレクサの逆にあたるのがデマルチプレクサで、デマルチプレクサ(demux)やデコーダとも呼ばれる。デマルチプレクサは、1本の入力線を複数の出力線のいずれかへ通すことができ、こちらも選択線を使ってどの出力へ送るかを決める。

2-to-1デマルチプレクサの回路図は、次のようになる。

入力はXとAの2つ、出力はY1とY2の2つである。Xがセレクタ入力であり、A入力を2つの出力のどちらに送るかを決める。Xが0のとき、Y2の出力はAをそのまま映す(一方Y1は常に0になる)。Xが1のとき、A入力はY1に送られる。

デマルチプレクサは、システムで使える出力が限られていて、それでいて多数の入力デバイスとやり取りする必要がある場合に、非常に重宝する。

必要なもの

  • ANDブロック × 2
  • NOTブロック × 2
  • 入力ブロック × 2
  • スプリッターブロック × 2
  • 電源ブロック × 1
  • フィードバックケーブル × 1

LogicBlocksの配置

以下のようにLogicBlocks回路を組み立てる。フィードバックケーブルを使って、片方のスプリッターの出力を単純に延長する(両方のブロックにうまく収まるよう、少し調整が必要になる)。

このLogicBlock回路では、セレクタ入力(X)はNOTブロックにつながる入力ブロックで表されている。残るもう一つの入力がA入力である。

2つの出力は、それぞれ各ANDゲート上の青いLEDで示される。Y1は、電源ブロックが接続されていないほうのANDブロックである。

実験

次の手順で試してみよう。

  1. セレクタ入力(X)を0に切り替える。次に、A入力をハイとローの両方に切り替えてみる。片方のANDブロックだけが変化するはずで、その値は入力と同じになるはずである。
  2. X入力を1に切り替える。再びAを何度か切り替えてみる。今度はもう一方のANDゲートがAに追従するはずである。
  • より大規模なデマルチプレクサがどんな形になるか想像できるだろうか。以下は、2-to-4デコーダの回路例である。

この回路には2本のセレクタ入力(X0とX1)があり、入力(A)を4つの出力のいずれかへ振り分ける。

  • 2-to-4デコーダを、(前回の実験の)4-to-1マルチプレクサと比較してみよう。どう違うだろうか。
  • 3-to-8デコーダの回路がどうなるか想像できるだろうか。

9. XORゲート

ここまで、3つの基本論理ゲートだけの世界で満足してきたことだろう。そろそろその認識を打ち破る時である。排他的ORという啓示に備えてほしい。

排他的OR、略してXORはORゲートに似ているが、一つ大きな違いがある。真理値表から、その違いがわかるだろうか。

入力A入力B出力
000
011
101
110

排他的というのは、文字どおりの意味である。XORは、単独の入力だけが1のときにのみ1を出力する。2つ以上の入力が1であれば、XORゲートは0を出力する。

XORゲートは、デジタル論理において信じられないほど便利な機能であることがわかっている。あまりに便利なので、専用の回路記号まで与えられている。おなじみのORゲートの手前に、凹んだ線を加えたような形をしている。

これまでの実験と同様、XORゲートも3つの基本論理ゲートを組み合わせて実装できる。NOT、AND、ORの組み合わせである。

LogicBlocksで組んでみよう。

必要なもの

  • ANDブロック × 2
  • ORブロック × 1
  • NOTブロック × 2
  • 入力ブロック × 2
  • スプリッターブロック × 2
  • 電源ブロック × 1
  • フィードバックケーブル × 1

LogicBlocksの配置

以下のようにXORを組み立てる。

このXOR LogicBlocks回路の出力は、最後のORゲート上の黄色いLEDで示される。

実験

両方の入力を切り替えて、XORの真理値表が正しいことを確かめてみよう。ORブロック上のLEDは、どちらか一方だけの入力がオンになっているときにのみ点灯するはずである。

  • XORは組み合わせ回路だろうか、順序回路だろうか。
  • 入力のどちらか一方だけが真であるときに、ある主張が真になる、という現実の例を思いつけるだろうか。

副実験

NANDとNORを覚えているだろうか。実はXORにも、対になる存在であるXNORがある。他の2つの否定ゲートと同様、XNORにも専用の「泡付き」回路図がある。

2入力XNORの真理値表は、次のようになる。

入力A入力B出力
001
010
100
111

XNORの本当に興味深い点は、両方の入力が同じときにのみ真になるということである。これが、この演算子を論理的等価と呼ぶ理由である。XNOR演算子として、等号(=)を使うことさえできる。等価演算子は、電子工学とプログラミングのあらゆる場面で使われている。2つの命題が等しいかどうかを確認する必要があるときには、必ずXNORが関わってくる。

ちょうどもう一つNOTブロックが余っているので、XNORのLogicBlocks回路を作ってみよう。電源ブロックをNOTブロックに置き換え、その先に電源ブロックをつなぐ。

この回路の出力は、最後のNOTブロック上の赤いLEDで示される。

  • 両方の入力ブロックを切り替えてみよう。出力のLEDは、両方が同じ値のときにだけ点灯するだろうか。

10. LogicBlocksのその先へ

これらの実験は、いわば氷山の一角にすぎない。多くの基本的な電子工学の構成要素を発見してきたが、まだまだ扱うべきものが残っている。残念ながら、標準のキットに含まれるブロックはここで尽きてしまう。触れずに済ませるわけにはいかない、いくつかの基礎的な回路や概念を紹介しておく。

加算器

加算器は、実際に数を足し合わせる回路であり、論理ゲートで作られている。半加算器は、もっとも単純な加算回路である。2つのビットを足し合わせ、和(S)と桁上げ(C)という2つの出力を持つ。見てのとおり、それほど複雑な回路ではない。

2つのビットの和は、単純にそれらのXORである。そしてAとBの両方が1であれば、桁上げの出力が生成される。

より完全な加算器は全加算器と呼ばれ、桁上げの入力も持つ。これらの回路を長く鎖状につなぐことで、複数ビットの2進数加算器を作ることができる。

たいていのプロセッサには、**算術論理演算装置(ALU)**と呼ばれる回路ブロックがあり、加算、減算、乗算、除算のすべての演算がここで行われる。ALUには何百もの加算回路(などの回路)が収められており、それらを組み合わせて巨大な32ビットや64ビットの加算器を作り上げている。

フリップフロップ(ラッチ)

SRラッチの実験でもフリップフロップに触れたが、これらの回路の重要性については軽く流しただけだった。作ったSRラッチは、電子工学の中でも比較的単純なラッチの一つである。SRラッチを少し手直しすれば、Dラッチを作ることができる。

中にSRラッチが入っているのがわかるだろうか。Dラッチにはデータ(D)とイネーブル(E)という2つの入力がある。イネーブル入力が1である限り、Q出力はDの値そのものになる。イネーブルがローになると、データ入力が何をしていようと、Qはその時点でセットされていた値を保持し続ける。

もう一つよく使われるラッチがJKラッチである。これもSRラッチをもとにしているが、(QとQが等しくなってしまう)「違法」な入力の組み合わせを、現在の出力を切り替える動作に変えている。JKラッチは、次のように作られる。

JKラッチの真理値表は、次のようになる。

JK直前のQ現在のQ
0000(状態保持)
0011(状態保持)
01X(不問)0(リセット)
10X1(セット)
1101(切り替え)
1110(切り替え)

では、このJKラッチをJKフリップフロップにしてみよう。フリップフロップは、たいていラッチにクロック入力を追加することで作られる。クロック入力を持つフリップフロップは、たいていクロック信号の立ち上がりエッジでのみ動作を行う。クロック入力にはさまざまな使い道があり、たとえば複数のフリップフロップにクロック入力を共有させることで、互いを同期させることもできる。これらの2入力ANDゲートを3入力タイプに置き換えることで、JKフリップフロップにクロック入力を追加できる。

これで、JKフリップフロップはクロック入力がハイのときにだけ新しい出力を生成するようになる。これによって、フリップフロップの動作をもう少し細かく制御できるようになる。

このJKフリップフロップは、次のセクション、カウンタで役立つことになる。

カウンタ

加算器は足し算をし、カウンタは数を数える。カウンタはたいていのプロセッサにおける主要な要素であり、特にタイミングに関わる用途で重要になる。デジタル時計は、何らかの方法で秒数を数えなければならないはずである。

数多くのJKフリップフロップをつなぎ合わせることで、非常に単純なカウンタを作ることができる。複数のJKフリップフロップをすべて常に切り替わる状態(J=K=1)に設定し、あるフリップフロップの出力を次のフリップフロップの入力につなげば、非同期リップルカウンタを作ることができる。JKフリップフロップから3ビットのリップルカウンタを作る例を紹介する。

Q0、Q1、Q2が3つの出力であり、Q0が最下位ビット、Q2が最上位ビットである。3ビットあれば、この回路は2進数で0から7まで数えられる。最初のクロック入力に周期的なクロックを与えれば、カウントが始まる。クロックの立ち上がりエッジのたびに、カウンタが1つ増える。あるJKの補数出力を次のJKのクロック入力に接続しているため、Q出力は直前の出力が落ちるたびに切り替わる。

この3ビットカウンタは7でオーバーフローするが、フリップフロップを追加すれば上限は2のべき乗で増えていく(n個のフリップフロップで2n-1まで数えられる)。つまり、100万を超えて数えるには20個のフリップフロップが必要になる。

他にもさまざまな種類のカウンタがあるが、これはここまで学んできた内容からそれほどかけ離れていない、論理回路で作られたよい例である。

7400シリーズ論理チップ

LogicBlocksの次にどこへ進めばよいか探しているなら、7400シリーズの論理チップを調べてみることをおすすめする。7400シリーズは、あらゆる種類のデジタル論理機能を実装した、膨大な種類の集積回路(IC)群である。クアッドNANDゲートをはじめ、さまざまな標準的なデジタル論理ゲートが見つかる。実のところ、LogicBlocksのゲートブロックに使われているチップも7400シリーズの部品であり、単一回路のSMD版になっている。

フリップフロップ、カウンタ、マルチプレクサ、デコーダなど、このチュートリアルで扱ってきたあらゆる種類の回路が、7400シリーズのチップとして実装されている。丸ごとの4ビットALUやメモリ、コンパレータのような、さらに複雑な回路もある。実のところ、その一覧はかなり長いので、こちらを確認してみてほしい。

たいていの7400シリーズのチップは、下に示す3-to-8デコーダ(74238)のように、ブレッドボードに優しいDIPパッケージで手に入る。つまり、実際にはんだ付けをしなくても、実験して確かめることができる。

それでもまだデジタル論理に物足りなさを感じるなら、CPLD(コンパクトプログラマブルロジックデバイス)や、さらにはFPGA(フィールドプログラマブルゲートアレイ)が次のステップになるだろう。これらは7400シリーズのチップと比べても複雑さの桁が大きく違うが、それらのICは何千ものプログラム可能なデジタル論理回路をごく小さな空間に詰め込むことができる。デジタル論理の世界には、まだまだ探求すべきことがたくさんあるが、LogicBlocksがその良い入り口になっていたら幸いである。

まとめ

実験ガイドを最後までやり遂げたことをお祝いしたい。これで、デジタル論理、AND、OR、NOT、XOR、マルチプレクサ、オシレータなどについての知識に、以前よりずっと自信が持てるようになっているはずである。デジタル論理をおさらいしたくなったら、いつでもデジタルロジックのチュートリアルを確認してほしい。

この先どこへ進めばよいかわからない場合は、次のようなSparkFunの他のチュートリアルもおすすめである。

  • 抵抗器コンデンサダイオードスイッチの基礎は、部品ごとのチュートリアルのほんの一部である。他の基礎的な電子部品について学びたい場合は、これらのチュートリアルから始めるとよいだろう。
  • Arduinoとは何か:Arduinoは、できる限り使いやすく作られた、非常に人気のあるマイクロコントローラ開発プラットフォームである。Arduinoの中心にあるのはマイクロコントローラ、つまり内部に何百万もの論理ゲートを持つ小さなコンピュータである。
  • Shift Registers:シフトレジスタは、わずかな制御線で幅広い入出力を切り替えられる、非常に便利なICである。しかも、完全にデジタル論理だけで作られている。
  • 16進数:数学好きで2進数に慣れているなら、ぜひ16進数についても学んでみてほしい。

タグ: 概念、電気工学


出典:LogicBlocks Experiment Guide(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

どこからでもセンサーデータを監視する

はじめに

WiFiは誰にとっても馴染み深いものである。 家庭のネットワークを支え、お気に入りの映画をストリーミングさせてくれ、コーヒーショップで他人と話さずに済むようにもしてくれる。 しかし、WiFiの使い道は、さまざまなアプリケーションを通じてインターネットにアクセスするだけにとどまらない。

前回のWiFiに関するチュートリアル、WiFi経由でセンサーデータを送信するの続きとして、環境センサーからデータを読み取り、シリアルLCDへ遠隔出力する、単純で閉じたピアツーピアネットワークの作り方を紹介した。 次の論理的なステップは、同じアイデアをIoTプロジェクトへと発展させ、インターネットに接続できる場所であれば世界のどこからでもセンサーの読み取り値を確認できるようにすることである。

これで、世界のどこにいても、いつでも自宅の状況を確認できる。

プロジェクトの概要:どこからでも温度・湿度・気圧をワイヤレスで監視する

最初のチュートリアルWiFi経由でセンサーデータを送信するを実際にやってみた、あるいは読むだけでも読んでいれば、最初のステップが基板のMACアドレスを調べることで、次のステップがハードウェアの接続だったことを覚えているはずである。 今回のチュートリアルではMACアドレスは不要で、ハードウェアのセットアップもQwiic Connectシステムを使えばこれ以上ないほど簡単である。 ESP32 Thing Plusを、1本のQwiicケーブルで1つのQwiicセンサーブレイクアウトに接続するだけでよい。 あまりにも速く簡単なので、これを「ステップ」と呼ぶことすらためらわれるほどである。

このプロジェクトのセットアップは、2本のQwiicケーブルによる単純な数珠つなぎである。

ステップ1:ダッシュボードを選ぶ

IoTダッシュボードとは何か

IoT(モノのインターネット)ダッシュボードとは、ネットワークに接続されたデバイスが取得・送信したデータの集まりを、変換し、表示し、整理してくれるデータ可視化ツールである。 IoTダッシュボードの主な目的は、過去のデータとリアルタイムのIoTデータを遠隔から監視するための、人間にとって読みやすい一目瞭然の情報を提供することである。

利用できるIoTダッシュボードは山ほどある。

データを受信し、変換し、できれば可視化する何らかの手段が必要である。 その方法はいくつもある。 自分のWebサイトを持っていて、Web開発に慣れており、100%自分で制御・カスタマイズしたいのであれば、自作するという選択肢もある。 しかし、多くの人にとってここでの主眼はもう少しIoT寄りのところにある。 筆者が検討したいくつかの選択肢を紹介するが、たいていのIoTプロジェクトと同様、唯一の正解というものはない。 筆者が使ったものをそのまま試してもよいし、これを出発点として、自分のプロジェクトのニーズに完璧に合うものを探してもよい。 筆者が検討したIoTプラットフォームの概要を紹介する。

  • Arduino IoT Cloud:IoTプロジェクトをWebに接続する、シンプルで手早い方法。ダッシュボードもかなり簡素である。
  • Cayenne:ドラッグ&ドロップの使いやすいUIを備えるが、現時点では対応センサーがかなり限られている。とはいえ、ArduinoやRaspberry Piの基板を使えば、選択肢はぐっと広がる。
  • Particle:非常に高機能だが、その真価を発揮するには少し調べる必要があり、独自の基板シリーズを使う(筆者は、Particleの最初のKickstarterキャンペーン以来ずっと使っている)。
  • Thingsboard:非常に高機能なプラットフォームだが、GNU/Linuxの事前知識があると、必須ではないにせよかなり役立つはずである(最初は無料プランがないように見えるかもしれないが、Professional EditionではなくCommunity Editionを見れば、無料プランが用意されていることがわかる)。
  • Thingspeak:データの可視化と分析の両方に優れたプラットフォームで、しっかりとしたArduinoの例も用意されている。
  • KaaIoT:こちらもしっかりしたプラットフォームで、良質なArduino向けの機能と例があり、優れた可視化ツールもそろっている。

最終的に、このチュートリアルではKaaIoTの無料トライアル版を使うことにした。

Kaa IoTプラットフォームの無料トライアル

ステップ2:コードを書き込む

KaaIoTには、始めるための例がいくつも用意されているので、まずはそこから見ていこう。 ただしその前に、KaaIoTのダッシュボード内でプロジェクトを作る必要がある。

  1. KaaIoTに無料アカウントを作成する(あるいはサインインする)。
  2. クラウドに移動し、Rootアカウントにログインする。
  3. 新しいSolution(KaaIoTにおけるプロジェクトの呼び方)を作る必要がある。名前と説明を付ける。
  4. Device Management/Devicesに移動し、デバイスを追加する。これによって、固有のApplication Version(基本的にはUUID)を持つ新しいエンドポイントインスタンスが作られる。
  5. Endpoint Tokenを取得する。自分で作成することも、Kaaにランダムに生成させることもできる。このトークンは、エンドポイントの身元を確認するために使われるため、既知の発信元からの通信要求だけが受け付けられる。どちらの方法を選ぶにせよ、必ずコピーするか書き留めておくこと。ArduinoのコードにはApp VersionとTokenの両方が必要になるが、KaaIoTはこれらを後から取得できる秘密の場所に保存してはくれない。

コードそのものについては、KaaのGitHubリポジトリのコードをもとに、独自のBME280用の基本的なデモコードSGP40のコードを取り出し、この3つを組み合わせて使った。

/*
* Monitor Sensor Data from Anywhere
*
* Rob Reynolds, Mariah Kelly, SparkFun Electronics, 2022
*
* This sketch will collect data from a BME280, a SGP40, and use a
* SparkFun ESP32 Thing Plus ESP32 WROOM to send the data
* over WiFi to a KaaIoT dashboard.
* https://www.kaaiot.com/
* Want to support open source hardware and software?
* Why not buy a board from us!
* Thing Plus ESP32 WROOM - https://www.sparkfun.com/products/17381
* SparkFun Air Quality Sensor - SGP40 (Qwiic) - https://www.sparkfun.com/products/18345
* SparkFun Atmospheric Sensor Breakout - BME280 (Qwiic) - https://www.sparkfun.com/products/15440
*
* License: This code is public domain but you can buy us a beer if you use
* this and we meet someday at the local (Beerware License).
*
*/


// まず、必要なライブラリをすべてインストールする
#include <Wire.h>
#include <WiFi.h>

#include "SparkFun_SGP40_Arduino_Library.h" // ライブラリはこちらから入手できる:http://librarymanager/All#SparkFun_SGP40
#include "SparkFunBME280.h"

#include <PubSubClient.h> // ダウンロードはこちらから:https://github.com/knolleary/pubsubclient/archive/refs/tags/v2.8.zip
#include <ArduinoJson.h>  // このライブラリはライブラリマネージャーの検索バーから見つかる
#include "kaa.h" // これもライブラリマネージャーの検索バーから見つかる

#define KAA_SERVER "mqtt.cloud.kaaiot.com"
#define KAA_PORT 1883
#define KAA_TOKEN "ESP32DemoToken"     //ここに自分のKaaIoTトークンを入力する(KaaIoTで作成したもの)
#define KAA_APP_VERSION "*******************-v1"  //ここに自動生成されたApp Versionを入力する

#define RECONNECT_TIME  5000 //ms
#define SEND_TIME       3000 //ms

// センサーデータの出力名をここで定義する
#define COMMAND_TYPE "OUTPUT_SWITCH"
#define OUTPUT_1_NAME "temperature"
#define OUTPUT_2_NAME "humidity"
#define OUTPUT_3_NAME "VOC"
#define OUTPUT_4_NAME "altitude"
#define OUTPUT_5_NAME "pressure"

const char* ssid = "WirelessNetworkName";     //WiFiネットワーク名をここに入力する
const char* password = "WirelessNetworkPassword";     //WiFiパスワードをここに入力する

char mqtt_host[] = KAA_SERVER;
unsigned int mqtt_port = KAA_PORT;

unsigned long now = 0;
unsigned long last_reconnect = 0;
unsigned long last_msg = 0;

WiFiClient espClient;
PubSubClient client(espClient);
Kaa kaa(&client, KAA_TOKEN, KAA_APP_VERSION);

#define PRINT_DBG(...) printMsg(__VA_ARGS__)

BME280 mySensor;
SGP40  myVOCSensor; //SGP40クラスのオブジェクトを作る

void setup() {
  Serial.begin(115200);
  Serial.println("Reading basic values from BME280 and SGP40");

  //mySensor.enableDebugging(); // 役立つデバッグメッセージをシリアルに出力したい場合は、この行のコメントを外す

  setupWifi();
  client.setServer(mqtt_host, mqtt_port);
  client.setCallback(callback);

  Wire.begin();

  //センサーを初期化する
  if (myVOCSensor.begin() == false) {
    Serial.println(F("SGP40 not detected. Check connections. Freezing..."));
    while (1); // これ以上何もしない
  }
  if (mySensor.beginI2C() == false) {   //I2C経由で通信を開始する
    Serial.println("The sensor did not respond. Please check wiring.");
    while (1); //停止する
  }
}

void loop() {
  if (!client.connected()) { //接続状態を確認する
    now = millis();
    if ( ((now - last_reconnect) > RECONNECT_TIME) || (now < last_reconnect) ) {
      last_reconnect = now;
      reconnect();
    }
    return;
  }
  client.loop();

  //何かを送信する
  now = millis();
  if ( ((now - last_msg) > SEND_TIME) || (now < last_msg) ) {
    last_msg = now;

    //ここで送信する
    sendOutputsState();
  }
}

void printMsg(const char * msg, ...) {
  char buff[256];
  va_list args;
  va_start(args, msg);
  vsnprintf(buff, sizeof(buff) - 2, msg, args);
  buff[sizeof(buff) - 1] = '\0';
  Serial.print(buff);
}

String getChipId() {
  char buf[20];
  uint64_t chipid = ESP.getEfuseMac();
  sprintf(buf, "%04X%08X", (uint16_t)(chipid >> 32), (uint32_t)chipid);
  return String(buf);
}

void composeAndSendMetadata() {
  StaticJsonDocument<255> doc_data;
  String ipstring = (
                  String(WiFi.localIP()[0]) + "." +
                  String(WiFi.localIP()[1]) + "." +
                  String(WiFi.localIP()[2]) + "." +
                  String(WiFi.localIP()[3])
                );

  // ここに、基板や場所など、任意の固定データを挿入する
  doc_data["name"] = "ESP32";
  doc_data["model"] = "SparkFun Thing Plus";
  doc_data["location"] = "Niwot, CO";
  doc_data["longitude"] = "40° 5' 25.5474";
  doc_data["latitude"] = "-105° 11' 6.2874";
  doc_data["ip"] = ipstring;
  doc_data["mac"] = String(WiFi.macAddress());
  doc_data["serial"] = String(getChipId());

  kaa.sendMetadata(doc_data.as<String>().c_str());
}

void sendOutputsState() {
  StaticJsonDocument<255> doc_data;

  // ここでセンサーデータを取得し、出力に割り当て、ダッシュボードへ送信する
  doc_data.createNestedObject();
  doc_data[0][OUTPUT_1_NAME] = mySensor.readTempF();  // 温度のセンサーデータを読み取る
  doc_data[1][OUTPUT_2_NAME] = mySensor.readFloatHumidity(); // 湿度のセンサーデータを読み取る
  doc_data[2][OUTPUT_3_NAME] = myVOCSensor.getVOCindex(); // VOCセンサーのデータを読み取る
  doc_data[3][OUTPUT_4_NAME] = mySensor.readFloatAltitudeFeet(); // 高度のセンサーデータを読み取る
  doc_data[4][OUTPUT_5_NAME] = mySensor.readFloatPressure(); // 気圧のセンサーデータを読み取る
  kaa.sendDataRaw(doc_data.as<String>().c_str());  // Kaa IoT Cloudへデータを送信する

}



void setupWifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.print(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  String ipstring = (
                  String(WiFi.localIP()[0]) + "." +
                  String(WiFi.localIP()[1]) + "." +
                  String(WiFi.localIP()[2]) + "." +
                  String(WiFi.localIP()[3])
                );
  Serial.println();
  PRINT_DBG("WiFi connected\n");
  PRINT_DBG("IP address: %s\n", ipstring.c_str());
}

void callback(char* topic, byte* payload, unsigned int length) {
  PRINT_DBG("Message arrived [%s] ", topic);
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  kaa.messageArrivedCallback(topic, (char*)payload, length);
}

void reconnect() {
  PRINT_DBG("Attempting MQTT connection to %s:%u ...", mqtt_host, mqtt_port);
  // クライアントIDを作る
  String clientId = "ESP8266Client-";
  clientId += String(getChipId());
  // 接続を試みる
  if (client.connect(clientId.c_str()))
  {
PRINT_DBG("connected\n");
kaa.connect();
composeAndSendMetadata();
  } else
  {
    PRINT_DBG("failed, rc=%d try again in %d milliseconds\n", client.state(), RECONNECT_TIME);
  }
}

Arduinoのシリアルモニタを開いてデータの流れを確認すれば、コードがローカルで正しく動作しているか確かめられる。 それが確認できたら、今度はダッシュボードに戻り、そちらでもデータを受信できているか確認する準備が整ったことになる。

Arduinoのシリアルモニタを見れば、Thing Plus Wroomが期待どおりにデータを読み取れているかがわかる。

KaaIoTのDevice Management/Devicesページに移動すれば、センサーデータが実際に受信されているかを確認できる。 KaaIoTには、温度、湿度、気圧などを自動で検出してくれる仕組みが備わっている。

(KaaIoTの各ページの左側にある)ナビゲーションバーが、必要な場所への移動を助けてくれる。

Note

注意:温度の範囲は100未満なのに対し、気圧の範囲(Pa単位で送信している)は80,000を超えているため、範囲が広すぎてKaaIoTのDevice Telemetryウィンドウでは変化を見て取ることができなかった。そこで、気圧の値を表示するチャートのポイントを非表示にした(標高の値についても同様である。コロラド州のこのあたりでは、標高の値がかなり大きいのである)。温度と湿度だけを表示するようにしたところ、ダッシュボードに値が届いているだけでなく、センサーに息を吹きかけると、その値がリアルタイムで変化する様子も確認でき、正確に動作していることがわかった(下記参照)。

ダッシュボードのDevicesページにあるDevice Telemetryウィンドウでは、届いたデータをリアルタイムで確認できる。

これで、センサーがデータを読み取れていること、ESP32がデータを送信できていること、そしてダッシュボードがデータを受信できていることが確認できた。次は、そのデータをどう表示したいかを決める番である。

ステップ3:ダッシュボードを調整する

このプロジェクトでKaaIoTを選んだ理由の一つは、情報を表示するための既製のウィジェットが幅広くそろっている点にあった。 ここでは、届いたデータを見やすく、かつ視覚的に楽しい形で表示できるよう、ダッシュボードを設定していく。

  1. 画面左側にあるSolutionsをクリックすると、自分のプロジェクトがすべて表示された画面になる。とはいえ、この時点では1つしかないはずである。自分のSolutionを選択する。
  2. 現在のプロジェクトに含まれるすべてのダッシュボードが表示された画面になる(こちらも、この時点では「Home」という名前のダッシュボードが1つだけのはずである)。そのダッシュボードを選択する。
  3. これでメインのダッシュボードに移動する。現時点では空っぽになっているはずである。画面左側の大きな「Add Widget」ボタンをクリックし、まずは温度を表示するウィジェットから始めよう。
  4. Gaugesウィジェットのいずれかを選ぶ。筆者はVertical Bold gaugeを選んだ。
  5. 右上のEditをクリックすれば、このウィジェットを編集できる。これによって、適切な情報、データ、見た目を設定できるようになる。筆者が使用した値をすべて以下の表に示す。Application NameやEndpoint IDのように具体的な指定が必要な項目もあるが、それ以外の多くは自由に調整してよい。
EDIT WIDGET
Widget Decoration
TitleTemperature
Display Header
Use Transparent Background
Display Icon
Z Index
Easy Load
Hide Based on Condition
Data Source
Service Instance Name**epts
Application**自分が名付けたApplication
Endpoint ID**自分のEndpoint ID
Time Series**auto-temperature
Time Series Value**values.value
Reference TimestampLatest
Update Interval1 seconds
Variables
Appearance
Gauge TypeVertical Bold
Precision2
PostfixF
Gauge Scale
Lower Boundary0
Upper Boundary100
Step10
Color Coding
Base ColorRed
Thresholds
ABC <=20 / Violet
ABC <=40 / Blue
ABC <=60 / Green
ABC <=80 / Lemon
ABC <=100 / Red

**印の付いた項目は、ほぼ固定の値である。それ以外の項目は自由に工夫してかまわない。

温度ウィジェットの表示例。

ウィジェットが望みどおりの見た目になったら、画面右上の「Publish Changes」ボタンをクリックして確定させる。 Edit Mode(あるいはその隣にあるLockスライダー)をクリックすれば、ダッシュボードがロックされる。 これで、世界のどこにいても、Webに接続できる場所であればどこからでもデータを確認できるようになった。 筆者はスマートフォンでもKaaIoTのWebサイトを開いてみたが、完全に閲覧・操作でき、ウィジェットの編集まで問題なく行うことができた。

トラブルシューティング

このプロジェクトで大きな問題に遭遇することはあまりないと思われるが、筆者と似たタイプの人であれば、どこかに置き忘れた括弧やセミコロンに頭を悩ませることもあるかもしれない。 期待どおりに動作しない場合に確認すべき、いくつかのポイントを紹介する。

Arduinoのシリアルモニタにセンサーの読み取り値がまったく表示されない場合、たいてい環境センサーと通信できていないことを示すメッセージが表示されているはずである。「The sensor did not respond. Please check wiring.」のようなメッセージが出るだろう。 WiFiに接続できていない場合は、シリアルモニタに「Connecting to <ネットワーク名>. Failed, trying again in x milliseconds」のようなメッセージが表示されるはずである。 ネットワーク名とパスワードが正しいか、再度確認してほしい。 それらがすべて問題なさそうなのに、ダッシュボードにデータが届かない場合は、Arduinoのスケッチに書き込んだApp VersionとApp Token(KaaIoTで作成したもの)が正しいか確認してほしい。

それ以外については、おおむね迷うところはないはずである。 筆者は、KaaIoTのダッシュボードでウィジェットを編集する際にたびたびつまずくことがあった。各ウィジェットの右上をクリックしてもEdit/Clone/Deleteのオプションが表示されず、まるでウィジェット自体を左クリックして画面上の新しい位置へドラッグしようとしているかのような挙動になってしまうことがあった。 この対策として、ウィジェットの外側でマウスの左ボタンを押したままウィジェットの右上までドラッグし、そこでノートパソコンのタッチパッドを使って左クリックする、という方法を見つけた。 毎回起こる問題ではなかったが、ノートパソコンでもデスクトップでも見られる現象だった。

さらに詳しく

このプロジェクトをさらに発展させるもっとも簡単な方法は、次々と拡充されているQwiicセンサーのラインナップから、さらにセンサーを選んでいくことである。 届いたセンサーデータを読み取るだけでなく、プロジェクトへコマンドを送信するように拡張することもできる。 湿度が上がりすぎていないだろうか。除湿機の電源を入れるリレーを切り替えればよい。そう、地球の反対側にあるあの除湿機のことである。 KaaIoTは現在Androidアプリを開発中だが、これをさらに発展させたり、iPhone向けに自分で作ってみたりするのもよいだろう。 WiFiとIoTが広げる可能性は事実上無限であり、ここまでの基礎を身につけたあなたのプロジェクトは、海を越えて羽ばたいていけるはずである。

プロジェクトに追加するQwiic部品のアイデアが欲しければ、次のような人気のセンサーも参考にしてほしい(いずれも英語)。

タグ: 3Dプリント、Arduino、通信、部品、概念、データロギング、ESP32、接続ガイド、IoT、ロギング、MQTT、プロジェクト、Qwiic、センサー、WiFi、無線


出典:Monitor Sensor Data from Anywhere(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

ヒューズブレイクアウトボードの使い方

はじめに

このチュートリアルでは、2種類のヒューズを見ていき、ヒューズブレイクアウトボードを組み立て、回路に保護素子として追加する。

必要な部品

このチュートリアルの内容を試すには、ブレイクアウトボードと組み合わせるヒューズが必要である。手元にあるものによっては、すべてが必要になるとは限らない。ガラス管ヒューズを使う場合の最小限の部品はキット版に含まれているが、試作やテストの際に交換できるよう、ガラスヒューズは複数個入手しておくことをおすすめする。

個別にブレイクアウトボードを注文する場合は、SparkFunのヒューズのカテゴリから、自分のプロジェクトに合ったヒューズを選ぶことができる。必要なヒューズクリップとコネクタも忘れずに入手すること。

工具

はんだごて、はんだ、そして一般的なはんだ付け用品が必要である。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

ヒューズはどうやって動作するのか

ヒューズ)は、プロジェクトを過電流から保護するための電子部品である。 メーカーや用途によって、電流や電圧の定格はさまざまである。 ヒューズが切れる速さにも、スローブロー(別名タイムディレイ)ノーマルブローファストブローウルトラファストといった種類がある。 ヒューズにはさまざまな種類があるが、ここでは次の2種類に絞って扱う。

  • ガラス管ヒューズ
  • 自己復帰型ヒューズ(別名、正温度係数(PTC)ヒューズ)

Note

ヒューズについてさらに知りたい場合:Digi-Keyによる、ヒューズの不具合をテスト・特定する方法についての優れた記事と動画を、こちらで見ることができる。

ガラス管ヒューズ

「ヒューズ」と聞いてまず思い浮かぶのは、たいていガラス管ヒューズだろう。仕組みはいたって単純である。 電流がヒューズの定格を超えると、ヒューズ内部の細いフィラメントが発熱して切れる(電球が切れるのと同じ原理である)。 これによって回路が遮断され、うまくいけば回路が溶解による破壊から救われる。 ガラス管は、ヒューズが切れているかどうかを目視で確認できるという利点があるが、セラミック管に比べると対応できる電流の故障は小さめである。

仕様によっては、フィラメントが光りながら派手に飛び散るように切れることもあれば、しばらく光ってから溶けるだけのこともある。 また、切断される前に曲がったり、小さな金属の球状に溶けたりすることもある(こちらはそれほど派手ではない)。

自己復帰型ヒューズ(別名PTC)

正温度係数(PTC)素子(マルチヒューズ、ポリヒューズ、ポリスイッチ、あるいはサーミスタとも呼ばれる)は、電流が流れるにつれて抵抗が増加していくデバイスである。 左側のPTCはスルーホール実装用、右側はSMD実装用である。

スルーホールタイプのPTCSMDタイプのPTC

PTCは頼りになる存在である。電子工作の初心者は、しばしば短絡を起こしたり、うっかり配線を逆につないでしまったりする。 これらのPTCは、ある一定の電流(たとえば500mAまでを保護する250mAのPTCだとする)に達すると抵抗値が劇的に増加し、電流の流れを制限するよう設計できる。 このような自己復帰型ヒューズは、以下の画像のように、USBポートに接続するタイプのモータードライバ基板やマイクロコントローラの一部で見つけることができる。

Raspberry Pi用Servo Hatの自己復帰型ヒューズArduino Uno用のカスタム自己復帰型ヒューズRedBoard Artemisの自己復帰型ヒューズ

基本的に、PTCは自己復帰型ヒューズとして機能する。 このデバイスは、電圧レギュレータの手前、直列につなぐのがよい。 回路が500mAを超える電流を引き込むと(たとえば電源をグラウンドへ短絡させてしまった場合など)、250mAのPTCが発熱し、電流を250mAに制限する。 短絡状態を取り除くと、電流は元の水準まで下がり、PTCは冷えて、回路は通常どおり動作を再開する。 これは、多くの設計を発煙から救ってくれる、実に頼もしい小さな部品である。

Beginning Embedded Electronics Tutorial Seriesの設計に組み込まれた自己復帰型ヒューズ。

以下のスルーホールタイプPTCの熱画像は、PTCが動作したときに何が起きるかをよく示している。 左の熱画像は、電圧レギュレータ回路が通常の状態にあるときのものである。 右の画像は、回路が短絡したときのものである。 回路に流れる危険な電流を制限しようとするにつれ、PTCがどれだけ熱くなっているか(なんと213°F!)に注目してほしい。 この見事な熱画像を提供してくれたJoshua Weaver氏に、心から感謝する。

通常の条件下で動作する電圧レギュレータ回路の損傷を防ぐために動作したPTCヒューズ

ハードウェアの概要

VIN

左側には、入力であるVINがある。 入力側(黄色でハイライトした部分)には2ピンのねじ端子(5mm)をはんだ付けできる。 あるいは、(センタープラスのバレルジャックを持つ)ACアダプタを極性を保ったまま簡単に接続したい場合は、(黒色でハイライトした部分に)バレルジャックをはんだ付けすることもできる。

5mmねじ端子は、バレルジャックの接点と比べて、より大きな電流に対応できる点に注意してほしい。 とはいえ、SparkFunのカタログで扱っているDC用ACアダプタは、電源供給にバレルジャックを使っている。 プロジェクトに応じて適切な太さのものであれば、ブレイクアウトボードに配線を直接はんだ付けすることもできる。

ガラスヒューズ

Note

注意:この基板は直流電源用に設計されている。交流電源用には設計されていない。保護用のガラスヒューズは、必ず直流側で使用すること。

ヒューズブレイクアウトボードは、5Aのガラス管ヒューズまでテスト済みである。

ガラス管ヒューズを使う場合、基板にはんだ付けする必要のあるクリップが2つある。 クリップの向きを間違えないようにはんだ付けすること。

PTCヒューズ

自己復帰型のPTCヒューズを使いたい場合に備えて、PTCヒューズ用のスルーホールも用意されている。 この基板はスルーホールタイプのPTC向けに設計されているが、試作段階であれば、このパッドにSMDタイプのPTCヒューズをはんだ付けすることもできる。SMDヒューズのサイズによっては、ぴったりとは収まらないかもしれない。

VOUT

右側には、出力であるVOUTがある。ここには2ピンのねじ端子(5mm)をはんだ付けできる。

取り付け穴

基板をパネルや筐体に取り付けたい場合のために、4つの取り付け穴が用意されている。 基板のサイズを最小限に抑えるため、半円形の取り付け穴が採用されている。

基板の寸法

基板のサイズは0.50インチ×2.56インチである。 基板を取り付けたり複数枚を並べて配置したりする場合のために、半円形の取り付け穴が4つ用意されている。

ハードウェアの組み立て

コネクタとヒューズクリップを、ブレイクアウトボードにはんだ付けする必要がある。部品をはんだ付けする順序は自由に決めてよい。 はんだ付けをしたことがない場合は、はんだ付けの基本(スルーホール編)のチュートリアルにコツがまとまっている。

入出力コネクタをはんだ付けする

VIN側には2つの選択肢がある。センタープラスのバレルジャックを持つACアダプタと組み合わせて使う場合は、バレルジャックコネクタを使うとよい。それ以外の場合は、VIN側に5mmのねじ端子をはんだ付けすればよい。

VIN用のバレルジャックVIN用の5mmねじ端子

入力側のはんだ付けが終わったら、VOUT側にもねじ端子を取り付ける。

Note

注:キットを注文した場合、基板に部品をはんだ付けした後、コネクタが1つ余るはずである。プロジェクトの必要に応じて選べるよう、余分に同梱している。部品箱にしまっておき、必要になったら取り出して使ってほしい。

5mmヒューズクリップをはんだ付けする

次のステップは、ガラスヒューズ用のクリップを基板にはんだ付けすることである。 両側にクリップを挿入する。 各脚を基板に仮止めする前に、クリップの向きが正しいことを確認しておく必要がある。 それぞれのヒューズクリップのシルク印刷をよく見ると、四角形の一辺に補助線が引かれているのがわかる。 これが、湾曲した部分を向けるべき側である。 各脚を仮止めしたら、もう一方の脚もはんだ付けする。 はんだ付け中はクリップが熱くなることがあるので、テープで基板に固定するか、小さな厚紙片でクリップを基板に押さえておくとよい。

ヒューズクリップをより詳しく見たい場合は、画像をクリックしてほしい。

Note

注:ブレイクアウトボードをPTCヒューズと組み合わせて使う場合は、ヒューズクリップをはんだ付けする必要はなく、スルーホールタイプのPTCヒューズをそのままはんだ付けするだけでよい。スルーホールタイプのPTCから余ったリード線は、フラッシュカッターで切り落とす必要がある。上級者向けとしては、スルーホール用のパッドにSMDタイプのPTCヒューズをはんだ付けすることもできる。

システムにヒューズを組み込む

ガラスヒューズを使う場合は、これでガラス管をクリップに挿入できる。 ヒューズが切れてしまった場合は、マイナスドライバーを使って慎重にこじ開けて取り出せばよい。

それ以外の場合は、VIN側にバレルジャックを挿入するか、電源と負荷の間の被覆を剥いた配線をねじ止めして固定する。 電圧線とグラウンド線については、シルク印刷を必ず確認しておくこと。

取り付け

設計には、半円形の取り付け穴が含まれている。 これは、基板をパネルや筐体に取り付けたい場合に便利である。 取り付けるには、次の手順が必要である。

  • スペーサー(あるいはネジとスペーサー)を締める。
    • 基板をハードウェアの間に滑り込ませるための隙間を確保しておくこと。
  • スペーサーの間に基板を挟んで締める。
    • 複数枚のヒューズブレイクアウトを使う場合は、締める前に2枚の基板の間にスペーサーを配置すること。
  • 各スペーサーについて同じ手順を繰り返す。

ヒューズを選ぶ際の考慮事項

どのヒューズを選ぶかは、プロジェクトによって異なる。 電源や電池の後段にヒューズを配置する際に考慮すべき点をいくつか紹介する。

プロジェクトの電圧・電流の要件

まず、負荷の電圧と電流に耐えられるヒューズを選ぶ必要がある。 ヒューズのデータシートに、その情報が記載されているはずである。 次に、回路を損傷させることなく、プロジェクトが電源から引き込むと想定される最大電力を測定する。 プロジェクトがある程度の時間にわたって過剰な熱を発生させる場合は、それも考慮に入れる必要がある。 測定結果をもとに、ヒューズが切れる、あるいは動作する電流を決める必要がある。 この値は、たいてい動作電流以下で、かつ電源の許容電流の範囲内に収める(つまり、20Aの大電流電源を使っていて、負荷の一部が1Aを引き込んだ時点でヒューズを動作させたい、というような場合である)。 モーターを使うロボットのように、短時間の電流スパイクが発生するプロジェクトには、スローブロー(タイムディレイ)タイプが必要になる。 即座にヒューズを切りたい他のプロジェクトには、ファストタイプやウルトラファストタイプが必要になるだろう。 ここでは、室温での使用を前提とする。

ガラス管ヒューズかPTCか

大電流の電源には、プロジェクトから完全に切り離してヒューズが切れるガラス管ヒューズを検討するとよいだろう。 低電流の電源には、自己復帰型ヒューズを検討するとよい。 ただし、自己復帰型ヒューズは動作時に発熱することがあり、動作中も負荷側にわずかに電流が漏れ続ける点には注意しておく必要がある。

負荷試験

試作に使うヒューズを決めたら、必ず実際にテストしておくこと。 そう、それはガラス管ヒューズを犠牲にするということだが、回路が予想外の挙動を始めたときに、この部品が期待どおりに機能することを確認しておく必要がある。

大電流の電源

この基板を設計するきっかけになったのは、Hackadayの記事「The Engineering Case for Fusing Your LED Strips」を読んだことだった。 大電流を出力する電源は、負荷にひたすら電流を流し続けてしまう。 これによって回路が損傷したり、火災の危険が生じたりすることもある。 電源の出力の近くにヒューズを配置しておけば、この先で何が起きても回路を保護できる。 この場合、ヒューズが切れて、残りのLEDへの電源供給を遮断してほしいということになる。 1つの大電流電源から複数のLEDストリップを駆動する場合は、それぞれのLEDストリップの区間ごとに電流を分割すればよい。

低電流の電源

低電流の電源で自己復帰型のPTCヒューズを使う場合は、入力電圧のすぐ後段に配置するとよい。 以下は、ACアダプタと電圧レギュレータの間にPTCを配置した回路図の例である。 試作段階でブレイクアウトボードにPTCヒューズを組み込んでおくと、最終設計に組み込む前に、セットアップを手早くテストするのに役立つ。

Breadboard Power Supply Kitの設計で使われているPTCヒューズ。

以下は、USBコネクタとマイクロコントローラの間にPTCヒューズを配置した例である。

RedBoard Qwiicの設計で使われているPTCヒューズ。

Note

ヒント:さらに回路を保護したい場合は、逆電流保護用にヒューズとショットキーダイオードを組み合わせて追加するとよい。

ダイオードのチュートリアルにある逆電流保護の回路。

まとめ

ヒューズブレイクアウトボードを無事に動かせるようになったところで、いよいよ自分のプロジェクトに組み込む番である。さらに詳しい情報は、次のリンクを参考にしてほしい。

さらにアイデアが欲しい場合は、次の関連チュートリアルも参考にしてほしい(いずれも英語)。

タグ: 部品、概念、接続ガイド、電力、プロジェクト、プロトタイピング、はんだ付け


出典:Fuse Breakout Board Hookup Guide(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

初心者向けLEDアニメーションの基礎(Arduino編)

はじめに

光を制御したいという欲求は、文字による記録が残るよりもずっと昔から、人類につきまとってきた。 明かりの持つ力は、誰の中にも生物的な感覚を呼び起こす。 木に蓄えられたエネルギーを化学的に燃焼させる方法から、より揮発性の高いガソリン蒸気へと、私たちは進化してきた。 物理的な炎は、やがて温かく輝く繊細な金属コイルに取って代わられた。 筆者のお気に入りの発光方法は、それよりもずっと単純で、電子がエネルギーを放出するエレクトロルミネセンスという現象そのものである。 発光ダイオード、いわゆるLEDは、過去の発光方法よりもはるかにエネルギー効率がよく、暗闇と戦うための、ほぼ無限とも言える可能性を与えてくれる。

このチュートリアルでは、LEDの扱いについてのいくつかの概念を振り返りながら、RedBoard Qwiicで個々のLEDを制御し、楽しいエフェクトを作ってみる。

必要な部品

このチュートリアルの内容を試すには、次の部品が必要である。手元にあるものによっては、すべてが必要になるとは限らない。

Note

注意:以下の画像では赤色版の超音波距離センサーを使用しているが、より正確な新しいモデルに置き換わっている。必ず赤色ではなく青色のバージョンを入手すること。

この部品一覧は、RedBoard Qwiicを搭載した新しいSparkFun Inventor’s Kitから抜粋したものである。電子部品をもっとたくさん揃えたい場合は、フルセットを購入してもかまわない。

基礎の振り返り

LEDについての重要なポイントを、いくつか思い出しておこう。

  1. 他のダイオードと同じく、電流は一方向にしか流れない
    • 十分に高い電圧をかければ、電流は逆方向にも一瞬だけ流れる。もちろん、あのマジックスモークとともにである。
  2. 同じく他のダイオードと同様、動作するには「最低限」の電圧が必要である。
  3. 最後に、光が「より青い」ほど、より多くのエネルギーを使っている。

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。ここに挙げたポイントの多くは、LEDを使った基本的な回路のルールを説明する、以前のチュートリアルで扱った内容である。振り返りたい場合は、ぜひそちらも確認してみてほしい。

Arduinoやブレッドボード、その他の電子工作の基礎に馴染みがない場合は、次のようなチュートリアルやガイドにもぜひ目を通してみてほしい。

Note

注:この例では、デスクトップに最新版のArduino IDEがインストールされていることを前提としている。Arduinoを初めて使う場合は、Arduino IDEのインストールのチュートリアルを確認してほしい。

CH340デバイスをパソコンに接続したことがない場合は、USB-シリアル変換用のドライバをインストールする必要があるかもしれない。インストールの参考として、CH340ドライバのインストール方法のセクションを確認してほしい。

順方向電圧

LEDは、他のダイオードと同様、動作するのに「最低限」の電圧を必要とする。 回路解析では、これを電圧降下と呼ぶ。 ダイオードの場合、この順方向電圧は利用可能な電圧の一部を「消費している」と考える。トラブルシューティングのコツその1:

  • アノードとカソード間の電圧が、動作に必要な最低限の順方向電圧を満たしているか確認すること。「最低限」という言葉はやや大まかに使っている。古くて弱った電池をLEDの端子に触れさせても、かすかに光ることがあるからである。

電流が多すぎる場合

LEDには最低限の要件があることを確認したが、最大値も存在する。 たいていの物理の教科書では、電流の例え話として水が使われる。 配管が破裂したことがある人なら、あまりに多くのものが一気に流れ込むことの危険性がわかるはずである。 ここでも、LEDのデータシートを確認し、電圧をかけすぎていないか確かめること。 電圧を上げれば、電流も上がる。トラブルシューティングのコツその2:

  • LEDの内部で、ぱっと光った後に暗い点が見えたら、それはもう壊れてしまったということである(また、古いLEDがどうしても点灯しない場合、誰かがうっかりやらかしたのかもしれない、ということも覚えておいてほしい)。

抵抗は味方になる

最初の2つのポイントで大きな鍵となるのが、抵抗を使って電流を制限するという考え方である。 電圧が高すぎる場合、LEDと直列に適切な抵抗を入れれば、より安全な水準まで電圧を下げることができる。 電圧は問題ないのにダイオードが次々と切れてしまい、LEDの手持ちが少なくなってきたとしよう。 理想的ではないが、大電流で意図的に切れるように設計された抵抗、いわゆるヒューズ抵抗というものもある。

GPIOによる単純なON/OFF

LEDのピンをコイン電池に触れさせるだけでも十分に単純で、テープを少し貼れば、それだけで超簡単な懐中電灯になる。 では、制御や派手さが欲しい場合はどうだろうか。LEDが一方向にしか電流を通さないからといって、私たちの発想まで一方向に縛られる必要はない。 ここからは、いくつかの単純な部品を組み合わせ、マイクロコントローラが照明の要求に対して何をしてくれるのか、いろいろ試していく。

まずはGPIOについて話そう。これはGeneral Purpose Input and Output(汎用入出力)の略で、単純に入力または出力のために使われる。 つまり、設定次第で、そのピンは電圧信号を受け取ることも、電圧信号を出力することもできるということである。 RedBoardでは、「オン」(つまり出力)の電圧は、非常に扱いやすい5ボルトである。 これをATMEGAのICに行わせるには、ArduinoのコードでdigitalWrite(PIN_NUMBER, HIGH);と書けばよい。 しかし、これをそのままloopセクションにコピー&ペーストしただけではうまく動かないことに気づくはずである。 まず、そのピンをどう扱いたいかを宣言しておく必要がある。 そこで、ピン番号を簡単に参照できるよう変数を作る。それがPIN_NUMBERである。 単純にするため、ここではRedBoard Qwiicのデフォルトのピンである13番ピンを使う。 次にsetup()関数の中で、pinMode(PIN_NUMBER, OUTPUT);と書く必要がある。 これは、そのピンを出力用として割り当てるという意味である。 これによって、デジタルハイを書き込んだとき、ICは何をすればよいか正確に把握できる。 マルチメーターを接続すれば、あるいはオシロスコープを使えば、そのピンはdigitalWrite(PIN_NUMBER, LOW);でLOWを宣言するまで、GND(0V)を基準に5Vになっているはずである。 つまるところ、これがオンからオフ、そしてまたオフへと戻る「点滅」というものである。 時間の遅延を加えることで、さまざまな効果を作ることができる。

//この例は、遅延を挟みながらGPIOピンをON/OFFする。

const int PIN_NUMBER = 13; //'PIN_NUMBER'を実際のピン番号に置き換える。ここではRedBoard Qwiicの13番ピンに内蔵されたLEDを使う

void setup() {
  pinMode(PIN_NUMBER, OUTPUT);    //デジタルピンを出力として設定する
}

void loop() {

  digitalWrite(PIN_NUMBER, HIGH); //13番ピンに接続されたLEDが点灯する
  delay(5000);                    //delay(ミリ秒)なので、'5000'は5秒
  digitalWrite(PIN_NUMBER, LOW);  //13番ピンに接続されたLEDが消灯する
  delay(5000);                    //delay(ミリ秒)なので、'5000'は5秒

}

「なるほど、それで結局何の役に立つのか」

これは、これらの「補助的なピン」が入力にも、今回のように出力にも使えるということを示している。 このステップを踏まえれば、この先には非常にたくさんの選択肢が広がっている。 ここから先は、LEDを使った楽しい配置やエフェクト、実用的な使い道をいろいろと探っていく。

マイクロコントローラのピンについて、少ししつこく説明しすぎたかもしれない。 ピン自体だけで一連のチュートリアルになるほどのテーマだが、ここではそこまでは扱わない。 それでもこれを強調しているのは、これらのピンが、複数のLEDを制御するための配線網の要になるからである。

大きな視点で見ると、回路のどこかに電圧のかかったポイントがあり、その電圧が十分に高ければ(そして高すぎなければ、LEDを壊さずに済む)、LEDを点灯させることができる、ということである。 GPIOピンの出力は、必要な電力を供給する電源として働く。 これらは、スイッチと電球であふれた部屋の中にある、ちょっと気の利いたスイッチのようなものだと考えるとよい。

ライト、カメラ、アクション

Booyahのように点滅させる

以下の回路図で、すべてがどう接続されているか確認してみよう。

回路が見づらい場合は、画像をクリックして拡大表示してほしい。

この例では少し遊んでみることにした。それぞれのLEDのセットを1つずつ順番に点灯させていく。あるセットが点灯し終わったら、次のセットに移る前に、それらを1つずつ順番に消灯していく。

以下のコードをArduino IDEにコピー&ペーストする。アップロードして、何が起こるか見てみよう。

//この例は、それぞれのLEDセットを1つずつ順番に点灯させる。あるセットが点灯し終わったら、次のセットに移る前に、それらを1つずつ順番に消灯していく。

//ピンを宣言する
const int GREEN_A = 8;
const int GREEN_B = 7;
const int GREEN_C = 6;
const int RED_A = 5;
const int RED_B = 4;
const int RED_C = 3;
const int BLUE_A = 11;
const int BLUE_B = 10;
const int BLUE_C = 9;

const int turn_time = 300;      //この整数値をいろいろ変えて試してみよう

void setup() {
  // ピンを出力として初期化する
  pinMode(GREEN_A, OUTPUT);
  pinMode(GREEN_B, OUTPUT);
  pinMode(GREEN_C, OUTPUT);
  pinMode(RED_A, OUTPUT);
  pinMode(RED_B, OUTPUT);
  pinMode(RED_C, OUTPUT);
  pinMode(BLUE_A, OUTPUT);
  pinMode(BLUE_B, OUTPUT);
  pinMode(BLUE_C, OUTPUT);
}

void loop() {
  //この一連の処理は、同じ色のLED3個を1つずつ順番に点灯させ、
  //その後1つずつ順番に消灯するだけである。
  digitalWrite(BLUE_A, HIGH);   // LEDを点灯する(HIGHが電圧レベル)
  delay(turn_time);                       // 少し待つ
  digitalWrite(BLUE_B, HIGH);   // LEDを点灯する(HIGHが電圧レベル)
  delay(turn_time);                       // 少し待つ
  digitalWrite(BLUE_C, HIGH);   // LEDを点灯する(HIGHが電圧レベル)
  delay(turn_time);                       // 少し待つ
  digitalWrite(BLUE_A, LOW);    // 電圧をLOWにしてLEDを消灯する
  delay(turn_time);                       // 少し待つ
  digitalWrite(BLUE_B, LOW);    // 電圧をLOWにしてLEDを消灯する
  delay(turn_time);                       // 少し待つ
  digitalWrite(BLUE_C, LOW);    // 電圧をLOWにしてLEDを消灯する
  delay(turn_time);                       // 少し待つ

  digitalWrite(GREEN_A, HIGH);   // LEDを点灯する(HIGHが電圧レベル)
  delay(turn_time);                       // 少し待つ
  digitalWrite(GREEN_B, HIGH);   // LEDを点灯する(HIGHが電圧レベル)
  delay(turn_time);                       // 少し待つ
  digitalWrite(GREEN_C, HIGH);   // LEDを点灯する(HIGHが電圧レベル)
  delay(turn_time);                       // 少し待つ
  digitalWrite(GREEN_A, LOW);   // LEDを消灯する
  delay(turn_time);                       // 少し待つ
  digitalWrite(GREEN_B, LOW);   // LEDを消灯する
  delay(turn_time);                       // 少し待つ
  digitalWrite(GREEN_C, LOW);   // LEDを消灯する
  delay(turn_time);                       // 少し待つ

  digitalWrite(RED_A, HIGH);   // LEDを点灯する(HIGHが電圧レベル)
  delay(turn_time);                       // 少し待つ
  digitalWrite(RED_B, HIGH);   // LEDを点灯する(HIGHが電圧レベル)
  delay(turn_time);                       // 少し待つ
  digitalWrite(RED_C, HIGH);   // LEDを点灯する(HIGHが電圧レベル)
  delay(turn_time);                       // 少し待つ
  digitalWrite(RED_A, LOW);    // 電圧をLOWにしてLEDを消灯する
  delay(turn_time);                      // 少し待つ
  digitalWrite(RED_B, LOW);    // 電圧をLOWにしてLEDを消灯する
  delay(turn_time);                      // 少し待つ
  digitalWrite(RED_C, LOW);    // 電圧をLOWにしてLEDを消灯する
  delay(turn_time);                      // 少し待つ

}

この例は、少し手を加えて試してみるとよい。turn_timeの値を変えてみよう。 delay()関数はこれらの整数値を引数に取り、ミリ秒を表す。50ならとても速く、5000ならとてもゆっくり動く。

催眠ガエル

以下の回路図で、すべてがどう接続されているか確認してみよう。

Arduino IDEには、Blink以外にも本当に優れた初心者向けの例がそろっている。 筆者のお気に入りはLED Fadeである。 これを少し手直しして、2つのLEDをフェードさせ、目に見立てて使ってみよう。 このフェード機能はanalogWrite()に頼っている。 この関数はパルス幅変調(PWM)信号を出力する。 整数値が小さいとLEDは暗くなり、大きいとLEDは明るくなる。

以下のコードをArduino IDEにコピー&ペーストする。アップロードして、何が起こるか見てみよう。

//この例は1つのLEDをフェードイン・フェードアウトさせる。その後、もう一方のLEDもフェードイン・フェードアウトする。

//ピンと変数を宣言する
const int ledA = 9;
const int ledB = 10;
int brightness = 0;
int fadeAmount = 5;

void setup() {

  //ピンを出力として宣言する
  pinMode(ledA, OUTPUT);
  pinMode(ledB, OUTPUT);
}

void loop() {

  //ledAがフェードインする
  for (int i = 0; i <= 255;) {
    analogWrite(ledA, brightness);
    brightness += fadeAmount;
    i += fadeAmount;
    delay(30);
  }

  //ledAがフェードアウトする
  for (int i = 255; i >= 0;) {
    analogWrite(ledA, brightness);
    brightness -= fadeAmount;
    i -= fadeAmount;
    delay(30);
  }

  //ledBがフェードインする
  for (int j = 0; j <= 255;) {
    analogWrite(ledB, brightness);
    brightness += fadeAmount;
    j += fadeAmount;
    delay(30);
  }

  //ledBがフェードアウトする
  for (int j = 255; j >= 0;) {
    analogWrite(ledB, brightness);
    brightness -= fadeAmount;
    j -= fadeAmount;
    delay(30);
  }

}

片方のLEDがフェードイン・フェードアウトし、その後もう一方のLEDもフェードイン・フェードアウトするはずである。 筆者は、あるお馴染みのキャラクターの画像を印刷し、目の部分にLED用の穴を開けてみた。 インターネットで面白い画像を探して、自分でも穴を開けてみるとよい。 目の位置を合わせるため、画像のサイズやLEDの位置を調整する必要があるかもしれない。ぜひ自由に工夫してみてほしい。

2進数カウンタ

コンピュータサイエンスの中でもあまり華やかではない話題が、2進数、いわゆる悪名高き1と0である。 2進数で数えるとき、私たちは数を1と0の並びで表現する。 たとえば、4という数を書きたければ、0100という「2進数の文」が必要になる。 2進数についてもっと詳しく知りたければ、2進数のチュートリアルで探ってみることができる。

今回作る2進数のプロジェクトでは、LEDを使って1と0を表す。 点灯しているLEDが1、消灯しているLEDが0である。 また、コードについて特筆すべき点として、今回はif()文の代わりにswitch文を使う。 switch文に馴染みがなければ、Arduinoのリファレンス言語を確認して慣れておいてほしい。

以下の回路図で、すべてがどう接続されているか確認してみよう。

以下のコードをArduino IDEにコピー&ペーストする。アップロードして、何が起こるか見てみよう。

//この例はLEDを2進数カウンタとして使う。

//ピンを宣言する
const int ledA = 3; //2進数では、このピンが一番右の桁(1の位)にあたる
const int ledB = 4; //2番目の桁
const int ledC = 5; //3番目の桁
const int ledD = 6; //4番目の桁

void setup() {
  //ピンを出力として宣言する
  pinMode(ledA, OUTPUT);
  pinMode(ledB, OUTPUT);
  pinMode(ledC, OUTPUT);
  pinMode(ledD, OUTPUT);
}

void loop() {
  for (int i = 0; i < 16; i++) {
    switch (i) {
      case 0:  //0 = 0b0000
        delay(1000);
        digitalWrite(ledA, LOW);
        digitalWrite(ledB, LOW);
        digitalWrite(ledC, LOW);
        digitalWrite(ledD, LOW);
        break;

      case 1: //1 = 0b0001
        digitalWrite(ledA, HIGH);
        delay(1000);
        digitalWrite(ledA, LOW);
        break;

      case 2: //2 = 0b0010
        digitalWrite(ledB, HIGH);
        delay(1000);
        digitalWrite(ledB, LOW);
        break;

      case 3: //3 = 0b0011
        digitalWrite(ledA, HIGH);
        digitalWrite(ledB, HIGH);
        delay(1000);
        digitalWrite(ledA, LOW);
        digitalWrite(ledB, LOW);
        break;

      case 4: //4 = 0b0100
        digitalWrite(ledC, HIGH);
        delay(1000);
        digitalWrite(ledC, LOW);
        break;

      case 5: //5 = 0b0101
        digitalWrite(ledA, HIGH);
        digitalWrite(ledC, HIGH);
        delay(1000);
        digitalWrite(ledA, LOW);
        digitalWrite(ledC, LOW);
        break;

      case 6: //6 = 0b0110
        digitalWrite(ledB, HIGH);
        digitalWrite(ledC, HIGH);
        delay(1000);
        digitalWrite(ledB, LOW);
        digitalWrite(ledC, LOW);
        break;

      case 7: //7 = 0b0111
        digitalWrite(ledA, HIGH);
        digitalWrite(ledB, HIGH);
        digitalWrite(ledC, HIGH);
        delay(1000);
        digitalWrite(ledA, LOW);
        digitalWrite(ledB, LOW);
        digitalWrite(ledC, LOW);
        break;

      case 8: //8 = 0b1000
        digitalWrite(ledD, HIGH);
        delay(1000);
        digitalWrite(ledD, LOW);
        break;

      case 9: //9 = 0b1001
        digitalWrite(ledA, HIGH);
        digitalWrite(ledD, HIGH);
        delay(1000);
        digitalWrite(ledA, LOW);
        digitalWrite(ledD, LOW);
        break;

      case 10: //10 = 0b1010
        digitalWrite(ledB, HIGH);
        digitalWrite(ledD, HIGH);
        delay(1000);
        digitalWrite(ledB, LOW);
        digitalWrite(ledD, LOW);
        break;

      case 11: //11 = 0b1011
        digitalWrite(ledA, HIGH);
        digitalWrite(ledB, HIGH);
        digitalWrite(ledD, HIGH);
        delay(1000);
        digitalWrite(ledA, LOW);
        digitalWrite(ledB, LOW);
        digitalWrite(ledD, LOW);
        break;

      case 12: //12 = 0b1100
        digitalWrite(ledC, HIGH);
        digitalWrite(ledD, HIGH);
        delay(1000);
        digitalWrite(ledC, LOW);
        digitalWrite(ledD, LOW);
        break;

      case 13: //13 = 0b1101
        digitalWrite(ledA, HIGH);
        digitalWrite(ledC, HIGH);
        digitalWrite(ledD, HIGH);
        delay(1000);
        digitalWrite(ledA, LOW);
        digitalWrite(ledC, LOW);
        digitalWrite(ledD, LOW);
        break;

      case 14: //14 = 0b1110
        digitalWrite(ledB, HIGH);
        digitalWrite(ledC, HIGH);
        digitalWrite(ledD, HIGH);
        delay(1000);
        digitalWrite(ledB, LOW);
        digitalWrite(ledC, LOW);
        digitalWrite(ledD, LOW);
        break;

      case 15: //15 = 0b1111
        digitalWrite(ledA, HIGH);
        digitalWrite(ledB, HIGH);
        digitalWrite(ledC, HIGH);
        digitalWrite(ledD, HIGH);
        delay(1000);
        digitalWrite(ledA, LOW);
        digitalWrite(ledB, LOW);
        digitalWrite(ledC, LOW);
        digitalWrite(ledD, LOW);
        break;
    }
  }
  delay(500);
}

青いLEDを左手に見ながら、LEDがゆっくりと2進数で数え上げ、そのシーケンスを繰り返す様子が見えるはずである。 LEDとswitchのcaseをさらに追加して、2進数カウンタの桁数を増やせるか試してみよう。

Note

注:上のLEDは、(写真のとおり)左から順にコード中のピンledDledCledBledAに対応している。

締めくくりにもう一つ

最後の演習では、LEDを点滅させたりフェードさせたりするのとは違い、センサーの状態を示すインジケータとしてLEDを使う感覚を味わってみよう。 センサーの状態を示すランプは、非常に単純でありながら効果的なユーザーインターフェースの一形態である。 そこで、近接センサーが何かが近づきすぎたことを検知したときに、信号機のようなシーケンスを起動させてみる。

以下の回路図で、すべてがどう接続されているか確認してみよう。

以下のコードをArduino IDEにコピー&ペーストする。アップロードして、何が起こるか見てみよう。

//この例は、近接センサーが何かが近づきすぎたことを検知したときに、「信号機」のシーケンスを起動する。

//ピンと変数を宣言する
int trigger = 13;
int echo = 12;
int red = 2;
int yellow = 3;
int green = 4;

void setup() {
  Serial.begin(9600);               //シリアルモニタを9600ボーで初期化する
  pinMode(trigger, OUTPUT);         //センサーのサイクルを開始するための出力
  pinMode(echo, INPUT);             //距離を計算するための入力
  pinMode(red, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(green, OUTPUT);

  digitalWrite(green, HIGH);
}

void loop() {
  long duration, distance;
  digitalWrite(trigger, LOW);
  delayMicroseconds(2);
  digitalWrite(trigger, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigger, LOW);
  duration = pulseIn(echo, HIGH);   //PWMを読み取る
  distance = (duration / 2) / 29.1; //durationを半分にして29.1で割る
  Serial.print(distance);
  Serial.println(" cm");
  delay(750);

  if (distance <= 15) {
    //信号機のアニメーション
    digitalWrite(green, LOW);
    digitalWrite(yellow, HIGH);
    delay(2000);
    digitalWrite(yellow, LOW);
    digitalWrite(red, HIGH);
    delay(3500);
    digitalWrite(red, LOW);
    digitalWrite(green, HIGH);
    delay(3500);
  }
}

コードが初期化されると、緑のLEDが点灯した状態になる。 超音波センサーに何かが近づきすぎると、信号機のシーケンスが動き始める。 これは、超音波センサーを使ってLEDを起動させる、信号機の仕組みを単純化した例である。 設計者によっては、実際の交通信号システムでは、カメラによる画像処理やレーダー、赤外線センサー、磁力計、あるいは誘導ループを使って、車が交差点を横切ろうとしていることを検知することもある。 車が検知されると、信号機が起動し、交差点の反対側にいる他の車に減速と停止を知らせる。 数秒後、超音波センサーの前にまだ物体がある場合、LEDは緑に戻り、再びシーケンスを繰り返す。

コードを調整して、緑に戻す代わりに、物体がセンサーの前にある限り赤いLEDを点灯させ続けるようにしてみよう。 この回路は、交通信号システムのミニチュア版の試作にすぎない。 LEDを段ボールの筐体に取り付けて、2本の一方通行の道が交わる、自分だけのミニチュア交差点を作ってみよう。 さらにLEDを追加し、コードを調整して、四差路の交差点用にLEDを制御することにも挑戦してみてほしい。

まとめ

さらに詳しい情報は、以下の資料を参考にしてほしい。

LEDは、どんな回路にも手軽に楽しく追加できる部品である。選択肢は無数にある。電源インジケータ、信号インジケータ、あるいは単純にかっこいい照明エフェクトなど、いろいろな使い道がある。 Arduinoのコードをいろいろいじって、かっこいいエフェクトを作ってみよう。ちょっとした明かりが、さらに素晴らしい何かのきっかけになるかもしれない。 次のプロジェクトのヒントが欲しい場合は、LEDを使った次の関連チュートリアルも参考にしてほしい(いずれも英語)。

タグ: Arduino、概念、教育、接続ガイド、LED、光、センサー


出典:Basic LED Animations for Beginners (Arduino)(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Arduinoにおけるプロセッサ割り込み

はじめに

割り込みとは何だろうか。日常的な意味では、今やっている作業を時々邪魔してくる人のことを指す。それはそれで的を射ているかもしれないが、ここで本当に知りたいのは、組み込み電子工作やマイクロプロセッサの文脈における割り込みが何を指すかである。

改めて問い直そう。割り込みとは何だろうか。 一言で言えば、プロセッサが通常のプログラムを実行しながら、同時に何らかのイベント、つまり割り込みを常に監視できるようにする仕組みのことである。 割り込みには2つの種類がある。

  • ハードウェア割り込み:ピンがハイやローに変化するような、外部のイベントに応じて発生する。
  • ソフトウェア割り込み:ソフトウェアの命令に応じて発生する。

一般に、たいていの8ビットAVRマイクロコントローラ(Arduinoなど)は、本来的にはソフトウェア割り込みに対応していない。そのため、このチュートリアルではハードウェア割り込みに焦点を当てる。

参考になるチュートリアル:

以下の概念に馴染みがなければ、続きを読む前にこれらのチュートリアルを確認しておくことをおすすめする。

どうやって動作するのか

イベント、つまり割り込みが発生すると、プロセッサはただちにそれに気づき、現在の実行状態を保存し、小さなコードの塊(割り込みハンドラ割り込みサービスルーチンと呼ばれることが多い)を実行してから、元々行っていた処理へと戻る。

プログラマーは、特定の割り込みが発生したときに実行したいコードを、プログラム自体の中で定義する。 Arduinoでは、これをattachInterrupt()という関数で行い、推奨される構文はおおむね次のようになる。

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)

この関数は、3つの引数を受け取る。

  • 第1引数(digitalPinToInterrupt(pin):割り込みのピン番号であり、マイクロプロセッサにどのピンを監視すべきかを伝える。ピンは使用しているマイクロコントローラによって異なる。
  • 第2引数(ISR:この割り込みが発生したときに実行したいコードの場所。
  • 第3引数(mode:どのような種類のトリガーを検出するかを指定する。論理ハイ、論理ロー、あるいはその間の遷移である。

割り込み用に予約されているピンや、いくつかのサンプルコードについては、ArduinoのattachInterrupt()のページを参照してほしい。

Arduino.cc: attachInterrupt()

Note

注:使用しているAVRマイクロコントローラのデフォルトのピン一覧にない、別のピンを割り込みとして使いたい場合は、PinChangeInt Arduinoライブラリを試してみるとよい。このライブラリは、AVRベースのArduinoであれば、どのピンにもピン変化割り込みを追加できる代替手段を提供してくれる。

Arduino.cc: PinChangeInt Library

ハードウェアの接続

以下のセクションでは、割り込みとその仕組みをよりよく理解するための、簡単な例を見ていく。 実際に試したい場合は、SparkFun RedBoardLEDボタン330Ωの抵抗ジャンパーワイヤー、そしてすべてに電源を供給するケーブルを用意してほしい。

以下のFritzing図のように、LEDを13番ピンに、ボタンを2番ピンに接続する。

今接続したものをよく見てみると、実はLEDが冗長であることに気づくはずである。13番ピンに内蔵されたLEDをそのまま使うこともできるが、見た目をわかりやすくするため、外付けのLEDを追加している。

例:単純な割り込み

Note

注:この例では、デスクトップに最新版のArduino IDEがインストールされていることを前提としている。Arduinoを初めて使う場合は、Arduino IDEのインストールのチュートリアルを確認してほしい。

ハードウェアの接続が終わったところで、LEDに常に「オフ」信号を送り続ける、単純な例を見てみよう。 2番ピンに割り込みを設定する。このピンはボタンを監視しており、押されるとLEDへ「オン」信号を送り、カウンタをインクリメントする。

たいていのArduinoには、2つの外部割り込みが標準で内蔵されている。interrupt0(デジタル2番ピン)とinterrupt1(デジタル3番ピン)である。 (Arduino Mega 2560のように)もっと多くの割り込みを持つ基板もあるので、使用している基板が具体的に何をサポートしているかは、ユーザーマニュアルやデータシートを確認してほしい。 ArduinoのattachInterrupt()のページにも、いくつかの基板についてのより詳しい情報がある。 ここではRedBoardを使うので、この例では割り込みの監視に2番ピンを使う。

単純な割り込みの例1

RedBoard用のボードとCOMポートを選択する。そして、以下のコードを書き込む。

/*
Simple Interrupt Example 1
by: Jordan McConnell
SparkFun Electronics
created on 10/29/11
*/

int ledPin = 13;  // LEDはデジタル13番ピンに接続されている
int x = 0;  // 割り込みによって更新される変数

void setup() {
  //割り込み0(2番ピン)を有効にする。ここにはボタンが接続されている
  //立ち下がりエッジでincrement関数に移動する
  pinMode(ledPin, OUTPUT);
  attachInterrupt(0, increment, RISING);
  Serial.begin(9600);  //シリアル通信を開始する
}

void loop() {
  digitalWrite(ledPin, LOW);
  delay(3000); //何か有用な処理をしているふりをする
  Serial.println(x, DEC); //xをシリアルモニタに出力する
}

// 割り込み0用の割り込みサービスルーチン
void increment() {
    x++;
    digitalWrite(ledPin, HIGH);
}

このプログラムのメインループは、3秒ごとにLEDへ「OFF」信号を送る。 その一方で、このプログラムはデジタル2番ピン(割り込み0に対応する)で立ち上がりエッジを監視している。 つまり、電圧が論理ロー(0V)から論理ハイ(5V)へ変化するのを検知しており、これはボタンが押されたときに起こる。 これが起きると、increment関数が呼び出される。 この関数の中のコードが実行され、変数xがインクリメントされ、LEDが点灯する。 その後、プログラムはメインループの元の場所へと戻る。

実際にいろいろ試してみると、LEDが点灯している時間は一見ランダムに見えるが、決して3秒を超えることはないとわかるはずである。 LEDがどれだけの時間点灯し続けるかは、メインループのコードのどこで割り込みが発生したかによって決まる。 たとえば、delay関数のちょうど中間地点で割り込みが発生した場合、ボタンを押してからおよそ1.5秒間LEDが点灯し続けることになる。

チャタリングへの対処

割り込みでよくある問題の一つが、1回のイベントに対して複数回トリガーされてしまうことである。 例1のコードのシリアル出力を見ると、ボタンを1回しか押していなくても、xが何度もインクリメントされていることに気づくはずである。 なぜこうなるのかを探るには、信号そのものを見てみる必要がある。 ボタンを押した瞬間のピンの電圧をオシロスコープで監視すると、次のような波形になっているはずである。

画像提供:AllAboutCircuits

ピンの主な遷移はローからハイへの1回だが、その過程でいくつものスパイクが発生しており、これが複数回の割り込みを引き起こすことがある。 これはノイズや*バウンス(チャタリング)*と呼ばれる。 ボタンを押すという行為は一見1段階の動作に見えるが、実際にはボタン内部の機械的な部品が、ある状態に落ち着くまでに何度も接触を繰り返している。 これを解決する方法はいくつかある。 たいていは、適切なRCフィルタを追加して遷移を滑らかにすることで、ハードウェア側でバウンスの問題を解決できる。 もう一つの選択肢は、最初の割り込みが発生してから短い時間だけ、それ以降の割り込みを一時的に無視するという方法でソフトウェア側から対処することである。 先ほどの例に戻り、ボタンを1回押すたびに変数xが1回だけインクリメントされるよう、この修正を加えてみよう。

単純な割り込みの例2

まだ選択していなければ、RedBoard用のボードとCOMポートを選択する。そして、以下のコードを書き込む。

/*
Simple Interrupt example 2
by: Jordan McConnell
SparkFun Electronics
created on 10/29/11
*/

int ledPin = 13; // LEDはデジタル13番ピンに接続されている
int x = 0; // 割り込みによって更新される変数

//直近の割り込みのタイミングを追跡するための変数
unsigned long button_time = 0;
unsigned long last_button_time = 0;

void setup() {
  //2番ピンを使う割り込み0を有効にする
  //立ち上がりエッジでincrement関数に移動する
  pinMode(ledPin, OUTPUT);
  attachInterrupt(0, increment, RISING);
  Serial.begin(9600);  //シリアル通信を開始する
}

void loop() {
  digitalWrite(ledPin, LOW);
  delay(3000); //何か有用な処理をしているふりをする
  Serial.println(x, DEC); //xをシリアルモニタに出力する
}

// 割り込み0用の割り込みサービスルーチン
void increment() {
  button_time = millis();
  //increment()が直近250ミリ秒以内に呼ばれていないか確認する
  if (button_time - last_button_time > 250)
  {
    x++;
    digitalWrite(ledPin, HIGH);
    last_button_time = button_time;
  }
}

ボタンを押しながら、もう一度シリアル出力を見てみよう。9600ボーに設定したシリアルモニタを開く。 今度は、ボタンを押すたびにincrementが1回だけ呼び出されているのがわかるはずである。 この修正がうまくいくのは、割り込みハンドラが実行されるたびに、millis()関数で取得した現在時刻と、ハンドラが最後に呼び出された時刻を比較しているからである。 それが、あらかじめ決められた時間の範囲内(この場合は4分の1秒)であれば、プロセッサは直前に行っていた処理へすぐに戻る。 そうでなければ、if文の中のコードを実行して変数xを更新し、LEDを点灯させ、last_button_time変数を更新する。これによって、次に割り込みが発生したときに比較できる新しい値が用意される。

割り込みの優先度

2つの割り込みが同時に発生した場合はどうなるだろうか。 たいていのAVRは、いわゆる割り込み優先度には対応していない。 2つの割り込みが同時に発生した場合や、2つ以上の割り込みがキューで待機している場合、優先度はそれぞれのベクタアドレスの順序によって決まる。 ベクタアドレスが小さいほうが先に処理され、リセットはすべての割り込み要求より優先される。 ここでも、具体的な基板についての詳しい情報は、データシートを確認してほしい。

例:LEDシーケンスへの割り込み

割り込みは、長いシーケンスを扱う際にも役立つことがある。 LEDを使ったもう一つの単純な例を見てみよう。LilyPad USB Plusに内蔵されたRGB LEDを使って、色のシーケンスを巡回させ、それぞれの色をフェードイン・フェードアウトさせるとしよう。 各色のフェードサイクルの時間は10秒で、この基板を何台もステージ衣装に縫い付けているとする。 もし、どれか一台の衣装が同期からずれてしまったらどうなるだろうか。

サイクルが終わるのを待って、他の基板と同期を取り直そうとする代わりに、10番ピン(LilyPad USB Plus基板ではこれが割り込み0にあたる)に割り込みを追加できる。 ボタンが押されると割り込みが発生し、次の色へ進む。 これによって、ずれてしまった衣装を素早く同期させることができ、ショーを止めずに済む。

実際に自分の手でやってみよう。実際に試したい場合は、LilyPad USB Plusを用意してほしい。 前回の実験で使ったボタン、ジャンパー、電源も必要になる。 さらに、LilyPadの縫い付けタブに接続するための、ワニ口クリップ付きのピッグテールワイヤーもいくつか必要になる。

次のように、すべてを接続する。

Note

警告:LilyPad USB Plusを使う場合は、必ずLilyPadのボード定義をインストールしておくこと。それ以外の方法としては、RedBoardとコモンカソードのLED(拡散型またはクリアタイプ)、そして電流制限抵抗を使うこともできる。その場合は、ピンの定義を書き換え、必要に応じて接続を調整することを忘れないこと。

LilyPad USB Plus用のボードとCOMポートを選択する。そして、以下のコードを書き込む。

/*
Example: Interrupting an LED sequence
SparkFun Electronics

Follow the tutorial at:
https://learn.sparkfun.com/tutorials/processor-interrupts-with-arduino#example-interrupting-an-led-sequence

This code is released under the MIT License (http://opensource.org/licenses/MIT)

******************************************************************************/

// LilyPad USBPlusに内蔵されたLEDを使い、色のシーケンスを巡回させる。割り込みを使って素早く色を切り替える

// 内蔵LED:

int RGB_red = 12;
int RGB_green = 13;
int RGB_blue = 14;

int x = 0;  // 割り込みによって更新される変数

//フェード用の変数
int ledMode = 0; //LEDを制御する色モード
int colorSwitch = 0; //current_FadeValと比較し、まだ色を切り替えるべきでないかを確認する
int prev_FadeVal = 0;
int current_FadeVal = 0;
boolean increasing = true;

//直近の割り込みのタイミングを追跡するための変数
unsigned long button_time = 0;
unsigned long last_button_time = 0;


void setup() {

// LEDのピンをすべて出力にする:

  pinMode(RGB_red, OUTPUT);
  pinMode(RGB_green, OUTPUT);
  pinMode(RGB_blue, OUTPUT);
  attachInterrupt(0, increment, CHANGE);
  Serial.begin(9600);  //シリアル通信を開始する

}

void loop()
{
  // このコードでは、7色の虹色(三原色、その中間色、さらにその中間色)を順番にたどっていく。

  // HIGH(オン)かLOW(オフ)しか取れないdigitalWriteと異なり、
  // analogWriteを使えば0(オフ)から255(フル点灯)まで明るさを滑らかに変化させられる。
  // RGB LEDにanalogWriteを使えば、何百万通りもの色を作り出せる。


  FadeColor();
}

// 割り込み0用の割り込みサービスルーチン
void increment() {

  button_time = millis();

  //increment()が直近250ミリ秒以内に呼ばれていないか確認する
  if (button_time - last_button_time > 250)
  {
    //カウンタをインクリメントする
    x++;

    //LEDを消灯する
    analogWrite(RGB_red,0);
    analogWrite(RGB_green,0);
    analogWrite(RGB_blue,0);

    Serial.println(x, DEC); //xをシリアルモニタに出力する
    delay(10000);

    //直近のボタン押下時刻を現在の時刻に更新する
    last_button_time = button_time;

    //色を切り替える
    if (ledMode < 7){
      ledMode++;
    }
    else {
      //赤からやり直す
      ledMode = 1;
    }

    //フェードの値をリセットする
    prev_FadeVal = 0;
    current_FadeVal = 0;

  }
}

void FadeColor() {
  switch (ledMode) {
    case 1://赤をフェードさせる
      analogWrite(RGB_green, 0);
      analogWrite(RGB_blue, 0);
      analogWrite(RGB_red, prev_FadeVal);
      break;
    case 2://黄色をフェードさせる
      analogWrite(RGB_red, prev_FadeVal);
      analogWrite(RGB_green, prev_FadeVal);
      analogWrite(RGB_blue, 0);
      break;
    case 3://緑をフェードさせる
      analogWrite(RGB_red, 0);
      analogWrite(RGB_green, prev_FadeVal);
      analogWrite(RGB_blue, 0);
      break;
    case 4://明るい青をフェードさせる
      analogWrite(RGB_red, 0);
      analogWrite(RGB_green, prev_FadeVal);
      analogWrite(RGB_blue, prev_FadeVal);
      break;
    case 5://青をフェードさせる
      analogWrite(RGB_red, 0);
      analogWrite(RGB_green, 0);
      analogWrite(RGB_blue, prev_FadeVal);
      break;
    case 6://マゼンタをフェードさせる
      analogWrite(RGB_red, prev_FadeVal);
      analogWrite(RGB_green, 0);
      analogWrite(RGB_blue, prev_FadeVal);
      break;

    default:
      analogWrite(RGB_red, prev_FadeVal);
      analogWrite(RGB_green, prev_FadeVal);
      analogWrite(RGB_blue, prev_FadeVal);
      break;
  }
  delay(100);

  if (increasing == true) {
    current_FadeVal += 5;
  }
  else { //減少中
    current_FadeVal -= 5;
  }

  if (current_FadeVal > 255) {
    increasing = false;
    prev_FadeVal -= 5;//加算を取り消す
    current_FadeVal = prev_FadeVal;

  }
  else if (current_FadeVal < 0) {
    increasing = true;
    prev_FadeVal += 5;//減算を取り消す
    current_FadeVal = prev_FadeVal;
  }

  prev_FadeVal = current_FadeVal;

  if(current_FadeVal == colorSwitch)
  {
    if (ledMode < 7){
      ledMode++;
    }
    else {
      //赤からやり直す
      ledMode = 1;
    }
  }
}

ボタンを押すたびに、次の色へ切り替わることに注目してほしい。 それほど一般的な用途ではないかもしれないが、割り込みが即座に必要な処理へ対応する様子が、視覚的にはるかにわかりやすい例になっている。

割り込みの利点は何か

ここまで読んで、「そもそもなぜ割り込みを使う必要があるのか。2番ピンをときどきdigitalRead()でチェックすれば済むのではないか。同じことができるのではないか」と疑問に思うかもしれない。

答えは状況による。 コードの中のある特定の時点や、ある時間の範囲でのピンの状態だけが気になるのであれば、digitalRead()で十分だろう。 ピンを常に監視したい場合は、digitalRead()を頻繁にポーリングすることもできる。 しかし、ポーリングとポーリングの間のデータを見落としてしまうことは十分にありうる。 この見落とされた情報が、多くのリアルタイムシステムでは致命的になりかねない。 それだけでなく、データをポーリングする頻度が高くなるほど、有用なコードを実行する代わりにその処理に費やされるプロセッサの時間も増えていく。

タイミングが重要になる例として、車のアンチロックブレーキシステムを監視・制御するシステムを考えてみよう。 センサーが車のトラクションが失われ始めたことを検知した場合、現在プログラムのどの部分が実行されているかなど気にしていられない。車がトラクションを保ち、事故(あるいはそれ以上の事態)を避けられるよう、即座に何らかの対応が必要だからである。 この状況でセンサーを単純にポーリングしていたら、ポーリングのタイミングが遅すぎて、そのイベントを完全に見逃してしまうこともありうる。 割り込みの優れた点は、必要な瞬間に即座に処理を開始できることにある。

まとめ

割り込みの仕組みが少しよくわかったところで、次のプロジェクトで使ってみることはできるだろうか。 割り込みについてさらに情報が欲しい場合は、次のリンクも参考にしてほしい(いずれも英語)。

Shawn Hymel氏も、割り込みについての楽しく有益な動画チュートリアルをいくつか公開している。ぜひチェックしてみてほしい。

さらに多くのプロセッサ割り込みの例を見たい場合は、次のチュートリアルも参考にしてほしい(いずれも英語)。

タグ: Arduino、概念、プログラミング


出典:Processor Interrupts with Arduino(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

IoTのための通信プロトコル

はじめに

画像提供:Pixabay

接続性は、IoT(モノのインターネット)プロジェクトを開発するうえで、常に意識しておくべき主要な要素の一つである。

新しいIoTプロジェクトに着手するとき、筆者の頭にまず浮かぶ疑問は次のようなものである。

  • どうやって接続させたいか。
  • 電力や到達距離に制約はあるか。
  • データレートはどれくらい必要か。
  • 現在利用できるネットワークインフラは何か。

IoTプロジェクトを始めるとき、多くの人が同じような疑問を抱くはずである。 どの通信プロトコルを使いたいか、すでにイメージが固まっていることもあるだろうが、それでもきちんと調べて、自分の用途にもっとも適したものかどうかを確認しておいて損はない。

幸い、利用できるネットワークインフラと通信プロトコルは数多く存在する。しかし不幸なことに、その数があまりに多く、かえって混乱してしまうこともある。

このチュートリアルでは、よく使われる通信プロトコルの(すべてではないが)大部分を取り上げ、プロジェクトにもっとも適したものをどう選べばよいかを扱う。それぞれの長所と短所についても詳しく見ていく。

  1. WiFi
  2. Thread
  3. ZigBee
  4. Bluetooth
  5. RFIDとNFC

これは接続方式の完全な一覧ではないが、たいていのIoTプロジェクトを始めるうえで十分な助けになるはずである。

ネットワークトポロジー

これから取り上げるさまざまなネットワークプロトコルを理解するには、まずネットワークトポロジーを理解しておくことが重要である。

ネットワークトポロジーとは、ネットワーク上のさまざまな要素がどう配置されているかを表すものである。 物理的、あるいは論理的にネットワークの構造を定義する。 筆者は、これをネットワークの要素とその間をデータがどう移動するかを描いた図のようなものだと捉えている。

出典:www.wikipedia.com

ネットワークトポロジーには数多くの種類があるが、ここではIoT向けの通信プロトコルを扱う際によく見かけるものに絞って紹介する。

  • ポイントツーポイント(P2P)
  • スター型
  • メッシュ型
  • ハイブリッド型

ポイントツーポイント

P2Pはもっとも単純なトポロジーで、2つのエンドポイントの間に恒久的なリンクを持つ。 P2Pのもっとも単純な例は、子どもの頃に遊んだ紙コップと糸で作った電話である。2つのノード(エンドポイント)が、通信専用の1本のチャンネルを持っている。 交換技術を使えば、P2Pを動的に構築することもできる。 初期の電話網は、この交換型P2Pトポロジーを基盤にしていた。

スター型

出典:www.wikipedia.com

スター型のネットワーク構成では、それぞれのノード(エンドポイント)が、単一の中央デバイスに接続する。 ノードどうしが直接通信することはできず、中央デバイスを介して通信する。 中央デバイスがサーバーとして振る舞い、ノードはクライアントとして振る舞う。 これはもっとも一般的な構成の一つであり、もっとも構築しやすい構成でもある。 ネットワークを乱すことなく、デバイスの追加や削除が簡単に行える。 この種のネットワークにおける最大の課題は、単一障害点(つまり中央のコンピュータ)を持つことである。中央のコンピュータが故障すれば、ネットワーク全体が機能しなくなる。

メッシュ型

出典:www.wikipedia.com

メッシュ型は、それぞれのノードが他のすべてのノードと接続されているタイプのネットワークである。 メッシュネットワークは、ネットワークのリンクに関して非常に高い冗長性を持つ。 1本のリンクが失われても、ノードは別のリンクを使って通信を続けられる。 冗長なリンクを構築するコストの増加と、ネットワークの構造が複雑になるという、当然の理由から、それほど一般的に使われているトポロジーではない。

ハイブリッド型

ハイブリッドネットワークは、その名のとおり、2つ以上の基本的なネットワークトポロジーを組み合わせたものである。 スター・メッシュ型のネットワークもあれば、スター・リング型のネットワークもある。 ハイブリッドネットワークは、両方の長所を兼ね備えているため、より柔軟で信頼性が高いものになる。 しかしその一方で、複雑さも増すため、構築のコストが高く、管理も難しくなる。 とはいえ、複数のネットワークトポロジーの機能を必要とする場合には、ハイブリッド型ならではの利点がある。

インフラストラクチャ型ネットワークとアドホック型ネットワーク

今回はワイヤレスネットワークについて扱うので、ワイヤレスネットワークが動作する2つの基本モード(トポロジーと呼ばれることもある)について説明しておく必要がある。

インフラストラクチャ型ネットワークとアドホック型ネットワークである。

出典

インフラストラクチャモードとは、ワイヤレスネットワークを支えるために物理的な構造を必要とする方式である。 これは基本的に、ネットワークの機能を扱う何らかの媒体があり、その周りにネットワークを維持するインフラが構築されているということを意味する。

このモードは、たいてい次のような機能を果たす。

  • 他のネットワークへのアクセスの提供
  • 転送
  • 媒体アクセス制御

インフラストラクチャ型のワイヤレスネットワークでは、通信はワイヤレスノード(パソコンやスマートフォンなど、ネットワーク上のエンドポイント)とアクセスポイント(ルーター)の間だけで行われる。

同じネットワーク上に複数のアクセスポイントがあり、それぞれが異なるワイヤレスノードを扱っていることもある。

インフラストラクチャ型ネットワークの典型例は、携帯電話網である。これは、機能させるために決まったインフラ(通信塔)を必要とする。

インフラストラクチャ型ネットワークを使うべき場面は、次のとおりである。

  • 到達距離を広げるためにアクセスポイントを簡単に追加できる場合
  • より恒久的なネットワークを構築したい場合
  • 他の種類のネットワークへブリッジする必要がある場合(たとえば必要に応じて有線ネットワークに接続できる場合)

Note

インフラストラクチャ型ネットワークの大きな欠点の一つは、一度構築するのにコストと時間がかかるという点である。そのため、インフラが弱い、あるいは存在しない遠隔地でデバイスを動作させたい場合には、インフラストラクチャ型ネットワークに頼ることはできない。

一方、アドホック型ワイヤレスネットワークは、動作させるために決まったインフラを必要としない。 アドホックネットワークでは、それぞれのノードが他のノードと直接通信できるため、アクセス制御を提供するアクセスポイントは不要である。

インフラストラクチャ型ネットワークではアクセスポイントが経路制御を担うのに対し、アドホックネットワークではネットワーク内のノード自身がルーティングを担う。

ルーティングとは、送信元ノードと宛先ノードの間で、データを転送するための最善の経路を見つけることである。

アドホックネットワーク内のすべての個々のノードは、他のノードに関する情報を含むルーティングテーブルを保持している。 アドホックネットワークの性質上、動的であるため、このルーティングテーブルは常に変化し続けることになる。 一つ注意しておきたいのは、アドホックネットワークは本質的に非対称であるという点である。つまり、ネットワーク内の2つのノード間で、データのアップロードとダウンロードの経路が異なることがありうる。

アドホックネットワークの典型例は、中央のアクセスポイントを介さずに、2台以上のノートパソコン(あるいは対応する他のデバイス)を、ワイヤレスまたはケーブルで直接互いに接続する場合である。

アドホック型ネットワークを使うべき場面は、次のとおりである。

  • 2台のデバイスの間で、素早くピアツーピア(P2P)ネットワークを構築したい場合
  • すぐに使える一時的なネットワークを作りたい場合
  • その地域にネットワークインフラが構築されていない場合(このような場所で使える唯一のネットワークモードがアドホックである)

Note

ルーティングはネットワーク内のそれぞれのノードが担うため、より多くのリソースを消費する。アドホックネットワークに接続されるデバイスの数が増えるほど、ネットワークの干渉が増え、ネットワークが遅くなることがある。

WiFi

出典:commons.wikimedia.org

WiFiは、もっともよく使われる通信プロトコルの一つである。 おそらく、WiFiのない生活は想像もつかないだろう。 自宅のくつろいだ空間から、教室、カフェ、空港まで、私たちはあらゆる場所でWiFiを目にする。 WiFiが私たちの生活に及ぼす影響はあまりに大きく、今ではこんなSSIDのダジャレのネタにもなっている(たいていは、あまり出来のよくないダジャレだが)。

WiFiは基本的にインフラストラクチャ型ネットワークを使用しているが、インフラストラクチャモードの中でアドホック的なネットワーキングもサポートしている。

ワイヤレス通信のインフラストラクチャモードは、他のネットワークへのブリッジ、媒体アクセス制御、転送を提供する。 ネットワークを扱う機能はアクセスポイント(ルーター)側に置かれ、クライアント側は(ネットワークの文脈では)単純なままでいられる。

また、WiFiはスター型のネットワークでもある。通信は、ワイヤレスノード(デバイス)からワイヤレスアクセスポイント(ルーターやネットワークコントローラー)へと向かう。

現在使われている標準規格は、2013年にリリースされた802.11acだが、2009年にリリースされた802.11nも依然として広く使われている。 802.11acは最大800Mbit/sの速度を提供するのに対し、802.11nは最大150Mbit/sだった。

さらに古い802.11a/b/gという規格のデバイスを見かけることもあるだろう。これらは今ではレガシーデバイスと呼ばれている。 とはいえ、WiFiには下位互換性があるため、古いデバイスも新しい規格のデバイスとそのまま通信できる。

デバイスのWiFiの到達距離は、いくつかの要因によって決まる。

  • そのデバイスがどのWiFi規格で動作しているか。当然、最新の規格ほど古いバージョンより広い到達距離を提供する。
  • 壁のような物理的な障害物も、到達距離を左右する重要な要因である。したがって、開けた空間でのWiFiネットワークの到達距離は、壁やその他の干渉物のある閉じた空間よりも広くなる。

Note

他の低電力技術に対するWiFiの弱点に対処するため、低電力WiFi(IEEE 802.11ah)を標準化する取り組みが始まっている。このプロトコルの開発は進められているが、世界規模での普及については疑問が残る。主な理由の一つは、既存の802.11bgnネットワークとの下位互換性がないことである。

WiFiの利点

  • WiFiはそれなりに広い到達範囲を持ち、壁やその他の障害物を透過できる。
  • WiFiネットワークへのデバイスの追加・削除は非常に簡単である。

WiFiの欠点

  • 当然ながら、配線がないことの代償として帯域幅は低くなる。ネットワークの電波は他の機器と干渉することもある。
  • もっとも重要な点として、WiFiのセキュリティは有線接続よりも弱い。

自分のプロジェクトについて考えるなら、WiFi対応のデバイスとインターネットの間で素早く接続を確立したい場合には、WiFiが理想的である。 WiFiは消費電力を抑えることを目標に設計されているため、専用の電池でプロジェクトを動かすこともできる。 デバイスがサーバーとどのタイミングでどう接続・通信するかをそれほど気にせず、ただ手間なくインターネットに接続したいだけの場合には、WiFiを使うとよい。

SparkFunでも、WiFiベースの開発ボードを数多く扱っている。

以下は、WiFiを通信プロトコルとして使うIoTプロジェクトの開発を紹介する、いくつかのプロジェクトチュートリアルである(いずれも英語)。

Thread

Threadは、信頼性が高くコスト効率のよい、低電力のD2D(デバイス間)ワイヤレス通信のためのオープン標準である。特にスマートホーム向けの用途を念頭に設計されている。

2014年にThread Groupが結成されたことで誕生した。現在では、Google、Samsung、Qualcomm、ARMといった大企業がThreadプロトコルの設計・開発に関わっている。

出典:thread.org

Nestは、サーモスタットやNest Cam製品にThreadネットワークを採用している。 Threadは、ホームオートメーション分野を念頭に設計されている。デバイスを簡単にセットアップ・接続でき、電池寿命を延ばすために消費電力を低く抑え、しかも安全である。

標準規格である802.15.4(6LoWPAN)アーキテクチャを基盤としている。 Threadの優れた点は、IPv6(インターネットプロトコルバージョン6)を組み込んだオープンプロトコルであることである。

Threadにおけるデバイス

Threadプロトコルは、ネットワーク上の主要なデバイスとして3種類を定義している。

  • ボーダールーター
  • ルーターとルーター対応可能なエンドデバイス
  • スリーピーエンドデバイス

これらの役割の関係については、Thread Stack Fundamentals 2015に詳しい図解がある。

ボーダールーター

Threadには、ボーダールーターと呼ばれる特殊なタイプのルーターを持つ仕組みがあり、802.15.4ネットワークと、異なる物理層を持つ隣接ネットワーク(WiFiやイーサネットなど)との間の接続性を提供する。 1台のボーダールーターが故障しても、ネットワーク内の別のルーターがボーダールーターの役割を引き継ぐことができ、Threadプロトコルの堅牢性が保たれる。

ルーター

ルーターは、その名のとおり、ネットワーク上のデバイスにルーティングサービスを提供する。 新しいデバイスをネットワークに組み込む際にも使われる。 通常、ルーターは常にアクティブな状態にあるが、REED(ルーター対応可能なエンドデバイス)に格下げされることもある。 これらのデバイスは、Threadネットワークにおけるルーティングやデータ転送には使われないが、必要に応じてルーターの役割を引き受けられる冗長なエンドポイントとして機能する。

スリーピーエンドデバイス

これらはThreadネットワークのエンドポイントであり、ホストデバイスとも呼ばれる。 ホストデバイスは、サーモスタット、防犯カメラ、ヒーターなど、それぞれIPアドレスを持つ個別の機能デバイスである。 これらのデバイスは、スリーピーチャイルドやスリーピーノードとも呼ばれる。 スリーピーデバイスに直接ペアリングされたルーターは、親と呼ばれる。 スリーピーデバイス(エンドポイント)は、ほとんどの時間をスリープモードで過ごし、データを送信するときだけ起動する。 これらは親デバイスを通じてのみ通信する(たとえば、Nestサーモスタットはスリーピーエンドデバイスである)。

デバイスの典型的な送信サイクルは、次のようになる。

  • スリープモードから目覚める。
  • 必要な起動処理と無線の初期化を行う。
  • 受信モードに入り、送信可能な状態か確認する。
  • 送信モードに入る。
  • データを送信する。
  • 必要に応じて確認応答を受け取る。
  • スリープする。

インフラストラクチャモードを使うWiFiとは対照的に、Threadはアドホックモードのネットワーキングを使用する。

利点

  • IPベースであるため、他のIPベースのネットワークに接続しやすい。802.15.4を基盤としているため、ZigBeeや6LoWPANのような既存のデバイスも簡単にThreadへ移行できる。
  • ネットワークの状況に応じて適応できるため、アーキテクチャ上の単一障害点を持たない。完全なメッシュ型のネットワークトポロジーをサポートしている。
  • スリープするデバイスに対応しているため、低電力で動作する。
  • 安全である。

注:Threadネットワークにはアーキテクチャ上の単一障害点は存在しないが、不適切なネットワーク設計によって単一障害点が生まれてしまうことはありうる。

欠点

  • 複雑さゆえに、あまりDIYフレンドリーなプロトコルとは言えない。大規模なホームオートメーション市場を主なターゲットとしている。
  • まだ非常に新しいネットワークプロトコルであり、確立されるにはもう少し時間が必要である。

Silicon LabsNXPはThread Allianceの一員であるため、Threadプロトコルに対応した開発ボードを積極的に展開している。

ZigBee

出典:Zigbee.org

ZigBeeもThreadと同様、200社以上が参加する連合であり、家庭・産業用オートメーションのための堅牢かつシンプルなネットワークの開発に協力している。

ZigBeeの設計目標

ZigBeeは家庭・産業用オートメーションに役立つことだけを目的として作られており、設計目標もそれに沿ったものになっている。

  • 低電力
  • セキュリティ
  • ISMバンドを使う他の無線ネットワークとの共存
  • 標準化
  • 低コスト

Threadと同様、ZigBeeもIEEE 802.15.4規格を土台にしている。

ZigBeeの仕様は、802.15.4に欠けていた部分を補い、真のメッシュネットワークを実現するとともに、スター型やツリー型のような他のトポロジーもサポートしている。

出典:AMX - Zigbee White Paper

ZigBeeネットワークにおけるデバイス

ZigBeeプロトコルでは、3種類のデバイスが定義されている。

  • ZigBeeコーディネータ
  • ZigBeeルーター
  • ZigBeeエンドデバイス(ノード)

ZigBeeコーディネータ

コーディネータは、ZigBeeネットワークの頭脳にあたる。デバイスをネットワークに組み込み、セキュリティキーを保存し、他のネットワークへのブリッジも担う。1つのネットワークに存在できるZigBeeコーディネータは1台だけである。

ZigBeeルーター

ZigBeeネットワークには、中継ルーターとして、あるいはネットワーク内でデータを送信するために、複数のルーターが存在することがある。

ZigBeeエンドデバイス

エンドデバイスは、親ノード(ルーターまたはコーディネータ)としか通信できない。他のエンドデバイスと直接通信することはできない。 Threadと同様、これらのデバイスはほとんどの時間をスリープモードで過ごし、親にデータを送信するときだけ起動するように設計されている。

ZigBeeは、多くの無線機器が使用する2.4GHz帯のうち、チャネル11〜26を使用する。 ZigBeeのチャネルは、両方のネットワークのチャネル割り当てが適切に行われていれば、干渉なくWiFiのチャネルと共存できるよう、特別に間隔が調整されている。

出典:eetimes.com

注:両者にとって最良のスペクトル利用は、WiFiのチャネルを1、6、11に、ZigBeeのチャネルを15、20、25に設定することで実現できる。

ZigBee対Thread

ZigBee標準は、2014年にThreadが登場したことで大きな課題に直面した。 これを受けてZigBee Allianceは、ZigBee 3.0という最新プロトコルの導入を推し進めた。 ThreadをはじめとするネットワークがホームオートメーションでZigBeeより優れていた部分に対処しようとしたのである。

ZigBee 3.0では、ZigBee RF4CEやZigBee Green Powerといった機能が追加された。

ZigBee RF4CE:赤外線リモコンを無線ベースのリモコンに置き換えるために開発された。リモコンだけでなく、照明やランプなども制御できる、汎用リモコンを実現することを目的としている。また、赤外線特有の「向けて操作する」という制約もなくなる。

ZigBee Green Power:エネルギーハーベスティングデバイスをサポートする、超低電力の規格として開発された。これらのデバイスがほとんどの時間オフの状態でいられるようネットワークを管理することで、非常に低い消費電力を実現している。

ZigBeeがThreadに後れを取っていた大きな要因の一つが、IP互換性だった。一方、ZigBee 3.0は完全にIP互換になっている。そのため、ルーターを介してZigBeeデバイスをインターネットに接続できるようになった。

利点:おおむねThreadと同様である。

欠点:到達距離が短く、データ速度が低い。

Digi InternationalのXbeeは、ZigBeeプロトコルに対応した無線通信モジュールである。ファームウェアを書き換えることで、ZigBee ProやDigiMeshにも対応できる。

Xbeeを手早く体験したい場合は、次のチュートリアルを参考にしてほしい(いずれも英語)。

Bluetooth

出典:wikimedia.org

ここでは、昔から使われているBluetooth Classicの無線技術と、IoTで使われる低電力デバイス向けに特化して設計された新しいBluetooth Low Energy(BLE)の両方を扱う。

議論の中心はBLEに置く。Bluetooth Classicの一般的な概要については、この技術の基礎を扱った次のチュートリアルを参照してほしい。

他の無線技術と同様、Bluetoothも2.4GHz帯のISMバンドを使用する。 到達距離は10mから100m(送信出力を上げた場合。ただしそれだけ消費電力も増える)である。 Bluetoothもアドホック型のネットワークであり、ポイントツーポイント(P2P)接続を提供する。

Bluetooth Classicは、1つのピコネットに最大1台のマスターと7台のスレーブを収容できる。 これもスター型のネットワークトポロジーに従っており、周辺機器どうしが互いに通信することはできない。

いくつか押さえておくべき点として、あるピコネットにおけるマスターは、別のピコネットのマスターになることはできないが、あるピコネットのマスターが別のピコネットではスレーブになることはできる。 Bluetooth Classicは、音声とデータの伝送はできるが、映像は伝送できない。

ここからは、BLEプロトコルと、この技術によってBluetoothがどう進化してきたかに焦点を当てて見ていく。

3種類のBluetooth

Bluetooth Low Energyは、Bluetooth Classicの無線技術とはまったく異なるものである。 新しいプロトコルスタック、新しいプロファイルアーキテクチャで設計されており、コイン電池のような低電力の電源でも動作できることを目的としている。

この無線技術は、既存のBluetooth Classicに取って代わったわけでも、置き換えたわけでもないことを理解しておく必要がある。 その結果、互いに関連し合う、異なる種類のBluetoothが生まれることになった。

出典:Bluetooth SIG

Bluetooth技術は、3種類のデバイスに分類できる。

  • Bluetooth Classic:従来からあるBluetoothで、スループットが高く、主にワイヤレスオーディオやファイル転送に使われる。この「クラシック」無線は、Bluetooth Smartにも対応している。
  • Bluetooth Smart:Bluetooth Low Energyはこの名前でブランド化されており、状態情報のみを送信する。低デューティサイクルの用途(つまり、無線が実際にオンになっている時間が短い用途)向けに特化して設計されている。Bluetooth SmartデバイスはBluetooth Classicデバイスと通信できない。
  • Bluetooth SmartReady:これらは基本的に、パソコンやスマートフォンのような「ハブ」デバイスである。「クラシック」と「スマート」の両方のデバイスに対応しており、スマートフォンがBluetoothスピーカーに音声を送信しつつ、フィットネストラッカーとも通信できるのはこのためである。

クラシックと低電力の違い

BLEは、他のワイヤレスプロトコルと同じ2.4GHzのISMバンドを使用する。 Bluetooth Classicの79個の1MHz幅チャンネルに対し、Bluetooth Low Energyはわずか40個の2MHz幅チャンネルしか持たない。

出典

BLEはまた1Mbpsの GFSK変調を使用しており、これによってBluetooth Classicよりも広い到達距離を実現している。

BLEは適応型周波数ホッピングアルゴリズムを使い、利用可能なチャンネルの一部だけを使ってホッピングを行う。これにより、状態の悪いチャンネルによるパケットロスから素早く回復できる。 この手法によって、無線の消費電力を抑えることができる。 Bluetooth Classicは疑似ランダムなホッピングシーケンスを使い、1秒間に1,600回送信周波数を切り替える。

もう一つ押さえておきたい点として、BLEは1台のマスターに最大128台のデバイスを接続できるが、Classicではわずか7台にとどまる。

BLEを他の無線プロトコルと、無線アプリケーションの観点から比較する

出典:Cambridge Silicon Radio

BLEスタック

BLEのスタックは、低電力の用途を念頭に特化して設計されている。

出典:blueradios.com

BLEの核となるのは、GAPとGATTというプロファイルである。今回は、この2つに絞って扱う。

Generic Access Profile(GAP)とGeneric Attribute Profile(GATT)は、私たちが周囲の人と基本的にどうコミュニケーションを取り、関わりを持つかに似ていると考えるとわかりやすい。 誰かと出会ったとき、まず自己紹介をし、自分についての基本的な情報を伝える。 その相手とつながりたい場合は、電話番号やメールアドレスのような個人情報を交換し、以降やり取りできるようにする。 一度そうすれば、次にその人と会ったとき、改めて自己紹介する必要はなく、他の情報のやり取りをすぐに始められる。 GAPは、自己紹介をする最初の出会いの段階にあたり、GATTは、その相手との接続を確立し、実際の通信を始める段階にあたる。

Generic Access Profile(GAP)

GAPは、BLEデバイスが外部と通信するために使う仕組みを定義している。

アドバタイジング

この段階では、デバイスは次の2つの状態のいずれかを取ることができる。

  • ブロードキャスト段階:デバイスがデバイス名、信号強度、製造情報など、公開のアドバタイジングデータパケットをブロードキャストする段階。
  • 観測段階:デバイスがアドバタイジングパケットを受信する段階。この時点ではまだデバイス間の接続は確立されていない。同じアドバタイザーを複数のデバイスが観測していることもある。

接続を確立する過程で、デバイスはそれぞれ次のような役割を担うことになる。

  • ペリフェラル:ブロードキャストするデバイスがペリフェラルの役割を担う。デバイスとの疑似的な接続を形成し、接続が確立される前に、セントラルデバイスからの接続要求に応じてより多くの情報を提供する。
  • セントラル:観測側のデバイスが、アドバタイズしているデバイスへの接続を開始すると、セントラルデバイスの役割を担う。マスターと考えることもでき、一度に複数のペリフェラルに接続できる。

ペリフェラルとセントラルの間で接続が確立されると、アドバタイジングパケットはそれ以降送信されなくなる。 ここからは、双方向の通信にGATTプロファイルが使われることになる。

Generic Attribute(GATT)プロファイル

GATTプロファイルは、属性プロトコルで定義されているサービスやキャラクタリスティックといった属性を使って、2台のBLEデバイスがどう通信するかを定義している。

GAPと同様、通信するデバイスにはそれぞれ決まった役割が割り当てられる。

  • クライアント:たいてい、セントラルデバイスがクライアントの役割を担う。GATTサーバーへリクエストを送り、サーバー上の属性を読み書きできる。
  • サーバー:たいてい、ペリフェラルがサーバーの役割を担う。これらの属性を保存しているため「サーバー」と呼ばれる。サーバーはクライアントからのリクエストに応じ、必要な属性を送り返す。

ペリフェラルもセントラルも、データの流れによってサーバーにもクライアントにもなりうる。

接続を確立する際、セントラルとペリフェラルは「接続間隔」を決める。これは、それぞれの接続イベントの間の時間を指す。

さらに詳しい情報は、以下のBluetooth SIGのページで確認できる。

BluetoothやBLEをBluetoothベースのIoTプロジェクトに直接活用する際の理解を深めるため、次のチュートリアルやブログ記事も確認してみてほしい(いずれも英語)。

RFIDとNFC

無線周波数識別(RFID)は、物体をワイヤレスで追跡・識別するために使われる通信方式である。

複雑に見えるかもしれないが、実際にはもっとも単純な通信方式の一つであり、それこそが、いたるところに存在しながらも目立たない理由になっている。 世界中で消費財の追跡に使われているだけでなく、料金収受のための車両追跡にも使われている。病院では患者の追跡に、農家では家畜の追跡に使われている。 RFID技術は私たちの生活の一部になっており、それがどう影響しているかにすら気づいていないことも多い。

単純に言えば、RFIDタグはユニバーサル・プロダクト・コード(バーコード)に近い代替品と考えることができる。ただし、より効率的である。

RFIDタグは、従来のバーコードにはない読み書き機能を持つ。更新したり、変更したり、ロックしたりできる。

RFID技術は、タグとリーダーから構成される。

タグ

タグは、RFIDシステムにおけるエンドポイントである。 タグの用途に応じて、識別情報とその他の情報を保存する。タグには2種類ある。

  • アクティブタグ:何らかのオンボード電源(たいていは電池)を持つタグで、より強い信号を送信できるため、より広い到達距離を持つ。この種のタグは、リーダーの有無にかかわらず定期的に信号を送信できる。
  • パッシブタグ:内蔵の電源を持たず、リーダーの近くにあるときだけ起動するタグである。地下鉄やバスの定期券はたいていパッシブタグで、リーダーに触れると起動する。これらのタグは、リーダーが送信する電波エネルギーを収集して動作する。

アクティブRFIDタグの内部――オンボードの電池に注目

出典

パッシブタグ――比較すると非常に小さいことに注目

出典:http://www.harlandsimon.co.uk

パッシブRFIDタグは、主に次の3つの周波数帯で動作する。

* 低周波(LF)125〜134kHz
* 高周波(HF)13.56MHz
* 極超短波(UHF)856MHz〜960MHz

リーダー

リーダーは、RFIDタグと似たような構造をしている。 タグとの間で信号を送受信するためのアンテナを備えている。 リーダーは電池で動くこともあれば、コンセントに接続されることもある。パッシブタグをリーダーの近くで起動させるには、強いRF信号が必要になるからである。 リーダーはリーダーコントローラーに接続されており、リーダーが読み取った情報を管理する。 用途によっては、リーダーがタグへの書き込みや更新を行うこともある。 たとえば、地下鉄の改札にあるリーダーは入口にあり、乗客がカード(タグ)をリーダーにかざすと、カード内の残高を読み取って入場を許可する。乗客が出るときには、運賃を計算してカードの残高を更新する。

RFIDタグには、主に次の3つの構成要素がある。

  • 識別情報の保存、処理、RF信号の変調・復調を行う集積回路(IC)
  • 電波を送受信するアンテナ
  • (アクティブタグの場合)電源(電池)

リーダーとタグを合わせて、RFIDシステムを構成する。

基本的なRFIDシステム

出典:www.impinj.com

上の画像は、非常に基本的なRFIDシステムを示している。 タグチップはRFIDタグの中の集積回路である。このICが、タグに演算、メモリ、その他の拡張機能を提供する。 タグチップにはアンテナがあり、タグ付けされた物体の情報を送受信する。 受信側のアンテナはRF信号を受信し、パッシブRFIDタグに励起エネルギーを与えることもある。 読み取られた情報は、リーダーの制御・管理ソフトウェアへと送られる。

NFC

出典:techradar.com

近距離無線通信(NFC)は、RFベースの通信プロトコルである。 RFIDプロトコルのサブセットにあたるため、RFIDに似ているが、重要な違いもある。 NFCも非常に人気の高い技術になっており、現在のスマートフォンの10台中9台がNFC機能を搭載して出荷されている。 これによって、Apple PayやGoogle Walletのような非接触決済が可能になっている。

NFC対応のスマートフォンは、2台を触れ合わせるだけで、連絡先情報や写真のようなデータのやり取りを簡単な操作で行える。 Android Beamのようなアプリがこれを実現しているが、Appleの端末では、現時点でNFCはApple Payにしか使われていない。

BMWのような自動車メーカーは、NFC対応の車のキーで車のドアを開けるためにNFCを使っている。 広告やマーケティングコンテンツの中には、NFC対応のスマートフォンをタップしたりかざしたりして、アプリをダウンロードしたり、製品についてのより詳しい情報を得たりするものも見かけたことがあるだろう。

NFCは、非常に短い距離(数センチメートル)での通信を想定して設計されている。 もっとも電力効率のよい通信プロトコルの一つである。 NFCは、高周波RFIDと同じ13.56MHz帯で動作するため、NFCデバイスはHF RFIDタグを読み取ることもできる。

NFCには2種類のデバイスがある(NFCでは、デバイス自体がタグにもリーダーにもなりうる点に注意してほしい)。

  • イニシエーター:通信を開始するデバイスをイニシエーターと呼ぶ。パッシブなターゲットに電力を供給できるRF場を能動的に生成する。
  • ターゲット:イニシエーターから情報を受け取るデバイスである。ターゲットは(単純なNFCタグの場合のように)パッシブであることもあれば、スマートフォンどうしのピアツーピア通信のようにアクティブであることもある。

RFID対NFC

この2つの通信プロトコルには本質的な類似点があるため、その違いはよく話題になる。

出典:RFIDinsider

NFCとRFIDはどちらも、私たちの身の回りにあるさまざまな物やデバイスで使われている、遍在する技術であるため、IoTにおいてもどちらも有用なプロトコルである。 これらのプロトコルは、タグとリーダーの間だけでなく、それらすべてをインターネットに接続することで、身の回りのさまざまな物への橋渡しを提供してくれる。

さらに詳しく学びたい場合は、次のチュートリアルやブログ記事も参考にしてほしい(いずれも英語)。

まとめ

私たちは、インターネットがコミュニケーションと協働のあり方をどう変革してきたかを目の当たりにしてきた。 インターネットの新しい時代は、単に人と人だけの話ではない。私たちを取り巻く世界、そして知能を持ち互いにつながったデバイスについての話でもある。

ここまで見てきたプロトコルは、必ずしもすべてがIoTを念頭に設計されたものではないが、それでもIoT向けの用途にうまく適応してきた。

IoTの成長に伴い、IoTネットワークに特化した新しいプロトコルの開発が今後も進んでいくのは避けられない。 これらのつながったスマートデバイスには、今日の人間中心のインターネットとは異なる要件がある。

これらのプロトコルには、3種類の異なる接続形態がある。

  • デバイス間(D2D):デバイスどうしが直接通信する必要がある場合
  • デバイス・サーバー間(D2S):デバイスのデータが収集され、サーバーへ送られる場合
  • サーバー間(S2S):サーバーのデータが、分析やデバイスへの返送のために他のサーバーと共有される場合

出典:electronicdesign.com

ここでは、上記のさまざまな接続形態に触れながら、次の4つのプロトコルについて紹介する。

  • MQTT(Message Queue Telemetry Transport):デバイスのデータを収集し、サーバーへ送信するためのプロトコル
  • XMPP(Extensible Messaging and Presence Protocol):サーバーに接続された人とデバイスをつなぐためのプロトコル
  • DDS(Data Distribution Service):インテリジェントなデバイス間の高速通信のためのプロトコル
  • AMQP(Advanced Message Queuing Protocol):異なるサーバー間の効果的な通信のために設計されたプロトコル

MQTT

MQTT.orgは、MQTTを次のように定義している。M2M(機械間通信)のためのIoT接続プロトコルである。 非常に軽量なパブリッシュ/サブスクライブ型のメッセージング伝送方式として設計されている。 小さなコードフットプリントが求められる、あるいはネットワーク帯域が貴重なリモート環境との接続に役立つ。 たとえば、衛星回線経由でブローカーと通信するセンサーや、医療機関との断続的なダイヤルアップ接続、さまざまなホームオートメーションや小型デバイスのシナリオで使われてきた。 サイズが小さく、消費電力が低く、データパケットが最小限に抑えられ、1つまたは複数の受信者へ効率的に情報を配信できることから、モバイルアプリケーションにも最適である。

MQTTの目的は、多数のデバイスからデータを収集し、そのデータをITインフラへ運ぶことである。 何千ものセンサーからのデータを1か所に集めて分析する必要がある場合、もっとも優れた解決策の一つになりうる。

MQTTプロトコルについてのさらに詳しい情報は、こちらで確認できる。

XMPP

XMPP.orgは、これを次のように説明している。Extensible Messaging and Presence Protocolは、インスタントメッセージング、プレゼンス、複数人でのチャット、音声・映像通話、コラボレーション、軽量なミドルウェア、コンテンツ配信、そしてXMLデータの汎用的なルーティングのためのオープンな技術群である。

XMPPは、つながったデバイスどうしが互いを発見し、会話を始める、つまり私たちがそうするように情報のやり取りを始めるための手段だと考えるとよい。

XMPP-IoTについてのさらに詳しい情報は、こちらで確認できる。

DDS

デバイス・サーバー間のプロトコルであるMQTTやXMPPとは異なり、DDSはデバイスのデータを直接利用するデバイスどうしを使う。 これは、あるデバイスのデータを別のデバイスへ配信するためのプロトコルである。 DDSは、1秒間に何百万ものメッセージを、多数の受信者へ同時に効果的に配信できる。

DDSはピアツーピア型の通信である。サーバーやメッセージブローカーを排除することで、通信が単純化され、遅延が最小限に抑えられ、複雑さも軽減される。 信頼性が高く高性能なアーキテクチャを必要とするIoTの用途において、信頼できる選択肢である。

DDSについてのさらに詳しい情報は、こちらで確認できる。

AMQP

AMQPは、サーバー間のプロトコルである。サーバー間でトランザクションメッセージを送信する。 AMQPの主な特徴は信頼性であり、データを失うことなく何千ものキューに入ったトランザクションを送信できる。

AMQP.orgは、このプロトコルを次のように定義している。アプリケーションや組織間でビジネスメッセージをやり取りするためのオープンな標準である。 システムどうしを接続し、必要な情報をビジネスプロセスへ供給し、その目標を達成するための指示を確実に先へと伝える。

AMQPはもともと、重要なメッセージを追跡・配信するためのミドルウェアとして、銀行業界向けに開発されたものである。 IoTの文脈では、異なるサーバーからのデータを効果的な分析のためにやり取りする必要がある、サーバーベースの分析機能に最適である。

結論として、IoT向けの決定的な最良のプロトコルというものは存在しない。IoTはまだ標準化できる段階になく、この先も永遠に標準化できないかもしれない。 その用途の多様さと、無数の異なる種類のつながったデバイスこそが、IoTを唯一無二のものにしている。

したがって、最良のプロトコルは用途によって決まるということになる。 IoT向けのMQTTとCoAPプロトコルについてより詳しく掘り下げた、次のブログ記事も参考になるかもしれない。

タグ: Bluetooth、概念、IoT、MQTT、WiFi、無線、XBee


出典:Connectivity of the Internet of Things(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

MIDI入門

はじめに

何かの機材の背面で、このプラグを見かけたことがあるかもしれない。マイクロUSBやThunderboltが当たり前になった今の時代では、直径1/2インチほどの、5本の接点を持つかなり大きな円形のコネクタである。このプラグが2個や3個、横に並んでいることも多い。

これがMusical Instrument Digital Interface(MIDI)のプラグである。 楽器はこのポートを使って演奏データをやり取りするが、このプロトコルはステージ照明やレコーディングスタジオの機材のような、関連する機器にも拡張されて使われている。

MIDIそのものは比較的単純なシリアル通信規格だが、専門用語が多いため、とっつきにくく感じられることがある。以下のセクションでは、より細かい技術的な内容を掘り下げながら、できる限り用語を丁寧に説明していく。

背景

MIDIは、他のチュートリアルでより詳しく扱ったいくつかの概念の上に成り立っている。

歴史

MIDIをより深く理解するには、それ以前に何があったのか、そしてMIDIがどんな問題を解決しようとしていたのかを見ておくとよい。

独自仕様のアナログシステム

もっとも初期の商業用シンセサイザーは、個々のモジュールを組み合わせて音を作り上げる、大型のアナログシステムだった。 その代表例が、Moog Modularである。

Moog System 35モジュラーシンセサイザー(画像提供:Moog Music

これらのシステムでは、パッチケーブル、ノブ、スイッチの組み合わせによって、どんな音が作られるかが決まった。 今日でも、シンセサイザーの音の設定はパッチと呼ばれるが、実際にはケーブルやプラグを一切使わないこともある。

モジュール間の信号はすべてアナログで、電圧を使って音楽的なパラメータを表していた。 ある電圧がピッチを、別の電圧が音色を、また別の電圧が音量を制御する、といった具合である。 システム内では、モジュール間の信号のやり取りは標準化されており、すべてのモジュールが互いに互換性を持っていた。

しかし、この電圧の互換性は、必ずしも他のメーカーの製品には通用しなかった。 各メーカーはそれぞれ独自の要件に合わせて、独自のアナログインターフェースを実装していた。 インターフェースがどう動作すべきかについて、共通の合意はほとんどなかった。 楽器どうしを接続することはできても、同じように反応する保証はどこにもなかった。 組み合わせのパターンがあまりに多く、簡単に通信できるものではなかったのである。

1970年代後半、Herbie Hancockはシンセサイザーの可能性を追求しており、さまざまなメーカーの楽器を組み合わせたライブ用のシステムを組んでいた。 彼は、それらすべてを1台のカスタムキーボードから演奏したいと考えていた。

Herbie Hancockの1978年のアルバム『Sunlight』のジャケット裏

彼のサウンドテクニシャンだったBryan Bellは、これらのシンセを接続し、パッチの保存と読み込みを管理するシステムを設計・製作した。 それは高価で原始的なものだったが、その根底にある発想の価値を証明することになった。

デジタルシステムの登場

1970年代の終わりまでに、多くのシンセサイザーはデジタルのマイクロプロセッサを搭載するようになり、アナログ回路の制御や、自動チューニング、パターン生成(アルペジオやシーケンス)、音色の保存といった機能を実現していた。 Rolandは、自社のシンセサイザーどうしを接続するためのDigital Control Bus(DCB)や、ドラムマシンを同期させるためのDIN-SYNCを導入したが、どちらも広くは普及しなかった。

1980年代初頭、DCBとDIN-SYNCの発想を受け継ぎ、RolandはSequential CircuitsやOberheimといったメーカーと共同で、シンセサイザーを接続するための新しい規格を開発した。 MIDIは1983年のNAMMトレードショーで発表され、そこでSequential Prophet 600とRoland Juno 106が接続された。

MIDIは、パソコンの普及とともに人気を高めていった。 Apple IIやCommodore 64が家庭用コンピュータの最先端だった1984年当時、MIDIは最新技術だった。 技術が進歩し続ける中、デジタルオーディオは当たり前のものになり、MIDIも何度か改訂・拡張されてきた。 今日のたいていのコンピュータには実際のMIDIポートはないが、アダプタを使えばUSBを簡単にMIDIへ変換できる。

MIDI対応機器

プロトコルの詳細に入る前に、MIDIを搭載した機器のいくつかと、それにまつわる用語を紹介しておこう。

キーボードシンセサイザー

もっともわかりやすいMIDI機器は、ごく普通のキーボードシンセサイザーである。 このチュートリアルでは、音を生成できるものはすべてシンセサイザー、あるいは音源と呼ぶことにする。 大まかに言えば、音を生成する具体的な方式そのものは重要ではなく、楽器を区別する微妙な違いは数多くある。

Kurzweil K2000シンセサイザー(画像提供:wikimedia commons

キーボードシンセサイザーは、たいていピアノ鍵盤(コントローラーと呼ばれる)と、アナログ・デジタル・機械式のいずれかでありうる内蔵の音源を備えている。 奏者が鍵を押すと、シンセはそれに応じて音を出す。

背景にある技術によって、シンセサイザーは次のように分類できる。

  • 単音(モノフォニック):木管楽器や金管楽器のように、一度に1つの音しか鳴らせないもの。
  • 和音(ポリフォニック):ギターやピアノ、オルガンのように、複数の音を同時に鳴らせるもの。同時に鳴らせる音の数はたいてい限られており、生成できるボイスの数として指定される。
  • マルチティンバー:異なる音を同時に鳴らせるポリフォニックシンセサイザー。マルチティンバー楽器には、こうした音を使うためのさまざまなモードが用意されていることが多い。
    • レイヤリング:単純に、複数の音を同時に、ユニゾンで鳴らせるようにするもの。
    • キーボードスプリット:キーボードの区域ごとに異なるボイスを割り当てるもの。たとえば、キーボードの左側にはストリングベース、右側にはピアノを割り当てる、というようなものである。
    • ベロシティスプリット:鍵盤をどれだけ強く叩いたかによって音を変えるもの。軽いタッチではグラスハーモニカのような音が、強いタッチではパイロフォンのような音が鳴る、といった具合である。

とはいえ、コントローラーの機能と音源の機能は、必ずしも同じ筐体にまとめられている必要はない。それぞれ独立した部品として分かれていてもよい。

単体の音源

サウンドモジュールとも呼ばれる単体のMIDI音源は、音を生成するが、演奏するための機構をオンボードで備えていない楽器である。 さまざまな形態があるが、もっとも一般的なのはテーブルトップ型のモジュールと、

Moog Minitaurモジュール(画像提供:Moog Music

ラックマウント型のユニットである。

Roland D550ラックマウントシンセサイザー(画像提供:wikimedia commons

このカテゴリにもう一種類含めておきたいのが、コンピュータ上で動作するソフトウェアである、バーチャルシンセサイザーやソフトウェアシンセサイザーである。 今日では、クラシックなビンテージ楽器のエミュレーションから、単体の専用機器としては現実的でない複雑な音の生成方式まで、数多くのバーチャルシンセサイザーが利用できる。

形態は異なっていても、機能的にはこれらは同等である。 MIDI入力でコマンドを受け取り、それに応じて音を生成する。 たいてい、コンピュータのシーケンサーや外部のMIDIコントローラーと組み合わせて使われる。

単体のコントローラー

単体の音源の対極にあるのが、単体のMIDIコントローラーである。もっとも一般的なのはMIDIキーボードコントローラーだろう。

これはピアノの鍵盤を備え、追加のノブやホイール、レバーが組み合わされていることもある。 それ自体では音を出さず、外部の音源へMIDIメッセージを送信するだけである。

MIDIコントローラーは、特にバーチャル楽器が広まるにつれて、近年大きく進化してきた。 MIDIコントローラーがあれば、奏者は物理的な操作子を使って設定にアクセスできる。 マウスに手を伸ばす代わりに、実際のノブを回すことができる。 現在では、さまざまな音楽的用途を反映した多種多様なコントローラーが手に入る。電子ドラムセット、サックス、ミキシングコンソール、DJ用のターンテーブルなどである。

キーボードコントローラーと、テーブルトップ型のドラムパッドコントローラー

ドラムマシン

ドラムマシンには、音源とシーケンサーという2つの主要な要素がある。

Roland TR-808ドラムマシン(画像提供:wikimedia commons

音源の部分は、これまで説明してきたものと同様、ドラムやパーカッションの音を作るために調整されたシンセサイザーである。

シーケンサーは、ドラムのビートを記録・再生し、対応する音源をトリガーするために使われる。 シーケンサーの中には読み取り専用で、あらかじめ録音されたリズムを再生するだけのものもある。祖父母の家にあった応接間のオルガンにあった「チャチャ」「タンゴ」「メレンゲ」ボタンを覚えているだろうか。 たいていのドラムマシンはプログラム可能で、ユーザーが自分でリズムを作ることができるが、具体的なプログラミング用のインターフェースは機種ごとに大きく異なる。

コンピュータ

MIDIはパソコンとともに発展してきており、PCにはMIDIインターフェースが搭載されていることが多かった。 古いPCのサウンドカードでは、MIDIは15ピンのジョイスティックインターフェースの中に隠れており、ピッグテールアダプタを使って5ピンのDINコネクタに分岐させていた。 もちろん、15ピンのジョイスティックプラグは姿を消し、今ではジョイスティックはUSB経由で接続する。 好都合なことに、USBにもMIDIデバイスクラスが定義されているため、現代のコンピュータでもMIDIを利用できる。

先ほどバーチャル楽器について触れたが、PC向けのMIDIアプリケーションには他にも数多くの種類がある。 実際のMIDIポートで接続されていようと、USB経由であろうと、パソコンはさまざまなMIDI関連の機能を果たすプログラムを実行できる。

  • ドラムマシンと同様、シーケンサープログラムはMIDIメッセージを記録・再生し、ユーザーによるMIDIデータの編集や並べ替えも可能にすることが多い。シーケンサーには、非常にシンプルなものから極めて高機能なものまで、さまざまな形態がある。
  • 記譜プログラムは、五線譜に楽譜を書き込んで作曲し、できあがった譜面を印刷できるようにする。
  • パッチエディタは、シンセサイザーの画面上の代替操作パネルとして機能する。内部パラメータにアクセスするための小さな液晶画面しかない楽器では、PCのGUIのほうがはるかにわかりやすく音のパラメータを表示できるため、エディタは特に人気がある。
  • ライブラリアンは、楽器上の音色を読み込み、保存し、整理するために使われる。

これらの機能は、1つのアプリケーションにまとめて統合されていることも多い。 現代のシーケンサーには、バーチャル楽器を組み込み、パッチを編集・整理でき、MIDIとデジタルオーディオの両方を録音・編集できるものもある。

その他の用途

MIDIは、厳密には楽器とは言えない機器にも使われることがある。 よくある用途の一つがステージ照明の制御だが、大規模な照明システムには、DMX-512というシリアルプロトコルが使われることのほうが多い。

音楽家というのは創造力に富んだ人々の集まりでもある。MIDIが広く普及したことで、数多くの独自の楽器を自作する人たちの例が見られる。

MIDI規格

MIDI規格は、MIDI Manufacturers Association(MMA)によって管理されており、MIDI.orgというWebサイトを運営している。 MIDIの仕様書そのものは印刷された文書で、MMAから入手できる。 かなりのボリュームがあり、プロトコルの多くの側面について詳しく解説している。

ちょっとMIDIを試してみたいだけなら、オンラインで入手できる参考資料が数多くある。 しかし、本格的にMIDI楽器を作りたいのであれば、この仕様書を手元に置いておく価値がある。 メーカーとしてMMAに加盟すると、システムエクスクルーシブIDコードも取得できる。

ハードウェアと電子回路の実装

MIDIハードウェア

MIDIの設計目標の一つは、比較的安価に実現できることだった。 MIDIが作られた当時、たいていの電子楽器はすでにマイクロプロセッサシステムを中心に構築されていたため、MIDIはマイクロプロセッサ間のデジタル通信バスとして定義された。 目標の一つは、インターフェース用のハードウェアが部品表のコストを5ドルほど押し上げる程度に収まることだった。これは、他の部品と比べればごくわずかなコストだった。

物理的な実装

電子楽器にはすでに数多くのプラグや接続端子が備わっていたため、MIDIでは当時あまり使われていなかったもの、つまり円形の5ピンDINコネクタが指定された。 誤接続を防ぐため、独自のコネクタが選ばれたのである。

コネクタのピン番号が順番どおりに並んでいない点に注目してほしい。まるで、3ピンコネクタのピンの間にさらに2本のピンを追加したかのようになっている。 わかりやすくするため、この番号はコネクタのプラスチック部分に刻印されていることが多い。

このコネクタに接続するには、MIDIケーブルが必要である。

コネクタには5本のピンがあるが、実際に使われるのは3本だけである。 自分でMIDIケーブルを配線したい場合は、2個のオス型5ピンDINコネクタと、シールド付きツイストペア(STP)ケーブルが必要になる。

MIDIケーブルは、次のように接続する。

1本目のコネクタケーブル2本目のコネクタ
ピン1未接続ピン1
ピン2シールドピン2
ピン3未接続ピン3
ピン4電圧基準線ピン4
ピン5データ線ピン5

仕様では、ケーブルの最大長は50フィート(15メートル)と定められている。

Note

注:5本すべてのピンが接続された5ピンDINケーブルが欲しい場合、通常のMIDIケーブルでは目的を果たせない。すべてのピンが接続されている保証はないからである。5ピンDINケーブルを別途用意する必要がある。とっさの場合、5ピンDINケーブルをMIDIケーブルの代わりに使うことはできるが、逆はできない。

電子回路の実装

MIDI仕様には、ポート用の推奨回路が含まれており、以下のとおりである。

MIDI標準ハードウェア(画像提供:MIDI.org

この回路は、3つの部分から構成されている。

MIDI入力

回路図の上部がMIDI入力である。フォトカプラ(オプトアイソレータ)が必要になるため、回路の中でもっとも凝った部分になっている。 リファレンス設計では、とうに製造中止になったSharp PC-900が指定されているが、現代の設計では6N138がよく使われる。

フォトカプラは、インターフェース回路でよく使われる興味深い部品である。 電気的な接続を作ることなく、データを伝送できる。 内部では、入力信号によってLEDが点滅する。 その光をフォトトランジスタが受け取り、電子信号へと変換し直す。 LEDとフォトトランジスタは、物理的にわずかな距離だけ離れて配置されている。 以下の写真では、その隙間が半透明のプラスチックで埋められている。

フォトカプラの内部構造

フォトカプラがどう動作するかについては、後ほどさらに詳しく説明するが、その前にまず接続先となるMIDI出力が必要である。

MIDI出力

回路図の下部が、送信側のハードウェアで、MIDI Outジャックの背後にある。 このハードウェアは比較的単純で、UARTの送信ラインが、2個の論理反転素子(インバータ)へそのままつながっているだけである。 古いマイクロコントローラでは、I/Oピンが比較的非力で、フォトカプラ内のLEDを点灯させるのに十分な電流を出し入れできなかった。 2個のインバータを使うのは、信号の駆動力を安価に高める方法である。

Atmel AVRのような現代のマイクロコントローラは、ピン周りの回路がはるかに強力になっている。 LEDを直接点灯させることもできるが、それでもこのバッファには意味がある。 コネクタが外部の世界とつながっているため、短絡したり、誤って接続されたり、静電気放電(ESD)を受けたりする可能性があるからである。 このバッファは、いわばヒューズのような、安価で犠牲になってくれる回路であり、プロセッサそのものより簡単に交換できる。

MIDI Thru [原文ママ]

回路図の中央、破線で囲まれた部分が、MIDI thruポートである。 これは実質的にMIDI outポートのコピーだが、MIDI入力のデータ線に接続されている点が異なる。つまり、受信したデータのコピーをそのまま送信することで、複数の楽器をデイジーチェーン接続できるようにしている。 この使い方については、トポロジーのセクションでさらに詳しく扱う。

実際のMIDIポート

すべてのMIDI機器が、これらすべてのポートを備えているわけではない。 送信だけ、あるいは受信だけしか必要としない機器もあり、その場合はそれぞれMIDI OutまたはInだけがあればよい。

MIDI thruポートも任意であり、サイズやコストを抑えるために省略されることもある。

MIDI thruポートの実装方法も、解釈の余地がある。 仕様では上記のようなハードウェア実装が求められているが、必ずしもそのとおりに実装されているとは限らない。 一部の楽器は、入力からのバイトを再送信するために、2つ目のUARTを使っている。 これによって遅延が生じ、長いデイジーチェーンではタイミングの問題を引き起こすことがある。

論理的な信号

上の回路図には、「TO UART」「FROM UART」と書かれ、図の外へ伸びている2つの信号がある。

UARTは「Universal Asynchronous Receiver/Transmitter(汎用非同期送受信機)」の略である。 デジタルデバイス間でバイトを転送するデジタルハードウェアの一部で、コンピュータやマイクロコントローラのシステムに周辺回路としてよく搭載されている。 これはシリアルポートの基盤となるデバイスであり、MIDIでも使われている。

UARTの基礎に馴染みがなければ、シリアル通信のチュートリアルで学ぶことができる。

上の回路図のUART信号は、論理レベルで動作する。 アイドル状態のときは、論理ハイの状態にある。 それぞれのバイトの先頭にはスタートビット(常に0)が付き、続けて8個のデータビット、最後に1個のストップビット(常にハイ)が続く。 MIDIはパリティビットを使わない。

MIDIは31,250ビット毎秒のクロックレートを使用する。 8ビットのバイトを送信するには、スタートビットとストップビットで挟む必要があり、合計10ビットになる。 つまり、1バイトの送信にはおよそ320マイクロ秒かかり、MIDI接続の最大スループットは1秒あたり3,125バイトになる。 平均的なMIDIメッセージは3バイトの長さであり、送信にはおよそ1ミリ秒かかる。

MIDIが登場したばかりの頃、たいていのシンセサイザーは16550や8250のような、外付けの独立したUARTチップを使っていた。 その後、UARTはマイクロコントローラの中に組み込まれるようになり、AVR、PIC、ARMのチップに非常によく見られる周辺回路になった。 UARTは、ArduinoのSoftware Serialライブラリのように、ファームウェアで実装することもできる。

それぞれのバイトが何を意味し、どう解釈すればよいかについては、次のセクションでさらに詳しく扱う。

出力から入力へ

プロトコルのメッセージ部分に進む前に、出力を入力に接続したときに形成される回路を分析しておこう。 以下は簡略化した図で、出力ポートが対応する入力ポートに接続されている様子を示している。

出力側では、ピン4は小さな抵抗を介してプルアップされており、ピン5はバッファリングされたUARTの送信ラインである。 入力側では、これらの線はフォトカプラ内部のLEDのアノードとカソードに接続されている。 UARTの出力は送信していないときはハイになっているため、ピン4とピン5は同じ電圧になり、LEDには電流が流れず、点灯しない。 LEDが消灯しているとき、フォトトランジスタはオフになっており、UARTはプルアップを通じて電圧を受け取り、論理1として認識する。

UARTがバイトの送信を開始すると、スタートビットによってピン5がローに引かれ、電流がLEDに流れて点灯する。 LEDが点灯すると、フォトトランジスタがオンになり、プルアップの電流を吸い込んでUARTの入力をグラウンドまで引き下げ、0を示すことになる。

ここで注目したいのは、このLEDが電気的には送信側の回路の一部になっているという点である。 電流は送信側から出て、LEDを通り、また送信側へと戻ってくる、いわば電流ループを形成している(上の図で青く示されている)。 送信側と受信側の間には、実際の電気的な接続は一切なく、フォトカプラ内部の光による経路だけがつながっている。 これは、グラウンドループを避けるのに役立つ。

メッセージ

これまでのセクションで述べたとおり、MIDIの根本的な目標は、明確に定義されたプロトコルを話すことで、異なる機器どうしが通信できるようにすることだった。 このプロトコルは、小さなメッセージの連なりを中心に構成されている。 たいていのメッセージは1〜4バイトの長さだが、もっと長いものもあり、複数のメッセージのまとまりを必要とする情報もある。

MIDIメッセージにはいくつかのカテゴリがある。演奏に関するメッセージ(「奏者が中央のCキーを押した」)、演奏中の音についての情報(「ピアノの音からオルガンの音に変更する」)、そしてメトロノームやリアルタイムクロックのような、その他の音楽データなどである。

数値の表記について一言。以下のセクションでは、10進数と16進数の両方の表記を使う。10進数はそのまま書き、16進数には0xという接頭辞を付ける。16進数に馴染みがなければ、このチュートリアルでさらに詳しく学ぶことができる。

ステータスかデータか

前のセクションでは、MIDIのUART設定、つまり31,250ビット毎秒、1バイトあたり8個のデータビット、1個のストップビットについて説明した。MIDIは、この8個のデータビットを余すところなく使い切っている。

1バイトの中で、それぞれのビットは0か1のどちらかを取りうる。

1つの8ビットバイト

一部のバイトは、さらにニブル、つまり4ビットのかたまりに分割される。 それぞれのニブルは、バイト内の位置によって識別される。16進数で書くと、それぞれのニブルは1文字で表される。左側の文字(より上位のビットで構成される)は最上位ニブル、右側の文字は最下位ニブルと呼ばれる。

ニブルに分割されたバイト

MIDIメッセージのバイトは、最上位ビットの設定に基づいて、2つの大きなカテゴリに分けられる。

ステータスバイトの分解

最初のビットがハイ(値が0x80から0xffの範囲)であれば、それはステータスバイトを示す。ステータスバイトは、MIDIストリームにおけるコマンドにあたる。

  • ステータスバイトは、さらにニブルによって細分化される。最初のニブルはコマンドの種類を、2番目のニブルはそのコマンドが適用されるチャンネルを指定する。
  • MSBがセットされたビットの組み合わせは8通りしかない(0x8から0xf)ため、ステータスコマンドも8種類しか存在しない。
  • チャンネルニブルの4ビットはすべて使用可能で、MIDIには16通りのチャンネルがある。

最初のビットがロー(値が0x00から0x7fの範囲)であれば、それはデータバイトであり、直前のステータスバイトに対応するパラメータを示す。 MSBは必ず0でなければならない(そうでなければステータスバイトになってしまう)ため、データは7ビット、つまり0から127(0x0から0x7f)の範囲に制限される。

ステータスと対応するデータ

ステータスバイトを見ていこう。まずは一覧を示し、その後それぞれについて詳しく見ていく。

メッセージの種類上位ニブル下位ニブルデータバイト数データバイト1データバイト2
Note Off0x8チャンネル2ノート番号ベロシティ
Note On0x9チャンネル2ノート番号ベロシティ
Polyphonic Pressure0xAチャンネル2ノート番号プレッシャー
Control Change0xBチャンネル2コントローラー番号
Program Change0xCチャンネル1プログラム番号なし
Channel Pressure0xDチャンネル1プレッシャーなし
Pitch Bend0xEチャンネル2ベンドLSB(7ビット)ベンドMSB(7ビット)
System0xFさらに細分化可変可変可変

ステータスバイトの下位ニブルにチャンネル番号が入るメッセージは、チャンネルメッセージと呼ばれる。 チャンネルは、個々の楽器を分けるためによく使われる。チャンネル1がピアノ、チャンネル2がベース、というようにである。 これによって、1本のMIDI接続で複数の宛先の情報を同時に運ぶことができる。 それぞれの音は、チャンネルニブルに適切な値を設定したメッセージを送ることで再生される。

Note

チャンネルの番号付けは、しばしば混乱の元になる。4ビットでは、0から15(0x0から0xF)までの16通りの2進数の値が表せる。たいていの人は0ではなく1から数え始めるため、MIDI機器では内部的な2進数の値に1のオフセットを加えて、1から16の範囲として扱うことが多い(ただし常にそうとは限らない)。システムがうまく通信できない場合は、チャンネルの番号を1つ上下させて試してみるとよい。

これらは非常に便利で実装も簡単なので、まずはもっともよく使われる2種類のメッセージ、ノートオン/オフとシステムリアルタイムから見ていこう。

Note Off(0x80)、Note On(0x90)

Note OnとNote Offのメッセージの意味は、比較的わかりやすい。 キーボードの鍵が押されるとNote Onメッセージが送られ、鍵が離されるとNote Offが送られる。 On、Offのメッセージは、ドラムパッドやMIDI管楽器のような、他の種類のコントローラーからも送信される。

シンセサイザーはNote Onを受け取ると音を生成し始め、Note Offによって停止するよう指示される。

Note OnとNote Offは、それぞれ3バイトで構成される。

0xnc, 0xkk, 0xvv

ここで、

  • nはコマンド(ノートオン(0x9)またはオフ(0x8))
  • cはチャンネル(1〜16)
  • kkはキー番号(0〜127。中央のCはキー番号60)
  • vvは打鍵の強さ(ベロシティ、0〜127)

ベロシティは、たいてい各鍵の下に配置された、わずかにずらして取り付けられた2個のスイッチを使って測定される。 鍵が押されると、一方のスイッチがもう一方より先に閉じる。 この2つのスイッチが閉じるまでの時間差を測定することで、鍵がどれだけ速く動いたかを判定できる。 楽器によってはベロシティを測定せず、代わりに0x40(64)のような固定値をそのバイトに送信するものもある。

ここまでは表面上シンプルだと述べたが、事態を複雑にする、いくつかの巧妙な近道がある。

ランニングステータス

送信するバイト数を減らし、接続の帯域を空けるため、MIDIは一種の省略記法を使う。 同じステータスバイトが繰り返し送信される場合、このプロトコルはランニングステータスという考え方を使う。最初のステータスバイトだけを送信し、それ以降のメッセージは新しいデータバイトだけを送信するのである。 たとえば、3回のNote Onメッセージは、通常であれば次のようになる。

0x90, 0x3C, 0x40
0x90, 0x3D, 0x40
0x90, 0x3E, 0x40

ランニングステータスを使うと、2回目と3回目のステータスバイトは省略される。

0x90, 0x3C, 0x40, 0x3D, 0x40, 0x3E, 0x40

ここではNote On/Offメッセージを例に説明しているが、これはどのステータスにも適用できる。 新しいステータスバイトが届くと、それまでのランニングステータスは置き換えられる。

暗黙のNote Off

ランニングステータスをより効果的に活用するため、MIDIではベロシティ0のNote OnをNote Offの別名として扱う。 たとえば、次のオン・オフのペアから始めるとしよう。

0x90, 0x3C, 0x40
0x80, 0x3C, 0x40

オフのバイト(0x80)を、ベロシティ0のオン(0x90)に変えることができる。

0x90, 0x3C, 0x40
0x90, 0x3C, 0x00

これで2回連続のNote Onメッセージになったので、ランニングステータスを適用し、2回目のコマンドを取り除いて、1バイト分の送信を節約できる。

0x90, 0x3C, 0x40, 0x3C, 0x00

暗黙のNote Offを使う場合、暗黙的に示されるNote Offにはベロシティの値がない。 Note Offのベロシティが実装されていないことは多いが、それが演奏の重要な要素になる場合もある。 そのような状況では、楽器側がこれに対応している必要があり、たいてい設定メニューで明示的に有効化する必要がある。

システムリアルタイム

もう一つの便利なカテゴリがシステムリアルタイムメッセージである。 これは、ステータスバイトの2番目のニブルのMSBがセットされている場合(値が0xF8から0xFFの範囲)に示される。

これらのメッセージはすべて1バイトの長さである。主に、高精度なメトロノームとして機能し、シーケンサーどうしを同期させるために使われる。

種類ステータスバイト用途
Timing Clock0xF8メトロノームのようなタイミングを表し、4分音符あたり24回の頻度で送信される。実際の頻度は曲のテンポに依存する。
Undefined0xF9
Start0xFA曲の最初から再生を開始する
Continue0xFB直前に停止した位置から再生を開始する
Stop0xFC再生を停止する
Undefined0xFD
Active Sense0xFE任意の「キープアライブ」メッセージ。実装されていれば、送信側がうっかり抜けてしまったことを検出するのに使える。送信側は300ミリ秒ごとにこれを送信する。このメッセージが届かなくなると、受信側はタイムアウトし、シーケンスを停止したり、鳴りっぱなしになりかねないノートをオフにしたりして後始末をする。
System Reset0xFF受信側に電源投入時の状態へリセットするよう指示する「パニックスイッチ」。

システムリアルタイムメッセージは1バイトの長さであるため、データバイトを持たず、したがってステータスバイトには当たらない。 これらは、ランニングステータスを中断することなく送信できる。

高度なメッセージ

このセクションでは、MIDIメッセージについてさらに深く掘り下げる。難しく感じる場合は、次のセクションへ読み進めてしまい、必要になったらこのページに戻ってきてもかまわない。

Polyphonic Pressure(0xA0)とChannel Pressure(0xD0)

一部のMIDIコントローラーには、アフタータッチと呼ばれる機能がある。 鍵を押さえたまま、奏者はその鍵をさらに強く押し込むことができる。コントローラーはこれを測定し、MIDIメッセージに変換する。

アフタータッチには2種類あり、それぞれ異なるステータスメッセージを持つ。

1つ目はポリフォニックアフタータッチで、コントローラー上のすべての鍵が、それぞれ独立したプレッシャー情報を送信できる。メッセージは次の形式になる。

0xnc, 0xkk, 0xpp
  • nはステータス(0xA)
  • cはチャンネルニブル
  • kkはキー番号(0〜127)
  • ppはプレッシャーの値(0〜127)

ポリフォニックアフタータッチはあまり一般的な機能ではない。それぞれの鍵に個別の圧力センサーと、それらすべてを読み取る回路が必要になるため、たいてい高級な楽器にしか搭載されていない。

より一般的に見られるのはチャンネルアフタータッチである。 鍵ごとに個別のセンサーを必要とする代わりに、すべての鍵をひとまとめにしたプレッシャーを、1つの大きなセンサーで測定する。 このメッセージにはキー番号が含まれず、2バイトの形式になる。

0xnc, 0xpp
  • nはステータス(0xD)
  • cはチャンネル番号
  • ppはプレッシャーの値(0〜127)

Pitch Bend(0xE0)

多くのキーボードには、鍵盤の左側にピッチベンド用のホイールやレバーが備わっている。 この操作子はたいていバネ仕掛けになっており、離すと可動範囲の中央に戻る。 これによって、上方向にも下方向にもベンドできる。

このホイールは、次の形式のピッチベンドメッセージを送信する。

0xnc, 0xLL, 0xMM
  • nはステータス(0xE)
  • cはチャンネル番号
  • LLは値の下位7ビット
  • MMは値の上位7ビット

ベンダーのデータは実際には14ビットの長さがあり、7ビットのデータバイト2個として送信されていることに気づいたかもしれない。 つまり、受信側は2進数の操作を使ってこれらのバイトを組み立て直す必要がある。 14ビットは214、つまり0から16,383までの範囲を表す。 デフォルトでは可動範囲の中央になるため、ベンダーのデフォルト値はその範囲のちょうど半分、8192(0x2000)になる。

Control Change(0xB0)

ピッチベンドに加えて、MIDIには継続コントローラーCCと略されることが多い)と呼ばれる、より幅広い表現制御のための仕組みが用意されている。 これらは、下の図に示すキーボードコントローラーの、残りのノブやスライダーから送信される。

これらの操作子は、次の形式のメッセージを送信する。

0xnc, 0xcc, 0xvv
  • nはステータス(0xB)
  • cはMIDIチャンネル
  • ccはコントローラー番号(0〜127)
  • vvはコントローラーの値(0〜127)

上の写真にある操作子は、それぞれ異なるコントローラー番号を送信するよう設定されている。

たいてい、ベンダーの隣にあるホイールはコントローラー番号1を送信し、モジュレーション(ビブラート)の深さに割り当てられている。これはたいていの楽器で実装されている。

残りのコントローラー番号の割り当ては、もう一つ混乱の元になる点である。 MIDI仕様はバージョン2.0で改訂され、この文書の2〜3ページに示されているとおり、多くのコントローラーに用途が割り当てられた。 とはいえ、この実装は普遍的なものではなく、割り当てのないコントローラー番号の範囲も残っている。

多くの現代のMIDI機器では、コントローラーは自由に割り当てられるようになっている。 写真に写っているコントローラーキーボードでは、さまざまな操作子を、異なるコントローラー番号を送信するよう設定できる。 逆のことも同じように多い。コントローラー番号を特定のパラメータにマッピングできるのである。 バーチャルシンセサイザーでは、画面上の操作子にCCを割り当てられることが多い。 これは非常に柔軟だが、接続の両端で設定が必要になることもあり、標準規格で定められた割り当てを完全に無視してしまうこともある。

Program Change(0xC0)

たいていのシンセサイザーはパッチを保存するメモリを持っており、次のコマンドでパッチを切り替えるよう指示できる。

0xnc, 0xpp
  • nはステータス(0xc)
  • cはチャンネル
  • ppはパッチ番号(0〜127)

これによって128通りの音を選択できるが、現代の楽器には128個をはるかに超えるパッチが収められていることが多い。 コントローラー#0は追加のアドレス指定の階層として使われ、「バンクセレクト」コマンドとして解釈される。 このような楽器で音を選択するには、バンクセレクトのコントローラーメッセージと、それに続くプログラムチェンジという、2つのメッセージが必要になることがある。

システムメッセージ(0xF0)

最後のステータスニブルは、他のステータスに当てはまらないデータのための「何でも入れ」の役割を果たす。 これらはすべて上位ニブルが0xFであり、下位ニブルが具体的なカテゴリを示す。

前のセクションでシステムリアルタイムメッセージを扱った。 これらは、2番目のニブルのMSBが1のときに示される。 そのビットが0の場合、メッセージはさらに2つのサブカテゴリに分かれる。

System Common

2番目のニブルのMSBがセットされていない場合、これはSystem Commonメッセージを示す。 これらのほとんどは、いくつかの追加のデータバイトを含むメッセージである。

種類ステータスバイトデータバイト数用途
Time Code Quarter Frame0xF11絶対タイムコードを使ってタイミングを示す。主に映像再生システムとの同期に使われる。1つの時刻位置を送るには、エンコードされた時:分:秒:フレーム形式で8個のメッセージが必要になる。*
Song Position0xF22シーケンサーに、曲の新しい位置へジャンプするよう指示する。データバイトは、曲の先頭から数えた16分音符の数を表す14ビットの値を構成する。
Song Select0xF31シーケンサーに新しい曲を選択するよう指示する。データバイトが曲を示す。
Undefined0xF40
Undefined0xF50
Tune Request0xF60受信側に、自分自身をチューニングし直すよう要求する。**

*MIDI Time Code(MTC)はかなり複雑で、このチュートリアルの範囲を超える。MTCの細かい部分まで知る必要がある場合は、MIDI Specificationを手元に置いておくべきだろう。

**現代のデジタル楽器はチューニングを保つのが得意だが、古いアナログシンセサイザーはチューニングがずれやすかった。一部のアナログシンセサイザーには、このコマンドで開始できる自動チューニング機能があった。

System Exclusive

ここまで注意深く読んできたなら、まだ定義されていないステータスバイトが2つあることに気づくだろう。0xf0と0xf7である。 これらはSystem Exclusiveメッセージ、略してSysExで使われる。 SysExは、MIDI接続を通じて任意のデータを送信する経路を提供する。 MIDI Time Codeの機構を細かく制御するような、複雑なデータのために定義済みのメッセージ群もある。 SysExは、パッチやファームウェアの更新のような、メーカー独自のデータを送るためにも使われる。

System Exclusiveメッセージは他のMIDIメッセージより長く、任意の長さを取ることができる。メッセージは次の形式になる。

0xF0, 0xID, 0xdd, ...(さらにデータが続く)... 0xF7

このメッセージは、明確なバイトで前後を挟まれている。

  • Start Of Exclusive(SOX)データバイト、0xF0で始まる。
  • 開始バイトの後に続く1〜3バイトが識別子である。
    • 0x01から0x7Cまでの値は1バイトのベンダーIDで、MIDIの黎明期から関わっていたメーカーに割り当てられている。
    • IDが0x00の場合は3バイトのベンダーIDで、続く2バイトがその値になる。
    • ID 0x7Dは非商用の団体向けのプレースホルダーである。
    • ID 0x7Eは、あらかじめ定義された非リアルタイムのSysExメッセージを示す。
    • ID 0x7Fは、あらかじめ定義されたリアルタイムのSysExメッセージを示す。
  • IDの後にペイロードのデータが、バイトの連なりとして送信される。
  • 転送はEnd of Exclusive(EOX)バイト、0xF7で締めくくられる。

ペイロードのデータは、MIDIのデータバイトのルールに従う必要がある。つまりMSBはセットしてはならず、実際に使えるのは1バイトあたり7ビットだけである。 MSBがセットされている場合、次の3通りの状況が考えられる。

  1. End of Exclusiveバイトが、SysEx転送の通常の終了を示す。
  2. システムリアルタイムメッセージは、転送を中断することなく、その途中に現れることがある。受信側はこれらを、SysEx転送とは切り離して処理すべきである。
  3. その他のステータスバイトは、暗黙のうちにSysEx転送を終了させ、新しいメッセージの開始を示す。

トラブルシューティングのヒント:安価なUSB-MIDIインターフェースの中には、4バイトより長いメッセージを扱えないものがある。そのようなインターフェースを使っていてSysExの転送に問題がある場合は、MIDI Oxのようなアプリケーションでバス上のメッセージを確認してみるとよい。

インプリメンテーションチャート

これだけ多くの種類のメッセージがあると、MIDIは一種の方言のようなものになっている。すべての機器がすべてのメッセージを実装しているわけではない。 単純なコントローラーとシンセサイザーの接続では、ノートオン・オフのメッセージしか必要としないかもしれない一方で、ステージ上の火薬演出コントローラーは、ノートメッセージを完全に無視し、タイムコードや、発煙筒・フラッシュポットを起動するための特定のSysExコマンドだけを必要とするかもしれない。

特定の機器がどんなメッセージを使うかをユーザーが理解できるよう、マニュアルには送受信できるメッセージを示す表が含まれていることが多い。

AKAI MPC500のMIDIインプリメンテーション(画像提供:Akaipro.com

上の表は、ある楽器の典型的なインプリメンテーションチャートである。この機器が話すMIDIの「方言」について、いくつかの注目すべき点がわかる。

  • この機器はNote Onのベロシティは送信するが、Note Offのベロシティは送信しない。
  • ポリフォニックアフタータッチ、あるいはチャンネルアフタータッチのいずれかを使用する(どちらを使うかは設定メニューで選択できる)。

トポロジー

MIDIを搭載した機器の種類と、それらが使うメッセージを見てきたところで、これらをどう配置できるかのいくつかの方法を見ていこう。

ケース1:デイジーチェーン

もっとも単純な接続トポロジーは、1台の送信側が1台以上の受信側に接続される、デイジーチェーンである。

この例では、コントローラーのMIDI Outが、音源モジュールのMIDI Inに接続されている。 これによって、奏者はコントローラーの鍵を使って、モジュールから音を鳴らすことができる。 コントローラーはノートオン、ノートオフ、コントローラーメッセージを送信し、それをモジュールが音として解釈する。 通信経路は一方向である。

モジュールがマルチティンバーであれば、複数のMIDIチャンネルに応答するよう設定でき、送信チャンネルを切り替えることで、奏者は音を切り替えられる。

途中にある機器のthruポートを使えば、さらに下流にモジュールを追加できる。thruは、inポートで受信したメッセージのコピーを送信する。

コントローラーとモジュールの設定次第で、いくつかの可能性がある。

  • すべてのモジュールが、単純にユニゾンでまとめて反応する。
  • それぞれのモジュールを異なるMIDIチャンネルに応答するよう設定し、コントローラーが送信するチャンネルを切り替えることで、モジュールを個別に演奏できる。
  • それぞれのモジュールを特定のキーやベロシティの範囲に応答するよう設定し、スプリットやレイヤーを構成できる。

ケース2:同期

この例では、ドラムマシンを複数接続して、パーカッションアンサンブルを組み立てたいとする。

左側のドラムマシンがマスタークロックとして機能し、右側は(クロックスレーブ外部同期モードと呼ばれることもある)クロックメッセージを受信するように設定されている。 オペレーターが左側のマシンで「play」を押すと、両方のマシンが再生を始める。 左側のマシンのテンポを調整すると、両方のマシンが揃って加速・減速する。

システムリアルタイムメッセージが、これらのマシンを同期させ続ける役割を果たす。

  • start(0xFA)バイトが送信され、シーケンスの最初から再生を開始する。
  • clock(0xF8)バイトが定期的に送信され、共有のメトロノームとして機能する。
  • stop(0xFC)バイトが再生を停止させる。
  • continue(0xFB)を使えば、直前に停止した位置からシーケンスを開始できる。

停止中もクロックを送信し続けることができ、これによってテンポを示すLEDが正しい速さで点滅し続けられる。

ケース3:コンピュータシーケンサー

最後に見るトポロジーは、デイジーチェーンの中間にパソコンを追加するものである。

MIDIコントローラーキーボードはパソコンに接続され、音源はパソコンの下流に接続される。 チェーンの途中にパソコンを追加することで、大きな力と柔軟性が得られる。 MIDIシーケンサーソフトウェアを使えば、コントローラーからの演奏を録音し、音源モジュールで再生し、編集・アレンジして曲にまとめることができる。 シーケンサーにはたいていトラックがあり、複数の演奏を重ねられる。このように演奏を重ねて作り上げることを、オーバーダビングと呼ぶ。

シーケンサーは録音中、コントローラーからノートオン・オフのメッセージを受信する。 それをメモリに保存すると同時に、音源モジュールへ送信するため、演奏者は自分が弾いている音をその場で聞くことができる。

再生中は、MIDIコントローラーは使われず、パソコンが録音済みのメッセージを再生し、音源モジュールをトリガーする。

MIDIを実装する

MIDIメッセージを直接扱うには、バイトを操作するための2進数の演算子をしっかり理解しておくと、はるかに簡単になる。 ビット単位のANDやOR演算を使えば、ステータスビットをマスクしたり、チャンネルニブルの値を取り出したりできる。 ビットシフトは、14ビットのベンダーデータを操作するのに便利である。

以下のコードはArduino向けに書かれている。 バイトの送信にはSerial.write()メソッドが使われていることに気づくはずである。これはSerial.print()のように文字列に変換するのではなく、生のバイナリデータをそのまま送信する。 また、Arduinoで定義されたbyteというデータ型も使っている。これは符号なしの8ビット値として定義されている。 これによってステータスビットを正しく扱えるが、char型は符号付きであるため、符号付きの値に対する2進数演算は、MSBの扱いで微妙なバグにつながることがある。

以下のソフトウェアの例は、意図的に不完全なものになっている。後ほど、より完成度が高く扱いやすい選択肢を紹介する。

メッセージの生成

MIDIメッセージを送信するには、単純に適切なバイトを正しい順序で送ればよい。

システムリアルタイムメッセージがもっとも送りやすい。単にそのバイトを出力に流すだけでよい。

void send_sys_rt(byte rt_byte)
{
    // 入力は有効な範囲にあると仮定する:
    //  System RTのバイトは0xF8から0xFFの間である。
    //
    // より現実的なコードでは、各入力を検証し、範囲外ならエラーを返すべきである

    Serial.write(rt_byte);
}

チャンネルメッセージはもう少し複雑である。 最初のバイトを作るには、上位ニブルにステータスの値を設定し、チャンネルから1を引いた値を下位ニブルに入れる。 最初のバイトを送信し、続けて必要な数のデータバイトを送る。 以下のコードにはランニングステータスも組み込まれている。送信側は、最後に送信したステータスバイトをグローバル変数で追跡している。

static byte last_status = 0;

void send_channel_message(byte command,
                          byte channel,
                          int num_data_bytes,
                          byte * data)
{
    // すべての入力は有効な範囲にあると仮定する:
    //  使用できるコマンドは0x80から0xF0である。
    // チャンネルは1から16の間でなければならない。
    // num_data_bytesは1か2のいずれかであるべきである
    // dataは1〜2バイトの配列で、各要素は
    // 0x0から0x7fの範囲に収まる必要がある。
    //
    // より現実的なコードでは、各入力を検証し、範囲外ならエラーを返すべきである

    byte first;

    // コマンドの上位ニブルとチャンネルニブルを組み合わせる。
    first = (command & 0xf0) | ((channel - 1) & 0x0f);

    if(first != last_status)
    {
        Serial.write(first);
        last_status = first;
    }

    // その後、必要な数のデータバイトを送信する
    for(int i = 0; i < num_data_bytes; i++)
    {
        Serial.write(data[i]);
    }
}

最後に、システムエクスクルーシブメッセージを送信するには、識別子と、どちらも可変長のデータペイロードを送信する必要がある。 適切なステータスバイトで始まり、終わる必要がある。

void send_system_exclusive(int num_id_bytes,
                          byte * id,
                          int num_data_bytes,
                          byte * data)
{
    // すべての入力は有効な範囲にあると仮定する:
    // num_id_bytesは1か3のいずれかであるべきである
    // num_data_bytesに制約はないが、現実的な上限としては1000バイト程度が妥当だろう。
    // idとdataの値は0x0から0x7fの範囲に収める必要がある。
    //
    // より現実的なコードでは、各入力を検証し、範囲外ならエラーを返すべきである



    // start-of-exclusiveを送信する
    Serial.write(0xF0);

    // 続けて識別子のバイトを送信する
    for(int i = 0; i < num_id_bytes; i++)
    {
        Serial.write(id[i]);
    }
    // 続けて必要な数のデータバイトを送信する
    for(int i = 0; i < num_data_bytes; i++)
    {
        Serial.write(data[i]);
    }

    // end-of-exclusiveを送信する
    Serial.write(0xF7);

}

メッセージの解析

受信したMIDIストリームを解析するには、もう少し洗練された処理が必要になる。 ランニングステータス暗黙のNote Off、Active Senseのような機能は送信側にとっては任意だが、受信側はそれらに対処できるよう準備しておく必要がある。

MIDIを解析するための、簡略化した有限状態機械を以下に示す。

いくつか注目すべき点がある。

  • システムは初期化され、バイトの受信を開始する。ステータスバイトを検出するまで、入力は無意味であり破棄される。実際にはステータスバイトはかなり頻繁に現れるため、この状態は一時的なものにすぎない。
  • 「Dispatch Status」の状態は、メッセージの長さに応じてどう処理するかを決める。
    • たいていのステータスメッセージは、1バイトか2バイトのデータを持つ。
    • システムエクスクルーシブメッセージは任意の長さを取ることができ、「end of exclusive」バイトによって終端が示される。
  • ランニングステータスは、Dispatch Status状態と、各ステータス処理の分岐が連携して処理する。
    • Dispatch Statusはステータスバイトを保存しており、ランニングステータスが使われたときにそれを呼び出せるようにしている。
    • 1バイト・2バイトの分岐でFSMが繰り返しデータバイトを受け取ると、保存されたステータスを繰り返し適用する。
  • FSMがデータバイトを期待している時点であっても、代わりに新しいステータスが届くことがある。その場合、それまでのステータスは破棄され、新しいステータスがディスパッチされる。

「receive bytes」の状態がすべて二重丸で示されていることに気づくかもしれない。これは、より複雑な振る舞いを表す略記法である。 先ほど触れたとおり、システムリアルタイムのバイトはどの時点でも発生しうる。 Note Onメッセージのベロシティバイトを待っている最中に、代わりにクロックバイトを受け取ることもありうる。 クロックは、解析処理を妨げることなく割り込むことが許されている。 受信状態の詳細を、以下に示す。

解析用のFSMの観点から見ると、システムリアルタイムのバイトはデータバイトともステータスバイトともみなされず、届き次第そのまま処理されるだけである。

上の図は、MIDIストリームのバイトをどうデコードするかを示しているが、受信側がそれらにどう応答するかについては何も示していない。 「処理する」という動詞をあえて曖昧なままにしているのは、機器の種類によって応答の仕方が異なりうるからである。

Arduinoライブラリ

上のFSMはかなり複雑である。これを書いてデバッグするというのは、それなりに本格的なソフトウェア開発になる。

しかし、もっと簡単な方法がある。GitHubユーザーのFortySevenEffectsが、MIDIメッセージの読み書きをはるかに簡単にしてくれるArduino MIDIライブラリを作成している。 このライブラリは柔軟で、さまざまな用途に合わせて設定できる。

  • ハードウェアシリアルポートでもソフトウェアシリアルポートでも使える(ハードウェアシリアルポートをデバッグメッセージの出力用に残しておくこともできる)。
  • 受信メッセージはポーリングで受け取ることも、特定のメッセージに対するコールバックを設定することもできる。
  • 特定のMIDIチャンネルのメッセージだけをフィルタすることも、すべてのチャンネルを受信することもできる。
  • 入力をそのまま出力ポートへエコーバックする、任意の「ソフトthru」ポートも実装している。

doxygen形式の詳細なドキュメントも用意されている。

このライブラリを使った実践的な例については、SparkFun MIDI Shield使い方ガイドを参照してほしい。

自分だけのインプリメンテーションチャートを作る

メッセージのセクションで、MIDIインプリメンテーションチャートについて触れた。 MIDI機器を実装するのであれば、どのメッセージを処理すべきかを把握するために、自分自身のチャートを書いておくことを検討するとよい。 たいていの機器はすべてのメッセージを実装しているわけではなく、実装しているメッセージについても、あえて無視することを選ぶ場合もある。 たとえば、音源はノートオン・オフのメッセージを処理するが、それも自分のMIDIチャンネルにあるものだけである。 不要なステータスについては、単純にそのメッセージを破棄すればよい。

メッセージを破棄することを選ぶ場合でも、System Resetメッセージ(0xff)だけは処理しておくことを勧める。これは、できるだけ早く音を止める必要がある状況で「パニックスイッチ」として使われるからである。

その他のMIDI関連技術

MIDIは通信プロトコルに加えて、相互互換性をさらに高めるためのいくつかの関連技術も規定している。 MIDIはこれまで何度も拡張され、メッセージングプロトコルの一部を明確にしたり、電子楽器に関連する分野の標準化を助けたりしてきた。 網羅的な一覧ではないが、以下ではよく使われる拡張のいくつかを扱う。

Standard MIDI File

MIDIシーケンサーが普及するにつれ、人々は曲のデータを異なるシーケンサー間で移動させたいと考えるようになった。 それぞれのシーケンサーは独自のファイル形式を実装しており、他のシーケンサーのデータを取り込めるものもあったが、決して普遍的なものではなかった。

Standard MIDI Fileは、シーケンスデータをやり取りするための共通言語として規定された。 このファイルにはSMFという拡張子が使われる。

SMFは、さまざまなOSにまたがって広く採用されている。 メディアプレーヤーのプログラムで再生できるほか、本格的なシーケンサーであればSMFをインポート、編集、エクスポートできる。

General MIDI

異なるプラットフォーム間でシーケンスデータを移動させると、関連するもう一つの問題が生じる。MIDI通信プロトコルは、楽器がパッチの変更をどう解釈するか、楽器をMIDIチャンネルにどう対応させるか、マルチティンバー機能をどう実装するかを規定していない。 General MIDIは、これらのパラメータにいくらかの標準化を加え、異なる楽器が似たような反応をするようにする。

General MIDIは標準の音色セット、つまりプログラムチェンジコマンドと特定の音色パッチの対応を定義している。 チャンネル10を除くすべてのMIDIチャンネルでは、プログラム#1は常にグランドピアノのパッチ、#2は「ブライトピアノ」、といった具合になる。

チャンネル10はドラム専用に予約されており、キーボードとドラムサウンドの対応関係も定義されている。

General MIDIはまた、対応する楽器が16チャンネルすべてで同時に音を鳴らせ、少なくとも24音のポリフォニーを提供する必要があることも規定している。

General MIDIの機能に対応した楽器には、General MIDIのロゴが表示される。

General MIDIのロゴ

General MIDIの音色セット向けに作られたシーケンス(たいていSMFとして保存される)は、どのGeneral MIDI対応楽器でも似たように再生される。 もちろん、標準化されているとはいえ、楽器ごとに多少のばらつきは生じる。

General MIDIは、内蔵のウェーブテーブルシンセサイザーを備えたPCのサウンドカードでもよく使われていた。 これはそれ自体が楽器として演奏可能であり、ビデオゲームのサウンドトラックにも使われた。 携帯電話にもGM音源が搭載されており、着信音としてSMFファイルを使うことができた。 今日では、コンピュータや携帯電話はビデオゲームのサウンドトラックや効果音のためにオーディオファイルをそのまま扱えるようになっており、General MIDIとSMFの組み合わせはあまり使われなくなってきている。

限界

MIDIは、当初の課題を解決するという点では大きな成功を収めた。異なるメーカーのシンセサイザーが、演奏情報をやり取りできるようになったのである。 演奏者はMIDI楽器を接続すれば、それらは似たように反応する。 それを実現できたこと自体が革命的であり、MIDIが広く普及する道を切り開いた。

しかし、その人気は諸刃の剣でもあった。 MIDIが普及するにつれ、何度も改訂・拡張され、当初の想定をはるかに超える機能を備えるようになった。 振り返ってみると、こうした機能の中には、いささか扱いにくかったり、時代遅れになってしまったりしているものもある。 たとえば、SysExメッセージを使ってMIDI楽器との間でファイルをやり取りすることもできるが、今日ではSDカードやUSBメモリを受け付ける楽器を作るほうが簡単かもしれない。

よく挙がるいくつかの不満を見ていこう。

ピアノ鍵盤という前提

MIDIはピアノ鍵盤をデジタルで表現することを基盤としており、もともとキーボードを備えた楽器にはよく機能する。 ノートオン・オフのコマンドは、ピアノの鍵を押すという動作にわかりやすく対応している。 しかし、他の楽器とどう関係するかは、それほど明確ではない。

具体的な例として、ギターの演奏をMIDIデータに変換するのは特に厄介である。 ギターの弦の振動を正確にMIDIのノート番号に変換するのは、単にスイッチが閉じたことを検知するのに比べて、はるかに難しい。 市販のMIDIギターも存在するが、ギターの単純な代替品としてではなく、独自の楽器として捉えるのがもっともよいアプローチである。

ピアノ鍵盤はまた、12音の西洋の半音階と本質的に結びついている。 他の文化圏の音階をMIDIにどう変換するかは、必ずしも自明ではない。 代替のチューニング情報を伝送するシステムエクスクルーシブメッセージもあるが、その実装はあまり一般的ではない。

デジタル技術としての制約

MIDIは、1980年代初頭には安価だったデジタル技術を使って設計された。 それから30年以上経った今も、MIDIは使われ続けている。同じ時代の他の多くのデジタル技術は、すでに姿を消している。5.25インチのフロッピーディスクや、モノクロでテキストのみのディスプレイを覚えているだろうか。

その30年の間に、コンピュータネットワーキングは大きく成熟してきた。 イーサネットやUSBのような現代のプロトコルと比べると、MIDIは極めて原始的である。 リンクは一方向であり、チェックサムやCRCのようなデータの整合性を確認する仕組みもなく、アドレス(チャンネル)は手動で設定する必要がある。 31,250ビット毎秒というリンクの速度も、相対的に遅い。

このコインの裏側として、MIDIは慎ましいマイクロコントローラシステムでも実装しやすいという利点がある。 シリアルポートの周辺回路は、多くのMCUに搭載されている。 データレートが低いということは、受信側に過剰なデータを押し付けにくいということでもある。 メッセージが小さいため、保存するのにも多くのメモリを必要としない。

メッセージの中にも、基盤となるデータフォーマットが制約されている箇所が数多くある。

チャンネルのデータは4ビットしかないため、1本のMIDIバスは最大16チャンネルまでしかサポートできない。 これへの一般的な回避策は、複数のバスを併用することである。

MIDIで送信される値の多くも制約されている。キー番号、継続コントローラー、アフタータッチの値はすべて7ビットの長さで、0から127までの範囲しか表せない。これは一部のパラメータには粗すぎることがある。 MIDIには、継続コントローラーをMSBとLSBのペアとして組み合わせ、14ビットの値を構成する仕組みもあるが、実際にはあまり使われていない。

ある市販のキーボードコントローラーの出力を調べたところ、ベンダーは実際には14ビットのベンダーメッセージのうち、上位7ビットにしかデータを送信しておらず、残りは詰め物になっていた。 ホイールをゆっくり動かすと、耳で聞き取れるほどの階段状の変化が生じる。 これはおそらく、システムのMCUに内蔵されたペリフェラルである、基盤となるADCの分解能によるものだろう。

MIDIは、成長の余地をあまり残さなかったのである。

更新と代替技術

MIDIが歩んできた道は、そこで分岐している。 一方の枝は、MIDIのメッセージ形式を保ったまま、より新しい技術で伝送するというものである。 もう一方の枝は、前のセクションで見てきたような限界に対処するための、新しい技術を発明するというものである。 以下では、両方の枝のうち、より広く使われている技術のいくつかに触れる。

より新しい伝送方式でのMIDI

USBは、古いPCの背面にあった、混乱を招くほど多種多様なポート群を置き換えることを目指して作られた。 かつては、PCに接続する周辺機器ごとに異なるコネクタが使われていた。キーボード、マウス、モデム、プリンタ、ジョイスティックには、それぞれ固有のプラグがあった。 USBは、これらすべての機能を1種類のホットスワップ可能なコネクタでこなせるよう設計された。 USBは2000年代初頭に一般的になった。

上記のような周辺機器に加えて、USB仕様にはMIDIポート向けのデバイスクラスも含まれている。

ほぼ同じ頃、Firewire(別名IEEE-1394)も展開されていた。 USBと似た存在だったが、より高帯域なマルチメディア用途を対象としていた。 マルチメディア指向のインターフェースとして、MIDIとの相性は自然に良かった。 初期の展開では、FirewireはUSBよりもはるかに高い帯域幅を持つという利点があった。1394が400Mbit/sだったのに対し、USBは12Mbit/sだった。

USBとFirewireにおけるMIDIの実装は似たようなものである。UARTとDINコネクタが、それぞれのバスインターフェースとプラグに置き換えられている。 とはいえ、やり取りされるメッセージは依然としてMIDIメッセージであり、USBやFirewireのトランザクションとしてラップされているだけである。 MIDIのメッセージング自体は、実質的に変わっていない。 これによって下位互換性は保たれているが、MIDIの限界そのものへの対処にはなっていない。

これらの適応版プロトコルは、最終的にはまったく異なる運命をたどることになった。

USBは広く使われ続け、今も進化を続けている。 USB 2.0の改訂では、480Mbit/sの高速オプションが追加され、1394がUSBに対して持っていた速度の優位性に対処した。 多くの新しいMIDI機器は、通常のMIDIポートの代わりに(あるいはそれに加えて)USBポートを備えている。 下位互換性のための、単体のUSB-MIDIインターフェースアダプタも存在する。

USB-MIDIアダプタ

Appleは長らくFirewireを推進する原動力だったが、その後はThunderbolt)やLightning)インターフェースへと切り替えた。 その結果、Firewireの人気は下がってきている。

Web MIDI

World Wide Web ConsortiumによってHTML5の一部として導入されたWeb MIDIは、Webページがユーザーのパソコン上のMIDI機器にアクセスできるようにするHTMLの拡張である。 Webページは、MIDIポートを見つけ出し、それを入力や出力として使うことができる。

以下は、Web MIDIアプリケーションの一例であるシンセサイザーである。 Web MIDIを使ってパソコン上のMIDIポートを検出する。 ユーザーがポートを選択すると、接続されたMIDIコントローラーからこのシンセサイザーを演奏できるようになる。 音の生成には、Web Audio APIを使用している。

自分で試してみたい場合は、こちらをクリックしてほしい。

Web MIDIとWeb Audioのいくつかのデモとともに、この例はwebaudiodemos.appspot.comによるものである。 作者のChris Wilson氏は、自身のGitHubリポジトリでソースコードを公開している。

その他の規格

MIDIは新しい用途に適応させられている一方で、まっさらな状態から作り直すほうが簡単な場合もある。

SoundfontsとDownloadable Sounds

GMにつながった発想をさらに発展させたのが、シンセサイザー間で音のデータをやり取りできるようにするファイルであるSoundfontsである。 数値を使って音の種類をリクエストするだけでなく、サンプルデータと関連するパラメータをすべて一緒に送ることで、音そのものを持ち運べるようにしている。

SoundFontはE-Mu SystemsとCreative Labsによって開発され、SoundBlaster AWE32サウンドカードで初めて実装された。 Downloadable Sound(DLS)は、MMAが採用した、音のデータを転送するための同様の発想である。

DMX-512

一部のベンダーはMIDIをステージ照明の制御に適応させたが、これはこのプロトコルの副次的な用途にすぎない。 MIDIには照明関連の情報を表すための固有のメッセージや構造がなく、規定されている最大ケーブル長50フィートは、大規模な照明システムには短すぎる。

DMX-512は、1986年に照明制御プロトコルとして規定された。 MIDIと同様、機器の一方向のデイジーチェーンを使用する。 しかしMIDIとは異なり、はるかに長いケーブル配線を可能にする、差動のRS-485電気インターフェースを使用する。 アドレス方式も大きく異なっており、1本のバスで最大512台の機器をサポートする。

このチェーン上のメッセージングプロトコルは、実際にはMIDIよりもはるかに単純である。 コントローラーは、最大512バイトの長さのバイト列を一気に送出する。 バス上の各機器にはアドレスが設定されており、そのアドレスによって、送出されたデータのどのバイトが自分向けかがわかる。

単純な照明器具であれば、明るさを制御する1バイトだけを受信するかもしれないが、モーター駆動の照明器具であれば、パン、色、明るさ、クコロリスの選択、その他のエフェクトを制御するために、多くのバイトを受信することもある。

Open Sound Control(OSC)

長年にわたり、MIDIの座を奪おうとする試みが数多くなされてきた。いくつもの新しいプロトコルが提案されてきたが、たいていは普及しなかった。

その中で注目すべき例外の一つが、Open Sound Control(OSC)である。

OSCは、UCバークレーのCenter for New Music and Audio Technology(CNMAT)によるプロジェクトである。 MIDIと比べると非常に高いレベルで動作し、現代的なネットワーキングとデータ構造の手法を活用している。 通常はイーサネット上で伝送されるが、シリアルポート経由でSLIPを使うよう適応させることもできる。 データ構造は階層的で、拡張性がある。

WikipediaのOSCについてのページには、OSCを実装しているハードウェアとソフトウェアの一覧がある。

OSCは、MIDIとは逆の問題を抱えているとも言える。MIDIが厳密に制約されており、メッセージが標準化されているのに対し、OSCは極めて自由度が高く、相互運用性をそれほど重視せずに、それぞれの実装が独自の方言を定義できてしまう。 SYNは、コントローラーとシンセサイザーの間で使うための共通の方言として提案されているものである。

まとめ

参考資料

自分だけのMIDIシステムを構築したいなら、その助けになるいくつかの製品がある。

  • 自分でMIDI機器を作りたい場合は、Arduino互換のMIDI Shieldから始めるとよい。このシールドの使い方ガイドには、いくつかのサンプルスケッチが載っている。
  • シールドではやりすぎだという場合は、単体のMIDIコネクタも扱っている。
  • DINコネクタをまるごと省きたい場合は、FreeSoC2Teensyが、いずれもクラス準拠のUSB-MIDIエンドポイント実装を提供している。
  • Dr. Bleepは、Bleep Drumの第2版にMIDIを追加している。

さらに詳しく

  • MIDI.orgは、MIDI Manufacturer’s Associationの公式サイトである。
  • ArduinoでMIDIを扱うなら、47 EffectsのMIDIライブラリがメッセージング層を代わりに処理してくれる。使いやすく、設定の自由度も高い。
  • MIDI機器は、昔からDIYのマイクロコントローラープロジェクトの定番だった。MIDIboxは、さまざまなMIDI機器を作るためのプラットフォームである。
  • 有限状態機械についての考察。
  • WikipediaのMIDIの記事
  • 本格的にMIDIに取り組みたいなら、Complete MIDI 1.0 Detailed Specificationの印刷版を手に入れておくとよいだろう。

BLE経由でMIDIを制御する方法についてさらに詳しく知りたい場合は、次のブログ記事にリンクされているMIDI BLEのチュートリアルを参照してほしい。

タグ: オーディオ、通信、概念


出典:MIDI Tutorial(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

SparkFunのトラブルシューティングのコツ

はじめに

「動かない!」電子工作をしていると、よくこう口にすることになる。しかし心配はいらない。数多くのトラブルシューティングのコツを知っておけば、問題の診断は見た目よりもずっと簡単になる。 このチュートリアルでは、SparkFunのテクニカルサポート部門によく寄せられる、一般的なトラブルシューティングのコツと、よくある解決策のいくつかを紹介する。 これらのコツがすべてのケースやプロジェクトに当てはまるわけではないが、問題の原因を突き止めるための良い出発点になるはずである。

前提

SparkFunが製造する開発ボードやブレイクアウトボードは、たいていポゴピン式の検査治具でテストされ、梱包・出荷される前に技術者による品質検査を受けている。 ここでは、基板自体は最初から問題ないものとして話を進める。

おすすめの道具

最低限、安価なマルチメーターは基本的なトラブルシューティングに欠かせない。セットアップによっては、追加の工具や部品が必要になることもある。

参考になるチュートリアル

以下の概念に馴染みがなければ、いくつかのスキル系チュートリアルを確認しておくことをおすすめする。プロジェクトの複雑さによっては、トラブルシューティングに追加のスキルが必要になることもある。

まず何かを始めてみる

「無線モジュールのネットワークに接続した10,080個のアドレサブルLEDを、1枚の基板で制御して、それをサメに取り付けたいんです。ちなみに、電子工作は今まで一度もやったことがありません。」

ちょっと待ってほしい。大きく一歩下がって、突拍子もないプロジェクトに飛びつく前に、まずは単純なところから始めよう。あと、動物をプロジェクトに巻き込むのはやめてほしい。 SparkFunのテクニカルサポート部門には、こういった興味深い相談が寄せられることがある。上の例は、サポートに寄せられる質問を誇張して一般化したものである。 プロジェクトに飛び込む前に、まずは基礎から始め、どこで情報を探せばよいかを見ていこう。 まずは、関連するドキュメントを確認するところから始めるとよい。夢は大きく持ちつつ、こうした小さな一歩から始めよう。

製品ページとキットから始める

SparkFunでは、カタログに掲載している部品についての情報をできる限り提供しようと努めている。 製品の説明文を読むだけでなく、製品ページのドキュメントセクションもぜひ確認してみてほしい。 製品によっては、数多くの有用なリンクが用意されている。 たとえば、SparkFun FTDI Basic Breakout — 3.3Vの製品ページを見てみよう。そこにリンクされている情報には、次のようなものが含まれる。

  • 回路図
  • Eagle設計ファイル
  • 使い方ガイドや実験ガイド
  • プロジェクトのチュートリアル
  • ドライバ
  • データシート
  • ユーザーマニュアル
  • GitHubリポジトリ

おすすめ製品の下までスクロールすると、その製品に関連する情報がある場合、「Product Help and Resources」というセクションが表示されることがある。 チュートリアルからテクニカルサポートのヒント、Hackster.io上でその部品が使われたプロジェクトまで、さまざまな情報が含まれる。 さらに下(この画像には写っていない)には、ユーザーが投稿したコメントのセクションもある。

キットに使われている特定の開発ボードを確認してみるのも、始めるうえで参考になる。 それぞれのキットには、その製品を使い始めるのに役立つ基本的な例やプロジェクトが含まれている。 ハードウェアの電子工作やプログラミングをまだ経験したことがない場合は、SparkFun Inventor’s Kit V3.3 for RedBoardやmicro:bit向けのキットを確認してみるとよい。これらのキットでは、部品をはんだ付けする必要はない。

データシートとマニュアル

基板の複雑さによっては、PCB上に異なる仕様を持つ数多くの部品が搭載されていることもある。 たいていは、ブレイクアウトボードの主要なICについて考え、I/Oピンの絶対最大定格、そのチップ全体がどれだけの負荷に耐えられるか、そしてそのICが何をできるかを確認するようにしている。 データシートの読み方のコツについては、以前のチュートリアル「How to Read a Datasheet」も参考にしてほしい。 ユーザーマニュアルには、製品の使い方についての実例やアプリケーションノートが載っていることもある。

オンラインでの情報収集

SparkFunのオンラインチュートリアルYouTube動画、ブログ記事(EnginursdayEngineering Roundtableなど)はどんどん増えているが、それ以外にもオンライン上には数多くの参考資料がある。役立ちそうなものをいくつか紹介する。

インターネットに投稿されたものであれば、クラウドはすべてを知っている。ページ上部のサイト内検索だけでなく、さまざまな検索語を使ってオンラインの検索エンジンで調べてみると、誰かが自分と似たようなことをすでにやっていないか確認できる。 おそらく世界のどこかに、同じプロジェクト(あるいはそれに近いもの)にすでに取り組んだ人がいて、その情報をオンラインで公開しているはずである。

ハードウェアの確認

指示どおりに進めたのに、部品やプロジェクトが期待どおりに動かない。使い方ガイドやチュートリアルに書かれているとおりに試してみたのに。 電子工作とプログラミングに取り組むということは、問題を診断し、部品を正しく機能させるための解決策を見つけるということでもある。心配しなくていい。誰にでも起こることであり、こうした課題があるからこそ学び、成長できる。 自分の回路で何が起きているのか、見つけ出していこう。

接続を確認する

その部品やプロジェクトはちゃんと接続されているだろうか。「接続を確認する」とはどういうことか、はっきりさせておこう。 よくあるトラブルシューティングの方法は、ハードウェアの接続と電源に、物理的な問題がないか確認することである。

ピン間に導通はあるか、接続はしっかりしているか

接続がゆるんでいると、回路が不完全になり、問題を引き起こすことがある。 配線が誤って接続されていたり、ゆるんでいたりする可能性を考えて、配線された接続をもう一度確認しておくのがよい。 以下の画像は、細い線をブレッドボードやメス型のヘッダーソケットに挿しただけの、試作時によく見られる不安定な電気接続の例である。 回路に少しの衝撃や振動が加わるだけで、接続が失われてしまうことがある。

やや信頼できる: ブレッドボードに接続されたLidar信頼できない: RedBoardとブレッドボードに接続されたLidar信頼できない: Arduino Pro Mini 3.3Vのメスヘッダーに接続された指紋センサー

ブレッドボードに接続された細い線は、製造方法や金属ストリップにかかった負荷の度合いによって、ゆるんでしまうことがある。 メスヘッダーに接続された細い線は、ソケットの公差の関係で、さらに不安定になりやすい。

より確実な接続にするには、配線をヘッダーピンにはんだ付けし、熱収縮チューブを追加するとよい。 SparkFunのスナップ式プロト基板を使ってアダプタを作ることもできるし、試作用基板を使ってカスタムシールドを作ることもできる。

短絡していないか

回路の短絡は、あるピンが触れてはいけない何かに触れていると、問題を引き起こすことがある。 部品が触れられないほど熱くなっていないか確認しよう。 ピンが短絡している場合は、電源を切り、ゆるんだ配線が触れてはいけない何かに触れていないか確認しよう。 基板を金属製のテーブルの上に直接置かないようにすること。

配線やケーブルが不良ではないか

配線やケーブルが不良で、回路がつながらないこともある。 導通測定に設定したマルチメーターで回路を確認してみるとよい。それでもだめなら、別の配線やケーブルを試してみよう。

そのUSBケーブルはどこで手に入れたものか

ケーブルの中には、充電専用に設計されており、データ線がまったく接続されていないものもある。 また、ケーブル内部に微細な断線が生じていることもある。 別のUSBケーブルを試してみることをおすすめする。 あるお客様が、学校の実験室にあったUSBケーブルを使ってArduinoにコードをアップロードしようとしていた事例があった。4本のうち3本が損傷していて使い物にならなかった。4本目のケーブルだけが、そのデバイスで正常に動作した。 こうした場合は、新品のUSBケーブルを注文してみるのもよいだろう。

部品を正しい極性で接続しているか

特定の極性を持つ部品は、正しい向きで接続しないと動作しない。 部品が正しく実装されているか確認しよう。これは、電池、集積回路、マイクロコントローラ、トランジスタ、電圧レギュレータ、電解コンデンサ、ダイオードなど、多岐にわたる。 詳しくは、極性のチュートリアルを参照してほしい。

基本的な接続方法どおりに接続したか

すべて正しく配線されているように見える場合は、最初に戻って基本的な接続方法を見直してみるとよい。 部品をいったん外し、それぞれの回路を配線し直してみることも、トラブルシューティングの助けになる。これによって、問題の範囲を絞り込みやすくなる。

2つの部品が似た名前だったり、見た目が同じだったりしても、実際には別物であることがある点にも注意してほしい。 たとえば、Arduino Mega 2560には「Arduino」という名前が含まれているが、Arduino Uno R3を使う回路をそのまま置き換えられるとは限らない。 気づきにくい細かな違いがいくつかある(ピンの配置が異なる、Software Serialに制約がある、ボード定義が異なる、など)。 場合によっては、ピンを再定義したり、回路を配線し直したりする必要が出てくることもある。

部品箱から正しい部品を取り出せているか、ICのラベルをよく確認しておこう。 たとえば、TMP36とBJTトランジスタは同じものではない。パッケージの見た目は同じでも、まったく別物である。これはSparkFun Inventor’s Kitでもよく見られる混同である。 別の事例では、あるお客様が別のnチャンネルMOSFETを使っていた。そのnチャンネルMOSFETは見た目こそ同じだったが、仕様が異なっていたため、回路の中でトランジスタが完全にオンにならなかった。

はんだ付けの接合部を確認する

はんだ付けの接合部は理想的で、十分な接続ができているか

そう、ここでも改めて接続を確認する。 ブレイクアウトボードを配線でブレッドボードに接続しようとしている場合、ブレイクアウトボードと配線の間の接続が十分かどうかを確認しておく必要がある。 以下の3枚の画像は、理想的とは言えないはんだ付けの例である。

1枚目の画像では、ヘッダーピンとブレッドボードをつなぐはんだ付けがまったくされていない。 ヘッダーピンのはんだ付けを助けるという目的ではよい方法だが、Pro Miniを他のブレイクアウトボードに接続しようとしている場合には不向きである。

信頼できない: はんだ付けされていないPro Miniとヘッダーピンをブレッドボードに挿した状態

2枚目の画像にははんだが乗っているものの、接合部は理想的とは言えない。 30番の行に沿った最初のピンには、はんだがまったく乗っていない。 29番の行のピンには、ヘッダー側には多少はんだが乗っているが、基板とは接触していない。 28番の行のピンは問題ないが、はんだが多すぎる。はんだの塊がピンからはみ出している部分もある。 27番と26番の行のピンには、意図しないはんだブリッジができてしまっている。 25番の行のピンは、スルーホールパッドとピンの両方にはんだが乗っているように見えるが、接続はできていない。 理想的なはんだ付けの接合部と言えそうなのは、21番の行にあるRSTピンだけである。 それ以外のすべてのピンは、再加熱するか、はんだを追加するかして、十分な接合を作れるようやり直すべきである。 さらに、Atmega328P IC上のピン間にも、意図しないはんだブリッジができている。 意図しないはんだブリッジを取り除くには、はんだ吸い取り線を使い、次の質問も確認してみるとよい。

信頼できない: はんだ付けの状態が悪いPro Mini

3枚目の画像は、1×12のヘッダーがPro Miniに誤ってはんだ付けされている様子をはっきりと示している。 はんだは、ヘッダーの短いほうの側に付けるべきである。ピンを保持している黒いハウジングは、PCBとブレッドボードの間に来るべきである。 さらに、はんだの接合部がピンの長さを超えて広がってしまっている。 まっすぐなヘッダーピンの長さのせいで、このPro Miniはブレッドボードに完全には挿し込めない。

信頼できない: はんだ付けの状態が悪く、ヘッダーが誤った側に付いているPro Mini

解決策は、はんだを追加するか、しっかりと接続できるようにはんだ付けをやり直すことである。 以下の画像は、Pro Miniに理想的なはんだ付けができている例である。 はんだ付けと理想的な接合部についての詳しい情報は、スルーホールはんだ付けのチュートリアルも参照してほしい。

信頼できる: Arduino Pro Miniとまっすぐなヘッダーピンの間の理想的なはんだ付けの接合部

本来はんだブリッジがあるべきでない場所に、ピンをつなぐはんだブリッジができていないか

回路によっては、基板の特定の箇所にあえてはんだブリッジを作りたい場合もある。 ICやヘッダーピンに意図しないはんだブリッジができている場合は、基板をやり直してそのはんだブリッジを取り除く必要がある。

以下は、「Simon Says」PTHはんだ付けキットで、意図せずできてしまったはんだの接合部の例である。

修正するには、はんだ吸い取り線を使ってはんだブリッジを取り除くとよい。 はんだ吸い取り線の使い方については、「Solder Jumpers」というラベルが付いたこちらのトラブルシューティングのセクションも参考にしてほしい。

基板に水溶性フラックスの残留物が残っていないか

水溶性フラックスを使っている場合は、基板に残った水溶性フラックスの残留物を必ず取り除くようにしよう。 これは、ピンの酸化や、デンドライト(樹枝状結晶)によるピン間の一時的な短絡を防ぐためである。 以下は、量産用のパネルに残った水溶性フラックスの残留物の画像である。

回路によっては、フラックスが残ったままでも問題なく動作することがあるが、シリアルUART経由で信号を送る回路(Arduinoへのコードのアップロードや、別のUARTへのASCII文字の送信など)やI2Cでは、汚れた基板が大きなトラブルの原因になっているのを見たことがある。 基板に残った水溶性フラックスによる問題は、避けておくに越したことはない。実際、SparkFunが組み立てる基板は、この種のフラックスを使っている場合、洗浄されている。

水溶性フラックスの残留物を取り除くには、少量の脱イオン水かイソプロピルアルコールと、歯ブラシを使うとよい。 脱イオン水の代わりとしては、趣味の用途であれば、水道水よりもミネラル分を含まないボトル入りの水を先に試すとよいだろう。 とはいえ、水道水を使うと沈着物が生じ、後々問題を引き起こすこともある。 圧縮空気を使って、基板に残った余分なフラックスや水分を乾燥させよう。 ヒートガンリワークステーションの温風を使って乾燥させることもできる。

特定の部品は水に弱いため、これらの部品を濡らさないよう注意する必要がある。水との接触を避けるべき部品の短い一覧を挙げる。

  • キャラクタLCD
  • 7セグメントLEDディスプレイ
  • 電池
  • GPSモジュール
  • 無線モジュール
  • 気圧センサー
  • スライド式ポテンショメータ
  • マイク
  • スピーカー
  • 心拍センサーIC

これらの内部に水が閉じ込められた状態で基板に電源を入れると、部品が損傷してしまう可能性が高い。

配線の長さ

必要以上に長い配線を使っていないか

使用している導電材料によっては、導電糸や配線の抵抗が、ある一定の距離を超えると増加することがある。 これは導電糸で特に顕著であり、解決策としては糸を二重にすることが挙げられる。

配線を数百フィートを超える距離で使う場合も、問題が生じることがある。 たとえば、ある長さを超えるとI2Cセンサーが正しく動作しなくなった事例がいくつかある。 I2Cはもともと短い距離で使うことを想定して設計されているため、一定のフィート数を超えて使うと、センサーがデータを送信する際に問題が生じることがある。 解決策としては、プルアップ抵抗を調整するか、データの送り方を工夫する(各センサーノードにマイクロコントローラを配置し、無線デバイスを追加するなど)ことが考えられる。

別のコンピュータで確認する

別のパソコンで試してみたか

デバイスが正常に動作するかどうか、別のパソコンでも確認してみることをおすすめする。 あるお客様のノートパソコンではデバイスが動作しなかったのに、別のパソコンでは動作した、という事例があった。 そのパソコンの設定に何らかの問題があり、デバイスを正しく使えなくなっていたのである。

使っているUSBハブやUSBポートに問題はないか

USBハブを経由せず、USBポートに直接接続してみてほしい。 デバイスが十分な電力を得られていなかったり、正しく通信できていなかったりする可能性がある。 また、一部のUSB-シリアル変換器をUSB 3.0で使うと問題が生じることもある。 別のパソコンでテストしてみてほしい。USB 3.0のポートではうまく動かなかったデバイスが、USB 2.0のハブでは動作した、という事例もいくつかあった。

ロジックレベルを確認する

3.3Vのセンサーを5Vの基板に接続できるか

すべての基板が同じロジックレベルの電圧を使っているわけではない。 たとえば、RedBoard Programmed with ArduinoやArduino Uno R3は5Vロジックを使用する。 しかし、ESP8266、SAMD21、Arduino Due、Raspberry Piのような他の基板では、I/Oピンは5V耐性を持たない。 接続する開発ボードとデバイスの間で、ロジックレベルが一致しているか、あるいは耐性があるか、必ず確認しよう。

信号を降圧するだけでよい場合は、10kΩの抵抗3個で分圧回路を作るという方法もある。 双方向の信号をやり取りする場合は、ロジックレベルコンバータ(双方向ロジックレベルコンバータPCA9306レベルトランスレータTXB0104電圧レベルトランスレータその他)を使えば安全に通信できる。 ロジックレベルについてさらに詳しくは、ロジックレベルのチュートリアルも参照してほしい。

複数の基板を積み重ねる

開発ボードの上に、複数の基板(Arduinoシールド、Raspberry Pi HAT、Beaglebone Capeなど)を積み重ねていないか

複数の基板を積み重ねること自体は可能な場合もあるが、それぞれの基板がどのピンを使っているかによる。 基板の設計ファイルや回路図、基本的なサンプルコードを確認し、それぞれのシールドがどのピンを使っているか確認してみよう。 複数の基板を開発ボードに積み重ねる場合、コード内でピンを再配線したり、再定義したり、シリアルアドレス(I2C、SPIなど)を変更したりする必要が出てくることもある。 複数の基板を使う場合は、それぞれのサンプルコードを組み合わせて、プロジェクトの中で動作するようにする必要がある。

設置場所の干渉を確認する

特定の部屋や建物の中で部品が動作しない場合

空気中に何か魔法がかかっているのか、あるいは電子機器に幽霊でも取り憑いているのだろうか。もしかしたらそうかもしれない。あるいは、単純に別の場所でその基板を試してみるのもよい。 これは、建物の中でGPS受信機を使う場合によくあることである。 GPSのロック問題を避けるには、建物の外周に近い場所でGPS受信機を使う、屋外で使う、周囲の建物の影響を避けるために場所を変える、あるいは屋外まで延ばした外部アンテナを使うとよい。

建物の特定の場所で超音波センサーを使うと問題が生じたこともあった。 たとえば、HC-SR04超音波センサーは建物のある場所では問題なく動作していたが、空調(HVAC)が発する音響ノイズが、ちょうどこのセンサーに干渉するような周波数になっていることがわかった。 このノイズを避けるため、建物の別の場所でセンサーを使う必要があった。

磁力計を使っていて、異常な読み取り値が出ることはないだろうか。 これは、周囲の環境にあるハードアイアン(永久磁化)やソフトアイアン(誘導磁化)が原因かもしれない。 ハードアイアンとソフトアイアンについてさらに詳しくは、廃番になった9DOF Razorの古いチュートリアルも参考にしてほしい。

電源を確認する

電源は十分な容量を持っているか

自分のシステムが必要とする電力を供給できる電源を使っているか確認しよう。 たとえば、Arduinoで3個のWS2812Bアドレサブル LEDを点灯させるだけなら、5V/1Aの電源で十分だろう。 しかし、2本以上の5mアドレサブルLEDストリップを点灯させる場合は話が変わってくる。 このような大規模な設置には、長い配線に対応できる強力な電源が必要になり、おそらく5mのセグメントごとに電力を追加供給する必要も出てくるだろう。

電源が十分な電力を供給できない場合、マイクロコントローラやシングルボードコンピュータがブラウンアウト(電圧降下による誤動作)を起こすことがある。 別の例として、Raspberry Pi 3は、以前のモデルよりもわずかに多くの電流を消費する。 以前の世代のRaspberry Piでは5V/2Aの電源で動作していたが、Pi 3に十分な電力を供給するには5.1V/2.5Aの電源が必要である。

モーターが起動するたびにArduinoが動作を止めてしまうのはなぜか

電源を確認してみよう。モーターが電圧降下を引き起こし、マイクロコントローラがブラウンアウトを起こしている可能性がある。 たいてい、ブラウンアウトやマイクロコントローラのリセットを防ぐため、モーター用に外部電源を別途接続することが推奨される。 基準を取るため、GNDはシステムの残りの部分と必ず接続しておくこと。 モーターとマイクロコントローラの両方に十分な電力を供給できる、より強力な電源を使うという方法もある。

コンセントに接続した電源では動作するのに、9V電池では動作しないのはなぜか

電池の化学的な種類やメーカーによって、コンセントに接続した電源とは放電特性が異なることがある。 9V電池は、他の種類の電池と比べて内部抵抗が高い。 また、内部抵抗はメーカーによっても異なる。 そのため、大電流を必要とする用途には、9V電池は理想的な電源とは言えない。 プロジェクトの電源には、他の電池の種類を検討してみるとよいだろう。

電源の入れ直し

コンセントに接続して数か月間は問題なく動いていたプロジェクトが、今は期待どおりに動かなくなった場合

電源を切ってから入れ直す、電源の再投入(パワーサイクル)を試してみよう。 リセットボタンがあれば、それを押すだけで済むこともある。 電源をコンセントから抜き、電源のVinを切り離し、数秒待ってから、電源をVinに再接続し、電源を再びコンセントに挿す、という手順が必要になることもある。 マルチメーターでACアダプタをテストし、まだ電力を出力しているか確認するか、正常に動作することがわかっているランプをコンセントに挿してみるのもよい。

発熱

モータードライバが触れると熱くなっているのは普通のことか

モータードライバとモーターを使う場合、発熱は正常なことである。 ドライバICにどれだけ負荷をかけているか、どんな電源を使っているかによっては、モータードライバの性能をフルに発揮させるためにヒートシンクが必要になることもある。 このようなブレイクアウトボードは、たいてい多少の放熱を助けるように設計されている。 ヒートシンクを追加する以外にも、熱に対処する方法はいくつかある。

静電気放電(ESD)

デバイスに触れる前に、自分自身をグラウンドに接続したか

特定のデバイスは静電気に弱い。 人は動き回るうちに静電気を帯び、それが基板を通じて放電されることがある。 冬場、カーペットの上を歩いた後は特に注意が必要である。 金属製のキャビネットに触れて、自分自身をグラウンドに接続しておくようにしよう。 一部の基板は多少の軽い静電気には耐えられるが、ある程度を超えるとICが損傷することがある。

製品の限界

その部品を想定どおりの使い方で使っているか

製品が世に出ると、想定していなかった使われ方をすることがある。 たとえば、たいていLEDは光を発するものだと考えるだろう。しかし、マイクロコントローラとLEDを使って光を検知することも可能である。

とはいえ、すべての部品が想定していないことまでこなせるとは期待しないでほしい。 たとえば、XBee Series 1トランシーバーはデータをワイヤレスで送信できるが、WiFiドングルのように映像を安定してストリーミングできるとは期待しないでほしい。仕様(データレートなど)がまったく異なる。

無線

無線デバイスが無線ネットワークに接続できないのはなぜか

正しいWiFiネットワーク名とパスワードを使っているか確認してみよう。 認証情報を誤って入力している可能性もある。 WiFi対応デバイス(SparkFun ESP8266 Thing Development Boardなど)に付属のサンプルコードでは、ネットワーク名とパスワードを手動で入力する必要がある。

別のパソコンで確認するのと同じように、WiFi対応デバイスを別のWiFiネットワークでテストしてみるのもよいだろう。 学校のネットワークでWiFi対応デバイスを使う場合、問題が生じることがある。 学校のネットワーク設定によっては、デバイスの接続を許可してもらうために、そのネットワークを管理する情報システム部門に問い合わせる必要があるかもしれない。 無線ルーターが故障していたり、無線対応デバイスと互換性がなかったりする可能性もある。

金属製の筐体の中で無線デバイスが動作しないのはなぜか

無線デバイスを金属製の筐体(つまりファラデーケージ)の中に入れると、電磁場が実質的に制限され、遮断されてしまうことがある。 送受信する信号を伝送できなくなる。 トランシーバーを金属製の筐体の外まで延ばせるよう、外部アンテナを使ってみてほしい。

ソフトウェアの確認

世の中には数多くのプログラミング言語がある。このチュートリアルとトラブルシューティングの範囲では、Arduino IDE(統合開発環境)と、Arduinoの開発ボードにコードをアップロードする際によくある問題に焦点を当てる。 とはいえ、これらのコツの一部は、他の開発環境でのトラブルシューティングにも役立つかもしれない。

FTDIドライバ

FTDIドライバをインストールしたか

FTDIを使うArduinoにアップロードしたことがない場合や、FTDIをパソコンに接続したことがない場合は、最新のFTDIドライバをインストールしておく必要がある。 自分のOS向けのドライバのインストール方法については、以下のチュートリアルを参考にしてほしい。このチュートリアルはFTDIの手順をもとにしている。より詳しいガイドについては、FTDIのインストールガイドも参照してほしい。

デバイスドライバは、開発ボードに搭載されているUSB-シリアル変換チップによって異なる点に注意してほしい。 異なるチップを使っている場合は、それぞれに対応するドライバをインストールする必要がある。以下は、その他のドライバの例である。

さまざまなドライバについてさらに詳しくは、こちらのブログ記事も参照してほしい。

ドライバがインストールされているかどうかはどう確認すればよいか

デバイスを接続した状態で、Arduino IDEのメニューからTools > Serial Portを選択すると、いくつかのCOMポートが表示される。 デバイスを取り外してから、もう一度Tools > Serial Portを開くと、あるCOMポートが消えていることに気づくはずである。 この消去法によって、そのデバイスがどのCOMポートとして認識されているかを確認できる。 これは、デバイスマネージャーの*ポート(COMとLPT)*ツリーを確認したときにも同じように見える。

USB-シリアル変換器がシリアルデータを送信しているかどうかはどう確認すればよいか

FTDIや他のUSB-シリアル変換器が正しく動作しているか確認するには、シリアルのループバックテスト、あるいはエコーテストを行うとよい。 このテストを行うには、UARTのRxピンとTxピンの間をジャンパー線で接続する。

シリアルターミナル(Tera Termなど)を、9600ボー、8-none-1-noneの設定で開く。 シリアルターミナルに文字を入力すると、キーボードから送信した文字がそのまま画面にエコーバックされるはずである。 データが送信されているタイミングを示す、RxとTxのステータスLEDも点灯するはずである。

Arduino IDEのバージョン

Arduino IDEに何か問題があるのか

Arduino IDEはバージョンごとに改善と恩恵をもたらしてくれるが、予期しないバグや、コードのコンパイルのされ方に違いが生じることもある。 エラー出力に警告がある場合、たいていは無視してかまわない。 コンパイルに問題がある場合、パソコン上のArduino IDEをアンインストールしてから再インストールする必要が出てくることもある。特定のArduinoファイルを削除してみるという方法もある。

使用しているArduinoベースの開発ボードが特定のIDEバージョンを必要としない場合は、より古いバージョンのArduino IDE(v1.6.5など)にロールバックして試してみるとよい。 次のリリースが出るまでの間は、安定して動作するIDEにロールバックしてテストするのが解決策になることもある。

ボードの選択

正しいボード定義を選択したか

正しいボード定義を選択していないと、コードをアップロードできない。 正しいボードの選び方については、Arduinoに関連するドキュメントを確認してほしい。 Arduinoのボード定義の一覧は、Tools > Boardの選択メニューから確認できる。

ボードの選択メニューに自分のArduinoボードが表示されないのはなぜか

Arduino IDE v1.6以降では、ファイル構造の要件が変更されたことによる問題が生じることがある。 これによって、Arduinoボードがデフォルトの一覧に表示されないことがある。

最新のSparkFun Arduino互換ボードの更新情報は、SparkFun Arduinoボードアドオンの GitHubリポジトリで確認できる。 このリポジトリには、SparkFunのArduino互換開発ボードのサポート情報と、ボードアドオンのインストール方法が含まれている。

最新のボード定義をインストールしてもコードがコンパイルされない場合は、以前のバージョンのボードアドオンにロールバックしてみるとよい。 複数のバージョンがリリースされている場合、ボードマネージャーでそのボードをクリックすると、異なるバージョンを選べる小さなドロップダウンメニューが表示されるはずである。

COMポートの選択

正しいCOMポートを選択したか

Tools > Serial Portメニューで、正しいCOMポートを選択できているか確認する必要がある。 デバイスを接続した状態で、Arduino IDEのメニューからTools > Serial Portを選択すると、いくつかのCOMポートが表示される。 デバイスを取り外してから、もう一度Tools > Serial Portを開くと、あるCOMポートが消えていることに気づくはずである。 この消去法によって、そのデバイスがどのCOMポートとして認識されているかを確認できる。 これは、デバイスマネージャーの*ポート(COMとLPT)*ツリーを確認したときにも同じように見える。

インストール済みのArduinoライブラリ

サンプルコードがライブラリのインストールを必要としていないか

必要なライブラリをインストールしていないと、Arduinoはそのために定義されていない特定の関数を理解できない。 たいてい、サンプルコードのファイルの冒頭付近に、そのライブラリをインクルードしようとしている記述が見つかるはずである。 ライブラリを正しくインストールするには、次のチュートリアルを確認することをおすすめする。

必要なArduinoライブラリをインストールしたのに、まだコンパイルできないのはなぜか

Arduino IDEを再インストールしてみよう。 あるエンジニアは、あるライブラリで問題が発生した際に、Arduino IDEをアンインストールしてから再インストールすることで解決した例がある。 それでもだめなら、そのArduinoライブラリを再インストールしてみるとよい。 ダウンロードしたライブラリが破損していたり、誤ってインストールされてしまったりすることもあるため、その場合はライブラリを再インストールする必要がある。

ブートローダーの破損、文鎮化したArduino

ブートローダーが破損している場合、Arduinoを復旧するにはどうすればよいか

別のArduinoマイクロコントローラやAVRプログラマーがあれば、ブートローダーを再インストールできる。 以下のチュートリアルは、ATmega328PのArduino Uno向けに書かれている。 別のAVRマイクロコントローラやArduino互換ボードを使っている場合は、ブートローダーを書き込む際に異なるボード定義を選ぶ必要があるかもしれない。

ATmega32U4搭載のArduinoが、新しいコードをアップロードした後に動作しなくなった。何が起きたのか

たいていの場合、コードをアップロードする際に間違ったボード定義が選ばれていたか、COMポート通信を扱うレジスタに何らかの干渉が起きている。 ATmega32U4ベースのArduinoを復旧させる方法として、ダブルリセット法がある。 最後の手段として、AVRプログラマーが必要になることもある。 異なるブートローダーを持つATmega32U4を復旧させるための、より詳しいヒントへのリンクについては、こちらのコメントを確認してみてほしい。

意味的なエラーとデバッグ

コンパイルは通るのに、コードが正しく動作しないのはなぜか

かなり漠然とした質問に聞こえるかもしれないが、おそらく意味的なエラー(セマンティックエラー)が原因である。 コードはコンパイルでき、構文エラーもないが、意図したとおりに動作するようには書かれていない可能性がある。 ハードウェアの接続と基板に問題がないと仮定すると、次のような原因が考えられる。

  • ピンや変数が正しく初期化されていない。
  • 変数が正しく計算・保存されていない。
  • 間違った変数がシリアルモニタに出力されている。
  • 配列[]の範囲外の値を使っている。
  • ボーレートが一致していない。
  • delay()関数が、あるコード行の実行を十分な速さで妨げてしまっている。
  • コードの実行順序が正しくない。

考えられる原因は、プロジェクトの複雑さに応じてまだまだ挙げられる。 もっとも単純なデバッグ方法は、コードのある部分に到達したらLEDを点灯させる、というものである。 しかし、Arduinoのコードをトラブルシューティングするもっとも良い方法は、serial.print()関数を使って、一歩ずつ処理を追いながらデバッグすることである。 正しく使えば、この関数はより柔軟であり、あるコード行に到達したことを示すこともできる。

ボタンを押したときや、センサーがある値に達したときに、「この関数に入った」とシリアルモニタに出力したいこともあるだろう。 serial.print()関数は、センサーの出力範囲がどうなるかを把握するために、変数の値を確認するのにも使える。 計算結果を検証するのにも使える。 他の開発環境では、serial.print()を使わなくても、コードを一歩ずつ実行してシミュレートできるものもある。

SparkFunトラブルシューティングチェックリスト

経験の程度にかかわらず、チェックリストを用意しておけば、失敗の頻度を減らし、問題をより速く解決できることがある。 プロジェクトのトラブルシューティングを行う際に、自分自身に問いかけるべき質問の一覧を示す。

ハードウェアの確認

接続を確認する

  • ☐ ピン間に導通はあるか、接続はしっかりしているか
  • ☐ 短絡していないか
  • ☐ 配線やケーブルが不良ではないか
  • ☐ そのUSBケーブルはどこで手に入れたものか
  • ☐ 部品を正しい極性で接続しているか
  • ☐ 基本的な接続方法どおりに接続したか
  • ☐ はんだ付けの接合部は理想的で、十分な接続ができているか
  • ☐ 本来はんだブリッジがあるべきでない場所に、ピンをつなぐはんだブリッジができていないか
  • ☐ 基板に水溶性フラックスの残留物が残っていないか

配線の長さ

  • ☐ 必要以上に長い配線を使っていないか
  • ☐ 別のパソコンで試してみたか
  • ☐ 使っているUSBハブやUSBポートに問題はないか

ロジックレベルを確認する

  • ☐ 3.3Vのセンサーを5Vの基板に接続できるか

複数の基板を積み重ねる

  • ☐ 開発ボードの上に、複数の基板(Arduinoシールド、Raspberry Pi HAT、Beaglebone Capeなど)を積み重ねていないか

設置場所の干渉を確認する

  • ☐ 特定の部屋や建物の中でその部品が動作しないことはないか

電源

  • ☐ 電源は十分な容量を持っているか
  • ☐ モーターが起動するたびにArduinoが動作を止めてしまうことはないか
  • ☐ コンセントに接続した電源では動作するのに、9V電池では動作しないことはないか

電源の入れ直し

  • ☐ コンセントに接続して数か月間は問題なく動いていたプロジェクトが、今は期待どおりに動かなくなっていないか

発熱

  • ☐ モータードライバが触れると熱くなっているのは普通のことか

静電気放電(ESD)

  • ☐ デバイスに触れる前に、自分自身をグラウンドに接続したか

製品の限界

  • ☐ その部品を想定どおりの使い方で使っているか

無線

  • ☐ 無線デバイスが無線ネットワークに接続できないことはないか
  • ☐ 無線デバイスが金属製の筐体の中で動作しないことはないか

ソフトウェアの確認

FTDIドライバ

  • ☐ FTDIドライバをインストールしたか
  • ☐ FTDIドライバがインストールされているかどうかをどう確認できるか
  • ☐ FTDIがシリアルデータを送信しているかどうかをどう確認できるか

Arduino IDEのバージョン

  • ☐ Arduino IDEに何か問題があるのか

ボードの選択

  • ☐ 正しいボード定義を選択したか

COMポートの選択

  • ☐ 正しいCOMポートを選択したか

インストール済みのArduinoライブラリ

  • ☐ サンプルコードがライブラリのインストールを必要としていないか
  • ☐ 必要なArduinoライブラリをインストールしたのに、まだコンパイルできないのはなぜか

ブートローダーの破損、文鎮化したArduino

  • ☐ ブートローダーが破損している場合、Arduinoをどう復旧すればよいか
  • ☐ ATmega32U4搭載のArduinoが、新しいコードをアップロードした後に動作しなくなった。ATmega32U4ベースのマイクロコントローラに何が起きたのか

確認、テスト、再確認

もしかすると、どこかの手順を急いでしまったのかもしれない。トラブルシューティングのチェックリストを見直してみよう。 あるいは、前提そのものが間違っていた可能性もある。自分の前提を確認してみよう。 めったにないことではあるが、基板そのものに何らかの不良(墓石現象を起こしたSMD部品、はんだ不足、不良なPCBなど)がある可能性もある。

回路の電源をいったん切り、時間を置いてから戻ってくることも、別の視点から問題に取り組む助けになる。

助けが必要な場合

トラブルシューティングのチェックリストやテスト、再確認を一通り試しても、まだ問題が解決しない場合。 SparkFunフォーラムが、もっとも良い問い合わせ先だと考えている。コミュニティと最大限の情報やドキュメントを共有できるからである。 SparkFunフォーラムに投稿する際は、できる限り多くの情報を準備しておいてほしい。次のような情報を集め、フォーラムを閲覧することで、問題を解決できたお客様もいる。

  • SparkFunの部品番号(SKU):これは、請求書の商品一覧や製品ページで確認できる。

  • はんだ付けの接合部やセットアップの、高品質で鮮明な画像:はんだ付けの接合部やセットアップの、高品質で鮮明な画像がいくつかあると役に立つ。ピントが合っていて、十分な明るさがあることを確認しよう。投稿する前に、回路の様子がきちんと見えるか写真を確認しておくこと。

    以下は、何が起きているのか見づらい、セットアップの不鮮明な画像の例である。とはいえ、そのチョコバーはおいしそうに見える。

    以下の画像は、トラブルシューティングの助けになる、はんだ付けの接合部を鮮明に写したものである。

    以下の画像は、セットアップとピンの接続を鮮明に写したものである。配線は途中で切れているが、接続をたどれるはずである。とはいえ、同じ色の配線が複数ある場合、トラブルシューティングの妨げになることもある。

  • セットアップについての情報:電源の電圧・電流設定、基板に電源が入っていたかどうか、基板への改造、システムに接続されている追加の部品、使用環境などが含まれる。


これらの情報を準備できたら、フォーラムに投稿してみよう。

SparkFun Forums

まとめ

SparkFunの以下の資料もぜひ確認してみてほしい。

トラブルシューティングについてさらに詳しく知りたい場合は、次の関連ブログ記事も参考にしてほしい(いずれも英語)。

タグ: 概念、電気工学、スキル


出典:SparkFun Troubleshooting Tips(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

AST-CAN485の使い方

AST-CAN485は、Arduino Pro Miniと同じ小型フォームファクタに収まる小型Arduinoである。 通常のArduinoの機能に加えて、オンボードのCANポートとRS485ポートを備えており、産業用機器の多くに手早く接続できる。 CAN485は、メイカーの世界と産業機器の世界の橋渡しをするボードである。

CAN485はArduinoプラットフォームをベースにしている。 Arduino Pro Miniとピン互換であり、プロジェクトに組み込みやすい小型フォームファクタを持つ。 Arduino IDE、Arduinoのコアライブラリに対応しており、ボードマネージャーからインストールできる。 CANポートとRS485ポートに対応するライブラリも提供されている。 オンボードのCANトランシーバーとRS485トランシーバーにより、追加の電子部品なしでCANネットワークやRS485ネットワークにそのまま接続できる。 CANとRS485は、自動化、産業システム、ビル管理、自動車システム、OBD-IIなど、多くの通信プロトコルの基盤になっている。

参考になるチュートリアル

以下の概念に馴染みがない場合は、先に次のチュートリアルを読んでおくとよい。

ハードウェア概要

CAN485はPro Miniと同じ約34.65mm × 19.20mmという小さなフォームファクタを採用しており、スペースが限られた用途にも組み込みやすい。 ピン配置もArduino Pro Miniと同じであるため、既存のPro Mini用シールドやアプリケーションとピン互換である。 四辺目のRESETボタン下にあるもう一列のピンには、CANポートとRS485ポートが割り当てられている。

AST-CAN485の寸法

Arduino Pro Miniの寸法

ピン配置

ピン割り当てはArduino Pro Miniとおおむね似ているが、機能にはいくつか違いがある。 Pro Mini用に設計されたシールドをCAN485で使う場合は注意が必要である。 各ピンの詳しい機能はグラフィカルデータシートを参照してほしい。

画像が見づらい場合は、クリックすると拡大表示できる。

CAN485はAtmelのAT90CAN128プロセッサをベースにしている。 このプロセッサは16MHzで動作し、128KBのフラッシュメモリと4KBのSRAMを持ち、ハードウェアのCANコントローラーを内蔵する。 CAN485は、I2C、SPI、UART、8本のアナログ入力、割り込み対応の6本のピンなど、よく使われる通信ポートとピン機能を引き出している。

詳しくはAT90CAN128のデータシートAST-CAN485の回路図を参照してほしい。

上級者向けの注意: CAN485のAT90CAN128にはArduinoのブートローダーが書き込まれている。 AVRプログラマとAtmel Studioを使ってチップに直接書き込みたい場合、ICSPピンは想定とは異なる位置にある。 D12(MISO)やD11(MOSI)といった通常のSPIピンではなく、実際にはFTDIヘッダーのピンD1(TX0)とD0(RXI)がこれにあたる。

ターゲットの外部電源CAN485AVRプログラマ
FTDIヘッダーのD1(TX0)MISO
D13(SCK)SCK
RSTRST
5V5V5V
FTDIヘッダーのD0(RXI)MOSI
GNDGNDGND

詳しくは、AT90CAN128データシートの349ページ、**25.7節「SPI Serial Programming」**を参照してほしい。

電源

CAN485にはいくつかの給電方法がある。

CAN485にはオンボードのレギュレータがあり、RAWピンに未調整の電圧を供給できる。 入力電圧の許容範囲は7〜16Vだが、推奨は7〜12Vである。

注意: CANポートと5本を超えるデジタル出力を同時に使う場合、入力電圧は12V未満に保つ必要がある。

調整済みの5V電源をVccに直接供給することもできる。 供給電圧は4.5V〜5.5Vの範囲でなければならない。 FTDIブレイクアウトからFTDIヘッダー経由で給電することも可能である。

警告: 誤った電源を接続すると、CAN485や接続している他の機器を破損する恐れがある。

ボードに電源が入ると、PWR LEDが点灯する。

FTDIプログラミングヘッダー

Pro Miniと同様に、CAN485にもオンボードのUSB接続はない。 ボードへの書き込みやPCとの接続には、外付けのFTDIブレイクアウトボードが必要である。

接続には5V仕様のFTDI、ヘッダーピン、mini-B USBケーブルが必要になる。

はんだ付けに不慣れな場合は、はんだ付けの基本(スルーホール編)のチュートリアルを確認してほしい。 はんだごて、はんだ、一般的なはんだ付け用アクセサリーも用意しておくとよい。

標準的なプロトタイピング用の構成としては、ブレッドボードに挿しやすいようピンを下向きに、FTDIを外側に向け、通信用ピンをジャンパーケーブルでアクセスしやすいよう上向きにする配置がよく使われる。

CANポート

CANコントローラーはハードウェアアクセラレーションに対応しており、プロセッサへの負荷を最小限に抑えながら高速なCAN通信を行える。 オンボードのCANトランシーバーにより、追加の電子部品なしでCAN485を直接CANネットワークに接続できる。

AST-CAN485の表側:CANポート

AST-CAN485の表側:CAN用ICとポート

CANネットワークへの接続

次の画像は、CAN485とCANネットワークの典型的な接続を示している。 このネットワークは2本の信号線(CANHとCANL)で構成されており、複数のデバイスをこれらの線に並列接続できる。 バスの両端は、終端抵抗(一般に100Ω〜120Ω)で終端しなければならない。

詳しくは、後述のCAN入門の節を参照してほしい。

RS485ポート

CANポートと同様に、CAN485にはオンボードのRS485トランシーバーが搭載されており、あらゆるRS485ネットワークに簡単に接続できる。 RS485ポートはUART1を専有するが、シリアルポートとして使いたい場合に備えてピン22と23にも引き出されている。

AST-CAN485の表側:RS485ポート

AST-CAN485の裏側:RS485用ICとポート

RS485ネットワークへの接続

次の画像は、CAN485とRS485ネットワークの典型的な接続を示している。 このネットワークは2本の信号線(AとB)で構成されており、デバイスはこれらの線に並列接続される。 バスの両端は、終端抵抗(一般に100Ω〜120Ω)で終端しなければならない。

詳しくは、後述のRS485入門の節を参照してほしい。

JTAG

JTAGによるプログラミング・デバッグ用インターフェースはピン18〜21に引き出されている。 これにより、Atmel Studioを使ったより高度なデバッグが可能になる。

重要な点として、これらのピンを通常の入出力として使うには、JTAGインターフェースを必ず無効化しなければならない。 これはsetup()関数に少しコードを追加するだけで行える。

対応するサンプルコードはASTのGitHubリポジトリ(JTAG_Software_Disable.ino)で公開されている。

AltSoftSerialを使ったソフトウェアシリアル

残念ながら、AT90CAN128チップのピンはピン変化割り込みに対応していない。 そのため、ArduinoのSoftwareSerialライブラリは利用できない。 代わりにAltSoftSerialライブラリを使うことができる。

AltSoftSerialライブラリにはいくつか制約がある。 マイクロプロセッサのタイマーリソースを一つ使用するため、利用できるAltSoftSerialポートは1つだけであり、ピン5と9に固定されている。 ASTは標準のAltSoftSerialライブラリをCAN485向けに改変しており、AST GitHubで公開している。

ハードウェアの接続

CAN485にはヘッダーがはんだ付けされた状態では出荷されない。 プロジェクトに合わせてヘッダーやワイヤーをボードにはんだ付けするのはユーザーの役目である。 選択肢としては、スタッカブルヘッダー、ベントヘッダー、ピンパッドへのワイヤーの直付けなどがある。

ソフトウェアのインストール

注意: Arduino IDEが1.6.3より古いバージョンの場合はアップグレードが必要である。 この説明はデスクトップ版Arduino IDEの最新版を使っている前提で進める。 Arduinoを初めて使う場合は、Arduino IDEのインストールのチュートリアルを先に確認してほしい。

次のステップは、CAN485ボードをArduino IDEにインストールすることである。 インストール方法は2通りある。 一つはArduinoのボードマネージャーを使う方法で、こちらが推奨の方法である。 もう一つは、GitHubリポジトリからファイルを手動でコピーする方法である。

ボードマネージャーを使ったボードのインストール

Arduino IDEのボードマネージャーを使う方法が推奨されている。

Arduino IDEで環境設定ウィンドウ(ファイル > 環境設定)を開く。 次のURLをコピーし、ボードマネージャーのURLリストに追加する。

https://raw.githubusercontent.com/Atlantis-Specialist-Technologies/Arduino-Boards-Packages/master/package_ast_boards_index.json

ボードマネージャー(ツール > ボード > ボードマネージャー…)を開く。

AST AVR Boardsまでスクロールし、インストールボタンをクリックする。

これで、AST AVR Boardsがボードメニューから選択できるようになる。 開発ボードに書き込む際はCan485を選択する。

ボードの手動インストール

AST AVR Boardアドオンを手動でインストールする手順は次のとおりである。

  • GitHubからCAN485リポジトリをダウンロードする。
  • フォルダを解凍する。
  • astフォルダを…\MyDocuments\Arduino\hardwareにコピーする。
  • ディレクトリ構造は…\MyDocuments\Arduino\hardware\astとなる。

ライブラリの手動インストール

Arduinoライブラリを一度もインストールしたことがない場合は、先にライブラリのインストールガイドを確認してほしい。

CANライブラリを手動でインストールする手順は次のとおりである。

  • GitHubからAST_CAN_Arduino_Libraryリポジトリをダウンロードする。
  • AST_CAN_Arduino_Library-master.zipフォルダを解凍する。
  • ...\AST_CAN_Arduino_Library-masterフォルダを開く。
  • AST_CAN_Arduino_Library-masterフォルダをArduinoのlibrariesフォルダ(...\MyDocuments\Arduino\libraries)に移動する(librariesフォルダが存在しない場合は作成する)。
  • 最終的なディレクトリ構造は...\MyDocuments\Arduino\libraries\AST_CAN_Arduino_Library-masterとなる。

RS485ライブラリを手動でインストールする手順は次のとおりである。

  • GitHubからAST_RS485_Arduino_Libraryリポジトリをダウンロードする。
  • AST_RS485_Arduino_Library-master.zipフォルダを解凍する。
  • ...\AST_RS485_Arduino_Library-masterフォルダを開く。
  • AST_RS485_Arduino_LibraryフォルダをArduinoのlibrariesフォルダ(...\MyDocuments\Arduino\libraries)に移動する(librariesフォルダが存在しない場合は作成する)。
  • 最終的なディレクトリ構造は...\MyDocuments\Arduino\libraries\AST_RS485_Arduino_Library-masterとなる。

AST AltSoftSerialライブラリを手動でインストールする手順は次のとおりである。

  • GitHubからAltSoftSerialリポジトリをダウンロードする。
  • AltSoftSerial-master.zipフォルダを解凍する。
  • ...\AltSoftSerial-masterフォルダを開く。
  • Arduinoのlibrariesフォルダ(...\MyDocuments\Arduino\libraries)に解凍する(librariesフォルダが存在しない場合は作成する)。
  • 最終的なディレクトリ構造は...\MyDocuments\Arduino\libraries\AltSoftSerial-masterとなる。

トラブルシューティング: ライブラリをArduinoのDocumentsフォルダに手動でインストールする場合、ライブラリがサブフォルダの中に入れ子になっていないか確認してほしい。 入れ子になっているとArduino IDEがライブラリを認識できず、コンパイルエラーの原因になる。 たとえばCANライブラリを手動インストールした際、...\Documents\Arduino\libraries\AST_CAN_Arduino_Library-master\AST_CAN_Arduino_Library-masterのようにsrcフォルダが二段目のAST_CAN_Arduino_Library-masterの中に入っていると、Arduino IDEはソースファイルを認識できない。 対処法は、サブフォルダの中身をすべて一段上のディレクトリに移動し、Arduino IDEを再起動することである。

トラブルシューティング: AST独自の「AltSoftSerial」ライブラリと、Paul Stoffregen氏の「AltSoftSerial」ライブラリの両方がインストールされていると、ライブラリが競合することがある。 Arduino IDEはどちらを使うべきか判断できず、最初に見つけたAltSoftSerialライブラリを使ってしまう。 発生しうるコンパイルエラーの例は次のとおりである。

Multiple libraries were found for "AltSoftSerial.h"
   Used: ...\Documents\Arduino\libraries\AltSoftSerial
   Not used: ...\Documents\Arduino\libraries\AST_AltSoftSerial_Arduino_Library
exit status 1
Error compiling for board Can485.

簡単な対処法は、Paul Stoffregen氏の「AltSoftSerial」をArduinoのlibrariesフォルダから一時的に取り除き、AST-CAN485向けのコードをコンパイルする際はASTの「AltSoftSerial」だけを使うようにすることである。 こうすれば、同名の複数ライブラリによる競合を避けられる。

コードの書き込み

図のとおりにFTDIプログラミングケーブルをFTDIヘッダーに接続する。

Arduino IDEを開き、ツールメニューでCAN485ボードを選択する。 正しいCOMポートが選択されていることを確認する。 Blinkのサンプル(File > Examples > 01.Basics > Blink)を書き込む。 ピン13に接続された内蔵LEDが点滅すれば成功である。

CAN入門

注意: この節では、CANバスの重要な特徴の一部を簡単に紹介する。 より詳しい情報は、後述のまとめ・参考資料を参照してほしい。

CAN(Controller Area Network)バスは、自動車業界を起源とする通信規格である。 堅牢性とノイズ耐性を高めるいくつかの機能を備えている。 複数のノードに対応できるメッセージベースのプロトコルである。 40m未満の距離であれば最大1Mbpsの速度に対応し、より長い距離でも低速であれば通信できる(125Kbpsで500m)。 CANバスにはアービトレーション(調停)という仕組みもあり、メッセージの優先順位付けとパケット衝突の解決を自動的に行う。

CANは産業用途のフィールドバスとして使われており、その上に多くの上位レイヤープロトコルが構築される下位レイヤーを構成する。 CANopenとDeviceNetは、CANバスをベースにした代表的な上位レイヤープロトコルで、産業オートメーションで使われている。 CANバスは、米国とEUの現行車両で義務付けられているOBD-II車両診断規格にも使われている。

信号の説明

CANバスは2本の信号線(CAN HとCAN L)で構成され、両端は終端抵抗(一般に100Ω〜120Ω)で終端する。 高速通信の場合は120Ωの終端抵抗が推奨される。 これらの線は通常、ツイストペアとして束ねられる。

バスにはリセッシブ状態(論理1)とドミナント状態(論理0)がある。 バスをドミナント状態にするには、いずれかのノードが能動的に駆動する必要がある。 どのノードもドミナント状態に駆動していなければ、バスはリセッシブ状態に戻る。 このドミナントとリセッシブの性質により、二つのノードが同時に送信した場合、ドミナントなビットが優先される。 アービトレーションの仕組みは、この性質を利用してパケットの衝突を解決する。

ラインの状態とマイクロプロセッサが扱う論理状態を変換するには、CANトランシーバーが必要になる。

画像が見づらい場合は、クリックすると拡大表示できる。

ネットワーク構造

複数のノードを並列に接続できる。 両端のラインは終端抵抗(一般に100Ω〜120Ω)で終端しなければならない。 高速CANバスの場合、下図のネットワークでは両端に120Ωの終端抵抗を入れている。

パケット構造

CANのメッセージは、メッセージID、データ長フィールド、データフレーム、CRC、その他の制御ビットからなる標準フォーマットを持つ。 メッセージベースのプロトコルであるため、ノードのアドレスは存在せず、代わりにメッセージIDが使われる。 データはデバイスではなくIDに紐づけられ、一つのノードが複数のメッセージIDを使って送信することもできる。 この性質は非常に便利である。 たとえば一つのノードが、モーターの速度、位置、加速度をそれぞれ異なるメッセージIDで報告すれば、受信側のノードはパラメータを簡単に識別できる。

メッセージIDは一意でなければならない。 二つのノードが同じIDのメッセージを同時に送信しようとするとエラーが発生する。 メッセージIDは、二つのノードが同時に送信しようとした際にどちらのメッセージを優先するかを決めるアービトレーションの過程でも使われる。

CANパケットには標準フォーマットが二つある。 基本フォーマット(CAN2.0A)と拡張フォーマット(CAN2.0B)である。 拡張フォーマットは29ビットのIDを持ち、基本フォーマットは11ビットのIDを持つ。 拡張フォーマットは後方互換性があり、同じCANネットワーク上で両方のフォーマットを使うことができる。

画像が見づらい場合は、クリックすると拡大表示できる。

アービトレーション

二つのノードが同時に送信しようとすると、アービトレーションの過程でどちらを優先するかが決まる。 送信中、各ノードはバスの状態も同時に読み取っている。 あるノードが、自分が送ったリセッシブなビットを別のノードによってドミナントに駆動されたことを検出すると、そのノードは送信を停止する。 この仕組みにより、IDの値が小さいメッセージほど優先される。 アービトレーションに敗れたノードは、現在の送信が完了した時点で再送を試みる。 この動作により、優先順位付けと衝突解決が自動的に行われる。

画像が見づらい場合は、クリックすると拡大表示できる。

例:シンプルなCANネットワーク

この例では、2ノードからなるシンプルなCANバスネットワークを構築する。 一方のノードがメッセージを送信し、もう一方がそれを受信してシリアルポート経由でPCに転送する。

必要な部品

この例に必要な部品は次のとおりである。 手元にあるものによっては、すべてが必要とは限らない。 カートに入れてガイドを読み進め、必要に応じて調整してほしい。

  • CAN485 × 2
  • 120Ω抵抗 × 2 ※
  • FTDI
  • USBケーブル
  • ブレッドボード、ジャンパーワイヤーなど

※120Ω抵抗が手元にない場合は、100Ωの抵抗1本と10Ωの抵抗2本を直列にすることで120Ωを作ることができる。

ハードウェアの接続

図のとおりにネットワークを構築する。

コードの書き込み

CAN485ボードとCANライブラリがインストールされていることを確認する。 サンプルコードはCANライブラリと一緒にインストールされ、Arduino IDEのExamplesメニューから利用できる。

送信側のノードに送信用のサンプルコードを書き込む。 続いて、受信側のノードに受信用のサンプルコードを書き込む。

動作の確認

送信ノードは500msごとにメッセージを送信する。 受信ノードはそれを受信し、シリアルポート経由でPCに転送する。 PC側では、Arduinoシリアルモニタ(または好みのシリアルターミナル)でシリアルポートを開き、**1000000(1MBaud)**を選択する。

例:マルチノードCANネットワーク

この例では、より大規模なCANネットワークを構築する。 複数のノードがメッセージを送信し、一つのノードがそれらをシリアルポート経由でPCに中継する。

必要な部品

この例に必要な部品は次のとおりである。 手元にあるものによっては、すべてが必要とは限らない。 カートに入れてガイドを読み進め、必要に応じて調整してほしい。

  • CAN485 × 3以上
  • 120Ω抵抗 × 2 ※
  • FTDI
  • USBケーブル
  • ブレッドボード、ジャンパーワイヤーなど
  • 外部電源 × 1 ※※
  • DCバレルジャックアダプタ(メス)× 1 ※※

※120Ω抵抗が手元にない場合は、100Ωの抵抗1本と10Ωの抵抗2本を直列にすることで120Ωを作ることができる。

※※FTDI変換器からの給電に頼るより、外部電源を使うことが望ましい。

ハードウェアの接続

図のとおりにネットワークを構築する。

コードの書き込み

CAN485ボードとCANライブラリがインストールされていることを確認する。 サンプルコードはCANライブラリと一緒にインストールされ、Arduino IDEのExamplesメニューから利用できる。

送信側の各ノードに送信用のサンプルコードを書き込む。 その際、各ノードのメッセージID(MESSAGE_ID)をそれぞれ一意な値に変更しておく。

続いて、受信側のノードに受信用のサンプルコードを書き込む。

動作の確認

送信ノードはそれぞれ500msごとにメッセージを送信する。 受信ノードはそれを受信し、シリアルポート経由でPCに転送する。 PC側では、Arduinoシリアルモニタ(または好みのシリアルターミナル)でシリアルポートを開き、**1000000(1MBaud)**を選択する。

RS485入門

RS485は、シリアル通信システムで広く使われている規格である。 RS485が規定するのは電気的なインターフェースのみであり、規格そのものが特定の通信プロトコルを定めているわけではない。 その代わりに、多くの異なるプロトコルの物理層として使われる。 たとえば、シリアルポートをRS485の物理層の上で動かすことができる。

RS485はツイストペア上で差動信号を使うため、ノイズに強い。 複数ノードにも対応しており、接続できるノード数は通常、使用するプロトコルによって決まる。 最大1200mの距離、最大10Mbpsの通信速度に対応できるが、距離と速度にはトレードオフがある。 たとえば、50mのケーブルであれば2Mbpsで通信できる。

RS485はよく使われる物理層の一つであり、産業システム、コンピューティング、自動車、ビル管理などの用途で使われている。 ModbusとProfibusは、RS485を利用する代表的な産業用プロトコルである。

信号の説明

インターフェースは、信号AとBの2本の線で構成される。 バスがアイドル状態のとき、両方の線はフロート状態になる。 動作中は、一つのノードがコントローラーとしてバスを制御し、2本の線を適切な電圧に駆動する。 他のノードはペリフェラルとして動作し、送信されるデータを受信する。 2本の線は互いに逆極性に駆動される。Aがプラスであれば、Bはマイナスになる。 この信号を反転させることで、論理レベルの0と1を表現できる。

画像が見づらい場合は、クリックすると拡大表示できる。

ネットワーク構造

複数のノードを並列に接続できる。 両端のラインは終端抵抗(一般に100Ω〜120Ω)で終端しなければならない。

例:シンプルなRS485ネットワーク

この例では、2ノードからなるシンプルなRS485バスネットワークを構築する。 一方のノードが500msごとにメッセージを送信し、もう一方がそれを受信してシリアルポート経由でPCに転送する。

必要な部品

この例に必要な部品は次のとおりである。 手元にあるものによっては、すべてが必要とは限らない。 カートに入れてガイドを読み進め、必要に応じて調整してほしい。

  • CAN485 × 2
  • FTDI
  • USBケーブル
  • 120Ω抵抗 × 2 ※
  • ブレッドボード、ジャンパーワイヤーなど

※120Ω抵抗が手元にない場合は、100Ωの抵抗1本と10Ωの抵抗2本を直列にすることで120Ωを作ることができる。

ハードウェアの接続

図のとおりにネットワークを構築する。

コードの書き込み

CAN485ボードとRS485ライブラリがインストールされていることを確認する。 サンプルコードはRS485ライブラリと一緒にインストールされ、Arduino IDEのExamplesメニューから利用できる。

受信側のノードに受信用のサンプルコードを書き込む。 続いて、送信側のノードに送信用のサンプルコードを書き込む。

動作の確認

送信ノードは500msごとにメッセージを送信する。 受信ノードはそれを受信し、シリアルポート経由でPCに転送する。 PC側では、Arduinoシリアルモニタ(または好みのシリアルターミナル)で115200baudでシリアルポートを開く。

拡張用ボード

CAN485を使って24Vの入出力を制御したい場合は、有線接続用のI/Oシールド(24V)を確認してほしい。 このシールドは、AST-CAN485開発ボードを24Vの入出力に接続できるようにするArduinoシールドで、産業システムへの応用範囲を広げる。

RS485やCANのデバイスを遠隔から制御したい場合は、WiFiシールドを確認してほしい。

まとめ・参考資料

AST-CAN485開発ボードを無事に動かせたら、次は自分のプロジェクトに組み込む番である。

より詳しい情報は、以下の資料を参照してほしい。

次のプロジェクトのヒントとして、関連するチュートリアルも参照してほしい。

タグ: 概念、通信、Arduino、Hookup


出典:AST-CAN485 Hookup Guide(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Raspberry PiのGPIO

Raspberry Piは、そのサイズからは想像できないほど強力なコンピュータである。 HDMIディスプレイを駆動し、マウス、キーボード、カメラの入力を処理し、インターネットに接続し、フル機能のLinuxディストリビューションを実行できる。 しかし、Raspberry Piは単なる小型コンピュータではなく、ハードウェアのプロトタイピングツールでもある。 Raspberry Piには双方向の入出力ピンが備わっており、LEDを駆動したり、モーターを回したり、ボタンの押下を読み取ったりできる。

このチュートリアルはもともとRaspberry Pi Model B向けに書かれたものだが、標準的な2×20ピンのヘッダーを持つあらゆるRaspberry Piモデルに当てはまる。

Raspberry PiのI/Oラインを駆動するには、多少のプログラミングが必要になる。 どの言語を使うかは自由である。 Raspberry PiのGPIOサンプル集を見れば、対応するプログラミング言語の選択肢が数十種類あることがわかる。 その中から、入出力を駆動するのに手軽で確実なツールを二つに絞り込んだ。 Pythonと、WiringPiライブラリを使ったCである。

Raspberry PiでLEDを駆動したりボタンの押下を読み取ったりしたことがなければ、このチュートリアルがよい入り口になるはずである。 読みやすいインタプリタ型のスクリプト言語Pythonが好みでも、根っからのCプログラマでも、それぞれのニーズに合ったプログラミングの選択肢が見つかるはずである。

このチュートリアルで扱う内容

このチュートリアルでは、Raspberry PiのGPIOピンを読み書きする二つのアプローチ、PythonCを紹介する。 扱う内容の概要は次のとおりである。

  • GPIOピン配置:PiのGPIOヘッダーの概要
  • Python APIとサンプル
    • RPi.GPIO API:GPIOを駆動するために使うPython関数の概要
    • RPi.GPIOのサンプル:入力と出力の両方の機能を示すPythonスクリプトの例
  • C(WiringPi)のAPIとサンプル
    • WiringPiのセットアップとテスト:WiringPiのインストール方法と、コマンドラインでの動作確認
    • WiringPi API:WiringPiライブラリが提供する基本的な関数の概要
    • WiringPiのサンプル:WiringPiの入出力機能を示すシンプルなサンプルプログラム
  • IDEの利用:Raspberry Pi向けプログラミングで使いやすいIDE、Geanyのダウンロードとインストール方法

それぞれのプログラミング言語には、それぞれの長所と短所がある。 Pythonは(特にプログラミング初心者にとって)扱いやすく、コンパイルも不要である。 Cはより高速で、慣れ親しんだ従来の書き方を好むユーザーにとっては扱いやすいこともある。

必要な部品

Raspberry PiのSDカードにはRaspbianがインストールされている必要がある。 Raspbianのインストール方法については、別のチュートリアルを参照してほしい。

Raspberry Piには、必要なマウス、キーボード、ディスプレイが接続されている前提で進める。

WiringPiをダウンロードするために、Raspberry Piにはインターネット接続が必要である。 イーサネットでもWiFiでも構わない。

Pi Wedgeは必須ではないが、あるとかなり作業が楽になる。 ブレイクアウト基板を使わない場合は、代わりにオス-メスのジャンパー線でPiとブレッドボードをつなぐこともできる。

もちろん、お好みのボタンやLEDに置き換えても構わない。

GPIOピン配置

Raspberry Piは、ボード上の標準的なオスヘッダーを通じてGPIOを提供する。 このヘッダーは、年々26ピンから40ピンへと拡張されてきたが、もとのピン配置は維持されている。

初期モデルと後期モデルのPiコンピュータのヘッダー構成

ArduinoユーザーとしてRaspberry Piに来た場合、ピンを単一の一意な番号で参照することに慣れているだろう。 Piのハードウェアをプログラミングする際もほぼ同様で、各ピンにはそれぞれの番号が振られている。それも一つだけではない。

Piのピン番号を参照する際に出会う番号体系には、少なくとも二つある。 Broadcomチップ固有のピン番号と、P1の物理ピン番号である。 基本的にはどちらの番号体系を使ってもよいが、多くのプログラムでは、プログラムの冒頭でどちらの体系を使うかを宣言する必要がある。

P1ヘッダーの全26ピンについて、特殊機能の有無と両方の番号を示した表は次のとおりである。

Element14のピン説明に注釈を加えたもの

Wedgeのシルク印刷Python(BCM)WiringPi GPIO名称P1ピン番号名称WiringPi GPIOPython(BCM)Wedgeのシルク印刷
3.3V電源125V電源
SDA8GPIO02(SDA1、I2C)345V電源
SCL9GPIO03(SCL1、I2C)56GND
G447GPIO04(GPIO_GCLK)78GPIO14(TXD0)15TXO
GND910GPIO15(RXD0)16RXI
G17170GPIO17(GPIO_GEN0)1112GPIO18(GPIO_GEN1)118G18
G27272GPIO27(GPIO_GEN2)1314GND
G22223GPIO22(GPIO_GEN3)1516GPIO23(GPIO_GEN4)423G23
3.3V電源1718GPIO24(GPIO_GEN5)524G24
MOSI12GPIO10(SPI_MOSI)1920GND
MISO13GPIO09(SPI_MISO)2122GPIO25(GPIO_GEN6)625G25
CLK14GPIO11(SPI_CLK)2324GPIO08(SPI_CE0_N)10CD0
GND2526GPIO07(SPI_CE1_N)11CE1
IDSD30ID_SD(I2C IDのEEPROM)2728ID_SC(I2C IDのEEPROM)31IDSC
G05521GPIO052930GND
G6622GPIO063132GPIO122612G12
G131323GPIO133334GND
G191924GPIO193536GPIO162716G16
G262625GPIO263738GPIO202820G20
GND3940GPIO212921G21

この表には、Piのピンヘッダー番号、Element14での名称、WiringPiの番号、Pythonの番号、Wedge上のシルク印刷が対応づけられている。

注意: 上記のBroadcomピン番号は、Piモデル2以降のみに対応する。 古いRev1のPiを使っている場合は、対応するBroadcomピン番号について外部の解説記事を確認してほしい。

このように、Piでは双方向の入出力ピンだけでなく、シリアル(UART)、I2C、SPI、さらにはPWM(「アナログ出力」)の一部にもアクセスできる。

ハードウェアのセットアップ

先に回路を組み立てておくとよい。 この回路は、C版とPython版どちらのサンプルでも共通で使う。 出力機能(デジタルとPWM)の確認には2つのLEDを、入力の確認にはボタンを1つ使う。

初期モデルのPiへの接続

Pi B+とPi 2 Bへの接続

2つのLEDは、PiのGPIO 18とGPIO 23(Broadcomチップ固有の番号)に接続する。 P1コネクタのピン番号を基準にするなら、ピン12と16にあたる。

ボタンは、BroadcomのGPIO 17(P1ピン11)に接続する。

Pi Wedgeを使っている場合、配線はかなり単純になる。 完成すると次のような見た目になる。

Pi Wedgeがない場合は、オス-メスのジャンパー線を使うと、PiからブレッドボードへスムーズにI/Oを引き出せる。

Python(RPi.GPIO)API

Pythonのサンプルの中核には、RPi.GPIOモジュールを使う。 このPythonファイル群とソースはRaspbianに同梱されているため、Raspbianを使っている限り、新たに何かをダウンロードする必要はない。

このセクションでは、このモジュールを使った基本的な関数呼び出しの概要を説明する。

セットアップ

Pythonスクリプトの残りの部分でRPi.GPIOを使うには、ファイルの先頭に次の一文を置く必要がある。

import RPi.GPIO as GPIO

この一文でRPi.GPIOモジュールを取り込み、さらにGPIOというローカル名を与えている。以降はこの名前でモジュールを参照する。

ピン番号方式の宣言

RPi.GPIOモジュールを取り込んだら、次に決めるのは、二つのピン番号方式のうちどちらを使うかである。

  1. GPIO.BOARD — ボード番号方式。ピン番号はP1ヘッダー上のピン番号に従う。
  2. GPIO.BCM — Broadcomチップ固有のピン番号。Raspberry PiのBroadcomチップが定義する、より下位レベルの番号体系に従う。

Pi Wedgeを使っている場合はGPIO.BCMの使用を推奨する。基板上にシルク印刷されている番号がこちらだからである。 ヘッダーに直接配線する場合はGPIO.BOARDの方が扱いやすいこともある。

コード中でどちらの番号体系を使うかを指定するには、GPIO.setmode()関数を使う。たとえば次のようにする。

GPIO.setmode(GPIO.BCM)

これでBroadcomチップ固有のピン番号が有効になる。

import文とsetmodeの行は、いずれもPythonを使う上で必須である。

ピンモードの設定

Arduinoを使ったことがあれば、入力・出力どちらとして使うかを事前に宣言する「ピンモード」の概念に馴染みがあるはずである。 ピンモードを設定するにはsetup([pin], [GPIO.IN, GPIO.OUT])関数を使う。 たとえばピン18を出力として設定するには、次のように書く。

GPIO.setup(18, GPIO.OUT)

ボード番号方式を使っている場合は、ピン番号が18ではなく12に変わることに注意してほしい。

出力

デジタル出力

ピンをHIGHまたはLOWに設定するには、GPIO.output([pin], [GPIO.LOW, GPIO.HIGH])関数を使う。 たとえばピン18をHIGHにするには、次のように書く。

GPIO.output(18, GPIO.HIGH)

ピンをGPIO.HIGHに設定すると3.3Vが出力され、GPIO.LOWにすると0Vになる。 GPIO.HIGHGPIO.LOWの代わりに、1True0Falseを使ってピンの値を設定することもできる。

PWM(「アナログ」)出力

Raspberry PiのPWMは非常に限定的で、対応するピンは18番(P1ピン12)ただ一つだけである。

PWMを初期化するにはGPIO.PWM([pin], [frequency])関数を使う。 このインスタンスを変数に代入しておくと、以降のスクリプトが書きやすくなる。 続いてpwm.start([duty cycle])関数で初期値を設定する。たとえば次のようにする。

pwm = GPIO.PWM(18, 1000)
pwm.start(50)

これで、PWMピンを1kHzの周波数、50%のデューティ比で動作させることができる。

PWM出力の値を調整するには、pwm.ChangeDutyCycle([duty cycle])関数を使う。 [duty cycle]には0(0%、LOW相当)から100(100%、HIGH相当)までの値を指定できる。 たとえばピンを75%オンに設定するには、次のように書く。

pwm.ChangeDutyCycle(75)

そのピンのPWM出力を止めるには、pwm.stop()コマンドを使う。

いたって簡単である。PWMとして使う前にピンを出力として設定しておくことだけ忘れないようにしたい。

入力

ピンが入力として設定されている場合、GPIO.input([pin])関数でその値を読み取れる。 input()関数は、ピンがHIGHかLOWかに応じてTrueまたはFalseを返す。 これをif文でテストできる。たとえば次のようにする。

if GPIO.input(17):
    print("Pin 11 is HIGH")
else:
    print("Pin 11 is LOW")

このコードは、ピン17を読み取り、HIGHかLOWかを表示する。

プルアップ・プルダウン抵抗

先ほどのGPIO.setup()関数で入力・出力を宣言したことを思い出してほしい。 この関数には、プルアップ抵抗やプルダウン抵抗を設定するための、任意の第三引数がある。 ピンにプルアップ抵抗を使うには、GPIO.setupの第三引数にpull_up_down=GPIO.PUD_UPを追加する。 プルダウン抵抗が必要な場合は、代わりにpull_up_down=GPIO.PUD_DOWNを使う。

たとえば、GPIO 17にプルアップ抵抗を使うには、セットアップの記述を次のようにする。

GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)

この第三引数を省略した場合、プルアップ抵抗もプルダウン抵抗も無効になる。

その他

遅延

Pythonスクリプトの動作を遅くしたい場合は、遅延を追加できる。 遅延をスクリプトに組み込むには、timeモジュールを取り込む必要がある。 スクリプトの先頭に次の一行を置けばよい。

import time

その後、スクリプトの残りの部分でtime.sleep([seconds])を使えば、処理を一時停止できる。 小数を使えば遅延時間を精密に指定できる。 たとえば250ミリ秒遅延させるには、次のように書く。

time.sleep(0.25)

timeモジュールには、sleep以外にも便利な機能が数多くある。詳しくは公式リファレンスを参照してほしい。

後片付け

スクリプトが役目を終えたら、次にGPIOを使うプロセスのために後片付けをしておくとよい。 スクリプトの末尾でGPIO.cleanup()コマンドを使い、スクリプトが確保していたリソースを解放する。

このコマンドを書き忘れてもPiが壊れるわけではないが、書けるところでは書いておくのがよい習慣である。


ここまでの内容を、実際に動くサンプルスクリプトにまとめてみよう。

Python(RPi.GPIO)のサンプル

前のセクションで説明した基本的なRPi.GPIOの関数を使って、シンプルなGPIOスクリプトの例を作ってみる。

1. ファイルの作成

まず、Pythonファイルを作成する。 GUIベースのファイルエクスプローラーから作成してもよいし、ターミナルから作業したい場合はLXTerminalを開き、ファイルを置きたいフォルダに移動する(なければ作成する)。 次のコマンドで新しいフォルダを作る。

mkdir python

続いて、次のコマンドでそのフォルダに移動する。

cd python

ファイルを作成する。ここでは“blinker“という名前にし、拡張子は**.py**とする。

touch blinker.py

続いて、好みのテキストエディタでそのファイルを開く。NanoでもよいしPiの標準GUIテキストエディタであるMousepadでもよい。

mousepad blinker.py &

注意: 以前はLeafpadがRaspberry Piイメージの標準GUIテキストエディタだったが、現在はMousepadに置き換わっている。 Mousepadは、Raspberry Piのスタートメニューのアクセサリ > テキストエディタから見つけられる。 sudo apt-get install leafpadコマンドでLeafpadを手動インストールすることもでき、インストール後はそちらのエディタを指定してファイルを開くこともできる。

leafpad blinker.py &

これで空のテキストファイルが開く(末尾の&はバックグラウンドで開くためのもので、ターミナルは引き続き使える状態のままになる)。 いよいよコードを書く番である。

2. コードを書く

前のセクションで学んだ内容をひととおり盛り込んだサンプルスケッチは次のとおりである。 入出力の処理に加えて、PWMの扱いも含まれている。 これは、ハードウェアのセットアップの節で組んだ回路をそのまま使う前提のコードである。

# External module imports
import RPi.GPIO as GPIO
import time

# Pin Definitons:
pwmPin = 18 # Broadcom pin 18 (P1 pin 12)
ledPin = 23 # Broadcom pin 23 (P1 pin 16)
butPin = 17 # Broadcom pin 17 (P1 pin 11)

dc = 95 # duty cycle (0-100) for PWM pin

# Pin Setup:
GPIO.setmode(GPIO.BCM) # Broadcom pin-numbering scheme
GPIO.setup(ledPin, GPIO.OUT) # LED pin set as output
GPIO.setup(pwmPin, GPIO.OUT) # PWM pin set as output
pwm = GPIO.PWM(pwmPin, 50)  # Initialize PWM on pwmPin 100Hz frequency
GPIO.setup(butPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Button pin set as input w/ pull-up

# Initial state for LEDs:
GPIO.output(ledPin, GPIO.LOW)
pwm.start(dc)

print("Here we go! Press CTRL+C to exit")
try:
    while 1:
        if GPIO.input(butPin): # button is released
            pwm.ChangeDutyCycle(dc)
            GPIO.output(ledPin, GPIO.LOW)
        else: # button is pressed:
            pwm.ChangeDutyCycle(100-dc)
            GPIO.output(ledPin, GPIO.HIGH)
            time.sleep(0.075)
            GPIO.output(ledPin, GPIO.LOW)
            time.sleep(0.075)
except KeyboardInterrupt: # If CTRL+C is pressed, exit cleanly:
    pwm.stop() # stop PWM
    GPIO.cleanup() # cleanup all GPIO

すべて入力し終えたら(インデントを忘れないように)、保存する。

スクリプトの実行

RPi.GPIOモジュールは管理者権限を必要とするため、Pythonスクリプトの呼び出しの先頭にsudoを付ける必要がある。 “blinker.py“スクリプトを実行するには、次のように入力する。

sudo python blinker.py

コードを実行した状態でボタンを押すと、デジタル出力のLEDが点灯する。 PWM制御のLEDも、ボタンを押すと明るさが反転する。

CTRL+Cを押すと、スクリプトをきれいに終了できる。

C(WiringPi)のセットアップ

Pythonは、使い慣れている人にとってはGPIOを駆動する優れた選択肢である。 しかし、もし空白文字に厳格なスクリプト言語に馴染みがなく、むしろ慣れ親しんだCの世界にとどまりたいのであれば、WiringPiライブラリを紹介したい。

1) WiringPiのインストール

注意: WiringPiは現在、標準のRaspbianシステムにあらかじめインストールされている。 WiringPi公式ホームページの手順は現在非推奨であり、元のWiringPiソース(git://git.drogon.net/wiringPi)はもう利用できない。

WiringPiは、以前のバージョンのRaspbianには同梱されていなかったため、ユーザーが自分でダウンロードしてインストールする必要があった。 現在は幸い、標準のRaspbianシステムに含まれている。 新しいハードウェアに対応した更新版のミラーからWiringPiを更新したい場合は、こちらのGitHubリポジトリを確認してほしい。

gitが必要になる(デフォルトでインストールされている場合もある)。 gitがインストールされていない場合は、コマンドラインで次のように入力する。

sudo apt-get install git-core

最新版はGitを使ってダウンロードすることを強く推奨する。 現在のバージョンを確認するには、次のコマンドを入力する。

gpio -v

次のようにUnknown17を含む出力が返ってきた場合、Raspberry Pi 4以降でWiringPiを更新する必要がある。

gpio version: 2.50
Copyright (c) 2012-2018 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
  Type: Unknown17, Revision: 02, Memory: 0MB, Maker: Sony
    * Device tree is enabled.
    * --> Raspberry Pi 4 Model B Rev 1.2
    * This Raspberry Pi supports user-level GPIO access.

WiringPiと設定ファイルを削除するには、次のように入力する。

sudo apt-get purge wiringpi

続いて、次のコマンドでPiにWiringPiの記憶を完全に消去させる。

hash -r

Gitさえインストールされていれば、WiringPiのダウンロードとインストールに必要なのは次のコマンドだけである。

git clone https://github.com/WiringPi/WiringPi.git

これで、カレントディレクトリにWiringPiという名前のフォルダが作られる。 WiringPiのディレクトリに移動する。

cd WiringPi

続いて、originから最新の変更を取得する。

git pull origin

続いて、次のコマンドを実行する。 ./buildは、ソースファイルからWiringPiをビルドするスクリプトである。 これによりヘルパーファイルが構築され、Linux上のいくつかのパスが変更され、WiringPiが使える状態になる。

./build

ここまでで、ライブラリは動作するはずである。 下記のgpioコマンドを実行し、WiringPiのバージョンと実行中のPiに関する情報を確認する。

gpio -v

次のコマンドを入力すると、40ピンコネクタの各ピンの設定を示す表が表示される。

gpio readall

トラブルシューティングのヒント: gpioコマンドでピンの読み書きや設定を行った際に、次のような出力が返ってくる場合、これはwiringPiとミラー版WiringPiの間の競合が原因である。 Raspberry Piにインストールされていた以前のwiringPiをpurgeコマンドで確実に削除してほしい。

gpio: Symbol 'piModelNames' has different size in shared object, consider re-linking
Oops - unable to determine board type... model:17

2) WiringPiのテスト

WiringPiが優れているのは、単なるCライブラリにとどまらず、コマンドラインユーティリティも備えている点である。 gpioユーティリティを使って、インストールをテストできる。 次の手順で、ピンを切り替えてLEDをオン・オフし、続いてボタンの押下を読み取ってみる。

LEDの点滅

ターミナルを開き、いくつかのシステムコールを試してみる。 ピン18を設定するには、次のように入力する。デフォルトでは、このピンは入力として設定されている。

gpio -g mode 18 output

ピンをHIGHにするには、次のように入力する。

gpio -g write 18 1

LOWに戻すには、次のように入力する。

gpio -g write 18 0

LEDがピン18に接続されたままであれば、この二つのコマンドを実行するたびに点灯・消灯するはずである。

ボタンの押下を読み取る

ボタンをテストするには、まずピン17をPiの内蔵プルアップ抵抗で設定する必要がある。

gpio -g mode 17 up

ピンを読み取るには、次のように入力する。

gpio -g read 17

ボタンが押されているかどうかに応じて、0か1が返される。 ボタンを押しながらもう一度同じコマンドを試してみてほしい。

gpioユーティリティは、マニュアルにもあるとおり「万能ツール」のコマンドラインツールである。 manページ(man gpioと入力する)を確認し、できることをひととおり把握しておくことを強く推奨する。


Cスタイルのプログラミングに進む準備ができたら、次のセクションに進んでほしい。 WiringPiライブラリが提供する、特に便利な関数の概要を紹介する。

C(WiringPi)API

このセクションでは、WiringPiライブラリが提供する特に便利な関数の一部を紹介する。 Arduinoによく似せて作られているため、Arduinoでのプログラミング経験があれば見覚えのある部分も多いはずである。

セットアップ

まず、ライブラリを取り込む必要がある。 プログラムの先頭に、次のように書く。

#include <wiringPi.h>

ライブラリを取り込んだら、最初のステップとしてこれを初期化する。 このステップでは、プログラムの残りの部分で使うピン番号方式も決まる。 ライブラリを初期化する関数呼び出しは、次のいずれか一つを選ぶ。

wiringPiSetup(); // Initializes wiringPi using wiringPi's simlified number system.
wiringPiSetupGpio(); // Initializes wiringPi using the Broadcom GPIO pin numbers

WiringPiの簡易番号方式は、これまでの表になかった第三の番号体系である。 この方式を使いたい場合は、WiringPiのピンページで概要を確認してほしい。

ピンモードの宣言

ピンを入力または出力として設定するには、pinMode([pin], [mode])関数を使う。 モードにはINPUTOUTPUTPWM_OUTPUTのいずれかを指定できる。

たとえば、ピン22を入力、23を出力、18をPWMとして設定するには、次のように書く。

wiringPiSetupGpio()
pinMode(17, INPUT);
pinMode(23, OUTPUT);
pinMode(18, PWM_OUTPUT);

この例ではBroadcomのGPIOピン番号方式を使っていることに注意してほしい。

デジタル出力

digitalWrite([pin], [HIGH/LOW])関数を使うと、出力ピンをHIGHまたはLOWに設定できる。 Arduinoユーザーであれば馴染み深いはずである。

たとえばピン23をHIGHにするには、次のように呼び出すだけでよい。

digitalWrite(23, HIGH);

PWM(「アナログ」)出力

唯一のPWM対応ピンには、pwmWrite([pin], [0-1023])を使って0から1024までの値を設定できる。たとえば次のようにする。

pwmWrite(18, 723);

これで、ピン18のデューティ比がおよそ70%に設定される。

デジタル入力

Arduino経験者であれば、次に何が来るか見当がつくだろう。 ピンのデジタル状態を読み取るにはdigitalRead([pin])関数を使う。たとえば次のようにする。

if (digitalRead(17))
    printf("Pin 17 is HIGH\n");
else
    printf("Pin 17 is LOW\n");

このコードは、ピン22の状態を表示する。 digitalRead()関数は、ピンがHIGHなら1、LOWなら0を返す。

プルアップ・プルダウン抵抗

デジタル入力にプルアップ抵抗やプルダウン抵抗が必要な場合は、pullUpDnControl([pin], [PUD_OFF, PUD_DOWN, PUD_UP])関数を使う。

たとえば、ピン22にボタンがあり、プルアップの助けが必要な場合は、次のように書く。

pullUpDnControl(17, PUD_UP);

これは、ボタンを押したときにピンがLOWに引かれる構成のときに役立つ。

遅延

点滅するLEDの動きを遅くしたい場合、つまり点灯と消灯を区別したい場合には、遅延が役に立つ。 WiringPiにはdelay([milliseconds])delayMicroseconds([microseconds])という二つの遅延関数がある。 標準のdelayは、指定したミリ秒数だけプログラムの流れを止める。 たとえば2秒遅延させるには、次のように書く。

delay(2000);

より精密なマイクロ秒単位の遅延が必要な場合は、delayMicroseconds()を使うこともできる。


基本を押さえたところで、実際のサンプルコードに適用してみよう。

C(WiringPi)のサンプル

WiringPiは、I/Oまわりのコードをできる限りArduino風に見せることを狙って作られている。 とはいえ、Arduinoの快適な世界からは離れており、loop()setup()は存在せず、あるのはint main(void)だけであることに注意してほしい。

ここでは、Cのサンプルファイルを作成し、WiringPiライブラリを組み込み、コンパイルして実行するまでの流れを追っていく。

blinker.cの作成

ターミナルで、好きな名前のフォルダを作る。

mkdir c_example

作成したフォルダに移動する。

cd c_example

“blinker.c“という名前の新しいファイルを作成する。

touch blinker.c

続いて、そのファイルをテキストエディタで開く(NanoやMousepad/LeafpadはRaspbianに同梱されている)。

mousepad blinker.c &

注意: 以前はLeafpadがRaspberry Piイメージの標準GUIテキストエディタだったが、現在はMousepadに置き換わっている。 Mousepadは、Raspberry Piのスタートメニューのアクセサリ > テキストエディタから見つけられる。 sudo apt-get install leafpadコマンドでLeafpadを手動インストールすることもでき、インストール後はそちらのエディタを指定してファイルを開くこともできる。

leafpad blinker.py &

これで“blinker.c“ファイルがMousepad(またはLeafpad)で開き、ターミナルはそのディレクトリでバックグラウンドのまま動き続ける。

プログラムを書く

前のセクションで説明した内容をひととおり盛り込んだサンプルプログラムは次のとおりである。 コピー&ペーストしてもよいし、自分で書き写して練習の足しにしてもよい。

#include <stdio.h>    // Used for printf() statements
#include <wiringPi.h> // Include WiringPi library!

// Pin number declarations. We're using the Broadcom chip pin numbers.
const int pwmPin = 18; // PWM LED - Broadcom pin 18, P1 pin 12
const int ledPin = 23; // Regular LED - Broadcom pin 23, P1 pin 16
const int butPin = 17; // Active-low button - Broadcom pin 17, P1 pin 11

const int pwmValue = 75; // Use this to set an LED brightness

int main(void)
{
    // Setup stuff:
    wiringPiSetupGpio(); // Initialize wiringPi -- using Broadcom pin numbers

    pinMode(pwmPin, PWM_OUTPUT); // Set PWM LED as PWM output
    pinMode(ledPin, OUTPUT);     // Set regular LED as output
    pinMode(butPin, INPUT);      // Set button as INPUT
    pullUpDnControl(butPin, PUD_UP); // Enable pull-up resistor on button

    printf("Blinker is running! Press CTRL+C to quit.\n");

    // Loop (while(1)):
    while(1)
    {
        if (digitalRead(butPin)) // Button is released if this returns 1
        {
            pwmWrite(pwmPin, pwmValue); // PWM LED at bright setting
            digitalWrite(ledPin, LOW);     // Regular LED off
        }
        else // If digitalRead returns 0, button is pressed
        {
            pwmWrite(pwmPin, 1024 - pwmValue); // PWM LED at dim setting
            // Do some blinking on the ledPin:
            digitalWrite(ledPin, HIGH); // Turn LED ON
            delay(75); // Wait 75ms
            digitalWrite(ledPin, LOW); // Turn LED OFF
            delay(75); // Wait 75ms again
        }
    }

    return 0;
}

入力し終えたら、保存してターミナルに戻る。

コンパイルと実行

インタプリタ型のPythonとは異なり、Cのプログラムは実行の前にビルドが必要である。

プログラムをコンパイルするには、gccを呼び出す。 ターミナルに次のように入力し、コンパイルが終わるまで少し待つ。

gcc -o blinker blinker.c -l wiringPi

このコマンドにより、“blinker“という実行ファイルが作られる。 -l wiringPiの部分が重要で、これによりwiringPiライブラリが読み込まれる。 コンパイルが成功した場合、メッセージは何も表示されない。エラーが出た場合は、そのメッセージを手がかりに原因を追ってほしい。

プログラムを実行するには、次のように入力する。

sudo ./blinker

blinkerプログラムが動き始めるはずである。 ハードウェアのセットアップの節でまとめたとおりに回路を組んでおくこと。 ボタンを押すとLEDが点滅し、離すと消灯する。 PWM制御のLEDは、ボタンを離しているときに最も明るく、押しているときに暗くなる。


色分けもハイライトもない味気ないエディタで、ここまでのコードを打ち込むのが辛かった場合は、次のセクションでプログラミングを効率化するシンプルなIDEを紹介する。

IDEの利用

これまでは、シンプルなテキストエディタ(LeafpadやNano)を使ってPythonやCのプログラムを書いてきた。 経験を積んだプログラマであれば、自動インデント、コンテキストハイライト、自動ビルドといった、基本的なエディタにすら備わっている機能の多くが物足りなく感じるはずである。 こうした機能を使いたい場合は、IDE(統合開発環境)の利用を推奨する。 Pi向けのお気に入りのIDEの一つがGeanyであり、ここではその導入方法を紹介する。

Geanyのダウンロードとインストール

GeanyはRaspbianに同梱されていないため、ダウンロードにはインターネット接続が必要である。 便利なapt-getユーティリティを使うことができる。 まず、次のコマンドを入力する。

sudo apt-get update

更新が終わったら、次のコマンドでインストールする。

sudo apt-get install geany

インストールが終わったら、「スタート」メニューの「プログラミング」タブからGeanyを起動できる。

あるいは、ターミナルからsudo geanyと入力してもよい。 コマンドラインから直接ファイルを開くこともできる。 たとえば先ほどのCファイルを開くにはsudo geany blinker.cと入力する。

Geanyを使う

Geanyを起動したら、ファイル > 新規からファイルを作成できる。 拡張子を“.c“や“.py“(あるいはその他の一般的な言語の拡張子)で保存すると、Geanyはすぐにどの言語で作業しているかを認識し、ハイライト表示を始める。

Geanyは、先ほど見たPythonとCのサンプルを含め、ほとんどの言語で使える。 ただし、デフォルトのIDE設定にはいくつか調整が必要である。 それぞれの言語での使い方の概要を以下に示す。

CとWiringPiでの利用

先ほどのWiringPiのサンプルをGeanyで再現してみる。 先ほど作成した“blinker.c“をGeanyで開く。 すぐに見やすい色分け表示が現れるはずである。

ただし、コンパイルの前にビルドオプションをいくつか調整する必要がある。 ビルドメニューからビルドコマンドの設定を開き、「Compile」と「Build」のテキストボックスの末尾にそれぞれ-l wiringPiを追加する。 これでwiringPiライブラリが読み込まれるようになる。

ついでに、実行コマンドの先頭に**“sudo“を追加**しておく。 上の画像のようにビルドコマンドが設定できていることを確認し、「OK」をクリックする。

設定が終われば準備は完了である。 ビルドメニューからビルドをクリックする(あるいは上部の赤いブロック状のアイコンをクリックする)。 ビルドが実行されると、IDEは下部の「Compiler」タブに切り替わり、コンパイル結果を表示する。 ビルドが成功したら、そのまま実行に進んでよい。

ビルドしたファイルを実行するには、ビルド > 実行をクリックする(あるいは上部の歯車アイコンをクリックする)。 実行すると新しいターミナルウィンドウが開き、プログラムが動き始める。 プログラムを止めるには、そのターミナルウィンドウでCTRL+Cを押す。

Pythonでの利用

GeanyはPythonでも使うことができる。 試しに、先ほど作成した“blinker.py“ファイルを開いてみる。 Cファイルのときと同様に、見やすいコンテキストハイライトが表示される。

Pythonの場合、ビルドは不要である。 スクリプトを書き終えたら、上部の「実行」(歯車アイコン)をクリックするだけでよい。 実行すると、こちらも別のターミナルが開く。終了するにはCTRL+Cを押す。


Geanyには、ここで紹介した以外にも数多くの機能がある。 下部や上部のタブやメニューも確認してほしい。 いろいろ試しながら、このIDEがプログラミングをどれだけ快適にしてくれるか実感してほしい。

まとめ・参考資料

PiのLEDを点滅させる方法がわかったところで、さらに先へ進むための資料をいくつか紹介する。

プロジェクトのヒントを探しているなら、Piプログラミングのスキルを活かせる次のようなチュートリアルも参考になる。

タグ: 概念、プログラミング、Python、Raspberry Pi、シングルボードコンピュータ


出典:Raspberry gPIo(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

Raspberry PiのSPIとI2C

I2CとSPIのシリアルインターフェースを介してマイクロプロセッサに追加できる周辺機器は数多い。 大気センサー、EEPROM、各種のディスプレイなどがその例である。

Pi WedgeはI2CとSPIの信号にアクセスしやすくしてくれる。

このチュートリアルでは、Raspberry PiのI2CとSPIのインターフェースを実際に動かすまでの手順を説明する。 これらのインターフェースはデフォルトでは有効になっておらず、使う前にいくつか追加の設定が必要である。

参考になるチュートリアル

始める前に、関連する背景知識のチュートリアルに目を通しておくとよい。

  • I2Cは、最小限の配線でマイクロコントローラーと周辺機器の間でデータをやり取りできる便利なバスである。
  • SPI(シリアルペリフェラルインターフェース)は、I2Cと似た用途を持つ親戚のようなインターフェースである。
  • C/C++のサンプルでは、これらのバスとのやり取りにwiringPiライブラリを使う。
  • Pythonのサンプルでは、SPIにspidevを、I2Cにsmbusを使う。

背景知識とソフトウェアのセットアップ

Raspberry PiのGPIOヘッダーには、3種類のシリアルインターフェースがある。 すでに馴染みがあるかもしれないUARTシリアルポートは、PuTTYのようなシリアルターミナルアプリケーションからログインセッションを開くのに使われる。

残る二つのシリアルインターフェースが、シリアルペリフェラルインターフェース(SPI)とInter-Integrated-Circuitバス(I2C)である。 Pi上のSPIは最大2台の周辺機器を接続できるのに対し、I2Cはアドレスが重複しない限り、原理上多数の機器を接続できる。

ソフトウェアの詳細

Raspberry Pi向けのソフトウェアを取り巻く状況は、Piの登場以来かなり進化してきた。 さまざまなOSがPiに移植され、デバイスドライバの基盤も大きく変化している。

このチュートリアルでは、比較的新しいバージョンのRaspbian(NOOBS経由でインストールしたもの)と、C/C++向けのwiringPi I/Oライブラリ(Pythonの場合はspidev/smbus)を使う。

Raspbianにデバイスツリーオーバーレイが導入されたことで、インターフェースを有効化する具体的な手順の一部が変更されている。 古いインストール環境を使っている場合は、SDカードをバックアップし、まっさらな状態からインストールし直すのも一つの手である。

OSとライブラリのインストール

まっさらなSDカードから始める場合は、Raspbianをインストールする必要がある。 すでに動作するRaspbian環境がある場合は、次のセクションまで読み飛ばしてよい。

Piのセットアップに別の方法を使いたい場合は、次のチュートリアルも参考にしてほしい。

C/C++でプログラミングする場合は、Raspberry PiのGPIOのWiring Piのセットアップの節を参照することを推奨する。 参考までに、以下に同じ手順を掲載しておく。

C/C++(Wiring Pi)のセットアップ

注意: WiringPiは現在、標準のRaspbianシステムにあらかじめインストールされている。 WiringPi公式ホームページの手順は現在非推奨であり、元のWiringPiソース(git://git.drogon.net/wiringPi)はもう利用できない。

WiringPiは、以前のバージョンのRaspbianには同梱されていなかったため、ユーザーが自分でダウンロードしてインストールする必要があった。 現在は幸い、標準のRaspbianシステムに含まれている。 新しいハードウェアに対応した更新版のミラーからWiringPiを更新したい場合は、GitHubリポジトリを確認してほしい。

gitが必要になる(デフォルトでインストールされている場合もある)。 gitがインストールされていない場合は、コマンドラインで次のように入力する。

sudo apt-get install git-core

最新版はGitを使ってダウンロードすることを強く推奨する。 現在のバージョンを確認するには、次のコマンドを入力する。

gpio -v

次のようにUnknown17を含む出力が返ってきた場合、Raspberry Pi 4以降でWiringPiを更新する必要がある。

gpio version: 2.50
Copyright (c) 2012-2018 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
  Type: Unknown17, Revision: 02, Memory: 0MB, Maker: Sony
    * Device tree is enabled.
    * --> Raspberry Pi 4 Model B Rev 1.2
    * This Raspberry Pi supports user-level GPIO access.

WiringPiと設定ファイルを削除するには、次のように入力する。

sudo apt-get purge wiringpi

続いて、次のコマンドでPiにWiringPiの記憶を完全に消去させる。

hash -r

Gitさえインストールされていれば、WiringPiのダウンロードとインストールに必要なのは次のコマンドだけである。

git clone https://github.com/WiringPi/WiringPi.git

これで、カレントディレクトリにWiringPiという名前のフォルダが作られる。 WiringPiのディレクトリに移動する。

cd WiringPi

続いて、originから最新の変更を取得する。

git pull origin

続いて、次のコマンドを実行する。 ./buildは、ソースファイルからWiringPiをビルドするスクリプトである。 これによりヘルパーファイルが構築され、Linux上のいくつかのパスが変更され、WiringPiが使える状態になる。

./build

ここまでで、ライブラリは動作するはずである。 下記のgpioコマンドを実行し、WiringPiのバージョンと実行中のPiに関する情報を確認する。

gpio -v

次のコマンドを入力すると、40ピンコネクタの各ピンの設定を示す表が表示される。

gpio readall

I2CとSPIのインターフェースは、それぞれ追加の設定と初期化が必要になる。詳しくは後述のセクションで説明する。

Python(spidev/smbus)のセットアップ

Python 3のセットアップとpipのインストールについては、Pythonプログラミングチュートリアルの「Piの設定」の節を参照してほしい。

ポートへの接続

設定とサンプルコードの説明に入る前に、それぞれのインターフェースが使うピンの位置を確認しておく。

Piのピンに直接配線する場合、配置はやや分かりにくい。 I2C.1は片端の近くにあるのに対し、SPIとI2C.0はヘッダーの中央付近にある。 これらのピンに配線する際は、慎重に数えるようにしてほしい。

Piのシリアルバスピン

Pi Wedgeアダプタ基板は、ピンを整理して分かりやすくラベル付けしてくれる。 以降のサンプルではこのWedgeを使う。

Wedgeのシリアルバスピン

PiでのSPI

設定

SPIペリフェラルはデフォルトでは無効になっている。 設定を変更する方法は二つある。有効化するには次の手順で行う。

デスクトップGUIによるRaspberry Piの設定

デスクトップGUIを使うには、Piのスタートメニュー > Preferences > Raspberry Pi Configurationを開く。

画像をクリックすると拡大表示できる。

ウィンドウが開き、設定を調整するためのタブがいくつか表示される。 ここで使うのはInterfacesタブである。 このタブをクリックし、SPIの項目でEnableを選択する。 プロジェクトの必要に応じて、他のインターフェースもここで有効化できる。 OKボタンをクリックして保存する。

画像をクリックすると拡大表示できる。

設定を確実に反映させるため、Piを再起動することを推奨する。 Piのスタートメニュー > Preferences > Shutdownをクリックする。 今回は再起動だけでよいので、Restartボタンをクリックする。

Shutdown

Turn Off、Restart、Log Off

画像をクリックすると拡大表示できる。

ターミナルによるraspi-configツール

ターミナルを使う場合は、次の手順で行う。

  1. sudo raspi-configを実行する。
  2. 下矢印キーで5 Interfacing Optionsを選択する。
  3. P4 SPIまで下矢印キーで移動する。
  4. SPIを有効にするか聞かれたらyesを選択する。
  5. カーネルモジュールを自動で読み込むか聞かれた場合もyesを選択する。
  6. 右矢印キーで<Finish>ボタンを選択する。
  7. 再起動するか聞かれたらyesを選択する。

SPI用のraspi-config

システムが再起動する。 再起動後、ログインして次のコマンドを入力する。

ls /dev/*spi*

Piは次のように応答するはずである。

/dev/spidev0.0  /dev/spidev0.1

これらは、それぞれチップイネーブルピン0と1に対応するSPIデバイスを表す。 これらのピンはPi内部で固定配線されている。 通常、このインターフェースが対応できるのは最大2台の周辺機器までだが、単一のチップイネーブル信号を共有しながら複数のデバイスをデイジーチェーン接続できる場合もある。

プログラミングの例

必要な部品

シリアル7セグメントディスプレイは、UART、SPI、I2Cのいずれからでもコマンドを受け付けられるため、シリアルインターフェースのテストに特に便利である。 配線の前に、7セグメントディスプレイにヘッダーピンをはんだ付けしておくこと。

接続表

ディスプレイは、Pi Wedgeを介して次のようにPiに接続した。

Raspberry Piの信号シリアル7セグメントの信号
GNDGND
3.3VVCC
CE1SS(Shift Select)
SCKSCK
MOSISDI
MISOSDO

テスト用のハードウェアは次のような見た目になった。

SPI用のシリアル7セグメントの接続

C++のサンプルプログラム

/******************************************************************************
spitest.cpp
Raspberry Pi SPI interface demo
Byron Jacquot @ SparkFun Electronics
4/2/2014
https://github.com/sparkfun/Pi_Wedge

A brief demonstration of the Raspberry Pi SPI interface, using the SparkFun
Pi Wedge breakout board.

This example makes use of the Wiring Pi library, which streamlines the interface
to the I/O pins on the Raspberry Pi, providing an API similar to Arduino.

Hardware connections (Raspberry Pi -> Serial 7 Segment):
GND  -> GND
3.3V -> Vcc
CE1  -> SS (Shift Select)
SCK  -> SCK
MOSI -> SDI
MISO -> SDO

To build: g++ spitest.cpp -lwiringPi
This test uses the single-segment mode of the 7 segment display.
******************************************************************************/

#include <iostream>
#include <errno.h>
#include <wiringPiSPI.h>
#include <unistd.h>

using namespace std;

// channel is the wiringPi name for the chip select (or chip enable) pin.
// Set this to 0 or 1, depending on how it's connected.
static const int CHANNEL = 1;

int main()
{
   int fd, result;
   unsigned char buffer[100];

   cout << "Initializing" << endl ;

   // Configure the interface.
   // CHANNEL indicates chip select,
   // 500000 indicates bus speed.
   fd = wiringPiSPISetup(CHANNEL, 500000);

   cout << "Init result: " << fd << endl;

   // clear display
   buffer[0] = 0x76;
   wiringPiSPIDataRW(CHANNEL, buffer, 1);

   sleep(5);

   // Do a one-hot bit selection for each field of the display
   for(int i = 1; i <= 0x7f; i <<= 1)
   {
      // the decimals, colon and apostrophe dots
      buffer[0] = 0x77;
      buffer[1] = i;
      result = wiringPiSPIDataRW(CHANNEL, buffer, 2);

      // The first character
      buffer[0] = 0x7b;
      buffer[1] = i;
      result = wiringPiSPIDataRW(CHANNEL, buffer, 2);

      // The second character
      buffer[0] = 0x7c;
      buffer[1] = i;
      result = wiringPiSPIDataRW(CHANNEL, buffer, 2);

      // The third character
      buffer[0] = 0x7d;
      buffer[1] = i;
      result = wiringPiSPIDataRW(CHANNEL, buffer, 2);

      // The last character
      buffer[0] = 0x7e;
      buffer[1] = i;
      result = wiringPiSPIDataRW(CHANNEL, buffer, 2);

      // Pause so we can see them
      sleep(5);
   }

   // clear display again
   buffer[0] = 0x76;
   wiringPiSPIDataRW(CHANNEL, buffer, 1);
}

wiringPiをビルドした際、それに対してアプリケーションをコンパイルする方法についての記述に気づいたかもしれない。

NOTE: To compile programs with wiringPi, you need to add:
    -lwiringPi
to your compile line(s) To use the Gertboard, MaxDetect, etc.
code (the devLib), you need to also add:
    -lwiringPiDev
to your compile line(s).

したがって、次のコマンドでコンパイルする。

g++ spitest.cpp -l wiringPi -o spitest

これによりspitestという実行ファイルが生成される。 ./spitestを実行すると、ディスプレイの各セグメントが順に光る。 各桁のセグメントを5秒ずつ点灯させながら次のセグメントに進み、全体でおよそ40秒かかる。

Pythonのサンプルプログラム

# spitest.py
# A brief demonstration of the Raspberry Pi SPI interface, using the Sparkfun
# Pi Wedge breakout board and a SparkFun Serial 7 Segment display

import time
import spidev

# We only have SPI bus 0 available to us on the Pi
bus = 0

# Device is the chip select pin. Set to 0 or 1, depending on the connections
device = 1

# Enable SPI
spi = spidev.SpiDev()

# Open a connection to a specific bus and device (chip select pin)
spi.open(bus, device)

# Set SPI speed and mode
spi.max_speed_hz = 500000
spi.mode = 0

# Clear display
msg = [0x76]
spi.xfer2(msg)

time.sleep(5)

# Turn on one segment of each character to show that we can
# address all of the segments
i = 1
while i < 0x7f:

    # The decimals, colon and apostrophe dots
    msg = [0x77]
    msg.append(i)
    result = spi.xfer2(msg)

    # The first character
    msg = [0x7b]
    msg.append(i)
    result = spi.xfer2(msg)

    # The second character
    msg = [0x7c]
    msg.append(i)
    result = spi.xfer2(msg)

    # The third character
    msg = [0x7d]
    msg.append(i)
    result = spi.xfer2(msg)

    # The last character
    msg = [0x7e]
    msg.append(i)
    result = spi.xfer2(msg)

    # Increment to next segment in each character
    i <<= 1

    # Pause so we can see them
    time.sleep(5)


# Clear display again
msg = [0x76]
spi.xfer2(msg)

このプログラムをspitest.pyのような名前で保存し、次のコマンドで実行する。

python spitest.py

これにより、各文字の各セグメントが5秒ずつ点灯し、次のセグメントに進む。 プログラム全体の実行にはおよそ40秒かかる。

PiでのI2C

設定

I2Cペリフェラルも、SPIと同様にデフォルトでは無効になっている。 設定を変更する方法は二つある。有効化するには次の手順で行う。

デスクトップGUIによるRaspberry Piの設定

デスクトップGUIを使うには、Piのスタートメニュー > Preferences > Raspberry Pi Configurationを開く。

画像をクリックすると拡大表示できる。

ウィンドウが開き、設定を調整するためのタブがいくつか表示される。 ここで使うのはInterfacesタブである。 このタブをクリックし、I2Cの項目でEnableを選択する。 プロジェクトの必要に応じて、他のインターフェースもここで有効化できる。 OKボタンをクリックして保存する。

画像をクリックすると拡大表示できる。

設定を確実に反映させるため、Piを再起動することを推奨する。 Piのスタートメニュー > Preferences > Shutdownをクリックする。 今回は再起動だけでよいので、Restartボタンをクリックする。

Shutdown

Turn Off、Restart、Log Off

画像をクリックすると拡大表示できる。

ターミナルによるraspi-configツール

SPIペリフェラルと同様に、I2Cもデフォルトでは無効になっている。 ここでもraspi-configを使って有効化できる。

  1. sudo raspi-configを実行する。
  2. 下矢印キーで5 Interfacing Optionsを選択する。
  3. P5 I2Cまで下矢印キーで移動する。
  4. I2Cを有効にするか聞かれたらyesを選択する。
  5. カーネルモジュールを自動で読み込むか聞かれた場合もyesを選択する。
  6. 右矢印キーで<Finish>ボタンを選択する。
  7. 再起動するか聞かれたらyesを選択する。

I2C用のraspi-config

システムが再起動する。 再起動後、ログインして次のコマンドを入力する。

ls /dev/*i2c*

Piは次のように応答するはずである。

/dev/i2c-1

これは、ユーザーモードのI2Cインターフェースを表す。

ユーティリティ

I2Cインターフェースを動かす助けになる、一連のコマンドラインユーティリティプログラムがある。 これらはaptパッケージマネージャーで入手できる。

sudo apt-get install -y i2c-tools

なかでもi2cdetectプログラムは、バス上のすべてのアドレスにプローブを送り、デバイスが存在するかどうかを報告してくれる。 コマンドラインで次のコマンドを入力する。 -yフラグは対話モードを無効にし、確認待ちを省略する。 1は、I2Cバス1(i2c-1)上のI2Cデバイスをスキャンすることを示している。

i2cdetect -y 1

Raspberry Piから、次のような出力が返ってくる。

pi@raspberrypi:~/$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

このマップは、アドレス0x60に周辺機器が存在することを示している。 i2cgeti2cseti2cdumpの各コマンドを使えば、そのレジスタの読み書きを試すことができる。

プログラミングの例

必要な部品

接続表

ディスプレイは、Pi Wedgeを介して次のようにPiに接続した。

Raspberry Piの信号MCP4725
GNDGND
3.3VVCC
SCLSCL
SDASDA

テスト用のハードウェアは次のような見た目になった。

ブレッドボード上のDAC

C++のサンプルプログラム

次のコードは、DACに連続した値を書き込み、出力ピンにのこぎり波を生成する。

/******************************************************************************
i2ctest.cpp
Raspberry Pi I2C interface demo
Byron Jacquot @ SparkFun Electronics
4/2/2014
https://github.com/sparkfun/Pi_Wedge

A brief demonstration of the Raspberry Pi I2C interface, using the SparkFun
Pi Wedge breakout board.

This example makes use of the Wiring Pi library, which streamlines the interface
to the I/O pins on the Raspberry Pi, providing an API similar to Arduino.

Hardware connections (Raspberry Pi -> MCP4725):
GND  -> GND
3.3V -> Vcc
SCL  -> SCL
SDA  -> SDA

An oscilloscope probe was connected to the analog output pin of the MCP4725.
To build: g++ i2ctest.cpp -lwiringPi
******************************************************************************/

#include <iostream>
#include <errno.h>
#include <wiringPiI2C.h>

using namespace std;

int main()
{
   int fd, result;

   // Initialize the interface by giving it an external device ID.
   // The MCP4725 defaults to address 0x60.
   //
   // It returns a standard file descriptor.
   //
   fd = wiringPiI2CSetup(0x60);

   cout << "Init result: "<< fd << endl;

   for(int i = 0; i < 0x0000ffff; i++)
   {
      // Doing a 16 bit register access, which properly handles the
      // endianness, with the length specified by the call. The register
      // address is the concatenation of the command (010x = write DAC
      // output) and power down (x00x = power up) bits.
      result = wiringPiI2CWriteReg16(fd, 0x40, (i & 0xfff) );

      if(result == -1)
      {
         cout << "Error.  Errno is: " << errno << endl;
      }
   }
}

wiringPiとリンクしてビルドするには、次のコマンドを使う。

g++ i2ctest.cpp -l wiringPi -o i2ctest

i2ctestを実行すると、DACが数秒間、アナログのこぎり波を出力する。

OUTピンで測定した波形

Pythonのサンプルプログラム

# i2ctest.py
# A brief demonstration of the Raspberry Pi I2C interface, using the Sparkfun
# Pi Wedge breakout board and a SparkFun MCP4725 breakout board

import smbus

# I2C channel 1 is connected to the GPIO pins
channel = 1

# MCP4725 defaults to address 0x60
address = 0x60

# Register addresses (with "normal mode" power-down bits)
reg_write_dac = 0x40

# Initialize I2C (SMBus)
bus = smbus.SMBus(channel)

# Create a sawtooth wave 16 times
for i in range(0x10000):

    # Create our 12-bit number representing relative voltage
    voltage = i & 0xfff

    # Shift everything left by 4 bits and separate bytes
    msg = (voltage & 0xff0) >> 4
    msg = [msg, (msg & 0xf) << 4]

    # Write out I2C command: address, reg_write_dac, msg[0], msg[1]
    bus.write_i2c_block_data(address, reg_write_dac, msg)

このプログラムをi2ctest.pyのような名前で保存し、次のコマンドで実行する。

python i2ctest.py

DACの出力にのこぎり波が現れるはずである。 オシロスコープを接続すれば、C++のサンプルと同様の波形が得られる。 ただし、PythonはC/C++よりもかなり低速である点に注意してほしい。 C++のサンプルでは、のこぎり波の周期がおよそ100msだったのに対し、Pythonのサンプルではおよそ1.8秒になった。

SMBusは、I2Cとは別のプロトコル層でありながら、I2Cの上に構築されているという点に注意してほしい。 I2Cの機能の一部はSMBusでは利用できないことがある。 たとえばSMBusはクロックストレッチングに対応していないため、それを必要とするセンサーはsmbusパッケージでは動作しない。

smbusプロトコルについて詳しくは、公式のカーネルドキュメントを参照してほしい。

40ピンPiボードのI2C-0

予備のI2Cバス?

B+の改良の一環として、Raspberry Pi Foundationは、拡張ボードへのインターフェースを「Hardware Added On Top」(HAT)仕様として標準化した。 これは拡張ボードの物理的なフォームファクタを標準化するとともに、B+が起動時にHATを自動的に識別・初期化する仕組みを含んでいる。 HAT上のEEPROMから説明情報を読み取るためにI2Cバスを使う点は、BeagleBone Blackにおけるcapeの識別方式に似ている。

この機能はA+とPi 2 Model Bにも引き継がれている。 このI2Cバスは、40ピンコネクタのID_SCピンとID_SDピン(ピン27と28)にある。 ただし、このバスに周辺機器を追加したくなる前に、そのポートの回路図にある注意書きを確認してほしい。

40ピンGPIOコネクタ(J8)の回路図の抜粋。画像をクリックすると拡大表示できる。

これについては、HAT設計ガイドでさらに詳しく説明されている。

Model B+では、GPIO0(ID_SD)とGPIO1(ID_SC)はALT0(I2C-0)モードに切り替わり、EEPROMの有無をプローブする。 プローブが完了すると、これらのピンは入力に戻る。

ID_ピンに接続してよいのは、IDのEEPROMと3.9kΩのプルアップ抵抗だけである。それ以外のものをこれらのピンに接続してはならない。

このバスは、起動時にアドレス0x50のEEPROMと通信するためだけに存在する。 実行時にユーザーがアクセスしようとすると問題が起きやすい。 B+で汎用のI2Cバスが必要な場合は、40ピンコネクタのピン3と5、Pi Wedge上ではSDAとSCLとラベル付けされているI2C-1を使う必要がある。

I2C-0の有効化

I2C-0はデフォルトでは無効になっている。 有効化するには、設定ファイルを手動で編集する必要がある。

/boot/config.txtを編集し、次の行を追加する。 以前raspi-configでI2C-1とSPIを有効化したことがあれば、ファイルの末尾付近に似たような記述が見つかるはずである。

dtparam=i2c_vc=on

これを追加したら、Piを再起動する(sudo reboot)。 再起動後、/dev/i2c-0というファイルシステムノードが存在すれば、有効化されたことがわかる。

EEPROM診断ツール

HAT設計ガイドと並んで、HATのEEPROMを扱うためのソフトウェアツール一式を収めたディレクトリが公開されている。 使用するには、これらをダウンロードし、コマンドラインでmakeする。

以下で、その使い方を見ていく。

I2C-0のテスト

上記の情報をもとに、24LC256というEEPROMチップを用意し、Piに配線した。 アドレスピンはすべてGNDに接続したため、アドレスは0x50になり、これはi2cdetectで確認できた。

ブレッドボード上のEEPROM

前述のEEPROMユーティリティを取得する。 test_settings.txtファイルは、EEPROMファイルの人間が読める形式のサンプルである。 テストのため、このファイルのvendorフィールドとproductフィールドをそれぞれ関連する情報に書き換えた。

このテキストファイル自体は、EEPROMに書き込む前にバイナリ形式に変換する必要がある。 eepmakeユーティリティがこの変換を行う。

./eepmake  test_settings.txt test.eep

バイナリ形式のtest.eepができたら、eepflash.shスクリプトを使って書き込むことができる。 このスクリプトはいくつかのパラメータを取り、-hフラグを付けて実行すれば説明が表示される。 EEPROMへの書き込み時には、プロンプトが表示されたらyesと完全な単語で入力して操作を承認する必要がある(単にyだけでは受け付けられない)。 eepflash.shは書き込みのステータスを表示する。書き込まれた118バイトは、上で生成したtest.eepファイルの長さと一致する。

sudo sh ./eepflash.sh -w -f=test.eep -t=24c256
This will disable the camera so you will need to REBOOT after this process completes.
This will attempt to write to i2c address 0x50. Make sure there is an eeprom at this address.
This script comes with ABSOLUTELY no warranty. Continue only if you know what you are doing.
Do you wish to continue? (yes/no): yes
Writing...
0+1 records in
0+1 records out
118 bytes (118 B) copied, 2.33811 s, 0.1 kB/s
Done.

この出力にあるとおり、ここで再起動する。

システムが起動し直すと、/proc/device-tree/hatに新しいファイルシステムノードができているはずである。

pi@raspberrypi /proc/device-tree/hat $ ls -al
total 0
drwxr-xr-x  2 root root  0 Oct 27 20:16 .
drwxr-xr-x 15 root root  0 Oct 27 20:16 ..
-r--r--r--  1 root root  4 Oct 27 20:16 name
-r--r--r--  1 root root 21 Oct 27 20:16 product
-r--r--r--  1 root root  7 Oct 27 20:16 product_id
-r--r--r--  1 root root  7 Oct 27 20:16 product_ver
-r--r--r--  1 root root 37 Oct 27 20:16 uuid
-r--r--r--  1 root root 24 Oct 27 20:16 vendor

これらのノードの中身を確認すると、test_settings.txtファイルに書き込んだ値が反映されていることがわかる。

pi@raspberrypi/proc/device-tree/hat $ cat vendor
SparkFun Electronics

pi@raspberrypi /proc/device-tree/hat $ cat product
EEPROM Testing

トラブルシューティング

raspi-configの「Advanced Options」からSPI/I2Cを有効化したにもかかわらず、デバイスツリーにデバイスが現れない場合でも、諦める必要はない。 確認すべきファイルが二つある。 raspi-configユーティリティだけでは解決しないことがあり、それはPiのバージョン、Raspbianの入手元、最後にアップデートした時期によって変わってくる。

/boot/config.txtの確認

raspi-configツールで詳細設定を選択した際に、/boot/config.txtが誤って編集されてしまうことがある。 このとき、ファイル内に誤った制御文字が混入する。

# NOOBS Auto-generated Settings:
hdmi_force_hotplug=1
config_hdmi_boost=4
overscan_left=24
overscan_right=24
overscan_top=16
overscan_bottom=16
disable_overscan=0^Mdtparam=spi=on
dtparam=i2c_arm=on

raspi-configによる設定後、/boot/config.txtに奇妙な^Mという文字が混入している

改行を修正し、次のような形になるようにする。

# NOOBS Auto-generated Settings:
hdmi_force_hotplug=1
config_hdmi_boost=4
overscan_left=24
overscan_right=24
overscan_top=16
overscan_bottom=16
disable_overscan=0
dtparam=spi=on
dtparam=i2c_arm=on

/etc/modulesの確認

次の行が存在しない場合は、/etc/modulesの末尾に追加する。

spi-dev
i2c-dev

システムの再起動

ファイルを確認したら、sudo rebootまたはsudo shutdown -r nowで再起動する。

まとめ・参考資料

このチュートリアルで扱った内容をさらに掘り下げたい場合は、次の資料を参照してほしい。

  • I2CとSPIの内部の細かな挙動に興味があるなら、WiringPiのソースコードを読んでみるとよい。GitHubからクローンできる
  • これらのインターフェースを支えるLinux側の仕組みについては、kernel.orgのドキュメントも参考になる。SPIのドキュメントは、I2Cのものより充実している。
  • ここで紹介したサンプルコードが動かない場合は、40ピンPi WedgeのGitHubリポジトリに更新版がないか確認してほしい。
  • RaspbianにおけるI2CとSPIデバイスの有効化方法は、最近のリビジョンで大きく変わっている。アップグレード後にインターフェースが消えてしまった場合の再有効化方法は、関連するフォーラムの投稿で説明されている。
  • HAT仕様と関連情報はGitHubで公開されている。HATを設計する場合は、まずHAT Design Guideを読み、B+ addonsフォーラムにも目を通しておくとよい。
  • Filezillaは、Piとの間でファイルをやり取りするのに便利なFTP・SFTPクライアントである。
  • PuTTYは、シリアル、telnet、SSHのモードを備えたターミナルプログラムである。
  • Raspberry PiのGPIOのチュートリアルでは、Piのデジタル入出力ピンの使い方を説明している。
  • Pi Wedgeを使うと、PiのSPIとI2Cインターフェースに手軽にアクセスできる。

Raspberry Piとここで紹介したソフトウェアについて、詳しくは次のサイトを参照してほしい。

Raspberry Piへのハードウェア接続やプロジェクトのヒントについては、次のガイドも参考になる。

タグ: 概念、通信、プログラミング、Python、Raspberry Pi、シングルボードコンピュータ


出典:Raspberry Pi SPI and I2C Tutorial(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。

PythonプログラミングでRaspberry Piを始める

Raspberry Piは、Linuxとさまざまなアプリケーションを動かせる驚くべきシングルボードコンピュータ(SBC)である。 Pythonは、学校教育、Web開発、科学研究をはじめ多くの業界で使われている、初心者に優しいプログラミング言語である。 このガイドでは、Raspberry Pi上でPythonのプログラムを自分の手で書き、ライトを点滅させ、ボタンの押下に反応し、センサーを読み取り、データを記録するところまでを説明する。

注意: このチュートリアルは、Raspbianバージョン「April 2018」とPythonバージョン3.5.3で書かれている。異なるバージョンでは、一部の手順が異なる場合がある。

必要な部品

このチュートリアルの内容を進めるには、いくつかのハードウェアが必要になる。

I2Cのサンプルの代替として、はんだ付けや4本のピンへの接続を必要としないQwiicケーブルとQwiic対応TMP102を使うこともできる。

参考になるチュートリアル

Raspberry Piの利用方法にはいくつかの選択肢がある。 最も一般的なのは、フルサイズのデスクトップコンピュータと同じように使う方法であり、モニタ、キーボード、マウスが必要になる(下記に挙げる)。 コストを抑えるため、モニタ、キーボード、マウスを使わないヘッドレスなコンピュータとして使うこともできる。 この構成は、他のコンピュータからコマンドラインインターフェース(CLI)を使う必要があるため、学習の難度がやや上がる。

画像が見づらい場合は、クリックすると拡大表示できる。

オープンソース!

このガイドは、Creative Commons Attribution Share-Alike 4.0 International Licenseの下で提供されている。

OSのインストール

Raspberry Piとのやり取りにはいくつかの選択肢がある。 最初の、そして最も一般的な方法は、通常のデスクトップコンピュータ(の小型版)のように使うことである。 これには、キーボード、マウス、モニタの接続が必要になる。 この構成では、フルのグラフィカルユーザーインターフェース(GUI)が使えるRaspbian with Desktopをインストールするのが最も適している。 Windows、macOS、あるいはUbuntuのような他の一般的なLinuxディストリビューションと同じような使い勝手を求めるなら、これが最良の選択肢である。

選択肢1:キーボード、マウス、モニタを使い、フルサイズのコンピュータとしてRaspberry Piを使う

もう一つの選択肢はヘッドレスな構成である。つまり、モニタ、キーボード、マウスを省くことができる。 これは安く済む方法だが、すべての操作をコマンドラインインターフェースで行う必要が出てくる。 この場合、Raspbian with DesktopまたはRaspbian LiteのどちらかのOSを使うことになる。

選択肢2:別のコンピュータからやり取りする「ヘッドレス」動作のためのRaspberry Piの設定

このガイドでは、どちらの構成でも動作するPythonプログラムの書き方と実行方法を説明する。

選択肢1:フルデスクトップ構成

Raspberry Pi 3 Starter Kit Hookup Guideでは、NOOBS(Raspberry Piの使いやすいグラフィカルOSインストーラー)を使ったセットアップ方法を詳しく解説している。

以降、フルデスクトップ構成に固有の説明は、水色で強調する。

選択肢2:ヘッドレスなPi

キーボード、マウス、モニタを省きたい場合は、Raspbian Liteをインストールできる。 これにより、別のコンピュータからSSHまたはシリアルでPiにターミナル接続できるようになる。 Headless Raspberry Pi Setupでは、グラフィカルインターフェースなしでRaspberry Piをセットアップする方法を解説している。

このチュートリアルの中で、ヘッドレス構成に固有の説明は、黄色で強調する。

Raspberry Pi Starter Kitを使っている場合は、付属のリボンケーブルでPi WedgeをPiに取り付け、FTDIブレイクアウトボードをPi Wedgeに接続できる。 そこから、コンピュータとFTDIブレイクアウトボードをUSBケーブルでつなぐ。 これにより、Headless Piチュートリアルの「シリアルターミナル」の節で説明されている方法で、Raspberry Piへのシリアルターミナルを開けるようになる。

Piの設定

フルデスクトップ構成とヘッドレス構成のどちらを使っている場合でも、新しくインストールしたRaspberry Piにはいくつか基本的な設定手順が必要になる。 これらの手順は、ターミナル(テキストの入出力環境)から簡単に実行できる。

フルデスクトップ: Xウィンドウマネージャー(いわゆるデスクトップ)に自動的にログインしているはずである。 ターミナルを開くには、デスクトップ左上のTerminalアイコンをクリックするだけでよい。 すぐにターミナルウィンドウ内のコマンドプロンプトが表示される。

ヘッドレス: ヘッドレス構成では、すべての操作をターミナルから行う。 シリアルまたはSSHでPiに接続すると、ターミナルにログインプロンプトが表示される。 デフォルトの認証情報を入力する。

  • ユーザー名: pi
  • パスワード: raspberry

コマンドプロンプトが表示される。

設定ツールの実行

コマンドプロンプトから、次のコマンドを入力する。

sudo raspi-config

パスワードの入力を求められた場合は、デフォルトのパスワードraspberryを入力する。

Raspberry Piの設定に関するいくつかの選択肢が表示される。

  • 矢印キーで1 Change User Passwordを選択し、画面の指示に従ってデフォルトのパスワードを変更する。

警告: パスワードの変更を強く推奨する。Piをネットワークに接続したままパスワードを’raspberry’のままにしておくと、そのネットワークにアクセスできる誰もが簡単にPiに侵入できてしまう。

  • 続いて、2 Network Optionsを選択する。
  • 次の画面でN2 Wi-fiを選択し、画面の指示に従ってPiをローカルのWiFiネットワークに接続する(利用可能な場合)。

4 Localisation Optionsを選択すると、キーボードとタイムゾーンのオプションが表示される。

  • I1 Change Localeを選択する。
  • 下にスクロールしてen_GB.UTF-8 UTF-8をハイライトし、スペースキーを押して選択を解除する(アスタリスク「*」が消える)。
  • 自分の言語・国を探してスペースキーで選択する(アスタリスク「*」が表示される)。
  • イギリスに住んでいる場合は、en_GB.UTF-8 UTF-8を選択したままでよい。
  • 米国に住んでいる場合は、おそらくen_US.UTF-8 UTF-8を選択することになる。

  • enterキーを押して変更を保存する。
  • 次の画面で、選択したロケール(米国であればen_US.UTF-8など)をハイライトし、enterキーを押す。

  • 4 Localisation Optionsに戻り、I2 Change Timezoneを選択する。
  • 画面の指示に従って、タイムゾーンを選択する。
  • 再び4 Localisation Optionsに戻り、I3 Change Keyboard Layoutを選択する。
  • 好みのレイアウトを選ぶ(デフォルトのGeneric 105-key (Intl) PCがほとんどの状況でうまく機能する)。
  • 次の画面で、自分の言語・国に対応するレイアウトを選択する。
  • イギリスに住んでいる場合は、English (UK)を選択したままでよい。それ以外の場合はOtherを選択し、enterキーを押して、自分の言語・国を選ぶ指示に従う。米国に住んでいる場合は**English (US)を選択し、次の画面で上にスクロールしてEnglish (US)**をハイライトする。enterキーを押す。

  • The default for the keyboard layoutを選択したままenterキーを押す。
  • 同様に、デフォルトのNo compose keyを選択したままenterキーを押す。
  • Control+Alt+Backspaceの使用について聞かれたらNoを選択したままenterキーを押す。
  • しばらくすると、設定ツールのメインメニューに戻る。

5 Interfacing Optionsを選択する。

  • 必要であればCameraインターフェースとSSHを有効にしておいてよい。
  • SPIを選択し、次の画面でyesを選択し、enterキーを押す。
  • I2Cについても同様に繰り返す。
  • Serialについても同様に繰り返す。

メイン画面に戻り、7 Advanced Optionsを選択する。

  • A1 Expand Filesystemを選択し、enterキーを押す。
  • 再度7 Advanced Optionsに入り、A4 Audioを選択し、1 Force 3.5mm (‘headphone’) jackをハイライトしてenterキーを押す。
  • 右矢印キーでFinishを選択し、enterキーを押す。再起動を聞かれたらYesを選択してenterキーを押す。Raspberry Piが再起動するのを待つ。

シリアルまたはSSHターミナルを使っている場合は、ユーザー名piと先ほど設定したパスワードで再度ログインする。

Python 3を使う

デフォルトでは、Raspbian(2018年4月版以前のStretch)はPython 2を使う。 ただし、バージョン2と3のどちらもあらかじめインストールされている。 ターミナルでpythonと入力したときに常にPython 3が使われるようにするには、わずかな変更を一つ加えるだけでよい。

ターミナルウィンドウで、次のコマンドを入力する。

python --version

デフォルトで使われているバージョンが表示される。 たとえばPython 2.7.13のように表示されるかもしれない。 OSがデフォルトでPython 2を使っている場合は、Python 3のインストールを使うように変更する必要がある。 ログインするたびにPython 3が使われるようにしたい。

次のコマンドを入力する。

nano ~/.bashrc

.bashrcは、ユーザーのホームディレクトリ(この場合はユーザーpi)にあるファイルである。 このファイルは、そのユーザーがターミナルを開くたび(あるいはSSHやシリアルでログインするたび)に実行されるシェルスクリプトとして動作する。 ユーザー環境をカスタマイズするのに役立ち、すでに他のコマンドがいくつか書かれているはずである。

ファイルの末尾までスクロールし、次のコマンドを追加する。

alias python='/usr/bin/python3'

ctrl+xnanoを終了し、ファイルを保存するか聞かれたらyキーを押し、続いてenterキーを押す。 新しいコマンドを反映させるためにログアウト・ログインし直す代わりに、次のコマンドで.bashrcスクリプトの内容をそのまま実行できる。

source ~/.bashrc

もう一度Pythonのバージョンを確認する。

python --version

Python 3の何らかのバージョンが使われているはずである。

pipのインストール

フルデスクトップ: Raspbianのフルデスクトップ版を使っている場合、pipはすでにインストールされているはずである。

ヘッドレス: Raspbian Liteを使っている場合、Pythonのパッケージマネージャーであるpipはあらかじめインストールされていない。 そのため、次のコマンドでインストールする必要がある。

sudo apt-get update
sudo apt-get install python3-pip

聞かれたらyキーを押す。

Python 3でpipを使うにはpip3コマンドを使う必要がある点に注意してほしい。 ただし、.bashrcファイルを変更してpip3の代わりにpipを使えるようにできる。このチュートリアルの以降の説明ではpipを使った例を示す。

nano ~/.bashrc

ファイルの末尾までスクロールし、次のコマンドを追加する。

alias pip=pip3

ctrl+xnanoを終了し、yenterを押す。次のコマンドで.bashrcスクリプトを実行する。

source ~/.bashrc

これで、pipコマンドを使ってPythonパッケージをインストールできるようになったはずである。

Hello, World!

Pythonの最も面白い特徴の一つは、インタプリタ型の言語であることだ(正確には、Pythonのスクリプトはまずバイトコードにコンパイルされ、そのバイトコードがインタプリタによって実行される)。 つまり、プログラムを実行するために別途コンパイルの工程(プログラムを機械語に翻訳する工程)を行う必要がない。 それどころか、インタラクティブモードと呼ばれる形でインタプリタを実行することもできる。 これにより、コマンドを一行ずつ試すことができる。

まずは、Pythonに「Hello, World!」という文をターミナルに出力させてみる。 最初はインタプリタから、続いてファイルを作成してプログラムとして実行する。 これにより、Pythonとやり取りする主な二つの方法を確認できる。

「Hello, World!」というフレーズの由来が気になる場合は、このWikipediaの記事に簡潔ながら興味深い歴史が書かれている。

インタプリタを始める

ターミナルから、次のコマンドを入力してPythonインタプリタを起動する。

python

3つの不等号記号>>>からなる、これまでとは異なるコマンドプロンプトが表示されるはずである。

次のコマンドを入力する。

print("Hello, World!")

enterキーを押すと、Hello, World!というフレーズが表示されるはずである。

これで完了である。最初のPythonプログラムを実行できた。

インタプリタを終了するには、次のように入力する。

exit()

ファイルからPythonプログラムを実行する

Pythonインタプリタでコマンドを一行ずつ入力・実行することもでき、これはさまざまなコマンドを試すのに(あるいは電卓代わりに使うのに)非常に便利である。 ただ、多くの場合、コマンドを一つ以上のファイルにまとめて保存し、まとめて実行したくなるはずである。

最も簡単な方法は、ターミナルからファイルを作成することだが、RaspbianのグラフィカルエディタであるLeafpad(Raspberry Piアイコンをクリックし、アクセサリ > テキストエディタから開く)を使ってもよい。

ターミナルで、次のコマンドを入力する。

nano hello.py

これにより、ホームディレクトリ(/home/pi)にhello.pyという名前のファイルが作成され、nanoプログラムで編集が始まる。

このファイルの1行目に、次のように入力する。

print("Hello, World!")

保存して終了する(ctrl+x、続いてyenter)。 Linuxのコマンドプロンプトに戻り、次のコマンドを入力する。

python hello.py

これで、hello.pyファイルにあるコードが実行されるはずである。 今回の場合、コンソールにおなじみのHello, World!というフレーズが表示されるはずである。

注意: ちなみに、筆者はスクリーンショットの間でclearコマンドを使ってターミナルをクリアしている。

ここまでの内容をまとめると、pythonコマンド単体でインタラクティブなインタプリタセッションを開始し、リアルタイムにコマンドを入力できる。 python <FILE>.pyのようにファイルを指定すると、Pythonインタプリタはインタラクティブなセッションを提供する代わりに、そのファイルにあるコマンドを実行する。

インタプリタがファイルの中身を実行する上で、.pyという拡張子は必須ではない点に注意してほしい。 とはいえ、ファイルを整理しておく上では非常に役立つ。.pyで終わるファイルを見れば、中にPythonのコードが入っているとすぐにわかるからである。 また、後で扱うモジュールを作る際にも*.py*という拡張子が必要になる。

開発環境

Pythonのプログラムを作る最もシンプルな方法は、テキストエディタ(nano、vim、emacs、Midnight Commander、Leafpadなど)でコードを書き、保存し、ターミナルからpython <FILE>.pyコマンドで実行することである。 このガイドの残りの部分も、テキストエディタとコマンドラインを使って進めて構わない。

コード開発には統合開発環境(IDE)を好むユーザーもいる。 IDEには、シンタックスハイライト、コード補完、ワンクリック実行、デバッグのヒントなど、数多くの利点がある。 ただし、ほとんどのIDEはグラフィカルインターフェースを必要とするため、Raspbianのフルデスクトップ版を使う必要がある。

注意: Raspbianには標準で3つのPython向けIDE、IDLE、Geany、Thonnyが同梱されている。以下でそれぞれを簡単に紹介するので、これらでも他の好みのテキストエディタやIDEでも自由に使ってほしい。

IDLE

IDLEは、長年にわたりRaspbianで使えるデフォルトのPythonエディタである。 よい点として、インタプリタが内蔵されており、コードをテストするためにコマンドを一つずつ実行できる。 悪い点は、行番号が表示されないことと、Pythonにしか対応していないことである(とはいえ、ここではPythonが目当てなのでちょうどよいとも言える)。

左上のRaspberry Piのロゴを選択し、*Programming > Python 3 (IDLE)*をクリックしてIDLEを開く。 Pythonのインタラクティブインタプリタが表示されるはずである。

プログラムを書くには、File > New Fileに進む。コードを入力する。

File > Save As…をクリックしてコードをPythonファイルに保存する(.pyの拡張子を忘れないように)。 Run > Run Moduleをクリックしてプログラムを実行する。

Geany

Geanyは、多くの言語に対応した、初心者に優しい優れたIDEである。 ただし、Python用のインタラクティブインタプリタを備えて起動するわけではない。 左上のRaspberry Piのロゴをクリックし、Programming > Geanyを選択してGeanyを開く。 ファイルエディタのペインでコードを書く。

コードを保存する。ファイル名の末尾が*.py*になっていることを確認する。

デフォルトでは、Geanyはコードの出力を表示するために新しいウィンドウを開こうとするが、Raspberry Piでは動作しない場合がある。 これを、代わりにTerminalペイン内で実行するように変更できる。 Edit > Preferencesをクリックする。Terminalタブを選択し、Execute programs in the VTEを有効にする。 enterキーを押して設定を保存し、Preferencesウィンドウを閉じる。

Build > Executeをクリックする(あるいは紙飛行機のアイコンをクリックする)とコードが実行される。 プログラムの出力がGeanyのTerminalペインに表示されるはずである。

Thonny

最後に紹介するThonnyも、Raspbianにあらかじめ用意されている使いやすい優れたIDEである。 Pythonに特化しており、プログラムを読み込むとインタラクティブな環境が使える。 Raspberry Piのアイコンをクリックし、続いてProgramming > Thonny Python IDEでThonnyを起動する。

上側のペインにプログラムを書き、*File > Save as…*をクリックして保存し、Run > Run current scriptをクリックしてプログラムを実行する。 出力は下側のインタプリタペインに表示される。

筆者の見解: プログラミングの旅を始めたばかりであれば、グラフィカルなIDEにはThonnyを、ヘッドレスなRaspberry Pi構成ではnanoを使うことを推奨する。

Pythonでプログラミングする

このチュートリアルの大部分は、Raspberry Piに接続したハードウェアの制御に焦点を当てている。 これを実現するために、Pythonというプログラミング言語を使う。 そのため、リテラル、変数、演算子、制御フロー、スコープ、データ構造といったPythonの基礎知識にある程度馴染んでおく必要がある。 Pythonへの習熟度に応じて、次のように読み進めることを推奨する。

  • 馴染みがない: 推奨されている資料を読み、チャレンジ課題に取り組む
  • ある程度馴染みがある: チャレンジ課題に取り組み、詰まったときに資料を参照する
  • 十分馴染みがある: このセクション全体を読み飛ばして構わない

車輪の再発明はしたくないので(Pythonについては優れたチュートリアルや書籍がすでに数多くある)、次の二つの資料を参照する。

  • A Byte of Python — Python言語への無料の、よくまとまった入門書。概念が例とともに簡潔に説明されている。紙の本もこちらで購入できる(著者の支援にもなる)。
  • The Python Documentation — Python言語をより技術的に、より深く扱ったチュートリアルとリファレンスガイド集。概念の理解に行き詰まったときはこちらを参照するとよい。

注意: ブラウザによっては、“A Byte of Python“へのリンクの一部がページ内の正しい位置に開かないことがある。その場合は、ページを再読み込みすれば正しい位置に移動するはずである。

実際に試そう! ここで示すコード例はどれも、それぞれ独立したプログラムとして実行できる。インタプリタに直接入力するか、(一つずつ)ファイルにコピーしてPythonで実行してみてほしい。

ここで扱う内容よりも多くの例や練習問題を使ってPythonのプログラミングを学びたい場合は、Non-Programmer’s Tutorial for Python 3learnpython.orgGoogle’s Python Classといった無料のサイトも参考にしてほしい。 このセクションでPython言語の基礎を扱ったら、いよいよライトの点滅、センサーの読み取り、モーターの制御に進む。

コメント

コメントとは、シャープ記号(ハッシュ記号)#の右側にあるテキストのことである。 Pythonインタプリタはこのテキストを無視するため、自分自身や他のプログラマ向けにコードの内容についてのメモを書くのに便利である。

例:

# This is a comment and is not seen by the interpreter
print("Hello, World!")

参考になる資料:

リテラル

リテラル(リテラル定数とも呼ばれる)は、整数(例:42)、浮動小数点数(例:6.23)、文字列(例:“Hello, World!”)といった固定値のことである。 文字列は、シングルクォート(’ ’)またはダブルクォート(“ “)で囲む必要がある点に注意してほしい。

例:

print(42)
print("hi")

参考になる資料:

チャレンジ: 先ほど書いたprint("Hello, World!")のプログラムを、自分の名前を出力するように変更してみよう。

print("your name")

変数

変数とは、値を変更できる入れ物である。 数値や文字列を変数に保存し、後でその値を取り出すことができる。

例:

number = 42
print(number)

参考になる資料:

チャレンジ: 自分の名前を変数に保存し、その変数の値をターミナルに出力してみよう。

name = "your name"
print(name)

論理行

ここまで、プログラムには1行につき一つの式を書いてきた。たとえば次のようになる。

message = "hello!"
print(message)

この2行は、セミコロン;で区切ることで1行にまとめることができる。

message = "hello"; print(message)

この二つのプログラムはまったく同じように動作する。 とはいえ、コードを読みやすくするために、物理的な1行につき論理的な行を一つだけ書くことがよく推奨される。

参考になる資料:

ユーザー入力

input()関数を使うと、ユーザーにターミナルへの入力を求めることができる。 これにより、ユーザーは何らかのテキスト(数値を含む)を入力し、enterキーを押してそのテキストを送信するよう促される。 送信されると、input()関数はそのテキストを読み取り、文字列として返す。この値は変数に保存できる。

括弧の間にあるもの(引数と呼ばれる)は、ユーザー入力を受け付ける前に画面に表示される。

関数とは、名前で呼び出せるコードのまとまりのことである。 たとえばprint()は、引数を受け取ってターミナルに出力する関数である。 下の例で、print()に渡す二つの引数がカンマで区切られていることに注目してほしい。 この場合、print()は異なる文字列(や変数)を1行に順番に出力する。

int()関数を使うと、文字列を整数に変換できる(その文字列が整数として解釈できる場合)。

例:

message = input("Type a message to yourself: ")
print("You said:", message)


number = int(input("Type a number:"))
print("You entered:", number)

参考になる資料:

チャレンジ: ユーザーの名(input()の呼び出し)と姓(別のinput()の呼び出し)を尋ね、1行にまとめて出力するプログラムを書いてみよう。実行例は次のようになる。

first_name = input("Enter your first name: ")
last_name = input("Enter your last name: ")
print("Full name:", first_name, last_name)

インデント

Pythonでは、行頭の空白(スペースの数)が重要な意味を持つ。 一つのまとまりを構成する文は、同じレベルのインデント(行頭の空白の量)でなければならない。 これは、制御フロー文(ifforなど)や関数を扱うときに重要になる。

他の言語でプログラムを書いたことがあれば、波括弧{}に馴染みがあるかもしれない。 他の言語では、この波括弧に挟まれたコードが一つのまとまり(ブロック)を構成する。 Pythonでは、コードのまとまり(ブロック)は、各行のインデントのレベルによって示される。

例:

answer = "yes"
guess = input("Is the sky blue? ")
if guess == answer:
    print("Correct!")
else:
    print("Try again")

if文については後で扱うが、print()関数がインデントされていることに注目してほしい。これにより、if文とelse文の下にそれぞれ別々のコードのまとまりが形成されている。

参考になる資料:

演算子

演算子とは、インタプリタに対し、1つ以上のデータに数学的、関係的、論理的な操作を行い、結果を返すよう指示する記号のことである。

数学演算子は、数値に対する基本的な演算を行う。

演算子説明
+2つの数値を加算する2 + 35を返す
-一方の数値からもう一方を減算する8 - 53を返す
*2つの数値を乗算する4 * 624を返す
**1つ目の数値を2つ目の数値でべき乗する2 ** 416を返す
/1つ目の数値を2つ目の数値で除算する5 / 41.25を返す
//2つの数値を除算し、最も近い整数に切り下げる(除算と切り捨て)5 // 41を返す
%1つ目の数値を2つ目の数値で除算し、余りを返す(剰余)19 % 83を返す

論理演算子は、2つの数値を比較し、ブール値TrueまたはFalse)のいずれかを返す。

演算子説明
<1つ目の数値が2つ目より小さければTrue、そうでなければFalse5 < 3Falseを返す
>1つ目の数値が2つ目より大きければTrue、そうでなければFalse5 > 3Trueを返す
<=1つ目の数値が2つ目以下であればTrue、そうでなければFalse2 <= 8Trueを返す
>=1つ目の数値が2つ目以上であればTrue、そうでなければFalse2 >= 8Falseを返す
==1つ目の数値が2つ目と等しければTrue、そうでなければFalse6 == 6Trueを返す
!=1つ目の数値が2つ目と等しくなければTrue、そうでなければFalse6 != 6Falseを返す

複合論理演算子は、ブール値を入力として受け取り、ブール値を返す。

演算子説明
not値を反転する(TrueFalseに、その逆も同様)x = False; not xTrueを返す
and両方のオペランドがTrueであればTrue、そうでなければFalsex = True; y = False; x and yFalseを返す
orいずれかのオペランドがTrueであればTrue、そうでなければFalsex = True; y = False; x or yTrueを返す

ビット演算子は、与えられた数値のビット(1と0)に対して二進演算を行う。ビット演算について詳しくは、2進数のチュートリアルを参照してほしい。

演算子説明
&両方のオペランドの対応するビットがともに1であるビット位置に1を返す(ビットAND)3 & 51を返す
|いずれかまたは両方のオペランドの対応するビットが1であるビット位置に1を返す(ビットOR)3 | 57を返す
^いずれか一方だけの対応するビットが1であるビット位置に1を返す(ビットXOR)3 ^ 56を返す
~与えられた数値のビットを反転する(ビットNOT)~5-6を返す
<<1つ目の数値のビットを、2つ目の数値で指定されたビット数だけ左にシフトする5 << 220を返す
>>1つ目の数値のビットを、2つ目の数値で指定されたビット数だけ右にシフトする5 >> 21を返す

参考になる資料:

チャレンジ: ユーザーに2つの整数を尋ね、それらの加算、減算、乗算、除算、剰余を出力してみよう。たとえば67を入力した場合、出力は次のようになるはずである。

First number: 6
Second number: 7
13
-1
42
0.8571428571428571
6
x = int(input("First number: "))
y = int(input("Second number: "))
print(x + y)
print(x - y)
print(x * y)
print(x / y)
print(x % y)

制御フロー

Pythonインタプリタは、コードの文をファイルの上から下へ、順番に実行していく。 もちろん、この通常の順次的な流れを崩すために何らかの制御フロー文を使う場合は別である。

以下の例ではrange(x, y)関数を紹介する。この関数は、1つ目の数値x(を含む)から2つ目の数値y(を含まない)までの数値のリストを生成する。

説明
if elif else条件が真であれば、if文の下にあるコードのまとまりを実行する。そうでなければ、1つ以上のelse ifelif)文の条件が真かどうかを調べる。いずれかが真であれば、その下のコードのまとまりを実行する。それ以外の場合は、else文の下にあるコードのまとまりを実行する。elif文とelse文は省略できる。number = 42
guess = int(input("Guess a number between 1-100: "))
if guess == number:
print("You win!")
elif guess < number:
print("Nope")
print("Too low")
else:
print("Nope")
print("Too high")
print("Run the program to try again")
whilewhileループは、条件が真である限り、その下にあるコードのまとまりを繰り返し実行する。counter = 15
while counter >= 5:
print(counter)
counter = counter - 1
for..in数値やオブジェクトの列を反復処理する。forループで宣言した変数は、ループの各繰り返しで、その数値(やオブジェクト)のいずれかの値を取る。for i in range(1, 11):
print(i)
breakループから抜け出すにはbreak文を使う。while True:
message = input("Tell me when to stop: ")
if message == "stop":
break
print("OK")
continuecontinue文breakと似た働きをするが、ループを抜ける代わりに、現在の繰り返しを中断してループの先頭に戻る。for i in range(1, 6):
if i == 3:
continue
print(i)

参考になる資料:

チャレンジ: 1から20まで数え上げて整数を出力するプログラムを書いてみよう。ただし、3の倍数(3、6、9など)の場合は、代わりに“fizz“という単語を出力する。出力は次のようになるはずである。

for i in range(1, 21):
    if i % 3 == 0:
        print("fizz")
    else:
        print(i)

関数

関数を使うと、コードのまとまりに名前を付け、その名前を呼び出して再利用できるようになる。 パラメータと呼ばれる変数を通じて、関数にデータを渡すことができる(関数定義の中の変数をパラメータ、実際に渡されるデータそのものを引数と呼ぶ)。 return文を使えば、呼び出し元にデータを返すこともできる。

関数定義の例は次のようになる。

def functionName(parameter1, parameter2):
    # Code goes here

コードの他の場所からこの関数をfunctionName(argument1, argument2)のように呼び出せる。

関数定義の中で宣言された変数はローカルスコープを持つと呼ばれる。 つまり、その関数の外からはアクセスできない。 プログラムのトップレベル(関数、ループ、クラスの外側)で宣言された変数はグローバルスコープを持つと呼ばれ、プログラムのどこからでも(関数の内部を含めて)アクセスできる。

重要:作成した関数は、使うに定義しておく必要がある。 コード中のより上の位置(def定義より前)で関数を呼び出そうとすると、次のようなエラーが出るはずである。

NameError: name 'FUNCTION_NAME' is not defined

Pythonには、あらかじめ用意された多くの組み込み関数がある(すでにprint()int()range()の3つを見た)。 これらの関数の一覧はThe Python Tutorialで確認できる。

例:

def add(x, y):
    sum = x + y
    return sum

print(add(2, 3))

参考になる資料:

チャレンジ: 次のコードから始めて、整数をパラメータ(n)として受け取り、1からnまで(nを含む)のすべての整数の和を計算して返すsumTo()関数を実装しよう。入力のnは常に正の整数であると仮定してよい(負の数の処理は考えなくてよい)。

def sumTo(n):
    # YOUR CODE GOES HERE

# Should be 1
print(sumTo(1))

# Should be 45
print(sumTo(9))

# Should be 5050
print(sumTo(100))
def sumTo(n):
    sum = 0
    for i in range(1, n + 1):
        sum = sum + i
    return sum
    
# Should be 1
print(sumTo(1))

# Should be 45
print(sumTo(9))

# Should be 5050
print(sumTo(100))

オブジェクト

オブジェクトについてはまだ触れていなかったが、実のところ、ここまでずっとオブジェクトを使ってきた。 Pythonの秘密は、あらゆるものがオブジェクトであるという点にある。 そう、関数も整数も含めて、すべてがオブジェクトなのである。

オブジェクトとは、単にコンピュータのメモリのどこかに保存されたデータの集まりである。 プログラミング言語においてオブジェクトを特別なものにしているのは、情報を保持する能力、動作を実行する能力を併せ持っている点にある。 オブジェクトがデータを保持する様子はすでに見た(たとえばa = 3は、aが整数オブジェクトであり、3という情報を保持していることを意味する)。 では、オブジェクトに動作を実行させるにはどうすればよいだろうか。

オブジェクトには、そのクラスによって定義された一連の関数が与えられる。 クラスは設計図のような役割を果たし、そのオブジェクトが何をできて何をできないか、どんな情報を保持できて保持できないかを規定する。 クラス(あるいはオブジェクト)の中にある関数のことをメソッドと呼ぶ。

たとえば、組み込みのis_integer()メソッドを使えば、浮動小数点数が整数かどうかを調べることができる。 このメソッドはfloatオブジェクトからしかアクセスできない点に注意してほしい。 is_integer()を単体で呼び出すことはできないので、ドット記法(.)を使い、floatオブジェクト自身にis_integer()メソッドを呼び出させる。

例:

a = 3.0
b = 7.32

print(a.is_integer())
print(b.is_integer())

整数をfloatとして扱うことはできない点にも注意してほしい。 たとえばc = 8と書けば、cは整数であってfloatではない。 cが整数であれば、整数には.is_integer()メソッドが存在しないため、c.is_intger()の呼び出しは失敗する(インタプリタのエラーになる)。試してみてほしい。 整数の値を強制的に浮動小数点数にするには、a = 3.0のときと同様に、末尾に.0を付け加えるだけでよい。

参考になる資料:

チャレンジ: 次のコードを変更し、my_stringに格納されているフレーズをすべて小文字に変換してターミナルに出力してみよう。ヒント:Pythonリファレンスガイドの文字列メソッドを確認し、これを行う組み込みメソッドを探してみよう。

my_string = "THiS iS A TEst!"

# Should print "this is a test!"
# YOUR CODE GOES HERE
my_string = "THiS iS A TEst!"

# Should print "this is a test!"
print(my_string.lower())

データ構造

変数オブジェクトに加えて、Pythonにはデータを保存する方法がさらに4つある。リストタプル辞書セットである。 これらの構造はいずれも関連するデータの集まりを保持し、それぞれ扱い方が少しずつ異なる。

構造説明
リストリストは順序付けられた項目の並びである。角括弧[]とインデックスを使ってリスト内の項目にアクセスできる(例:list[2])。インデックスは0始まりであるため、list[0]でリストの最初の項目にアクセスすることになる。リストは変更可能であるため、ミュータブルであると言われる。my_list = [1, 5, 73, -3]
my_list[2] = -42

# Get third item in list
print(my_list[2])

# Get all but first item in list
print(my_list[1:])
タプルタプルはリスト(順序付けられた集合)と同じように動作する。違いは、タプルがイミュータブルであり、一度設定した値を変更できない点にある。タプルは通常、括弧()で指定される。括弧は必須ではないが、コードを読みやすくするために付けることが強く推奨される。my_tuple = ("bird", "plane", 5, "train")

# Get one item from the tuple
print(my_tuple[0])

# Get a tuple of second and third items
print(my_tuple[1:3])

# Can't do this because tuples are immutable!
my_tuple[1] = "skyscraper"
辞書辞書は、対応付けられたキーのペアの集まりである。電話帳の仕組みに似ている。名前(キー)を調べて、その電話番号(値)を見つけるようなものである。辞書は波括弧{}で定義され、キーと値のペアはコロン:で区切られる。辞書はミュータブルである。my_dictionary = {"name": "Bruce", "aka": "The Hulk"}
my_dictionary["name"] = "Banner"
print(my_dictionary["name"])
セットセットは、重複した要素を持たない、ミュータブルで順序を持たない集まりである。セットは、ある項目がその中に含まれているかどうかを判定するために最適化されている(項目の順序は気にしなくてよい)。Pythonで何らかの集合論を扱いたい場合、セットが役立つ。my_set_1 = set(["orange", "banana"])
my_set_2 = set(["apple"])
my_set_2.add("orange")

print(my_set_1)
print(my_set_2)
print("apple" in my_set_2)
print("strawberry" in my_set_2)
print(my_set_1.union(my_set_2))
print(my_set_1.intersection(my_set_2))

参考になる資料:

チャレンジ: 次のコードから始めて、リストとして渡された数値の平均を計算するaverage()関数を実装しよう。ヒント:len()関数を使うとよいだろう。

def average(num_list):
    # YOUR CODE GOES HERE

# Should print 5.0
list_1 = [4, 7, 9, 0]
print(average(list_1))

# Should print 4.406333333333
list_2 = [-3.2, 6.419, 10]
print(average(list_2))

# Should print 42.0
list_3 = [42]
print(average(list_3))
def average(num_list):
    avg = 0
    for n in num_list:
        avg = avg + n
    avg = avg / len(num_list)
    return avg

# Should print 5.0
list_1 = [4, 7, 9, 0]
print(average(list_1))

# Should print 4.406333333333
list_2 = [-3.2, 6.419, 10]
print(average(list_2))

# Should print 42.0
list_3 = [42]
print(average(list_3))

モジュール

モジュールは、コードを再利用しプログラムを整理するもう一つの方法である。 モジュールは単に、メインプログラムにインポートされるファイルである。 モジュールをインポートすると、オブジェクトとほぼ同じ方法で、つまりドット記法で定数や関数にアクセスして使うことができる。

例:

次の内容をstringmod.pyとして保存する。

a = 42

def string_to_list(s):
    c_list = []
    for c in s:
        c_list.append(c)
    return c_list

stringmod.pyと同じフォルダで、次のコードを実行する(インタプリタでもファイルに保存してもよい)。

import stringmod

s = "Hello!"
print(stringmod.a)
print(stringmod.string_to_list(s))

参考になる資料:

チャレンジ: Pythonには、プログラムにインポートできる標準モジュールがいくつか付属している。その一つがmathモジュールで、import mathで使うことができる。mathモジュールにある定数と関数を使って、次の操作を行ってみよう。

  • 3.456の天井関数を出力する(4になるはず)
  • 9216の平方根を出力する(96.0になるはず)
  • 半径2の円の面積を計算して出力する(12.566370614359172になるはず)
import math

print(math.ceil(3.456))
print(math.sqrt(9216))
print(math.pi * (2 ** 2))

バグを見つけて直す

プログラムがすぐに正しく動くことはほとんどないので、気に病む必要はない。 コード中の問題を見つけて修正する技術と知識はデバッグと呼ばれる。 最も役立つデバッグツールは、Python標準の出力である。 コードに問題があれば、たいていエラーの場所と内容を教えてくれる。

たとえば、次のコード片を見てみよう。 forループの下にあるコードのインデントを忘れてしまっている。

a = [1, 2, 3, 4]

for n in a:
print(n)

このコードを実行すると、Pythonインタプリタが4行目あたりでインデントされたコードを期待していたことを親切に教えてくれる。

  File "test_01.py", line 4
    print(n)
        ^
IndentationError: expected an indented block

もう一つ例を見てみよう。エラーを見つけられるだろうか。

a = [1, 2, 3, 4]

for n in a
    print(n)

forループの後のコロンを忘れている。インタプリタは次のように教えてくれる。

  File "test_01.py", line 3
    for n in a
             ^
SyntaxError: invalid syntax

「Invalid syntax」というのは少し漠然としているが、コロンの欠落、括弧の数の誤り、ダブルクォートの代わりにシングルクォートを使っているなど、何かがおかしい箇所として3行目あたりを見るよう教えてくれている。

コードが実行はされるものの、期待した値が出力されない場合はどうすればよいだろうか。 これはプログラマ自身が見つけて直すべき問題である。 コードのあちこちにprint()文を追加すると、どこで問題が起きたのかを突き止める助けになる。

次のコードを実行してみてほしい。

for i in range(1, 10):
    if i == 10:
        print("end")

なぜ“end“がターミナルに表示されないのだろうか。 この問題を診断するため、print()文を追加して何が起きているか見てみよう。

for i in range(1, 10):
    print(i)
    if i == 10:
        print("end")

これを実行すると、iの値が順番に出力されるのがわかる。

なるほど。iは10に到達しないことがわかる。 これは、range()関数の2つ目の数値が「含まれない」ためである。 10まで数えたい場合は、次のように変更する必要がある。

for i in range(1, 11):
    if i == 10:
        print("end")

print()に感謝である。

参考になる資料:

チャレンジ: 次のプログラムに含まれる7つのエラーを見つけよう。エラーを修正して実行すると、1つ目の引数までの数値を出力し、2つ目の引数の倍数を“buzz“という単語に置き換えて出力するはずである。

print("Count to 7, buzz on 2's")            
buzz(7, 2)

print('Count to 10, buzz on 5's")
buzz(10, 5)

def buzz(n):
    for i in range(1, n):
        if i % z = 0:
            print("buzz")
        else
            print(n)

正常に動作した場合のプログラムの実行結果は次のとおりである。

def buzz(n, z):                     # Added z as second parameter
    for i in range(1, n + 1):       # n should be n + 1
        if i % z == 0:              # Change single equal sign to double equal sign
            print("buzz")
        else:                       # Add colon
            print(i)                # Change 'n' to 'i'

print("Count to 7, buzz on 2's")
buzz(7, 2)                          # Move calls to buzz() underneath function definition

print("Count to 10, buzz on 5's")   # Change single quote to double quote
buzz(10, 5)

実験1:デジタル入出力

組み込みの世界では、多くの開発者がまず最初に手を付けたがるのがLEDの点滅である。 これはある意味、組み込み電子工作における「Hello, World!」である。 コードを実行してハードウェアを制御できることを(しかも即座に、たいてい楽しい形で)証明してくれる。 このセクションではまずLEDを点滅させ、続いてプッシュボタンへの反応も加えてみる。

参考になるチュートリアル

  • Python (RPi.GPIO) API — このチュートリアル全体でハードウェア制御に使うRPi.GPIOモジュールの概要
  • 電気とは何か — 電気の仕組みの基礎を扱う
  • 回路とは何か — 電気が回路の中をどう流れるかを説明する
  • 極性 — LEDを回路に特定の向きで組み込む必要がある理由を示す
  • ブレッドボードの使い方 — ブレッドボードはプロトタイピングに便利で、このチュートリアルでも使う

Raspberry Piのピン配置

Raspberry Piが他の多くのコンピュータより電子工作の学習に向いている理由の一つは、簡単にアクセスできる複数のピンの電圧を制御できる点にある。 Piを縦向きにして正面から見ると(下の写真のとおり)、右側に40ピンのヘッダーがある。 このヘッダーには、3.3V、5V、グラウンド、そして数多くの汎用入出力(GPIO)ピンの出力が用意されている。

写真に示すとおり、ピン1はヘッダーの左上にある。 ピン1をこの位置に置くと、それぞれのピンが何に使われているかがわかる。

ハードウェアの接続

Raspberry PiとLED・ボタンを直接接続することもできるし、SparkFun Pi Wedgeを経由してブレッドボード上で接続を楽にすることもできる。 重要なのは、コードの中ではGPIO番号を使っているという点である(Pi Wedge上ではGxと表記されている。xはGPIO番号)。 これらのGPIO番号は、上のGPIOピン配置図の中で黄色の枠に示されている。

  • GPIO12(ピン32)を330Ω抵抗に接続し、抵抗をLEDに接続する
  • GPIO4(ピン7)をボタンに接続する
  • Fritzing図のとおりに電源(3.3V)とグラウンド(GND)を接続する

図が見づらい場合は? 画像をクリックするとフルサイズの表示になる。

Pi Wedgeがあれば、ブレッドボード上の外部ハードウェアへの接続が楽になる。 なくても、ジャンパー線でRaspberry Piに直接接続することはできる。

Pi Wedgeを介した接続:

Raspberry Piに直接接続:

注意: LEDの向きは重要である。電流はLEDの中を一方向にしか流れないため、リード線の向きに注意してほしい。LEDの長いリード線は、330Ω抵抗と同じ行に接続する必要がある。

注意: ボタンを初めて使う場合、少し戸惑うかもしれない。対角にあるピンは常に接続されているのに対し、同じ側にあるピン同士はボタンを押したときだけ接続される。

注意: フルサイズのブレッドボードを使っている場合、電源レールは中央で分割されている。そのため、電源レール全体に電力を行き渡らせるには、両半分をつなぐ必要がある。下の写真で、ジャンパー線を使って電源レールの両半分をつなぐ方法を確認してほしい。

コード パート1:LEDを点滅させる

Raspbianのバージョンによっては、RPi.GPIOパッケージをインストールする必要があるかもしれない(たとえばRaspbian Liteには一部のPythonパッケージがあらかじめ入っていない)。 ターミナルで次のように入力する。

pip install rpi.gpio

新しいファイルに、次のコードを入力する。

import time
import RPi.GPIO as GPIO

# Pin definitions
led_pin = 12

# Suppress warnings
GPIO.setwarnings(False)

# Use "GPIO" pin numbering
GPIO.setmode(GPIO.BCM)

# Set LED pin as output
GPIO.setup(led_pin, GPIO.OUT)

# Blink forever
while True:
    GPIO.output(led_pin, GPIO.HIGH) # Turn LED on
    time.sleep(1)                   # Delay for 1 second
    GPIO.output(led_pin, GPIO.LOW)  # Turn LED off
    time.sleep(1)                   # Delay for 1 second

ファイルを保存する(筆者はblink.pyという名前にした)。ターミナルから次のように入力してコードを実行する。

python blink.py

LEDが1秒ごとに点滅し始めるはずである。

LEDの点滅を見飽きたら、ctrl + cを押してプログラムを終了する。

トラブルシューティング: 「ModuleNotFoundError: No module named ‘rpi’」というメッセージが表示された場合は、ターミナルでpip install RPi.GPIOと入力してRPi.GPIOパッケージをインストールする必要がある。

注目すべきコード:

Raspberry Piからハードウェアを制御するために、RPi.GPIOモジュールを利用する。 このモジュール(他の言語で言うところの「ライブラリ」)は、ピンの切り替えや他のハードウェアとの通信を助けるために特別に設計されている。 ありがたいことに、Raspbianにはあらかじめパッケージ化されて含まれている。

最初の2行でモジュールをインポートしているが、そこにいくつか手を加えている。 まず、asというキーワードを使った。

import RPi.GPIO as GPIO

RPi.GPIOはモジュールの名前である。 as GPIOと書くことで、プログラムの残りの部分でこのモジュールをどう呼ぶかを変えている。 これにより、次のように書けるようになる。

GPIO.output(led_pin, GPIO.HIGH)

もっと長い次のような書き方をしなくて済む。

RPi.GPIO.output(led_pin, RPi.GPIO.HIGH)

コーディング中に警告を無効にするのは一般的にはよい考えではないが、次の行を加えた。

GPIO.setwarnings(False)

これがないと、blinkプログラムをもう一度実行しようとしたときにインタプリタから警告が出る。

blink.py:14: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  GPIO.setup(led_pin, GPIO.OUT)

これは、プログラムを終了した際にGPIO 12ピンをきちんと停止させなかったためである。 これを行うには、プログラムの末尾にGPIO.cleanup()の行を追加すればよい。 ただし、今回のプログラムは永遠に実行し続けるように書いたため、プログラムを止めるには中断する必要があり(cleanup()の呼び出しは決して行われない)、当面は警告を無視するだけで十分である。

チャレンジ: プログラムを変更し、LEDが心拍のように点滅するようにしてみよう。短い点滅を2回連続で行い、その後に長めの間隔を空ける。

import time
import RPi.GPIO as GPIO

# Pin definitions
led_pin = 12

# Suppress warnings
GPIO.setwarnings(False)

# Use "GPIO" pin numbering
GPIO.setmode(GPIO.BCM)

# Set LED pin as output
GPIO.setup(led_pin, GPIO.OUT)

# Blink forever
while True:
    GPIO.output(led_pin, GPIO.HIGH)
    time.sleep(0.2)
    GPIO.output(led_pin, GPIO.LOW)
    time.sleep(0.2)
    GPIO.output(led_pin, GPIO.HIGH)
    time.sleep(0.2)
    GPIO.output(led_pin, GPIO.LOW)
    time.sleep(1)

コード パート2:PWMでLEDをフェードさせる

LEDのオン・オフの切り替え方は見たが、明るさのレベルを制御するにはどうすればよいだろうか。 LEDの明るさは、流れる電流の量を制御することで決まるが、それにはさらに多くのハードウェア部品が必要になる。 簡単な方法として、目で追えないほど速くLEDを点滅させるというやり方がある。

LEDがオンになっている時間とオフになっている時間の割合を制御することで、見た目の明るさを変えることができる。 これはパルス幅変調(PWM)と呼ばれる。 利用できるPWMチャンネルは2つあり、PWM0とPWM1である。 PWM0にPWM信号を出力すると、GPIO12とGPIO18に現れる。 また、PWM1はGPIO13とGPIO19の信号を制御する。

次のコードをファイル(例:pwm.py)にコピーする。

import time
import RPi.GPIO as GPIO

# Pin definitions
led_pin = 12

# Use "GPIO" pin numbering
GPIO.setmode(GPIO.BCM)

# Set LED pin as output
GPIO.setup(led_pin, GPIO.OUT)

# Initialize pwm object with 50 Hz and 0% duty cycle
pwm = GPIO.PWM(led_pin, 50)
pwm.start(0)

# Set PWM duty cycle to 50%, wait, then to 90%
pwm.ChangeDutyCycle(50)
time.sleep(2)
pwm.ChangeDutyCycle(90)
time.sleep(2)

# Stop, cleanup, and exit
pwm.stop()
GPIO.cleanup()

実行すると(python pwm.pyなど)、LEDが薄暗い状態から始まり、2秒待って明るくなり、さらに2秒待ってからプログラムの終了とともに消灯するはずである。

注目すべきコード:

先ほどはLEDの切り替えにGPIOモジュールの.output()関数を使った。 ここではPWMオブジェクトを作成し、pwmという変数に格納する。次の行で行う。

pwm = GPIO.PWM(led_pin, 50)

これ以降は、そのオブジェクト内のメソッドを呼び出すことでPWMを制御できる。 たとえば、明るさを変えるには次のように呼び出す。

pwm.ChangeDutyCycle(t)

tは0〜100の間の数値である(0がオフ、100が常時オン)。 50という数値を入れると、LEDは半分の時間オン、残り半分の時間オフになる(切り替えが速すぎて目には見えないだけである)。

また、今回はGPIO.setwarnings()の呼び出しを省いている。 プログラムの末尾でGPIO.cleanup()を実際に呼び出せるからである。 PWMのコードを2回実行しても、警告は表示されないはずである。

チャレンジ: LEDが約2秒かけて、消灯状態から最大の明るさまでゆっくりフェードするようにしてみよう。 最大の明るさに達したらLEDを消灯し、フェードの過程をもう一度繰り返す。 このフェードを永遠に繰り返すようにする。

import time
import RPi.GPIO as GPIO

# Pin definitions
led_pin = 12

# Use "GPIO" pin numbering
GPIO.setmode(GPIO.BCM)

# Set LED pin as output
GPIO.setup(led_pin, GPIO.OUT)

# Initialize pwm object with 50 Hz and 0% duty cycle
pwm = GPIO.PWM(led_pin, 50)
pwm.start(0)

# Have the LED slowly fade up, turn off, and repeat
while True:
    for brightness in range(0, 101):
        pwm.ChangeDutyCycle(brightness)
        time.sleep(0.02)

コード パート3:ボタン入力

ユーザー入力を加えてみよう。次の内容をファイル(例:button.py)に保存する。

import time
import RPi.GPIO as GPIO

# Pins definitions
btn_pin = 4
led_pin = 12

# Set up pins
GPIO.setmode(GPIO.BCM)
GPIO.setup(btn_pin, GPIO.IN)
GPIO.setup(led_pin, GPIO.OUT)

# If button is pushed, light up LED
try:
    while True:
        if GPIO.input(btn_pin):
            GPIO.output(led_pin, GPIO.LOW)
        else:
            GPIO.output(led_pin, GPIO.HIGH)

# When you press ctrl+c, this will be called
finally:
    GPIO.cleanup()

コードを実行する(python button.py)。 これで、ボタンを押すとLEDが点灯するはずである。

注目すべきコード:

まず目につく奇妙な点はtry:finally:という文だろう。 これらはPythonのエラー・例外処理機能の一部である(詳しくはByte of Pythonの例外の章を参照してほしい)。

プログラムがwhile True:ループの中にいる間にctrl + cを押すと、例外が発生する。 その例外自体に対して何かをしたいわけではない(そのため「例外処理」で読んだようなexceptブロックは見当たらない)。 ただ、例外の内容にかかわらず、GPIO.cleanup()関数は必ず呼び出したい。 そうすればGPIOをきちんと閉じることができ、それ以上のエラーを心配せずに済む。

もう一つ気になる点として、GPIO.input(btn_pin)True(つまりピンが論理ハイ、3.3V)のときにLEDを消灯している。おや、と思うかもしれない。

この回路では、ボタンの一方のピンを常時3.3Vにつなぐプルアップ抵抗を使っている。 つまり、デフォルトの状態(押されていない状態)では、ボタンに接続されたピンは3.3Vになる。 ボタンを押すと、(ボタン内部の接点を通じて)そのピンはグラウンドに接続され、論理ロー(0V)になる。

その結果、ボタンが押されていないときは論理ハイになり(GPIO.input()Trueを返す)、ボタンが押されているときは論理ローになる(GPIO.input()Falseを返す)。

チャレンジ: ボタンを押すたびに変数を1つ増やし、画面に出力するプログラムを書いてみよう。 これはシンプルなボタンカウンターとして動作するはずである。 0から始まり、ボタンを押すたびに画面上でカウントアップする。

import time
import RPi.GPIO as GPIO

# Pins definitions
btn_pin = 4

# Set up pins
GPIO.setmode(GPIO.BCM)
GPIO.setup(btn_pin, GPIO.IN)

# Our counter
counter = 0

# Remember the current and previous button states
current_state = True
prev_state = True

# If button is pushed, light up LED
try:
    while True:
        current_state = GPIO.input(btn_pin)
        if (current_state == False) and (prev_state == True):
            counter = counter + 1
            print(counter)
        prev_state = current_state

# When you press ctrl+c, this will be called
finally:
    GPIO.cleanup()

実験2:音を鳴らす

Raspberry Piで音声クリップをダウンロードして再生するのは非常に簡単である。 コマンドラインを使って.wavファイルをダウンロードし、音量を調整し、再生をテストする。 続いて、ボタンを押すたびにそのファイルを再生するPythonスクリプトを書く。

参考になるチュートリアル

  • amixer — Raspberry Piの音量調整にamixerというLinuxツールを使う
  • Pygame — Pygameは、Pythonでシンプルなゲームを作るためのフレームワークである。Raspbianにはあらかじめpygameが入っているため、音を再生するのに使うことができる。

ハードウェアの接続

朗報である。前回の実験と同じ回路をそのまま使う。

  • GPIO12(ピン32)を330Ω抵抗に接続し、抵抗をLEDに接続する
  • GPIO4(ピン7)をボタンに接続する
  • Fritzing図のとおりに電源(3.3V)とグラウンド(GND)を接続する

Pi Wedgeを介した接続:

Raspberry Piに直接接続:

外部スピーカー(またはヘッドホン)をPiのヘッドホンジャックに接続する必要もある。 Hamburger Mini Speakerを使っている場合は、充電されていて電源が入っていることを確認する。

オーディオの設定

コードを書く前に、コマンドラインからオーディオを設定する必要がある。 (デスクトップ版のRaspbianを使っている場合は)ターミナルを開く。

注意: sudo raspi-configのAdvanced Optionsから、出力オーディオデバイスとして3.5mm(「ヘッドホン」)ジャックを選択していることを確認してほしい。方法については「Piの設定」の節を参照してほしい。

ターミナルから、次のコマンドを入力する。

amixer set PCM unmute
amixer set PCM 100%

オーディオがオンになり音量が上がっていることを確認するには、次のコマンドを入力する。

amixer

出力の末尾にMono: Playback 400 [100%] [4.00dB] [on]と表示されるはずである。

無料のサウンドクリップをダウンロードする(せっかくなので拍手の音にしてみよう)。

wget http://www.pacdv.com/sounds/people_sound_effects/applause-1.wav

次のコマンドでこのサウンドの再生をテストする。

aplay applause-1.wav

スピーカー(またはヘッドホン)から歓声と拍手の音が聞こえるはずである。

コード:ボタンを押すと音が鳴る

Raspbianのバージョンによっては、pygameパッケージをインストールする必要があるかもしれない(たとえばRaspbian Liteには一部のPythonパッケージがあらかじめ入っていない)。 ターミナルで次のように入力する。

sudo apt-get update
sudo apt-get install python3-pygame

新しいファイルに、次のコードを入力する。

import time
import RPi.GPIO as GPIO
from pygame import mixer

# Pins definitions
btn_pin = 4

# Set up pins
GPIO.setmode(GPIO.BCM)
GPIO.setup(btn_pin, GPIO.IN)

# Initialize pygame mixer
mixer.init()

# Remember the current and previous button states
current_state = True
prev_state = True

# Load the sounds
sound = mixer.Sound('applause-1.wav')

# If button is pushed, light up LED
try:
    while True:
        current_state = GPIO.input(btn_pin)
        if (current_state == False) and (prev_state == True):
            sound.play()
        prev_state = current_state

# When you press ctrl+c, this will be called
finally:
    GPIO.cleanup()

ファイルを保存し(例:applause.py)、python applause.pyでプログラムを開始する。 ボタンを押すと、お祝いの音が聞こえるはずである。

トラブルシューティング: 「ModuleNotFoundError: No module named ‘pygame’」というメッセージが表示された場合は、ターミナルでpip install pygameと入力してpygameパッケージをインストールする必要がある。

注目すべきコード:

音を鳴らすためにpygameパッケージを使っている。 Pythonにおけるパッケージとは、モジュールをまとめた集まりである。 ありがたいことに、pygameはRaspbianのPythonにあらかじめインストールされている。 これを使うには、コード中でfrom pygameと書き、その後にimportを続けてどのモジュールを使いたいかを指定すればよい。たとえば次のように書く。

from pygame import mixer

これは、pygameパッケージからmixerモジュールをインポートしたいという意味である。 この後のコードでは、mixerモジュールを使って次のようにSoundオブジェクトを作成できる。

sound = mixer.Sound('applause-1.wav')

ダウンロードしたファイルapplause-1.wavを使ってSoundオブジェクトを作成し、それをsound変数に格納している。 Soundオブジェクトの.play()メソッドを呼び出すと、.wavファイルの再生が始まる。

sound.play()

チャレンジ: 音が再生されている最中にもう一度ボタンを押すと、新しい音が最初のクリップと重なって再生されてしまうことに気づいたかもしれない。これを直してみよう。 音の再生中にボタンを押すと音が止まるようにコードを変更する。 もう一度押すと、そのサウンドクリップが最初から再生される。 さらに、せっかくなので音が再生されている間はLEDが点灯するようにしてみよう。 ヒント:音が再生中(「ミックス中」)かどうかを調べる方法や、音を止める方法についてはpygame.mixerのメソッドを確認するとよい。

import time
import RPi.GPIO as GPIO
from pygame import mixer

# Pins definitions
btn_pin = 4
led_pin = 12

# Set up pins
GPIO.setmode(GPIO.BCM)
GPIO.setup(btn_pin, GPIO.IN)
GPIO.setup(led_pin, GPIO.OUT)

# Initialize pygame mixer
mixer.init()

# Remember the current and previous button states
current_state = True
prev_state = True

# Load the sounds
sound = mixer.Sound('applause-1.wav')

# If button is pushed, light up LED
try:
    while True:

        # If button is pressed, turn on LED and play sound
        current_state = GPIO.input(btn_pin)
        if (current_state == False) and (prev_state == True):
            if mixer.get_busy():
                sound.stop()
            else:
                GPIO.output(led_pin, GPIO.HIGH)
                sound.play()

        # Only turn off LED if sound has stopped playing
        if mixer.get_busy() == False:
            GPIO.output(led_pin, GPIO.LOW)

        # Save state of switch to use in next iteration of the loop
        prev_state = current_state

# When you press ctrl+c, this will be called
finally:
    GPIO.cleanup()

実験3:SPIとアナログ入力

世の中の多くのセンサーは、測定データをアナログ電圧として伝える。 たとえば、フォトセルは、センサーに当たる光の量に応じて抵抗値を変化させる。 回路の中で分圧回路を使うことで、電圧を測定することにより、実質的に周囲の光の量を測定できる。

残念ながら、Raspberry Piにはアナログ電圧を測定する手段が備わっていない。 これを行うには、別のハードウェア、アナログ-デジタルコンバータ(ADC)が必要になる。 今回はMicrochip MCP3002を使う。 これは、最大2つのアナログ電圧を別々のチャンネルで測定し、シリアルペリフェラルインターフェース(SPI)経由でその値を報告できる、便利な小型チップである。

SPIバス上でコマンドを送信し応答を読み取るために、Pythonの組み込みモジュールであるspidevを使う。

参考になるチュートリアル

  • アナログとデジタルの違い — 両者の違いと、この例でそれを気にする必要がある理由
  • 分圧回路 — 分圧回路の構成、使い方、値の計算方法を説明する
  • シリアルペリフェラルインターフェース(SPI) — SPIが低レベルでどう動作するかを学びたい場合に読んでほしい
  • 2進数 — このセクションでは2進数を直接扱う

ハードウェアの接続

それぞれの接続がどのピンとGPIOラベルに対応するかは、前の例のRaspberry Piのピン配置の節を参照してほしい。

  • MOSI(GPIO10、ピン19)をMCP3002のDinに接続する
  • MISO(GPIO9、ピン21)をMCP3002のDoutに接続する
  • SCLK(GPIO11、ピン23)をMCP3002のCLKに接続する
  • CE0(GPIO8、ピン24)をMCP3002のCS/SHDNに接続する
  • フォトセルの分圧回路をMCP3002のCH0に接続する
  • ポテンショメータの中央のピンをMCP3002のCH1に接続する
  • Fritzing図のとおりに電源(3.3V)とグラウンド(GND)を接続する

Pi Wedgeを介した接続:

Raspberry Piに直接接続:

注意: MCP3002の向きに注意してほしい。チップの上面に切り欠きがあるはずである。切り欠きを上に向けたとき、ピン1は切り欠きの左下にある。

MCP3002データシートによるピン配置

コード:アナログ電圧を読み取る

Raspbianのバージョンによっては、spidevパッケージをインストールする必要があるかもしれない(たとえばRaspbian Liteには一部のPythonパッケージがあらかじめ入っていない)。 ターミナルで次のように入力する。

pip install spidev

新しいファイルに、次のコードを入力する。

import time
import spidev

spi_ch = 0

# Enable SPI
spi = spidev.SpiDev(0, spi_ch)
spi.max_speed_hz = 1200000

def read_adc(adc_ch, vref = 3.3):

    # Make sure ADC channel is 0 or 1
    if adc_ch != 0:
        adc_ch = 1

    # Construct SPI message
    #  First bit (Start): Logic high (1)
    #  Second bit (SGL/DIFF): 1 to select single mode
    #  Third bit (ODD/SIGN): Select channel (0 or 1)
    #  Fourth bit (MSFB): 0 for LSB first
    #  Next 12 bits: 0 (don't care)
    msg = 0b11
    msg = ((msg << 1) + adc_ch) << 5
    msg = [msg, 0b00000000]
    reply = spi.xfer2(msg)

    # Construct single integer out of the reply (2 bytes)
    adc = 0
    for n in reply:
        adc = (adc << 8) + n

    # Last bit (0) is not part of ADC value, shift to remove it
    adc = adc >> 1

    # Calculate voltage form ADC value
    voltage = (vref * adc) / 1024

    return voltage

# Report the channel 0 and channel 1 voltages to the terminal
try:
    while True:
        adc_0 = read_adc(0)
        adc_1 = read_adc(1)
        print("Ch 0:", round(adc_0, 2), "V Ch 1:", round(adc_1, 2), "V")
        time.sleep(0.2)

finally:
    spi.close()
    GPIO.cleanup()

ファイルを保存し(例:adc.py)、Pythonで実行する。

python adc.py

フォトセルを覆うと、Ch 0の電圧が変化するはずである。 ポテンショメータのつまみを回すと、Ch 1の電圧が変化する。

注目すべきコード:

SpiDevオブジェクトを初期化する際、Raspberry PiのSPIチャンネル0を使っている。

spi_ch = 0
spi = spidev.SpiDev(0, spi_ch)

チャンネル0は、Pi上のCE0(チップイネーブル0)に対応する。 SPIバス上で別のデバイスを使いたい場合は、それをCE1に接続し、SpiDevのチャンネル1も使う必要がある。

SPIメッセージは、個々のビットを操作して組み立てる。 まず、接頭辞’0b’を使って2進数の11(10進数の3にあたる)から始める。

msg = 0b11

MCP3002データシートのセクション5を見ると、送信を開始するために1を送り、続けて「シングルエンドモード」を示すもう一つの1を送る必要があることがわかる。 その後、0(チャンネル0の場合)または1(チャンネル1の場合)でチャンネルを選択する。 続いて、下位ビット(LSB)から先に返してほしいことを示す0を送る。

msg = ((msg << 1) + adc_ch) << 5

最後に、さらに12個の0を送る。 ここで送る内容自体に意味はなく、MCP3002からDout(MISO)ライン経由でデータを送り返してもらうためのクロックパルスを送っているだけである。 このデータ(4つの設定ビットに続く12個の0)はリストに格納される。

msg = [msg, 0b00000000]

返ってきたデータはreply変数に格納され、2バイト(それぞれ整数として保存された2要素)のリストとして受け取る。 SPIでは、データを送信すると同時に応答を読み取る点に注意してほしい。

reply = spi.xfer2(msg)

そこから、1つ目のバイトを8ビット左にシフトし、2つ目のバイトを加えることで、2つのバイト(8ビット)から一つの整数を組み立てる。 最後に読み込む1ビットは余分なもの(ADCの戻り値には含まれない)なので、答えを右に1ビットシフトする。

adc = 0
for n in reply:
    adc = (adc << 8) + n

adc = adc >> 1

ADCの値は、(Vdd/Vrefピンの電圧が何であれ)最大電圧に対する割合として与えられる。 この割合は、応答値を1024で割ることで計算される。 1024という数字が出てくるのは、MCP3002が10ビットADCであり、10ビットの最大値(0b1111111111)が1023であることによる。 多くのADCには何らかの誤差があるため、計算をしやすくするために切り上げて1024としている(興味があれば、ADCの最大値についてのこの議論を参照してほしい)。

val / 1024Vrefに対する割合が求まったら、その割合にVref(Raspberry Piの場合は3.3Vとわかっている)を掛ける。

voltage = (vref * adc) / 1024

こうしてアナログ電圧の読み取り値が得られる。 ここまでの説明がわかりにくければ、Enable SPIの部分とread_adc()関数をそのまま自分のコードにコピーしてしまってよい。 あとはread_adc(0)を呼び出すだけで、MCP3002のCH0の電圧が得られる。

もう一つ興味深いのが、デフォルトパラメータという考え方である。 read_adc()の定義を見てみよう。

def read_adc(adc_ch, vref = 3.3):

実際にはadc_chvrefという2つのパラメータがあることがわかる。 この関数を呼び出す際は、チャンネル番号(0または1)を必ず渡す必要がある。 ただし、Vrefの値は任意で渡すことができる。 Raspberry Piの場合、ほとんどの状況で電圧は3.3Vになる。 別の電圧(たとえば5V)を使う場合は、計算式を変更することでADCからより正確な読み取り値を得られる。

この関数を別のVref(たとえば5)で呼び出すには、read_adc(0, 5)のように書くか、vrefパラメータを明示的に指定してread_adc(0, vref=5)のように書く。 ただし、MCP3002には3.3Vを接続していることがわかっているので、単にread_adc(0)と呼び出せば、計算の際にデフォルトパラメータのvref=3.3が使われる。

チャレンジ: 回路にLEDを追加しよう。 可変ナイトライトとして動作するプログラムを書いてみよう。 つまり、フォトセルが暗さ(周囲の光が少ないこと)を検知したときにLEDを点灯させ、フォトセルが明るさ(周囲の光が多いこと)を検知したときにLEDを消灯させる。 LEDが点灯しているときは、ポテンショメータでその明るさを制御できるようにする。 ヒント:明るいか暗いかのしきい値を決めるために、いくつか測定しておくとよいだろう。フォトセルを手で覆ったときの電圧はいくつだろうか。

前の実験と同様に、GPIO12(ピン32)にLEDと抵抗を接続する。

import time
import spidev
import RPi.GPIO as GPIO

# Pin definitions
led_pin = 12

# Light/dark threshold (Volts)
light_threshold = 2.2

# Use "GPIO" pin numbering
GPIO.setmode(GPIO.BCM)

# Set LED as output
GPIO.setup(led_pin, GPIO.OUT)

# Initialize pwm object with 50 Hz and 0% duty cycle
pwm = GPIO.PWM(led_pin, 50)
pwm.start(0)

# SPI channel (use CE0)
spi_ch = 0

# Enable SPI
spi = spidev.SpiDev(0, spi_ch)
spi.max_speed_hz = 1200000

def read_adc(adc_ch, vref = 3.3):

    # Make sure ADC channel is 0 or 1
    if adc_ch != 0:
        adc_ch = 1

    # Construct SPI message
    #  First bit (Start): Logic high (1)
    #  Second bit (SGL/DIFF): 1 to select single mode
    #  Third bit (ODD/SIGN): Select channel (0 or 1)
    #  Fourth bit (MSFB): 0 for LSB first
    #  Next 12 bits: 0 (don't care)
    msg = 0b11
    msg = ((msg << 1) + adc_ch) << 5
    msg = [msg, 0b00000000]
    reply = spi.xfer2(msg)

    # Construct single integer out of the reply (2 bytes)
    adc = 0
    for n in reply:
        adc = (adc << 8) + n

    # Last bit (0) is not part of ADC value, shift to remove it
    adc = adc >> 1

    # Calculate voltage form ADC value
    voltage = (vref * adc) / 1024

    return voltage

# Read ADC values and determine if LED should be on or off
try:
    while True:

        # Read ADC values
        light_val = read_adc(0)
        knob_val = read_adc(1)

        # Calculate brightness for when LED is on
        # Max brightness is 100% duty cycle
        brightness = (knob_val / 3.3) * 100

        # Turn LED off if ambient light is above threshold
        # Turn LED on if ambient light is equal to or below threshold
        if light_val > light_threshold:
            pwm.ChangeDutyCycle(0)
        else:
            pwm.ChangeDutyCycle(brightness)
        time.sleep(0.1)

finally:
    pwm.stop()
    spi.close()
    GPIO.cleanup()

実験4:I2C温度センサー

アナログセンサーやSPIチップに加えて、Inter-Integrated Chip(IICあるいはI2C)プロトコルに依存するセンサー(や他のデバイス)にもよく出会う。 これは、クロックとデータのチャンネルからなる2線式のバスである。 マスター(Raspberry Pi)とデバイス(センサー)は、同じデータ線の上で通信できる。

このプロトコルの動作を実際に見るため、TMP102温度センサーと通信するプログラムを書いてみる。 低レベルの通信処理は、Pythonのsmbusモジュールに任せる。 「SMBus」は「System Management Bus」の略で、I2Cプロトコルの上に構築されたもう一つのプロトコル層である点に注意してほしい。 smbusを使うと、I2Cのいくつかの機能(クロックストレッチングなど)は失われるが、それでも多くのI2Cセンサーと通信できる。

参考になるチュートリアル

  • I2C — I2Cプロトコルがどう動作するかを詳しく見る

ハードウェアの接続

I2Cのサンプルの代替として、はんだ付けや4本のピンへの接続を必要としないQwiicケーブルとQwiic対応TMP102を使うこともできる。

前の実験のピン配置の図を参照してほしい。

  • SDA1(GPIO2、ピン3)をTMP102のSDAに接続する
  • SCL1(GPIO3、ピン5)をTMP102のSCLに接続する
  • 電源(3.3V)をTMP102のVCCに接続する
  • グラウンド(GND)をTMP102のGNDに接続する

Pi Wedgeを介した接続:

Raspberry Piに直接接続:

コード:温度を読み取って計算する

Raspbianのバージョンによっては、smbusパッケージをインストールする必要があるかもしれない(たとえばRaspbian Liteには一部のPythonパッケージがあらかじめ入っていない)。 ターミナルで次のように入力する。

sudo apt-get install python3-smbus

新しいファイルに、次のコードをコピーする。

import time
import smbus

i2c_ch = 1

# TMP102 address on the I2C bus
i2c_address = 0x48

# Register addresses
reg_temp = 0x00
reg_config = 0x01

# Calculate the 2's complement of a number
def twos_comp(val, bits):
    if (val & (1 << (bits - 1))) != 0:
        val = val - (1 << bits)
    return val

# Read temperature registers and calculate Celsius
def read_temp():

    # Read temperature registers
    val = bus.read_i2c_block_data(i2c_address, reg_temp, 2)
    # NOTE: val[0] = MSB byte 1, val [1] = LSB byte 2
    #print ("!shifted val[0] = ", bin(val[0]), "val[1] = ", bin(val[1]))

    temp_c = (val[0] << 4) | (val[1] >> 4)
    #print (" shifted val[0] = ", bin(val[0] << 4), "val[1] = ", bin(val[1] >> 4))
    #print (bin(temp_c))

    # Convert to 2s complement (temperatures can be negative)
    temp_c = twos_comp(temp_c, 12)

    # Convert registers value to temperature (C)
    temp_c = temp_c * 0.0625

    return temp_c

# Initialize I2C (SMBus)
bus = smbus.SMBus(i2c_ch)

# Read the CONFIG register (2 bytes)
val = bus.read_i2c_block_data(i2c_address, reg_config, 2)
print("Old CONFIG:", val)

# Set to 4 Hz sampling (CR1, CR0 = 0b10)
val[1] = val[1] & 0b00111111
val[1] = val[1] | (0b10 << 6)

# Write 4 Hz sampling back to CONFIG
bus.write_i2c_block_data(i2c_address, reg_config, val)

# Read CONFIG to verify that we changed it
val = bus.read_i2c_block_data(i2c_address, reg_config, 2)
print("New CONFIG:", val)

# Print out temperature every second
while True:
    temperature = read_temp()
    print(round(temperature, 2), "C")
    time.sleep(1)

ファイルを保存し(例:tmp102.py)、Pythonで実行する。

python tmp102.py

CONFIGレジスタの2バイトが更新され、続けて1秒ごとに温度が画面に出力されるはずである。

注目すべきコード:

SPIとは異なり、I2Cはアドレスとレジスタの組み合わせに依存する。 SPIは一度に一つのチップとだけ通信するように構成されているのに対し、I2Cは一つのバス上に多数のデバイスを共存させることができる。 競合を避けるため、(メーカーによって)デバイスにアドレスが割り当てられ、ホスト(Pi)がどのデバイスと通信しようとしているかを各デバイスが判別できるようになっている。 今回のTMP102のアドレスは0x48である。

TMP102と通信するたびに、そのアドレス(0x48)をバス上に送信する必要がある。 そうして初めて、TMP102上で読み書きしたいレジスタのメモリ位置(アドレス)を送信できる。 ほとんどのI2Cデバイスにおいて、レジスタとはデバイスのメモリ上の、8ビット(1バイト)のデータを保持する位置のことである点に注意してほしい。 このデータがデバイスの機能を制御することもあれば(CONFIGレジスタの場合のように)、センサーの測定データを保持することもある(温度レジスタの場合のように)。

TMP102の温度レジスタから2バイトを読み取るには、次のコマンドを使う。

val = bus.read_i2c_block_data(i2c_address, reg_temp, 2)

これらの値はval変数にリスト[x, y]として格納される。 TMP102のデータシートを見ると、温度は12ビットで表されることがわかる。 この読み取り値を含む2バイトを読む際は、2バイト目の末尾4ビットを取り除く必要がある。 また、1バイト目は4ビット分シフトする。

temp_c = (val[0] << 4) | (val[1] >> 4)

温度の負の値を表現できるようにするため、TMP102からの値は2の補数の形式で送られてくることがある。 この場合、12ビットの数値の最初のビットが、その値が正か負かを決める(0なら正、1なら負)。 2の補数について詳しくはこの記事を参照してほしい。

Pythonで2の補数の数値を負の数に変換するには、最初のビットが0か1かを調べる。 0であれば、その数値をそのまま使う(正の数である)。 1であれば、その数値から2の補数の最大の負の数(今回の場合は2^12=4096)を引く。

if (val & (1 << (bits - 1))) != 0:
    val = val - (1 << bits)

チャレンジ: CONFIGレジスタを変更し、TMP102が1秒間に8回、温度の読み取りを更新するようにしてみよう(8回ではなく)。 また、温度を華氏で出力してみよう。 ヒント:TMP102のデータシートの7ページを見て、CONFIGレジスタのどのビットを変更する必要があるか確認してほしい。

import time
import smbus

i2c_ch = 1

# TMP102 address on the I2C bus
i2c_address = 0x48

# Register addresses
reg_temp = 0x00
reg_config = 0x01

# Calculate the 2's complement of a number
def twos_comp(val, bits):
    if (val & (1 << (bits - 1))) != 0:
        val = val - (1 << bits)
    return val

# Read temperature registers and calculate Celsius
def read_temp():

    # Read temperature registers
    val = bus.read_i2c_block_data(i2c_address, reg_temp, 2)
    # NOTE: val[0] = MSB byte 1, val [1] = LSB byte 2
    #print ("!shifted val[0] = ", bin(val[0]), "val[1] = ", bin(val[1]))
    
    temp_c = (val[0] << 4) | (val[1] >> 4)
    #print (" shifted val[0] = ", bin(val[0] << 4), "val[1] = ", bin(val[1] >> 4))
    #print (bin(temp_c))

    # Convert to 2s complement (temperatures can be negative)
    temp_c = twos_comp(temp_c, 12)

    # Convert registers value to temperature (C)
    temp_c = temp_c * 0.0625

    return temp_c

# Initialize I2C (SMBus)
bus = smbus.SMBus(i2c_ch)

# Read the CONFIG register (2 bytes)
val = bus.read_i2c_block_data(i2c_address, reg_config, 2)
print("Old CONFIG:", val)

# Set to 8 Hz sampling (CR1, CR0 = 0b11)
val[1] = val[1] & 0b00111111
val[1] = val[1] | (0b11 << 6)

# Write 8 Hz sampling back to CONFIG
bus.write_i2c_block_data(i2c_address, reg_config, val)

# Read CONFIG to verify that we changed it
val = bus.read_i2c_block_data(i2c_address, reg_config, 2)
print("New CONFIG:", val)

# Print out temperature every second
while True:
    temperature = read_temp()
    temp_f = temperature * (9 / 5) + 32
    print(round(temp_f, 2), "F")
    time.sleep(1)

実験5:ファイルの読み書き

前回の例(I2Cデバイスからの計測)を発展させ、その値をファイルに記録してみよう。 これは、温度(光量、湿度、風速、気圧、部屋に入ってくる人の数など、何であれ)を測定し、それが数分、数時間、数日という単位でどう変化するかを見たい場合に非常に役立つ。

参考になるチュートリアル

ハードウェアの接続

I2Cのサンプルの代替として、はんだ付けや4本のピンへの接続を必要としないQwiicケーブルとQwiic対応TMP102を使うこともできる。

前回と同じ回路を使う。

  • SDA1(GPIO2、ピン3)をTMP102のSDAに接続する
  • SCL1(GPIO3、ピン5)をTMP102のSCLに接続する
  • 電源(3.3V)をTMP102のVCCに接続する
  • グラウンド(GND)をTMP102のGNDに接続する

Pi Wedgeを介した接続:

Raspberry Piに直接接続:

コード:温度を測定してファイルに記録する

先ほどのコードをモジュールに作り替え、再利用できるようにする。 tmp102.pyのコードを次のように変更する。

tmp102.py

import smbus

# Module variables
i2c_ch = 1
bus = None

# TMP102 address on the I2C bus
i2c_address = 0x48

# Register addresses
reg_temp = 0x00
reg_config = 0x01

# Calculate the 2's complement of a number
def twos_comp(val, bits):
    if (val & (1 << (bits - 1))) != 0:
        val = val - (1 << bits)
    return val

# Read temperature registers and calculate Celsius
def read_temp():

    global bus

    # Read temperature registers
    val = bus.read_i2c_block_data(i2c_address, reg_temp, 2)
    # NOTE: val[0] = MSB byte 1, val [1] = LSB byte 2
    #print ("!shifted val[0] = ", bin(val[0]), "val[1] = ", bin(val[1]))

    temp_c = (val[0] << 4) | (val[1] >> 4)
    #print (" shifted val[0] = ", bin(val[0] << 4), "val[1] = ", bin(val[1] >> 4))
    #print (bin(temp_c))

    # Convert to 2s complement (temperatures can be negative)
    temp_c = twos_comp(temp_c, 12)

    # Convert registers value to temperature (C)
    temp_c = temp_c * 0.0625

    return temp_c

# Initialize communications with the TMP102
def init():

    global bus

    # Initialize I2C (SMBus)
    bus = smbus.SMBus(i2c_ch)

    # Read the CONFIG register (2 bytes)
    val = bus.read_i2c_block_data(i2c_address, reg_config, 2)

    # Set to 4 Hz sampling (CR1, CR0 = 0b10)
    val[1] = val[1] & 0b00111111
    val[1] = val[1] | (0b10 << 6)

    # Write 4 Hz sampling back to CONFIG
    bus.write_i2c_block_data(i2c_address, reg_config, val)

    # Read CONFIG to verify that we changed it
    val = bus.read_i2c_block_data(i2c_address, reg_config, 2)

新しいファイルを作成し、次のコードを入力する。ファイル名はtemplogger.pyなどにする。

templogger.py

import time
import datetime
import tmp102

filename = "temp_log.csv"

# Create header row in new CSV file
csv = open(filename, 'w')
csv.write("Timestamp,Temperature\n")
csv.close

# Initialize communication with TMP102
tmp102.init()

# Sample temperature every second for 10 seconds
for t in range(0, 10):

    # Construct CSV entry from timestamp and temperature
    temp_c = str(round(tmp102.read_temp(), 2))
    entry = str(datetime.datetime.now())
    entry = entry + "," + temp_c + "\n"

    # Log (append) entry into file
    csv = open(filename, 'a')
    try:
        csv.write(entry)
    finally:
        csv.close()

    # Wait 1 second before sampling temperature again
    time.sleep(1)

# When all the writing has been completed, print the CSV contents
csv = open(filename, 'r')
print(csv.read())
csv.close()

python templogger.pyで温度ロガーを実行する。 プログラムが1秒ごとに温度を読み取る間、10秒間は何も起きないはずである。 試しに温度センサーに息を吹きかけてデータに影響を与えてみるのも面白い。 10秒後、収集が完了し、temp_log.csvの内容が画面に出力される。

コンソールにcat temp_log.csvと入力すれば、ログの内容を確認できる。

注目すべきコード:

「Pythonでプログラミングする」の節で、モジュールの作り方を説明したのを思い出してほしい。 モジュールを使うと、他のファイルにあるコードを再利用できる。 今回は、tmp102.pyのコードのうち「温度を測定する」部分を関数定義にまとめ、他のファイルから呼び出せるようにした。

メインプログラム(templogger.py)では、import tmp102で自作のモジュールをインポートしている。 .py拡張子を省いていることに注目してほしい。Pythonは自動的に.pyファイルを探してくれる。

また、ファイルを読み書きのために開くたびに、できるだけ早く閉じていることにも気づくだろう。 ファイルを開いたまま放置しておくのは、一般的によくない習慣である。 ファイルが開いたままプログラムやOSがクラッシュすると、そのファイル(あるいは最悪の場合、ファイルシステム全体)が破損する可能性がある。

さらに保護を強めるため、書き込みの部分をtryブロックに入れている。

try:
    csv.write(entry)
finally:
    csv.close()

これにより、プログラムがファイルへの書き込み中にクラッシュしても、例外が発生してPythonが終了前に自動的にファイルを閉じてくれる。

open()関数の2つ目のパラメータで、ファイルへのアクセス方法を指定していることも確認できる。

  • ‘r’ — 読み取り
  • ‘w’ — 書き込み(ファイルの元の内容は消去される)
  • ‘a’ — 追記(元の内容は保持され、末尾に追加される)

datetime.datetime.now()datetimeオブジェクトを返し、それをstr()で文字列に変換している。 これはRaspberry Piのローカルタイムに基づく点に注意してほしい。 協定世界時(UTC)の日時を取得したい場合はdatetime.datetime.utcnow()を使う。

チャレンジ: 温度のログを表計算プログラムで開き、その10秒間で温度がどう変化したかを示すグラフを作ってみよう(さらに挑戦したい場合は、より長い期間にわたって温度を測定するようプログラムを変更してみよう)。 ヒント:Raspbianには無料の表計算プログラムLibreOffice Calcが付属している。 Calcを使う場合、データ > テキストを列に分割の機能が、日時のタイムスタンプを使いやすい形式に変換するのに役立つかもしれない。

ヘッドレス: Raspberry Piをヘッドレスなデバイスとして使っている場合は、CSVの内容を画面に出力し、それをコピー&ペーストして手元のコンピュータの表計算プログラムに貼り付けるとよいだろう。

解答: これには決まった「正解」があるわけではない。創造力を発揮して、グラフ作成の腕前を見せてほしい。

まとめ・参考資料

このチュートリアルが、Pythonでの(より具体的には、Pythonでハードウェアを制御するための)冒険の出発点になれば幸いである。 Python言語をさらに深く学びたい場合は、次の資料を参考にしてほしい。

さらにインスピレーションが欲しい場合は、次のようなRaspberry Piプロジェクトも参考になる。

タグ: 概念、データロギング、Hookup、ロギング、プログラミング、Python、Raspberry Pi


出典:Python Programming Tutorial: Getting Started with the Raspberry Pi(SparkFun Learn)を日本語に翻訳し、再構成した。 原文は CC BY-SA 4.0 ライセンスで公開されており、本ページも同ライセンスの下で提供する。