pi_piper 1.9.9 → 2.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|