United Statesからアクセスのようです。言語設定をEnglishに切り替えますか?
Switch to English site
Skip to main content

Raspberry Piで使用できる入力は? Part2 比例センサー(プロポーショナル・センサー)

この記事はJames MacfarlaneとLucy Rogersが執筆しました。

入力・出力(I/O)に関する記事を2回に分けてご紹介します、今回はPart2です。 Part 1はこちら.

比例(プロポーショナル)センサーについて

スイッチやロジックレベルのセンサーは使いやすいですが、オンとオフの2つの離散的な状態しか得られません。しかし多くのセンサーは感知している物理量に比例した電気出力を生成します。測定したい物理量のほとんどに対応するセンサーがあり、ここでは取り上げきれないほどの数がありますが、膨大なリストを書くのではなく、いくつかの例を挙げながら原理や仕組みなどを説明していきます。

シグナルコンディショニング(信号調整)

センサーは、物理的な「現実世界」の量(例:温度)を電気的な量(例:電圧)に変換します。センサーには、数多くの異なる電気的出力形式がありますが、より一般的なものは、電圧、電流、抵抗、周波数です。これらのほとんどは「アナログ」の性質を持っており、いくつかの手順を踏まなければPiに直接接続することはできません。アナログ・デジタル変換器(ADC)が必要です。ADCは通常、入力信号が特定の値の範囲内の電圧である事を必要とします。つまり、センサーの電気出力をADCに受け入れられる電圧に変換するために、別のステップが必要になります。このステップをシグナルコンディショニング(信号調整)と呼びます。シグナルコンディショニング回路には、単純な電位分割器から高精度の計測用アンプまで、さまざまなものがあります。さらに、「ノイズの多い」物質量を測定する場合、エイリアシングと呼ばれる効果を防ぐため、シグナルコンディショニング回路とADCの間にある程度のフィルタリングが必要になりますが、これについてはこの記事で説明しません。

幸いな事に、多くのセンサーメーカーはシグナルコンディショニングとADCをセンサー本体に統合することで、開発を楽にしてくれます。これらは、Piでサポートされているほとんどすべての一般的なフォーマットでデジタル出力を提供します。

シグナルコンディショニングとアナログからデジタルへの変換は、それだけで一冊の本が必要なほどの主題ですから、この記事では主にこれらのパッケージ化された「デジタル出力」のセンサーに焦点を当てます。ただし、最初により一般的なタイプの「生の」アナログセンサーのクイックツアーを行い、遭遇する可能性のあるいくつかのフレーバーを示し、PiとNode-REDプログラミング言語で使用できる2つのADCソリューションについて簡単に説明します。

アナログセンサー

ポテンショメータ

アナログセンサーの中でも最もシンプルなものの一つがポテンショメータ(略してポット)です。ラジオのボリュームノブを調整したことがある人にはおなじみのものです。ポテンショメータは、ほとんどのADCに接続でき、余分な信号処理を必要としないため、簡単に使用できます。ポテンショメータは、ユーザーが操作するコントロールや、動きの遅い機械部品の位置を特定するために使用されます。ただし、動作範囲は約270°なので、連続的に回転するものに適していません(この場合ロータリーエンコーダーが必要)。ロータリーポットの他にスライダーポットなどがある。ポットは総抵抗値で規定されています(一般的には5kΩ~20kΩ程度の物が良い)。

センサーとしてのポットは、接続の仕方によって電圧や抵抗が出力されると考えることができます。トラックの両端(外側の端子)を電源とグラウンドに接続すると、中央に電圧が出力されます。

(ワイパー)の接続を行います。ワイパーとトラックの片方の端だけを使えば、可変抵抗が得られます。なお、ほとんどのポットは大きな電流を扱えないので、接続方法に注意しないと魔法の煙が出てしまいます。

光センサー

LDR(Light Dependent resistor)とは、光量によって抵抗値が変化する抵抗器のことです。このほか、光量に応じた電流を流すフォトダイオードやフォトトランジスタなどもあります。

温度センサー

熱電対やサーミスタなど、さまざまな種類のものがあります。熱電対はゼーベック効果を利用した物です。異なる2つの金属でできた線をつなぎ合わせることで、温度差を電圧差に変換します。熱電対の使い方はここでは説明しませんが、いくつかの注意点を挙げておきます:

  1. 用途に応じてさまざまなタイプがあります。レターコードで名前が付けられています。適切な種類のワイヤーで接続しないと、読み取りにエラーが出てしまいます。
  2. 熱電対が作り出す電圧は非常に小さいため(例えばK型熱電対の出力は1℃当たり約41マイクロボルト)、信号をADCに送るためには多くの増幅が必要になります。
  3. 温度から電圧への変換は非線形であり、1℃あたりのマイクロボルト数は温度によって変化するため、ソフトウェアでこれを考慮する必要があります(ハードウェアによる解決策もあります)。
  4. これらは温度差を測定するだけなので「冷接点」の温度を測定する独立した手段と、それをソフトウェアまたはハードウェアで処理する方法が必要です。これを「冷接点補償」と言います。

