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は消灯

値を連続して変化させれば
ゆっくり光らせることもできる