Ruby
IoT
Edison

Intel Edison と ruby で Lチカ

More than 3 years have passed since last update.

ruby で Lチカさせるのやってみたかった。

Intel Edison の GPIO

Edison に Breakout Board を装着すると色々な I/O が引き出せるようになります。
GPIO はプログラムで ON/OFF を制御することができるのでソフトウェアで外部に接続した何かを動かすには基本となります。

Breakout Board のマニュアルを見ながらそこにテスト用のコードをハンダ付けしていきます。
今回は GND, GPIOx2, I2Cの2本を選択しました。
DSC00709.JPG

J19-3 --- GND
J20-7 --- GPIO15
J18-2 --- GPIO165
J18-6 --- I2C_1 SCL
J17-8 --- I2C_1 SDA

ここで注意すべき点があります。
Edison で使っているのは高密度な SoC でホビー用の一般的なマイコンと異なりますので、通常のマイコン電子工作とは違って GPIO の電圧が 5V や 3.3V ではありません。Edison のポート電圧は 1.8V となっています。
また電流のドライブ能力も 3mA しかありませんので、この信号で LED を点灯させることはおろかシンク電流としての能力も期待できず LED を直接繋げるのは御法度です。

GPIO sysfs の基本

Linux のユーザーランドから GPIO を操作する手法としてはグローバルな GPIO sysfs を用いる方法が一般的なようです。Intel のネイティブポートドライバーがあるのかどうか良くわかりません。

GPIO sysfs では GPIO デバイスが /sys/class/gpio/ の中に見えます。
この /sys/class/gpio/ にマウントされたデバイスにファイルシステムとしてアクセスすることで、GPIO の制御ができるようになります。

ポートを GPIO として利用する

/sys/class/gpio/ の中を覗いてもまだ gpio15 と gpio165 がいないかもしれません。
まずはポートを GPIO として使用する宣言が必要です。

使用したいポート番号をテキストで /sys/class/gpio/export に書き込みます。

echo '165' > /sys/class/gpio/export
echo '15' > /sys/class/gpio/export

これで gpio15 と gpio165 が現れます。

ポートの方向を指定する

GPIO には in と out の二種類があります。
out は CPU からの制御で ON/OFF をピンに出力します。
in はポートにかかっている ON/OFF (を表す電圧)を CPU に読み込みます。
out では LED を光らせたりするのに対し、in ではスイッチが押されたかどうかの検知に使われます。
このポート方向の指定は gpio フォルダ内の direction で指定します。

echo 'out' > /sys/class/gpio/gpio15/direction
echo 'out' > /sys/class/gpio/gpio165/direction

今回は LED を光らすことが目的なので out しか使いません。

ポートを ON/OFF する

以上で準備が完了しています。あとは、gpio の value に値を書き込んで制御を行ってください。

echo '1' > /sys/class/gpio/gpio15/value
echo '0' > /sys/class/gpio/gpio165/value

1を設定するとGPIOポートの電圧が 1.8V になることが計測でわかります。
まずはテスター等で確認してください。

LEDを光らせたい

次はお待ちかねの LEDチカチカです。

トランジスタドライバ

Edison の SoC から主力される GPIO は 電圧 1.8V、電流 3mA と微弱なモノです、これで LED を点灯させるわけにはいきませんのでトランジスタで電流電圧増幅をしてやる必要があります。

今回はこんな回路を組みました。
LED_drive.PNG

ブレッドボードなりで実装します。
DSC00711.JPG

最初はGPIOの代わりに 5V を与えて光ることを確認してください。
次に GPIO に繋いだあと、GPIO sysfs をコマンドラインから制御して LED を ON/OFF できることを確認してください。
成功したらほとんど完成です。おめでとうございます。

ruby でLEDチカチカ

ねんがんの るびーで Lちか が できたぞ

ruby_led_flush.rb
def gpio_out(port)
  number = port.to_s
  if !File.exist?("/sys/class/gpio/gpio#{number}") then
    open("/sys/class/gpio/export", "w") do |fp|
      fp << number
    end
  end
  open("/sys/class/gpio/gpio#{number}/direction", "w") do |fp|
    fp << 'out'
  end
end

def led(port, sw)
  code = "0"
  if sw == true then
    code = '1'
  end
  open("/sys/class/gpio/gpio#{port}/value", "w") do |fp|
    fp << code
  end
end

# ---- main
gpio_out(15)
gpio_out(165)

t = Thread.new do
  while(1) do
    led("15", true)
    sleep(0.5)
    led("15", false)
    sleep(0.5)
  end
end

Thread.new do
  while(1) do
    led("165", true)
    sleep(0.8)
    led("165", false)
    sleep(0.8)
  end
end

t.join