nxt 0.2.0 → 0.3.0
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/lib/nxt.rb +1 -0
- data/lib/nxt/commands/base.rb +23 -0
- data/lib/nxt/commands/input.rb +60 -0
- data/lib/nxt/commands/program.rb +70 -0
- data/lib/nxt/connectors/base.rb +35 -0
- data/lib/nxt/connectors/input/color.rb +20 -1
- data/lib/nxt/connectors/output/motor.rb +34 -46
- data/lib/nxt/errors.rb +25 -0
- data/lib/nxt/exceptions.rb +3 -0
- data/lib/nxt/interfaces/base.rb +3 -1
- data/lib/nxt/interfaces/serial_port.rb +13 -1
- data/lib/nxt/nxt_brick.rb +12 -0
- data/lib/nxt/utils/accessors.rb +7 -3
- data/spec/nxt/connectors/output/motor_spec.rb +55 -0
- metadata +7 -4
data/lib/nxt.rb
CHANGED
data/lib/nxt/commands/base.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module NXT
|
2
2
|
module Command
|
3
3
|
module Base
|
4
|
+
|
4
5
|
private
|
5
6
|
|
6
7
|
COMMAND_TYPES = {
|
@@ -9,6 +10,28 @@ module NXT
|
|
9
10
|
reply: 0x02
|
10
11
|
}.freeze
|
11
12
|
|
13
|
+
COMMANDS = {
|
14
|
+
0x00 => 'startprogram',
|
15
|
+
0x01 => 'stopprogram',
|
16
|
+
0x02 => 'playsoundfile',
|
17
|
+
0x03 => 'playtone',
|
18
|
+
0x04 => 'setoutputstate',
|
19
|
+
0x05 => 'setinputmode',
|
20
|
+
0x06 => 'getoutputstate',
|
21
|
+
0x07 => 'getinputvalues',
|
22
|
+
0x08 => 'resetinputscaledvalue',
|
23
|
+
0x09 => 'messagewrite',
|
24
|
+
0x0a => 'resetmotorposition',
|
25
|
+
0x0b => 'getbatterylevel',
|
26
|
+
0x0c => 'stopsoundplayback',
|
27
|
+
0x0d => 'keepalive',
|
28
|
+
0x0e => 'lsgetstatus',
|
29
|
+
0x0f => 'lswrite',
|
30
|
+
0x10 => 'lsread',
|
31
|
+
0x11 => 'getcurrentprogramname',
|
32
|
+
0x13 => 'messageread',
|
33
|
+
}
|
34
|
+
|
12
35
|
PORTS = {
|
13
36
|
a: 0x00,
|
14
37
|
b: 0x01,
|
data/lib/nxt/commands/input.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
module NXT
|
2
|
+
module Command
|
3
|
+
module Input
|
4
|
+
include NXT::Command::Base
|
5
|
+
extend NXT::Utils::Accessors
|
6
|
+
|
7
|
+
@@command_type = COMMAND_TYPES[:direct]
|
8
|
+
@@command = 0x05
|
9
|
+
|
10
|
+
SENSOR_TYPES = {}
|
11
|
+
[:no_sensor,
|
12
|
+
:switch,
|
13
|
+
:temperature,
|
14
|
+
:reflection,
|
15
|
+
:angle,
|
16
|
+
:light_active,
|
17
|
+
:light_inactive,
|
18
|
+
:sound_db,
|
19
|
+
:sound_dba,
|
20
|
+
:custom,
|
21
|
+
:lowspeed,
|
22
|
+
:lowspeed_9v,
|
23
|
+
:highspeed,
|
24
|
+
:colorfull,
|
25
|
+
:colorred,
|
26
|
+
:colorgreen,
|
27
|
+
:colorblue,
|
28
|
+
:colornone
|
29
|
+
].each_with_index do |key, index|
|
30
|
+
SENSOR_TYPES[key] = index
|
31
|
+
end
|
32
|
+
|
33
|
+
SENSOR_MODES = {
|
34
|
+
:rawmode => 0x00,
|
35
|
+
:booleanmode => 0x20,
|
36
|
+
:transitioncntmode => 0x40,
|
37
|
+
:periodcountermode => 0x60,
|
38
|
+
:pctfullscalemode => 0x80,
|
39
|
+
:celsiusmode => 0xA0,
|
40
|
+
:fahrenheitmode => 0xC0,
|
41
|
+
:anglestepmode => 0xE0,
|
42
|
+
:slopemask => 0x1F,
|
43
|
+
:modemask => 0xE0
|
44
|
+
}
|
45
|
+
|
46
|
+
def set_input_mode(type, mode)
|
47
|
+
raise "Invalid sensor type: #{type}" if !type.nil? && !SENSOR_TYPES.include?(type)
|
48
|
+
|
49
|
+
@interface.send_and_receive([
|
50
|
+
@@command_type,
|
51
|
+
@@command,
|
52
|
+
port_as_byte(@port),
|
53
|
+
SENSOR_TYPES[type],
|
54
|
+
SENSOR_MODES[mode]
|
55
|
+
])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
data/lib/nxt/commands/program.rb
CHANGED
@@ -0,0 +1,70 @@
|
|
1
|
+
module NXT
|
2
|
+
module Command
|
3
|
+
module Output
|
4
|
+
class Program
|
5
|
+
include NXT::Command::Base
|
6
|
+
|
7
|
+
@@command_type = COMMAND_TYPES[:direct]
|
8
|
+
START_PROGRAM = 0x00
|
9
|
+
STOP_PROGRAM = 0x01
|
10
|
+
GET_CURRENT_PROGRAM_NAME = 0x11
|
11
|
+
|
12
|
+
def initialize(interface, name=nil)
|
13
|
+
@interface = interface
|
14
|
+
@name = name
|
15
|
+
end
|
16
|
+
|
17
|
+
def start
|
18
|
+
self.class.start(@interface, @name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def stop
|
22
|
+
self.class.stop(@interface)
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
class << self
|
27
|
+
|
28
|
+
def start(interface, name)
|
29
|
+
response = send_command(interface, START_PROGRAM, name)
|
30
|
+
|
31
|
+
unless response[:status] == NXT::Errors::SUCCESS
|
32
|
+
message = "#{response[:message]}; Try using '.rxe' as the filename extension"
|
33
|
+
raise NXT::Exceptions::CommandError.new message
|
34
|
+
end
|
35
|
+
|
36
|
+
response
|
37
|
+
end
|
38
|
+
|
39
|
+
def stop(interface)
|
40
|
+
send_command(interface, STOP_PROGRAM)
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_running_name(interface)
|
44
|
+
response = send_command(interface, GET_CURRENT_PROGRAM_NAME)
|
45
|
+
raise NXT::Exceptions::CommandError.new(response[:message]) if response[:status] != NXT::Errors::SUCCESS
|
46
|
+
convert_data_to_string(response[:data])
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def send_command(interface, command, name=nil)
|
51
|
+
|
52
|
+
array = [@@command_type, command]
|
53
|
+
array.concat convert_string_to_data(name) unless name.nil?
|
54
|
+
|
55
|
+
response = interface.send_and_receive(array)
|
56
|
+
end
|
57
|
+
|
58
|
+
def convert_data_to_string(data)
|
59
|
+
data.pack("C*").strip
|
60
|
+
end
|
61
|
+
|
62
|
+
def convert_string_to_data(name, max_length=20)
|
63
|
+
name.ljust(max_length, "\0").unpack("C*")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module NXT
|
2
|
+
module Connector
|
3
|
+
module Base
|
4
|
+
SENSOR_TYPES = {}
|
5
|
+
[:no_sensor,
|
6
|
+
:switch,
|
7
|
+
:temperature,
|
8
|
+
:reflection,
|
9
|
+
:angle,
|
10
|
+
:light_active,
|
11
|
+
:light_inactive,
|
12
|
+
:sound_db,
|
13
|
+
:sound_dba,
|
14
|
+
:custom,
|
15
|
+
:lowspeed,
|
16
|
+
:lowspeed_9v,
|
17
|
+
:highspeed,
|
18
|
+
:colorfull,
|
19
|
+
:colorred,
|
20
|
+
:colorgreen,
|
21
|
+
:colorblue,
|
22
|
+
:colornone
|
23
|
+
].each_with_index do |key, index|
|
24
|
+
SENSOR_TYPES[key] = index
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_input_mode(interface, type, mode)
|
28
|
+
raise "Invalid sensor type: #{mode}" if !mode.nil? && !SENSOR_TYPES.include?(mode)
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -2,9 +2,28 @@ module NXT
|
|
2
2
|
module Connector
|
3
3
|
module Input
|
4
4
|
class Color
|
5
|
-
|
5
|
+
include NXT::Command::Input
|
6
|
+
|
7
|
+
attr_accessor :port, :interface
|
8
|
+
|
9
|
+
COLORS = {
|
10
|
+
:off => :colornone,
|
11
|
+
:red => :colorred,
|
12
|
+
:green => :colorgreen,
|
13
|
+
:blue => :colorblue,
|
14
|
+
:all => :colorfull
|
15
|
+
}
|
16
|
+
def initialize(port, interface)
|
17
|
+
@interface = interface
|
6
18
|
@port = port
|
7
19
|
end
|
20
|
+
|
21
|
+
def set_color(color)
|
22
|
+
raise "Invalid color #{color}" unless COLORS.include?(color)
|
23
|
+
|
24
|
+
set_input_mode(COLORS[color], :booleanmode)
|
25
|
+
|
26
|
+
end
|
8
27
|
end
|
9
28
|
end
|
10
29
|
end
|
@@ -13,10 +13,12 @@ module NXT
|
|
13
13
|
|
14
14
|
attr_combined_accessor :duration, 0
|
15
15
|
attr_combined_accessor :duration_type, :seconds
|
16
|
-
attr_combined_accessor :duration_after, :
|
16
|
+
attr_combined_accessor :duration_after, :brake
|
17
17
|
attr_combined_accessor :direction, :forwards
|
18
18
|
|
19
|
-
attr_setter :direction,
|
19
|
+
attr_setter :direction, is_in: DIRECTION
|
20
|
+
attr_setter :duration_after, is_in: DURATION_AFTER
|
21
|
+
attr_setter :duration_type, is_in: DURATION_TYPE
|
20
22
|
|
21
23
|
def initialize(port, interface)
|
22
24
|
@port = port
|
@@ -27,39 +29,11 @@ module NXT
|
|
27
29
|
raise TypeError.new('Expected duration to be a number') unless duration.is_a?(Integer)
|
28
30
|
@duration = duration
|
29
31
|
|
30
|
-
if options.include?(:type)
|
31
|
-
type = options[:type]
|
32
|
-
|
33
|
-
unless DURATION_TYPE.include?(type)
|
34
|
-
raise TypeError.new("Expected duration type to be one of: :#{DURATION_TYPE.join(', :')}")
|
35
|
-
end
|
36
|
-
|
37
|
-
@duration_type = type
|
38
|
-
else
|
39
|
-
@duration_type = :seconds
|
40
|
-
end
|
32
|
+
self.duration_type = options[:type] if options.include?(:type)
|
41
33
|
|
42
34
|
if options.include?(:after)
|
43
|
-
if
|
44
|
-
|
45
|
-
|
46
|
-
unless DURATION_AFTER.include?(after)
|
47
|
-
raise TypeError.new("Expected after option to be one of: :#{DURATION_AFTER.join(', :')}")
|
48
|
-
end
|
49
|
-
|
50
|
-
@duration_after = after
|
51
|
-
else
|
52
|
-
raise TypeError.new('The after option is only available when the unit duration is in seconds.')
|
53
|
-
end
|
54
|
-
else
|
55
|
-
@duration_after = :stop
|
56
|
-
end
|
57
|
-
|
58
|
-
case @duration_type
|
59
|
-
when :rotations
|
60
|
-
self.tacho_limit = @duration * 360
|
61
|
-
when :degrees
|
62
|
-
self.tacho_limit = @duration
|
35
|
+
raise TypeError.new('The after option is only available when the unit duration is in seconds.') if self.duration_type != :seconds
|
36
|
+
self.duration_after = options[:after]
|
63
37
|
end
|
64
38
|
|
65
39
|
self
|
@@ -84,13 +58,9 @@ module NXT
|
|
84
58
|
|
85
59
|
# takes block for response, or can return the response instead.
|
86
60
|
def move
|
87
|
-
response_required =
|
88
|
-
|
89
|
-
if self.duration > 0 && self.duration_type != :seconds
|
90
|
-
response_required = true
|
91
|
-
end
|
61
|
+
response_required = (self.duration > 0 && self.duration_type != :seconds)
|
92
62
|
|
93
|
-
|
63
|
+
set_motor_output_state(response_required)
|
94
64
|
|
95
65
|
if self.duration > 0 && self.duration_type == :seconds
|
96
66
|
sleep(self.duration)
|
@@ -110,16 +80,34 @@ module NXT
|
|
110
80
|
self.run_state = :running
|
111
81
|
self.tacho_limit = 0
|
112
82
|
end
|
113
|
-
end
|
114
83
|
|
115
|
-
# overrides
|
116
|
-
def set_output_state(response_required=true)
|
117
|
-
original_power = self.power
|
118
|
-
self.power *= -1 if self.direction == :backwards
|
119
84
|
|
120
|
-
|
85
|
+
private
|
86
|
+
def set_motor_output_state(response_required=true)
|
87
|
+
original_tacho_limit = self.tacho_limit
|
88
|
+
adjust_tacho_limit
|
89
|
+
|
90
|
+
original_power = self.power
|
91
|
+
adjust_power
|
92
|
+
|
93
|
+
set_output_state(response_required)
|
94
|
+
|
95
|
+
self.power = original_power
|
96
|
+
self.tacho_limit = original_tacho_limit
|
97
|
+
end
|
121
98
|
|
122
|
-
|
99
|
+
def adjust_tacho_limit
|
100
|
+
case self.duration_type
|
101
|
+
when :rotations
|
102
|
+
self.tacho_limit = self.duration * 360
|
103
|
+
when :degrees
|
104
|
+
self.tacho_limit = self.duration
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def adjust_power
|
109
|
+
self.power *= -1 if self.direction == :backwards
|
110
|
+
end
|
123
111
|
end
|
124
112
|
end
|
125
113
|
end
|
data/lib/nxt/errors.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module NXT
|
2
|
+
module Errors
|
3
|
+
SUCCESS = 0x00
|
4
|
+
CODES = {
|
5
|
+
SUCCESS => 'Success',
|
6
|
+
0x20 => 'Pending communication transaction in progress',
|
7
|
+
0x40 => 'Specified mailbox queue is empty',
|
8
|
+
0xBD => 'Request failed (i.e., specified file not found)',
|
9
|
+
0xBE => 'Unknown command opcode',
|
10
|
+
0xBF => 'Insane packet',
|
11
|
+
0xC0 => 'Data contains out-of-range values',
|
12
|
+
0xDD => 'Communication bus error',
|
13
|
+
0xDE => 'No free memory in communication buffer',
|
14
|
+
0xDF => 'Specified channel/connection is not valid',
|
15
|
+
0xE0 => 'Specified channel/connection not configured or busy',
|
16
|
+
0xEC => 'No active program',
|
17
|
+
0xED => 'Illegal size specified',
|
18
|
+
0xEE => 'Illegal mailbox queue ID specified',
|
19
|
+
0xEF => 'Attempted to access invalid field of a structure',
|
20
|
+
0xF0 => 'Bad input or output specified',
|
21
|
+
0xFB => 'Insufficient memory available',
|
22
|
+
0xFF => 'Bad arguments'
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
data/lib/nxt/exceptions.rb
CHANGED
data/lib/nxt/interfaces/base.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
require_relative '../commands/base' #TODO: bad code smell here
|
2
|
+
|
1
3
|
module NXT
|
2
4
|
module Interface
|
3
5
|
class Base
|
4
6
|
def send_and_receive(msg, response_required = true)
|
5
7
|
if response_required
|
6
|
-
msg[0] = msg[0] | (response_required ?
|
8
|
+
msg[0] = msg[0] | (response_required ? 0x00 : 0x80)
|
7
9
|
end
|
8
10
|
|
9
11
|
self.send(msg)
|
@@ -69,7 +69,19 @@ module NXT
|
|
69
69
|
#
|
70
70
|
# Reference: Appendix 1, Page 22
|
71
71
|
length = @connection.sysread(2)
|
72
|
-
|
72
|
+
actual_length = length.unpack('v')[0]
|
73
|
+
response_bytes = @connection.sysread(actual_length)
|
74
|
+
response_array = response_bytes.unpack('C*')
|
75
|
+
response = {
|
76
|
+
:reply => response_array[0] == 0x02,
|
77
|
+
:for_command => response_array[1],
|
78
|
+
:status => response_array[2]
|
79
|
+
}
|
80
|
+
response[:message] = NXT::Errors::CODES[response[:status]]
|
81
|
+
response[:for_command_name] = NXT::Command::Base::COMMANDS[response[:for_command]]
|
82
|
+
response[:data] = response_array[3..-1] if response_array.size > 3
|
83
|
+
|
84
|
+
response
|
73
85
|
end
|
74
86
|
end
|
75
87
|
end
|
data/lib/nxt/nxt_brick.rb
CHANGED
@@ -146,6 +146,18 @@ class NXTBrick
|
|
146
146
|
end
|
147
147
|
end
|
148
148
|
|
149
|
+
def start_program(name)
|
150
|
+
NXT::Command::Output::Program.start(self.interface, name)
|
151
|
+
end
|
152
|
+
|
153
|
+
def stop_program
|
154
|
+
NXT::Command::Output::Program.stop(self.interface)
|
155
|
+
end
|
156
|
+
|
157
|
+
def running_program_name
|
158
|
+
NXT::Command::Output::Program.get_running_name(self.interface)
|
159
|
+
end
|
160
|
+
|
149
161
|
private
|
150
162
|
def validate_interface(interface_type_name_string)
|
151
163
|
unless NXT::Interface.constants.include?(interface_type_name_string.to_sym)
|
data/lib/nxt/utils/accessors.rb
CHANGED
@@ -4,11 +4,15 @@ module NXT
|
|
4
4
|
def attr_setter(name, options)
|
5
5
|
define_method("#{name}=") do |value|
|
6
6
|
if options.include?(:is)
|
7
|
-
raise TypeError.new('Expected value to be a
|
7
|
+
raise TypeError.new('Expected value to be a #{options[:is]}') unless duration.is_a?(options[:is])
|
8
8
|
end
|
9
9
|
|
10
|
-
if options.include?(:
|
11
|
-
raise TypeError.new("Expected value to be one of:
|
10
|
+
if options.include?(:is_in)
|
11
|
+
raise TypeError.new("Expected value to be one of: #{options[:is_in].join(', ')}") unless options[:is_in].include?(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
if options.include?(:is_key_in)
|
15
|
+
raise TypeError.new("Expected value to be one of: :#{options[:is_key_in].keys.join(', :')}") unless options[:is_key_in].include?(value)
|
12
16
|
end
|
13
17
|
|
14
18
|
instance_variable_set("@#{name}", value)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NXT::Connector::Output::Motor do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
NXT::Connector::Output::Motor.new(nil, nil)
|
7
|
+
end
|
8
|
+
|
9
|
+
context '#duration' do
|
10
|
+
# TODO: Should be OK to use any number, but documenting current behavior
|
11
|
+
it 'should not allow a non-Integer duration' do
|
12
|
+
expect do
|
13
|
+
subject.duration(0.5)
|
14
|
+
end.to raise_exception(TypeError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should allow valid type options' do
|
18
|
+
subject.duration(1, :type => :rotations)
|
19
|
+
subject.duration(1, :type => :seconds)
|
20
|
+
subject.duration(1, :type => :degrees)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should not allow invalid type option' do
|
24
|
+
expect do
|
25
|
+
subject.duration(1, :type => :incorrect_duration_after_type)
|
26
|
+
end.to raise_exception(TypeError)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should default to seconds as the duration unit' do
|
30
|
+
subject.duration(1)
|
31
|
+
|
32
|
+
subject.duration_type.should == :seconds
|
33
|
+
end
|
34
|
+
|
35
|
+
context "setting the :after option" do
|
36
|
+
# TODO: This isn't right...should change this
|
37
|
+
# but I'm just documenting current behavior
|
38
|
+
it 'should prevent using the :after option unless duration_type is :seconds' do
|
39
|
+
expect do
|
40
|
+
subject.duration(1, :type => :rotations, :after => :coast)
|
41
|
+
end.to raise_exception(TypeError)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should allow using the :afer option when the duration type is :seconds' do
|
45
|
+
subject.duration(1, :type => :seconds, :after => :coast)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should not allow setting an invalid value' do
|
49
|
+
expect do
|
50
|
+
subject.duration(1, :type => :seconds, :after => :foobar)
|
51
|
+
end.to raise_exception(TypeError)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nxt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-03-
|
13
|
+
date: 2013-03-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: serialport
|
@@ -124,7 +124,7 @@ dependencies:
|
|
124
124
|
- - ~>
|
125
125
|
- !ruby/object:Gem::Version
|
126
126
|
version: 2.1.0
|
127
|
-
description: Control an NXT 2.0 See http://github.com/
|
127
|
+
description: Control an NXT 2.0 See http://github.com/tchype/ruby-nxt for more information.
|
128
128
|
email: tony@heupel.org
|
129
129
|
executables: []
|
130
130
|
extensions: []
|
@@ -139,10 +139,12 @@ files:
|
|
139
139
|
- lib/nxt/commands/program.rb
|
140
140
|
- lib/nxt/commands/sound.rb
|
141
141
|
- lib/nxt/commands/tone.rb
|
142
|
+
- lib/nxt/connectors/base.rb
|
142
143
|
- lib/nxt/connectors/input/color.rb
|
143
144
|
- lib/nxt/connectors/input/touch.rb
|
144
145
|
- lib/nxt/connectors/input/ultrasonic.rb
|
145
146
|
- lib/nxt/connectors/output/motor.rb
|
147
|
+
- lib/nxt/errors.rb
|
146
148
|
- lib/nxt/exceptions.rb
|
147
149
|
- lib/nxt/interfaces/base.rb
|
148
150
|
- lib/nxt/interfaces/serial_port.rb
|
@@ -153,10 +155,11 @@ files:
|
|
153
155
|
- lib/nxt/utils/accessors.rb
|
154
156
|
- lib/nxt.rb
|
155
157
|
- spec/matchers.rb
|
158
|
+
- spec/nxt/connectors/output/motor_spec.rb
|
156
159
|
- spec/nxt/interfaces/serial_port_spec.rb
|
157
160
|
- spec/nxt/nxt_brick_spec.rb
|
158
161
|
- spec/spec_helper.rb
|
159
|
-
homepage: http://github.com/tchype/nxt
|
162
|
+
homepage: http://github.com/tchype/ruby-nxt
|
160
163
|
licenses: []
|
161
164
|
post_install_message:
|
162
165
|
rdoc_options: []
|