Hardware: I/O and Sensors
|
Hardware: I/O and Sensors
This section covers the classes for user input and output, and also the standard NXT
sensors. The NXT hardware has buttons for input, a Liquid
Crystal Display (LCD) and a small speaker for output. leJOS NXJ
provides software abstractions for all these bits of hardware.
LCD
The LCD class has no instances (there being only one LCD on the NXT), so all the methods are static.
It can be used in text mode and graphics mode.
LCD Text methods
As a text display, the NXT LCD screen is 16 characters wide and eight characters deep. It is addressed using (x, y) co-ordinates as follows:
x ranges from 0 to 15, and y from 0 to 7.
The methods to write to the LCD in text mode are :-
void drawString(String str, int x, int y) This draws a string of text to the LCD screen starting at text co-ordinate (x, y).
void drawInt(int i, int x, int y)
This draws an integer starting at text co-ordinate (x,y).The integer is left aligned and takes up as many characters as are necessary.
void drawInt(int i, int places, int x, int y)
This variant of drawInt right-aligns the integer and always uses the number of characters indicated by places.
This means that it always writes to a fixed number of character places and, if used in a loop, the previous value will always be fully overwritten.
void clear() Clears the display.
Example:
import lejos.nxt.*;
import java.io.*;
public class LCDTest {
public static void main(String[] args) throws Exception {
LCD.drawString("Free RAM:", 0, 0);
LCD.drawInt((int) System.getRuntime().freeMemory(), 6, 9, 0);
Thread.sleep(2000);
}
}
Note that you can also write to the LCD display with System.out.println(String str). This scrolls the display up one line
and writes to the bottom line of the screen.
Note, also, that by default, the LCD display is refreshed automatically. If you want to control when the LCD is refreshed,
you can call LCD.setAutoRefresh(0) to turn off auto-refreshing and call LCD.refresh() when you want to refresh the display.
Back to top
LCD Graphics methods
As a graphics display, the NXT LCD screen is 100 pixels wide and 64 pixels deep.
It is addressed using (x, y) pixel co-ordinates in the same way as for text co-ordinates:
x ranges from 0 to 99, and y from 0 to 63.
To display graphics on the LCD screen, you can use the Graphics class from the package javax.microedition.lcdui.
See the Graphics class API.
With this class, you can draw lines, rectangles, arcs, and position strings with pixel accuracy.
Example:
import javax.microedition.lcdui.Graphics;
public class GraphicsSample {
public static void main(String [] options) throws Exception {
Graphics g = new Graphics();
g.drawLine(5,5,60,60);
g.drawRect(62, 10, 25, 35);
Thread.sleep(2000);
}
}
There is a set of methods in the LCD class to write to the screen using pixel co-ordinates.
These are mainly there to support the Graphics class, but can be called directly:
void drawString(String str,int x, int y, boolean invert)
This variant of drawString uses pixel co-ordinates and supports inverting the text drawing white characters on a black background.
void drawChar(char c, int x, int y, boolean invert)
This draws a character at text co-ordinate (x, y) with optional inversion of the character.
void setPixel(int rgbColor, int x, int y) Set or unset the pixel at (x,y). rgbColor=1 sets the pixel and zero unsets it.
Back to top
Buttons
The Button class has four instances, accessed by static fields:
- Button.ENTER
- Button.ESCAPE
- Button.LEFT
- Button.RIGHT
To test if a button is pressed, you use:
Example:
import lejos.nxt.*;
public class ButtonPresses {
public static void main(String[] args) throws Exception {
while (true) {
LCD.clear();
if (Button.ENTER.isPressed()) LCD.drawString("ENTER", 0, 0);
if (Button.ESCAPE.isPressed()) LCD.drawString("ESCAPE", 0, 0);
if (Button.LEFT.isPressed()) LCD.drawString("LEFT", 0, 0);
if (Button.RIGHT.isPressed()) LCD.drawString("RIGHT", 0, 0);
}
}
}
To wait for a specific button to be pressed and released, you use:
Example:
import lejos.nxt.*;
public class ButtonTest
{
public static void main (String[] args)
throws Exception
{
Button.ENTER.waitForPressAndRelease();
LCD.drawString("Finished", 3, 4);
Thread.sleep(2000);
}
}
To wait for any button to be pressed, you use:
button
ENTER LEFT
RIGHT ESCAPE
Code
1
2
4 8
To specify a listener to listen for button events for this button, you: use
To read the current state of all the buttons, you use:
Back to top
Sound
This class controls the single speaker so it has no instances and all the methods are static.
To play a single tone, use
Example:
import lejos.nxt.*;
public class PlayTones {
private static final short [] note = {2349,115, 0,5, 1760,165, 0,35};
public static void main(String [] args) throws Exception {
for(int i=0;i <note.length; i+=2) {
short w = note[i+1];
int n = note[i];
if (n != 0) Sound.playTone(n, w*10);
Thread.sleep(w*10);
}
}
}
There are two ways to play system sounds. One is:
void systemSound (boolean aQueued, int aCode)
The aQueued parameter is ignored on the NXT, it is here to be backwards compatible with the RXC.
The values of code are:
code = 0 Short beep
code = 1 Double beep
code = 2 Descending arpeggio
code = 3 Ascending arpeggio
code = 4 Long, low buzz
Individual methods to play a particular system sound, if you don’t remember the code, are
There is also a method to produce a rest when playing a tune; time in milliseconds
leJOS NXJ has methods that can also play 8-bit WAV files:
The return value of milliseconds the sample will play for or < 0 if there is an error.
To play a musical note, use:
void playNote(int[] inst,int freq, int len)
The inst array contains the attack,
decay, sustain and release parameters for the note. The
static constants for some predefined instruments are: FLUTE,
PIANO and XYLOPHONE. You can also experiment with defining you own.
Back to top
Battery
There are two static methods to get the battery voltage:
Example:
import lejos.nxt.*;
public class BatteryTest {
public static void main(String[] args) throws Exception {
LCD.drawString("Battery: " + Battery.getVoltage(), 0, 0);
Thread.sleep(2000);
}
}
Back to top
Sensors
The NXT comes with four sensors; the touch sensor, the sound sensor, the light
sensor and the ultrasonic sensor. leJOS NXJ provides software
abstractions of all these sensor types, as well as many provided
by third parties.
A physical sensor must be connected to a port, and the sensor object must
know which port this is. To provide this information, you
create an instance of the sensor, and pass this information in its
constructor. The possibilities are: SensorPort.S1, S2, S3 or
S4.
Touch Sensor
To use a touch sensor, you create an instance of it, using the constructor:
To test if the touch sensor is pressed, you use the isPressed() method:
Example:
import lejos.nxt.*;
public class TouchTest {
public static void main(String[] args) throws Exception {
TouchSensor touch = new TouchSensor(SensorPort.S1);
while (!touch.isPressed() ;
LCD.drawString("Finished", 3, 4);
}
}
Back to top
Light Sensor
To use a light sensor, you create an instance of it using the constructor:
Example:
import lejos.nxt.*;
public class LightTest {
public static void main(String[] args) throws Exception {
LightSensor light = new LightSensor(SensorPort.S1);
while (true) {
LCD.drawInt(light.readValue(), 4, 0, 0);
LCD.drawInt(light.readNormalizedValue(), 4, 0, 1);
LCD.drawInt(SensorPort.S1.readRawValue(), 4, 0, 2);
LCD.drawInt(SensorPort.S1.readValue(), 4, 0, 3);
}
}
}
Back to top
Sound Sensor
The sound sensor supports two modes: DB and DBA. These modes
give different frequency response, so that it may be
possible to get an idea of the frequency of a sound by switching
between modes.
There are two constructors:
SoundSensor(SensorPort port) creates a sound sensor using DB mode.
SoundSensor(SensorPort port, dba) creates a sound sensor using DBA mode if the second parameter is true.
You can switch modes with:
Example using DB mode only:
The above example gives a graphical display of the way the sound reading varies over a two-second period.
import lejos.nxt.*;
public class SoundScope {
public static void main(String[] args) throws Exception {
SoundSensor sound = new SoundSensor(SensorPort.S1);
while (!Button.ESCAPE.isPressed()) {
LCD.clear();
for (int i = 0; i < 100; i++) {
LCD.setPixel(1, i, 60 - (sound.readValue() / 2));
Thread.sleep(20);
}
}
}
}
Back to top
Ultrasonic Sensor
To create an instance, use the constructor:
The sensor operates in two modes, continuous (defalt) and ping. When in
continuous mode the sensor sends out pings as often as it can and
the most recently obtained result is available via a call to
Example:
import lejos.nxt.*;
public class SonicTest {
public static void main(String[] args) throws Exception {
UltrasonicSensor sonic = new UltrasonicSensor(SensorPort.S1);
while (!Button.ESCAPE.isPressed()) {
LCD.clear();
LCD.drawString(sonic.getVersion(), 0, 0);
LCD.drawString(sonic.getProductID(), 0, 1);
LCD.drawString(sonic.getSensorType(), 0, 2);
LCD.drawInt(sonic.getDistance(), 0, 3);
}
}
}
When in ping mode, a ping is sent only when a call is made to
void ping() This sets the sensor in ping mode and sends a
single ping and up to 8 echoes are captured. These may be
read by making a call to
int readDistances(int [] distances)
You provide an integer
array of length that contains the data after the method returns.
A delay of approximately 20ms is required between the call to
ping and getDistances. This delay is not included in the method.
Calls to getDistances before this period may result in an error
or no data being returned. The normal getDistance call may also
be used with ping, returning information for the first echo.
Calling ping() will disable the default
continuous mode. Toto switch back to continuous mode, call
int continuous()
Program: multiple echoes
Write a program that displays the distances from multiple echoes in a
column. The program should make four calls to ping(), and display
the four columns of results, then wait for a button press.
Exit if the ESCAPE button was pressed.
Solution
Back to top
|
|