nxt

package module
v0.0.0-...-9efa1cd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 27, 2015 License: MIT Imports: 3 Imported by: 0

README

NXT

A Go package for controlling Lego Mindstorms NXT 2.0

Installation

Either install it from the command-line:

$ go install github.com/tonyheupel/go-nxt

or add as a dependency in your code files:

import "github.com/tonyheupel/go-nxt"
$ go get

Usage

The most basic usage can be done using the NXT class by connecting your NXT 2.0 brick over Bluetooth.

There are two main ways to interact with an NXT instance:

  1. Traditional method calls on the NXT instance, checking for errors
  2. Interacting with the CommandChannel on the NXT directly.

Interacting with the channels gives you lower-level access and requires a little more work, but if you prefer using channels as your communication paradigm, it's there for you. The NXT commands are all defined as Command structs and can be passed around, so if you are managing multiple bots at once and want to issue the same command to multiple bots, this approach may make more sense.

The example below has one method that first uses the more traditional style interaction, and the second uses channels. They should produce the same output and have the same effect on the bot.

The brick is connected at /dev/tty.NXT-DevB.

package main

import (
	"fmt"
	"github.com/tonyheupel/go-nxt"
	"time"
)

func main() {
	n := nxt.NewNXT("heupel-home-bot", "/dev/tty.NXT-DevB")

	fmt.Println(n)
	err := n.Connect()

	if err != nil {
		fmt.Println("Could not connect:", err)
		return
	}

	fmt.Println("Connected!")

	// Use a more traditional-looking method/check-for-error style
	methodStyle(n)

	// Pause in between styles to ensure the old commands are done executing
	time.Sleep(2 * time.Second)

	// Use the raw channels style
	channelStyle(n)

	n.Disconnect()
}

func methodStyle(n *nxt.NXT) {
	// Normally use StartProgram but we want to see the name of the running program
	// so we need to wait
	startProgramReply, err := n.StartProgramSync("DREW.rxe")

	if err != nil {
		fmt.Println("Error starting a program:", err)
	}

	fmt.Println("Reply from StartProgram:", startProgramReply)

	runningProgram, err := n.GetCurrentProgramName()

	if err != nil {
		fmt.Println("Error getting current program name:", err)
	} else {
		fmt.Println("Current running program:", runningProgram)
	}

	time.Sleep(3 * time.Second) // Wait 3 seconds before trying to stop

	fmt.Println("Stopping running program...")
	_, err = n.StopProgramSync()

	if err != nil {
		fmt.Println("Error stopping the running program:", err)
	}

	batteryMillivolts, err := n.GetBatteryLevelMillivolts()

	if err != nil {
		fmt.Println("Error getting the battery level:", err)
	} else {
		fmt.Println("Battery level (mv):", batteryMillivolts)
	}
}

func channelStyle(n *nxt.NXT) {
	// All reply messages will be sent to this channel
	reply := make(chan *nxt.ReplyTelegram)

	// Normally would pass in nil for the reply channel and not wait,
	//but we want to see the name of the running program so we need to wait
	n.CommandChannel <- nxt.StartProgram("DREW.rxe", reply)
	fmt.Println("Reply from StartProgram:", <-reply)

	n.CommandChannel <- nxt.GetCurrentProgramName(reply)
	runningProgramReply := nxt.ParseGetCurrentProgramNameReply(<-reply)
	fmt.Println("Current running program:", runningProgramReply.Filename)

	time.Sleep(3 * time.Second) // Wait 3 seconds before trying to stop

	fmt.Println("Stopping running program...")
	n.CommandChannel <- nxt.StopProgram(reply)

	stopProgramReply := <-reply

	if stopProgramReply.IsSuccess() {
		fmt.Println("Stopped running program successfully!")
	} else {
		fmt.Println("Was unable to stop the program.")
	}

	n.CommandChannel <- nxt.GetBatteryLevel(reply)
	batteryLevelReply := nxt.ParseGetBatteryLevelReply(<-reply)

	if batteryLevelReply.IsSuccess() {
		fmt.Println("Battery level (mv):", batteryLevelReply.BatteryLevelMillivolts)
	} else {
		fmt.Println("Was unable to get the current battery level")
	}
}

