Skip to content
This repository
  • 9 commits
  • 13 files changed
  • 0 comments
  • 2 contributors
Apr 06, 2012
Christian Höltje Added development dependency on rake
It annoys me to no end that tools don't auto add this when
they add a Rakefile.
11ffcf1
Steve Klabnik steveklabnik Merge pull request #1 from docwhat/gemfile-rake
Added development dependency on rake
ca823aa
Apr 09, 2012
Christian Höltje Alrighty, we have working code!
This adds the Connection object.  It is very minimal at the moment.
The specs will actually cause your NXT brick to beep, if you have
it plugged in, powered up, and have the environment variable
'HAS_NXT' set to 'true'.

This is fully documented as well.
600648b
Christian Höltje Added travis support files 6a30949
Christian Höltje Added references cb8ecd2
Steve Klabnik steveklabnik Merge pull request #2 from docwhat/nxtcomm
Nxtcomm
aa72c47
Apr 10, 2012
Christian Höltje Renamed class constant to LegoNXT 1e81f94
Christian Höltje better handling for when NXT brick isn't there. a31690d
Christian Höltje Added check for return value on transmit
Renamed send_bits() to transmit(). I discovered
earlier that I couldn't name it .send()...
959239c
3  .rspec
... ... @@ -0,0 +1,3 @@
  1 +--colour
  2 +--format doc
  3 +--order rand
5 .travis.yml
... ... @@ -0,0 +1,5 @@
  1 +rvm:
  2 + - 1.8.7
  3 + - 1.9.2
  4 + - 1.9.3
  5 +script: "bundle exec rake spec"
6 .yardopts
... ... @@ -0,0 +1,6 @@
  1 +--protected
  2 +--no-private
  3 +--markup markdown
  4 +-
  5 +README.md
  6 +
6 Guardfile
... ... @@ -0,0 +1,6 @@
  1 +guard 'rspec', :version => 2 do
  2 + watch(%r{^spec/.+_spec\.rb$})
  3 + watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
  4 + watch('spec/spec_helper.rb') { "spec" }
  5 +end
  6 +
