Thursday, August 21, 2014

raspberry pi B+ LED x PWM

raspberry pi B+ でPWMを使って明るさの制御をやったときのメモ.

rubyとnodeでそれぞれサンプルコードを記述。配線はごく単純にLED, 抵抗, ケーブル2本。

ruby

require "open3"

out, err, status = Open3.capture3("gpio mode 1 pwm")
out, err, status = Open3.capture3("gpio pwm-bal")
out, err, status = Open3.capture3("gpio pwmr 1024")

0.step(1023, 8) do |x|
    Open3.capture3("gpio pwm 1 " + x.to_s)
    sleep 0.1
end

0.step(1023, 8) do |x|
    Open3.capture3("gpio pwm 1 " + (1023-x).to_s)
    sleep 0.1
end

rubyにはwiringpiのモジュールがあってgemでインストールできるのだけど(参考)、まだModel B+に対応していないぽい。仕方がないので直接外部コマンドを叩くことにした。

  • gpio mode 1 pwm …GPIOピン1をpwmモードに変更
  • gpio pwm-bal …pwmの制御モードを「バランス」に設定
  • gpio pwmr 1024 …pwmの制御幅を「1023」に設定
  • gpio pwm 1 x …pwmによる電圧調整(厳密には電圧一定でパルス調整なんだろうけど)

node

var Q = require('q');
var exec = require('child_process').exec;

// この3コマンドもdefferedで実行制御したほうがいいかも.
exec('gpio -g mode 18 pwm');
exec('gpio pwm-bal');
exec('gpio pwmr 1024');

var step = 8;

function inc_intensity() {
    var deffered = Q.defer();
    var intensity = 0;
    var id = setInterval(function() {
        intensity += step;
        if(intensity > 1023) {
            clearInterval(id);
            deffered.resolve();
            return;
        }
        exec('gpio pwm 1 ' + intensity);
    }, 100);
    return deffered.promise;
}

function dec_intensity() {
    var deffered = Q.defer();
    var intensity = 1023;
    var id = setInterval(function() {
        intensity -= step;
        if(intensity < 0) {
            clearInterval(id);
            deffered.resolve();
            return;
        }
        exec('gpio pwm 1 ' + intensity);
    }, 100);
    return deffered.promise;
}

inc_intensity().then(dec_intensity);

やってることはrubyのコードで一緒。ただし、nodeは非同期で動いちゃうので、Q(deffered)を使って明るさの制御順を指定している。最初はだんだん明るくして…次にだんだん暗くする。

まとめ

単純なプログラムだけどruby, nodeそれぞれで特色が出るなぁ。rubystepを使いつつnodedeffered使えたら最高なんだけど…coffee script、type script使えって話ですかね。

Written with StackEdit.

No comments:

Post a Comment