Lチカ実験キットで、ラズパイのIOピンの制御を試してみた。がしかし、LEDの光る光らないのオンオフ制御(一応PWMによる明るさ調整できるが、白色LEDを白色で発光するには3チャネルPWMでもあればねぇ)、入力もCDSのオンオフ制御では面白くないので、、多彩なセンサ類入手のために、秋月通商の、 最新RaspberryPiで学ぶ電子工作キットを購入する(以下敢えて学ぶではなく遊ぶと称することにする)。 本書の中で説明されているのでこれを選んでみました。実際は、日経ラズパイマガジンの部品集と合わせて購入しましたが、それはまたおいおい説明しましょう。
Raspberry Piで学ぶ電子工作:講談社を元に遊びます。本書を詳細読めば、サポートページへの案内があって、本書で提示される例題のダウンロードサービスもありますので、お勧めかと思います(IDE環境使わないと、字下げがおかしいとかいろいろ言われる可能性もあって、サンプルあるのはうれしい)。
キットの内容(Lチカキットの内容に加え、ADCによる入力とPWMとか、PC連動の実験など:模型制御はパスの予定。カメラは別途購入予定)
本書には、小型LCDディスプレイの例もあるがキットには含まれない(個人的にはラズパイマガジンの部品セットから流用予定)。 カメラの連動も記事もあるがカメラも別売(大した実験ではないし、これ入れると値段高くなるから今のキットの値段の方が妥当かな)。
- ブレッドボード
- 5*2*30列 :両サイド電源各2列。四方に凸凹ついていて、同一モデルなら縦横方向に連結できる(電源はジャンパーでつなごうね)
- ブレッドボード用ジャンパー
- オスーオスタイプ(一般的)色違い長さ違い多数。 が、オスーメス(ラズパイとブレッドボード間)が赤一色20本は使いにくいぞ。色別がいいけど、値段を考えるとしかたなし?
シングルピンヘッダ(20ピン)ケーブル2組(つながった状態)ならつなぎやすが、その場合ブレッドボードの長さが不足(ケープルに20ピン使うと、実実験に10ピン分しか残らない(ADC差すとほぼ終わり)。 ラズパイマガジン関連部品集では63ピンブレッドボードがあるので、それなら全ピン引き出しのケーブルがいいなぁ- 小型LED
- 赤3mm 5本
- RGBフルカラーLED
- カソードコモン:拡散キャップとともに
- 抵抗(2種330Ω、10kΩ各10本)、コンデンサ(0.1uF3本)、ボリューム半固定
- 実は抵抗1本欠品(どっかに飛ばした可能性も無きしも非ず)。手持ちがあるから気が付かなかったことにする(代わりに他のキットにLEDが2ケ余分に入っていたので本来返さないといかんかなぁ。 単純に価格的にはもうかっているし、郵送すると部品代より高いし、おあいこということで手を打ちたい。
- Cds(硫化カドミウム、Cadmium sulfide)光センサ
- 光で抵抗値が変わる素子という理解でいいかな? Lチカセットと見た目同じもの?
- ADコンバータ
- ボリュームやCDSの値を読み取る(LチカキットのCDSのオンオフ制御より面白いかも) 。12bit MCP3208-CI/P
- タクトスイッチ
- 押しボタン(押してon/話すとoff)
- DCモータ(FA-130RA-2270L)、サーボモータ(SG90)、モータドライバ (TP7291)
- 模型を買って走らせるのが筋かな? PWM駆動の実験
- 温度センサ
- I2C対応 (ADT7410)
--加筆中--
OSインストール(3章以前)は、中型ラズベリーパイでお茶をとか、 ノーマルラズベリーパイは手間いらずと被っています。
4章LED出力の章の内容は、L-chikaキットで遊ぼう(ターミナル編)や、 L-chikaキットで遊ぼう(python編)をご参照ください。
第五章タクトスイッチによる入力で、新しいアイテム学習。
ユーザ関数と割り込みトリガの記載方法です。
#--------- ユーザ関数の定義 ------------------------------
SW=24
LED=25
def my_callback(channel):
global ledState
if channel==SW:
ledState = not ledState
GPIO.output(LED, ledState)
#def文でユーザ関数の定義
#global で、関数内変数ではなく、呼び出し元のメインルーチンでも、同じ名前(ledState)の利用を宣言
#------- 端子のイベントトリガ指定方法 --------------------------
GPIO.setmode(GPIO.BCM)
GPIO.setup(SW, GPIO.IN)
GPIO.add_event_detect(SW, GPIO.RISING, callback=my_callback, bouncetime=200)
#GPIO端子のイベント割り込み処理の宣言(中止の宣言はremove_event_detect)
#第一引数:GPIOのポート指定
#第二引数:立ち上がりを検出(立ち下がりエッジはGPIO.FALLING、両方の場合はGPIO.BOTH)
#第三引数:イベント発生時の処理
#第四引数:再割り込み禁止期間(200msec); 物理スイッチの反転では、Off<->on遷移期間にリンギングと呼ばれる、短時間の振動が起きやすい。 本例では、スイッチを押したことの検出は、その後、200msec時間は、過渡状態と考えて再処理実行しないという設定。 制御工学的には、この2度押し検出保護が結構大切であるが、関数としてサポートされているラズパイは賢い(実力はシラネ:意地悪く繰り返し実験すると失敗する模様(笑))
#現在の疑問、callback関数にポート番号(SW)がわたる仕組みが良く解らん。 "callback=my_callback(SW)"とでも書いていれば良く解るんだが。 やっぱカーニハンがええなぁ
#--------- 後処理(例えばexcept KeyboardInterrupt:)で、以下を実行のこと(再コマンド実行時にエラーになるらしい)-------------
GPIO.remove_event_detect(SW)
GPIO.cleanup()
#---本書”05-03-sw-pd-event.py”からの変更点
#趣味の問題。ポート名を、SW,LEDと変数置き換える。Basicインタプリタ―では、即値(実際の数値)より、変数参照にする方が、高速処理できるという思い込みに起因している
#if文で、現状のH/Lを判断して、それぞれ別の分岐によりL/H反転出力しているが、leadStateという変数で状態記憶しているので、そのまま出力すれば、条件判断、分岐もいらないし、処理も単純化(理解しやすい)。 本当は、Lチカキット実験の時にも試したんだけど(シェルコマンドでパイプでデータ渡せなかった)、その時はうまくいかず、今回簡単に動くのでちょっと拍子抜け。
#remove_evet_detect分の追記 まあ、書く方が正解だという噂なので、書いてみた。
なお、上記ソースコードを、カットアンドペーストで、本書のサンプルソースに修正しても、たぶんうまくいかない(htmlエディタとして使っているホームページビルダーが、複数の半角空白文字挿入許してくれないので、基本的に全角空白を挿入しています。青文字の部分を量少ないので、書き換えればokかな?
第五章の後半のカメラ制御は、いま発注交渉中(どこで買っても大差ないのでひいきのショップと再販の交渉中)なので、後日試す。
-------------------------------------------------------------
ちなみに、シェルコマンドでL-chikaキットで遊ぼう(ターミナル編)で入力閾値を調べた(ページ一番下)。
今回サイトンプログラムで同様の実験をしてみた(本来CDSは次章に出てくるんだけど、まあ一部先走りということで)。
プログラムは------- (本書05-02-sw-pd.py からの赤字の部分を手直し)--------
#!/usr/bin/python
import RPi.GPIO as GPIO
from time import sleep
LED = 25
SW = 24
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED, GPIO.OUT)
GPIO.setup(SW, GPIO.IN, pull_up_down=GPIO.PUD_UP)
try:
while True:
GPIO.output(LED, GPIO.input(SW))
except KeyboardInterrupt:
pass
GPIO.cleanup()
#---------------------------------
ホームページビルダーが空白許さないので、左づめになっているので、適当に直してください。
先頭の実行プログラムの指定をしているので、このファイルが、0502swpdr.pyという名前だとすると、ターミナルプロンプト($が表示)状態で
$ ./0502swpdr.py
と入力すれば実行される。ctr-Cで終了。
一応復習として、実験回路は、内蔵プルアップ抵抗onにしたうえで、外付けプルアップ抵抗10kをつけています。CDSの動作範囲が、手かざしだとDレンジ取れないので、窮地の作です(これも先のページでもう少し紹介済みの話です)。
さすがにpythonはシェルコマンドより高速動作するようだ。前述Lchikaキットで遊ぼうの同様波形と見比べてね。時間軸1/10に拡大していますが、こちだと、LED変化点に対して、入力端子の取り込み位置はっきりしない程度でほぼ同時(シェルプログラムだと、20msec程度のタイムラグが発生しているが、python版は、数msec未満かな?(時間分解能上げると、振幅変動がすくなくて、どのあたりを閾値としているのか、予測できなかった。CDSの明るさも精度よく制御しないと、良く解らんということやねぇ)
Ch1:LEDカソード駆動端子25pin(330ΩシリーズLEDのアノード3.3V)
ch2:CDS入力(SW)端子24pin:内蔵抵抗on+並列プルアップ抵抗10kΩ)、CDSのもう一品はGND接続
CDSに対する明暗を高速に変化させて、プログラムの反転時間を見てみた。while turueの、実行サイクルは数msecなのかな?立ち上がりに対して、最短H期間は5msec程度あるようだが、立下りの時間分解能ははるかに細かい時間分解能があるので、さまざまなシステム割り込みの大小で、わずかな時間差が発生していると考えてもよいかも。勉強していればそのうちわかるでしょう。 入力回路のシュミット幅が、時間決めてる説もあるかなぁ???(プログラムは下記の通り、マイクロ秒で実行できるので、CDSの応答時間とラズパイ入力端子の、閾値が主因かな?
#--------------実行速度見積もり-----------------
#!/usr/bin/python
import RPi.GPIO as GPIO
from time import sleep
LED = 25
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED, GPIO.OUT)
ledState = GPIO.LOW
count = 20
try:
while count > 0:
ledState = not ledState
GPIO.output(LED, ledState)
count = count - 1
except KeyboardInterrupt:
pass
GPIO.cleanup()
#-----------------------------------------
#例によって、空白文字位置不正があるので、そのままでは動きませんが。
外乱?(割り込み等)ばらつきありますが、whileサイクルは5マイクロ秒オーダが普通かな? ときおりはるかに遅い(といっても倍程度)。下図;右のように全体が遅くなるんじゃなくて、1サイクルだけ遅い場合もごくまれにあって、遅くなる要因いろいろあるんでしょうねぇ(テラタームで本体のコンソール使わずwinパソコンから制御しているし)。 インタプリタとして早いという感想とともに、GHzクロック使って、やっとマイクロ秒オーダというのはやっぱり効率悪いなぁという感想。H8では遅くてあきらめたんだけど、ARMでリトライしたいのがDDS・SG(任意波形の発生器:正弦波以外に矩形波や三角波等も作る。10M位は出したい。できれば、外部入力に対して、変調機能も付けたいetc)のために、ARMのアセンブラの本も買って積読状態。
この辺が実力とすると、やはり、先の、CDS反転検出によるLED反転のサイクルが遅いのは、プログラムが遅いのではなく、CDS反応と、おそらく、ラズパイの入力端子のヒステリシス特性の遅れという話だったんだと思います。 さすがに、シェルコマンド(一処理20msecオーダ)とは段違いに早いねぇ
なお、”count = count - 1”は、”count--"と書けると嬉しいし、そもそも”while count > 0:”だって、”while count--;"みないな書き方でもいいよなぁ?
第六章AD変換によるアナログ値の利用
12bit 8ch ADコンバータ MCP3208-CI/Pが、キットに含まれています。3Vでも5V電源でも使えるアナログデータ電圧を、デジタル値に変換する装置で、高い電圧で使えば100kHzでデータ変換できるらしい。8chとはいえ、IC入り口で、スイッチを切り替えてどれかを変換するという方式なので、オーディオのLR2チャンネルを同時にAD変換するというような用途には使えません(本来同時に右耳と左耳に届く音を捕まえたいのに、ちょっと時間差をつけて捕まえるので、本当に耳のいい人なら、ちょっとづれて(角度が違って聞こえたりするのかも...)。
それでもこういう装置を使うと、先のCDSは、連続的に明るさの変化を見つけているのに、ラズパイ君の端子が、あるしきい値の上か下かの2通りしか見つけられないので、明るいかくらいかしかわからない状態だったのが、すごく暗い、ちょっとくらい、ほんわかしている、やや明るい、まぶしい等のいろいろな状態を見分けることが出来るようになります。 もっとも、情報をえても、応用が、暗いから天井灯をつける明るかったら消すという2つしか考えないのなら、どうでもいい情報だという意見もあるかとは思いますが、暗いときとすごく暗いときで、電燈1本付けるか、二本つけるか考えるようなら、役に立つのかもしれません(一本、二本とかいってるあたりで蛍光灯世代だというのが解ってしまいますなぁ)。 ADCが区別するのは電圧の大小です。 たとえばCDSは明るさにより抵抗値が変わりますが、この抵抗値の変動を、つないだ電源・抵抗との分圧比という電圧次元・領域で判断することになります。
12bitの意味は、状態をいくつに分類できるかという情報で、1bitの場合は、明るいか、暗いか。2ビットなら、すごく暗い、暗い、少しあかるい、明るいという4種類に分類できるようなイメージになります。12ビットあるということは、4096とおりの分類できるという意味になりますが、型名にくっつくーCは、ちょびっと性能・できの悪い訳あり廉価版を示す記号で、ーCクラスは2ビット直線性保障無しとかいてあるようなので、上位だけ見た1024とおりは、間違いなく大小区別できますが、11ビットの2048に分類したときの、例えば1026と、1025は、どっちが大きいか保障は難しいという理解でいいかな?(1026>1024は間違いないし、1025>1024も間違いないけど、1026>1025はちょっと怪しいとかいうこと)。
余計なお世話という話はありますが、老婆心ながら。 今回使ってみる(ADCをはじめとする)ICは、静電気に弱い。 今は進化して強くなって良いですけど、それでも注意はしましょう。昔IC買うと、かならずアルミホイールで包んでくれました。導電性の黒いスポンジに差すようになったのもあって、最近はあまり見ない風習ですけど。 そういえば、インテルがペンティアムCPUのリコール交換してくれた時に、壊さないように注意したのは覚えているけど、どんな梱包されていたかは記憶にないなぁ。
業務としてIC量産の前には、大量の良品IC用意して、これらに対してわざわざ静電気想定の高電圧(電荷)を印加して壊れないというのを確認していました。壊れない前提なんだけど、壊れると大騒ぎになります。 まあ、一匹ゴキブリさん見かけたら100匹は隠れているということわざもあるから、たかが試験で壊れるとしたら、量産で市場に出回と怖い。壊れる前に作り直して対策するというのが、製造メーカとしての良心でした(だから日本製は壊れないという神話につながるんかな?)。
で、作業するには、鉄板があると一番いいけど、そこまで考えなくても大丈夫でしょう。 すくなくとも、銀紙パック・スポンジ差しの状態で、ICも体も、作業環境一帯のGNDに触って全体同電位にして、間違って、高電位差がICに印加されないというのが大切です。 あ、今回関係ないけど、半田ごて買うときも、はんだ小手先が絶縁されているのを買わないと、IC壊すかも(というか大概のものは対策済みだと思いますが、銅無垢の電力大きいのは注意した方がいいかも(道具は選ぶものです。一般のひとは弘法大使さんにはなれません))。
ところで、新品のICを上から眺めてみましょう。足が外側に広がってますよね? ブレッドボードに一列穴に入るように置くと、もう一列は穴の位置よりやや外側に広がってますね? 素人はこのちょっと広がっている足を、穴にうまくさすのが難しいと思います(足の太さが途中で変わることが多いですが、このあたりで折れて、外に足が広がるか、足が穴に刺さっていると、逆に足の根本が外に開い太さが変わるあたりで”くの字”に折れる失敗が起きてしまいます)。 ブレッドボードに差す前に、まず固い台の上に、銀紙(アルミホイール)を敷きます。ICの長方形の短編(足の出てない辺)を左右両側を親指と人差し指で指で挟んで、足をアルミホイールに全ピン置いた状態で、モールド(大概黒いプラスチックみたいなIC本体)と足:ピンが直角になるように、ゆっくり力をいれて曲げていきます。 両辺の足を処理したらok。今度ブレッドボードにおいたら穴と2列の足が同じ幅になっていて、足が曲がる事故が起きにくくなるのが実感できると思います(いや、足を曲げてしまう事故は再現しなくてもよろしい)。
さらに、ICを、ブレッドボードから抜くとき。これも慣れないと足を前後(ICの長さ方向)に曲げてしまい易い。 本当はIC引抜機というのを売っていますが、これはICのサイズ(ピン数とか)毎に別商品を取り揃えなくてはいけないので、量産現場でないと、使う可能性のあるもの予想して何種類もそろえるのは高くて現実的ではありません。 そこまでいかなくても、U字型の金具で、先端が、内側に曲がっていて、この曲がった先端を、ICの下に差し込んで上に引き抜く工具もあります(PLCCという特殊なパッケージのICの対格を挟むものも似ているといえば似ているかな?もあります)。 まあ、このこも、なれないと結構使い方難しいので、両手にそれぞれ持ったピンセット2本を、ICの上下辺(足の無い辺)に片足づつ差し込んでもう一方の足を親指でIC方向に押し付けつつ、IC下にあるピンセットの先をてこの視点として両手均等に上方向に持ち上げれば何とかなります。なれれば、片手のピンセットだけで、ピンセットの先方向に力を入れるイメージで持ち上げれば(この場合はピンセットの根本側が視点かな?)、わざわざ両手の2本ピンセット使わなくても楽に抜けるようになります。 不幸にして壊してしまったICが出来てしまったら、練習してみましょう。
--------------------
サイトマップ 、トップ < ラズパイの部屋