25 README.md
Source Rendered
... ... @@ -1,6 +1,8 @@
1 1 # LegoNxt
2 2
3   -TODO: Write a gem description
  3 +[![Build Status](https://secure.travis-ci.org/JumpstartLab/lego_nxt.png?branch=master)](http://travis-ci.org/JumpstartLab/lego_nxt)
  4 +
  5 +An object oriented interface for talking to the LEGO NXT brick.
4 6
5 7 ## Installation
6 8
@@ -20,6 +22,18 @@ Or install it yourself as:
20 22
21 23 TODO: Write usage instructions here
22 24
  25 +## Testing
  26 +
  27 +Most tests will work without owning a NXT brick
  28 +
  29 +To run all the tests, including the ones that require a NXT brick, then you need to
  30 +plugin your NXT brick, power it on, and set the environment variable `HAS_NXT` to
  31 +the value `true`.
  32 +
  33 +Example:
  34 +
  35 + env HAS_NXT=true rspec spec
  36 +
23 37 ## Contributing
24 38
25 39 1. Fork it
@@ -27,3 +41,12 @@ TODO: Write usage instructions here
27 41 3. Commit your changes (`git commit -am 'Added some feature'`)
28 42 4. Push to the branch (`git push origin my-new-feature`)
29 43 5. Create new Pull Request
  44 +
  45 +## Reference Material
  46 +
  47 +Useful if you're going to be hacking on the code:
  48 +
  49 +* [libusb](https://github.com/larskanis/libusb) - The [docs](http://rubydoc.info/gems/libusb/LIBUSB) in particular.
  50 +* [LEGO's Support Files](http://mindstorms.lego.com/en-us/support/files/default.aspx#Advanced) - In particular:
  51 + * The Bluetooth Developer Kit -- Appendix 1: LEGO MINDSTORMS NXT Communication protocol
  52 + * Software Development Kit -- The PDF contains a description of the Executable File Specification
7 Rakefile
... ... @@ -1,2 +1,9 @@
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 +
17 lego_nxt.gemspec
@@ -13,5 +13,20 @@ Gem::Specification.new do |gem|
13 13 gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14 14 gem.name = "lego_nxt"
15 15 gem.require_paths = ["lib"]
16   - gem.version = LegoNxt::VERSION
  16 + gem.version = LegoNXT::VERSION
  17 +
  18 + gem.add_runtime_dependency 'libusb', '~> 0.1.3'
  19 +
  20 + gem.add_development_dependency 'rake', '~> 0.9.2'
  21 +
  22 + # Testing framework
  23 + gem.add_development_dependency 'rspec', '~> 2.9.0'
  24 +
  25 + # Continous integration testing
  26 + gem.add_development_dependency 'guard', '~> 1.0.1'
  27 + gem.add_development_dependency 'guard-rspec', '~> 0.7.0'
  28 +
  29 + # Documentation
  30 + gem.add_development_dependency 'yard'
  31 + gem.add_development_dependency 'redcarpet'
17 32 end
4 lib/lego_nxt.rb
... ... @@ -1,3 +1,5 @@
1 1 require "lego_nxt/version"
2 2
3   -puts "coming soon..."
  3 +# {LegoNXT} is a library for working with the LEGO NXT bricks.
  4 +module LegoNXT
  5 +end
73 lib/lego_nxt/connection.rb
... ... @@ -0,0 +1,73 @@
  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 + #
  8 + # It's interface is very simple. Higher levels of abstractions provide
  9 + # access to opcodes, etc.
  10 + #
  11 + class Connection
  12 + # The USB idVendor code
  13 + LEGO_VENDOR_ID = 0x0694
  14 + # The USB idProduct code
  15 + NXT_PRODUCT_ID = 0x0002
  16 +
  17 + # The USB endpoint (communication channel) to send data out to the NXT brick
  18 + USB_ENDPOINT_OUT = 0x01
  19 +
  20 + # The USB endpoint (communication channel) to receive data from the NXT brick
  21 + USB_ENDPOINT_IN = 0x82
  22 +
  23 + # Creates a connection to the NXT brick.
  24 + #
  25 + def initialize
  26 + @mutex = Mutex.new
  27 + open
  28 + end
  29 +
  30 + # Sends a packed string of bits.
  31 + #
  32 + # Example:
  33 + #
  34 + # # Causes the brick to beep
  35 + # conn.send_bits [0x80, 0x03, 0xf4, 0x01, 0xf4, 0x01].pack('C*')'
  36 + #
  37 + # @see The LEGO MINDSTORMS NXT Communications Protocol (Appendex 1 of the Bluetooth Development Kit)
  38 + #
  39 + # @param {String} bits This must be a binary string. Use `Array#pack('C*')` to generate the string.
  40 + # @return [Boolean] Returns true if all the data was sent and received by the NXT.
  41 + def transmit bits
  42 + bytes_sent = @handle.bulk_transfer dataOut: bits, endpoint: USB_ENDPOINT_OUT
  43 + bytes_sent == bits.length
  44 + end
  45 +
  46 + # Closes the connection
  47 + #
  48 + # @return [nil]
  49 + def close
  50 + return if @handle.nil?
  51 + @handle.close
  52 + @handle = nil
  53 + end
  54 +
  55 +
  56 + private
  57 +
  58 + # Opens the connection
  59 + #
  60 + # This is triggered automatically by intantiating the object.
  61 + #
  62 + # @return [nil]
  63 + def open
  64 + @mutex.synchronize do
  65 + context = LIBUSB::Context.new
  66 + device = context.devices(:idVendor => LEGO_VENDOR_ID, :idProduct => NXT_PRODUCT_ID).first
  67 + raise NoDeviceError.new("Please make sure the device is plugged in and powered on") if device.nil?
  68 + @handle = device.open
  69 + @handle.claim_interface(0)
  70 + end
  71 + end
  72 + end
  73 +end
10 lib/lego_nxt/errors.rb
... ... @@ -0,0 +1,10 @@
  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 +end
3  lib/lego_nxt/version.rb
... ... @@ -1,3 +1,4 @@
1   -module LegoNxt
  1 +module LegoNXT
  2 + # The version of the LegoNXT code
2 3 VERSION = "0.0.1"
3 4 end
51 spec/lib/lego_nxt/connection_spec.rb
... ... @@ -0,0 +1,51 @@
  1 +require 'spec_helper'
  2 +require 'lego_nxt/connection'
  3 +
  4 +describe LegoNXT::Connection do
  5 + subject { LegoNXT::Connection.new }
  6 + after(:each) { HAS_NXT and subject.close }
  7 +
  8 + describe "#new" do
  9 + it "does something" do
  10 + needs_nxt do
  11 + LegoNXT::Connection.new.close
  12 + end
  13 + end
  14 +
  15 + it "works twice" do
  16 + needs_nxt do
  17 + LegoNXT::Connection.new.close
  18 + LegoNXT::Connection.new.close
  19 + end
  20 + end
  21 + end
  22 +
  23 + describe ".transmit" do
  24 + it "should beep" do
  25 + needs_nxt do
  26 + subject.transmit [0x80, 0x03, 0xf4, 0x01, 0xf4, 0x01].pack('C*')
  27 + end
  28 + end
  29 +
  30 + it "return success" do
  31 + needs_nxt do
  32 + subject.transmit([0x80, 0x03, 0xf4, 0x01, 0xf4, 0x01].pack('C*')).should be_true
  33 + end
  34 + end
  35 + end
  36 +
  37 + describe ".close" do
  38 + it "does something" do
  39 + needs_nxt do
  40 + subject.close
  41 + end
  42 + end
  43 +
  44 + it "can be called twice with no ill effects" do
  45 + needs_nxt do
  46 + subject.close
  47 + subject.close
  48 + end
  49 + end
  50 + end
  51 +end
15 spec/spec_helper.rb
... ... @@ -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

No commit comments for this range

Something went wrong with that request. Please try again.