概要
- ラズベリーパイにはアナログ入力がありませんが、外部ADCを追加することで、現実世界の電圧をデジタル形式に変換して記録、操作、制御することができます。
- 一般的なADCオプションとしては、速度と精度のトレードオフを考慮したMCP3004/MCP3008、または低速のサンプリングレートで16ビットの読み取りを行うADS111xがあります。
- AdafruitのADS1115は、プログラマブルゲインアンプ(PGA)を備えたシンプルなオプションで、小さな電圧差を検出し、プログラム中にゲインを調整することができます。I2Cを使用してラズベリーパイに接続するのは簡単です。
ラズベリーパイには、箱から出してすぐにアナログ入力がありません。これは、Arduinoのようなマイクロコントローラベースのボードと比較すると不利になります。
しかし、落胆しないでください。検討すべきオプションはたくさんあります。ラズベリーパイと外部ADCを使用して、すぐに使い始めることができます。
なぜ入力を追加するのか?
現実の世界には、適切な回路があれば電圧を使って簡単に記述できる現象がたくさんあります。これらの電圧をデジタル形式に変換すれば、記録したり、操作したり、他のパラメータやデバイスを制御するために使用したりすることができます。
土壌の水分量、温室の温度、ハムスターの体重を監視したいと考えるかもしれません。Piにボリュームコントロールを追加したり、フェーダーのバンク全体を構築したり、ジョイスティックをゼロから設計したりしたいと考えるかもしれません。可能性は、ほとんど無限大です。
ADCのオプション
では、初心者にとって最適なADCはどれでしょうか?
最も一般的で簡単なオプションには、MicrochipのMCP3004(およびMCP3008)チップがあります。10ビットの4チャンネル(または8チャンネル)が得られ、最大200kSPSを読み取ることができます。一方、Texas InstrumentsのADS111xデバイスは、860SPSで16ビットを読み取ります。したがって、速度と精度(そして当然、価格)のトレードオフがあります。
多くのマイクロコントローラには、内蔵のADCが搭載されています。平均的なArduinoで見つかるATMegaは、他の機能に加えて、いくつかの10ビットチャンネルを提供します。これが、Arduinoがラズベリーパイではできないアナログ入力を提供できる理由です。すでにセットアップにArduinoが関与しており、10ビットの忠実度で十分な場合は、これが実際に最も簡単な方法かもしれません。
ここでは、AdafruitのADS1115を使用して、シンプルに説明します。
プログラマブルゲインアンプとは?
このチップには、プログラマブルゲインアンプ(PGA)を含む、いくつかの興味深い機能が備わっています。これにより、目的の値の範囲をデジタルで設定することができ、1ボルトの分数まで設定することができます。16ビットで表現できる値の数で、わずか数マイクロボルトの差を検出することができます。
利点は、プログラムの途中でゲインを変更できることです。MCP3004などの他のチップは、異なるアプローチをとります。追加のピンがあり、そこにリファレンス電圧を供給することができます。
マルチプレクシングはどうでしょうか?
マルチプレクサー(またはMUX)は、単一のADCを使用して多くの入力を読み取ることができるスイッチです。ADCチップに多くの入力ピンがある場合、内部でマルチプレクシングが行われています。ADS1115のMUXは4つの入力を許可しており、内部レジスタを使用して選択することができます。
レジスタの扱い
ADS1115は、これらのオプションに加えて、さらにいくつかのオプションを提供します。マルチプレクサーを操作したり、ゲインを調整したり、内蔵コンパレータを有効にしたり、サンプリングレートを変更したり、デバイスを低電力スリープモードにしたりすることができます。これらはすべて、いくつかのスイッチを操作するだけで行うことができます。
しかし、それらのスイッチはどこにあるのでしょうか?それらはパッケージの中にあり、レジスタと呼ばれる非常に小さなメモリのビットの形をしています。特定の機能を有効にするには、関連するビットを0ではなく1に設定するだけです。
ADS111xのデータシートを見ると、これらのモデルにはデバイスの動作を制御するコンフィギュレーションレジスタを含む4つのレジスタが搭載されていることがわかります。
たとえば、ビット14から12はマルチプレクサーを制御します。この3つのビットを使用すると、8つの構成から選択できます。ここで使用したいのは「100」で、入力0とグラウンドの差が得られます。一方、ビット7から5はサンプリングレートを制御します。1秒あたり最大860サンプルが必要な場合は、「111」に設定することができます。
設定するオプションがわかれば、ADCに送信する2バイトが得られます。後で1ビットずつ設定したい場合は、ビット演算子を使用して個別に処理することができます。
ここで混乱するかもしれません。この場合、2進数は値を表しているのではなく、個々のスイッチの値を表しています。これらの変数を、10進数または16進数で1つの大きな数字として表現することができます。しかし、頭痛を避けるためには、読みやすい2進数バージョンを使用する必要があります。
配線
このデバイスは、ブレッドボードに直接差し込むことができます。正の電圧入力は2~5.5Vの間で受け入れるため、ラズベリーパイの3.3Vレールがうまく機能します。
SDAとSCL入力をRPiの対応する入力に接続し、グラウンドと3.3vでも同じことを行います。グラウンドと電圧ラインの間にポテンショメータを接続し、中央のリードをADCの最初の入力に接続します。これで準備完了です!
I2Cの扱い
異なるADCは異なるプロトコルで動作します。ADS1115の場合、I2Cを使用します。
以下の例では、Pythonを使用してADCと対話します。しかし、その前に、設定を行う必要があります。最近のバージョンのRaspberry Pi OSでは、これは非常に簡単になりました。Preferences > Raspberry Pi Configurationに進みます。次に、InterfacesタブからI2Cをオンにします。
すべてが機能していることを確認するには、ターミナルを開いて次を実行します。
sudo i2cdetect -y 1
このコマンドはグリッドを出力します。すべてが機能しており、正しく配線されていると仮定すると、グリッドに新しい値が表示されます。これはADCのアドレスです。ここでは、コードで使用するときに「0x」を接頭辞として付ける必要があるため、16進値であることに注意してください。ここでは、0x48です。
アドレスがわかれば、SMBusライブラリを使用してI2Cコマンドを送信できます。ここでは2つのメソッドを扱います。1つ目はwrite_word_data()で、デバイスアドレス、書き込み先のレジスタ、書き込み値の3つの引数を受け取ります。
2つ目はread_word_data()で、デバイスアドレスとレジスタのみを受け取ります。ADCは電圧を継続的に読み取り、その結果を変換レジスタに格納します。このメソッドを使用すると、そのレジスタの内容を取得できます。
結果を少し整えてから、印刷することができます。ループの先頭に戻る前に、少し遅延を設けます。これにより、データに圧倒されないようにすることができます。
from smbus import SMBusimport timeaddr = 0x48bus = SMBus(1)# set the registers for readingCONFIGREG = 1CONVERSIONREG = 0# set the address register to point to the config register# write to the config registersbus.write_word_data(addr, CONFIGREG, (0b00000100 8) & 0xFF)# subtract half the range to set ground to zerob -= 0x8000# divide the result by the range to give us a value between zero and oneb /= TOP# cap at oneb = min(b, 1)# bottom is zerob = max(b, 0)# two decimal placesb = round(b, 2)print(b)time.sleep(.01)
もう終わりです。取得した値の範囲を希望の範囲にマッピングし、希望の小数点以下の桁数に切り捨てます。印刷関数を調整して、前回の値と異なる場合にのみ新しい値を印刷するようにすることができます。max、min、roundがわからない場合は、最も重要なPython関数20個のリストを確認してください。
ノイズの扱い
ただし、設定が非常に整頓されていなければ、ノイズが発生することがあります。これは、10ビットではなく16ビットを使用することの避けられない欠点です。そのわずかなノイズがより顕著になります。
隣接する入力(入力1)をグラウンドに接続し、モードを切り替えて入力1と入力2を比較するようにすると、はるかに安定した結果を得ることができます。また、ノイズを収集する長いジャンパーケーブルを短いケーブルに交換し、ついでにコンデンサをいくつか追加することもできます。ポテンショメータの値も影響します。
ソフトウェアのオプションもあります。ローリング平均を作成したり、小さな変更を無視したりすることができます。欠点は、余分なコードが計算コストを課すことです。Pythonなどの高レベル言語で条件文を記述し、毎秒数千のサンプルを取得する場合、これらのコストは急速に増加します。
さまざまな次のステップでさらに進歩
I2Cを介して読み取りを行うことは非常に簡単で、SPIなどの他の方法でも同様です。利用可能なADCオプションには大きな違いがあるように思えるかもしれませんが、実際には、そのうちの1つを動作させたら、その知識を他のADCに適用するのは簡単です。
そこで、さらに進めてみませんか?複数のポテンショメータを接続したり、光、音、温度を読み取ってみましょう。作成したばかりのコントローラを拡張して、本当にハンズオンのRaspberry Piセットアップを作成しましょう!
コメントする