熱電対は高温(100℃以上)の測定によく使われますが、低温ではサーミスタの方が使いやすいです。

サーミスタは単なる温度依存性を持った抵抗器です。PTCとNTCの2種類があります。PTC(positive temperature coefficient)サーミスタは温度が上がると抵抗値が大きくなります。NTC(負の温度係数)のサーミスタはその逆です。また、RTD(Resistance Thermometry Device)と呼ばれる、非常に精度の高い(そして高価な)サーミスタもあります。サーミスタは一般的に、非線形の温度 - 抵抗反応を示します。

サーミスタの抵抗値出力は、電圧に変換してからADCに入力する必要があります。詳しくは後述します。

3つ目の温度センサーは、半導体ジャンクションにかかる電圧が温度によって変化する事を利用しています。これを増幅して、温度と直線的な関係を持つ変化する電圧(LM35など)または電流(AD590など)を生成します。

最後にデジタル出力付きの温度センサーがありますが、これについてはしばらく後に説明します。

ストレインゲージ(ひずみゲージ)

ストレインゲージとは、素材がどれだけ伸びたかを測定するための装置です。細かいワイヤーをフィルタに接着し、そのフィルムに接着し、そのフィルムを対象物(金属構造物の一部など)に接着したもので、対象物が伸びるとワイヤーも伸び、抵抗値が変化する仕組みになっています。ひずみゲージは、ロードセルや圧力センサーなど、他のいくつかのタイプやセンサーの基礎となっています。

ロードセル(荷重計)

力を計測するロードセルです。ほとんどの電子式体重計の基礎となっています。通常、金属の塊に特殊な形状の穴をあけ、機械的な負荷がかかった時に予測可能な方法で曲がるようにしたものです。ホイートストンブリッジ(またはストレインブリッジ)と呼ばれる4つのストレインゲージの特殊な構成により、負荷に応じて直線的に変化する小さな電圧が発生します。ホイートストンブリッジには、通常5Vまたは10Vの正確な電源が必要です。出力電圧は非常に小さく(例:最大20mV)、電源電圧の半分に相当する電圧の上に乗ります。このため、ADCに適した信号を生成するには、インスツルメンテーション・アンプ(または差動アンプ)と呼ばれる特殊な回路が必要となります。

圧力センサー

圧力センサー(圧力変換器とも呼ばれる)は、空気やその他の流体の圧力変化を測定します。数ミリバールから数百バール(1バールは14.5psiで大気圧とほぼ同じです)までの圧力範囲のものがあります。主に金属製のダイアフラムを使用して、測定したい圧力と基準となる圧力の間に挟むことで動作します。このダイアフラムは、かかる圧力に応じて異なる量だけ曲がります。これをわずかな電圧の変化に変えるために、ストレインブリッジが使用されます。多くの圧力トランスデューサーには、これを0~5Vの範囲の電圧または4~20mAの範囲の電流に変えるための信号調整回路(シグナルコンディショニング)が内蔵されています。圧力変換器の注意点としては、圧力と同様に温度にも敏感に反応する傾向があるので、ほとんどの場合、何らかの温度補償が組み込まれています。

圧力変換器には、基準となる圧力によってゲージ式、絶対圧式、差動式の3種類があります。ゲージ式はケースの外気との相対的な圧力を測定するだけのものです。絶対圧式は、基準となる真空を密閉し、気圧そのものを測定する事ができます。*これを大気圧測定といいます。
最後に差動式は2つの圧力接続部があり、その差を測定します。
その他重要な点として、メディアの互換性についても注意が必要です。例えば、すべての圧力変換器が内部での水漏れに耐えられるわけではありません。

アナログセンサーの出力タイプについて

ここまででアナログセンサーの例を紹介してきましたが、ここからはその出力タイプとシグナルコンディショニングについて紹介していきます。

電圧出力

電圧を生成するセンサーは、非常に便利に使用できます(ADCに直接接続できるものもあります)。しかし、増幅が必要なものもあります。センサーの中には、熱電対や太陽電池パネルのように、その物理的な働きによって自然に電圧が発生し、外部電源を必要としないものがあります。他のセンサーでは出力電圧と供給(または励磁)電圧の比率が測定量に比例します。これらはレシオメトリック変換器と呼ばれます。ポテンショメータやストレインブリッジがその良い例です。最後に、トランスデューサーの中には、電源電圧に依存しない出力(例えば0~5V)を生成する信号調整(シグナルコンディショニング)回路を内蔵しているものもあります(一定の範囲内のみ)。

