AP KS GM-POVInput.java

From Mech
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
/**********************************************
 * POVController.java
 * Author:Greg McGlynn
 * Persistence-of-Vision Display project
 * Alexander Park, Kwang Xiong Sim, Greg McGlynn
 * ME 333 Mechatronics - Winter 2008
 * Northwestern University
 *
 *    This code uses the SimpleSerial code found at
 * http://alumni.media.mit.edu/~benres/simpleserial/
 * It lets you talk serial from a Java program on a Windows PC.
 * Java programmers may find this useful for a project.
 *
 *    This code runs on a PC and talks through a serial port to
 * the POV. This code is hacked together, ugly, and uncommented!
 * Read at your own risk!
 **********************************************/

import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.io.*;

public class POVController extends MouseInputAdapter implements ActionListener, KeyListener, WindowListener
{

	public static void main(String[] args)
	{
                //initialization necessary to accept keyboard input (very long functions), not shown
		init();
		init2();
		init3();
		init4();

		new POVController().run();
	}

	InputStream serIn;
	OutputStream serOut; //we talk to the display with this

        //the image:
        boolean[][] leds = new boolean[width][height];

        //user interface stuff:
	final int px = 6;
	final int width = 193;
	final int height = 14;

	final int offX = 10;
	final int offY = 100;

	Checkbox eraseCheckbox;
	Button clearButton;
	Button refreshButton;
	Button dumpButton;
	Button invertButton;

	static int[][][] ascii = new int[255][][];

	public void run()
	{

		setupComPort();

		Frame f = new Frame("POV Display Controller");
		f.setSize(width*px+offX*2, height*px + offY + 20);
		f.setLayout(new FlowLayout());

		f.addMouseListener(this);
		f.addMouseMotionListener(this);
		f.addKeyListener(this);

                eraseCheckbox = new Checkbox("Erase?");
		f.add(eraseCheckbox);

		clearButton = new Button("Clear Display");
		clearButton.addActionListener(this);
		f.add(clearButton);

		refreshButton = new Button("Refresh (if the image isn't appearing)");
		refreshButton.addActionListener(this);
		f.add(refreshButton);

                dumpButton = new Button("Dump code");
		dumpButton.addActionListener(this);
		//f.add(dumpButton);

		invertButton = new Button("Invert pixels");
		invertButton.addActionListener(this);
		f.add(invertButton);

		f.setVisible(true);
		f.addWindowListener(this);
		f.requestFocus();

		BufferedImage im = new BufferedImage(width*px+1, height*px+1, BufferedImage.TYPE_INT_RGB);
		Graphics g = im.getGraphics();
		g.setColor(Color.white);
		g.fillRect(0, 0, width*px, height*px);
		g.setColor(Color.black);
		for(int x = 0; x <=  width*px; x += px) g.drawLine(x, 0, x, height*px);
		for(int y = 0; y <= height*px; y += px) g.drawLine(0, y,  width*px, y);

		while(true)
		{

			for(int x = 0; x < width; x += 1)
			{
				for(int y = 0; y < height; y += 1)
				{
					if(leds[x][y]) g.setColor(Color.red);
					else           g.setColor(Color.white);

					g.fillRect(x*px+2, y*px+2, px-3, px-3);
				}
			}

			f.getGraphics().drawImage(im, offX, offY, f);
			f.requestFocus();
			try { Thread.sleep(20); }
			catch(Exception e) {}
		}
	}

        void setupComPort() {
                System.out.print("PLEASE ENTER A COM PORT NUMBER: ");
                try {
                    int com = Integer.parseInt(new BufferedReader(new InputStreamReader(System.in)).readLine());
                    if(tryComPort(com)) return;
                    else System.out.println("That com port doesn't seem to work! :(");
                } catch(Exception e) {
                    e.printStackTrace();
                    System.out.println("Sorry, there was some kind of error! :(");
                }
                System.out.println("Press any key to exit...");
                try {
                    System.in.read();
                    System.in.read();
                } catch(Exception e) {}
                System.exit(0);
        }

        boolean tryComPort(int com) {
                SimpleSerial ss = new SimpleSerialNative(com /*com port!*/);
                serIn = ss.getInputStream();
		serOut = ss.getOutputStream();

		return (serIn != null && serOut != null);
        }


	int lastX, lastY;

	int ledX(int mouseX)
	{
		return (mouseX - offX)/px;
	}

	int ledY(int mouseY)
	{
		return (mouseY - offY)/px;
	}

	boolean inBounds(int x, int y)
	{
		return (x >= 0 && y >= 0 && x < width && y < height);
	}

	void set(int x, int y, boolean state)
	{
		if(inBounds(x, y)) leds[x][y] = state;
	}


	public void mousePressed(MouseEvent e)
	{
		lastX = ledX(e.getX());
		lastY = ledY(e.getY());
		boolean state = !eraseCheckbox.getState();
		set(lastX, lastY, state);
		updateColumn(lastX);
	}

