0

ArduinoとRubyで赤外線リモコン をgemにした

これを大改修した。
ArduinoとRubyで赤外線リモコン作ってWebから操作できるようにした
特徴は以下のとおり

  • Arduinoに約110円分の電子部品を追加すれば赤外線学習リモコンが作れる
  • 市販の学習リモコンが対応していないような長大なデータでも読み書きできる
  • 学習リモコン機能を自作アプリに組み込めるRubyライブラリ付き

最近は多少涼しくなった気もするけど、いまだに夕方の閉めきった部屋の中は40度近くまで上昇していて危ない。このツールで家に帰る前に冷房をonにしておくと助かる。

gitリポジトリはここ https://github.com/shokai/arduino_ir_remote


機能追加・変更された事

  • rubygemにした。赤外線学習リモコンをライブラリとして自作アプリに組み込める。
  • 学習した赤外線データを別々のアプリ間で共有できるように、データを管理する機構もgemに含めた。
  • 6つのアナログピンの数値をRubyで読めるようにした。温度センサなどを追加できる。
  • CUIから赤外線リモコンを使えるコマンド “arduino_ir_remote” もgemに同梱した。ssh接続可能なmac/linuxサーバーにArduinoを接続し、このrubygemをインストールするだけでリモートから赤外線機器をコントロールできる。
  • webブラウザから赤外線リモコンを操作できるアプリは別のgitリポジトリに移動した。READMEに書いてある通りに起動すれば動くしサービスとして常駐させられる。


回路

たったこれだけの回路で作れる。
デジタル12ピンに赤外線LED、デジタル3ピンに赤外線リモコン受光器を接続。
このfirmwareをArduinoに書き込む。

Arduino IR Remote


インストール

gem install arduino_ir_remote
which arduino_ir_remote
arduino_ir_remoteコマンドもインストールされる。


赤外線の読み書き


まずarduino_ir_remoteコマンドを使う例。 -helpで使い方が表示される

読む

arduino_ir_remote -read 名前
で赤外線を読む。

reading…と表示されてから1.5秒以内に赤外線リモコンを当てると、デコードされて表示される。
データは ~/.ir_remote.yml にyaml形式で保存されている。

部屋の蛍光灯が赤外線リモコンと同じ波長・周波数をだして邪魔になる事があるので、調子が悪い時は電気を消してから学習させてください。


書く

arduino_ir_remote -write 名前
で発射する。

とりあえずCUIから赤外線が読み書きできる。


このコマンドはサーバーに赤外線リモコンを付けている場合に便利。
sshはコマンドを渡せるので、
ssh shokai@サーバー名 arduino_ir_remote -write エアコンON
とかでリモートからエアコンつけられる。

一覧

arduino_ir_remote -list
で保存した全データが確認できる。


赤外線の読み書き(アプリから)

READMEにも書いたが、ライブラリとして使用して自作Rubyアプリにも組み込める。

読む

接続時にデバイス名は指定しなくても自動的にArduinoらしきデバイスを探す。
require 'rubygems'
require 'arduino_ir_remote'

ir = ArduinoIrRemote.connect # use default device
## ir = ArduinoIrRemote.connect "/dev/tty.usb-devicename"

ir.read do |data|
p data
ArduinoIrRemote::DATA["tv_on"] = data
ArduinoIrRemote::DATA.save # ~/.ir_remote.yml に保存される
end
ir.wait
コールバックでデータを読んで、Hashとして扱えるArduinoIrRemote::DATAにデータを保存できる。


書く

これでテレビの電源がつく。
ir.write ArduinoIrRemote::DATA["tv_on"]
ir.wait

読むのはarduino_ir_remoteコマンドでやっちゃって、書くところだけ自作アプリで作ったUIからやるとかでいいと思う。


外部センサーの追加

Arduinoなので赤外線リモコン専用というわけではなく、センサーを追加できる。
うちではこんな風になっている。
Analog 0にLM35DZ温度センサ、Analog 1にCdS照度センサを接続した。
Arduino IR Remote

