I2Cデバイスと raspberry Pi

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デバイス

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

カーボン抵抗(炭素皮膜抵抗) 1/4W 2.2kΩ

ジャンパーワイヤー 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 からとることはできない

このためサーボモータ専用の電池ボックスなどをつかって電源をとることになる

今回は使用するパーツを
秋月電子通商通販

で購入

使用した部品は

GWSサーボ MICRO/STD/F(フタバ)

電池ボックス 単3×4本用

そして
ハック ラズベリーパイ 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 でサーボモータ制御

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機能

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調光

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 でLED調光

raspberry Pi のPWMで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の明るさ変更

raspberry Pi のPWMでLEDの明るさ変更

GPIOの出力は
0 つまり 0V
1 つまり 3.3V
だけなので
これだとLEDをつけるか消すしかできない

しかしPWMを使えば明るさの変更ができるようになる

デジタル信号は


だけだけど
高速で信号を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中の特定の文字列の抽出

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&parameter2=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&parameter2=value2

getFragment()で
fragmentの取得

表示中のページへJavascript発行

表示中のページへJavascript発行

これは、アプリでWebページを書き換えるときに使う

WebページへJavascriptを発行するには
WebViewクラスのloadUrl()を使う

このときに、引数として渡す文字列をhttp://とかのUrlではなく

javascript.
というようにして渡す

また
WebViewクラスの
setJavascriptEnabled(true)
を先に呼び出してJavascriptを使えるようにしておく必要がある

mWebView.loadUrl("javascript.document.getElementById('area').innerText = ('Javascript replace !');");

これで、Javascriptでテキストの置き換えができる