電流出力

圧力変換器、赤外線温度計、回転数センサー、超音波位置センサーなど、さまざまな種類の頑丈な工業用センサーがパッケージされており、これらは工業用電流ループまたは4~20mA出力と呼ばれる標準的なタイプの出力を備えています。これらのセンサーは一対のワイヤーだけで電力を供給し、出力を送信するという巧妙な仕組みになっています。公称DC24Vの電源電圧で動作するように設計されていますが、通常はこれよりもかなり低い電圧(15V以下の場合もある)で動作します。電流ループ方式は、干渉を排除するのに非常に優れており、配線の抵抗による誤差も生じない。通常は、4mAがセンサーの最小出力、20mAがフルスケール出力に相当します。電流を電圧に変換するには、反対側が接地された抵抗器に電流をかければできます。例えば、250Ωの抵抗器に4〜20mAを印加すると、1〜5Vの信号に変換されます。この場合、トランスデューサーのヘッドルームが最大5V失われることに注意してください。つまり、トランスデューサーには、抵抗値に応じて変化する電源電圧がかかることになります。これは通常は問題ではありませんが、用途に合わせてデータシートを確認してください。時には、より小さな抵抗を使用して電圧を増幅する必要があるかもしれません。

抵抗出力

抵抗を電圧に変換する方法はいくつかありますが、非常に簡単な方法は、センサーと普通の抵抗器を使って、それらを分圧器にすることです。出力電圧は、センサーの抵抗値によって変化します。感覚的に電圧が変化するように、固定抵抗器の値を選択することができます(またはトリムポットを使用することでできます)。電圧は抵抗値に対して直線的には変化しませんが、これはソフトウェアで対処できます(下記参照)。オペアンプを使って直線的な出力を得る方法もありますが、ここでは説明しません。他の方法としては、抵抗器をRC(抵抗器-コンデンサ)発振器の一部にして、抵抗値の線形関数である発振の周期を測定する方法があります。これはPiでの実用にはあまり適していません、少なくとも、プログラミング言語Node-REDを使うことはできません。もう1つの方法は、Arduinoなどのマイクロコントローラー・ボードを使って周期の測定を行い、その結果をシリアル・リンク経由でPiに送信することです。

アナログ・デジタル変換

ADCは、入力された電圧を表すデジタル数値を出力する。アナログからデジタルへの変換にはいくつかの異なる方法があり、それらを実装するための膨大な数のチップが存在します。ここでは、ADCの主な特性をいくつか紹介します。

電圧リファレンス:ADCが出力するデジタル数値は、入力電圧と基準電圧(VREF)の比の関数です。リファレンスの精度が高ければ高いほど、結果も正確になります。ほとんどのADCはリファレンスを内蔵していますが、そうでないものもあります。一部のADC(Arduinoに搭載されているものなど)では、独自の電源をリファレンスとして使用することができます。

入力範囲:ADCが受け入れることのできる電圧範囲です。多くの場合、0VからVREFまで、またはその倍数の範囲です。両極性の入力範囲を持つものもあります(通常は-VREF~VREF)。ADCの入力電圧範囲を超えると、おかしな動きをしたり、壊れたりすることがあります。

チャネル数:一部のADCはマルチプレクサを内蔵しており、複数の入力を変換することができます(ただし、通常は同時に変換することはできません)。

ビット数(分解能):これは、ADCがどれだけ小さな電圧差を識別できるかを示します。ビット数が多いほど分解能が高くなります。例えば、8ビットのADCは256の入力ステップを持っていますが、ADCはその入力範囲で2B(Bはビット数)の異なる電圧ステップを解決します。必要以上のビット数を使用する意味はありません。例えば、12ビットのADCは4096の入力ステップを持ちます。これは、約0.025%の分解能に相当します。これを有効に活用するためには、適切な信号処理回路と高精度なセンサーが必要です。

変換時間/レート:ADCは「連続」ではなく、入力データを定期的にサンプリングします。ある種のADC(デルタ・シグマ)は非常に正確ですが、速度は遅くなります。他のタイプ(フラッシュ)は非常に高速ですが、精度は低いです。その中間に位置するのが逐次比較法(SAR)ADCで、高精度で中速のアプリケーションに適しています。

出力インターフェース:ADCには、パラレル(1ビットにつき1本の配線)や、SPIやI2Cなどのシリアルフォーマットを含む、さまざまなデジタルインターフェースが用意されています(詳細は後述します)。

入力電圧の計算