上から見た図
Arduino IR Remote with Temperature&Light Sensors


外部センサーを読む

Ruby側でanalog_readできる。値は300ミリ秒毎にArduinoから送られてきている。
require 'rubygems'
require 'arduino_ir_remote'

ir = ArduinoIrRemote.connect # use default device

loop do
puts ir.analog_read 0 # アナログ0ピンを読む
puts ir.analog_read 1
end
部屋の明るさだけでなく、テレビに近づければ電源がついているかも判別できると思う。

温度センサLM35DZを読む

LM35DZは安くて定番なんだけど数値を摂氏に変換する手間がある。
ライブラリ内でやっておいた。
ir.temp_pin = 0  # set temperature sensor pin

loop do
puts ir.temp_sensor
end
これで温度がチェックできる。室温が40度とかになっててエアコンつけざるをえない事がわかる。

温度はコマンドからも見れる。
手元から自宅の温度が1行で取得できて便利。エアコン切って1時間ぐらいで37度になるとかヤバイ


サンプルアプリ

webから赤外線リモコンを操作できるインタフェースを作った。トータルで100行ぐらいで実装されているので見るといいと思う。
もちろんgit cloneすれば手元ですぐ動かせる。
https://github.com/shokai/arduino_ir_remote_webui

2013-08-19 05.01.48


要望・バグなど

@shokaigithubのissueにどうぞ

0

Serialport ServerをRuby2.0.0対応した

これを直した。仕様は変わってないけど中身はだいぶ書き換わった。

HTML+JavaScriptをArduinoに直結できるシリアルポートサーバーを作った
http://shokai.github.io/serialport-server

インストール

gem install serialport-server

動かす
serialport-server /dev/tty.usb-devicename
これだけでシリアルポートがHTTP/WebSocket/TCP Socketの3通りの方法で同時に使えるようになる。
HTMLとJS書くだけでArduino使える。


1年前の実装なので、
bundlerじゃなくhoeでテンプレート作っちゃってる
グローバル変数使いまくりでRuby2.0で警告出ていた
markdownじゃなくrdoc使ってる
などなど色々古かったのを直した。

きっかけはhoeからbundlerへの修正をpull requestしてくれた方で、じゃあせっかくだしRuby2.0対応とかも一気にやるか・・・となった。

githubに置いておくと、それなりに自分以外にも使われているプロダクトなら誰かが修正してくれて助かる。

0

jQuery.editableでtextarea編集できるようにした

クリックするとinputタグになるのはいいけど、textareaにはできないの?という質問が来たので、実装した。

デモ

こういうところをクリックすると


編集できるようになって


枠外をクリックすると保存される


edit-in-place(その場編集)プラグインはいくつか存在するけど、jQuery.editableは最も使いやすいAPIを出していると思います。
他のは・・あまりカッコよく書けない。

clickしたら編集し、編集終了後の値をコールバックで取得するのはこう書ける。
click以外にもmouseover, dblclick, clickholdなどトリガーは色々設定できる。

$("span#edit").editable("click", function(e){
alert(e.value);
});


値をチェックして、条件に合わなかったら元の値に戻すこともできる(validatorがわり)
$("span#zip").editable("click", function(e){
if( !e.value.match(/^\d{3}\-\d{4}$/) ){
e.target.html(e.old_value);
alert(e.value + " is not valid zip-code");
}
});

編集するテキスト以外のDOM要素をトリガーにする事もできる。この場合は横に「編集ボタン」があってそれを押したら編集モードになる。編集中はトリガーになった要素はhide()される。
var option = {trigger : $("input#btn_edit"), action : "click"};
$("span#edit").editable(option, function(e){
alert(e.value);
});


今回追加したtextarea版はこうやる。type: “textarea”を指定すればtextareaになり、その中は複数行の編集ができる。
var option = {type : "textarea", action : "click"};
$("p#license").editable(option, function(e){
alert(e.value);
});

