前々回に製作したArduinoシールド風デバッグボードをベースに、pcDuino3 nano の I/O をPythonで操作するサンプルプログラムを作りました。
今回使用する機能は GPIO(汎用入出力)、アナログ入力、IIC です。
Python は2.x 系です。
***** 準備運動(しましょう) *****
プログラムのソースはこちらに置いておきますので、適当に自分のpcDuino3 nanoにダウンロードしてください。
ソースは3つに分かれています。
IOExample_main.py ...プログラム本体です。
HW.py ...I/Oを操作するクラスライブラリです。
HW_IIC.py ...IIC接続されたLCDを制御するクラスライブラリです。
また、このプログラムはIICインターフェースにアクセスするためにPythonのSMBusモジュールを使用しています。
SMBusはIICから派生した規格で、ソフトウェアから見ればIICと殆ど違いはありません。
Synapticを起動して(パスワードはubuntu)、”python-smbus"で検索するか、あるいはコンソールから
$ sudo apt-get install python-smbus[Enter]
とすればインストールされます。
インストールされたら、Pythonからは
import smbus
で利用できるようになります。
なお、私の環境ではpython-smbusをインストールした後、実際に機能を有効にするために一旦pcDuino3 nanoの電源を切る必要がありました(リブートではダメっぽい)。
***** プログラムの動作 *****
準備が出来たら、コンソールから
$ python IOExample_main.py [Enter]
と入力するか、前回紹介したSpyderで読み込んだ後、IOExample_main.py を実行してください。
プログラムの動作は大体こんな感じです
- 実行すると緑のLEDが点灯します。
- SW1を押すと黄色のLEDが点灯します。
- SW2を押すと赤色のLEDが点灯します。
- SW1とSW2を同時に押すと、プログラムが終了します。
- LCDの上段はLM35Zで測定した室温を表示します
- LCDの下段はボリュームの状態です。0~100.0%のスケールで表示します
温度はLM35Zの自己発熱の影響もあって、実際の温度よりもかなり高く表示されています。
ADコンバータの入力レンジを間違えているわけではありません。
心配ならADの端子電圧を測ってみてください。電圧[V] * 100.0が温度です。例えば電圧が0.274[V]だとすると、室温は27.4℃ということになります。
***** プログラムの中身について *****
短いプログラムなので、ソースを見ればどんな処理をしているかは判ると思います。
I/Oの操作の詳細についてはSparkfunのチュートリアルを参考にしてください。もしリンクが切れていたら、SparkfunのホームページからpcDuinoで検索してみてください。
このブログではポイントだけ説明しておきます。
***** 初めにモードの設定を *****
Arduino風ヘッダに割り当てられているI/Oのうち、いくつかは使用する前にモードを設定する必要があります。
自分の知っている範囲ではこんな感じです。
機能 値
===================================
デジタル出力 1
デジタル入力(プルアップなし) 0
デジタル入力(プルアップ使用) 8
UART 3
SPI 2
IIC (不要)
アナログ入力 (不要)
ところでUARTですが、こちらのSparkfunのチュートリアルではモード設定の処理が抜けており、このままでは動作しません。
実際にはプログラムの初めにこんな記述が必要です。
GPIO_MODE_PATH=os.path.normpath('/sys/devices/virtual/misc/gpio/mode/')
GPIO_MODE_PATH=os.path.join(GPIO_MODE_PATH, 'gpio0')
file = open(GPIO_MODE_PATH, 'r+')
file.write( "3" ) # "3" is serial(UART) interface mode.
file.close()
GPIO_MODE_PATH=os.path.normpath('/sys/devices/virtual/misc/gpio/mode/')
GPIO_MODE_PATH=os.path.join(GPIO_MODE_PATH, 'gpio1')
file = open(GPIO_MODE_PATH, 'r+')
file.write( "3" ) # "3" is serial(UART) interface mode.
file.close()
これでGPIO0とGPIO1がUARTモードになります。
***** デジタルインプット、アウトプット *****
特に説明するほどのものでもないと思います。
サンプルプログラムの通り、モードを設定後、ファイルを開いて読み書きするだけです。
***** アナログ入力 *****
モードの設定は不要です。ファイルを開いて読み込むだけです。
ただし、読み込んだ値は文字列なので、数値に変換する必要があります。
前々回の記事で説明した通り、チャンネルによって分解能と電圧範囲が異なります。
***** IIC で LCD を制御する *****
SMBusモジュールを使用しています。
ここではIICの使い方の例として8文字x2行のLCDを使用しています。
使用したのは秋月電子のAE-AQM0802です
制御コマンドのやり取りについてはネット上にある色々な情報を参考にさせてもらいました。
***** ところでIICの電気的仕様は? *****
秋月電子のFAQによると、AE-AQM0802はRaspberry Piでは動作しないことがあるそうです。
理由はRaspberry Pi の基板に実装されている1.8kΩのプルアップ抵抗がAE-AQM0802の負荷として重すぎ、信号線をLレベルにしようとした時に、電圧が十分なところまで下げられないためとのことです。
pcDuino3 nanoはどうかというと、基板上に2.2kΩのプルアップ抵抗が実装されており、無効にすることはできません。
LCDの制御は問題なく出来ているようなのですが、念のためオシロで信号線の波形を記録しておきました。結果は以下の通りです。
SCL(シリアルクロック)はA20が駆動するから良いとして、SDA(シリアルデータ)はAE-AQM0802が駆動する時(Acknowledgeを返す時)、狙ったようにほぼ1.0Vでした
とはいえ、波形を見ただけでは、設計の妥当性は確認できません。
肝心のA20 が、H/L入力レベルを認識する電圧が不明なためです。
ネット上に出回っているデータシートを読んでみましたが、GPIOとして使用した時のしきい値電圧は記載されているものの、IIC(A20ではTWIと呼んでいる、大人の事情で)モードに設定したときの値が不明です。
IICにはIICの規格があり、H/Lの入力電圧も決まっているわけですが、A20がどこまで従っているかは神のみぞ知る、です。
なので、波形はあくまで参考...ということにしておいてください。
おわりです。
※コメント投稿者のブログIDはブログ作成者のみに通知されます