theremin-pi/theremin/lib/gpio.rb
mahlon 07b2d81523 Initial commit.
Stuff working well with a single 3-pin range finder.

FossilOrigin-Name: 483d8caaef350827c026d7c234b026e9e720d26a7e27e54b0436f60b099a0ab9
2023-05-09 03:32:09 +00:00

121 lines
2.1 KiB
Ruby
Executable file

# -*- ruby -*-
# vim: set noet sta sw=4 ts=4 :
require 'socket'
require 'configurability'
require 'loggability'
require 'pathname'
# A representation of a GPIO pin.
# Manages basic reads/writes (HIGH/LOW).
#
class GPIO
extend Configurability,
Loggability
# Default read timeout.
TIMEOUT = 0.5
# The sysfs path.
BASE = Pathname( "/sys/class/gpio" )
# Loggability API
log_as :gpio
### Instance a new GPIO at +pin+. It will be automatically exported.
###
def initialize( pin )
@pin = pin
@paths = {
export: BASE + "export",
unexport: BASE + "unexport",
edge: BASE + "gpio#{pin}" + "edge",
direction: BASE + "gpio#{pin}" + "direction",
value: BASE + "gpio#{pin}" + "value"
}
self.export rescue Errno::EBUSY nil
end
# The GPIO PIN number.
attr_reader :pin
### Mark this pin as either input or output.
###
def mode( dir )
case dir.to_sym
when :in, :out
self.set( :direction ) { dir.to_s }
else
raise "Mode must be :in or :out."
end
end
### Hint at voltage measurement capture.
###
def edge( mode )
case mode.to_sym
when :none, :rising, :falling, :both
self.set( :edge ) { mode.to_s }
else
raise "Edge must be one of: :none, :rising, :falling, or :both"
end
end
### Tell the operating system to make this gpio available to sysfs.
###
def export
self.set( :export ) { self.pin }
end
### Remove this gpio from sysfs.
###
def unexport
self.set( :unexport ) { self.pin }
end
### Write a single +val+ to the GPIO.
###
def write( val )
self.set( :value ) { val }
end
### Read a single value from the GPIO, with an optional timeout.
###
def read( timeout=TIMEOUT )
io = @paths[ :value ].open
ready = IO.select( [io], nil, nil, timeout )
return unless ready # timeout
rv = io.read( 1 ).to_i
self.log.debug "Read %p from GPIO %d" % [ rv, self.pin ]
return rv
ensure
io.close
end
#########
protected
#########
### Generic write helper.
###
def set( path, &block )
@paths[ path ].open( 'w' ) do |f|
self.log.debug "Writing %p to %p of GPIO %d" % [ block.yield, path, self.pin ]
f.puts( block.yield )
end
end
end