pi_piper 1.9.9 → 2.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -3
- data/Gemfile.lock +12 -42
- data/README.md +8 -38
- data/Rakefile +7 -8
- data/lib/pi_piper.rb +2 -41
- data/lib/pi_piper/bcm2835.rb +12 -46
- data/lib/pi_piper/i2c.rb +1 -4
- data/lib/pi_piper/libbcm2835.img +0 -0
- data/lib/pi_piper/pin.rb +43 -98
- data/lib/pi_piper/platform.rb +4 -6
- data/lib/pi_piper/spi.rb +15 -30
- data/pi_piper.gemspec +8 -19
- metadata +14 -99
- data/.gitignore +0 -4
- data/.rspec +0 -3
- data/.travis.yml +0 -8
- data/examples/2_bit_counter/2_bit_counter.rb +0 -22
- data/examples/7-segment/7-segment.rb +0 -37
- data/examples/dsl_switch/dsl_switch.rb +0 -15
- data/examples/mcp3008/circuit.png +0 -0
- data/examples/mcp3008/mcp3008.rb +0 -55
- data/examples/mcp3008_spi/mcp3008_spi.rb +0 -24
- data/examples/morse_code/circuit.png +0 -0
- data/examples/morse_code/morse_code.rb +0 -43
- data/examples/simple_switch/circuit.png +0 -0
- data/examples/simple_switch/simple_switch.rb +0 -10
- data/lib/pi_piper/libbcm2835.so +0 -0
- data/lib/pi_piper/pin_error.rb +0 -3
- data/lib/pi_piper/pin_values.rb +0 -10
- data/lib/pi_piper/stub_driver.rb +0 -107
- data/spec/i2c_spec.rb +0 -83
- data/spec/pin_spec.rb +0 -149
- data/spec/pull_mode_spec.rb +0 -70
- data/spec/spec_helper.rb +0 -7
- data/spec/spi_spec.rb +0 -44
- data/spec/stub_driver_spec.rb +0 -140
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cecbad62bc8eeedf7e061bfc03396691f584ee82
|
4
|
+
data.tar.gz: 5c22774ad6b6c737019baa7802c99934668f537a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dac9621e23d30b021ead1b74f30496fedfa93474346bb1656fb5a9f1a882e7bedfbdff87c28e6b3b4c3c84adb39427599a37c1eedd3c9fde9f318c22e7e3d5c7
|
7
|
+
data.tar.gz: 7167326e0245ee3a3272fc926298b94d7aa2b4e893c5b20f8ce5bb6a84414efca45bb5776adac1454a60f4e8f7c2eb4b3c9d792c623c5926ccbdfa006d89f008
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,10 +1,3 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
pi_piper (2.0.beta.11)
|
5
|
-
eventmachine (= 1.0.9)
|
6
|
-
ffi
|
7
|
-
|
8
1
|
GEM
|
9
2
|
remote: https://rubygems.org/
|
10
3
|
specs:
|
@@ -16,50 +9,27 @@ GEM
|
|
16
9
|
rake (>= 0.9.2)
|
17
10
|
rdoc (>= 3.6.1)
|
18
11
|
rubyforge (>= 2.0.4)
|
19
|
-
|
20
|
-
ffi (1.9.0)
|
12
|
+
ffi (1.4.0)
|
21
13
|
gemcutter (0.7.1)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
rspec-expectations (~> 3.4.0)
|
34
|
-
rspec-mocks (~> 3.4.0)
|
35
|
-
rspec-core (3.4.1)
|
36
|
-
rspec-support (~> 3.4.0)
|
37
|
-
rspec-expectations (3.4.0)
|
38
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
39
|
-
rspec-support (~> 3.4.0)
|
40
|
-
rspec-mocks (3.4.1)
|
41
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
42
|
-
rspec-support (~> 3.4.0)
|
43
|
-
rspec-support (3.4.1)
|
14
|
+
json_pure (1.7.7)
|
15
|
+
rake (10.0.3)
|
16
|
+
rdoc (4.0.0)
|
17
|
+
rspec (2.14.1)
|
18
|
+
rspec-core (~> 2.14.0)
|
19
|
+
rspec-expectations (~> 2.14.0)
|
20
|
+
rspec-mocks (~> 2.14.0)
|
21
|
+
rspec-core (2.14.5)
|
22
|
+
rspec-expectations (2.14.2)
|
23
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
24
|
+
rspec-mocks (2.14.3)
|
44
25
|
rubyforge (2.0.4)
|
45
26
|
json_pure (>= 1.1.7)
|
46
|
-
simplecov (0.7.1)
|
47
|
-
multi_json (~> 1.0)
|
48
|
-
simplecov-html (~> 0.7.1)
|
49
|
-
simplecov-html (0.7.1)
|
50
27
|
|
51
28
|
PLATFORMS
|
52
29
|
ruby
|
53
30
|
|
54
31
|
DEPENDENCIES
|
55
32
|
echoe
|
56
|
-
eventmachine (~> 1.0.9)
|
57
33
|
ffi
|
58
|
-
mocha
|
59
|
-
pi_piper!
|
60
34
|
rake
|
61
35
|
rspec
|
62
|
-
simplecov
|
63
|
-
|
64
|
-
BUNDLED WITH
|
65
|
-
1.11.2
|
data/README.md
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
## Overview
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
Pi Piper brings event driven programming to the Raspberry Pi's GPIO pins. Pi Piper works with all revisions of the Raspberry Pi,
|
3
|
+
Pi Piper brings event driven programming to the Raspberry Pi's GPIO pins. Pi Piper works with all revisions of the Raspberry Pi,
|
6
4
|
and has been tested with Ruby 1.9.3 & 2.0 under both [Raspbian "wheezy"](http://www.raspberrypi.org/downloads) and [Occidentalis v0.2](http://learn.adafruit.com/adafruit-raspberry-pi-educational-linux-distro/occidentalis-v0-dot-2).
|
7
5
|
|
8
6
|
To get started:
|
9
7
|
|
10
8
|
If you do not already have Ruby installed, first you'll need to:
|
11
|
-
|
9
|
+
|
12
10
|
sudo apt-get install ruby ruby1.9.1-dev
|
13
|
-
|
11
|
+
|
14
12
|
Despite one of the packages being titled "ruby1.9.1-dev", the above command will install Ruby 1.9.3 (as of January 2013) and the Ruby dev tools.
|
15
13
|
|
16
14
|
To install Pi Piper:
|
@@ -40,7 +38,7 @@ PiPiper.wait
|
|
40
38
|
|
41
39
|
Your block will be called when a change to the pin's state is detected.
|
42
40
|
|
43
|
-
When using pins as input, you can use internal resistors to pull the pin
|
41
|
+
When using pins as input, you can use internal resistors to pull the pin
|
44
42
|
up or pull down. This is important if you use open-collector sensors
|
45
43
|
which have floating output in some states.
|
46
44
|
|
@@ -65,26 +63,15 @@ sleep 1
|
|
65
63
|
pin.off
|
66
64
|
```
|
67
65
|
|
68
|
-
_please note, in the above context "pin" refers to the GPIO number of the Raspberry Pi._
|
69
|
-
|
70
66
|
### SPI
|
71
|
-
Starting with version 1.2, Pi Piper offers SPI support.
|
67
|
+
Starting with version 1.2, Pi Piper offers SPI support.
|
72
68
|
|
73
69
|
```ruby
|
74
|
-
PiPiper::Spi.begin do
|
75
|
-
puts write [0x01, 0x80, 0x00]
|
70
|
+
PiPiper::Spi.begin do
|
71
|
+
puts write [0x01, 0x80, 0x00]
|
76
72
|
end
|
77
73
|
```
|
78
74
|
|
79
|
-
If you are using an operating system that supports `/dev/spidev0.0` like the [adafruit
|
80
|
-
distro][adafruit-linux] you can also write to the spi using `PiPiper::Spi.spidev_out`
|
81
|
-
|
82
|
-
```ruby
|
83
|
-
# Example writing red, green, blue to a string of WS2801 pixels
|
84
|
-
PiPiper::Spi.spidev_out([255,0,0,0,255,0,0,0,255])
|
85
|
-
```
|
86
|
-
[adafruit-linux]:http://learn.adafruit.com/adafruit-raspberry-pi-educational-linux-distro/overview
|
87
|
-
|
88
75
|
## Documentation
|
89
76
|
|
90
77
|
API documentation for Pi Piper can be found at [rdoc.info](http://rdoc.info/github/jwhitehorn/pi_piper/frames/).
|
@@ -98,26 +85,9 @@ Looking for more examples/sample code for Pi Piper? Then check out the following
|
|
98
85
|
* [Project 3: 2-bit counter](https://github.com/jwhitehorn/pi_piper/wiki/Project-3:-2-bit-counter)
|
99
86
|
* [Project 4: MCP3008](https://github.com/jwhitehorn/pi_piper/wiki/Project-4:-MCP3008)
|
100
87
|
|
101
|
-
## Under the hood
|
102
|
-
|
103
|
-
PiPiper use the libbcm2835 library from Mike McCauley at airspayce.
|
104
|
-
|
105
|
-
http://www.airspayce.com/mikem/bcm2835/index.html
|
106
|
-
|
107
|
-
if you want to upgrade or downgrade the library for compatibility reason, get it and make it a shared object library :
|
108
|
-
|
109
|
-
```script
|
110
|
-
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.49.tar.gz
|
111
|
-
tar zxvf bcm2835-1.49.tar.gz && cd bcm2835-1.49
|
112
|
-
./configure && make
|
113
|
-
sudo make check
|
114
|
-
sudo make install
|
115
|
-
cd src && cc -shared bcm2835.o -o libbcm2835.so
|
116
|
-
cp libbcm2835.so ~/pi_piper/lib/pi_piper
|
117
|
-
|
118
88
|
## License
|
119
89
|
|
120
|
-
Copyright (c) 2013, [Jason Whitehorn](https://github.com/jwhitehorn)
|
90
|
+
Copyright (c) 2013, [Jason Whitehorn](https://github.com/jwhitehorn)
|
121
91
|
All rights reserved.
|
122
92
|
|
123
93
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
data/Rakefile
CHANGED
@@ -1,24 +1,23 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
|
-
require '
|
4
|
+
require 'rake/testtask'
|
5
5
|
|
6
6
|
#rake manifest
|
7
7
|
#rake build_gemspec
|
8
|
-
#
|
9
|
-
#gem push xxx.gem
|
8
|
+
#rake release
|
10
9
|
|
11
|
-
Echoe.new('pi_piper', '2.0.beta.
|
10
|
+
Echoe.new('pi_piper', '2.0.beta.1') do |p|
|
12
11
|
p.description = "Event driven Raspberry Pi GPIO library"
|
13
12
|
p.url = "http://github.com/jwhitehorn/pi_piper"
|
14
13
|
p.author = "Jason Whitehorn"
|
15
14
|
p.email = "jason.whitehorn@gmail.com"
|
16
15
|
p.ignore_pattern = ["examples/**/*", "spec/**/*"]
|
17
|
-
p.dependencies = ['ffi'
|
16
|
+
p.dependencies = ['ffi']
|
18
17
|
end
|
19
18
|
|
20
19
|
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
Rake::TestTask.new do |t|
|
22
|
+
t.pattern = 'spec/**/*_spec.rb'
|
23
|
+
end
|
data/lib/pi_piper.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'eventmachine'
|
2
1
|
Dir[File.dirname(__FILE__) + '/pi_piper/*.rb'].each {|file| require file unless file.end_with?('bcm2835.rb') }
|
3
2
|
|
4
3
|
module PiPiper
|
@@ -11,7 +10,7 @@ module PiPiper
|
|
11
10
|
# Options hash. Options include `:pin`, `:invert` and `:trigger`.
|
12
11
|
#
|
13
12
|
def watch(options, &block)
|
14
|
-
|
13
|
+
Thread.new do
|
15
14
|
pin = PiPiper::Pin.new(options)
|
16
15
|
loop do
|
17
16
|
pin.wait_for_change
|
@@ -21,9 +20,7 @@ module PiPiper
|
|
21
20
|
pin.instance_exec &block
|
22
21
|
end
|
23
22
|
end
|
24
|
-
end
|
25
|
-
new_thread.abort_on_exception = true
|
26
|
-
new_thread
|
23
|
+
end.abort_on_exception = true
|
27
24
|
end
|
28
25
|
|
29
26
|
#Defines an event block to be executed after a pin either goes high or low.
|
@@ -35,44 +32,8 @@ module PiPiper
|
|
35
32
|
options[:trigger] = options.delete(:goes) == :high ? :rising : :falling
|
36
33
|
watch options, &block
|
37
34
|
end
|
38
|
-
|
39
|
-
#Defines an event block to be called on a regular schedule. The block will be passed the slave output.
|
40
|
-
#
|
41
|
-
# @param [Hash] options A hash of options.
|
42
|
-
# @option options [Fixnum] :every A frequency of time (in seconds) to poll the SPI slave.
|
43
|
-
# @option options [Fixnum] :slave The slave number to poll.
|
44
|
-
# @option options [Number|Array] :write Data to poll the SPI slave with.
|
45
|
-
def poll_spi(options, &block)
|
46
|
-
EM::PeriodicTimer.new(options[:every]) do
|
47
|
-
Spi.begin options[:slave] do
|
48
|
-
output = write options[:write]
|
49
|
-
block.call output
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
#Defines an event block to be called when SPI slave output meets certain characteristics.
|
55
|
-
#The block will be passed the slave output.
|
56
|
-
#
|
57
|
-
# @param [Hash] options A hash of options.
|
58
|
-
# @option options [Fixnum] :every A frequency of time (in seconds) to poll the SPI slave.
|
59
|
-
# @option options [Fixnum] :slave The slave number to poll.
|
60
|
-
# @option options [Number|Array] :write Data to poll the SPI slave with.
|
61
|
-
# @option options [Fixnum] :eq Tests for SPI slave output equality.
|
62
|
-
# @option options [Fixnum] :lt Tests for SPI slave output less than supplied value.
|
63
|
-
# @option options [Fixnum] :gt Tests for SPI slave output greater than supplied value.
|
64
|
-
def when_spi(options, &block)
|
65
|
-
poll_spi options do |value|
|
66
|
-
if (options[:eq] && value == options[:eq]) ||
|
67
|
-
(options[:lt] && value < options[:lt]) ||
|
68
|
-
(options[:gt] && value > options[:gt])
|
69
|
-
block.call value
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
35
|
|
74
36
|
#Prevents the main thread from exiting. Required when using PiPiper.watch
|
75
|
-
# @deprecated Please use EventMachine.run instead
|
76
37
|
def wait
|
77
38
|
loop do sleep 1 end
|
78
39
|
end
|
data/lib/pi_piper/bcm2835.rb
CHANGED
@@ -5,8 +5,7 @@ module PiPiper
|
|
5
5
|
# It serves as an FFI library for PiPiper::SPI & PiPiper::I2C.
|
6
6
|
module Bcm2835
|
7
7
|
extend FFI::Library
|
8
|
-
ffi_lib File.dirname(__FILE__) + '/libbcm2835.
|
9
|
-
@pins = []
|
8
|
+
ffi_lib File.dirname(__FILE__) + '/libbcm2835.img'
|
10
9
|
|
11
10
|
SPI_MODE0 = 0
|
12
11
|
SPI_MODE1 = 1
|
@@ -20,54 +19,28 @@ module PiPiper
|
|
20
19
|
|
21
20
|
attach_function :init, :bcm2835_init, [], :uint8
|
22
21
|
attach_function :close, :bcm2835_close, [], :uint8
|
23
|
-
|
22
|
+
|
24
23
|
#pin support...
|
25
|
-
attach_function :pin_set_pud,
|
24
|
+
attach_function :pin_set_pud, :bcm2835_gpio_set_pud, [:uint8, :uint8], :void
|
26
25
|
|
27
26
|
def self.pin_input(pin)
|
28
|
-
export(pin)
|
29
|
-
|
27
|
+
File.open("/sys/class/gpio/export", "w") { |f| f.write("#{pin}") }
|
28
|
+
File.open("/sys/class/gpio/gpio#{pin}/direction", "w") { |f| f.write("in") }
|
30
29
|
end
|
31
|
-
|
30
|
+
|
32
31
|
def self.pin_set(pin, value)
|
33
32
|
File.open("/sys/class/gpio/gpio#{pin}/value", 'w') {|f| f.write("#{value}") }
|
34
33
|
end
|
35
|
-
|
34
|
+
|
36
35
|
def self.pin_output(pin)
|
37
|
-
export(pin)
|
38
|
-
|
36
|
+
File.open("/sys/class/gpio/export", "w") { |f| f.write("#{pin}") }
|
37
|
+
File.open(direction_file, "w") { |f| f.write("out") }
|
39
38
|
end
|
40
|
-
|
39
|
+
|
41
40
|
def self.pin_read(pin)
|
42
41
|
File.read("/sys/class/gpio/gpio#{pin}/value").to_i
|
43
42
|
end
|
44
43
|
|
45
|
-
def self.pin_direction(pin, direction)
|
46
|
-
File.open("/sys/class/gpio/gpio#{pin}/direction", 'w') do |f|
|
47
|
-
f.write(direction)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# Exports pin and subsequently locks it from outside access
|
52
|
-
def self.export(pin)
|
53
|
-
File.open('/sys/class/gpio/export', 'w') { |f| f.write("#{pin}") }
|
54
|
-
@pins << pin unless @pins.include?(pin)
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.release_pin(pin)
|
58
|
-
File.open('/sys/class/gpio/unexport', 'w') { |f| f.write("#{pin}") }
|
59
|
-
@pins.delete(pin)
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.release_pins
|
63
|
-
@pins.dup.each { |pin| release_pin(pin) }
|
64
|
-
end
|
65
|
-
|
66
|
-
#NOTE to use: chmod 666 /dev/spidev0.0
|
67
|
-
def self.spidev_out(array)
|
68
|
-
File.open('/dev/spidev0.0', 'wb'){|f| f.write(array.pack('C*')) }
|
69
|
-
end
|
70
|
-
|
71
44
|
#SPI support...
|
72
45
|
attach_function :spi_begin, :bcm2835_spi_begin, [], :uint8
|
73
46
|
attach_function :spi_end, :bcm2835_spi_end, [], :uint8
|
@@ -86,17 +59,16 @@ module PiPiper
|
|
86
59
|
attach_function :i2c_write, :bcm2835_i2c_write, [:pointer, :uint], :uint8
|
87
60
|
attach_function :i2c_set_address,:bcm2835_i2c_setSlaveAddress, [:uint8], :void
|
88
61
|
attach_function :i2c_set_clock_divider, :bcm2835_i2c_setClockDivider, [:uint16], :void
|
89
|
-
attach_function :i2c_read, :bcm2835_i2c_read, [:pointer, :uint], :uint8
|
90
62
|
|
91
63
|
def self.i2c_allowed_clocks
|
92
64
|
[100.kilohertz,
|
93
65
|
399.3610.kilohertz,
|
94
66
|
1.666.megahertz,
|
95
|
-
1.689.megahertz]
|
67
|
+
1.689.megahertz]
|
96
68
|
end
|
97
69
|
|
98
70
|
def self.spi_transfer_bytes(data)
|
99
|
-
data_out = FFI::MemoryPointer.new(data.count)
|
71
|
+
data_out = FFI::MemoryPointer.new(data.count)
|
100
72
|
data_in = FFI::MemoryPointer.new(data.count)
|
101
73
|
(0..data.count-1).each { |i| data_out.put_uint8(i, data[i]) }
|
102
74
|
|
@@ -112,11 +84,5 @@ module PiPiper
|
|
112
84
|
i2c_write data_out, data.count
|
113
85
|
end
|
114
86
|
|
115
|
-
def self.i2c_read_bytes(bytes)
|
116
|
-
data_in = FFI::MemoryPointer.new(bytes)
|
117
|
-
i2c_read(data_in, bytes) #TODO reason codes
|
118
|
-
|
119
|
-
(0..bytes-1).map { |i| data_in.get_uint8(i) }
|
120
|
-
end
|
121
87
|
end
|
122
88
|
end
|
data/lib/pi_piper/i2c.rb
CHANGED
@@ -28,6 +28,7 @@ module PiPiper
|
|
28
28
|
|
29
29
|
def self.clock=(clock)
|
30
30
|
valid_clocks = Platform.driver.i2c_allowed_clocks
|
31
|
+
|
31
32
|
raise "Invalid clock rate. Valid clocks are 100 kHz, 399.3610 kHz, 1.666 MHz and 1.689 MHz" unless valid_clocks.include? clock
|
32
33
|
|
33
34
|
Platform.driver.i2c_set_clock clock
|
@@ -42,10 +43,6 @@ module PiPiper
|
|
42
43
|
Platform.driver.i2c_transfer_bytes data
|
43
44
|
end
|
44
45
|
|
45
|
-
def read(bytes)
|
46
|
-
Platform.driver.i2c_read_bytes(bytes)
|
47
|
-
end
|
48
|
-
|
49
46
|
end
|
50
47
|
|
51
48
|
end
|
Binary file
|
data/lib/pi_piper/pin.rb
CHANGED
@@ -1,112 +1,72 @@
|
|
1
|
-
require_relative 'pin_values'
|
2
|
-
|
3
1
|
module PiPiper
|
4
2
|
# Represents a GPIO pin on the Raspberry Pi
|
5
3
|
class Pin
|
6
|
-
|
4
|
+
GPIO_PUD_OFF = 0
|
5
|
+
GPIO_PUD_DOWN = 1
|
6
|
+
GPIO_PUD_UP = 2
|
7
7
|
|
8
|
-
attr_reader :pin, :last_value, :direction, :invert
|
8
|
+
attr_reader :pin, :last_value, :value, :direction, :invert
|
9
9
|
|
10
10
|
#Initializes a new GPIO pin.
|
11
11
|
#
|
12
12
|
# @param [Hash] options A hash of options
|
13
13
|
# @option options [Fixnum] :pin The pin number to initialize. Required.
|
14
|
-
#
|
15
|
-
# @option options [
|
16
|
-
# either :
|
17
|
-
#
|
18
|
-
# @option options [Boolean] :invert Indicates if the value read from the
|
19
|
-
# physical pin should be inverted. Defaults to false.
|
20
|
-
#
|
21
|
-
# @option options [Symbol] :trigger Indicates when the wait_for_change
|
22
|
-
# method will detect a change, either :rising, :falling, or :both edge
|
23
|
-
# triggers. Defaults to :both.
|
24
|
-
#
|
25
|
-
# @option options [Symbol] :pull Indicates if and how pull mode must be
|
26
|
-
# set when pin direction is set to :in. Either :up, :down or :offing.
|
27
|
-
# Defaults to :off.
|
28
|
-
#
|
14
|
+
# @option options [Symbol] :direction The direction of communication, either :in or :out. Defaults to :in.
|
15
|
+
# @option options [Boolean] :invert Indicates if the value read from the physical pin should be inverted. Defaults to false.
|
16
|
+
# @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.
|
17
|
+
# @option options [Symbol] :pull Indicates if and how pull mode must be set when pin direction is set to :in. Either :up, :down or :offing. Defaults to :off.
|
29
18
|
def initialize(options)
|
30
|
-
options = {
|
31
|
-
|
32
|
-
:trigger => :both,
|
33
|
-
:pull => :off}.merge(options)
|
34
|
-
|
35
|
-
@pin = options[:pin]
|
19
|
+
options = {:direction => :in, :invert => false, :trigger => :both, :pull => :off}.merge options
|
20
|
+
@pin = options[:pin]
|
36
21
|
@direction = options[:direction]
|
37
|
-
@invert
|
38
|
-
@trigger
|
39
|
-
@pull
|
40
|
-
@released = false
|
22
|
+
@invert = options[:invert]
|
23
|
+
@trigger = options[:trigger]
|
24
|
+
@pull = options[:pull]
|
41
25
|
|
42
|
-
raise "Invalid pull mode. Options are :up, :down or :float (default)" unless
|
43
|
-
|
44
|
-
raise "
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
raise "Invalid trigger. Options are :rising, :falling, or :both" unless
|
49
|
-
[:rising, :falling, :both].include? @trigger
|
26
|
+
raise "Invalid pull mode. Options are :up, :down or :float (default)" unless [:up, :down, :float, :off].include? @pull
|
27
|
+
raise "Unable to use pull-ups : pin direction must be ':in' for this" if @direction != :in && [:up, :down].include?(@pull)
|
28
|
+
raise "Invalid direction. Options are :in or :out" unless [:in, :out].include? @direction
|
29
|
+
raise "Invalid trigger. Options are :rising, :falling, or :both" unless [:rising, :falling, :both].include? @trigger
|
30
|
+
|
31
|
+
@direction == :out ? Platform.driver.pin_output(@pin) : Platform.driver.pin_input(@pin)
|
50
32
|
|
51
|
-
if @direction == :out
|
52
|
-
Platform.driver.pin_output(@pin)
|
53
|
-
else
|
54
|
-
Platform.driver.pin_input(@pin)
|
55
|
-
end
|
56
33
|
pull!(@pull)
|
57
34
|
|
58
35
|
read
|
59
36
|
end
|
60
|
-
|
61
|
-
# If the pin has been initialized for output this method will set the
|
62
|
-
# logic level high.
|
37
|
+
|
38
|
+
# If the pin has been initialized for output this method will set the logic level high.
|
63
39
|
def on
|
64
|
-
|
65
|
-
Platform.driver.pin_set(pin, GPIO_HIGH) if direction == :out
|
40
|
+
Platform.driver.pin_set(pin, 1) if direction == :out
|
66
41
|
end
|
67
|
-
|
42
|
+
|
68
43
|
# Tests if the logic level is high.
|
69
44
|
def on?
|
70
45
|
not off?
|
71
46
|
end
|
72
|
-
|
73
|
-
# If the pin has been initialized for output this method will set
|
74
|
-
# the logic level low.
|
47
|
+
|
48
|
+
# If the pin has been initialized for output this method will set the logic level low.
|
75
49
|
def off
|
76
|
-
|
77
|
-
Platform.driver.pin_set(pin, GPIO_LOW) if direction == :out
|
50
|
+
Platform.driver.pin_set(pin, 0) if direction == :out
|
78
51
|
end
|
79
|
-
|
52
|
+
|
80
53
|
# Tests if the logic level is low.
|
81
54
|
def off?
|
82
|
-
value ==
|
55
|
+
value == 0
|
83
56
|
end
|
84
57
|
|
85
|
-
|
86
|
-
@value ||= read
|
87
|
-
end
|
88
|
-
|
89
|
-
# If the pin has been initialized for output this method will either raise
|
90
|
-
# or lower the logic level depending on `new_value`.
|
58
|
+
# If the pin has been initialized for output this method will either raise or lower the logic level depending on `new_value`.
|
91
59
|
# @param [Object] new_value If false or 0 the pin will be set to off, otherwise on.
|
92
60
|
def update_value(new_value)
|
93
|
-
!new_value || new_value ==
|
61
|
+
!new_value || new_value == 0 ? off : on
|
94
62
|
end
|
95
|
-
alias_method :value=, :update_value
|
96
63
|
|
97
|
-
# When the pin has been initialized in input mode, internal resistors can
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
# is floating.
|
102
|
-
#
|
103
|
-
# For instance when nothing is plugged in, pulling the pin-up will make
|
104
|
-
# subsequent value readings to return 'on' (or high, or 1...).
|
105
|
-
# @param [Symbol] state Indicates if and how pull mode must be set when
|
106
|
-
# pin direction is set to :in. Either :up, :down or :offing. Defaults to :off.
|
64
|
+
# When the pin has been initialized in input mode, internal resistors can be pulled up or down (respectively with :up and :down).
|
65
|
+
# Pulling an input pin wil prevent noise from triggering it when the input is floating.
|
66
|
+
# For instance when nothing is plugged in, pulling the pin-up will make subsequent value readings to return 'on' (or high, or 1...).
|
67
|
+
# @param [Symbol] state Indicates if and how pull mode must be set when pin direction is set to :in. Either :up, :down or :offing. Defaults to :off.
|
107
68
|
def pull!(state)
|
108
|
-
return nil
|
109
|
-
fail PiPiper::PinError, "Pin #{@pin} already released" if released?
|
69
|
+
return nil unless @direction == :in
|
110
70
|
@pull = case state
|
111
71
|
when :up then GPIO_PUD_UP
|
112
72
|
when :down then GPIO_PUD_DOWN
|
@@ -119,8 +79,7 @@ module PiPiper
|
|
119
79
|
@pull
|
120
80
|
end
|
121
81
|
|
122
|
-
# If the pin direction is input, it will return the current state of
|
123
|
-
# pull-up/pull-down resistor, either :up, :down or :off.
|
82
|
+
# If the pin direction is input, it will return the current state of pull-up/pull-down resistor, either :up, :down or :off.
|
124
83
|
def pull?
|
125
84
|
case @pull
|
126
85
|
when GPIO_PUD_UP then :up
|
@@ -134,15 +93,14 @@ module PiPiper
|
|
134
93
|
last_value != value
|
135
94
|
end
|
136
95
|
|
137
|
-
#
|
138
|
-
# `:trigger` modifies what edge this method will release on.
|
96
|
+
# blocks until a logic level change occurs. The initializer option `:trigger` modifies what edge this method will release on.
|
139
97
|
def wait_for_change
|
140
98
|
fd = File.open(value_file, "r")
|
141
99
|
File.open(edge_file, "w") { |f| f.write("both") }
|
142
100
|
loop do
|
143
101
|
fd.read
|
144
102
|
IO.select(nil, nil, [fd], nil)
|
145
|
-
read
|
103
|
+
read
|
146
104
|
if changed?
|
147
105
|
next if @trigger == :rising and value == 0
|
148
106
|
next if @trigger == :falling and value == 1
|
@@ -151,29 +109,15 @@ module PiPiper
|
|
151
109
|
end
|
152
110
|
end
|
153
111
|
|
154
|
-
# Reads the current value from the pin. Without calling this method
|
155
|
-
#
|
156
|
-
|
157
|
-
# In short, you must call this method if you are curious about the
|
158
|
-
# current state of the pin.
|
159
|
-
def read
|
160
|
-
fail PiPiper::PinError, "Pin #{@pin} already released" if released?
|
112
|
+
# Reads the current value from the pin. Without calling this method first, `value`, `last_value` and `changed?` will not be updated.
|
113
|
+
# In short, you must call this method if you are curious about the current state of the pin.
|
114
|
+
def read
|
161
115
|
@last_value = @value
|
162
116
|
val = Platform.driver.pin_read(@pin)
|
163
117
|
@value = invert ? (val ^ 1) : val
|
164
118
|
end
|
165
|
-
|
166
|
-
def release
|
167
|
-
Platform.driver.release_pin(@pin)
|
168
|
-
@released = true
|
169
|
-
end
|
170
|
-
|
171
|
-
def released?
|
172
|
-
@released == true
|
173
|
-
end
|
174
|
-
|
119
|
+
|
175
120
|
private
|
176
|
-
|
177
121
|
def value_file
|
178
122
|
"/sys/class/gpio/gpio#{pin}/value"
|
179
123
|
end
|
@@ -185,5 +129,6 @@ module PiPiper
|
|
185
129
|
def direction_file
|
186
130
|
"/sys/class/gpio/gpio#{pin}/direction"
|
187
131
|
end
|
132
|
+
|
188
133
|
end
|
189
134
|
end
|