0

Rubyでメールを送る

mail gemを使う
https://github.com/mikel/mail
ファイルの添付も、ローカルのファイル名指定するだけで簡単そうだった。


インストール

gem install mail


送ってみる
require 'mail'

mail = Mail.new do
from 'from@example.com'
to 'to@example.com'
subject 'こんにちは'
body '本文です'
end

mail.delivery_method 'sendmail'
puts mail

mail.deliver!

ローカルのsendmailを使うのでsmtpサーバーの指定はいらない。
Macは最初から入ってる。Ubuntuなどではaptで入れればいい。

0

Scalaをちょっと勉強した

Scalaを勉強した結果、今日のNode.js初級入門勉強会でcoffee-scriptが書けるようになってた。coffee気持ち悪いと思ってたけど苦手克服できてよかった。


Java/JRuby/Scala

ScalaはJava。JRubyはRuby。
ScalaはJavaのシンタックスをシンプルに直して、Java使ってて不満な文字列、正規表現、配列やMap、無名関数や高階関数などの機能を追加した、より良いJavaという印象。
JRubyはRubyがJVM上で動いていて、ついでにJavaの機能も使える言語だと思う。

JRubyと比べると、JRubyよりもJavaに寄っている気がする。Javaのライブラリをスクリプト言語から使いたい時は今後はscala使おうと思う。

Scalaは型宣言をしなければならないのが良い。JRubyの方がRubyに寄っていて、スクリプト言語としての使い勝手はRubyの方が良いと思うけど、型がRubyの型なのかJavaの型なのかよくわからなくなって辛かった。
もちろんJVM上でRailsアプリを書くみたいな、Javaの機能は使わないでRubyだけでやるならJRubyは問題ないと思う。

スクリプト言語としての書き心地はRubyの方が好みだけど、スクリプト言語からJavaを使いたいならScalaの方がいい。


インストール

brew install scala
scala -version

scalaコマンドでインタラクティブシェルが起動して、適当に書いてtabを押せばメソッド名一覧とかでてくる。
おかげで特に本とか読まずにいきなりコード書ける。


練習問題

研究室のwikiにスクリプト言語の便利な機能を使わざるを得ないRubyの初級問題集がある。


“abracadabra” などに “a” がいくつあるか数える

正規表現を使う。String.rでRegexpになる。メソッドチェインでつないでいける。
: の後ろが型。


「また大阪か」を「ま た 大 阪 か」に変換する

いったん文字列を配列に分解してから結合し直す
return書かなくてもいい。


フィボナッチ数列をどんどん生成する

無名関数をコールバック関数として登録するようにした。
defじゃなくてvalに関数オブジェクトを保存するようにしてみた。valは定数でvarは再代入可能な変数。
普通のArrayは中身をいじれないので、mutable.ListBufferかmutalbe.ArrayBufferを使う。
配列の添字が[]ではなく()だった。Unitはvoidの事。
BigIntを使ったら9223372036854775807桁まで数値計算できた。


最大公約数を求める

可変長引数を使って、引数を何個でも取れるようにした。
<-はrange。大きい数から試行したくてRange.reverseしてみたらちゃんと動いてくれてうれしかった。
Arrayにminやmaxといったメソッドがあって楽だった。
map,filter,forallなんかも良い。


fizzbuzz

scalaは型が固いのがいいのだけど、文字列と数値どちらも渡せる関数を作りたい時もある。
Any型を使えばどんな型でも渡せる。


「ゎたしはっらぃょ」のように、小さい平仮名に変換しろ

argvで実行時引数が取れる。Mapも機能が豊富で使いやすかった。
三項演算子はないけどif elseで同じ事ができる。


素因数分解

末尾再帰の結果をlistで巻き戻して返す。
Scalaコレクションメソッドメモ(Hishidama's Scala collection method Memo)を見たら、四則演算子でlist同士を連結したり色々と操作する機能が充実してた。