mraaを使ってmruby on intel edisonで なんやかんや する

[mruby-mraa](https://github.com/nocd5/mruby-mraa)を作ったので
mruby on intel edison でなんやかんやしてみました。

ドキュメントは全然書いてないし、SPIは通信相手がなかったのでエコーバックくらいしか確認できてないですが…

追記
====
`Mraa::Gpio.isrに不具合があるようで
たびたびSEGVを起こします。
現在原因調査中(callbackの関数がGCで回収されちゃってるのかな？)。

追記2(R.I.P. Mraa::Gpio#isr)
===========================
なぜSEGVが起こるか、なんとなく分かった(つもり)のですが、
自分の技量では修正できないと判断し`isr`は封印しました…
かわりに`Mraa::Gpio#irq`を追加しました(あと有効/無効を切り替えるenable_irq/disable_irqも)
GPIOの割り込みタイミングでirqフラグだけセットします。
このirqは**read clear**(読み出す自動的にクリアされる)としました。
とりあえず、こうしておけば他の方法で、非同期処理も可能かな。と。
合わせてサンプルの方も修正しました。

######ぼちぼちドキュメント書こう

下準備
=====
http://iotdk.intel.com/repos/1.1/intelgalactic/
にあるmraaが0.6.0なので、それをベースに関数をラップして**mruby-mraa**を作ったので
ライブラリを更新します。

edison側
--------
```
edison$ opkg upgrade
edison$ opkg update
```
してmraaを更新します。

Windwos側
---------
今回も「[intel edison用にmrubyをWindowsでクロスコンパイル](http://qiita.com/nocd5/items/0464e3c460665d3ae2d7)」同様
Windows PCでクロスビルドします。
クロスコンパイラに入ってるライブラリが古いので、こちらも0.6.0に更新します。
ちゃんとした更新方法があるのかもしれませんが、分からなかったので以下の手順で更新しました。
1. http://iotdk.intel.com/repos/1.1/intelgalactic/ から libmraa0_0.6.0_i586.ipkをDL
2. ipkはzipなので展開する
3. 中の`data.tar`を展開する。しかし、linuxのシンボリックリンクが含まれているようで
  `usr/lib/libmraa.so`と`usr/lib/libmraa.so.0`の展開にコケるので、
  `usr/lib/libmraa.so.0.6.0`をコピーして上記2つを作成。
4. コンパイラの方に`usr`以下のファイルを上書きコピー

mrubyのビルド
============
「[intel edison用にmrubyをWindowsでクロスコンパイル](http://qiita.com/nocd5/items/0464e3c460665d3ae2d7)」ではホスト側もedison側も同じ`mrbgems/default.gembox`を使用していましたが、
ホスト側のライブラリにmraaは含まれていないので、ホスト側とedison側のgemoboxのファイルを変えます。
`mrbgems/default.gembox`を`mrbgems/edison.gembox`というファイル名でコピーし、

```rb:build_config.rb
MRuby::CrossBuild.new('edison') do |conf|
(省略)
  conf.gembox 'edison'
(省略)
end
```
と書き換えます。

次に`mrbgems/edison.gembox`に
`conf.gem :github => 'nocd5/mruby-mraa'`を追加しますが、
サンプルでSleepを使うので
`conf.gem :github => 'matsumoto-r/mruby-sleep'`
も追加しておきます。

```rb:mrbgems/edison.gembox
  conf.gem :github => 'nocd5/mruby-mraa'
  conf.gem :github => 'matsumoto-r/mruby-sleep'
```

あとは`make`

**なんやかんや**
===============
手元にI2Cで通信できる照度センサー(Si1145)があったので、
照度センサーのデータに合わせてPWMのデューティを変更し、LEDの明るさを調整してみました。
GP15の立ち上がりで終了します。

```rb:sample.rb
p RUBY_VERSION
p Mraa.version
si7013_adr  = 0x40
si1145_adr  = 0x60
adxl345_adr = 0x1d

puts "I2C-1 SDA : " + Mraa.pin_mode_test(Mraa::INTEL_EDISON_GP20, Mraa::PIN_I2C).to_s
puts "I2C-1 SCL : " + Mraa.pin_mode_test(Mraa::INTEL_EDISON_GP19, Mraa::PIN_I2C).to_s
puts "PWM-1     : " + Mraa.pin_mode_test(Mraa::INTEL_EDISON_GP13, Mraa::PIN_PWM).to_s
puts "GPIO-15   : " + Mraa.pin_mode_test(Mraa::INTEL_EDISON_GP15, Mraa::PIN_GPIO).to_s

# Initialize LightSensor
i2c = Mraa::I2c.new(1)
i2c.address(si1145_adr)
# PARAM_WR=0x10
i2c.write_reg(0x30, 0x17)
# WRITE TO RAM (ADDR=0x01)
i2c.write_reg(0xA1, 0x18)

def readSensorData(i2c)
  # Start Mearsurement
  i2c.write_reg(0x06, 0x18)
  # ALS_VIS
  als_vis = i2c.read_reg(0x22) + (i2c.read_reg(0x23) << 8)
  # ALS_IR
  als_ir  = i2c.read_reg(0x24) + (i2c.read_reg(0x25) << 8)

  return als_vis, als_ir
end

gpio = Mraa::Gpio.new(Mraa::INTEL_EDISON_GP15)
gpio.enable_irq(Mraa::Gpio::EDGE_RISING)
p "gpio.irq:" + gpio.irq.to_s

pwm = Mraa::Pwm.new(Mraa::INTEL_EDISON_GP13)
Mraa.result_print pwm.owner(true)

pwm.period 10
pwm.write 1.0
pwm.enable(true)

Sleep::sleep(1)
base_vis, base_ir = readSensorData(i2c)
while true do
  current_vis, current_ir = readSensorData(i2c)

  pwm.write base_vis.to_f/current_vis.to_f

  Sleep::usleep(100000)

  if gpio.irq then
    p "gpio.irq:" + gpio.irq.to_s
    p "irq is asserted"
    gpio.disable_irq
    break
  end
end

Sleep::sleep(1)

p "-- exit --"
```

なんとなく動画とってみました
![snapshot-15-02-15-180610.png](https://qiita-image-store.s3.amazonaws.com/0/52493/074842ef-f755-37cd-d892-1705737a79ca.png)
http://youtu.be/tsCVauMTG1g