minilab 2.0.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/.document +2 -0
  2. data/.gitignore +2 -0
  3. data/CHANGES +22 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +19 -0
  6. data/README.rdoc +101 -0
  7. data/Rakefile +25 -0
  8. data/doc/UniLib.chm +0 -0
  9. data/doc/minilab-1008.pdf +0 -0
  10. data/doc/minilab_systest_setup.txt +38 -0
  11. data/doc/port_mapping.txt +2 -0
  12. data/lib/minilab/analog_io.rb +25 -0
  13. data/lib/minilab/connection_state.rb +15 -0
  14. data/lib/minilab/digital_auxport_io.rb +36 -0
  15. data/lib/minilab/digital_configuration.rb +55 -0
  16. data/lib/minilab/digital_port_io.rb +41 -0
  17. data/lib/minilab/library_translator.rb +48 -0
  18. data/lib/minilab/minilab.rb +130 -0
  19. data/lib/minilab/minilab_constants.rb +22 -0
  20. data/lib/minilab/minilab_context.rb +18 -0
  21. data/lib/minilab/minilab_hardware.rb +118 -0
  22. data/lib/minilab/minilab_wrapper.rb +14 -0
  23. data/lib/minilab/objects.yml +24 -0
  24. data/lib/minilab/version.rb +3 -0
  25. data/lib/minilab.rb +14 -0
  26. data/minilab.gemspec +32 -0
  27. data/spec/acceptance/analog_spec.rb +35 -0
  28. data/spec/acceptance/digital_port_spec.rb +81 -0
  29. data/spec/acceptance/digital_screw_terminal_spec.rb +22 -0
  30. data/spec/spec_helper.rb +102 -0
  31. data/spec/unit/analog_io_spec.rb +55 -0
  32. data/spec/unit/connection_state_spec.rb +14 -0
  33. data/spec/unit/digital_auxport_io_spec.rb +98 -0
  34. data/spec/unit/digital_configuration_spec.rb +96 -0
  35. data/spec/unit/digital_port_io_spec.rb +65 -0
  36. data/spec/unit/library_translator_spec.rb +86 -0
  37. data/spec/unit/minilab_context_spec.rb +17 -0
  38. data/spec/unit/minilab_hardware_spec.rb +17 -0
  39. data/spec/unit/minilab_spec.rb +104 -0
  40. data/spec/unit/minilab_wrapper_spec.rb +20 -0
  41. data/vendor/mcc/cbw32.dll +0 -0
  42. metadata +192 -0
