Skip to content

Peripherals (GPIO / I2C / RMT)

Note

Under construction.

APIs for operating hardware peripherals from Ruby.

Note

For pin layouts and electrical specifications, see Hardware. To check whether a pin is already in use by another function, use FmrbHw.pin_status.

GPIO

Digital input/output.

Constructor

GPIO.new(pin, flags, alt_function = 0)
Argument Purpose
pin GPIO number
flags Direction and pull configuration (can be OR-combined)
alt_function Alternate function number (normally 0)

flags Constants

Constant Meaning
GPIO::IN Input
GPIO::OUT Output
GPIO::HIGH_Z High impedance
GPIO::PULL_UP Pull-up resistor enabled
GPIO::PULL_DOWN Pull-down resistor enabled
GPIO::OPEN_DRAIN Open drain output
GPIO::ALT Alternate function

Combine with OR:

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

Instance Methods

Method Purpose
read Read the level (0 / 1)
write(val) Output 0 or 1
high? Returns true if the level is High
low? Returns true if the level is Low

Class Methods (Direct Operation Without Creating an Instance)

Method Purpose
GPIO.read_at(pin) Read level
GPIO.write_at(pin, val) Output level
GPIO.high_at?(pin) / GPIO.low_at?(pin) Level check
GPIO.set_dir_at(pin, dir) Change direction only
GPIO.pull_up_at(pin) / GPIO.pull_down_at(pin) Enable pull resistor
GPIO.open_drain_at(pin) Open drain
GPIO.set_function_at(pin, alt) Alternate function

Example: Toggle LED with a Button

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   # Falling edge
      @led.write(@led.read == 1 ? 0 : 1)
    end
    @prev = cur
    20
  end
end

LedToggle.new.start

I2C

Communicates with devices via the I2C bus.

Constructor

I2C.new(unit:, frequency: 100_000, sda_pin: -1, scl_pin: -1, timeout: 500)
Argument Purpose
unit: Bus identifier. e.g. "ESP32_I2C0", "ESP32_I2C1"
frequency: Clock frequency (Hz). Default 100kHz
sda_pin: / scl_pin: -1 uses the default pins
timeout: Timeout in ms

Methods

Method Purpose
read(addr_7bit, length, timeout: @timeout, *write_data) Read (write_data triggers a write first, then read without STOP)
write(addr_7bit, *data, timeout: @timeout) Write. Accepts Integer / Array<Integer> / String
scan(timeout: @timeout) Scan addresses 0x08 to 0x77 and return a list of responding devices
close Release the bus

Example: Scanning I2C Devices

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

Example: Register Read/Write

i2c = I2C.new(unit: "ESP32_I2C0")
# Read 4 bytes starting from register 0x10
data = i2c.read(0x32, 4, 0x10)   # Arguments after the 2nd are write_data
i2c.write(0x32, 0x10, 0xAB)      # Write 0xAB to register 0x10

RMT

Drives WS2812B / WS2812 LEDs and infrared remotes via the ESP32 RMT peripheral.

Constructor

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

Specifies NRZ encoding timing in nanoseconds. Standard values for WS2812B:

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

Methods

Method Purpose
write(*params) Output byte sequence. Accepts Integer / Array / String arguments

Example: Lighting WS2812B LEDs

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)  # Red
  end

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

LedStrip.new.start

A WS2812B matrix sample is available in /app/demo/led_matrix.app.rb.

Pin Assignment Check

Before using a pin, you can check whether the system is already using it.

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

For details, see FmrbHw.