lego_nxt 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://secure.travis-ci.org/docwhat/lego_nxt.png?branch=master)](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:
|