Program: Penman Plotter

This program in Example 11-10 is an outgrowth of the Plotter class from Section 8.12. It connects to a Penman plotter. These serial-port plotters were made in the United Kingdom in the 1980s, so it is unlikely that you will meet one. However, there are several companies that still make pen plotters. See Figure 11-4 for a photograph of the plotter in action.

Penman plotter in action

Figure 11-4.  Penman plotter in action

Example 11-10. Penman.java

import java.io.*;
import javax.comm.*;
import java.util.*;

/**
 * A Plotter subclass for drawing on a Penman plotter.
 * These were made in the UK and sold into North American markets.
 * It is a little "turtle" style robot plotter that communicates
 * over a serial port. For this, we use the "Java Communications" API.
 * Java Communications is a "standard extension" and must be downloaded
 * and installed separately from the JDK before you can even compile this 
 * program.
 *
 */
public class Penman extends Plotter {
    private final String OK_PROMPT = "
!";
    private final int MAX_REPLY_BYTES = 50;    // paranoid upper bound
    private byte b, reply[] = new byte[22];
    private SerialPort tty;
    private DataInputStream is;
    private DataOutputStream os;

    /** Construct a Penman plotter object */
    public Penman(  ) throws NoSuchPortException,PortInUseException,
            IOException,UnsupportedCommOperationException {
        super(  );
        init_comm("COM2");        // setup serial commx
        init_plotter(  );        // set plotter to good state
    }

    private void init_plotter(  ) {
        send("I"); expect('!'),    // eat VERSION etc., up to !
        send("I"); expect('!'),    // wait for it!
        send("H");        // find home position
        expect('!'),    // wait for it!
        send("A");        // Set to use absolute coordinates
        expect('!'),
        curx = cury = 0;
        penUp(  );
    }

    //
    // PUBLIC DRAWING ROUTINES
    //

    public void setFont(String fName, int fSize) {
        // Font name is ignored for now...

        // Penman's size is in mm, fsize in points (inch/72).
        int size = (int)(fSize*25.4f/72);
        send("S"+size + ","); expect(OK_PROMPT);
        System.err.println("Font set request: " + fName + "/" + fSize);
    }

    public void drawString(String mesg) {
        send("L" + mesg + "
"); expect(OK_PROMPT);
    }

    /** Move to a relative location */
    public void rmoveTo(int incrx, int incry){
        moveTo(curx + incrx, cury + incry);
    }

    /** move to absolute location */
    public void moveTo(int absx, int absy) {
        System.err.println("moveTo ["+absx+","+absy+"]");
        curx = absx;
        cury = absy;
        send("M" + curx + "," + cury + ","); expect(OK_PROMPT);
    }

    private void setPenState(boolean up) {
        penIsUp = up;
        System.err.println("Pen Up is ["+penIsUp+"]");
    }

    public void penUp(  ) {
        setPenState(true);
        send("U"); expect(OK_PROMPT);
    }
    public void penDown(  ) {
        setPenState(false);
        send("D"); expect(OK_PROMPT);
    }
    public void penColor(int c) {
        penColor = (c%3)+1;        // only has 3 pens, 4->1
        System.err.println("PenColor is ["+penColor+"]");
        send("P" + c + ","); expect(OK_PROMPT);
    }

    //
    // PRIVATE COMMUNICATION ROUTINES
    //

    private void init_comm(String portName) throws
            IOException, UnsupportedCommOperationException {

        // get list of ports available on this particular computer.
        // Enumeration pList = CommPortIdentifier.getPortIdentifiers(  );

        // Print the list. A GUI program would put these in a chooser!
        // while (pList.hasMoreElements(  )) {
            // CommPortIdentifier cpi = (CommPortIdentifier)pList.nextElement(  );
            // System.err.println("Port " + cpi.getName(  ));
        // }
        
        // Open a port. 
        CommPortIdentifier port =
            CommPortIdentifier.getPortIdentifier(portName);

        // This form of openPort takes an Application Name and a timeout.
        tty = (SerialPort) port.openPort("Penman Driver", 1000);

        // set up the serial port
        tty.setSerialPortParams(9600, SerialPort.DATABITS_8,
            SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
        tty.setFlowcontrolMode(SerialPort.FLOWCTRL_RTSCTS_OUT|
            SerialPort.FLOWCTRL_RTSCTS_OUT);

        // Get the input and output streams
        is = new DataInputStream(tty.getInputStream(  ));
        os = new DataOutputStream(tty.getOutputStream(  ));
    }

    /** Send a command to the plotter. Although the argument is a String,
     * we send each char as a *byte*, so avoid 16-bit characters!
     * Not that it matters: the Penman only knows about 8-bit chars.
     */
    private    void send(String s) {
        System.err.println("sending " + s + "...");
        try {
            for (int i=0; i<s.length(  ); i++)
                os.writeByte(s.charAt(i));
        } catch(IOException e) {
            e.printStackTrace(  );
        }
    }

    /** Expect a given CHAR for a result */
    private    void expect(char s) {
        byte b;
        try {
            for (int i=0; i<MAX_REPLY_BYTES; i++){
                if ((b = is.readByte(  )) == s) {
                        return;
                }
                System.err.print((char)b);
            }
        } catch (IOException e) {
            System.err.println("Penman:expect(char "+s+"): Read failed");
            System.exit(1);
        }
        System.err.println("ARGHH!");
    }

    /** Expect a given String for a result */
    private    void expect(String s) {
        byte ans[] = new byte[s.length(  )];

        System.err.println("expect " + s + " ...");
        try {
            is.read(ans);
        } catch (IOException e) {
            System.err.println("Penman:expect(String "+s+"): Read failed");
            System.exit(1);
        };
        for (int i=0; i<s.length(  ) && i<ans.length; i++)
            if (ans[i] != s.charAt(i)) {
                System.err.println("MISMATCH");
                break;
            }
        System.err.println("GOT: " + new String(ans));

    }
}

See Also

In the online source there is a program called JModem, which implements remote connections (like tip or cu on Unix, or HyperTerminal on MS-Windows). It is usable, but too long to include in this book.

There are other specialized APIs for dealing with particular devices. For communicating with Palm Computing Platform devices, you can either use the Palm SDK for Java from Palm Computing, or the third-party API jSyncManager by Brad Barclay, which can be obtained from http://web.idirect.com/~warp/.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.34.197