Difference between revisions of "AP KS GM-POVInput.java"
From Mech
Jump to navigationJump to search| Line 1: | Line 1: | ||
<pre>/********************************************** |
<pre>/********************************************** |
||
* POVController.java |
|||
* pov.c |
|||
* Author:Greg McGlynn |
* Author:Greg McGlynn |
||
* Persistence-of-Vision Display project |
* Persistence-of-Vision Display project |
||
* Alexander Park, Kwang Xiong Sim, |
* Alexander Park, Kwang Xiong Sim, Greg McGlynn |
||
* ME 333 Mechatronics - Winter 2008 |
* ME 333 Mechatronics - Winter 2008 |
||
* Northwestern University |
* Northwestern University |
||
Latest revision as of 03:26, 19 March 2009
/**********************************************
* 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[][][])
}