さて、前回はラズパイから少し離れて電池でLEDを光らせてみたわけですが、今回はラズパイでその制御をやってみようと思います。
何は無くともラズパイのGPIOの制御の仕方を見ていかなくてはいけませんね。
GPIOピンはラズパイのバージョンアップと共に増えているので、ご自分のラズパイに合わせたピン配置図を参照するようにしてください。
gpioの18番を使用するために、以下のコマンドを実施します。
$ sudo echo 18 > /sys/class/gpio/export
# GPIOの18番を使用するよ。という指定
$ sudo echo out > /sys/class/gpio/gpio18/direction
# GPIOの18番は出力用だよ。という指定。
さて、ラズパイくんは基本的にはデジタルデータしか扱えません。つまりGPIOには1または0しか書くことができず、(出力電圧が3.3Vなので)1.6Vくらいを出力したいからと言って、0.5を指定することができません。
こういうときに登場するのがPWM(Pulse Width Modulation)という変調方式です。0.5は表現できませんが、単位時間あたりの1or0の量は制御出来ます。つまり、短い時間の中でon,off,on,off,on,off…という具合に、onの回数を半分にしてやれば、平均的には0.5になるという感じです。こういうのをデューティ比というので表したりしますが、ここでは詳細は省きます。
PWMのライブラリもあるようですが。LEDの点灯くらいなら自作でいいと思いますので、サンプルとして、一色だけのLEDの変化を見てみます。
<< pwm_sample.c >>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(void){
int i, on, off;
int on_max = 1;
int off_max = 19;
char *buf[] = {"1\n", "0\n"};
int fd = open("/sys/class/gpio/gpio18/value", O_RDWR);
if(fd < 0){
return -1;
}
// (1)
for(i=0;i<1000000;i++){
write(fd, buf[0], 2);
}
// (2)
for(i=0;i<1000000;i++){
write(fd, buf[i%2], 2);
}
// (3)
for(i=0;i<1000000/(off_max/2);i++){
for(on=0;on<on_max;on++){
write(fd, buf[0], 2);
}
for(off=0;off<(off_max/2);off++){
write(fd, buf[1], 2);
}
}
// (4)
for(i=0;i<1000000/off_max;i++){
for(on=0;on<on_max;on++){
write(fd, buf[0], 2);
}
for(off=0;off<off_max;off++){
write(fd, buf[1], 2);
}
}
close(fd);
return 0;
}
ソースの説明。"iで回っているループ"(iループと略記)は、点灯時間の長さを表しています。
on/offのそれぞれのループの長さを変えることによって、iループの1回分の中にあるon/offの回数を変えているわけです。
例えば、(1)の部分では、buf[0](="1¥n"つまり電源ON)しかを書き込んでいないので、iループの中では常にONです。100%ONのままです。
対して、(4)の部分では、on_max=1, off_max=19なので、iループ1回の中では、
on, off, off, ..., off という感じでonが1回、offが19回繰り返されることになります。
20回のon,offの繰り返し中の1回だけがonなので1/20がon。
(2), (3)は中間を表現してみている感じです。
では、実行させてみます。
写真だと、ちょっとわかりづらいかもしれませんが、上から(1),(2),(3),(4)とだんだん暗くなります。
PWMでの擬似的なアナログ出力が確認出来たことになりますね。
次回、いよいよフルカラーLEDをラズパイから操作して色をこねくり回してみたいと思います。
何は無くともラズパイのGPIOの制御の仕方を見ていかなくてはいけませんね。
GPIOピンはラズパイのバージョンアップと共に増えているので、ご自分のラズパイに合わせたピン配置図を参照するようにしてください。
gpioの18番を使用するために、以下のコマンドを実施します。
$ sudo echo 18 > /sys/class/gpio/export
# GPIOの18番を使用するよ。という指定
$ sudo echo out > /sys/class/gpio/gpio18/direction
# GPIOの18番は出力用だよ。という指定。
さて、ラズパイくんは基本的にはデジタルデータしか扱えません。つまりGPIOには1または0しか書くことができず、(出力電圧が3.3Vなので)1.6Vくらいを出力したいからと言って、0.5を指定することができません。
こういうときに登場するのがPWM(Pulse Width Modulation)という変調方式です。0.5は表現できませんが、単位時間あたりの1or0の量は制御出来ます。つまり、短い時間の中でon,off,on,off,on,off…という具合に、onの回数を半分にしてやれば、平均的には0.5になるという感じです。こういうのをデューティ比というので表したりしますが、ここでは詳細は省きます。
PWMのライブラリもあるようですが。LEDの点灯くらいなら自作でいいと思いますので、サンプルとして、一色だけのLEDの変化を見てみます。
<< pwm_sample.c >>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(void){
int i, on, off;
int on_max = 1;
int off_max = 19;
char *buf[] = {"1\n", "0\n"};
int fd = open("/sys/class/gpio/gpio18/value", O_RDWR);
if(fd < 0){
return -1;
}
// (1)
for(i=0;i<1000000;i++){
write(fd, buf[0], 2);
}
// (2)
for(i=0;i<1000000;i++){
write(fd, buf[i%2], 2);
}
// (3)
for(i=0;i<1000000/(off_max/2);i++){
for(on=0;on<on_max;on++){
write(fd, buf[0], 2);
}
for(off=0;off<(off_max/2);off++){
write(fd, buf[1], 2);
}
}
// (4)
for(i=0;i<1000000/off_max;i++){
for(on=0;on<on_max;on++){
write(fd, buf[0], 2);
}
for(off=0;off<off_max;off++){
write(fd, buf[1], 2);
}
}
close(fd);
return 0;
}
ソースの説明。"iで回っているループ"(iループと略記)は、点灯時間の長さを表しています。
on/offのそれぞれのループの長さを変えることによって、iループの1回分の中にあるon/offの回数を変えているわけです。
例えば、(1)の部分では、buf[0](="1¥n"つまり電源ON)しかを書き込んでいないので、iループの中では常にONです。100%ONのままです。
対して、(4)の部分では、on_max=1, off_max=19なので、iループ1回の中では、
on, off, off, ..., off という感じでonが1回、offが19回繰り返されることになります。
20回のon,offの繰り返し中の1回だけがonなので1/20がon。
(2), (3)は中間を表現してみている感じです。
では、実行させてみます。
写真だと、ちょっとわかりづらいかもしれませんが、上から(1),(2),(3),(4)とだんだん暗くなります。
PWMでの擬似的なアナログ出力が確認出来たことになりますね。
次回、いよいよフルカラーLEDをラズパイから操作して色をこねくり回してみたいと思います。
0 件のコメント:
コメントを投稿