ADCは、その出力を整数(整数)として出力します。この数値は、0~2Bの範囲になります。Bは分解能のビット数を表します。ADCをアプリケーションで使用する場合、通常、この数値を電圧に戻したいと思います。メーカーのデータシートには、その方法が記載されています。ほとんどのADCの場合

Screenshot_2020-11-13_at_19.32_.26__e59b400204bda7ed81c863a1901c4b0eaea81e5d.png

となります。ここで、nはADCで生成される数、Bはビット数です。

例えば、10ビットのADCで、基準電圧が3.3Vだったとします。出力値は0~1023までになります。620を出力した場合は、入力が2.0Vだったことを意味します:Screenshot_2020-11-13_at_19.32_.33__bbe14949b3c3ce7c0eacfc71f0465d8dd93717ce.png

コード(Javascript)では以下のようになります:

// n is the input value from the ADC. const steps = 1023;
const Vref = 3.3;
var Vin = Vref * n / steps;

Raspberry Piは悲しいことに、ADCを内蔵していません。しかし、多くのアドオン・オプションが用意されています。Node-REDには、マイクロチップ社製のADC(MCP3008)と連動するノードがあります。これは、SPI(Serial Peripheral Interface)出力を備えた10ビット、8チャネルのSAR ADCです。つまりわずか数本の配線でPiに接続できるのです。
配線の手間を省くために、1つまたは2つのHATが用意されています。例えば、 RasPiO Analog Zero boardが挙げられます。

Arduinoのatmega328のようなマイクロコントローラには、ADCが内蔵されています。これらのADCはPiに代わってアナログ電圧を読み取り、そのデータをシリアル接続、あるいはBluetoothやWifiなどのRFリンクで送り返すことができます。

センサーのデータシートを読む

ここではデータシートで目にすることが多い、アナログセンサーの一般的な特性をご紹介します:

  • 定格 - センサーが測定できる物理量(入力)の最大値。
  • FSO(full scale output) - 定格入力時にセンサーが出す出力。
  • ゼロ・オフセット - センサーの入力がゼロの時の出力値。
  • 直線性(線形成) - 入力から出力までの特性が直線グラフからどれだけ乖離しているかを、FSOに対するパーセンテージで表したもの。
  • ヒステリシス - 入力が増加しているか減少しているかによって、センサーの入力と出力の関係が異なる場合があります。この偏差は、FSOに対するパーセンテージで表されます。
  • 温度計数 - ゼロ・オフセットやFSOが温度によってどの程度変化するかを示されています。
  • 電源電圧 - 最小値と最大値が示されています。
  • スパン誤差 - 製造上のばらつきなどにより、FSOがどの程度変化するかを示しています。
  • オフセットエラー - 上記と同様の理由でゼロ・オフセットがどの程度変化するかを示しています。

     

センサーデータの処理と校正

センサーの出力をADCで読み取ると、得られるのは数値だけです。この数値をADCの入力電圧に変換する方法を見ていきましょう。次に、この電圧で何かに役立つことをする前に、この電圧を物理量に戻す必要があります。そのためには、まずシグナルコンディショニングの効果を「元に戻す」必要があります。次にセンサーの影響を「元に戻す」必要があります。

ここでは、Node-REDのfunctionノードに入れるものの例を示します:
注意:数学やコーディングに慣れていない方には、以下の内容は難しいと感じるかもしれません。このコードをコピーして貼り付けてください。異なる抵抗やセンサーを使用する場合はどのビットを変更するかを知る必要があるだけです。

ADCに接続されたサーミスタには、非常にシンプルな信号処理が施されており、単なる分圧器です。ポテンシャルデバイダには次のような特性があることが分かっています:
Screenshot_2020-11-13_at_19.43_.38__adba00925b618013ad29aed53e8bbc7ae58cfd90.png

今回の回路では、サーミスタはR1です。この式を変形してサーミスタの抵抗値を求めることができます:

Screenshot_2020-11-13_at_19.43_.43__960d8a77e62251d4fd5bdb37f5b1d53bf0d4f53d.png

今回の場合、 Vin が3.3、Vout がADCに入力される電圧、R2が10kとなっています。コード(javascript)では次のようになります:

// Vadc is the voltage from the ADC.
// R1 will come out in same units as R2 const R2 = 10e4; // Ohms
var R1 = R2 * (3.3/Vadc - 1);

これでシグナルコンディショニングしたものを“元に戻す”ことができました。今度は、トランスデューサーに同じことをする必要があります。そこで、R1をVishay社製の10K NTCサーミスタにします(部品番号はNTCLE100E3103HB0 (538-0654))。  メーカーのデータシート には、与えられた抵抗値に対する温度を求めるための式(「拡張Steinhart and Hart」式)が記載されています:

 Screenshot_2020-11-13_at_19.50_.16__6edef187707d0cd37c98b0b59fb4284205b24bb3.png

