FileDocCategorySizeDatePackage
Penman.javaAPI DocExample5060Sat Mar 20 14:49:08 GMT 2004None

Penman

public class Penman extends Plotter
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 Communicatons" API. Java Communications is a "standard extention" and must be downloaded and installed separately from the JDK before you can even compile this program.
author
Ian Darwin, http://www.darwinsys.com/

Fields Summary
private final String
OK_PROMPT
private final int
MAX_REPLY_BYTES
private SerialPort
tty
private DataInputStream
is
private DataOutputStream
os
Constructors Summary
public Penman()
Construct a Penman plotter object


	      
	   
			 
		super();
		init_comm("COM2");		// setup serial commx
		init_plotter();		// set plotter to good state
	
Methods Summary
public voiddrawString(java.lang.String mesg)

		send("L" + mesg + "\r"); expect(OK_PROMPT);
	
private voidexpect(char s)
Expect a given CHAR for a result

		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!");
	
private voidexpect(java.lang.String s)
Expect a given String for a result

		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));

	
private voidinit_comm(java.lang.String portName)
Set up communication.
XXX: Should probably re-use CommPortOpen instead.


		// 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 open takes an Application Name and a timeout.
		tty = (SerialPort) port.open("Penman Driver", 1000);

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

		// Get the input and output streams
		is = new DataInputStream(tty.getInputStream());
		os = new DataOutputStream(tty.getOutputStream());
	
private voidinit_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 voidmoveTo(int absx, int absy)
move to absolute location

		System.err.println("moveTo ["+absx+","+absy+"]");
		curx = absx;
		cury = absy;
		send("M" + curx + "," + cury + ","); expect(OK_PROMPT);
	
public voidpenColor(int c)

		penColor = (c%3)+1;		// only has 3 pens, 4->1
		System.err.println("PenColor is ["+penColor+"]");
		send("P" + c + ","); expect(OK_PROMPT);
	
public voidpenDown()

		setPenState(false);
		send("D"); expect(OK_PROMPT);
	
public voidpenUp()

		setPenState(true);
		send("U"); expect(OK_PROMPT);
	
public voidrmoveTo(int incrx, int incry)
Move to a relative location

		moveTo(curx + incrx, cury + incry);
	
private voidsend(java.lang.String s)
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.

		System.err.println("sending " + s + "...");
		try {
			for (int i=0; i<s.length(); i++)
				os.writeByte(s.charAt(i));
		} catch(IOException e) {
			e.printStackTrace();
		}
	
public voidsetFont(java.lang.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);
	
private voidsetPenState(boolean up)

		penIsUp = up;
		System.err.println("Pen Up is ["+penIsUp+"]");