Documentation

Overview

Package nxt provides tools to allow one to control a Lego Mindstorms NXT 2.0.

Index

Constants

View Source
const (
	Success                                   ReplyStatus = 0x00
	PendingCommunicationTransactionInProgress             = 0x20
	SpecifiedMailboxQueueIsEmpty                          = 0x40
	RequestFailed                                         = 0xBD
	UnknownCommandOpcode                                  = 0xBE
	InsanePacket                                          = 0xBF
	DataContainsOutOfRangeValues                          = 0xC0
	CommunicationBusError                                 = 0xDD
	NoFreeMemoryInCommunicationBuffer                     = 0xDE
	SpecifiedConnectionIsNotValid                         = 0xDF
	SpecifiedConnectionIsNotConfiguredOrBusy              = 0xE0
	NoActiveProgram                                       = 0xEC
	IllegalSizeSpecified                                  = 0xED
	IllegalMailboxQueueIDSpecified                        = 0xEE
	AttemptedToAccessInvalidFieldOfStructure              = 0xEF
	BadInputOrOutputSpecified                             = 0xF0
	InsufficientMemoryAvailable                           = 0xFB
	BadArguments                                          = 0xFF
)
View Source
const (
	DirectRequiresResponse CommandType = 0x00
	SystemRequiresResponse             = 0x01
	Reply                              = 0x02
	DirectNoResponse                   = 0x80
	SystemNoResponse                   = 0x81
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Command

type Command struct {
	Telegram     *Telegram
	ReplyChannel chan *ReplyTelegram
}

Command represents a command that is sent to the NXT and the optional reply. The ReplyChannel is the channel that the NXT should send the reply to.

func GetBatteryLevel

func GetBatteryLevel(replyChannel chan *ReplyTelegram) *Command

GetBatteryLevel creates a command that can be sent to the NXT to retrieve the battery level on the device, represented in millivolts.

func GetCurrentProgramName

func GetCurrentProgramName(replyChannel chan *ReplyTelegram) *Command

GetCurrentProgramName creates a Command to get the currently running program name. The filename will be passed on the message of the reply to this command.

func NewDirectCommand

func NewDirectCommand(command CommandCode, message []byte, replyChannel chan *ReplyTelegram) *Command

NewDirectCommand creates a Command that can be sent to the NXT. To wait for a reply, pass in a replyChannel value; to not wait for a reply, pass in nil for the replyChannel argument. Direct commands are the most typical commands that are sent to the NXT.

func NewSystemCommand

func NewSystemCommand(command CommandCode, message []byte, replyChannel chan *ReplyTelegram) *Command

NewSystemCommand creates a Command that can be sent to the NXT. To wait for a reply, pass in a replyChannel value; to not wait for a reply, pass in nil for the replyChannel argument. System commands are not usually the most typical commands sent to the NXT.

func PlaySoundFile

func PlaySoundFile(filename string, loop bool, replyChannel chan *ReplyTelegram) *Command

PlaySoundFile creates a Command to play a sound file given a filename and whether it should loop or not. NOTE: The NXT will so the filename without a file extension. If playing that file does not work, try adding ".rso" as the extension for sound files. To wait for the reply, pass in a replyChannel; to not wait, pass in nil for the replyChannel.

func PlayTone

func PlayTone(frequency int, duration int, replyChannel chan *ReplyTelegram) *Command

PlayTone plays a tone with the Hz specified in frequency and for the duration of duration milliseconds. To wait for the reply, pass in a replyChannel; to not wait, pass in nil for the replyChannel.

func StartProgram

func StartProgram(filename string, replyChannel chan *ReplyTelegram) *Command

StartProgram creates a Command to start a program with the filename passed in. NOTE: If the filename on the device does NOT have a file extension but just has a name, you should add ".rxe" to the end of the filename. To wait for the reply, pass in a replyChannel; to not wait, pass in nil for the replyChannel.

func StopProgram

func StopProgram(replyChannel chan *ReplyTelegram) *Command

StopProgram creates a Command to stop a running program. To wait for the reply, pass in a replyChannel; to not wait, pass in nil for the replyChannel.

func StopSoundPlayback

func StopSoundPlayback(replyChannel chan *ReplyTelegram) *Command

StopSoundPlayback tells the NXT to stop playing whatever sound is currently playing.

type CommandCode

type CommandCode byte

CommandCode is the code used to represent the command to send to the NXT in a Telegram.

type CommandType

type CommandType byte

CommandType represents the different type of telegrams that can be sent to the NXT.

func (CommandType) String

func (c CommandType) String() string

type Connection

type Connection interface {
	io.ReadWriteCloser
	Port() string
	Open() error
}

Connection represents a connection to a port that can be manipulated using an io.ReadWriteCloser.

func NewMockConnection

func NewMockConnection(devicePort string) Connection

type GetBatteryLevelReply

type GetBatteryLevelReply struct {
	*ReplyTelegram
	BatteryLevelMillivolts int
}

GetBatteryLevelReply is the reply telegram for the GetBatteryLevel command. The battery level is accessed via the BatteryLevelMillivolts member.

func ParseGetBatteryLevelReply

func ParseGetBatteryLevelReply(reply *ReplyTelegram) *GetBatteryLevelReply

ParseGetBatteryLevelReply takes a raw ReplyTelegram and converts it to a GetBatteryLevelReply.

type GetCurrentProgramNameReply

type GetCurrentProgramNameReply struct {
	*ReplyTelegram
	Filename string
}

GetCurrentProgramNameReply represent the reply to the GetCurrentProgramName call. The name of the running program can be accessed via the Filename member.

func ParseGetCurrentProgramNameReply

func ParseGetCurrentProgramNameReply(reply *ReplyTelegram) *GetCurrentProgramNameReply

ParseGetCurrentProgramNameReply takes a raw ReplyTelegram and returns a GetCurrentProgramNameReply.

type NXT

type NXT struct {
	CommandChannel chan *Command
	// contains filtered or unexported fields
}

NXT represents the thing that a caller interacts with to control an NXT brick.

func NewNXT

func NewNXT(name string, port string) *NXT

NewNXT creates a new NXT with the given name and will connect to the brick over Bluetooth using the serial port specified at the port argument.

func NewNXTUsingConnection

func NewNXTUsingConnection(name string, port string, connection Connection) *NXT

NewNXTUsingConnection creates a new NXT with the given name and a connection that implements the Connection interface. This method is good for testing when passing in a test double for the connection.

func (*NXT) Connect

func (n *NXT) Connect() error

Connect connects the NXT to the port and makes the NXT ready to receive commands.

func (*NXT) Disconnect

func (n *NXT) Disconnect() (err error)

Disconnect closes the connection to the port and

func (NXT) GetBatteryLevelMillivolts

func (n NXT) GetBatteryLevelMillivolts() (int, error)

GetBatteryLevelMillivolts gets the battery level of the NXT device, represented in millivolts.

func (NXT) GetCurrentProgramName

func (n NXT) GetCurrentProgramName() (string, error)

GetCurrentProgramName gets the currently running program on the NXT. If there was a problem getting the program name (usually because no program is running), it will return a non-nil error.

func (NXT) Name

func (n NXT) Name() string

Name returns the friendly name of the NXT.

func (NXT) PlaySoundFile

func (n NXT) PlaySoundFile(filename string, loop bool)

PlaySoundFile plays the sound file with the given filename and loops the file if true is passed in for loop; does not loop if false is passed in. NOTE: The NXT will so the filename without a file extension. If playing that file does not work, try adding ".rso" as the extension for sound files. This call is asynchronous and does not wait for a reply. To wait for a reply to see if the call is successful, use PlayToneSync.

func (NXT) PlaySoundFileSync

func (n NXT) PlaySoundFileSync(filename string, loop bool) (*ReplyTelegram, error)

PlaySoundFileSync plays the sound file with the given filename and loops the file if true is passed in for loop; does not loop if false is passed in. NOTE: The NXT will so the filename without a file extension. If playing that file does not work, try adding ".rso" as the extension for sound files. This call is snchronous waits for a reply. If there was a problem starting the program, it will return a non-nil error.

func (NXT) PlayTone

func (n NXT) PlayTone(frequency int, duration int)

PlayTone plays a tone with the Hz specified in frequency and for the duration of duration milliseconds. This call is asynchronous and does not wait for a reply. To wait for a reply to see if the call is successful, use PlayToneSync

func (NXT) PlayToneSync

func (n NXT) PlayToneSync(frequency int, duration int) (*ReplyTelegram, error)

PlayToneSync plays a tone with the Hz specified in frequency and for the duration of duration milliseconds. This call is snchronous waits for a reply. If there was a problem, it will return a non-nil error.

func (NXT) Port

func (n NXT) Port() string

Port returns the port that the NXT is to be connected to.

func (NXT) StartProgram

func (n NXT) StartProgram(filename string)

StartProgram starts a program on the NXT with the given filename. This call is asynchronous and does not wait for a reply. To wait for a reply to see if the call is successful, use StartProgramSync.

func (NXT) StartProgramSync

func (n NXT) StartProgramSync(filename string) (*ReplyTelegram, error)

StartProgramSync starts a program on the NXT with the given filename. This call is snchronous waits for a reply. If there was a problem starting the program, it will return a non-nil error.

func (NXT) StopProgram

func (n NXT) StopProgram()

StopProgram stops the currently running program on the NXT. This call is asynchronous and does not wait for a reply. To wait for a reply to see if the call is successful, use StopProgramSync.

func (NXT) StopProgramSync

func (n NXT) StopProgramSync() (*ReplyTelegram, error)

StopProgramSync stops the currently running program on the NXT. This call is snchronous waits for a reply. If there was a problem stopping the program (usually because no program is running), it will return a non-nil error.

func (NXT) StopSoundPlayback

func (n NXT) StopSoundPlayback()

StopSoundPlayback tells the NXT to stop playing whatever sound is currently playing. This call is asynchronous and does not wait for a reply. To wait for a reply to see if the call is successful, use PlayToneSync

func (NXT) StopSoundPlaybackSync

func (n NXT) StopSoundPlaybackSync() (*ReplyTelegram, error)

StopSoundPlaybackSync tells the NXT to stop playing whatever sound is currently playing. This call is snchronous waits for a reply. If there was a problem, it will return a non-nil error.

func (NXT) String

func (n NXT) String() string

type ReplyStatus

type ReplyStatus byte

ReplyStatus is the possible status codes returned as part of a ReplyTelegram's Status value.

func (ReplyStatus) String

func (rs ReplyStatus) String() string

type ReplyTelegram

type ReplyTelegram struct {
	*Telegram
	Status ReplyStatus
}

ReplyTelegram is the response to a command when the caller waits for the reply.

func NewReply

func NewReply(replyForCommand CommandCode, status ReplyStatus, message []byte) *ReplyTelegram

NewReply creates a new ReplyTelegram for the given command, status, and an optional reply message; pass nil if there is no reply message for the command.

func (ReplyTelegram) IsSuccess

func (r ReplyTelegram) IsSuccess() bool

IsSuccess returns true when the reply indicates a successful operation.

func (ReplyTelegram) String

func (r ReplyTelegram) String() string

String represents the ReplyTelegram as a string.

type Telegram

type Telegram struct {
	Type    CommandType
	Command CommandCode
	Message []byte
}

Telegram is the basic communication structure used to interact with the NXT.

func (Telegram) Bytes

func (t Telegram) Bytes() []byte

Bytes returns the slice of bytes that represents the Telegram in a format that can be understood by the NXT.

func (Telegram) IsResponseRequired

func (t Telegram) IsResponseRequired() bool

IsResponseRequired returns true when the Telegram is going to wait for the reply from the NXT. Only require a response when necessary, as it can add up to 60ms to the command time (per the NXT documentation).

func (Telegram) String

func (t Telegram) String() string

String represents the Telegram as a string.

Directories

Path Synopsis
samples
basic command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL