ラズベリーパイセンサーとアクチュエーター制御
通常、プログラマーとしてディスク上のデータを操作し、運が良ければ画面に絵を描きます。これは、プログラマーとして実世界から感知されたデータを操作し、実世界を移動するデバイスを制御できる物理コンピューティングとは対照的です。
目標
Raspberry Piを使用して、加速度計の値を読み取り、サーボモーターを制御します。
定義
- ラズベリーパイ
- 2つのUSBポート、HDMI出力、イーサネット、そして最も重要なのは… を備えた35ドルの小型Linuxコンピューター
- GPIOピン
- 汎用入力/出力ピン
- これは、真に「物理コンピューティング」を可能にするコンポーネントです。プログラマーは、各ピンの電圧を高くまたは低く設定できます。これにより、アクチュエーターと通信できます。また、各ピンの現在の電圧を読み取ることもできます。これは、センサーがあなたに話しかける方法です。各ピンはバイナリ状態を表し、0または1のみを出力でき、その間には何も出力できないことに注意することが重要です。
この記事では、4つの基本的なPythonプロジェクトを調べて、RaspberryPiのハードウェア機能を示します。それらのプロジェクトは次のとおりです。
- LEDを点滅させます。
- 鍋を読む。
- ストリームデータ。
- サーボを制御します。
LEDを点滅させます。
LEDは発光ダイオードです。ダイオードは、電流が一方向に流れることを可能にするが、他の方向には流れないようにする回路要素です。発光とは…発光することを意味します。通常のLEDには10〜30 mAの範囲の電流が必要で、約2〜3ボルト低下します。 LEDをPiのGPIOに直接接続すると、30 mAをはるかに超える光源になり、おそらくLED(および場合によってはPi)を揚げます。これを防ぐには、抵抗を配置する必要があります。数学をしたい場合は、次の式を使用して適切な抵抗を計算できます。
R =(Vs-Vd)/ I
ただし、計算を行いたくない場合は、500〜1500オームの抵抗を選択してください。すべての回路要素(LEDと抵抗器)をまとめたら
コードも非常に単純です。ただし、最初にRPi.GPIOをインストールする必要があります。 (OSにプリインストールされている場合があります。)
import timefrom itertools import cycleimport RPi.GPIO as ioio.setmode(io.BCM)io.setup(12、io.OUT)o =cycle([1、0])while True:io.output(12、o .next())time.sleep(0.5)
重要な行は基本的に次のとおりです。
io.setup(12、io.OUT)io.output(12、1)
これらのコード行は、ピン12を出力として設定し、1(3.3ボルト)を出力します。回路に接続された上記のコードを実行すると、LEDが0.5秒ごとに点滅するのがわかります。
鍋を読む。
ポットは、可変抵抗器であるポテンショメータの略です。これは、ノブを表すための空想的な言葉です。基本的に、ノブを回すと抵抗に影響し、ポットの両端の電圧に影響します。 ( V =IR
、 覚えて?)。ある物理的値に対して電圧を変化させることは、機能するセンサーの数であり、このクラスのセンサーはアナログセンサーとして知られています。 。 GPIOピンはバイナリ状態しか表現できないと言ったのを覚えていますか?そのアナログ電圧値をPiが処理できるビットのバイナリストリームに変換するには、さらにシリコンの補助を呼び出す必要があります。
そのシリコンの塊は、アナログ-デジタルコンバーター(ADC)と呼ばれます。私が気に入っているのはMCP3008と呼ばれ、10ビットチャネルが8つあります。つまり、それぞれ1024(2 ^ 10)の解像度で8つのセンサー値を読み取ることができます。これにより、0〜3.3ボルトの入力電圧が0〜1023の整数にマッピングされます。
図を簡略化するために、Piを一時的な黄色のラベルに変更しました
チップと通信するには、spidevというPythonパッケージが必要です。パッケージとMCP3008での動作の詳細については、このすばらしいブログ投稿をご覧ください
spidevがインストールされ、回路が構築された状態で、次のプログラムを実行して、ライブセンサー値を読み取り、それらをstdoutに出力します。
import spidev import timespi =spidev.SpiDev()spi.open(0,0)def readadc(adcnum):0でない場合<=adcnum <=7:return -1 r =spi.xfer2([1、( 8 + adcnum)<<4、0])adcout =((r [1]&3)<<8)+ r [2] return adcoutwhile True:val =readadc(0)print val time.sleep(0.5)
最も重要な部分は次の2行です:
r =spi.xfer2([1、(8 + adcnum)<<4、0])adcout =((r [1]&3)<<8)+ r [2]
それらは読み取りコマンドを送信し、関連する返されたビットを抽出します。ここで何が起こっているかについての詳細は、上記でリンクしたブログ投稿を参照してください。
ストリームデータ。
有線でデータをストリーミングするには、ØMQネットワークライブラリを使用し、REQUEST / REPLYパターンを実装します。 ØMQを使用すると、Pythonでクライアントとサーバーを非常に簡単にセットアップできます。以下は完全な実例です。
サーバー
import zmqcontext =zmq.Context()socket =context.socket(zmq.REP)socket.bind( 'tcp:// *:1980')while True:message =socket.recv()print message socket.send (「私はここにいます」)
クライアント
import zmqcontext =zmq.Context()socket =context.socket(zmq.REQ)a ='tcp://192.168.1.6:1980' socket.connect(a)for request in range(10):socket。 send( 'You home?')message =socket.recv()print message
これで、traitsとenamlを使用して、クライアント側できれいなUIを作成できます。 githubリポジトリのacc_plotデモをチェックして、クライアントによってプロットされるネットワーク上のPiストリーミングデータの例を確認してください。
サーボを制御する
サーボは(多くの場合小さな)モーターであり、特定の位置まで駆動できます。たとえば、特定のサーボについて、ドライブシャフトを0度から18度、またはその間の任意の場所に設定できる場合があります。ご想像のとおり、これは多くのタスク、特にロボット工学に役立つ可能性があります。
シャフトの回転は、GPIOピンの高電圧パルスの持続時間内に情報をエンコードするパルス幅変調(PWM)によって制御されます。ほとんどのホビーサーボは、標準のパルス幅の意味に従います。 0.5ミリ秒のパルスは最小位置に移動することを意味し、2.5ミリ秒のパルスは最大位置に移動することを意味します。このパルスを20ミリ秒ごとに繰り返し、サーボを制御します。
パルス幅は周波数よりもはるかに重要です
この種のタイミングはPythonでは不可能です。実際、最新のオペレーティングシステムでは実際には不可能です。制御コードでいつでも割り込みが発生し、サーボに希望よりも長いパルスとジッターが発生する可能性があります。タイミング要件を満たすには、カーネルモジュールの楽しい世界に入る必要があります。 ServoBlasterは、DMA制御ブロックを利用してCPUを完全にバイパスするカーネルモジュールです。ロードされると、カーネルモジュールは / dev / servoblaster
にあるデバイスファイルを開きます 位置コマンドを書き込むことができます。
この周りに、サーボ制御を簡単にする小さなオブジェクト指向レイヤーを作成しました。私のライブラリはここにあります:
https://github.com/jminardi/RobotBrain
サーボを5vに接続し、Piを接地してから、制御線をピン4に接続するだけです。
Pythonコードは非常に単純です:
import timeimport numpy as npfrom robot_brain.servo import Servoservo =Servo(0、min =60、max =200)for val in np.arange(0、1、0.05):servo.set(val)time.sleep( 0.1)
サーボをインスタンス化して、その set()
を呼び出すだけです。 浮動小数点値が0〜1のメソッド。githubのservo_sliderデモをチェックして、ネットワーク上に実装されたサーボ制御を確認してください。
詳細:RaspberryPiセンサーとアクチュエーター制御
製造プロセス