ここで、Rは抵抗値(単位:オーム)、Tは温度(単位:ケルビン)です。係数A1、B1などの値を求めるためには、値の表がありますが、使用するサーミスタに適した項目を見つける必要があります。使用するサーミスタは10Kタイプです(R25 = 10,000Ω)。「Electrical Data And Ordering Information」の表を見ると、使用するサーミスタの「B25/85」の値が3977であることがわかります。この数値を「Parameters for Determining Nominal Resistance Values」の表で調べてみると、9行目に次のような値が出てきました:

Screenshot_2020-11-13_at_19.55_.34__f2beb1d56effbfd54d91d7040b5d355dfe950d38.png

Rref は、25℃におけるサーミスタの値であるR25と同じで、10,000Ωとなります。

これをコード化します:

// R1 is already set from earlier.

const A1 = 3.354016e-03;
const B1 = 2.569850e-04;
const C1 = 2.620131e-06;
const D1 = 6.383091e-08;
const Rref = 10e3;
var k = R1/Rref; // We make a substitution here to simplify things.
var T = 1.0 / ( A1 + B1*Math.log(k)

+ C1*Math.pow(Math.log(k),2)

+ D1*Math.pow(Math.log(k),3) );

var Tc += 273.15 // Turn from Kelvin into degrees C

先ほどのADCの計算と合わせて、MCP3008に接続されたサーミスタから温度を計算するNode-RED関数ノードを作成することができます:

var n=msg.payload;
const steps = 1023;
const Vref = 3.3;
var Vadc = Vref * n / steps;
// Vin is the voltage from the ADC.
// R1 and R2 must be in same units (e.g. K or ohms)
const R2 = 10e3;
var R1 = R2 * (3.3/Vadc - 1); 
const A1 = 3.354016e-03; 
const B1 = 2.569850e-04; const 
C1 = 2.620131e-06; 
const D1 = 6.383091e-08; 
const Rref = 10e3;
var k = R1/Rref; // We make a substitution here to simplify things. 
var T;
if (k > 0) {
  T = 1.0 / ( A1 + B1*Math.log(k)
                 + C1*Math.pow(Math.log(k),2)
                 + D1*Math.pow(Math.log(k),3) );
} else {
  // Avoid taking logs of negative numbers 
  T = 0.0;
}
var Tc = T - 273.15 // Turn from Kelvin into degrees C 
msg.payload = Tc;
return msg;

多くのセンサーは、電圧と入力値の関係が直線的であるため、サーミスタのような複雑な式は必要ありません。ここでは、0〜25mbarを計測し、1〜5Vの出力を得る圧力センサーの例を示します:

const Vmax = 5.0 // Sensor max output of 5V. 
const Vmin = 1.0 // Sensor minimum output of 1V.
const span = Vmax - Vmin;
const Pmax = 25.0;
var P = Pmax * (Vadc - Vmin) / span;

ある入力に対するセンサーの出力を正確に把握できないことがあります。データシートがなかったり、特性に大きな製造上のばらつきがあったり、時間の経過とともに特性が変化していたりするからです。これに対処するためには、センサーを校正する必要があります。既知の入力(例:圧力)を加え、その出力を正確に測定します。この作業は通常、最低2つのデータポイントで行う必要があります。その後、データ処理コードを新しい数値で更新する必要があります。

ほとんどのセンサーは、製造時に校正されています。これを証明する校正証明書が付属しているものもあります。また、ある種の自動校正ルーチンが組み込まれているものもあります。また、センサーの校正を代行し、校正が国家標準にまで遡って行われていることを示す証明書を発行してくれる会社もあります。これは通常、安価なものではありませんが、重要な科学実験の一部としてセンサーを使用する場合などに必要となります。また、センサー(電子天秤など)を使用して、人々に販売する商品の量を測定する場合にも、校正は重要です。

デジタルセンサーは、現実世界の「アナログ」値を測定しますが、センサーとすべての信号調整、フィルタリング、アナログ-デジタル変換を1つのモジュールまたはチップにまとめ、数ある一般的なフォーマットの中から1つを選んで出力します。チップの中には小型のものもあり、はんだ付けは容易ではありませんが、プロトタイピングのために、メーカーや RS Components などのオンラインショップで、ほとんどのデバイスのブレイクアウトボードを入手することができます!

以下の表は、デジタルセンサの例です:

