|
C CODE (MCU)
- stm.c
JAVA CODE (PC)
- CmdInterp.java
- Draw.java
- Message.java
- SerialTalk.java
- TokenReader.java
|
|
|
|
/* ECE 476 Spring 2002 Final Project
* Scanning Tunneling Microscope MCU Software
* Sunarni Maulan
* Engin Ipek
* Cornell University
*/
#include <Mega163.h>
#include <stdio.h>
#include <Math.h>
#include <delay.h>
#define begin {
#define end }
void init(void);
void cal(void);//calibration & scanning function
void scan(void);
bit r_ready; //signal ready, receive buffer is full
unsigned char r_buffer[2]; //receive buffer
unsigned char r_char, r_index; //character received and the index
unsigned char z, x, y, r, a, vbias; //specification received from PC
unsigned char stepy, stepx, countx ; //current steps
unsigned char vx, vy, vinc; //digital voltage
unsigned char i;
//data read from ADC
int Ain, avg;
float bias;
float v1, v2, c, h; //calibration variables
float vz, vstep;
float Vref, Aref; //voltage reference of DAC and ADC
//**********************************************************
//Entry point and task scheduler loop
void main(void)
begin
//Initialize
init();
stepmax = 60*Vref; //min step
stepmin = stepmax/256;
//Usual endless loop
while(1)
begin
//Interpreting the command received from PC
if(r_ready)
begin
r_ready=0;
if (r_buffer[0] == 'z') z = r_buffer[1];
if (r_buffer[0] == 'x') x = r_buffer[1];
if (r_buffer[0] == 'y') y = r_buffer[1];
if (r_buffer[0] == 'r') r = r_buffer[1];
if (r_buffer[0] == 'a') a = r_buffer[1];
if (r_buffer[0] == 'b') vbias = r_buffer[1];
if (r_buffer[0] == 'c') cal();
if (r_buffer[0] == 's') scan();
end
end
end
//**********************************************************
//UART character-ready ISR
interrupt [UART_RXC] void uart_rec(void)
begin
r_char = UDR; //get the commancd
r_buffer[r_index] = r_char; //put in buffer
if (r_index == 0) r_index = 1;
else
begin
r_index = 0;//reinitialize index
r_ready = 1;//signal ready
end
end
//**********************************************************
//UART_TXC ISR
interrupt [UART_TXC] void uart_tra(void)
begin
vx = vx + vinc; //increment vx
PORTB = vx; //send vx to DAC
UCSRB.6 = 0; //disable TXC interrupt
end
//**********************************************************
//ADC ISR
interrupt [ADC_INT] void adc_done(void)
begin
Ain = ADCH; //Read input from ADC
end
//**********************************************************
//Calibration
void cal(void)
begin
//set vbias
bias = (float)vbias;
bias = (bias/Vref)*256;
vbias = (unsigned char) bias;
PORTB = vbias;
//Take two measurements at different point
//to find the value of constant c.
//The sleep statment lowers digital noise
//and starts the A/D conversion
//Take 1st measurement
#asm
sleep
#endasm
putchar('m');
putchar(Ain);
delay_us(2000);
v1 = (float)avg ;
v1 = (v1/256)*Aref ; //(fraction of full scale)*Aref
//increase z by h
vz = h/60; //1V = 60nm
vz = (vz/Vref) * 256;
//PORTC = (unsigned char)vz;
//Take 2nd measurement
#asm
sleep
#endasm
putchar('n');
putchar(avg);
v2 = (float)avg ;
v2 = (v2/256)*Aref ; //(fraction of full scale)*Aref
c = log(v1/v2);
c = c/h; //h or z??
//Back to original position
PORTC = 0x00;
//calibration done
//send done signal to PC
putchar('c');
putchar('d');
end
//**********************************************************
//Scan
void scan(void)
begin
//set Vz
diff = z - d;
vz = diff/60; //1V = 300nm
vz= (vz/Vref) * 256;
PORTC = (unsigned char)vz; //float --> char ??*/
//count steps -- 1 step = r nm
stepx = x/r;
stepy = y/r;
countx = stepx;
vinc = r;
PORTB = 0;
PORTC = 0;
//start scanning
while (stepy-- > 0)
begin
while (stepx-- > 0)
begin
//Averaging is off
if (a == 0)
begin
#asm
sleep
#endasm
UCSRB.6 = 1; //enable TXC interrupt
putchar(Ain); //send data to PC
delay_us(2000);
end
//Averaging is on
else
begin
//Take 'a' measurement and compute the average
for (i = 0; i < a; i++)
begin
delay_us(2000);
#asm
sleep
#endasm
avg = avg + Ain;
end
avg = avg/a;
UCSRB.6 = 1; //enable TXC interrupt
putchar(avg); //send data to PC
end
end
stepx = countx; //recover stepx
vx = 0; //reset vx
PORTB = vx;
vy = vy + vinc; //increment vy
PORTC = vy;
end
vy = 0;
//return to initial position
PORTC = 0;
PORTB = 0;
end
//**********************************************************
//Initialize
void init(void)
begin
DDRA = 0x00; //input port : ADC
DDRB = 0xff; //output port : Vbias, Vx
DDRC = 0xff; //output port : Vz, Vy
DDRD = 0x00; //input UART
//Initialize output PORT
PORTC = 0;
PORTB = 0;
//Set UART
UCSRB = 0x10 + 0x08 + 0x80;//enable RXC interrupt
UBRR = 51; //baud rate for 8MHz
//init the A to D converter
//channel zero/ left adj /int Aref
ADMUX = 0b11100000;
//enable ADC and set prescaler to 1/64*8MHz=125,000
//and set int enable
ADCSR = 0x80 + 0x06 + 0x08;
MCUCR = 0b01010000; //enable sleep and choose ADC mode
//Initialize variables
r_index = 0;
r_ready = 0;
h = 0.03;
dir = 0;
vx = 0;
vy = 0;
vinc = 1;
//check Vref & Aref, then change accordingly
Aref = 5.0;
Vref = 5.0;
#asm
sei
#endasm
end
|
|
JAVA CODE
|
|
i) Interprets command
package stmcontroller;
/**
* Title: STM Controller Software
* Description: Handles communication to MCU and receives data
* Copyright: Copyright (c) 2002
* Company: Cornell University
* @author Engin Ipek
* @version 1.0
**/
import javax.comm.*;
import java.util.*;
import javax.comm.*;
import java.io.*;
//Commad interpretor Class
public class CmdInterp {
//Messages for communicating to the MCU
public static byte[] xscan = {(byte)'x',(byte)0};
public static byte[] yscan = {(byte)'y',(byte)0};
public static byte[] zheight = {(byte)'z',(byte)0};
public static byte[] resolution = {(byte)'r',(byte)0};
public static byte[] sampleBias = {(byte)'b',(byte)0};
public static byte[] startCal = {(byte)'c',(byte)'a'};
public static byte[] startScan= {(byte)'s',(byte)'c'};
public static byte[] numAverages = {(byte)'a',(byte)0};
public static boolean beginCal = false;
public static boolean beginScan = false;
public static String fileName = "";
public static Draw topology;
public static int xrange = 0;
public static int yrange = 0;
public static int stepsize = 0;
public CmdInterp() {
}
//**********************************************************
public static void main(String[] args) {
TokenReader in = new TokenReader(System.in);
//Create new GUI
topology = new Draw();
//Initialize communication to the MCU
SerialTalk S= new SerialTalk();
//Read commands
S.readCmd();
//Wait until user starts calibration
while(!beginCal){}
System.out.println("CAL BEGAN");
//Transmit user specified parameters
S.write(xscan);
S.write(yscan);
S.write(zheight);
S.write(resolution);
S.write(sampleBias);
S.write(numAverages);
S.write(startCal);
//Wait for calibratio to end
while(!S.calDone){}
System.out.println("CAL DONE");
//Wait until userstarts scan
while(!beginScan){}
//Start reading data
S.readData(xrange/stepsize, yrange/stepsize);
S.write(startScan);
System.out.println("SCAN BEGAN");
while(!S.scanDone){}
System.out.println("SCAN DONE");
FileOutputStream out; // declare a file output object
PrintStream p; // declare a print stream object
try{
// Create a new file output stream
// connected to "myfile.txt"
out = new FileOutputStream(fileName);
// Connect print stream to the output stream
p = new PrintStream(out);
//Write the results to the file
for(int xIndex = 0; xIndex < SerialTalk.lengthX; xIndex++){
for(int yIndex = 0; yIndex < SerialTalk.lengthY; yIndex++){
p.print (SerialTalk.dataArray[xIndex][yIndex]+" ");
if(yIndex ==SerialTalk.lengthY-1) p.println("");
}
}
//Close the file
p.close();
}
catch (Exception e){
System.err.println ("Error writing to file");
}
}
}
//**********************************************************
|
|
ii) Makes GUI and real time plotting
package stmcontroller;
/**
* Title: STM Controller Software
* Description: Handles communication to MCU and receives data
* Copyright: Copyright (c) 2002
* Company: Cornell University
* @author Engin Ipek
* @version 1.0
**/
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Draw extends Frame{
public static Panel mk;
public static int numRows = 40;
public static int numCols = 40;
Panel x;
Label xScan = new Label("X Range (nm) :");
Label yScan = new Label("Y Range (nm) :");
Label zHeight = new Label("Tip Height (nm) :");
Label resolution = new Label("Stepsize (nm) :");
Label sampleBias = new Label("Sample Bias (V):");
Label fileName = new Label(" Output File :");
Label numAvg = new Label("Number of averages per data point");
TextField xScanTxt = new TextField(10);
TextField yScanTxt = new TextField(10);
TextField zHeightTxt = new TextField(10);
TextField resolutionTxt = new TextField(10);
TextField sampleBiasTxt = new TextField(10);
TextField fileNameTxt = new TextField(10);
TextField numAvgTxt = new TextField(10);
Button StartCal = new Button("Start Calibration");
Button StartScan = new Button("Start Scan");
CheckboxGroup cbg = new CheckboxGroup();
Checkbox avgOn = new Checkbox("Averaging On", cbg, false);
Checkbox avgOff = new Checkbox("Averaging Off", cbg, true);
Label[][] GridLabel;
Panel Grids;
//make the grid for real-time imaging
public Panel MakeGrid(int rows, int cols){
GridLabel = new Label[rows][cols];
Panel GRIDS = new Panel(new BorderLayout(5, 5));
Grids = new Panel(new GridLayout(rows, cols, 1, 1));
Panel Index = new Panel(new GridLayout(1,cols));
for(int i =0; i < cols; i++){
String s = i + " ";
Index.add(new Label(s));
}
for (int i=0; i < rows; i++){
for( int j=0; j < cols; j++){
GridLabel[i][j] = new Label();
}
}
for(int i=rows-1; i>=0; i--){
for (int j=0; j<cols;j++){
Grids.add(GridLabel[i][j]);
}
}
//GRIDS.add(Index,BorderLayout.NORTH);
GRIDS.add(Grids,BorderLayout.CENTER);
return GRIDS;
}
//Create the GUI
public Draw(){
x=new Panel(new GridLayout(10,1));
Panel x1 = new Panel();
Panel x2 = new Panel();
Panel x3 = new Panel();
Panel x4 = new Panel();
Panel x5 = new Panel();
Panel x6 = new Panel();
Panel x7 = new Panel();
Panel x8 = new Panel();
Panel x9 = new Panel();
Panel x10 = new Panel();
Panel x11 = new Panel();
x9.setLayout(new GridLayout(2, 1));
x10.setLayout(new GridLayout(2, 1));
x.setForeground(Color.black);
x.setBackground(Color.lightGray);
x1.add(xScan);
x1.add(xScanTxt);
x2.add(yScan);
x2.add(yScanTxt);
x3.add(zHeight);
x3.add(zHeightTxt);
x4.add(resolution);
x4.add(resolutionTxt);
x5.add(sampleBias);
x5.add(sampleBiasTxt);
x6.add(fileName);
x6.add(fileNameTxt);
x7.add(StartCal);
x7.add(StartScan);
x9.add(avgOn);
x9.add(avgOff);
x10.add(numAvg);
x10.add(numAvgTxt);
x11.add(x9);
x11.add(x10);
x.add(x1);
x.add(x2);
x.add(x3);
x.add(x4);
x.add(x5);
x.add(x6);
x.add(x11);
x.add(x7);
setLayout(new GridLayout(1,2));
this.setSize(1000,500);
this.setResizable(false);
add(x);
mk = MakeGrid(40,40/*numRows,numCols*/);
add(/*MakeGrid(40,40)*/mk);
// GridLabel[1][1].setBackground(Color.blue);
//repaint();
addListeners();
setVisible(true);
}
public void addListeners(){
StartCal.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
CmdInterp.xrange = Integer.parseInt(xScanTxt.getText());
CmdInterp.yrange = Integer.parseInt(yScanTxt.getText());
CmdInterp.xscan[1] = (byte) CmdInterp.xrange;
CmdInterp.yscan[1] = (byte) CmdInterp.yrange;
CmdInterp.zheight[1] = (byte) Integer.parseInt(zHeightTxt.getText());
CmdInterp.stepsize = Integer.parseInt(resolutionTxt.getText());
CmdInterp.resolution[1] = (byte) CmdInterp.stepsize;
CmdInterp.sampleBias[1] = (byte) Integer.parseInt(sampleBiasTxt.getText());
CmdInterp.fileName = fileNameTxt.getText();
if(avgOn.getState())
CmdInterp.numAverages[1] = (byte) Integer.parseInt(numAvgTxt.getText());
else
CmdInterp.numAverages[1] = 0;
CmdInterp.beginCal = true;
}
});
StartScan.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
CmdInterp.beginScan = true;
}
});
}
}
//**********************************************************
|
|
iii) Creates message for user
package stmcontroller;
/**
* Title: STM Controller Software
* Description: Handles communication to MCU and receives data
* Copyright: Copyright (c) 2002
* Company: Cornell University
* @author Engin Ipek
* @version 1.0
**/
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Message extends Frame{
Panel x;
Label Message;
//Send message to user for calibration
public Message(double voltage){
x=new Panel();
Message = new Label("Please adjust Vref to: " + voltage + " and hit StartScan");
x.setForeground(Color.black);
x.setBackground(Color.lightGray);
x.add(Message);
this.setSize(500,500);
this.setResizable(false);
add(x);
setVisible(false);
}
}
//**********************************************************
|
|
iv) Receives data from the MCU
package stmcontroller;
import java.io.*;
import java.util.*;
import javax.comm.*;
import java.awt.*;
//Serial Communication Class for Reading/Writing
public class SerialTalk implements SerialPortEventListener, Runnable {
static CommPortIdentifier portId;
private static final int DATA = 1;
private static final int CMD = 2;
private static int TYPE = 0;
private static int dataIndexX = 0;
private static int dataIndexY = 0;
private static int cmdIndex = 0;
public static int lengthX = 0;
public static int lengthY = 0;
public int k = 0;
public int c = 0;
public int measure1 = 0;
public int measure2 = 0;
public int measure3 = 0;
public boolean scanDone = false;
public boolean calDone = false;
OutputStream outputStream;
InputStream inputStream;
SerialPort serialPort;
Thread readCmdThread, readDataThread;
int[] cmdArray = new int[2];
public static int[][] dataArray;
public SerialTalk() {
//get the port identifier for COM1
try{portId = CommPortIdentifier.getPortIdentifier("COM1");}
catch(NoSuchPortException e){}
//Open a serial port connection at COM1
try {
serialPort = (SerialPort) portId.open("SimpleReadApp2", 7000);
} catch (PortInUseException e) {}
//Get the output stream for this connection
try {
outputStream = serialPort.getOutputStream();
} catch (IOException e) {}
//Get the input stream
try {
inputStream = serialPort.getInputStream();
} catch (IOException e) {}
//Initialize RS232 parameters
try {
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {}
readCmdThread = new Thread(this);
readDataThread = new Thread(this);
}
//Read commands sent by MCU
public void readCmd(){
cmdIndex = 0;
serialPort.removeEventListener();
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {}
serialPort.notifyOnDataAvailable(true);
TYPE = CMD;
readCmdThread.stop();
readDataThread.stop();
readCmdThread.start();
}
//Read data sent by MCU
public void readData(int numStepsX, int numStepsY){
dataIndexX = 0;
dataIndexY = 0;
serialPort.removeEventListener();
dataArray = new int[numStepsX][numStepsY];
lengthX = numStepsX;
lengthY = numStepsY;
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {}
serialPort.notifyOnDataAvailable(true);
TYPE = DATA;
readCmdThread.stop();
readDataThread.stop();
readDataThread.start();
}
//Process the commands/data sent by MCU
public void serialEvent(SerialPortEvent event) {
switch(event.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
//Process commands
if (TYPE == CMD){
try {
while (inputStream.available() > 0) {
cmdArray[cmdIndex] = (byte) inputStream.read();
// System.out.println("COMMAND:" + cmdArray[cmdIndex]);
if(cmdIndex == 0)
cmdIndex = 1;
else if (cmdIndex == 1){
cmdIndex = 0;
switch(cmdArray[0]){
case (byte)'m':
measure1 = cmdArray[1];
System.out.println("m received:"+ measure1);
break;
case (byte)'n':
measure2 = cmdArray[1];
System.out.println("n received:"+ measure1);
break;
case (byte)'p':
measure3 = cmdArray[1];
System.out.println("p received:"+ measure1);
break;
case (byte)'c':
//System.out.println("Caldone");
calDone = true;
final Message M = new Message(CmdInterp.xrange*0.017);
M.setVisible(true);
break;
// case (byte)'s':
// scanDone = true;
//break;
}
}
}
} catch (IOException e) {}
}
//Process data
else if (TYPE == DATA){
try {
while (inputStream.available() > 0) {
System.out.println("P");
dataArray[dataIndexX][dataIndexY] = inputStream.read();
int currentPoint = dataArray[dataIndexX][dataIndexY];
if((dataIndexX == lengthX-1) &(dataIndexY == lengthY - 1))
scanDone = true;
if((currentPoint >= 0) & (currentPoint<50))
CmdInterp.topology.GridLabel[dataIndexX][dataIndexY].setBackground(Color.black);
else if((currentPoint > 50) & (currentPoint<100))
CmdInterp.topology.GridLabel[dataIndexX][dataIndexY].setBackground(Color.darkGray);
else if((currentPoint > 100) & (currentPoint<150))
CmdInterp.topology.GridLabel[dataIndexX][dataIndexY].setBackground(Color.gray);
else if((currentPoint > 150) & (currentPoint<200))
CmdInterp.topology.GridLabel[dataIndexX][dataIndexY].setBackground(Color.lightGray);
else if((currentPoint > 200) & (currentPoint<=256))
CmdInterp.topology.GridLabel[dataIndexX][dataIndexY].setBackground(Color.white);
CmdInterp.topology.repaint();
if(dataIndexX == lengthX-1) {
dataIndexX = 0;
dataIndexY++;
}
else
dataIndexX++;
//System.out.println((char)dataArray[dataIndex]);
}
} catch (IOException e) {}
}
break;
}
}
public void run() {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {}
}
public void write(byte[] message){
try {
outputStream.write(message);
} catch (IOException e) {}
}
}
//**********************************************************
|
|
v) Token Reader
package stmcontroller;
// Simple text input class for Cornell CS
// H. Perkins 7/97, 8/97, 1/98, 6/98
// File input constructor added by M Godfrey, 1/98
// Inspired by an idea in J. Bishop "Java Gently", A-W, 1997.
import java.io.*;
import java.util.*;
class TokenReader {
// Simple text input from keyboard and files. Input is parsed into tokens separated
// by whitespace. Tokens are returned as either int, double, or String values depending
// on the input method. If an int or double is requested and the next token is not a
// properly formatted integer or floating-point number, an error message is written to
// the console (actually System.err) and the method will repeatedly read tokens until
// one with the proper format is read.
//
// Here is an example of the use of this class by a client:
//
// TokenReader in = new TokenReader(System.in);
//
// int k = in.readInt();
// double d = in.readDouble();
// String s = in.readString();
// String t = in.readLine();
//
// The identifiers s, d, k, and in are arbitrary. Also, note that function readLine()
// discards any unused input on the current line and returns the next input line
// as a single string.
//
// TokenReader input does not throw any IOExceptions. To detect the end of the stream,
// function eof is provided. The expression
//
// in.eof()
//
// evaluates to true if the end of stream in has been encountered, false otherwise.
// Example:
//
// k = in.readInt();
// while (!in.eof()) {
//
// k = in.readInt();
// }
//
// If an attempt is made to read past the end of the stream, an error message is
// written to System.err and the input function evaluates to an unspecified result.
//
// Finally, the operation
//
// in.waitUntilEnter();
//
// prints a message on the screen and then reads and discards a line of input. It can
// be used to pause execution to, for example, ensure that the console window remains
// visible until the user chooses to terminate the program (a problem with the Windows
// console window).
//
// Class TokenReader can be used to read any InputStream, not just System.in. Use the
// desired stream as the parameter in the "new TokenReader(...)" allocation.
//
// Technical note: TokenReader is not derived from InputStream or any other stream class
// because it does not provide the normal interface of a java.io input stream.
// Local state
private DataInputStream theStream; // the stream being read
private boolean eofReached = false; // = "end of theStream has been encountered"
private String S; // current input line
private StringTokenizer T; // parser for current input line
// T==null means no more available tokens
// on this line (including when eofReached).
// Constructors: a TokenReader object for input stream s or ds. (The second constructor
// is provided to reduce overhead if the desired stream is already a DataInputStream.)
public TokenReader(InputStream s)
{
theStream = new DataInputStream(s);
}
public TokenReader(DataInputStream ds)
{
theStream = ds;
}
// Constructor: a TokenReader object connected to file fileName.
public TokenReader(String fileName) {
try {
FileInputStream fis = new FileInputStream (fileName);
theStream = new DataInputStream(fis);
} catch (FileNotFoundException e) {
System.err.println ("Sorry, couldn't find file " + fileName
+ " for some reason.");
}
}
// Yield next integer from stream.
// If the next token is not an integer, print an error message on System.err and
// continue reading input until an integer is read.
// If the end of the file is encountered before finding an integer, the smallest
// integer Integer.MIN_VALUE is returned.
public int readInt ()
{
String item = ""; // next token as a string
if (T == null)
refresh();
while (true) {
if (eofReached)
return Integer.MIN_VALUE;
try {
item = T.nextToken();
return Integer.parseInt(item.trim());
}
catch (NoSuchElementException e) {
refresh();
}
catch (NumberFormatException e) {
System.err.println("Integer expected but input was \"" + item + "\". Please try again.");
}
}
}
// Yield next double from stream.
// If the next token is not a double, print an error message on System.err and
// continue reading input until a floating-point number is read.
// If the end of the file is encountered before finding an double, a NaN is returned.
public double readDouble ()
{
String item = ""; // next token as a string
if (T == null)
refresh();
while (true) {
if (eofReached)
return Double.NaN;
try {
item = T.nextToken();
return Double.valueOf(item.trim()).doubleValue();
}
catch (NoSuchElementException e) {
refresh();
}
catch (NumberFormatException e) {
System.err.println("Double expected but input was \"" + item + "\". Please try again.");
}
}
}
// Yield next string from stream or an appropriate error message if
// attempting to read past eof.
public String readString ()
{
if (T == null)
refresh();
while (true) {
if (eofReached)
return "readString called after reaching end of TokenReader stream.";
try {
return T.nextToken();
}
catch (NoSuchElementException e) {
refresh();
}
}
}
// Yield the next input line from stream as a single string or an
// appropriate error message if attempting to read past eof.
// Unused input remaining in the current line is discarded.
public String readLine ()
{
refresh();
if (eofReached)
return "readLine called after reaching end of TokenReader stream.";
// return new line and mark current line as fully read
String line = S;
T = null;
return line;
}
// Yield "end of stream has been reached" (i.e. no more data)
public boolean eof()
{
return eofReached;
}
// Write prompt to output, then wait until user enters an input line
public void waitUntilEnter()
{
System.out.println();
System.out.println("Press Enter to continue.");
try {
theStream.read();
} catch (java.io.IOException e) {}
}
// Read next input line into S and initialize tokenizer T to parse it.
// Print appropriate error messages to System.err if attempting to read
// past end of stream or some other I/O error occurs.
private void refresh ()
{
// print error message and return if eof already encountered.
if (eofReached) {
System.err.println("Attempt to read past end of TokenReader stream.");
return;
}
// read next line into S and T
try {
S = theStream.readLine();
}
catch (EOFException e) {
eofReached = true;
T = null;
return;
}
catch (IOException e) {
System.err.println("Unexpected error reading TokenReader input.\nIOException: " + e);
return;
}
if (S == null) {
eofReached = true;
T = null;
} else
T = new StringTokenizer(S);
}
} // end of class TokenReader
|
|
|