コンテンツにスキップ

周辺機器 (GPIO / I2C / RMT)

ハードウェア周辺機器を Ruby から操作するための API です。

Note

各端子のピン配置・電気的仕様は ハードウェア を参照してください。
ピンが他の機能で使われていないかは FmrbHw.pin_status で確認できます。

GPIO

デジタル入出力です。

コンストラクタ

GPIO.new(pin, flags, alt_function = 0)
引数 用途
pin GPIO 番号
flags 方向・プル設定(OR で組み合わせ可)
alt_function 代替機能番号(通常 0

flags 定数

定数 意味
GPIO::IN 入力
GPIO::OUT 出力
GPIO::HIGH_Z ハイインピーダンス
GPIO::PULL_UP プルアップ抵抗有効
GPIO::PULL_DOWN プルダウン抵抗有効
GPIO::OPEN_DRAIN オープンドレイン出力
GPIO::ALT 代替機能

OR で組み合わせます:

btn = GPIO.new(10, GPIO::IN | GPIO::PULL_UP)
led = GPIO.new(11, GPIO::OUT)

インスタンスメソッド

メソッド 用途
read レベル読み出し(0 / 1
write(val) 0 または 1 を出力
high? レベルが High なら true
low? レベルが Low なら true

クラスメソッド(インスタンスを作らずダイレクト操作)

メソッド 用途
GPIO.read_at(pin) レベル読み出し
GPIO.write_at(pin, val) レベル出力
GPIO.high_at?(pin) / GPIO.low_at?(pin) レベル判定
GPIO.set_dir_at(pin, dir) 方向のみ変更
GPIO.pull_up_at(pin) / GPIO.pull_down_at(pin) プル抵抗を有効化
GPIO.open_drain_at(pin) オープンドレイン
GPIO.set_function_at(pin, alt) 代替機能

サンプル: ボタンで LED トグル

class LedToggle < FmrbApp
  BTN_PIN = 10
  LED_PIN = 11

  def on_create
    @btn = GPIO.new(BTN_PIN, GPIO::IN | GPIO::PULL_UP)
    @led = GPIO.new(LED_PIN, GPIO::OUT)
    @led.write(0)
    @prev = 1
  end

  def on_update
    cur = @btn.read
    if @prev == 1 && cur == 0   # 立ち下がり
      @led.write(@led.read == 1 ? 0 : 1)
    end
    @prev = cur
    20
  end
end

LedToggle.new.start

I2C

I2C バス経由でデバイスと通信します。

コンストラクタ

I2C.new(unit:, frequency: 100_000, sda_pin: -1, scl_pin: -1, timeout: 500)
引数 用途
unit: バス識別子。例: "ESP32_I2C0""ESP32_I2C1"
frequency: クロック周波数 (Hz)。デフォルト 100kHz
sda_pin: / scl_pin: -1 で既定ピンを使用
timeout: タイムアウト ms

メソッド

メソッド 用途
read(addr_7bit, length, timeout: @timeout, *write_data) リード(write_data があれば事前ライト → STOP なしでリード)
write(addr_7bit, *data, timeout: @timeout) ライト。Integer / Array<Integer> / String を受け付け
scan(timeout: @timeout) 0x08〜0x77 をスキャンして応答デバイス一覧を返す
close バス解放

サンプル: I2C デバイスのスキャン

i2c = I2C.new(unit: "ESP32_I2C0", frequency: 400_000)
addrs = i2c.scan
Log.info("found: #{addrs.map { |a| a.to_s(16) }.join(', ')}")

サンプル: レジスタ読み書き

i2c = I2C.new(unit: "ESP32_I2C0")
# レジスタ 0x10 から 4 バイト読み出し
data = i2c.read(0x32, 4, 0x10)   # 第3引数以降が write_data
i2c.write(0x32, 0x10, 0xAB)      # 0x10 = 0xAB を書き込み

RMT

ESP32 の RMT ペリフェラル経由で WS2812B / WS2812 LED や赤外線リモコンを駆動します。

コンストラクタ

RMT.new(pin, t0h_ns:, t0l_ns:, t1h_ns:, t1l_ns:, reset_ns:)

NRZ 符号化のタイミング(ナノ秒)を指定します。WS2812B の標準値:

rmt = RMT.new(8,
              t0h_ns: 350,  t0l_ns: 900,
              t1h_ns: 700,  t1l_ns: 600,
              reset_ns: 50_000)

メソッド

メソッド 用途
write(*params) バイト列出力。Integer / Array / String 引数対応

サンプル: WS2812B を点灯

class LedStrip < FmrbApp
  RMT_PIN = 8

  def on_create
    @rmt = RMT.new(RMT_PIN,
                    t0h_ns: 350,  t0l_ns: 900,
                    t1h_ns: 700,  t1l_ns: 600,
                    reset_ns: 50_000)
    set_color(0xFF, 0x00, 0x00)  # 赤
  end

  def set_color(r, g, b)
    # WS2812B は GRB 順
    @rmt.write([g, r, b])
  end
end

LedStrip.new.start

flash/app/demo/led_matrix.app.rb に WS2812B マトリクスのサンプルがあります。

ピン割り当て確認

ピンを使う前に、システムが既に使っていないか確認できます。

unless FmrbHw.pin_available?(10)
  Log.error("Pin 10 already in use: #{FmrbHw.pin_status(10)}")
  return
end

詳細は FmrbHw を参照。