Device Type Interface RS Stock Number
MAX31855K 熱電対アンプとADC SPI (190-5078)
DS18B20 温度センサ 1-wire (190-1709)
MCP9808 温度センサ I2C (770-9892)
TMP06 産業用非接触温度センサ I2C (160-9817)
MS560702BA03-50 気圧/高度センサ I2C or SPI (893-7095)
BME280 温度、圧力、湿度センサ I2C or SPI (174-3744)
CCS811 エアークォリティセンサ I2C (174-3732)
TSL2561 光レベルセンサ I2C (642-4367)
ADXL345 3軸加速度計 I2C or SPI (709-8439)
L3GD20H

3軸ジャイロ

I2C or SPI (878-7461)
LSM303 加速度計とマゼントメーター(コンパス) I2C (163-9802)
LSM9DS0 慣性モジュール(3Dアクセル、ジャイロ、磁力計) I2C or SPI (110-6555)
GPS-1216F GPS受信機 UART (203-4661)

表1:デジタルセンサの例

デジタルセンサ出力タイプ

デジタルセンサには、さまざまな出力タイプがあります。これらのほとんどは、PiのGPIOポートと直接互換性があります。

Parallelインターフェースは、最近ではそれほど一般的ではありませんが、たまに目にすることがあります。非常に高速で、使い方も比較的簡単ですが、欠点もあります。パラレルインターフェースには多くの配線が必要で、通常は1ビットにつき1本の配線が必要です。つまり、たくさんのGPIOピンが必要なのです。また、データラインに加えて、データ転送のタイミングと方向を調整するハンドシェイクラインもあります。入力デバイスではありませんが、パラレルインターフェースを使用する一般的な製品として、液晶ディスプレイがあります。

SPISPI(Serial Peripheral Interface)は、センサーと「ホスト」CPU(Piやマイクロコントローラーなど)の間でデータを転送するための非常に一般的な規格です。

一般的に、SPIは4本の配線を使用します(グランドと電源の接続を除く):

• SCLK - シリアルクロック
• MOSI - マスター出力、スレーブ入力
• MISO - マスター入力、スレーブ出力
• SS or CS - スレーブ選択またはチップセレクト

[注-ハイテク業界では、「マスター」と「スレーブ」という言葉の使用に取り組み始めています-詳しくはこちら]

SPIの用語では、「マスター」とはホストCPU(ここではPi)を指し、「スレーブ」とはホストCPUに接続されたデバイス(センサーなど)を指します。SPIはバスシステムです。マスターに複数のスレーブデバイスを接続することができますが、それぞれにCS信号が必要となります。CS信号は反転しており、Highの場合、スレーブデバイスはそのMISO出力を高インピーダンス(フローティング)状態に保ち、他のデバイスがバスを使用できるようにします。Lowの場合、スレーブはバスへの送信を許可されます。

SPIのいくつかの特性について:

  • シリアルプロトコル - データビットは一度に1つずつ送信されます。
  • 同期的 - データビットはSCLKラインの制御下で送信されます。
  • 全二重 - 転送には2つの回線が使用され、マスターからスレーブへの送信にはMOSI回線が使用され、その逆にはMISO回線が使用されます。これは、マスターとスレーブが同時にデータを交換できることを意味します。
  • 高速 - SPIインターフェースを備えたほとんどのデバイスは、毎秒500,000バイトに相当する4MHz以上のクロックレートをサポートしています。

PiはGPIOポートにSPIインターフェースを搭載しており、2つのチップセレクト信号を備えているので、2つのSPIデバイスを簡単に接続することができます。理論的には、他のGPIOピンを追加のCS信号として使用することも可能ですが、その場合はソフトウェアで若干の工夫が必要になります。Arduinoのような他のほとんどのマイクロコントローラもSPIを内蔵しており、簡単に使用できるライブラリも用意されています。

SPIを設定する上での注意点:

  • クロックの極性(CPOL=0, CPOL=1)と位相(CPHA=0, CPHA=1)の2種類のモードがあります。これにより、4種類のモードでインターフェースを設定することができます。マスターとスレーブが同じモードを使用するようにする必要があります。

  • また、MSB(最上位ビット)とLSB(最下位ビット)のどちらを先に送信するかなど、データプロトコルの他の側面はデバイスによって異なり、設定はマスターとスレーブで同じでなければなりません。

  • SPIデバイスには最大指定クロック速度があります。マスターはこれを超えない設定する必要があります。もしそうでない場合、データの破損が起こります。

    上記内容とさらに詳しい内容はデバイスのデータシートに記載されています。

I2CI2C(Inter-Integrated Circuit)は、SPIと同様に同期式のシリアルインターフェースバスですが、いくつかの大きな違いがあります:

  • 4本のラインを使うところをSCKとSDAの2本だけにしています(もちろん、電源とグランドは除く)。
  • 半二重方式で、デバイスが同時に送信と受信を行うことはできません。
  • SPIよりも低速です(通常は100kHzまたは400kHzのクロックレート)。
  • より複雑なプロトコルを持っています(詳細はこの記事では説明しません)。
  • アドレッシングが可能なので、複数のデバイスをバスに接続することができ、デバイスごとにチップセレクトラインを必要としません。
  • バスには複数のマスターが存在します。
  • すべてのソフトウェアを自分で書かなければならないという点では、SPIよりも不便ですが、簡単に使えるライブラリが多数存在します。
  • SCKとSDAのラインは、バスのどこかにプルアップ抵抗が必要です。

