RCXLink class 1.2 for REALbasic

By Guillermo Zaballa
I work in a software development company. You can check out our web pages (in spanish)
Check out our Macintosh resources web page:
MacBang!

Download RCXLink 1.2 (you may need StuffIt Expander 6 to decompress this file)

Please send any comments and bug reports by email


The following information is also available in the Read me file, packed in the stuffit archive.

RCXLink
is a freeware REALbasic class that allows the operation of Lego Mindstorms RCX brick using REALbasic. RCXLink is not for programming the RCX, for this task you can use the RIS software included with Mindstorm (for Windows) or the excellent NQC language by Dave Baum <http://www.enteract.com/~dbaum/nqc/index.html>.

To use this class you need the Lego Mindstorms Robotics Invention System and a serial port adapter to connect the Lego IR tower to your Macintosh. You can build an adapter from the DB-9 IR connector to the mini-DIN mac connector, see the FAQ section at the NQC web page <http://www.enteract.com/~dbaum/nqc/faq.html>.

Also it's neccesary you download the firmware to the RCX brick, the firmware is included in the Mindstorms CD. If you don't have a Windows machine (or Virtual PC) you can download the software using NQC.

It's possible to make very cool things by creating two programs to cooperate, one built in REALbasic and another one in NQC.

RCXLink class is implemented as a subclass of the RB serial control, to use, drag the class to a window, give it a name and use this name to access the control properties and methods.

I included a sample RB program to show you the use of the class.

Following, here's a list of the methods and properties of the class:

Properties:

lastError as integer
reportErrors as boolean

Methods:

Serial port:
Connect(serialPort as integer)
Disconnect
Alive() as boolean

Motors control:
SetMotorState(motors as string, state as string)
SetMotorPower motors as string, powerlevel as integer
SetMotorDirection(motors as string, direction as string)

Sensors:
SetSensorType(sensor as integer, type as string)
GetSensor(sensor as integer) as integer
GetSensorRaw(sensor as integer)as boolean
GetSensorBool(sensor as integer) as boolean
ClearSensorValue(sensor as integer)

RCX settings and info:
GetBatteryPower() as integer
GetProgramNumber() as integer
PowerOff
SetDisplay(mode as string)
SetTransmitterRange(range as integer)
SetTime(hours as integer, minutes as integer)
SetPowerDownDelay(minutes as integer)

Tasks:
StartTask(task as integer)
StopTask(task as integer)
StopAllTasks

Timers:
SetTimer(timer as integer, value as integer)
GetTimer(timer as integer) as integer
ClearTimer(timer as integer) as integer

Sounds:
PlaySound(sound as integer)
PlayTone(frequency as integer, duration as integer)

Misc:
SendMessage(message as integer)
SetVariable(varNumber as integer, value as integer)
GetVariable(varNumber as integer) as integer
UploadDatalog( byref datalog() as string)

The rest of the document, describes each method and properties, in all the examples I assume the control is named "RCX".

Properties:

lastError:integer
Contains the last error code, 0 means no error.

The error codes are:

1 "I can't open the serial port."
2 "The serial port is not open."
3 "Incorrect answer for the IR Tower (No echo)"
4 "The IR Tower is not responding."
5 "The RCX is not responding"
6 "Incorrect header from the RCX."
7 "Timeout waiting answer from the RCX."
8 "Invalid sensor type."
9 "Invalid sensor number."
10 "Invalid mode for setDisplay"
11 "Invalid variable number (The valid numbers are 0...31)"
12 "Invalid task number (The valid numbers are 0...9)"
13 "Invalid transmitter range (The valid range are 0...1)"
14 "Invalid program number (The valid range are 1...5)"
15 "Invalid sound number (The valid range are 0...5)"
16 "Invalid timer number (The valid range are 0...3)"

Example:

if RCX.lastError<>0 then
msgBox "Error number "+str(lastError)
end if

reportErrors:boolean
If true the class puts a dialog with the error message after each error.

Example:

RCX.reportErrors=true


Methods:

Connect(serialPort as integer)
serialPort-integer : 0 = Modem port, 1=Printer port

Open the serial port.

Example:

RCX.connect 0 // Connect using the modem port
if RCX.lastError<>0 then
msgBox "I can't open the serial port"
end if

Disconnect
Closes the serial port connection.

Example:

RCX.Disconnect


Alive() as boolean
Returns true if the IR Tower is responding AND the RCX is responding, false otherwise.

example:

if not RCX.alive then
msgBox "The RCX is not responding"
end if


SetMotorState(motors as string, state as string)
motors: string - The affected motors, example "AC"
state - The state "ON" turns on the motors, "OFF" turns off the motors, "FLOAT" puts the motors in float state

Changes the state of one ore more motors.

example:

RCX.SetMotorState "AC","On" // Turns on the motors connected to the A and C outputs.

SetMotorDirection(motors as string, direction as string)
motors: string - The affected motors, example "AC"
direction: string - The direction, the allowed values are "forward","reverse" or "flip"

Changes the direction of one or more motors.

example:

