lego_nxt 0.0.1 → 0.0.2
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.
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/.yardopts +6 -0
- data/Guardfile +6 -0
- data/README.md +76 -1
- data/Rakefile +14 -0
- data/lego_nxt.gemspec +27 -11
- data/lib/lego_nxt.rb +3 -1
- data/lib/lego_nxt/constants.rb +147 -0
- data/lib/lego_nxt/errors.rb +14 -0
- data/lib/lego_nxt/usb_connection.rb +99 -0
- data/lib/lego_nxt/version.rb +3 -2
- data/spec/lib/lego_nxt/usb_connection_spec.rb +98 -0
- data/spec/spec_helper.rb +15 -0
- metadata +104 -10
data/.rspec
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# LegoNxt
|
2
2
|
|
3
|
-
|
3
|
+
[](http://travis-ci.org/docwhat/lego_nxt)
|
4
|
+
|
5
|
+
An object oriented interface for talking to the LEGO NXT brick.
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -16,10 +18,74 @@ Or install it yourself as:
|
|
16
18
|
|
17
19
|
$ gem install lego_nxt
|
18
20
|
|
21
|
+
### Mac OS X
|
22
|
+
|
23
|
+
You'll need a copy of [libusb](http://www.libusb.org/) and its development library installed.
|
24
|
+
|
25
|
+
One easy way to do this is with [homebrew](http://mxcl.github.com/homebrew/):
|
26
|
+
|
27
|
+
brew install libusb
|
28
|
+
|
29
|
+
To get the bluetooth working, it's pretty easy:
|
30
|
+
|
31
|
+
1. Pair your NXT to your computer.
|
32
|
+
1. In "Bluetooth Preference" in "System Preferences":
|
33
|
+
1. Click on "NXT" (This may be different if you renamed your NXT brick).
|
34
|
+
1. Click on the gear below the list box.
|
35
|
+
1. Select "Edit Serial Ports..."
|
36
|
+
1. Press the "+" button. It should fill in as:
|
37
|
+
* Name: NXT-DevB
|
38
|
+
* Protocol: RS-232
|
39
|
+
* Service: Dev B
|
40
|
+
1. Click "Apply"
|
41
|
+
|
42
|
+
You should now have two new devices in your `/dev` directory:
|
43
|
+
* `/dev/tty.NXT-DevB` -- This is what we'll use to talk to the NXT brick.
|
44
|
+
* `/dev/cu.NXT-DevB`
|
45
|
+
|
46
|
+
### Linux
|
47
|
+
|
48
|
+
You need a copy of [libusb](http://www.libusb.org/)'s development libraries.'
|
49
|
+
|
50
|
+
TODO: Add instructions for setting up bluetooth.
|
51
|
+
|
52
|
+
### Windows
|
53
|
+
|
54
|
+
WARNING: I only use Windows at work. I don't own a personal copy and therefore
|
55
|
+
don't use it. However, my goal is to make this work on Windows with the help
|
56
|
+
of people like you. So find me on [http://freenode.net/] IRC as `docwhat` or
|
57
|
+
via [docwhat.org](http://docwhat.org) if you have problems. Or file an issue!
|
58
|
+
|
59
|
+
The [libusb](https://github.com/larskanis/libusb) gem has support for windows
|
60
|
+
built in; it ships with a `libusb.dll` ready to use.
|
61
|
+
|
62
|
+
You may need a USB driver. I'm hopeful that if you installed the lego NXT-G
|
63
|
+
environment (the CD that came with Mindstorms) that you should be ready to go.
|
64
|
+
If not, read the [libusb](https://github.com/larskanis/libusb) gem's docs.
|
65
|
+
They suggest something called
|
66
|
+
[Zadig](http://sourceforge.net/apps/mediawiki/libwdi/index.php?title=Main_Page).
|
67
|
+
|
68
|
+
TODO: Add instructions for setting up bluetooth. Until then, see [this helpful
|
69
|
+
document](http://www.eng.buffalo.edu/~colinlea/Bluetooth_With_NXT.pdf)
|
70
|
+
|
19
71
|
## Usage
|
20
72
|
|
21
73
|
TODO: Write usage instructions here
|
22
74
|
|
75
|
+
## Documentation
|
76
|
+
|
77
|
+
The documentation is written for yard. Install the `yard` gem and you can
|
78
|
+
use the `yri` command to browse the documentation.
|
79
|
+
|
80
|
+
Alternatively, you can read the [online documentation](http://rubydoc.info/github/docwhat/lego_nxt/master/frames).
|
81
|
+
|
82
|
+
## Testing
|
83
|
+
|
84
|
+
Most tests will work without owning a NXT brick
|
85
|
+
|
86
|
+
To run all the tests, including the ones that require a NXT brick, then you need to
|
87
|
+
plugin your NXT brick, power it on, and run `rake usb:spec`
|
88
|
+
|
23
89
|
## Contributing
|
24
90
|
|
25
91
|
1. Fork it
|
@@ -27,3 +93,12 @@ TODO: Write usage instructions here
|
|
27
93
|
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
94
|
4. Push to the branch (`git push origin my-new-feature`)
|
29
95
|
5. Create new Pull Request
|
96
|
+
|
97
|
+
## Reference Material
|
98
|
+
|
99
|
+
Useful if you're going to be hacking on the code:
|
100
|
+
|
101
|
+
* [libusb](https://github.com/larskanis/libusb) - The [docs](http://rubydoc.info/gems/libusb/LIBUSB) in particular.
|
102
|
+
* [LEGO's Support Files](http://mindstorms.lego.com/en-us/support/files/default.aspx#Advanced) - In particular:
|
103
|
+
* The Bluetooth Developer Kit -- Appendix 1: LEGO MINDSTORMS NXT Communication protocol
|
104
|
+
* Software Development Kit -- The PDF contains a description of the Executable File Specification
|
data/Rakefile
CHANGED
@@ -1,2 +1,16 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
|
+
|
2
3
|
require "bundler/gem_tasks"
|
4
|
+
require "yard"
|
5
|
+
require "rspec/core/rake_task"
|
6
|
+
|
7
|
+
YARD::Rake::YardocTask.new
|
8
|
+
RSpec::Core::RakeTask.new(:spec)
|
9
|
+
|
10
|
+
namespace :usb do
|
11
|
+
desc "Run RSpec code examples with a NXT connected via USB"
|
12
|
+
task :spec do
|
13
|
+
ENV['HAS_NXT'] = 'true'
|
14
|
+
Rake::Task["spec"].invoke
|
15
|
+
end
|
16
|
+
end
|
data/lego_nxt.gemspec
CHANGED
@@ -2,16 +2,32 @@
|
|
2
2
|
require File.expand_path('../lib/lego_nxt/version', __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
|
-
gem.authors
|
6
|
-
gem.email
|
7
|
-
gem.description
|
8
|
-
gem.summary
|
9
|
-
gem.homepage
|
5
|
+
gem.authors = ["Christian Höltje", "Steve Klabnik"]
|
6
|
+
gem.email = ["docwhat@gerf.org", "steve@steveklabnik.com"]
|
7
|
+
gem.description = %q{A gem to interface with LEGO MINDSTORMS NXT bricks.}
|
8
|
+
gem.summary = %q{A gem to interface with LEGO MINDSTORMS NXT bricks.}
|
9
|
+
gem.homepage = "http://github.com/docwhat/lego_nxt"
|
10
10
|
|
11
|
-
gem.files
|
12
|
-
gem.executables
|
13
|
-
gem.test_files
|
14
|
-
gem.name
|
15
|
-
gem.require_paths
|
16
|
-
gem.version
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "lego_nxt"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = LegoNXT::VERSION
|
17
|
+
gem.required_ruby_version = "~> 1.9.2"
|
18
|
+
|
19
|
+
gem.add_runtime_dependency 'libusb', '~> 0.1.3'
|
20
|
+
|
21
|
+
gem.add_development_dependency 'rake', '~> 0.9.2'
|
22
|
+
|
23
|
+
# Testing framework
|
24
|
+
gem.add_development_dependency 'rspec', '~> 2.9.0'
|
25
|
+
|
26
|
+
# Continous integration testing
|
27
|
+
gem.add_development_dependency 'guard', '~> 1.0.1'
|
28
|
+
gem.add_development_dependency 'guard-rspec', '~> 0.7.0'
|
29
|
+
|
30
|
+
# Documentation
|
31
|
+
gem.add_development_dependency 'yard'
|
32
|
+
gem.add_development_dependency 'redcarpet'
|
17
33
|
end
|
data/lib/lego_nxt.rb
CHANGED
@@ -0,0 +1,147 @@
|
|
1
|
+
module LegoNXT
|
2
|
+
|
3
|
+
# op-codes for direct commands.
|
4
|
+
#
|
5
|
+
# All commands, when using {REQUIRE_RESPONSE} should
|
6
|
+
# return: `0x02, <op-code>, <status-byte> [, <data-payload>...]`
|
7
|
+
#
|
8
|
+
# The status byte is either 0 for success, or one of the
|
9
|
+
# constants below that end in `_ERROR`.
|
10
|
+
#
|
11
|
+
# For brevity, only the data-payload is documented.
|
12
|
+
#
|
13
|
+
# All strings should be null (`0x00`) terminated.
|
14
|
+
#
|
15
|
+
# See the LEGO MINDSTORMS NXT Bluetooth Developer Kit
|
16
|
+
# Appendix 2 - LEGO MINDSTORMS NXT Direct commands
|
17
|
+
module DirectOps
|
18
|
+
# The first byte sent when sending a direct command
|
19
|
+
# and you expect a response.
|
20
|
+
REQUIRE_RESPONSE = 0x00
|
21
|
+
# The first byte sent when sending a direct command
|
22
|
+
# and you don't want a response.
|
23
|
+
NO_RESPONSE = 0x80
|
24
|
+
|
25
|
+
STARTPROGRAM = 0x00
|
26
|
+
STOPPROGRAM = 0x01
|
27
|
+
PLAYSOUNDFILE = 0x02
|
28
|
+
# Play a tone (beep)
|
29
|
+
#
|
30
|
+
# Arguments:
|
31
|
+
#
|
32
|
+
# 1. 2 bytes (UWORD) - Frequency in Hz (200 - 1400Hz)
|
33
|
+
# 2. 2 bytes (UWORD) - Duration of the tone in ms.
|
34
|
+
PLAYTONE = 0x03
|
35
|
+
SETOUTPUTSTATE = 0x04
|
36
|
+
SETINPUTMODE = 0x05
|
37
|
+
GETOUTPUTSTATE = 0x06
|
38
|
+
GETINPUTVALUES = 0x07
|
39
|
+
RESETINPUTSCALEDVALUE = 0x08
|
40
|
+
MESSAGEWRITE = 0x09
|
41
|
+
RESETMOTORPOSITION = 0x0A
|
42
|
+
|
43
|
+
# Get the battery Level
|
44
|
+
#
|
45
|
+
# Response:
|
46
|
+
#
|
47
|
+
# 1. 2 bytes (UWORD) - Voltage in millivolts.
|
48
|
+
GETBATTERYLEVEL = 0x0B
|
49
|
+
STOPSOUNDPLAYBACK = 0x0C
|
50
|
+
KEEPALIVE = 0x0D
|
51
|
+
LSGETSTATUS = 0x0E
|
52
|
+
LSWRITE = 0x0F
|
53
|
+
LSREAD = 0x10
|
54
|
+
GETCURRENTPROGRAMNAME = 0x11
|
55
|
+
MESSAGEREAD = 0x12
|
56
|
+
end
|
57
|
+
|
58
|
+
# Errors that may be return via the status-byte
|
59
|
+
# for direct commands.
|
60
|
+
module DirectOpsErrors
|
61
|
+
PENDING_COMMUNICATION_TRANSACTION_IN_PROGRESS_ERROR = 0x20
|
62
|
+
SPECIFIED_MAILBOX_QUEUE_IS_EMPTY_ERROR = 0x40
|
63
|
+
REQUEST_FAILED_ERROR = 0xBD
|
64
|
+
UNKNOWN_COMMAND_OPCODE_ERROR = 0xBE
|
65
|
+
INSANE_PACKET_ERROR = 0xBF
|
66
|
+
DATA_CONTAINS_OUT_OF_RANGE_VALUES_ERROR = 0xC0
|
67
|
+
COMMUNICATION_BUS_ERROR = 0xDD
|
68
|
+
NO_FREE_MEMORY_IN_COMMUNICATION_BUFFER_ERROR = 0xDE
|
69
|
+
SPECIFIED_CHANNEL_CONNECTION_IS_NOT_VALID_ERROR = 0xDF
|
70
|
+
SPECIFIED_CHANNEL_CONNECTION_NOT_CONFIGURED_OR_BUSY_ERROR = 0xE0
|
71
|
+
NO_ACTIVE_PROGRAM_ERROR = 0xEC
|
72
|
+
ILLEGAL_SIZE_SPECIFIED_ERROR = 0xED
|
73
|
+
ILLEGAL_MAILBOX_QUEUE_ID_SPECIFIED_ERROR = 0xEE
|
74
|
+
ATTEMPTED_TO_ACCESS_INVALID_FIELD_OF_A_STRUCTURE_ERROR = 0xEF
|
75
|
+
BAD_INPUT_OR_OUTPUT_SPECIFIED_ERROR = 0xF0
|
76
|
+
INSUFFICIENT_MEMORY_AVAILABLE_ERROR = 0xFB
|
77
|
+
BAD_ARGUMENTS_ERROR = 0xFF
|
78
|
+
end
|
79
|
+
|
80
|
+
# op-codes for system commands.
|
81
|
+
#
|
82
|
+
# All commands, when using {REQUIRE_RESPONSE} should
|
83
|
+
# return: `0x02, <op-code>, <status-byte> [, <data-payload>...]`
|
84
|
+
#
|
85
|
+
# The status byte is either 0 for success, or one of the
|
86
|
+
# constants below that end in `_ERROR`.
|
87
|
+
#
|
88
|
+
# For brevity, only the data-payload is documented.
|
89
|
+
#
|
90
|
+
# All strings should be null (`0x00`) terminated.
|
91
|
+
#
|
92
|
+
# See the LEGO MINDSTORMS NXT Bluetooth Developer Kit
|
93
|
+
# Appendix 1 - LEGO MINDSTORMS NXT Communication protocol
|
94
|
+
module SystemOps
|
95
|
+
# The first byte used when sending a system command
|
96
|
+
# and you expect a response.
|
97
|
+
REQUIRE_RESPONSE = 0x01
|
98
|
+
# The first byte used when sending a system command
|
99
|
+
# and you don't want a response.
|
100
|
+
NO_RESPONSE = 0x81
|
101
|
+
|
102
|
+
OPEN_READ_COMMAND = 0x80
|
103
|
+
OPEN_WRITE_COMMAND = 0x81
|
104
|
+
READ_COMMAND = 0x82
|
105
|
+
WRITE_COMMAND = 0x83
|
106
|
+
CLOSE_COMMAND = 0x84
|
107
|
+
DELETE_COMMAND = 0x85
|
108
|
+
FIND_FIRST = 0x86
|
109
|
+
FIND_NEXT = 0x87
|
110
|
+
GET_FIRMWARE_VERSION = 0x88
|
111
|
+
OPEN_WRITE_LINEAR_COMMAND = 0x89
|
112
|
+
OPEN_READ_LINEAR_COMMAND_INTERNAL = 0x8A
|
113
|
+
OPEN_WRITE_DATA_COMMAND = 0x8B
|
114
|
+
OPEN_APPEND_DATA_COMMAND = 0x8C
|
115
|
+
BOOT_COMMAND = 0x97
|
116
|
+
SET_BRICK_NAME_COMMAND = 0x98
|
117
|
+
GET_DEVICE_INFO = 0x9B
|
118
|
+
DELETE_USER_FLASH = 0xA0
|
119
|
+
POLL_COMMAND_LENGTH = 0xA1
|
120
|
+
POLL_COMMAND = 0xA2
|
121
|
+
BLUETOOTH_FACTOR_RESET_COMMAND = 0xA4 # Don't send via bluetooth, duh.
|
122
|
+
end
|
123
|
+
|
124
|
+
# Errors that may be return via the status-byte
|
125
|
+
# for system commands.
|
126
|
+
module SystemOpsErrors
|
127
|
+
NO_MORE_HANDLES_ERROR = 0x81
|
128
|
+
NO_SPACE_ERROR = 0x82
|
129
|
+
NO_MORE_FILES_ERROR = 0x83
|
130
|
+
END_OF_FILE_EXPECTED_ERROR = 0x84
|
131
|
+
END_OF_FILE_ERROR = 0x85
|
132
|
+
NOT_A_LINEAR_FILE_ERROR = 0x86
|
133
|
+
FILE_NOT_FOUND_ERROR = 0x87
|
134
|
+
HANDLE_ALL_READY_CLOSED_ERROR = 0x88
|
135
|
+
NO_LINEAR_SPACE_ERROR = 0x89
|
136
|
+
UNDEFINED_ERROR = 0x8A
|
137
|
+
FILE_IS_BUSY_ERROR = 0x8B
|
138
|
+
NO_WRITE_BUFFERS_ERROR = 0x8C
|
139
|
+
APPEND_NOT_POSSIBLE_ERROR = 0x8D
|
140
|
+
FILE_IS_FULL_ERROR = 0x8E
|
141
|
+
FILE_EXISTS_ERROR = 0x8F
|
142
|
+
MODULE_NOT_FOUND_ERROR = 0x90
|
143
|
+
OUT_OF_BOUNDARY_ERROR = 0x91
|
144
|
+
ILLEGAL_FILE_NAME_ERROR = 0x92
|
145
|
+
ILLEGAL_HANDLE_ERROR = 0x93
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module LegoNXT
|
2
|
+
# All LegoNXT errors are subclassed from this
|
3
|
+
# error class.
|
4
|
+
class LegoNXTError < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
# No NXT bricks were found.
|
8
|
+
class NoDeviceError < LegoNXTError
|
9
|
+
end
|
10
|
+
|
11
|
+
# The transmit failed for some reason
|
12
|
+
class TransmitError < LegoNXTError
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'libusb'
|
2
|
+
require 'lego_nxt/errors'
|
3
|
+
|
4
|
+
module LegoNXT
|
5
|
+
|
6
|
+
# Low-level connection object for communicating with the NXT brick
|
7
|
+
# via USB.
|
8
|
+
#
|
9
|
+
# It's interface is very simple and mainly deals with bytes `pack`ed
|
10
|
+
# into `String`s.
|
11
|
+
#
|
12
|
+
# Example of packing:
|
13
|
+
#
|
14
|
+
# [ 0x80, 0x03].pack('C*')
|
15
|
+
#
|
16
|
+
# Example of unpacking
|
17
|
+
#
|
18
|
+
# bytestring.unpack('C*')
|
19
|
+
#
|
20
|
+
# WARNING: This class is *not* threadsafe. To use it in a threaded environment
|
21
|
+
# you need to synchonize access to it.
|
22
|
+
class UsbConnection
|
23
|
+
# The USB idVendor code
|
24
|
+
LEGO_VENDOR_ID = 0x0694
|
25
|
+
# The USB idProduct code
|
26
|
+
NXT_PRODUCT_ID = 0x0002
|
27
|
+
|
28
|
+
# The USB endpoint (communication channel) to send data out to the NXT brick
|
29
|
+
USB_ENDPOINT_OUT = 0x01
|
30
|
+
|
31
|
+
# The USB endpoint (communication channel) to receive data from the NXT brick
|
32
|
+
USB_ENDPOINT_IN = 0x82
|
33
|
+
|
34
|
+
# Creates a connection to the NXT brick.
|
35
|
+
#
|
36
|
+
def initialize
|
37
|
+
open
|
38
|
+
end
|
39
|
+
|
40
|
+
# Sends a packed string of bits.
|
41
|
+
#
|
42
|
+
# Example:
|
43
|
+
#
|
44
|
+
# # Causes the brick to beep
|
45
|
+
# conn.transmit [0x80, 0x03, 0xf4, 0x01, 0xf4, 0x01].pack('C*')'
|
46
|
+
#
|
47
|
+
# @see The LEGO MINDSTORMS NXT Communications Protocol (Appendex 1 of the Bluetooth Development Kit)
|
48
|
+
#
|
49
|
+
# @param {String} bits This must be a binary string. Use `Array#pack('C*')` to generate the string.
|
50
|
+
# @return [Boolean] Returns true if all the data was sent and received by the NXT.
|
51
|
+
def transmit bits
|
52
|
+
bytes_sent = @handle.bulk_transfer dataOut: bits, endpoint: USB_ENDPOINT_OUT
|
53
|
+
bytes_sent == bits.length
|
54
|
+
end
|
55
|
+
|
56
|
+
# Sends a packet string of bits and then receives a result.
|
57
|
+
#
|
58
|
+
# Example:
|
59
|
+
#
|
60
|
+
# # Causes the brick to beep
|
61
|
+
# conn.transceive [0x80, 0x03, 0xf4, 0x01, 0xf4, 0x01].pack('C*')'
|
62
|
+
#
|
63
|
+
# @see The LEGO MINDSTORMS NXT Communications Protocol (Appendex 1 of the Bluetooth Development Kit)
|
64
|
+
#
|
65
|
+
# @param {String} bits This must be a binary string. Use `Array#pack('C*')` to generate the string.
|
66
|
+
# @raise {LegoNXT::TransmitError} Raised if the {#transmit} fails.
|
67
|
+
# @return [String] A packed string of the response bits. Use `String#unpack('C*')`.
|
68
|
+
def transceive bits
|
69
|
+
raise TransmitError unless transmit bits
|
70
|
+
bytes_received = @handle.bulk_transfer dataIn: 64, endpoint: USB_ENDPOINT_IN
|
71
|
+
return bytes_received
|
72
|
+
end
|
73
|
+
|
74
|
+
# Closes the connection
|
75
|
+
#
|
76
|
+
# @return [nil]
|
77
|
+
def close
|
78
|
+
return if @handle.nil?
|
79
|
+
@handle.close
|
80
|
+
@handle = nil
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
# Opens the connection
|
87
|
+
#
|
88
|
+
# This is triggered automatically by intantiating the object.
|
89
|
+
#
|
90
|
+
# @return [nil]
|
91
|
+
def open
|
92
|
+
context = LIBUSB::Context.new
|
93
|
+
device = context.devices(:idVendor => LEGO_VENDOR_ID, :idProduct => NXT_PRODUCT_ID).first
|
94
|
+
raise NoDeviceError.new("Please make sure the device is plugged in and powered on") if device.nil?
|
95
|
+
@handle = device.open
|
96
|
+
@handle.claim_interface(0)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/lego_nxt/version.rb
CHANGED
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'lego_nxt/usb_connection'
|
3
|
+
require 'lego_nxt/constants'
|
4
|
+
|
5
|
+
describe LegoNXT::UsbConnection do
|
6
|
+
subject { LegoNXT::UsbConnection.new }
|
7
|
+
after(:each) { HAS_NXT and subject.close }
|
8
|
+
|
9
|
+
describe "#new" do
|
10
|
+
it "does something" do
|
11
|
+
needs_nxt do
|
12
|
+
LegoNXT::UsbConnection.new.close
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "works twice" do
|
17
|
+
needs_nxt do
|
18
|
+
LegoNXT::UsbConnection.new.close
|
19
|
+
LegoNXT::UsbConnection.new.close
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe ".transmit" do
|
25
|
+
it "should beep" do
|
26
|
+
needs_nxt do
|
27
|
+
ops = [LegoNXT::DirectOps::NO_RESPONSE,
|
28
|
+
LegoNXT::DirectOps::PLAYTONE,
|
29
|
+
500,
|
30
|
+
500].pack('CCvv')
|
31
|
+
subject.transmit ops
|
32
|
+
sleep 0.5
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "return success" do
|
37
|
+
needs_nxt do
|
38
|
+
ops = [LegoNXT::DirectOps::NO_RESPONSE,
|
39
|
+
LegoNXT::DirectOps::PLAYTONE,
|
40
|
+
700,
|
41
|
+
500].pack('CCvv')
|
42
|
+
subject.transmit(ops).should be_true
|
43
|
+
sleep 0.5
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe ".transceive" do
|
49
|
+
context "with a successful transmit" do
|
50
|
+
let (:ops) do
|
51
|
+
[LegoNXT::SystemOps::REQUIRE_RESPONSE,
|
52
|
+
LegoNXT::SystemOps::GET_FIRMWARE_VERSION].pack 'CC'
|
53
|
+
end
|
54
|
+
let (:retval) { subject.transceive(ops).unpack('C*') }
|
55
|
+
it "should return 7 bytes" do
|
56
|
+
needs_nxt do
|
57
|
+
retval.should have(7).items
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should return the response bits" do
|
62
|
+
needs_nxt do
|
63
|
+
retval[0].should == 0x02
|
64
|
+
retval[1].should == 0x88
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should be successful" do
|
69
|
+
needs_nxt do
|
70
|
+
retval[2].should == 0x0
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "with an unsuccessful transmit" do
|
76
|
+
it "should raise TransmitError" do
|
77
|
+
LegoNXT::UsbConnection.any_instance.stub(:open)
|
78
|
+
subject.stub(:transmit) { false }
|
79
|
+
expect { subject.transceive(double) }.to raise_error(LegoNXT::TransmitError)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe ".close" do
|
85
|
+
it "does something" do
|
86
|
+
needs_nxt do
|
87
|
+
subject.close
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it "can be called twice with no ill effects" do
|
92
|
+
needs_nxt do
|
93
|
+
subject.close
|
94
|
+
subject.close
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
HAS_NXT = ENV['HAS_NXT'] == 'true'
|
2
|
+
|
3
|
+
if not HAS_NXT
|
4
|
+
puts "**NOTE** Some tests are marked pending because you did not indicate you have a NXT brick."
|
5
|
+
puts " To run all tests, plugin a NXN brick via USB, power it on, and set"
|
6
|
+
puts " the environment variable 'HAS_NXT' to 'true'."
|
7
|
+
end
|
8
|
+
|
9
|
+
def needs_nxt &block
|
10
|
+
if HAS_NXT
|
11
|
+
yield
|
12
|
+
else
|
13
|
+
pending "This requires a NXT brick"
|
14
|
+
end
|
15
|
+
end
|
metadata
CHANGED
@@ -1,32 +1,120 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lego_nxt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
|
+
- Christian Höltje
|
8
9
|
- Steve Klabnik
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
13
|
-
dependencies:
|
14
|
-
|
13
|
+
date: 2012-04-13 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: libusb
|
17
|
+
requirement: &70097839321340 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.1.3
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *70097839321340
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rake
|
28
|
+
requirement: &70097839300880 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.9.2
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *70097839300880
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rspec
|
39
|
+
requirement: &70097839298840 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 2.9.0
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *70097839298840
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: guard
|
50
|
+
requirement: &70097839296420 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.0.1
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *70097839296420
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: guard-rspec
|
61
|
+
requirement: &70097839293320 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ~>
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 0.7.0
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *70097839293320
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: yard
|
72
|
+
requirement: &70097839292400 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: *70097839292400
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: redcarpet
|
83
|
+
requirement: &70097839290720 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: *70097839290720
|
92
|
+
description: A gem to interface with LEGO MINDSTORMS NXT bricks.
|
15
93
|
email:
|
94
|
+
- docwhat@gerf.org
|
16
95
|
- steve@steveklabnik.com
|
17
96
|
executables: []
|
18
97
|
extensions: []
|
19
98
|
extra_rdoc_files: []
|
20
99
|
files:
|
21
100
|
- .gitignore
|
101
|
+
- .rspec
|
102
|
+
- .travis.yml
|
103
|
+
- .yardopts
|
22
104
|
- Gemfile
|
105
|
+
- Guardfile
|
23
106
|
- LICENSE
|
24
107
|
- README.md
|
25
108
|
- Rakefile
|
26
109
|
- lego_nxt.gemspec
|
27
110
|
- lib/lego_nxt.rb
|
111
|
+
- lib/lego_nxt/constants.rb
|
112
|
+
- lib/lego_nxt/errors.rb
|
113
|
+
- lib/lego_nxt/usb_connection.rb
|
28
114
|
- lib/lego_nxt/version.rb
|
29
|
-
|
115
|
+
- spec/lib/lego_nxt/usb_connection_spec.rb
|
116
|
+
- spec/spec_helper.rb
|
117
|
+
homepage: http://github.com/docwhat/lego_nxt
|
30
118
|
licenses: []
|
31
119
|
post_install_message:
|
32
120
|
rdoc_options: []
|
@@ -35,19 +123,25 @@ require_paths:
|
|
35
123
|
required_ruby_version: !ruby/object:Gem::Requirement
|
36
124
|
none: false
|
37
125
|
requirements:
|
38
|
-
- -
|
126
|
+
- - ~>
|
39
127
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
128
|
+
version: 1.9.2
|
41
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
130
|
none: false
|
43
131
|
requirements:
|
44
132
|
- - ! '>='
|
45
133
|
- !ruby/object:Gem::Version
|
46
134
|
version: '0'
|
135
|
+
segments:
|
136
|
+
- 0
|
137
|
+
hash: 400650911654824634
|
47
138
|
requirements: []
|
48
139
|
rubyforge_project:
|
49
|
-
rubygems_version: 1.8.
|
140
|
+
rubygems_version: 1.8.17
|
50
141
|
signing_key:
|
51
142
|
specification_version: 3
|
52
|
-
summary: A gem to interface with LEGO NXT
|
53
|
-
test_files:
|
143
|
+
summary: A gem to interface with LEGO MINDSTORMS NXT bricks.
|
144
|
+
test_files:
|
145
|
+
- spec/lib/lego_nxt/usb_connection_spec.rb
|
146
|
+
- spec/spec_helper.rb
|
147
|
+
has_rdoc:
|