(35連休)13日目:Raspberry Pi(はじめての電子工作②:WEBIOPi、ApacheとphpでLEDを制御)
前回の続きです。*1
http://hsuetsugu.hatenablog.com/entry/2014/08/27/005149
前回やったことと今回やりたいこと
前回は、下記の流れでRaspberry Piに接続したLEDを制御してみました。
①LEDをただただ光らせる
②LEDの点灯をRaspberry Piで制御してみる。
1)コマンドラインでLEDを制御
2)WiringPiでLEDを制御する
3)RubyでLEDを制御してみる(プログラムでチカチカさせる)
③PWMでLEDの明るさを制御してみる
④スマートフォンでGPIOを制御してみる
④でWEBIOPiというフレームワークを使って用意されている画面を使って、スマホからLEDを制御するところまできました。
今回はWEBIOPiのREST APIを用いて画面を自分で作って、そこから制御したいと思います。
ちなみに、WEBIOPiの公式ドキュメントには、「Internet of Things framework」と書かれています。なんかかっこいい・・・。
以下、基本的には下記の書籍をトレースしています。
- 作者: 林和孝
- 出版社/メーカー: ラトルズ
- 発売日: 2014/01/25
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
Javascriptライブラリの用意
WEBIOPi公式のjsライブラリ(JAVASCRIPT - webiopi - Internet of Things framework - Google Project Hosting)もあるのですが、これはWEBIOPiの簡易WEBサーバーでの使用が前提となっているようです。今回はApacheで動かすことを目指すので、jsライブラリを用意します。
ApiMapper.js
//functionの設定 function set_gpio_function(port,dir,callback) { var url = "/GPIO/"+port+"/function/"+dir; webiopi_api("POST",url,"text","string",callback); } //値の取得 function get_gpio_value(port,callback) { var url = "/GPIO/"+port+"/value"; webiopi_api("GET",url,"text","numeric",callback); } //値の設定 function set_gpio_value(port,value,callback) { var url = "/GPIO/"+port+"/value/"+value; webiopi_api("POST",url,"text","numeric",callback); } //PWM値の設定(ratio=0〜100) function set_gpio_pwm(port,ratio,callback) { var value = ratio / 100; var url = "/GPIO/"+port+"/pulseRatio/"+value; webiopi_api("POST",url,"text","float",callback); } //PWM値の設定(angle=0〜360) function set_gpio_servo(port,angle,callback) { var url = "/GPIO/"+port+"/pulseAngle/"+angle; webiopi_api("POST",url,"text","numeric",callback); } //WebIOPi APIとの通信 function webiopi_api(method,url,dataType,convert,callback) { if(USE_API_PROXY) { url = "webiopi_proxy.php?arg=" + url; } $.ajax({ type: method, url: url, data: "", dataType: dataType, success: function(data, dataType) { if(callback != undefined) { if(convert == "numeric") callback(parseInt(data)); else if(convert == "float") callback(parseFloat(data)); else callback(data); } } }); }
WEBIOPi簡易サーバでPWMで明るさ制御
pwm.js
PWMで明るさを制御するので、LEDをGPIO18(Pin12)に接続しておき、明るさをボタンとスライダーで制御するようにします。
var USE_API_PROXY = false; var port = 18; //GPIO18 var val = 0; //初期値 $(function() { //初期設定: GPIO18をPWMモードにして、出力を0にする set_gpio_function(port,"pwm",function(){ set_gpio_pwm(port,0); }); //ボタンが押されたらPWMの値を変える $('#btn1').click( function(){ set_gpio_pwm(port,0); $('#slider').val(0); }); $('#btn2').click( function(){ set_gpio_pwm(port,33); $('#slider').val(33); }); $('#btn3').click( function(){ set_gpio_pwm(port,66); $('#slider').val(66); }); $('#btn4').click( function(){ set_gpio_pwm(port,100); $('#slider').val(100); }); //スライダーが動いたらPWMの値を変える $('#slider').change(function(){ set_gpio_pwm(port, $(this).val()); }); });
test.htmlファイルの用意
上記で設定したボタン1-4とスライダーをhtmlファイルで配置し、上記APIのjsとボタン/スライダーの設定のjsを読み込むようにします。
test.html
・・・ <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="ApiMapper.js"></script> <script type="text/javascript" src="pwm.js"></script> <ul> <li id="btn1" class="ledoff">GPIO<br />18<br />0%</li> <li id="btn2" class="ledoff">GPIO<br />18<br />33%</li> <li id="btn3" class="ledoff">GPIO<br />18<br />66%</li> <li id="btn4" class="ledoff">GPIO<br />18<br />100%</li> </ul> <form> <input type="range" id="slider" min="1" max="100" value="0" style="width:100%"> </form> ・・・
接続
上記をまとめて/usr/share/webiopi/htdocs/[folder] を作ってそこに格納します。
ブラウザで、http://raspberrypi.local:8000/[folder]/test.htmlに接続すれば、画面上でLEDの明るさを変更できることが確認できました。
ApacheでPWMで明るさ制御
Apacheとphpのインストール(していない場合)
- インストール
$ sudo apt-get install apache2 php5
- 権限設定
$ sudo chown pi -R /var/www
- 起動とシステム起動時の起動設定
$ sudo /etc/init.d/apache2 start $ sudo update-rc.d apache2 defaults
クロスドメインの対応
WEBIOPiはポート8000、Apacheはポート80なので、Apacheで動いているjsから直接WEBIOPiにhttpリクエストを送信することができないようです。そのため、proxyプログラムをApache側におくことで、クロスドメインの制約を回避します。
proxy.php
<? //WebIOPiの情報 $host = "localhost"; //ホスト名 $port = "8000"; //ポート $auth_idpw = "webiopi:raspberry"; //ユーザー名:パスワード $arg = (isset($_REQUEST['arg'])) ? $_REQUEST['arg'] : ""; $arg = str_replace(chr(0),"",$arg); if(ereg("^/GPIO/[0-9]+/[-a-zA-Z0-9.,_/]+$",$arg)) { $url = "http://".$host.":".$port.$arg; $data = ""; $options = array( "http" => array( "method" => $_SERVER['REQUEST_METHOD'], "header" => "Authorization: Basic ".base64_encode($auth_idpw), "content" => "" ) ); $data = @file_get_contents($url, false, stream_context_create($options)); header("Content-length: ".strlen($data)); header("Content-type: text/plain"); echo $data; } else { header("HTTP/1.0 403 Forbidden"); } exit; ?>
pwm.jsの微修正
下記の部分のみtrueに変更します。
var USE_API_PROXY = True;
接続
先ほどと同様に、html、ApiMapper.js、pwm.js、proxy.phpをまとめて/var/www/[folder] を作ってそこに格納します。ブラウザで、http://raspberrypi.local/[folder]/配下のhtmlに接続すれば、画面上でLEDの明るさを変更できることが確認できました。
*1:RStanの計算はまだ終わりません。