PCF8591の使用とPythonの制御
前書き
PCF8591チップ、A0、A1、A2、channel0-channel3、AIN0-AIN3、AOUT、SCL、SDAなどとI2Cプロトコルについて非常に混乱している必要があります。同時に、Pythonコードの0x40、0x41、0x42、0x43、および0x48が何であるか、およびbus.write_byte(0x48, 0x40) bus.write_byte(0x48, 0x40, value) bus.read_byte(0x48)
これらのコードが正確に何を制御するかを完全には理解していませんでした。
この記事は、上記のコンテンツを整理するのに役立ちます。
1.PCF8591とRaspberryPiの関係
非常に単純な視覚化を行い、システム全体をインレット/アウトレットデバイスとして扱います。
このデバイスには、AIN0、AIN1、AIN2、AIN3という名前の4つの入口パイプと、AOUTという名前の唯一の出口パイプがあります。また、それぞれchannel0、channel1、channel2、channel3という名前の4つの転送チャネルがあります。4つの入口パイプからの水は、制御下の特定のチャネルから流出し、メインパイプラインに入り、2つの出口パイプを通過できます-SDAそしてSCL、水処理および貯蔵施設に入ります。
Raspberry PIは「MASTER」、PCFは「SLAVER」であり、主従関係にあります。マスターデバイスがスレーブデバイスにデータを送信する場合は、データ転送を開始し、データをスレーブデバイスに送信し、最後にデータ転送を終了します。マスターデバイスがスレーブデバイスから送信されたデータを受け入れたい場合は、データ転送を開始して受信するコマンドも発行します。デバイスから送信されたデータは、最終的に受信プロセスを終了します。
1つのポイントを強調します。各データ送信は「MASTER」によってアクティブに開始されます。
はっきりしていますか?一般的な関係を整理した後、具体的な詳細を見ていきます。
2.PCFアドレスとA0-A2ピン
「MASTER」は「SLAVER」を1つだけ持つことはできません。したがって、「MASTER」の場合、「SLAVERS」には制御とコマンドの番号を付ける必要があります。この番号はPCFアドレスでもあります。アドレスのコーディング規則は次のとおりです。
これは7桁のバイナリ番号であり、最初の4桁は固定番号であり、最後の3桁はPCF-A0、A1、A2の3つのピンに対応していることがわかります。各ピンの値は0または1、合計2 ^ 3 = 8種類の配置、つまり合計8つの使用可能なアドレスにすることができます。したがって、1つの「MASTER」が最大で8つの「SLAVER」を同時に制御できます。PCF8591の場合、デフォルトのアドレスは0x48(16進数)で、2進数に変換すると1001000になるため、A0、A1、およびA2ピンがすべて0であることがわかります。
事前にもう1つ強調する必要があります。つまり、Pythonコードのすべての0x 16進数、0x48のみがアドレスを表し、PCFのみがアドレスを持ち、他のすべての16進数はアドレスを表しません。(これはシンクホールです)
3.I2CプロトコルとSDASCL
「MASTER」と「SLAVERS」の間で通信が必要であり、「SLAVER」に作業を割り当てるか、「SLAVER」に作業を報告させ、「SLAVER」にその方法を指示する必要があります。したがって、I ^ 2 C通信プロトコル(Inter-Integrated Circuit)と呼ばれる、それらの間の特定の通信方法があります。I ^ 2 Cバスは、バスに接続されたデバイス間の情報伝送を実現するために2本のワイヤを必要とします。1本はSDA(シリアルデータ)シリアルデータラインで、もう1本はSCL(シリアルクロック)シリアルクロックラインです。
次の図は、AD変換のI2Cデータ送信プロセスを示しています。
紛らわしいですね。それは問題ではありません、ここに視覚的な説明があります。前述のように、I2Cは通信手段であるため、このデータ送信プロセスは、I2Cのような特定の通信方法での通信として理解できます。もっと一般的に言えば、それは単なるチャットの会話です。理解する方法は?
チャットの最初のステップは、電話を取り出してWeChatを開くことです。(START条件に対応して、SDAラインとSCLラインのレベルが同時に一定の条件を満たすと、送信が開始されます。)
WeChatを開いた後、チャットする連絡先を見つける必要があります。「MASTER」には「SLAVERS」がたくさんあると前に言いましたが、このステップは「MASTER」が特定の「SLAVER」と話すことを選択することです。(ADDRESSに対応します。)
3番目のステップでは、「MASTER」は、このダイアログの目的が「SLAVER」に作業を割り当てることであるか、作業の終了後に「SLAVER」に報告させることであるかを決定します。(R / Wに対応し、R手段がW手段は、書き込み、読み取り、このデータ送信を制御する目的は、ラズベリーPiはPCFに値を書き込むか、ラズベリーPiはPCFから値を読み出すか否かである。)
あなたがあることがわかります多くのACK。ACKは確認文字を意味し、データ受信者がデータ送信者に「受信済み」と通知することを意味します。
その後はデータ送信となり、1バイトのデータが送信されるたびにACKが返送され、データの受信を確認します。
4、Pythonコードは値の読み取り/書き込みを制御します
import smbus
import time
if __name__ == "__main__":
bus=smbus.SMBus(1)
bus.write_byte(0x48,0x42)
bus.read_byte(0x48)
while True:
num= bus.read_byte(0x48)
print(num)
bus.write_byte_data(0x48,0x42,160)
time.sleep(0.01)
実際、コードは非常に単純です。前のリファレンスで与えられたコードが混乱している主な理由は、多くのメソッドがカスタマイズされていることです。ここで、最も簡単な方法で記述します。使用されるコアメソッドは3つだけです。
bus.read_byte(ADDRESS)
bus.write_byte(ADDRESS, CONTROL_byte)
bus.write_byte_data(ADDRESS, CONTROL_byte, value)
名前が示すように、read_byteはPCFから1バイトのデータを読み取ること、write_byteはPCFに1バイトのデータを書き込むこと、write_byte_dataはPCFにデータを書き込むことです。
write_byteとwrite_byte_dataの違いは何ですか?
PART1で強調されたポイントを覚えていますか?各データ送信は「MASTER」によってアクティブに開始される必要があるため、write_byteの目的は、「MASTER」が通信する「SLAVER」を明確にし、接続を確立し、「CONTROLバイト」を使用して「SLAVER」に送信せずに動作する方法を指示することです。値。これが、コードの最初のステップがbus.read_byte(0x48)
Raspberry Piが主導権を握ってダイアログを開き、アドレス0x48に対応するPCF8591との接続を確立し、CONTROLバイトを介して動作モード(アナログ入力モード)を指定します。
2番目の質問は、CONTROLバイトとは何ですか?それは住所ではありませんか?
このとき、PART2で強調されている内容を覚えておく必要があります(アドレスは0x48のみ)。write_byteメソッドの2番目のパラメーターはCONTROLバイトです。
これは、CONTROLバイトの公式ドキュメントの説明です。8ビットのバイナリコード。1桁目と5桁目は固定番号(0)で、プログラムできる部分は2桁目です。これは、AOUT出力ポートがオンになっているかどうか、0はオンになっていない、1はオンになっている、このビットのみを表します。 1の場合、DAが機能し、デジタル信号がアナログ信号に変換されてAOUTポートから出力されます。3桁目と4桁目は、AINポートとチャネル間のデータ関係を明確にするために、4つの異なるアナログ入力モードを表します。
最初の写真には大きな疑問符があり、アナログ入力モードはこの疑問符を明確にするためのものです。2つの対応があります。1つはシングルエンド、つまり1対1です。たとえば、00モードでは、channel0から読み取られたデータは、AD変換後のAIN0ポートからのアナログ入力のデジタル値です。00モードの4つのAINポートは、チャネルに1つずつ対応します。10モードでは、 AIN0とAIN1は、channel0とchannel1に1対1で対応します。もう1つの対応は、差分、つまり差分です。たとえば、01モードでは、channel0の値はAIN0とAIN3の差であり、10モードでは、channel2の値はAIN2とAIN3の差です。
CONTROLバイトの7番目の8番目のビットはADチャネル番号であり、データを読み取るチャネルを制御するために使用されます。6桁目は自動インクリメントです。値が1の場合、データが読み取られるたびにチャネルが自動的に切り替えられます。最初にchannel0のデータが読み取られ、次にchannel1のデータが読み取られます。
Pythonコードでは、CONTROLバイトは16進数であり、バイナリに変換された後の8ビットのバイナリです。制御方法は次のとおりです。CONTROLバイトのコード化可能なビットに必要な値を決定し、8桁のバイナリ番号を取得し、それを16進数に変換して、Pythonメソッドを入力します。
これについて話した後、ほとんどのコンテンツはほぼ完成しています。コード例read_byteを続けると、値を読み取るプロセスはCONTROLバイトを必要としないため、パラメーターはADDRESSのみです。
ご覧のとおり、目的の数値が実際に読み取られる前に、別の空の読み取りがあります。これは、読み取りコマンドを受信した後、PCF8591が最後の変換データ送信とこのデータ変換を同時に実行するため、最初の空の読み取りのデータは不確実な数値であり、最初の空の読み取りは次の通常の読み取りを開始するため。
bus.write_byte_data(0x48,0x42,160)
write_byte_dataメソッドについて詳しく説明します。書き込まれた値はデジタル値として直接使用され、変換後に電圧の形式でアナログ量としてAOUTポートから出力されます。私たちが使用するPCF8591は8ビットのAD / DAコンバーターです。8ビットは、AD / DAのスケールが合計2 ^ 8 = 256であることを意味するため、送信されるデジタル値の範囲は0〜255です。たとえば、AOUTポートからLEDライトに3.13Vの電圧を出力する場合、書き込む必要のある値は3.13v / 5v * 255 = 160(ここでは、ADCは5vの基準電圧に接続されています)ですが、実際には電圧計で測定されます。このとき、LEDランプ両端の電圧は2.64vであり、理想値から一定の誤差があります。
五、何かもっと
私はほとんどすべてのアナログ入力モードを試し、マイクをさまざまなAINポートに接続し、さまざまなチャネルを選択し、オシロスコープ/ボルトメーター+パイソンによって描かれたグラフを使って多くの実験を行いました。差動モードではまだ説明が難しいものがたくさんあります。しかし、基本的に全体の原則が間違っていないことは確かです。
また、シングルエンドモードでは、AD変換のアナログ値はAINポートとGND間の電圧です。差動モードでは、AD変換のアナログ値は2つのAINポート間の電圧差であるため、1つのAINのみを使用する場合差動モードを使用する場合は、他のAINポートを接地することを忘れないでください。
六、学習体験
30時間以上の学習過程で得られた経験:
①以前の理解が正しいとは決して思わないでください。理解プロセス全体に誤りがあり、転覆して再構築する必要がある場合があります。
②インターネット上の情報は不均一で誤りだらけです。盲目的に信じてはいけません。
③実験は条件や現象を明確に記録する必要があります。そうしないと、現象/条件が明確に記録されないため、実験が何度も繰り返されます。
④真新しい知識システムを学ぶ過程で、たくさんの情報が殺到します。問題1を解決するための情報を検索すると、問題2が見つかり、次に問題2に注意が移り、新しい問題が発見されることがよくあります。無限のループ。ですから、時間内に立ち止まって、自分が誰であるか、どこにいるのか、何をしたいのかを考える必要があります。
⑤問題を記録してから、調査を続けます。2日目には、1日目の質問を振り返り、ため息をつく可能性が非常に高くなります。このようなばかげた質問をするにはどうすればよいでしょうか。
⑥チームメイトはとても重要です。ディスカッション/ストップロス/質問/レビュー/要約。