@@ -0,0 +1,118 @@
1
+ require "ffi"
2
+ require "pathname"
3
+
4
+ module Minilab
5
+ class MinilabHardware
6
+ include MinilabConstants
7
+
8
+ def setup_error_handling(reporting, handling)
9
+ create_error_hash cbErrHandling(reporting, handling)
10
+ end
11
+
12
+ def declare_revision(revision)
13
+ memory = FFI::MemoryPointer.new :float
14
+ memory.write_float(revision)
15
+ create_error_hash cbDeclareRevision(memory)
16
+ end
17
+
18
+ def get_revision
19
+ dll_revision_number = FFI::MemoryPointer.new :float
20
+ vxd_revision_number = FFI::MemoryPointer.new :float
21
+ error = cbGetRevision(dll_revision_number, vxd_revision_number)
22
+ create_error_or_value_hash(error, dll_revision_number.read_float)
23
+ end
24
+
25
+ def get_error_string(error)
26
+ message = FFI::MemoryPointer.new :char, ERRSTRLEN
27
+ new_error = cbGetErrMsg(error, message)
28
+ if new_error != 0
29
+ create_error_hash(new_error)
30
+ else
31
+ message.read_string
32
+ end
33
+ end
34
+
35
+ def configure_auxport(optz)
36
+ raise ":pin is a required parameter" if optz[:pin].nil?
37
+ raise ":direction is a required parameter" if optz[:direction].nil?
38
+ create_error_hash cbDConfigBit(BOARDNUM, AUXPORT, optz[:pin], optz[:direction])
39
+ end
40
+
41
+ def configure_port(optz)
42
+ raise ":port is a required parameter" if optz[:port].nil?
43
+ raise ":direction is a required parameter" if optz[:direction].nil?
44
+ create_error_hash cbDConfigPort(BOARDNUM, optz[:port], optz[:direction])
45
+ end
46
+
47
+ def read_analog(channel)
48
+ raw_data = FFI::MemoryPointer.new :ushort
49
+ error = cbAIn(BOARDNUM, channel, BIP10VOLTS, raw_data)
50
+ return create_error_hash(error) if error != 0
51
+
52
+ voltage = FFI::MemoryPointer.new :float
53
+ error = cbToEngUnits(BOARDNUM, BIP10VOLTS, raw_data.get_ushort(0), voltage)
54
+ create_error_or_value_hash(error, voltage.read_float)
55
+ end
56
+
57
+ def read_digital_pin(pin)
58
+ data = FFI::MemoryPointer.new :ushort
59
+ error = cbDBitIn(BOARDNUM, FIRSTPORTA, pin, data)
60
+ create_error_or_value_hash(error, data.get_ushort(0))
61
+ end
62
+
63
+ def read_auxport(pin)
64
+ data = FFI::MemoryPointer.new :ushort
65
+ error = cbDBitIn(BOARDNUM, AUXPORT, pin, data)
66
+ create_error_or_value_hash(error, data.get_ushort(0))
67
+ end
68
+
69
+ def read_port(port)
70
+ data = FFI::MemoryPointer.new :ushort
71
+ error = cbDIn(BOARDNUM, port, data)
72
+ create_error_or_value_hash(error, data.get_ushort(0))
73
+ end
74
+
75
+ def write_analog(channel, volts)
76
+ raw_data = FFI::MemoryPointer.new :ushort
77
+ error = cbFromEngUnits(BOARDNUM, UNI5VOLTS, volts, raw_data)
78
+ return create_error_hash(error) if error != 0
79
+ error = cbAOut(BOARDNUM, channel, UNI5VOLTS, raw_data.get_ushort(0))
80
+ create_error_hash(error)
81
+ end
82
+
83
+ def write_digital_pin(pin, data)
84
+ create_error_hash cbDBitOut(BOARDNUM, FIRSTPORTA, pin, data)
85
+ end
86
+
87
+ def write_auxport(pin, data)
88
+ create_error_hash cbDBitOut(BOARDNUM, AUXPORT, pin, data)
89
+ end
90
+
91
+ private
92
+ def create_error_or_value_hash(error, value)
93
+ error != 0 ? { :error => error } : { :value => value }
94
+ end
95
+
96
+ def create_error_hash(error)
97
+ create_error_or_value_hash(error, true)
98
+ end
99
+
100
+ MCC_LIBRARY = Pathname.new(__FILE__).dirname.join("..", "..", "vendor", "mcc", "cbw32.dll")
101
+ extend FFI::Library
102
+ ffi_lib MCC_LIBRARY
103
+
104
+ attach_function "cbErrHandling", [:int, :int], :int
105
+ attach_function "cbDeclareRevision", [:pointer], :int
106
+ attach_function "cbGetRevision", [:pointer, :pointer], :int
107
+ attach_function "cbGetErrMsg", [:int, :pointer], :int
108
+ attach_function "cbDConfigBit", [:int, :int, :int, :int], :int
109
+ attach_function "cbDConfigPort", [:int, :int, :int], :int
110
+ attach_function "cbAIn", [:int, :int, :int, :pointer], :int
111
+ attach_function "cbToEngUnits", [:int, :int, :ushort, :pointer], :int
112
+ attach_function "cbFromEngUnits", [:int, :int, :float, :pointer], :int
113
+ attach_function "cbDBitIn", [:int, :int, :int, :pointer], :int
114
+ attach_function "cbDIn", [:int, :int, :pointer], :int
115
+ attach_function "cbAOut", [:int, :int, :int, :ushort], :int
116
+ attach_function "cbDBitOut", [:int, :int, :int, :ushort], :int
117
+ end
118
+ end
@@ -0,0 +1,14 @@
1
+ module Minilab
2
+ class MinilabWrapper #:nodoc:
3
+ constructor :minilab_hardware
4
+
5
+ def method_missing(method, *argz)
6
+ result = @minilab_hardware.send(method, *argz)
7
+ if result[:error]
8
+ message = @minilab_hardware.get_error_string(result[:error])
9
+ raise "Command [#{method}(#{argz.inspect})] caused a hardware error: #{message}"
10
+ end
11
+ result[:value]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ using_namespace Minilab:
2
+ minilab:
3
+ compose: minilab_wrapper, analog_io, digital_auxport_io, digital_port_io, connection_state
4
+
5
+ connection_state:
6
+
7
+ minilab_wrapper:
8
+ compose: minilab_hardware
9
+
10
+ minilab_hardware:
11
+
12
+ analog_io:
13
+ compose: minilab_wrapper
14
+
15
+ digital_auxport_io:
16
+ compose: minilab_wrapper
17
+
18
+ digital_port_io:
19
+ compose: minilab_wrapper, digital_configuration, library_translator
20
+
21
+ library_translator:
22
+
23
+ digital_configuration:
24
+ compose: minilab_wrapper
@@ -0,0 +1,3 @@
1
+ module Minilab
2
+ VERSION = "2.0.0"
3
+ end
data/lib/minilab.rb ADDED
@@ -0,0 +1,14 @@
1
+ require "constructor"
2
+
3
+ require_relative "minilab/minilab_constants"
4
+ require_relative "minilab/minilab_context"
5
+
6
+ require_relative "minilab/analog_io"
7
+ require_relative "minilab/connection_state"
8
+ require_relative "minilab/digital_auxport_io"
9
+ require_relative "minilab/digital_configuration"
10
+ require_relative "minilab/digital_port_io"
11
+ require_relative "minilab/library_translator"
12
+ require_relative "minilab/minilab"
13
+ require_relative "minilab/minilab_hardware"
14
+ require_relative "minilab/minilab_wrapper"
data/minilab.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "minilab/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "minilab"
7
+ s.version = Minilab::VERSION
8
+ s.platform = Gem::Platform::CURRENT
9
+ s.authors = ["Matt Fletcher"]
10
+ s.email = ["fletcher@atomicobject.com"]
11
+ s.homepage = "http://atomicobject.github.com/minilab"
12
+ s.summary = %q{Ruby interface to Measurement Computing's miniLAB 1008}
13
+ s.description = "#{s.summary} "
14
+
15
+ s.add_dependency "constructor", "~>2.0"
16
+ s.add_dependency "diy", "~>1.1"
17
+ s.add_dependency "ffi", "~>1.0"
18
+
19
+ s.add_development_dependency "steak", "~>1.0"
20
+ s.add_development_dependency "rr", "~>1.0"
21
+
22
+ s.rubyforge_project = "minilab"
23
+
24
+ s.has_rdoc = true
25
+ s.extra_rdoc_files = %w[ README.rdoc CHANGES LICENSE ]
26
+ s.rdoc_options = %w[ --main README.rdoc --title minilab ]
27
+
28
+ s.files = `git ls-files`.split("\n")
29
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
30
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
31
+ s.require_paths = ["lib"]
32
+ end
@@ -0,0 +1,35 @@
1
+ require_relative "../spec_helper"
2
+
3
+ feature "Analog" do
4
+ scenario "inputs" do
5
+ analog_input_4_should_be_about 5.0
6
+
7
+ analog_input_1_should_be_about 0.0
8
+ end
9
+
10
+ scenario "outputs" do
11
+ write_analog_1 5.0
12
+ analog_input_0_should_be_about 5.0
13
+
14
+ write_analog_1 0.0
15
+ analog_input_0_should_be_about 0.0
16
+
17
+ write_analog_1 2.77
18
+ analog_input_0_should_be_about 2.77
19
+
20
+ write_analog_1 3.19
21
+ analog_input_0_should_be_about 3.19
22
+
23
+ write_analog_0 5.0
24
+ analog_input_6_should_be_about 5.0
25
+
26
+ write_analog_0 0.0
27
+ analog_input_6_should_be_about 0.0
28
+
29
+ write_analog_0 3.75
30
+ analog_input_6_should_be_about 3.75
31
+
32
+ write_analog_0 1.88
33
+ analog_input_6_should_be_about 1.88
34
+ end
35
+ end
@@ -0,0 +1,81 @@
1
+ require_relative "../spec_helper"
2
+
3
+ feature "Digital ports" do
4
+ scenario "reading bits" do
5
+ configure_portb_for_input
6
+ digital_pin_10_should_be 1
7
+
8
+ configure_porta_for_input
9
+ digital_pin_30_should_be 0
10
+ end
11
+
12
+ scenario "writing bits" do
13
+ # Port A --> Port B
14
+ configure_porta_for_output
15
+ configure_portb_for_input
16
+
17
+ write_digital_pin_36 1
18
+ digital_pin_7_should_be 1
19
+
20
+ write_digital_pin_36 0
21
+ digital_pin_7_should_be 0
22
+
23
+ # Port B --> Port CL
24
+ configure_portb_for_output
25
+ configure_portcl_for_input
26
+
27
+ write_digital_pin_5 0
28
+ digital_pin_28_should_be 0
29
+
30
+ write_digital_pin_5 1
31
+ digital_pin_28_should_be 1
32
+
33
+ # Port CL -> Port CH
34
+ configure_portcl_for_output
35
+ configure_portch_for_input
36
+
37
+ write_digital_pin_27 1
38
+ digital_pin_22_should_be 1
39
+
40
+ write_digital_pin_27 0
41
+ digital_pin_22_should_be 0
42
+
43
+ # Port CH -> Port A
44
+ configure_portch_for_output
45
+ configure_porta_for_input
46
+
47
+ write_digital_pin_24 0
48
+ digital_pin_34_should_be 0
49
+
50
+ write_digital_pin_24 1
51
+ digital_pin_34_should_be 1
52
+ end
53
+
54
+ scenario "reading bytes" do
55
+ configure_porta_for_output
56
+ configure_portcl_for_output
57
+ configure_portb_for_input
58
+
59
+ # GND to pin 3 (portb bit 7)
60
+ # GND to pin 4 (portb bit 6)
61
+ write_digital_pin_28 1 # map to pin 5 (portb bit 5)
62
+ # GND to pin 6 (portb bit 4)
63
+ write_digital_pin_36 1 # map to pin 7 (portb bit 3)
64
+ # GND to pin 8 (portb bit 2)
65
+ # GND to pin 9 (portb bit 1)
66
+ # +5v to pin 10 (portb bit 0)
67
+ digital_portb_should_be 0x29
68
+
69
+
70
+
71
+ configure_porta_for_output
72
+ configure_portcl_for_output
73
+ configure_portch_for_input
74
+
75
+ write_digital_pin_27 1 # map to pin 22 (portch bit 3)
76
+ # GND to pin 23 (portch bit 2)
77
+ write_digital_pin_32 1 # map to pin 24 (portch bit 1)
78
+ # GND to pin 22 (portch bit 0)
79
+ digital_portch_should_be 0x0A
80
+ end
81
+ end
@@ -0,0 +1,22 @@
1
+ require_relative "../spec_helper"
2
+
3
+ feature "Digital screw terminals" do
4
+ scenario "input" do
5
+ dio1_should_be 1
6
+ dio2_should_be 0
7
+ end
8
+
9
+ scenario "output" do
10
+ write_dio0 1
11
+ dio3_should_be 1
12
+
13
+ write_dio0 0
14
+ dio3_should_be 0
15
+
16
+ write_dio0 0
17
+ analog_input_2_should_be_about 0.0
18
+
19
+ write_dio0 1
20
+ analog_input_2_should_be_greater_than 0.0
21
+ end
22
+ end
@@ -0,0 +1,102 @@
1
+ require_relative "../lib/minilab"
2
+ require "steak"
3
+
4
+ module MinilabUnitSpecHelpers
5
+ def create_mocks(*mox)
6
+ mox.inject({}) do |bag, name|
7
+ the_mock = Object.new
8
+ self.instance_variable_set("@#{name}", mock(the_mock))
9
+ bag[name] = the_mock
10
+ bag
11
+ end
12
+ end
13
+ end
14
+
15
+ module MinilabAcceptanceSpecHelpers
16
+ GOOD_DELTA = 0.12
17
+ VALID_PORTS = [:porta, :portb, :portcl, :portch]
18
+ VALID_PINS = (30..37).to_a + (3..10).to_a + (26..29).to_a + (22..25).to_a
19
+
20
+ # Analog input methods
21
+ 0.upto(7) do |channel|
22
+ define_method("analog_input_#{channel}_should_be_about") do |value|
23
+ input = @minilab.read_analog(channel)
24
+ assert_in_delta(value, input, GOOD_DELTA, "Input voltage was not ~#{value} volts")
25
+ end
26
+
27
+ define_method("analog_input_#{channel}_should_be_greater_than") do |value|
28
+ volts = @minilab.read_analog(channel)
29
+ assert volts > (value + GOOD_DELTA)
30
+ end
31
+ end
32
+
33
+ # Analog output methods
34
+ [0, 1].each do |channel|
35
+ define_method("write_analog_#{channel}") do |value|
36
+ @minilab.write_analog(channel, value)
37
+ sleep 0.1
38
+ end
39
+ end
40
+
41
+ # Digital pin input and output methods
42
+ VALID_PINS.each do |pin|
43
+ define_method("digital_pin_#{pin}_should_be") do |value|
44
+ assert_equal value, @minilab.read_digital(pin)
45
+ end
46
+
47
+ define_method("write_digital_pin_#{pin}") do |value|
48
+ @minilab.write_digital(pin, value)
49
+ end
50
+ end
51
+
52
+ # Digital port read (entire bytes) methods
53
+ VALID_PORTS.each do |port|
54
+ define_method("digital_#{port}_should_be") do |value|
55
+ assert_equal value, @minilab.read_digital_byte(port)
56
+ end
57
+ end
58
+
59
+ # DIOx input and output methods
60
+ 0.upto(3) do |pin|
61
+ define_method("dio#{pin}_should_be") do |value|
62
+ assert_equal value, @minilab.read_digital("dio#{pin}")
63
+ end
64
+
65
+ define_method("write_dio#{pin}") do |value|
66
+ @minilab.write_digital("dio#{pin}", value)
67
+ end
68
+ end
69
+
70
+ # Configuration methods
71
+ VALID_PORTS.each do |port|
72
+ define_method("configure_#{port}_for_input") do
73
+ @minilab.configure_input_port(port)
74
+ end
75
+
76
+ define_method("configure_#{port}_for_output") do
77
+ @minilab.configure_output_port(port)
78
+ end
79
+ end
80
+
81
+ # Other
82
+ def minilab_revision_should_be(revision)
83
+ assert_equal revision, @minilab.get_revision
84
+ end
85
+ end
86
+
87
+ RSpec.configure do |config|
88
+ # Using both to minimize the amount of porting work.
89
+ # most assertions are still test:unit based, but some
90
+ # (like exceptions) us rspec
91
+ config.expect_with :stdlib, :rspec
92
+ config.mock_framework = :rr
93
+
94
+ config.include Minilab::MinilabConstants
95
+
96
+ config.include MinilabUnitSpecHelpers
97
+ config.include MinilabAcceptanceSpecHelpers, :type => :acceptance
98
+ config.before(:all, :type => :acceptance) do
99
+ @minilab = Minilab.build
100
+ @minilab.connect
101
+ end
102
+ end
@@ -0,0 +1,55 @@
1
+ require_relative "../spec_helper"
2
+
3
+ describe Minilab::AnalogIo do
4
+ before { @mox = create_mocks(:minilab_wrapper) }
5
+ subject { described_class.new(@mox) }
6
+
7
+ it "read analog data" do
8
+ @minilab_wrapper.read_analog(2).returns 5.7
9
+ assert_equal 5.7, subject.read_analog(2)
10
+ end
11
+
12
+ it "raise an exception when analog input channel is out of range" do
13
+ # The minilab device has 8 analog inputs (when used in straight
14
+ # input mode, not differential). We expect that exceptions
15
+ # it be thrown for channels that are out of bounds.
16
+ -> { subject.read_analog(-1) }.should raise_error
17
+ 0.upto(7) do |channel|
18
+ @minilab_wrapper.read_analog(channel).returns(1.0)
19
+ -> { subject.read_analog(channel) }.should_not raise_error
20
+ end
21
+ -> { subject.read_analog(8) }.should raise_error
22
+ end
23
+
24
+ it "write analog data" do
25
+ @minilab_wrapper.write_analog(1, 4.5)
26
+ subject.write_analog(1, 4.5)
27
+ end
28
+
29
+ it "raise an error when analog output voltage is out of range" do
30
+ -> { subject.write_analog(0, -0.1) }.should raise_error
31
+
32
+ @minilab_wrapper.write_analog(0, 0.0)
33
+ -> { subject.write_analog(0, 0.0) }.should_not raise_error
34
+
35
+ @minilab_wrapper.write_analog(0, 2.1)
36
+ -> { subject.write_analog(0, 2.1) }.should_not raise_error
37
+
38
+ @minilab_wrapper.write_analog(0, 5.0)
39
+ -> { subject.write_analog(0, 5.0) }.should_not raise_error
40
+
41
+ -> { subject.write_analog(0, 5.1) }.should raise_error
42
+ end
43
+
44
+ it "raise an error when analog output channel is out of range" do
45
+ -> { subject.write_analog(-1, 0.0) }.should raise_error
46
+
47
+ @minilab_wrapper.write_analog(0, 0.0)
48
+ -> { subject.write_analog(0, 0.0) }.should_not raise_error
49
+
50
+ @minilab_wrapper.write_analog(1, 0.0)
51
+ -> { subject.write_analog(1, 0.0) }.should_not raise_error
52
+
53
+ -> { subject.write_analog(2, 0.0) }.should raise_error
54
+ end
55
+ end
@@ -0,0 +1,14 @@
1
+ require_relative "../spec_helper.rb"
2
+
3
+ describe Minilab::ConnectionState do
4
+ it "default to an unconnected state" do
5
+ assert_equal false, subject.connected?
6
+ end
7
+
8
+ it "allow the connection state to be changed" do
9
+ subject.connected = true
10
+ assert_equal true, subject.connected?
11
+ subject.connected = false
12
+ assert_equal false, subject.connected?
13
+ end
14
+ end
@@ -0,0 +1,98 @@
1
+ require_relative "../spec_helper"
2
+
3
+ describe Minilab::DigitalAuxportIo do
4
+ before { @mox = create_mocks(:minilab_wrapper) }
5
+ subject { described_class.new(@mox) }
6
+
7
+ it "read digital data from the screw terminals" do
8
+ expected_configuration = { :direction => DIGITALIN, :pin => get_pin_number("DIO1") }
9
+ @minilab_wrapper.configure_auxport(expected_configuration)
10
+ @minilab_wrapper.read_auxport(get_pin_number("DIO1")).returns 1
11
+
12
+ assert_equal 1, subject.read_digital('DIO1')
13
+ end
14
+
15
+ it "raise an error when digital input pin is not valid" do
16
+ make_sure_bad_pins_blow_up
17
+
18
+ good_pins.each do |pin|
19
+ expected_configuration = { :direction => DIGITALIN, :pin => get_pin_number(pin) }
20
+ @minilab_wrapper.configure_auxport(expected_configuration)
21
+ @minilab_wrapper.read_auxport(get_pin_number(pin)).returns 0
22
+ -> { subject.read_digital(pin) }.should_not raise_error
23
+ end
24
+ end
25
+
26
+ # Output tests
27
+ it "write digital data to the screw terminals" do
28
+ expected_configuration = { :direction => DIGITALOUT, :pin => get_pin_number("DIO1") }
29
+ @minilab_wrapper.configure_auxport(expected_configuration)
30
+ @minilab_wrapper.write_auxport(get_pin_number("DIO1"), 1)
31
+
32
+ subject.write_digital("DIO1", 1)
33
+ end
34
+
35
+ it "write 1 to a digital output when the commanded value is anything not 0" do
36
+ expected_configuration = { :direction => DIGITALOUT, :pin => get_pin_number("DIO1") }
37
+ @minilab_wrapper.configure_auxport(expected_configuration)
38
+ @minilab_wrapper.write_auxport(get_pin_number("DIO1"), 1)
39
+ subject.write_digital("DIO1", 173)
40
+
41
+ @minilab_wrapper.configure_auxport(expected_configuration)
42
+ @minilab_wrapper.write_auxport(get_pin_number("DIO1"), 1)
43
+ subject.write_digital("DIO1", 872)
44
+ end
45
+
46
+ it "raise an exception if someone tries to command a negative value" do
47
+ -> { subject.write_digital("DIO2", -1) }.should raise_error
48
+ -> { subject.write_digital("DIO2", -80) }.should raise_error
49
+ end
50
+
51
+ it "raise an exception when digital output pin is out of range" do
52
+ make_sure_bad_pins_blow_up
53
+
54
+ good_pins.each do |pin|
55
+ expected_configuration = { :direction => DIGITALOUT, :pin => get_pin_number(pin) }
56
+ @minilab_wrapper.configure_auxport(expected_configuration)
57
+ @minilab_wrapper.write_auxport(get_pin_number(pin), 1)
58
+ -> { subject.write_digital(pin, 1) }.should_not raise_error
59
+ end
60
+ end
61
+
62
+ it "accept case-insensitive DIO strings as pins" do
63
+ expected_configuration = { :direction => DIGITALOUT, :pin => get_pin_number("DIO1") }
64
+ @minilab_wrapper.configure_auxport(expected_configuration)
65
+ @minilab_wrapper.write_auxport(get_pin_number("DIO1"), 1)
66
+ subject.write_digital('dio1', 1)
67
+
68
+ expected_configuration = { :direction => DIGITALOUT, :pin => get_pin_number("DIO2") }
69
+ @minilab_wrapper.configure_auxport(expected_configuration)
70
+ @minilab_wrapper.write_auxport(get_pin_number("DIO2"), 1)
71
+ subject.write_digital('dIo2', 1)
72
+
73
+ expected_configuration = { :direction => DIGITALIN, :pin => get_pin_number("DIO0") }
74
+ @minilab_wrapper.configure_auxport(expected_configuration)
75
+ @minilab_wrapper.read_auxport(get_pin_number("DIO0")).returns 1
76
+ subject.read_digital('DiO0')
77
+
78
+ expected_configuration = { :direction => DIGITALIN, :pin => get_pin_number("DIO3") }
79
+ @minilab_wrapper.configure_auxport(expected_configuration)
80
+ @minilab_wrapper.read_auxport(get_pin_number("DIO3")).returns 1
81
+ subject.read_digital('diO3')
82
+ end
83
+
84
+ private
85
+ def get_pin_number(pin)
86
+ pin.match(/(\d)$/)[0].to_i
87
+ end
88
+
89
+ def good_pins
90
+ %w[ DIO0 DIO1 DIO2 DIO3 ]
91
+ end
92
+
93
+ def make_sure_bad_pins_blow_up
94
+ [ 'yourmom', 'bill', nil, false, 55, 'DIO4', -1, 38 ].each do |pin|
95
+ -> { subject.read_digital(pin) }.should raise_error
96
+ end
97
+ end
98
+ end