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でクロスコンパイル」同様
Windows PCでクロスビルドします。
クロスコンパイラに入ってるライブラリが古いので、こちらも0.6.0に更新します。
ちゃんとした更新方法があるのかもしれませんが、分からなかったので以下の手順で更新しました。
- http://iotdk.intel.com/repos/1.1/intelgalactic/ から libmraa0_0.6.0_i586.ipkをDL
- ipkはzipなので展開する
- 中の
data.tar
を展開する。しかし、linuxのシンボリックリンクが含まれているようで
usr/lib/libmraa.so
とusr/lib/libmraa.so.0
の展開にコケるので、
usr/lib/libmraa.so.0.6.0
をコピーして上記2つを作成。 - コンパイラの方に
usr
以下のファイルを上書きコピー
mrubyのビルド
「intel edison用にmrubyをWindowsでクロスコンパイル」ではホスト側もedison側も同じmrbgems/default.gembox
を使用していましたが、
ホスト側のライブラリにmraaは含まれていないので、ホスト側とedison側のgemoboxのファイルを変えます。
mrbgems/default.gembox
をmrbgems/edison.gembox
というファイル名でコピーし、
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'
も追加しておきます。
conf.gem :github => 'nocd5/mruby-mraa'
conf.gem :github => 'matsumoto-r/mruby-sleep'
あとはmake
なんやかんや
手元にI2Cで通信できる照度センサー(Si1145)があったので、
照度センサーのデータに合わせてPWMのデューティを変更し、LEDの明るさを調整してみました。
GP15の立ち上がりで終了します。
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 --"
なんとなく動画とってみました
http://youtu.be/tsCVauMTG1g