raspberry pi と I2C
Raspberry Pi では
GPIO 2 が SDA
GPIO 3 が SCL
となっている
このため I2C デバイスの
SDA
SCL
へそれぞれ接続する
注意点は
Raspberry Pi の GPIO ポートは 3.3V なので
3.3V 対応デバイスであること
もし 5V デバイスを使うのなら
間にレベルコンバータなどをいれて
電圧を変換する必要がある
部品の調達にまだ時間がかかるため
さきにRTCモジュールを実験
Just another WordPress site
raspberry pi と I2C
Raspberry Pi では
GPIO 2 が SDA
GPIO 3 が SCL
となっている
このため I2C デバイスの
SDA
SCL
へそれぞれ接続する
注意点は
Raspberry Pi の GPIO ポートは 3.3V なので
3.3V 対応デバイスであること
もし 5V デバイスを使うのなら
間にレベルコンバータなどをいれて
電圧を変換する必要がある
部品の調達にまだ時間がかかるため
さきにRTCモジュールを実験
I2Cデバイスと raspberry Pi
I2C
Inter Integrated Circuit
はシリアルパスで
SDA と SCLという2本の信号線だけでデバイスを制御できる
Raspberry Pi のGPIOポートは
I2Cデバイス対応なのでさまざまなデバイスを扱うことができる
ちなみに
GPIO 2 が SDA
GPIO 3 が SCL
となる
I2C も 1-wire みたいに個々のデバイスにIDが振られているので複数のデバイスを並列に接続し
同時に使うことができる
I2C対応デバイスとしては
温度センサー
湿度センサー
気圧センサー
不揮発メモリ
RTCモジュール
LCD液晶ディスプレイ
I/Oポートエキスパンダ
D/Aコンバータ
A/Dコンバータ
などがある
ちなみに、今回インストールしている OS
Raspbian では
初期状態では I2C が無効化されている
このため
sudo vim /etc/modprobe.d/raspi-blacklist.conf
で設定ファイルを編集
blacklist i2c-bcm2708
の先頭に#をつけて
#blacklist i2c-bcm2708
とする
次に
sudo vim /etc/modules
でファイルを編集
最終行に
i2c-dev
を追記
ここまでできたら
端末からI2C 制御のためのユーティリティ
i2c-tools をインストールする
sudo apt-get install i2c-tools libi2c-dev
これで設定ができたので再起動すれば使えるようになる
次回、配線と実行
Raspberry Pi と 1-wireデバイス
1-wire は非同期シリアルインターフェースで
1本の信号線を使ってデータの送受信ができるインターフェース
信号線が1本でも
複数デバイスを接続することができ
電源を信号機からとることもできる
通信速度は 15.4kbps
125kbps となっていて
I2C SPIに比べると低速
個々の 1-wire デバイスには
ROM ID
という重複しない固有IDが振られているので
同じ種類のデバイスを
同じ 1-wire 上のパス上に複数接続できる
これはIPで振り分けている複数のパソコンが
インターネットに接続できる
ように
複数の接続が可能
例えば20個の温度の監視をするときにも
使用する Raspberry Pi のGPIOポートは
1つで済む
まずは実践したほうがわかりやすいので実験
使うものは
1-wire デバイスの温度センサーDS18B20
ジャンパーワイヤー 3本
そしてブレッドボードと raspberry Pi 本体
Amazon で調べたけどみあたらないので
今回も秋月電子でネットで購入
複数の抵抗をかったためわかりにくいので
をみて
一番右の金色以外すべて赤が 2,2 kΩなので
これを使う
そして配線
3.3V 左下11番め
GPIO 4 左下4番め
GND 左上3番め
から
ブレッドボードにさす
さすときに、これらを縦に同じ列にする
そして
3.3V と GPIO 4 のピンの部分へまたぐように
2.2KΩの抵抗をさす
そして、
GPIO 4
3.3V
GND
のそれぞれの横の列と同じようになるように
温度センサーDS18B20
をさす
センサーには向きがあるので注意
今回、反応しなかったので
検索したところ
[コラム] 第9回『1-wire温度センサーで部屋の温度を測定しよう』
に
接続例がでていたので、それを参考にさせてもらいました
どうやら文字がかかれていて
1番左がGND
真ん中が GPIO 4
一番右が 3.3V
なるようです
GND側に抵抗を入れるのがプルダウン
で
+のほうに抵抗を入れるのがプルアップ
今回はプルアップを行う
配線ができても、そのままだと Raspberry Pi は
1-wire が有効になっていないので使えない
sudo vim /etc/modules
でファイルを開いて編集する
最終行に
w1-gpio w1-therm
を追記する
編集が終わったら再起動することで
設定が有効になり
1-wire デバイスを使えるようになる
一時的に使うのなら
sudo modprobe w1-gpio sudo modprobe w1-therm
を実行することで使えるようになる
ただしこれだけだと再起動すると使えない状態に戻る
設定ができたら、次に 1-wire デバイスのIDを調べる
1-wire デバイスには ROM ID というIDが振られているので
1-wireデバイスを配線したら
ls /sys/bus/w1/devices/
で調べると
28-000006479c5b
みたいに
28-0000 ではじまるシンボリックリンクがみつかる
これが接続しているデバイスのIDになる
ちなみに、何も接続していないと
w1_bus_master1
として表示される
これで認識しているのがわかったので
次に温度センサーの値を取得
cat /sys/bus/w1/devices/28-000006479c5b/w1_slave
で値を得ることができる
実行結果は
c6 01 4b 46 7f ff 0a 10 17 : crc=17 YES c6 01 4b 46 7f ff 0a 10 17 t=28375
この2行めの
t=28375
が温度になる
これは1000倍された値のため
実際の温度は 28.375 度となる
このままだと読みにくいけど
perl とかシェルスクリプトなどを使えば
温度だけを表示できるので見やすくできる
サーボモータの配線
モータを動かすには大きな電流が必要なので
サーボモータの電源を Raspberry Pi からとることはできない
このためサーボモータ専用の電池ボックスなどをつかって電源をとることになる
今回は使用するパーツを
秋月電子通商通販
で購入
使用した部品は
そして
ハック ラズベリーパイ Raspberry Pi 電子工作入門キット。
使用する単3電池は100均で購入
配線するときの注意点として
Raspberry Pi の 3.3V と
サーボモータ用の+を接続しないこと
これは、Raspberry PI のほうが電圧が低いため
Raspberry Pi に電圧がかかり
Raspbery Pi が物理的に壊れるため
なお、今回購入したサーボモータは
端子がソケットになっていて
ブレッドボードにさせないので
電子工作入門キットに両方ともオスの
ジャンパケーブルがあるので、
これをつかってブレッドボードに接続する
配線は
Raspberry Pi のGND
サーボモータの -
電池ボックスの ー
が同じ横の列
そして
サーボモータの+
電池ボックスの+
が同じ横の列
Raspberry Pi のGND、つまり右から3つめと
GPIO18 つまり右から6つめ
と同じ縦の列にさす
これで配線は完了
次に、電池ボックスの電源をいれてから
ServoBlaster を起動する
起動は
sudo servod
実行結果は
Board revision: 2
Using hardware: PWM
Using DMA channel: 14
Idle timeout: Disabled
Number of servos: 8
Servo cycle time: 20000us
Pulse increment step size: 10us
Minimum width value: 50 (500us)
Maximum width value: 250 (2500us)
Output levels: Normal
Using P1 pins: 7,11,12,13,15,16,18,22
Using P5 pins:
Servo mapping:
0 on P1-7 GPIO-4
1 on P1-11 GPIO-17
2 on P1-12 GPIO-18
3 on P1-13 GPIO-27
4 on P1-15 GPIO-22
5 on P1-16 GPIO-23
6 on P1-18 GPIO-24
7 on P1-22 GPIO-25
となる
これで次にサーボモータを制御する
サーボモータの制御は
仮想デバイスファイルの
/dev/servoblaster
にパルス幅を書き込む
パルス幅の単位はミリ秒を100倍した値になる
もし 1,2ms のパルス幅を出力するなら
値は120になる
指定できる値は、初期値では
50~250 だけど
-min オプションで下限
-max オプションで上限を変えることができる
サーボモータの制御の構文は
echo サーボ番号=パルス幅 >/dev/servoblaster
となる
サーボ番号は
sudo servod
を実行したときに
Servo mapping:
0 on P1-7 GPIO-4
1 on P1-11 GPIO-17
2 on P1-12 GPIO-18
3 on P1-13 GPIO-27
4 on P1-15 GPIO-22
5 on P1-16 GPIO-23
6 on P1-18 GPIO-24
7 on P1-22 GPIO-25
の部分でみることができる
今回なら GPIO 18 は2番になっている
これをつかってパルス幅を 1.2ms にするなら
echo 2=120 > /dev/servoblaster
となる
2回実行してもすでにその角度に動いている後なので
変化しない
簡単な操作なら、スクリプトにすることもできる
Raspberry PiのPWM出力を使ってサーボモーターを動かす!
を参考に角度を動かすなら
vim servo..sh
でファイルを作成して
#!/bin/bash echo 2=150 >/dev/servoblaster sleep 0.5 echo 2=60 >/dev/servoblaster sleep 0.5 echo 2=240 >/dev/servoblaster
で保存
chmod 755 servo.sh
で権限を与えて
./servo.sh
で実行すると回転を始める
あと ServoBlaster デーモン起動中は
GPIO 4
GPIO 17
GPIO 18
GPIO 27
GPIO 22
GPIO 23
GPIO 24
GPIO 25
は ServoBlaster 専用になる
もし、特定のポートだけServoBlaster にするなら
–p1pins=基盤のピン番号
とする
GPIOポート番号ではないので注意
sudo servod --p1pins=12
とすれば
Servo mapping:
0 on P1-12 GPIO-18
となり18ポートだけ ServoBlaster 対応になる
ServoBlaster 終了は
sudo killall servod
で終了となる
raspberry Pi でサーボモータ制御
サーボモーターは、回転軸の角度、速度が制御できる特殊なモーターのこと
ホビー用としては
ラジコンとかロボットで使われるRCサーボがある
RCサーボは3本のケーブルを持ち
2本は電源用
1本は制御信号用
となっている
サーボモータに送る制御信号で
モーターの角度を変化させることができるので
ロボットの手足の関節部分に使われる
制御信号の送りかたは
信号のパルス幅でサーボモータの角度が変化する
というもの
これはPWMが使われている
サーボモータの種類により異なるけど
20ms 単位の周期で
1~2ms 程度のパルス幅を与えると
そのパルス幅を与えた角度に移動する
Raspberry Pi のPWM回路は
数百KHz の周期でパルスを発生できるけど
サーボモータで発生する周期は
50Hz 程度のため
Raspberry Pi のPWM回路で生成するのは困難なので
サーボモータの制御に特価した ServiBlaster
もしくは
WiringPi の softServiWrute'( で制御する
ServoBlaster はサーボモータの制御に特化している
これは、仮想デバイスファイルにアクセスすることで
簡単にサーボモータの角度を制御できる
また
デーモンとして起動し
ソフトウェアでPWM信号を出力するため
複数のGPIOポートに接続したサーボモータを制御できる
ServoBlaster を起動すると
初期設定では
GPIO 4
GPIO 17
GPIO 18
GPIO 27
GPIO 22
GPIO 23
GPIO 24
GPIO 25
がサーボモータ用のポートになる
とりあえずまずは実験したほうがわかりやすいので
実際に ServoBlaster をインストール
インストールには git が必要なので
sudo apt-get install git-core
でインストール
次に
ServoBlaster のソースをダウンロード
git clone git://github.com/richardghirst/PiBits.git
ダウンロード完了したらコンパイル
cd PiBits/ServoBlaster/user/ make sudo make install
ServoBlaster をインストールすると
自動起動する
自動起動しないようにするには
sudo update-rc.d servoblaster remove
とする
ServoBaster を自動起動させたいのなら
sudo update-rc.d servoblaster defaults
とする
これでソフトのインストールはできたので次回配線
WiringPi の SoftPWM機能
Raspberry PI でPWM機能を使えるのは
GPIO18だけだけど
SoftPWM() を使うことで
ソフトウェアでON/OFF させることで
擬似的に他のGPIOポートでPWMを行える
ただし、あくまで擬似的なので
実際に出力されるパルス幅が安定しないし
CPUに負荷がかかるとパルス幅がずれる
LEDを光らせる程度ならわからないレベルのずれ
正確に制御するならGPIO18で制御することになる
試しに
まず
sudo shutdown -h now
で電源を切って配列を変える
+のほうをGPIO4に接続
そして抵抗を270Ωでつけて
LEDの+になるアノードにつなげる
そして
-になるカノードを
GPIOのGNDに接続
これで制御してみる
今回使う WiringPi のメソッドは
wiringPiSetupGpio()
wiringPi の初期化
softPwmCreate(GPIOポート番号, 初期値, 最大値)
初期値はPWMの初期値
LEDとかなら0にする
最大値はパルス幅の最大値で
定数にしておくとメンテしやすい
softPwmWrite(GPIOポート番号, 値)
値は0から設定した最大値になる
これも最大値を定数にするとメンテが楽
基本的には PWM のときのソースと変わらないので
cp pwm_led.c soft_pwm.c
でコピーして改造する
まず、ポートを変えるので
#define LED_PORT 18
を
#define LED_PORT 4
次に softPwmCreate() でポートや初期値
最大値を設定するので
//GPIO 18 を PWM
pinMode(LED_PORT, PWM_OUTPUT);
を
//softPWM設定
softPwmCreate(LED_PORT,0,RANGE);
さらに定数を宣言しておく
#define RANGE 100
次に、繰り返す幅も変えるので
for(pw=0;pw<1024;pw++){
を
for(pw=0;pw<RANGE;pw++){
にして
for(pw=1023;pw>=0;pw--){
を
for(pw=RANGE;pw>=0;pw--){
にする
値の変更がsoftPwm を使うので
pwmWrite(LED_PORT,pw);
を
softPwmWrite(LED_PORT,pw);
に変える
そして待ち時間も変更
現在は 0.3ms なので
3ms にする
delayMicroseconds(300);
を
delay(3);
に書き換える
ここまでできたら
cc -o softpwm soft_pwm.c -lwiringPi
でコンパイルして
sudo ./softpwm
とすると
GPIO4でも PWMが行えることが確認できる
C言語でLED調光
WiringPi のC言語ライブラリにある
pwmWrite()
を使うことで PWMのデューティー比を指定できる
今回、使用するメソッドとしては
wiringPiSetupGpio()
wiringPi の初期化
pinMode(GPIOポート番号,モード)
指定したGPIOポートのモードを設定
PWMにするのなら
PWM_OUTPUT
でPWM出力になる
pwmWrite(GPIOポート番号, 値)
指定したGPIOポートのPWM値を設定
1~1023 で設定
delayMicroSeconds()
マイクロ秒単位の dekay()
vim pwm_led.c
でファイル作成
ソースは
#include<wiringPi.h>
#define LED_PORT 18
int main(void){
int pw, i;
//初期化
if(wiringPiSetupGpio() == -1) return 1;
//GPIO 18 を PWM
pinMode(LED_PORT, PWM_OUTPUT);
for(i=1;i<10;i++){
//fade in
for(pw=0;pw<1024;pw++){
//PWM の値変更
pwmWrite(LED_PORT,pw);
//03ms 待つ
delayMicroseconds(300);
}
//fade out
for(pw=1023;pw>=0;pw--){
//PWMの値を変更
pwmWrite(LED_PORT,pw);
delayMicroseconds(300);
}
}
return 0;
}
これで
cc -o pwmled pwm_led.c -lwiringPi
でコンパイル
そして
sudo ./pwmled
とするとLEDが点滅を10回繰り替えして消灯する
WiringPi でLED調光
で配線の汲み上げが終わったので続き
WiringPi 付属の gpio ユーティリティを使えば
簡単にPWMの出力ができる
初期設定状態だと
デューティー比を 1024 段階で調整可能
0~1023の値で指定できる
1出力の幅が50%で
0出力の幅が50%なら
中間となるので
指定する値は 511 になる
出力幅が25%なら 255
この半分なら 127 になる
実際に行うにはGPIO18を出力モードで宣言する
gpio -g mode 18 pwm
次に明るさを指定する
構文は
gpio -g pwm 18 値
となる
値を
1023
255
127
で行うのなら
gpio -g pwm 18 1023 gpio -g pwm 18 255 gpio -g pwm 18 127 gpio -g pwm 18 0
とすればいい
最後の0は消灯
値を連続して変化させれば
ゆっくり光らせることもできる
raspberry Pi のPWMでLEDの明るさ変更
GPIOの出力は
0 つまり 0V
1 つまり 3.3V
だけなので
これだとLEDをつけるか消すしかできない
しかしPWMを使えば明るさの変更ができるようになる
デジタル信号は
0
1
だけだけど
高速で信号をON/OFF させることで
明るさを調整していかのように錯覚させることができる
これはLEDを人間では分からないくらいの早さで
ON/OFF にしていることで錯覚させている
この原理でONの状態が長いと明るく感じて
ONの状態が短いと暗く感じる
このON/OFF のパルスの幅を変える仕組みのことを
PWM
Pulse Width Modulation
といい
パルス幅変調とも言われる
そしてPWMの ON/OFF の長さの比率のことを
デューティー幅という
PWMは様々なところで使われていて
PCのファンの回転数のコントロールにも使われている
Raspberry Pi ではGPIO18だけ
PWM出力可能で
他のGPIOではできない
プログラムを組んで
他のポートでも擬似的にできるけど
CPU処理などで微妙な待ち時間ができるため
不安定な動作になってしまう
とりあえずLEDを使って実験
ハック ラズベリーパイ Raspberry Pi 電子工作入門キット。
の中から
赤のLED
ジャンパワイヤーのメスオスx2本
ブレッドボード
270Ωの抵抗
を使うことに
抵抗は色で判断するしかないので
http://part.freelab.jp/s_regi_list.html
を参考に
見分けの方法ですが
金色の線をを右側にして
左側から3番めの線が橙色なのが 10KΩです
入っている部品は
10KΩ が4本
270Ω が4本
となっているので消去法で270Ωをみつけました
さらに、LEDにも極性
つまり+と-があります
LEDは足の長いほうが+で
アノードと呼ばれ
足の短いほうがーで
カノードと呼ばれます
ちなみに、抵抗には極性がないらしいです
これでブレッドボードを実践します
今回はGPIO18の部分を+にするので
Raspberry Pi の
Pin1 右上から6番めのところへ+の抵抗とつけたジャンパケーブルをさして
Pin 6 右上から3番めがGNDになるので
ここへLEDの-部分にさしたジャンパケーブルをさします
これで配線準備は完了
URL中の特定の文字列の抽出
これは、表示中のページからJavascriptコードを使うときに利用する
URL文字列を使っていると
ホスト部分や
クエリパラメーター部分だけ切り出して利用することがある
PHPのマッシュアップではおなじみのもの
これを実現するには
Uriクラスを使う
まずほ、Uriインスタンスの取得
Uriクラスの
parse()を使うことで、Uriインスタンスを取得する
Uri uri = Uri.parse("http://www.example.com/");
次に、取得したインスタンスのメソッドを取得
もし、ホスト部分を取得したいのなら
getHost()
を使う
String scheme = uri.getHost();
ほかのメソッドを使えば
様々な部分の値の取得が可能
例えばURLが
https://user:pass@www.example.com:8080/path/to/index.html?parameter1=value1¶meter2=value2#fragment
だったなら
getScheme()で
http:// とかhttps:// の判別
getSchemeSpecificPart()は
URL全部
getUserInfo()では
user:pass
みたいなユーザ名、パスワード
getAuthority()で
user:pass@www.example.com:8080
みたいに、
ユーザ名:パスワード@ドメイン:ポート番号
getHost()で
www.example.comというようにドメイン
取得
getPort()で8080というように、ポート番号の取得
getPathSegment()で
ファイルまでのパス取得
今回なら
path/to/index.htmlを
配列で [path, to, index.html]と扱う
getLastPathSegment()で
パスの最後を取得
今回なら index.html
getQuery()で
URLの ? 以降のパラメーターを取得
今回なら
parameter1=value1¶meter2=value2
getFragment()で
fragmentの取得