	public void mouseDragged(MouseEvent e)
	{
		int newX = ledX(e.getX());
		int newY = ledY(e.getY());

		if(newX == lastX && newY == lastY) return;

		boolean state = !eraseCheckbox.getState();
		double dist = Math.sqrt((newX-lastX)*(newX-lastX) + (newY-lastY)*(newY-lastY));
		double dx = (newX - lastX)/dist/10;
		double dy = (newY - lastY)/dist/10;
		for(int i = 0; i < dist*10; i++)
		{
			int x = (int)(lastX + dx*i);
			int y = (int)(lastY + dy*i);
			set(x, y, state);
		}

		int startCol = (newX < lastX ? newX : lastX);
		int endCol   = (newX > lastX ? newX : lastX);
		for(int col = startCol; col <= endCol; col += 1)
		{
			updateColumn(col);
		}

		lastX = newX;
		lastY = newY;
	}

	void updateColumn(int x)
	{
		byte byte1 = (byte)(x >> 8);
		byte byte2 = (byte)(x & 255);
		byte byte3 = 0, byte4 = 0;

		//here we assume height = 14
		for(int y = 0; y < 7; y += 1)
		{
			if(leds[x][y]) byte4 |= (1 << y);
		}
		for(int y = 7; y < 14; y += 1)
		{
			if(leds[x][y]) byte3 |= (1 << (y-7));
		}

		try
		{
			serOut.write(byte1);
			serOut.write(byte2);
			serOut.write(byte3);
			serOut.write(byte4);
			try { Thread.sleep(5); }
			catch(Exception e) {}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	final byte CLEAR = 0x00;

	void sendCommand(byte command)
	{
		try
		{
			serOut.write(0xff);
			serOut.write(0xff);
			serOut.write(0x00);
			serOut.write(command);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	public void actionPerformed(ActionEvent e)
	{
		if(e.getSource() == clearButton)
		{
			for(int x = 0; x < width; x += 1)
			{
				for(int y = 0; y < height; y += 1)
				{
					leds[x][y] = false;
				}
			}
			sendCommand(CLEAR);
		}
		else if(e.getSource() == refreshButton)
		{
			for(int x = 0; x < width; x++)
			{
				updateColumn(x);
				try { Thread.sleep(5); } 
				catch(Exception ex) {}
			}
		} 
		else if(e.getSource() == dumpButton) 
		{
			try 
			{ 
				FileWriter fw = new FileWriter(new File("dump.txt"));

				for(int x = 0; x < width; x++) 
				{
					fw.write("pixels[" + x + "][1] = 0b0");
					for(int y = 6; y >= 0; y--) fw.write(leds[x][y] ? "1" : "0"); 
					fw.write(";\r\n");

					fw.write("pixels[" + x + "][0] = 0b0");
					for(int y = 13; y >= 7; y--) fw.write(leds[x][y] ? "1" : "0");
					fw.write(";\r\n");
				}

				fw.flush();
				fw.close();
			} 
			catch(Exception ex) {}
		} 
		else if(e.getSource() == invertButton) {
			for(int x = 0; x < width; x++) 
			{
				for(int y = 0; y < 14; y++) 
				{
					leds[x][y] = !leds[x][y];
				}
			}
		}
	}

	int asciiCursor = 0;
	int asciiWidth = 10, asciiHeight = 14;
	public void keyPressed(KeyEvent e) 
	{
		
		char c = e.getKeyChar();
		if(c >= ' ' && c <= '~' && asciiCursor + asciiWidth < width) 
		{
			for(int x = 0; x < asciiWidth; x++)
			{
				for(int y = 0; y < asciiHeight; y++) 
				{
					leds[asciiCursor + x][y] |= (ascii[c][y][x] == 1);
				}
				updateColumn(x);
			}

			asciiCursor += asciiWidth;
		}

		if(e.getKeyCode() == KeyEvent.VK_BACK_SPACE) 
		{
			if(asciiCursor >= asciiWidth) 
			{
				asciiCursor -= asciiWidth;
				for(int x = 0; x < asciiWidth; x++)
				{
					for(int y = 0; y < asciiHeight; y++) 
					{
						leds[asciiCursor + x][y] = false;
					}
					updateColumn(x);
				}
			}
		}
		
	}


	public void keyReleased(KeyEvent e) {}
	public void keyTyped(KeyEvent e) {}

	public void windowActivated(WindowEvent e) {}
	public void windowClosed(WindowEvent e) {}
	public void windowClosing(WindowEvent e) { System.exit(0); }
	public void windowDeactivated(WindowEvent e) {}
	public void windowDeiconified(WindowEvent e) {}
	public void windowIconified(WindowEvent e) {}
	public void windowOpened(WindowEvent e) {}
																																																	  

//...init# functions omitted (these just initialize ascii[][][])
}