class Frankenpins::Pin

Represents a GPIO pin on the Raspberry Pi

Constants

INPUT
PUD_DOWN
PUD_OFF
PUD_UP

Attributes

direction[R]
invert[R]
io[R]
last_value[R]
pin[R]
value[R]
wiring_pin[R]

Public Class Methods

new(options) click to toggle source

Initializes a new GPIO pin.

@param [Hash] options A hash of options
@option options [Fixnum] :pin The pin number to initialize. Required.
@option options [Symbol] :direction The direction of communication, either :in or :out. Defaults to :in.
@option options [Boolean] :invert Indicates if the value read from the physical pin should be inverted. Defaults to false.
@option options [Symbol] :trigger Indicates when the wait_for_change method will detect a change, either :rising, :falling, or :both edge triggers. Defaults to :both.
@option options [Symbol] :pull Use an internal pull-up/down resistor, either :up, :down, :none
# File lib/frankenpins/pin.rb, line 31
def initialize(options)
  options = {:direction => :in, :invert => false, :trigger => :both, :pull => :none}.merge options
  @io = WiringPiSingleton.gpio_instance

  @wiring_pin = options[:pin]
  @pin = wiring_to_gpio(options[:pin])
  @direction = options[:direction]
  @invert = options[:invert]
  @trigger = options[:trigger]
  @pull = options[:pull]

  raise "Invalid direction. Options are :in or :out" unless [:in, :out].include? @direction
  raise "Invalid trigger. Options are :rising, :falling, or :both" unless [:rising, :falling, :both].include? @trigger

  File.open("/sys/class/gpio/export", "w") { |f| f.write("#{@pin}") }
  File.open(direction_file, "w") { |f| f.write(@direction == :out ? "out" : "in") }

  if @pull == :up || @pull == :down
    direction = PUD_UP   if @pull == :up
    direction = PUD_DOWN if @pull == :down
    @io.pull_up_dn_control(@wiring_pin, direction)
  end

  read
end

Public Instance Methods

changed?() click to toggle source

Tests if the logic level has changed since the pin was last read.

# File lib/frankenpins/pin.rb, line 84
def changed?
  last_value != value
end
off() click to toggle source

If the pin has been initialized for output this method will set the logic level low.

# File lib/frankenpins/pin.rb, line 68
def off
  File.open(value_file, 'w') {|f| f.write("0") } if direction == :out
end
off?() click to toggle source

Tests if the logic level is low.

# File lib/frankenpins/pin.rb, line 73
def off?
  value == 0
end
on() click to toggle source

If the pin has been initialized for output this method will set the logic level high.

# File lib/frankenpins/pin.rb, line 58
def on
  File.open(value_file, 'w') {|f| f.write("1") } if direction == :out
end
on?() click to toggle source

Tests if the logic level is high.

# File lib/frankenpins/pin.rb, line 63
def on?
  not off?
end
read() click to toggle source

Reads the current value from the pin. Without calling this method first, ‘value`, `last_value` and `changed?` will not be updated. In short, you must call this method if you are curious about the current state of the pin.

# File lib/frankenpins/pin.rb, line 106
def read
  @last_value = @value
  val = File.read(value_file).to_i
  @value = invert ? (val ^ 1) : val
end
update_value(new_value) click to toggle source

If the pin has been initialized for output this method will either raise or lower the logic level depending on ‘new_value`. @param [Object] new_value If false or 0 the pin will be set to off, otherwise on.

# File lib/frankenpins/pin.rb, line 79
def update_value(new_value)
  !new_value || new_value == 0 ? off : on
end
wait_for_change() click to toggle source

blocks until a logic level change occurs. The initializer option ‘:trigger` modifies what edge this method will release on.

# File lib/frankenpins/pin.rb, line 89
def wait_for_change
  fd = File.open(value_file, "r")
  File.open(edge_file, "w") { |f| f.write("both") }
  loop do
    fd.read
    IO.select(nil, nil, [fd], nil)
    read
    if changed?
      next if @trigger == :rising and value == 0
      next if @trigger == :falling and value == 1
      break
    end
  end
end
wiring_to_gpio(pin) click to toggle source
# File lib/frankenpins/pin.rb, line 19
def wiring_to_gpio(pin)
  @io.wpi_pin_to_gpio(pin)
end
write(value) click to toggle source
# File lib/frankenpins/pin.rb, line 112
def write(value)
  value = value ? "1" : "0"
  File.open(value_file, 'w') {|f| f.write(value) } if direction == :out
end

Private Instance Methods

direction_file() click to toggle source
# File lib/frankenpins/pin.rb, line 126
def direction_file
  "/sys/class/gpio/gpio#{pin}/direction"
end
edge_file() click to toggle source
# File lib/frankenpins/pin.rb, line 122
def edge_file
  "/sys/class/gpio/gpio#{pin}/edge"
end
value_file() click to toggle source
# File lib/frankenpins/pin.rb, line 118
def value_file
  "/sys/class/gpio/gpio#{pin}/value"
end