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
data/.document ADDED
@@ -0,0 +1,2 @@
1
+ README.rdoc
2
+ lib/minilab.rb
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ Gemfile.lock
2
+ minilab*.gem
data/CHANGES ADDED
@@ -0,0 +1,22 @@
1
+ == 2.0.0
2
+ * minilab now requires Ruby 1.9 to run and is built for the RubyInstaller package.
3
+ minilab's public interface has not changed.
4
+ * Now using the latest and greatest bundler techniques for gem development.
5
+ * Two libraries minilab used for testing (hardmock and systir) do not run on Ruby 1.9. Therefore, minilab now uses:
6
+ ** RSpec as a test harness
7
+ ** steak as an acceptance test harness
8
+ ** rr for mocking in unit tests
9
+
10
+ == 1.1.1
11
+ * Lots of little things changed as part of the Rubyforge -> Gemcutter/GitHub/rdoc.info migration
12
+ minilab's public interface has not changed.
13
+ * Using bundler to package what gems.
14
+
15
+ == 1.1.0
16
+ * Conversion from native extension to FFI
17
+ * Upgraded diy, constructor, and hardmock to their latest versions
18
+ * Internal implementation changes. minilab's public interface is unchanged
19
+ * Integration tests removed, as the value they provide did not outweigh the maintenance burden
20
+
21
+ == 1.0.0
22
+ First release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2007-2011 Atomic Object LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,101 @@
1
+ == About
2
+
3
+ minilab is a Ruby library for Measurement Computing's miniLAB 1008 device. The minilab library provides a simple interface to several of the miniLAB 1008's analog and digital IO functions. I've used the miniLAB to control the input and examine the output from our embedded devices; the minilab library allowed us to use automated system testing tools for Ruby.
4
+
5
+ minilab does not work with other Measurement Computing devices, but could be extended to do so.
6
+
7
+ === Ruby 1.9
8
+ The minilab gem now requires Ruby 1.9 to run. The gem is built to run on the RubyInstaller package. minilab's public interface has not changed as part of the Ruby 1.9 migration.
9
+
10
+ If you're looking for Ruby 1.8 support, try using the 1.1.0 version of the gem. The code is available in the git repository via the v1.1.0 tag.
11
+
12
+ == Installation
13
+
14
+ 1. Install the minilab gem onto your system or unpack it into a local directory in your project. Install Measurement Computing's Universal Library and InstaCal software; both come on CDs with the device.
15
+
16
+ 1. Plug in the device and then fire up the InstaCal software. Go to Install -> Configure in the menus and the Custom Serial Number to 253, No. of Channels to 8 Single Ended, and Trigger Source to DIO0. Use the Flash LED button to ensure that InstaCal can communicate with the device (I've never had a problem with this). Although I don't think the Custom Serial Number and Trigger Source make much difference to my library, the No. of Channels is important (see Known limitations below).
17
+
18
+ 1. That should be it---you should now be able to require 'minilab', create a minilab object, and connect to it. If you can't, please contact me! I've only installed this on a limited number of computers, so I'd like to hear about problems with the library installation, gem installation, LOAD_PATH, etc.
19
+
20
+ == Usage
21
+ === Build and connect
22
+
23
+ First you'll need to build the Minilab object; use the +Minilab.build+ method to do this. The method is important to use instead of +new+, since it takes care of a lot of behind-the-scenes object construction for you.
24
+
25
+ After building the object, use the +connect+ method. This will establish the connection to the library. None of the other methods will work until you connect.
26
+
27
+ Example:
28
+
29
+ minilab = Minilab.build
30
+ minilab.connect
31
+
32
+ === Reading and writing data
33
+
34
+ I've created methods for reading and writing both digital and analog data from the device. Analog data goes through the read and write pins on the top of the device; no configuration is needed for the analog methods.
35
+
36
+ Digital data goes through either the DIO pins on the top of the device or the digital ports on the DB37 port. If you're using the DIO pins, then you don't need to do any configuration. If you're using the DB37 pins, then you'll need to configure the appropriate port for input and output. You can find a mapping of DB37 pin numbers to ports either in Measurement Computing's miniLAB 1008 data sheet or at the end of this README.
37
+
38
+ Check out the read and write analog and read, write, and configure digital methods in the Minilab document for more information.
39
+
40
+ Example:
41
+
42
+ minilab.configure_input_port(:portb)
43
+ value = minilab.read_digital_byte(:portb)
44
+ assert_equal 12, value, "wrong value read for system time"
45
+
46
+ The adventurous may also want to look at the included acceptance tests for the device, since they are examples of how to use the device and are not contrived.
47
+
48
+ == Tests
49
+
50
+ The minilab library comes with unit and acceptance tests. The unit tests stress individual units and can run without any hardware plugged in. The acceptance tests represent real use cases for the software when plugged into hardware.
51
+
52
+ See the end of this document for an outline of how a miniLAB and DB37 connector should be set up in order to run the system tests.
53
+
54
+ == Known limitations
55
+
56
+ * Ruby 1.8 is no longer supported.
57
+
58
+ * The minilab library only supports one device plugged in at a time. I could add support for multiple devices, but since I only have one, I haven't bothered adding support for more than one.
59
+
60
+ * I never got around to writing out an entire digital byte because I never needed it.
61
+
62
+ * Reading analog values only supports single-ended mode. As you can probably guess, I didn't need differential mode, so I didn't add support for it.
63
+
64
+ == Contact information
65
+ * Matt Fletcher <fletcher@atomicobject.com>
66
+ * Atomic Object <http://atomicobject.com>
67
+
68
+ == Appendix
69
+ === DB37 pin to port mapping
70
+ Pin:: Port
71
+ 30-37:: :porta
72
+ 3-10:: :portb
73
+ 26-29:: :portcl
74
+ 22-25:: :portch
75
+
76
+ === System test setup
77
+
78
+ On top of the miniLAB:
79
+ CH0 IN:: D/A OUT 1
80
+ CH1 IN:: GND
81
+ CH2 IN:: DIO0
82
+ CH4 IN:: PC 5V
83
+ CH6 IN:: D/A OUT 0
84
+ DIO0:: DIO3
85
+ DIO1:: PC 5V
86
+ DIO2:: GND
87
+
88
+ On the DB37 pins:
89
+ 3:: 11
90
+ 4:: 11
91
+ 5:: 28
92
+ 6:: 11
93
+ 7:: 36
94
+ 8:: 11
95
+ 9:: 11
96
+ 10:: 20
97
+ 22:: 27
98
+ 23:: 21
99
+ 24:: 34
100
+ 25:: 21
101
+ 30:: 21
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ require "rake/rdoctask"
2
+ require "rspec/core/rake_task"
3
+
4
+ desc "Run the unit specs"
5
+ task :default => "spec:unit"
6
+
7
+ namespace :spec do
8
+ RSpec::Core::RakeTask.new(:unit) do |t|
9
+ t.pattern = "spec/unit/**/*_spec.rb"
10
+ end
11
+
12
+ RSpec::Core::RakeTask.new(:acceptance) do |t|
13
+ t.pattern = "spec/acceptance/**/*_spec.rb"
14
+ end
15
+
16
+ desc "all tests"
17
+ task :all => %w[ spec:unit spec:acceptance ]
18
+ end
19
+
20
+ Rake::RDocTask.new do |rdoc|
21
+ rdoc.rdoc_dir = "rdoc"
22
+ rdoc.title = "minilab: Ruby library for the miniLAB 1008"
23
+ rdoc.options = %w[ --main README.rdoc --title minilab ]
24
+ rdoc.rdoc_files.include("lib/minilab.rb", "README.rdoc", "CHANGES", "LICENSE")
25
+ end
data/doc/UniLib.chm ADDED
Binary file
Binary file
@@ -0,0 +1,38 @@
1
+ Setting up new Minilab hardware:
2
+ 1) Get it out of the packaging.
3
+ 2) Install the Minilab software (InstaCal, universal library are most important).
4
+ 3) Plug in the Minilab
5
+ 4) Fire up the InstaCal software. Configure the board:
6
+ - Custom Serial No. 253
7
+ - No. Of Channels 8 Single Ended
8
+ - Trigger Source DIO0
9
+ This configuration should work with the config file I have in the minilab driver
10
+ directories.
11
+ 5) Wire up the minilab. Use the below wiring:
12
+
13
+ On top of the minilab:
14
+ CH0 IN <---> D/A OUT 1
15
+ CH1 IN <---> GND
16
+ CH2 IN <---> DIO0
17
+ CH4 IN <---> PC +5V
18
+ CH6 IN <---> D/A OUT 0
19
+ DIO0 <---> DIO3
20
+ DIO1 <---> PC +5V
21
+ DIO2 <---> GND
22
+
23
+ On the external digital IO pins:
24
+ 3 <---> 11
25
+ 4 <---> 11
26
+ 5 <---> 28
27
+ 6 <---> 11
28
+ 7 <---> 36
29
+ 8 <---> 11
30
+ 9 <---> 11
31
+ 10 <---> 20
32
+ 22 <---> 27
33
+ 23 <---> 21
34
+ 24 <---> 34
35
+ 25 <---> 21
36
+ 30 <---> 21
37
+
38
+ 6) Getrdone.
@@ -0,0 +1,2 @@
1
+ printf ("| FIRSTPORTA | FIRSTPORTB |FIRSTPORTCL|FIRSTPORTCH|\n ");
2
+ printf ("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23\n");
@@ -0,0 +1,25 @@
1
+ module Minilab
2
+ class AnalogIo #:nodoc:
3
+ constructor :minilab_wrapper
4
+
5
+ def read_analog(channel)
6
+ check_channel_range(channel, 0, 7)
7
+ @minilab_wrapper.read_analog(channel)
8
+ end
9
+
10
+ def write_analog(channel, volts)
11
+ check_channel_range(channel, 0, 1)
12
+
13
+ unless (0.0 .. 5.0) === volts
14
+ raise "#{volts} volts is out of range for this device; Only voltage between 0.0 and 5.0 is supported."
15
+ end
16
+
17
+ @minilab_wrapper.write_analog(channel, volts)
18
+ end
19
+
20
+ private
21
+ def check_channel_range(channel, low, high)
22
+ raise "Channel #{channel} is out of range." unless (low..high) === channel
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ module Minilab
2
+ class ConnectionState
3
+ def initialize
4
+ @connected = false
5
+ end
6
+
7
+ def connected?
8
+ @connected
9
+ end
10
+
11
+ def connected=(value)
12
+ @connected = value
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,36 @@
1
+ module Minilab
2
+ class DigitalAuxportIo #:nodoc:
3
+ constructor :minilab_wrapper
4
+ include MinilabConstants
5
+
6
+ VALID_PINS = %w[ DIO0 DIO1 DIO2 DIO3 ]
7
+
8
+ def read_digital(pin)
9
+ validate_pin(pin)
10
+ configuration = {:direction => DIGITALIN, :pin => get_pin_number(pin)}
11
+
12
+ @minilab_wrapper.configure_auxport(configuration)
13
+ @minilab_wrapper.read_auxport(get_pin_number(pin))
14
+ end
15
+
16
+ def write_digital(pin, value)
17
+ raise "#{value} is not a valid digital output." if (value < 0)
18
+ value = 1 if (value > 0)
19
+
20
+ validate_pin(pin)
21
+ configuration = { :direction => DIGITALOUT, :pin => get_pin_number(pin)}
22
+
23
+ @minilab_wrapper.configure_auxport(configuration)
24
+ @minilab_wrapper.write_auxport(get_pin_number(pin), value)
25
+ end
26
+
27
+ private
28
+ def validate_pin(pin)
29
+ raise "#{pin} is not a valid digital IO pin" unless VALID_PINS.include?(pin.to_s.upcase)
30
+ end
31
+
32
+ def get_pin_number(pin)
33
+ pin.match(/(\d)$/)[0].to_i
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,55 @@
1
+ module Minilab
2
+ class DigitalConfiguration #:nodoc:
3
+ include MinilabConstants
4
+ constructor :minilab_wrapper
5
+
6
+ PORTS = [:porta, :portb, :portcl, :portch]
7
+ LIBRARY_PORT_NAMES = {
8
+ :porta => FIRSTPORTA,
9
+ :portb => FIRSTPORTB,
10
+ :portcl => FIRSTPORTCL,
11
+ :portch => FIRSTPORTCH
12
+ }
13
+
14
+ def setup
15
+ @port_status = PORTS.inject({}) do |port_status, port|
16
+ port_status[port] = :not_configured
17
+ port_status
18
+ end
19
+ end
20
+
21
+ def configure_port_for_input(port)
22
+ configure_port(port, DIGITALIN)
23
+ end
24
+
25
+ def configure_port_for_output(port)
26
+ configure_port(port, DIGITALOUT)
27
+ end
28
+
29
+ def is_port_configured_for_input?(port)
30
+ check_port_status(port, DIGITALIN)
31
+ end
32
+
33
+ def is_port_configured_for_output?(port)
34
+ check_port_status(port, DIGITALOUT)
35
+ end
36
+
37
+ private
38
+ def is_port_recognized?(port)
39
+ raise "Port #{port} is not valid." unless PORTS.include?(port)
40
+ end
41
+
42
+ def configure_port(port, direction)
43
+ is_port_recognized?(port)
44
+
45
+ @minilab_wrapper.configure_port(:direction => direction, :port => LIBRARY_PORT_NAMES[port])
46
+ @port_status[port] = direction
47
+ true
48
+ end
49
+
50
+ def check_port_status(port, status)
51
+ is_port_recognized?(port)
52
+ @port_status[port] == status ? true : false
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,41 @@
1
+ module Minilab
2
+ class DigitalPortIo #:nodoc:
3
+ constructor :minilab_wrapper, :digital_configuration, :library_translator
4
+
5
+ def configure_input_port(port)
6
+ @digital_configuration.configure_port_for_input(port)
7
+ end
8
+
9
+ def configure_output_port(port)
10
+ @digital_configuration.configure_port_for_output(port)
11
+ end
12
+
13
+ def read_digital(pin)
14
+ check_pin_configuration(pin, :input)
15
+ @minilab_wrapper.read_digital_pin(get_library_pin_number(pin))
16
+ end
17
+
18
+ def write_digital(pin, value)
19
+ check_pin_configuration(pin, :output)
20
+ @minilab_wrapper.write_digital_pin(get_library_pin_number(pin), value)
21
+ true
22
+ end
23
+
24
+ def read_port(port)
25
+ raise "Digital port #{port} is not configured for input." unless @digital_configuration.is_port_configured_for_input?(port)
26
+ @minilab_wrapper.read_port(@library_translator.get_library_port(port))
27
+ end
28
+
29
+ private
30
+ def get_library_pin_number(pin)
31
+ @library_translator.get_library_pin_number(pin)
32
+ end
33
+
34
+ def check_pin_configuration(pin, type)
35
+ port = @library_translator.get_port_for_pin(pin)
36
+ unless @digital_configuration.send("is_port_configured_for_#{type}?", port)
37
+ raise "Digital port #{port} for pin #{pin} is not configured for #{type}."
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,48 @@
1
+ module Minilab
2
+ class LibraryTranslator #:nodoc:
3
+ include MinilabConstants
4
+
5
+ def get_port_for_pin(pin)
6
+ case pin
7
+ when 30..37
8
+ :porta
9
+ when 3..10
10
+ :portb
11
+ when 26..29
12
+ :portcl
13
+ when 22..25
14
+ :portch
15
+ else
16
+ raise "Pin #{pin} does not map to a known minilab DB37 port."
17
+ end
18
+ end
19
+
20
+ def get_library_pin_number(pin)
21
+ case pin
22
+ when 30..37 # port a pins
23
+ 7 - (pin - 30)
24
+ when 3..10 # port b pins
25
+ 15 - (pin - 3)
26
+ when 26..29 # port cl pins
27
+ 19 - (pin - 26)
28
+ when 22..25 # port ch pins
29
+ 23 - (pin - 22)
30
+ else
31
+ raise "Pin #{pin} does not map to a minilab library pin number."
32
+ end
33
+ end
34
+
35
+ def get_library_port(port)
36
+ port_to_library_port_mapping = {
37
+ :porta => FIRSTPORTA,
38
+ :portb => FIRSTPORTB,
39
+ :portcl => FIRSTPORTCL,
40
+ :portch => FIRSTPORTCH
41
+ }
42
+
43
+ library_port = port_to_library_port_mapping[port]
44
+ return library_port unless library_port.nil?
45
+ raise "Port #{port} is not a valid port."
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,130 @@
1
+ module Minilab
2
+ # Use this method to construct Minilab objects. The object will not yet
3
+ # be connected to the device.
4
+ def self.build
5
+ MinilabContext.new.build[:minilab]
6
+ end
7
+
8
+ # The main interface to the minilab library. Create one of these objects
9
+ # using the +Minilab.build+ method. After you've created a minilab object,
10
+ # use the +connect+ method to establish the connection to the device.
11
+ # Minilab objects are not usable until they've been connected.
12
+ class Minilab
13
+ include MinilabConstants
14
+ constructor :minilab_wrapper, :analog_io, :digital_auxport_io, :digital_port_io, :connection_state
15
+
16
+ # Connect to the device. There are two side effects of connecting.
17
+ # * Error reporting from MCC's universal library is set to print
18
+ # errors to standard out instead of popping up a Windows dialog.
19
+ # * Each of the DB37 digital ports is setup for input.
20
+ def connect
21
+ @minilab_wrapper.setup_error_handling(DONTPRINT, STOPALL)
22
+ @minilab_wrapper.declare_revision(CURRENTREVNUM)
23
+ @connection_state.connected = true
24
+ DigitalConfiguration::PORTS.each { |port| configure_input_port(port) }
25
+ end
26
+
27
+ # Read from one of the eight analog channels (0 - 7) on top of the device.
28
+ #
29
+ # Single-ended mode is the only analog mode supported.
30
+ #
31
+ # An error is raised if an invalid channel number is given.
32
+ def read_analog(channel)
33
+ ensure_connected_to_device
34
+ @analog_io.read_analog(channel)
35
+ end
36
+
37
+ # Output a voltage on one of the eight analog channels. The output voltage
38
+ # must be in the range of 0.0 - 5.0 volts.
39
+ #
40
+ # Single-ended mode is the only analog mode supported.
41
+ #
42
+ # An error is raised if an invalid channel number or an out-of-range
43
+ # voltage is given.
44
+ def write_analog(channel, volts)
45
+ ensure_connected_to_device
46
+ @analog_io.write_analog(channel, volts)
47
+ end
48
+
49
+ # Configure one of the DB37 ports for input.
50
+ #
51
+ # Specify _port_ as a symbol. The available ports are <tt>:porta</tt>,
52
+ # <tt>:portb</tt>, <tt>:portcl</tt>, and <tt>:portch</tt>. An error is
53
+ # raised if an invalid port is given.
54
+ def configure_input_port(port)
55
+ ensure_connected_to_device
56
+ @digital_port_io.configure_input_port(port)
57
+ end
58
+
59
+ # Configure one of the DB37 ports for output.
60
+ #
61
+ # Specify _port_ as a symbol. The available ports are <tt>:porta</tt>,
62
+ # <tt>:portb</tt>, <tt>:portcl</tt>, and <tt>:portch</tt>. An error is
63
+ # raised if an invalid port is given.
64
+ def configure_output_port(port)
65
+ ensure_connected_to_device
66
+ @digital_port_io.configure_output_port(port)
67
+ end
68
+
69
+ # Read a single bit from one of the digital pins.
70
+ #
71
+ # If you'd like to read from one of the pins on the top of the device (the
72
+ # auxport pins), then specify the pin as a string with its label (e.g.
73
+ # read_digital("DIO1")). Alternatively, if you'd like to read from one of
74
+ # the DB37 pins, specify the pin as the number it's labeled with (e.g.
75
+ # read_digital(13)).
76
+ #
77
+ # An error is raised if you specify a pin that doesn't exist or if you
78
+ # try to read from a DB37 pin on a port that is not configured for input.
79
+ # The digital pins on the top of the device do not need to be configured.
80
+ def read_digital(pin)
81
+ ensure_connected_to_device
82
+ perform_digital_op(pin, :read, pin)
83
+ end
84
+
85
+ # Write a single bit to one of the digital pins. _value_ must be an integer
86
+ # 1 or 0.
87
+ #
88
+ # If you'd like to write to one of the pins on the top of the device (the
89
+ # auxport pins), then specify the pin as a string with its label (e.g.
90
+ # write_digital("DIO2", 0)). Alternatively, if you'd like to write to one
91
+ # of the DB37 pins, specify the pin as the number it's labeled with (e.g.
92
+ # write_digital(17, 1)).
93
+ #
94
+ # An error is raised if you specify a pin that doesn't exist or if you
95
+ # try to write to a DB37 pin on a port that is not configured for output.
96
+ # The digital pins on the top of the device do not need to be configured.
97
+ #
98
+ # Values above 1 are interpreted as 1; negative values raise an error.
99
+ def write_digital(pin, value)
100
+ ensure_connected_to_device
101
+ perform_digital_op(pin, :write, pin, value)
102
+ end
103
+
104
+ # Read a byte from one of the DB37 ports.
105
+ #
106
+ # Specify _port_ as a symbol. The available ports are <tt>:porta</tt>,
107
+ # <tt>:portb</tt>, <tt>:portcl</tt>, and <tt>:portch</tt>.
108
+ #
109
+ # An error is raised if an invalid port is given.
110
+ def read_digital_byte(port)
111
+ ensure_connected_to_device
112
+ @digital_port_io.read_port(port)
113
+ end
114
+
115
+ private
116
+ def perform_digital_op(pin, op, *args)
117
+ method = "#{op.to_s}_digital"
118
+ case pin
119
+ when String
120
+ @digital_auxport_io.send(method,*args)
121
+ when Fixnum
122
+ @digital_port_io.send(method,*args)
123
+ end
124
+ end
125
+
126
+ def ensure_connected_to_device
127
+ raise "Cannot use any minilab methods without calling 'connect' first." unless @connection_state.connected?
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,22 @@
1
+ # Lifted from cbw.h. Let's hope these don't change often.
2
+ # Using revision number 5.90.
3
+ module Minilab
4
+ module MinilabConstants
5
+ CURRENTREVNUM = 5.90
6
+
7
+ BOARDNUM = 0
8
+ DONTPRINT = 0
9
+ STOPALL = 2
10
+ ERRSTRLEN = 256
11
+ BIP10VOLTS = 1
12
+ UNI5VOLTS = 101
13
+
14
+ AUXPORT = 1
15
+ DIGITALOUT = 1
16
+ DIGITALIN = 2
17
+ FIRSTPORTA = 10
18
+ FIRSTPORTB = 11
19
+ FIRSTPORTCL = 12
20
+ FIRSTPORTCH = 13
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ require "diy"
2
+ require "yaml"
3
+ require "pathname"
4
+
5
+ module Minilab
6
+ class MinilabContext #:nodoc:
7
+ OBJECT_DEFINITION = Pathname.new(__FILE__).dirname + "objects.yml"
8
+
9
+ def build
10
+ if not @context
11
+ DIY::Context.auto_require = false
12
+ @context = DIY::Context.new(YAML.load_file(OBJECT_DEFINITION))
13
+ @context.build_everything
14
+ end
15
+ @context
16
+ end
17
+ end
18
+ end