RCX.SetMotorState "AC","Forward" // Sets the direction of motors A and C to forward

SetMotorPower(motors as string, powerlevel as integer)
motors: string - The affected motors, example "AC"
direction: string - The power level of the motors, is a number from 0 to 7

Sets the power of the motors.

example:

RCX.SetMotorState "AC",6 // Sets power of motors A and C to 6

SetSensorType(sensor as integer type as string)
sensor: integer - The sensor number (1 to 3)
type: string - The type of the sensor RAW,TOUCH,TEMPERATURE,LIGHT,ROTATION

example
RCX.SetSensorType 1,"TOUCH" // There is a touch sensor in input 1


GetSensor(sensor as integer) as integer
sensor: integer - The sensor number (1 to 3)

This function returns the value of a sensor.

example:
// This program turns the motors A and C on in forward direction and waits
// for the sensor 1 to become pressed.

rcx.setSensorType(1,"touch")
rcx.SetMotorDirection("AC","forward")
rcx.SetMotorState("AC","on")
while rcx.GetSensor(1)>500
wend
rcx.SetMotorState("AC","off")


GetSensorBool(sensor as integer) as boolean

sensor: integer - The sensor number (1 to 3)

This function returns the boolean value of a sensor.

example:
while not rcx.GetSensorBool(1)
wend

GetSensorRaw(sensor as integer)as boolean

sensor: integer - The sensor number (1 to 3)

This function returns the raw value of a sensor (a integer from 0 to 1024).

example:
while not rcx.GetSensorRaw(1)<500
wend

ClearSensorValue(sensor as integer)
sensor: integer - The sensor number (1 to 3)

Resets the sensor internal counter, for example with rotatory sensors.

example:
rcx.ClearSensorValue(1)

GetBatteryPower() as integer

Returns the battery power of the RCX in milivolts.

example:
dim volts as integer
volts = rcx.GetBatteryPower(1)

GetProgramNumber() as integer

Returns the current program number (1 to 5) of the RCX.

SetProgramNumber(programNumber as integer) as integer
programNumber: integer - The program number (1 to 5).

Sets the current program number (1 to 5) of the RCX.

PowerOff()

Turns off the RCX

SetDisplay(mode as string)
mode:string - The display mode, allowed values are "motor a","motor b","motor c","sensor 1","sensor 2","sensor 3","watch"

Changes the mode of the LCD display in the RCX, equivalent to use the "View" button in the RCX.

SetTransmitterRange( range as integer)
Range: integer - 0 = short range, 1 = long range

Sets the IR transmitter range of the RCX.

SetTime(hours as integer, minutes as integer)
hours: integer - The hour (0-23)
minutes: integer - The minutes (0-59)

Sets the time and minutes of the RCX internal clock.

SetPowerDownDelay (minutes as integer)
minutes: integer - The monutes (0-59)

Sets the delay for automatic power-down of the RCX, in minutes.

StartTask(task as integer)
task: the task number (0..9)

Starts a task for the current program in the RCX.

StopTask(task as integer)
task: the task number (0..9)

Stops a task in the RCX.

StopAllTasks()

Stops execution of the current program in the RCX.

GetTimer(timer as integer) as integer
timer: the timer number (0 - 3)

Gets the current value of a RCX timer.

ClearTimer(timer as integer) as integer
timer: the timer number (0 - 3)

Resets a RCX timer.

PlaySound (sound as integer)
soundNumber:integer - sound number (0 - 5)

Plays a sound in the RCX.

PlayTone(frequency as integer, duration as integer)
frequency - The sound frequency in Hz
duration - The sound duration 1/100 of second

Plays a tone in the RCX

SendMessage(message as integer)
message:integer - The message number (0..255)

Sends a message to the RCX.


SetVariable(varNumber as integer, value as integer)
varNumber:integer - The variable number (0..31)
value:integer - The value of the variable

Sets the value of a variable in the current program in the RCX. Can be used to communicate a RB program to a RCX program

The following example is a program in NQC and another in RB, the NQC program turns on the motors and waits the stop command from RB using the variable 0 to communicate.

example:
rcx.setVariable(0,1) // Set the variable 0 to 1

NQC example:

int realBasic; // The first variable is the number 0 variable

task main()
{
realBasic=0;
OnFwd(OUT_A + OUT_C);
until( realBasic==1 ); // Wait for realbasic to set the variable to 1
Off(OUT_A + OUT_C);
}

GetVariable(varNumber as integer) as integer
varNumber:integer - The variable number (0..31)

Gets the value of a RCX variable. Can be used to communicate with a RCX program.

UploadDatalog(byref datalog() as string)
datalog(): string array - returns the datalog in a string array

Each element of the array has the following format:
<source>,<value>

Source can be: Sensor n, Motor x or variable n, value is the datalog entry value.

Example: "sensor 1,1200"

You can use the nthField RB function to extract the source of the value

Example:
Dim datalog(0) as string
rcx.UploadDatalog( datalog )
msgbox "The source 1 is "+nthField( datalog(1),",",1)
msgbox "The value 1 is "+nthField( datalog(1),",",2)