LoginSignup
3
3

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-02-15

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に更新します。
ちゃんとした更新方法があるのかもしれませんが、分からなかったので以下の手順で更新しました。
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.sousr/lib/libmraa.so.0の展開にコケるので、
usr/lib/libmraa.so.0.6.0をコピーして上記2つを作成。
4. コンパイラの方にusr以下のファイルを上書きコピー

mrubyのビルド

intel edison用にmrubyをWindowsでクロスコンパイル」ではホスト側もedison側も同じmrbgems/default.gemboxを使用していましたが、
ホスト側のライブラリにmraaは含まれていないので、ホスト側とedison側のgemoboxのファイルを変えます。
mrbgems/default.gemboxmrbgems/edison.gemboxというファイル名でコピーし、

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'
も追加しておきます。

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

あとはmake

なんやかんや

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

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
http://youtu.be/tsCVauMTG1g

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3