Stuff working well with a single 3-pin range finder. FossilOrigin-Name: 483d8caaef350827c026d7c234b026e9e720d26a7e27e54b0436f60b099a0ab9
121 lines
2.1 KiB
Ruby
Executable file
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
|
|
|