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
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'pi_piper'
|
2
|
-
include PiPiper
|
3
|
-
|
4
|
-
puts "Press the switch to get started"
|
5
|
-
|
6
|
-
watch :pin => 17, :invert => true do
|
7
|
-
puts "Pin changed from #{last_value} to #{value}"
|
8
|
-
end
|
9
|
-
|
10
|
-
after :pin => 17, :goes => :high do
|
11
|
-
puts "ouch!"
|
12
|
-
end
|
13
|
-
|
14
|
-
PiPiper.wait
|
15
|
-
|
Binary file
|
data/examples/mcp3008/mcp3008.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'pi_piper'
|
2
|
-
#port of the Adafruit MCP3008 interface code found @ http://learn.adafruit.com/send-raspberry-pi-data-to-cosm/python-script
|
3
|
-
|
4
|
-
def read_adc(adc_pin, clockpin, adc_in, adc_out, cspin)
|
5
|
-
cspin.on
|
6
|
-
clockpin.off
|
7
|
-
cspin.off
|
8
|
-
|
9
|
-
command_out = adc_pin
|
10
|
-
command_out |= 0x18
|
11
|
-
command_out <<= 3
|
12
|
-
|
13
|
-
(0..4).each do
|
14
|
-
adc_in.update_value((command_out & 0x80) > 0)
|
15
|
-
command_out <<= 1
|
16
|
-
clockpin.on
|
17
|
-
clockpin.off
|
18
|
-
end
|
19
|
-
result = 0
|
20
|
-
|
21
|
-
(0..11).each do
|
22
|
-
clockpin.on
|
23
|
-
clockpin.off
|
24
|
-
result <<= 1
|
25
|
-
adc_out.read
|
26
|
-
if adc_out.on?
|
27
|
-
result |= 0x1
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
cspin.on
|
32
|
-
|
33
|
-
result >> 1
|
34
|
-
end
|
35
|
-
|
36
|
-
clock = PiPiper::Pin.new :pin => 18, :direction => :out
|
37
|
-
adc_out = PiPiper::Pin.new :pin => 23
|
38
|
-
adc_in = PiPiper::Pin.new :pin => 24, :direction => :out
|
39
|
-
cs = PiPiper::Pin.new :pin => 25, :direction => :out
|
40
|
-
|
41
|
-
adc_pin = 0
|
42
|
-
|
43
|
-
loop do
|
44
|
-
value = read_adc(adc_pin, clock, adc_in, adc_out, cs)
|
45
|
-
invert = 1023 - value
|
46
|
-
mvolts = invert * (3300.0 / 1023.0)
|
47
|
-
if mvolts < 2700
|
48
|
-
temp = (mvolts - 380.0) / (2320.0 / 84.0)
|
49
|
-
else
|
50
|
-
temp = (mvolts - 2700.0) / (390.0 / 92.0) + 84.0
|
51
|
-
end
|
52
|
-
temp_f = (temp * 9.0 / 5.0) + 32
|
53
|
-
puts "Value = #{value}, invert = #{invert}, mvolts = #{mvolts}, temp = #{temp} C | #{temp_f} F"
|
54
|
-
sleep 1
|
55
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'pi_piper'
|
2
|
-
#special thanks to Jeremy Blythe, and his article @ http://jeremyblythe.blogspot.com/2012/09/raspberry-pi-hardware-spi-analog-inputs.html
|
3
|
-
#it greatly helped in getting the MCP3008 setup with SPI
|
4
|
-
|
5
|
-
adc_num = 0
|
6
|
-
|
7
|
-
loop do
|
8
|
-
value = 0
|
9
|
-
PiPiper::Spi.begin do |spi|
|
10
|
-
raw = spi.write [1, (8+adc_num)<<4, 0]
|
11
|
-
value = ((raw[1]&3) << 8) + raw[2]
|
12
|
-
end
|
13
|
-
|
14
|
-
invert = 1023 - value
|
15
|
-
mvolts = invert * (3300.0 / 1023.0)
|
16
|
-
if mvolts < 2700
|
17
|
-
temp = (mvolts - 380.0) / (2320.0 / 84.0)
|
18
|
-
else
|
19
|
-
temp = (mvolts - 2700.0) / (390.0 / 92.0) + 84.0
|
20
|
-
end
|
21
|
-
temp_f = (temp * 9.0 / 5.0) + 32
|
22
|
-
puts "Value = #{value}, invert = #{invert}, mvolts = #{mvolts}, temp = #{temp} C | #{temp_f} F"
|
23
|
-
sleep 1
|
24
|
-
end
|
Binary file
|
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'pi_piper'
|
2
|
-
|
3
|
-
unit = 0.1
|
4
|
-
dot = unit
|
5
|
-
dash = unit * 3
|
6
|
-
inter_element_gap = unit
|
7
|
-
short_gap = unit * 3
|
8
|
-
medium_gap = unit * 7
|
9
|
-
|
10
|
-
#http://en.wikipedia.org/wiki/Morse_code
|
11
|
-
character_timing = { "a" => [dot, dash], "b" => [dash, dot, dot, dot], "c" => [dash, dot, dash, dot],
|
12
|
-
"d" => [dash, dot, dot], "e" => [dot], "f" => [dot, dot, dash, dot],
|
13
|
-
"g" => [dash, dash, dot], "h" => [dot, dot, dot, dot], "i" => [dot, dot],
|
14
|
-
"j" => [dot, dash, dash, dash], "k" => [dash, dot, dash], "l" => [dot, dash, dot, dot],
|
15
|
-
"m" => [dash, dash], "n" => [dash, dot], "o" => [dash, dash, dash],
|
16
|
-
"p" => [dot, dash, dash, dot], "q" => [dash, dash, dot, dash], "r" => [dot, dash, dot],
|
17
|
-
"s" => [dot, dot, dot], "t" => [dash], "u" => [dot, dot, dash],
|
18
|
-
"v" => [dot, dot, dot, dash], "w" => [dot, dash, dash], "x" => [dash, dot, dot, dash],
|
19
|
-
"y" => [dash, dot, dash, dash], "z" => [dash, dash, dot, dot]}
|
20
|
-
|
21
|
-
pin = PiPiper::Pin.new(:pin => 17, :direction => :out)
|
22
|
-
pin.off
|
23
|
-
|
24
|
-
loop do
|
25
|
-
puts "Please type something"
|
26
|
-
something = gets.chomp.downcase
|
27
|
-
|
28
|
-
something.each_char do |letter|
|
29
|
-
if letter == " "
|
30
|
-
pin.off
|
31
|
-
sleep medium_gap
|
32
|
-
else
|
33
|
-
character_timing[letter].each do |timing|
|
34
|
-
pin.on
|
35
|
-
sleep timing
|
36
|
-
pin.off
|
37
|
-
sleep inter_element_gap
|
38
|
-
end
|
39
|
-
sleep short_gap - inter_element_gap
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
Binary file
|
data/lib/pi_piper/libbcm2835.so
DELETED
Binary file
|
data/lib/pi_piper/pin_error.rb
DELETED
data/lib/pi_piper/pin_values.rb
DELETED
data/lib/pi_piper/stub_driver.rb
DELETED
@@ -1,107 +0,0 @@
|
|
1
|
-
# @description driver that can be used either with tests or with rails or other frameworks for development
|
2
|
-
require_relative 'pin_values'
|
3
|
-
|
4
|
-
module PiPiper
|
5
|
-
|
6
|
-
class NullLogger
|
7
|
-
def debug(*) end
|
8
|
-
end
|
9
|
-
|
10
|
-
module StubDriver
|
11
|
-
include PiPiper::PinValues
|
12
|
-
extend self
|
13
|
-
|
14
|
-
def new(options = {})
|
15
|
-
opts = {
|
16
|
-
:logger => NullLogger.new
|
17
|
-
}.merge(options)
|
18
|
-
|
19
|
-
@logger = opts[:logger]
|
20
|
-
|
21
|
-
@pins = {}
|
22
|
-
@spi = {data:[], chip_select:0,}
|
23
|
-
|
24
|
-
self
|
25
|
-
end
|
26
|
-
alias_method :reset, :new
|
27
|
-
|
28
|
-
def pin_input(pin_number)
|
29
|
-
#@pins[pin_number] = { direction: :in }
|
30
|
-
pin(pin_number)[:direction] = :in
|
31
|
-
@logger.debug("Pin ##{pin_number} -> Input")
|
32
|
-
end
|
33
|
-
|
34
|
-
def pin_output(pin_number)
|
35
|
-
#@pins[pin_number] = { direction: :in }
|
36
|
-
pin(pin_number)[:direction] = :out
|
37
|
-
@logger.debug("Pin ##{pin_number} -> Output")
|
38
|
-
end
|
39
|
-
|
40
|
-
def pin_direction(pin_number)
|
41
|
-
pin(pin_number)[:direction] if @pins[pin_number]
|
42
|
-
end
|
43
|
-
|
44
|
-
def pin_set(pin_number, value)
|
45
|
-
pin(pin_number)[:value] = value
|
46
|
-
@logger.debug("Pin ##{pin_number} -> #{value}")
|
47
|
-
end
|
48
|
-
|
49
|
-
def pin_set_pud(pin_number, value)
|
50
|
-
pin(pin_number)[:pud] = value
|
51
|
-
@logger.debug("PinPUD ##{pin_number} -> #{value}")
|
52
|
-
end
|
53
|
-
|
54
|
-
def spidev_out(array)
|
55
|
-
@spi[:data] = array
|
56
|
-
@logger.debug("SPIDEV -> #{array.pack('C*')}")
|
57
|
-
end
|
58
|
-
|
59
|
-
def spi_begin
|
60
|
-
@logger.debug("SPI Begin")
|
61
|
-
@spi[:data] = []
|
62
|
-
end
|
63
|
-
|
64
|
-
def spi_transfer_bytes(data)
|
65
|
-
@logger.debug("SPI CS#{@spi[:chip_select]} <- #{data.to_s}")
|
66
|
-
@spi[:data] = Array(data)
|
67
|
-
end
|
68
|
-
|
69
|
-
def spi_chip_select(chip = nil)
|
70
|
-
chip = chip || @spi[:chip_select]
|
71
|
-
@logger.debug("SPI Chip Select = #{chip}")
|
72
|
-
@spi[:chip_select] = chip
|
73
|
-
end
|
74
|
-
|
75
|
-
def pin_read(pin_number)
|
76
|
-
val = pin(pin_number)[:value]
|
77
|
-
val ||= case pin(pin_number)[:pud]
|
78
|
-
when GPIO_PUD_UP then GPIO_HIGH
|
79
|
-
when GPIO_PUD_DOWN then GPIO_LOW
|
80
|
-
else nil
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def release_pins
|
85
|
-
@pins.keys.each { |pin_number| release_pin(pin_number) }
|
86
|
-
end
|
87
|
-
|
88
|
-
def release_pin(pin_number)
|
89
|
-
@pins.delete(pin_number)
|
90
|
-
end
|
91
|
-
|
92
|
-
def method_missing(meth, *args, &block)
|
93
|
-
puts "Needs Implementation: StubDriver##{meth}"
|
94
|
-
end
|
95
|
-
|
96
|
-
private
|
97
|
-
|
98
|
-
def pin(pin_number)
|
99
|
-
@pins[pin_number] ||= {}
|
100
|
-
end
|
101
|
-
|
102
|
-
## The following methods are only for testing and are not available on any platforms
|
103
|
-
def spi_data
|
104
|
-
@spi[:data]
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
data/spec/i2c_spec.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
require_relative 'spec_helper'
|
2
|
-
|
3
|
-
describe 'I2C' do
|
4
|
-
describe 'clock setting' do
|
5
|
-
it 'should check driver settings' do
|
6
|
-
Platform.driver = StubDriver.new.tap do |d|
|
7
|
-
expect(d).to receive(:i2c_allowed_clocks).and_return([100.kilohertz])
|
8
|
-
end
|
9
|
-
|
10
|
-
I2C.clock = 100.kilohertz
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'should accept 100 kHz' do
|
14
|
-
Platform.driver = StubDriver.new.tap do |d|
|
15
|
-
expect(d).to receive(:i2c_allowed_clocks).and_return([100.kilohertz])
|
16
|
-
expect(d).to receive(:i2c_set_clock).with(100.kilohertz)
|
17
|
-
end
|
18
|
-
|
19
|
-
I2C.clock = 100.kilohertz
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'should not accept 200 kHz' do
|
23
|
-
Platform.driver = StubDriver.new.tap do |d|
|
24
|
-
expect(d).to receive(:i2c_allowed_clocks).and_return([100.kilohertz])
|
25
|
-
end
|
26
|
-
|
27
|
-
expect { I2C.clock = 200.kilohertz }.to raise_error(RuntimeError)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe 'when in block' do
|
32
|
-
it 'should call i2c_begin' do
|
33
|
-
driver = StubDriver.new
|
34
|
-
expect(driver).to receive(:i2c_begin)
|
35
|
-
|
36
|
-
Platform.driver = driver
|
37
|
-
I2C.begin do
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'should call i2c_end' do
|
42
|
-
driver = StubDriver.new
|
43
|
-
expect(driver).to receive(:i2c_end)
|
44
|
-
|
45
|
-
Platform.driver = driver
|
46
|
-
I2C.begin do
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'should call i2c_end even after raise' do
|
51
|
-
driver = StubDriver.new
|
52
|
-
expect(driver).to receive(:i2c_end)
|
53
|
-
|
54
|
-
Platform.driver = driver
|
55
|
-
begin
|
56
|
-
I2C.begin { raise 'OMG' }
|
57
|
-
rescue
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
describe 'write operation' do
|
62
|
-
it 'should set address' do
|
63
|
-
Platform.driver = StubDriver.new.tap do |d|
|
64
|
-
expect(d).to receive(:i2c_set_address).with(4)
|
65
|
-
end
|
66
|
-
|
67
|
-
I2C.begin do
|
68
|
-
write to: 4, data: [1, 2, 3, 4]
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'should pass data to driver' do
|
73
|
-
Platform.driver = StubDriver.new.tap do |d|
|
74
|
-
expect(d).to receive(:i2c_transfer_bytes).with([1, 2, 3, 4])
|
75
|
-
end
|
76
|
-
|
77
|
-
I2C.begin do
|
78
|
-
write to: 4, data: [1, 2, 3, 4]
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
data/spec/pin_spec.rb
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
include PiPiper
|
3
|
-
|
4
|
-
describe 'Pin' do
|
5
|
-
it 'should export pin for input' do
|
6
|
-
Platform.driver = StubDriver.new.tap do |d|
|
7
|
-
expect(d).to receive(:pin_input).with(4)
|
8
|
-
end
|
9
|
-
Pin.new pin: 4, direction: :in
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'should export pin for output' do
|
13
|
-
Platform.driver = StubDriver.new.tap do |d|
|
14
|
-
expect(d).to receive(:pin_output).with(4)
|
15
|
-
end
|
16
|
-
|
17
|
-
Pin.new pin: 4, direction: :out
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'should read start value on construction' do
|
21
|
-
Platform.driver = StubDriver.new.tap do |d|
|
22
|
-
expect(d).to receive(:pin_read).with(4).and_return(0)
|
23
|
-
end
|
24
|
-
|
25
|
-
Pin.new pin: 4, direction: :in
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should detect on?' do
|
29
|
-
Platform.driver = StubDriver.new.tap do |d|
|
30
|
-
expect(d).to receive(:pin_read).with(4).and_return(1)
|
31
|
-
end
|
32
|
-
|
33
|
-
pin = Pin.new pin: 4, direction: :in
|
34
|
-
expect(pin.on?).to be(true)
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'should detect off?' do
|
38
|
-
Platform.driver = StubDriver.new.tap do |d|
|
39
|
-
expect(d).to receive(:pin_read).with(4).and_return(0)
|
40
|
-
end
|
41
|
-
|
42
|
-
pin = Pin.new pin: 4, direction: :in
|
43
|
-
expect(pin.off?).to be(true)
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'should invert true' do
|
47
|
-
Platform.driver = StubDriver.new.tap do |d|
|
48
|
-
expect(d).to receive(:pin_read).with(4).and_return(1)
|
49
|
-
end
|
50
|
-
|
51
|
-
pin = Pin.new pin: 4, direction: :in, invert: true
|
52
|
-
expect(pin.on?).to be(false)
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'should invert true' do
|
56
|
-
Platform.driver = StubDriver.new.tap do |d|
|
57
|
-
expect(d).to receive(:pin_read).with(4).and_return(0)
|
58
|
-
end
|
59
|
-
|
60
|
-
pin = Pin.new pin: 4, direction: :in, invert: true
|
61
|
-
expect(pin.off?).to be(false)
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'should write high' do
|
65
|
-
Platform.driver = StubDriver.new.tap do |d|
|
66
|
-
expect(d).to receive(:pin_set).with(4, 1)
|
67
|
-
end
|
68
|
-
|
69
|
-
pin = Pin.new pin: 4, direction: :out
|
70
|
-
pin.on
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'should write low' do
|
74
|
-
Platform.driver = StubDriver.new.tap do |d|
|
75
|
-
expect(d).to receive(:pin_set).with(4, 0)
|
76
|
-
end
|
77
|
-
|
78
|
-
pin = Pin.new pin: 4, direction: :out
|
79
|
-
pin.off
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'should not write high on direction in' do
|
83
|
-
Platform.driver = StubDriver.new.tap do |d|
|
84
|
-
expect(d).not_to receive(:pin_set)
|
85
|
-
end
|
86
|
-
|
87
|
-
pin = Pin.new pin: 4, direction: :in
|
88
|
-
pin.on
|
89
|
-
end
|
90
|
-
|
91
|
-
it 'should not write low on direction in' do
|
92
|
-
Platform.driver = StubDriver.new.tap do |d|
|
93
|
-
expect(d).not_to receive(:pin_set)
|
94
|
-
end
|
95
|
-
|
96
|
-
pin = Pin.new pin: 4, direction: :in
|
97
|
-
pin.off
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'should detect high to low change' do
|
101
|
-
Platform.driver = StubDriver.new.tap do |d|
|
102
|
-
value = 1
|
103
|
-
# begins low, then high, low, high, low...
|
104
|
-
allow(d).to receive(:pin_read) { value ^= 1 }
|
105
|
-
end
|
106
|
-
|
107
|
-
pin = Pin.new pin: 4, direction: :in
|
108
|
-
expect(pin.off?).to be(true)
|
109
|
-
pin.read
|
110
|
-
expect(pin.off?).to be(false)
|
111
|
-
expect(pin.changed?).to be(true)
|
112
|
-
end
|
113
|
-
|
114
|
-
xit 'should wait for change' do
|
115
|
-
pending
|
116
|
-
end
|
117
|
-
|
118
|
-
context 'given a pin is released' do
|
119
|
-
it 'should actually release it' do
|
120
|
-
Platform.driver = StubDriver.new.tap do |driver|
|
121
|
-
expect(driver).to receive(:release_pin).with(4)
|
122
|
-
end
|
123
|
-
|
124
|
-
pin = Pin.new(pin: 4, direction: :in)
|
125
|
-
pin.release
|
126
|
-
expect(pin.released?).to be(true)
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'should not mark unreleased pins as released' do
|
130
|
-
pin = Pin.new(pin: 4, direction: :in)
|
131
|
-
expect(pin.released?).to be(false)
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'should not continue to use the pin' do
|
135
|
-
Platform.driver = StubDriver.new.tap do |driver|
|
136
|
-
expect(driver).to receive(:release_pin).with(4)
|
137
|
-
end
|
138
|
-
|
139
|
-
pin = Pin.new(pin: 4, direction: :in)
|
140
|
-
pin.release
|
141
|
-
|
142
|
-
expect { pin.read }.to raise_error(PinError, 'Pin 4 already released')
|
143
|
-
expect { pin.on }.to raise_error(PinError, 'Pin 4 already released')
|
144
|
-
expect { pin.off }.to raise_error(PinError, 'Pin 4 already released')
|
145
|
-
expect { pin.pull!(:up) }.to(
|
146
|
-
raise_error(PinError, 'Pin 4 already released'))
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|