I2Cは、SPIと同様に、ほとんどのマイクロコントローラに搭載されています。Piには、2つのI2Cインターフェースがあります。1つは、コネクタの3番ピン(SDA1)と5番ピン(SCL1)を使用するもので、一般的な使用に適しています。もう1つは、27番ピン(ID_SD)と28番ピン(ID_SC)で、一般的にHATプロトコル用に設定されています。

I2Cを使用するセンサーには、温度センサー、湿度センサー、圧力センサーなどがあり、数え上げればきりがありません。I2Cバス上で複数の同じセンサーを使用するために、メーカーは通常、センサーのアドレスビットの一部を選択するためのピンを提供しています(アドレスの残りの部分は固定で、デバイスやメーカーによって異なります)。これらのビットはデバイスごとに異なるように設定する必要があります。通常、一部をグランドに、一部を電源レールに引きます。利用可能なアドレスラインの数はセンサーによって異なります。1本しかないものもあれば(同じデバイスが2台までバスに接続可能)、3本まであるものもあります(同じようなデバイスが8台まで接続可能)。

UART(またはシリアル)プロトコルUARTとは、Universal Asynchronous Receive Transmitterの略です。UARTプロトコルは、SPIと同様に全二重のシリアル通信方式ですが、以下の点で異なります:

• UARTプロトコルのpoint-to-point - バスではありません。マイクロコントローラー(またはPi)のUARTインターフェースは、通常、1つのデバイスとしか通信できません(RS485など、この制限を克服する方法もありますが、この記事では説明しません)。
• 非同期式 - 別のクロックラインを必要としません。これは良いことでもあり、悪いことでもあります。配線の手間は省けますが、2つの機器があらかじめ同じビットレート(ボーレートと呼ばれることもあります)に設定されている必要があります。

シリアルインターフェースの2本のラインは、通常、TXD(送信データ)とRXD(受信データ)と呼ばれています。これらの名前は、各デバイスに関連するデータの進行方向(アウトまたはイン)にちなんでいることに注意してください。つまり、この2つのラインを接続すると、ラインが入れ替わることになります。つまり、一方のRXDがもう一方のTXDになるのです。

Piは、8番ピン(TXD)と10番ピン(RXD)にUARTインターフェースを備えています。

UARTプロトコルを使用する一般的なセンサーとして、GPSレシーバーがあります。GPS受信機モジュールの中には、3.3Vまたは5Vの電源を持ちながら、1.8Vのコアを使用しているものがあります。これは、シリアルラインにレベルコンバーターが必要であることを意味します。通常、GPSレシーバー、アンテナ、レベルコンバーターを1つのプリント基板にまとめたブレイクアウトボードが販売されています。

プリパッケージのセンサーの中には、RS232のUARTプロトコルを使用しているものがあります。このプロトコルは、通常の論理レベルではなく、高い正負の電圧を使用します。これらのセンサーをPiのUARTピンで使用するには、特別なRS232レベルコンバータチップが必要です(ただし、いくつかの受動的な部品を使用して、多くの場合、これを行うための様々なハックがあります)。

シリアル機器をPiに接続するもう一つの方法は、USBシリアルケーブルを使うことです。USBシリアルケーブルには、TTL(ロジックレベル)とRS232(正/負のハイレベル信号)の2種類があります。TTLタイプには3.3Vと5Vのバージョンがありますので、用途に合わせてお選びください。Arduinoのような多くのマイクロコントローラー・ボードは、ロジックレベルのUART接続(TXD、RXD)を備えていますが、USBシリアルアダプタも内蔵しており、Piに接続すると便利なシリアルインターフェース(例:/dev/ttyACM0)として表示されます。

1-Wire Sensors

ダラス・セミコンダクター社(現マキシム・インテグレーテッド社)が発明した「1-Wire」インターフェースを採用した温度センサー(およびその他のデバイス)があります。この「1-Wire」はデータと電源の両方を伝送します。もちろん、これらのデバイスには、1本のワイヤー(配線)だけでは回路を完成させることができないため、グランド接続も必要です。1-WireはI2Cに似ていますが、余分なクロック信号と電源の接続は必要ありません。

マイクロコントローラには1線式インターフェースは搭載されていませんが、ほとんどの場合、ソフトウェアでプロトコルを実装することができます。これは「ビット・バンギング」と呼ばれる技術の一例です。ビット・バンギングは、通常、正確なタイミングを必要とするため、LinuxなどのOSでは非常に困難です。1-WireのセンサーをPiに接続したい場合は、DS2482-100のようなI2C-1-Wireブリッジチップを使用するのが最も良い方法でしょう。

パルス出力付きセンサー

センサーの中には、発生するパルスの速度やタイミングを変えることで、アナログ情報を伝えるものがある。この種のセンサーの例としては、超音波距離測定器がある。送信したパルスと受信したパルスの間の時間は、距離に比例します。Piは一般的に、高速で正確なパルスタイミングやパルスカウントを行うのは得意ではありません。このような用途には、ハードウェアでカウンター/タイマーを備えたArduinoのような「ベアメタル」タイプのプラットフォームにインターフェースを「アウトソース」するのが最適です。

パルス出力センサーの他の例には、回転速度を検出するセンサーであるタコメーターが含まれます。この例については、オプトスイッチのセクションで説明しました。多くの場合パルス出力を持つ別のタイプのセンサーは、液体流量センサーです。

USB センサー

パッケージされているセンサーの中には、USBで接続できるものもありますが、すべてのメーカーがPiで動作するソフトウェアやドライバを提供しているわけではありません。USBセンサーの中には、UART出力のセンサーにUSBシリアルコンバーターを付けただけのものもあります。これらは特別なドライバを必要としませんが、メーカーがデータプロトコルを記述していない場合は、Piでの使用がほとんど不可能な場合があります。

オーディオビジュアル入力

これまでは、主にPiのGPIOポートに接続するセンサーを見てきました。

もう一つの入力装置は、視聴覚系(オーディオ・ビジュアル)のものです。マイク(音声入力)やカメラ(映像入力)などがあります。

オーディオ入力Piには、オンボードのオーディオインターフェースがありません。適切なオーディオADCを搭載したHATもありますが、最も安価なソリューションは、外付けのUSBサウンドドングルを使用することです。これらのデバイスは通常、3.5mmジャックによるステレオ(2チャンネル)オーディオの入出力を備えています。

ビデオ入力コンポジットビデオやHDMIなどのビデオ信号をキャプチャするには、大量のCPUパワーと特殊なインターフェースが必要です。一般的なビデオキャプチャーは、Piでは容易ではありません。安価で高価なUSBビデオキャプチャーデバイスは数多くありますが、Linuxドライバを提供しているメーカーは少なく、ましてやPiのARMプロセッサに対応しているものはありません。

しかし、Piには独自のカメラ用の専用コネクタがあり、HDビデオや高解像度の静止画を撮影することができます。

Piカメラには、「NoIRカメラ」があります。これは、通常のデジタルカメラに装備されている赤外線カットフィルターがないものです。これは、暗い場所でもよく見えることを意味しています。NoIRという言葉は少々紛らわしいのですが、この「No」は赤外線そのものではなく、赤外線カットフィルターがないことを意味していることを覚えておいてください。つまり、特に暗いところを見たいのでなければ、NoIRのカメラは買わない方がいいでしょう。昼間の写真では、むしろ白っぽく写ってしまいます。

センサーと入力についてまとめ

この記事では、さまざまな種類のセンサーと入力デバイスについて説明してきました。デジタル入力は、追加の電子機器が必要な場合もありますが、Piに接続するのは比較的簡単なのがお分かりいただけたかと思います。

対して、アナログセンサーには、シグナルコンディショニング(信号の調整)とアナログ - デジタル変換器の両方が必要です。

デジタルセンサはますます普及しており、さまざまな一般的なプロトコルの1つで出力を提供し、そのほとんどはPiによって十分にサポートされています。

センサーや入力機器の中には、Piに簡単に接続できるものがあります。また、HATやその他のインターフェイスボードを利用できるものもあります。

一部のセンサーと入力デバイスは、Piに簡単に配線できます。さらに多くの場合、HATまたはその他のインターフェイスボードを利用できます。

さまざまなセンサーすべてをPiに接続する方法を詳細に説明することはできませんでしたが、製造元のデータシートを理解し、インターネットでその他の必要なものを見つけることができる十分な基本情報と用語を提供できれば幸いです。活発なRaspberry Piコミュニティが存在します。多くのメンバーが有用な記事、ビデオ、フォーラム投稿を公開しているため、必要なものを見つけるのは簡単です。

I am an inventor, engineer, writer and presenter. Other stuff: Royal Academy of Engineering Visiting Professor of Engineering: Creativity and Communication at Brunel University London; Fellow of the Institution of Mechanical Engineers and have a PhD in bubbles; Judge on BBC Robot Wars.