Search This Blog

Sunday, June 5, 2011

Computer Monitor Recommendations

A place for my thoughts and links to computer monitors.

I do tons of electronic graphical design both at work and at home.  I'm a fan of lots of pixels on the screen, multiple monitors, etc.  I feel it gives me more productivity to have my design, my blog, my datasheets, all in view at the same time.  I also have a house full of teenage sons who do video gaming.  Every time I get a new monitor I have to look up what my old one was so I can match sizes and swap things around.  I recently bought a new monitor to replace a hulking CRT monster which was once a miracle of technology and wanted to jot down my thinking on this topic and record what monitors I have in one place.

Circa summer 2011, 1900x1200 is king, and he is near death.   LCD, price and HDTV has ruined the computer monitor market.   Since monitors have grown to the size of TVs, and the price for either is rock bottom,   (you may not think it is rock bottom, but as a designer of consumer electronics, it barely pays to build and sell either)  manufacturers have consolidated sizes.   Lot of people watch TV and movies on their computer screens anyway, and the layman thinks 1080p is a big resolution.

Lots of engineering applications expect 1900x1200, and those extra pixels above 1900x1080 make a big difference in having a usable workspace.   1900x1080 is like peering through a mail slot at your work.   Taller is better for document reading too.   So despite the price I still snap up 1900x1200 monitors when I find a good deal.   Note I consider resolution over size any day.

Larger than 1900x1200 are priced out of this world, >$1000.  Not worth it.  Used to be you could crank your CRT monitor up to 2560.  It could get blurry but it still worked.  Those days are over.  That is why I hung onto my 23# widescreen CRT Sun monitor forever.  But side by side, the 24 LCDs were brighter and crisper and I found my self sliding my window over to the LCD no matter what the resolution on the CRT was.  So the CRT is now a boat anchor at the dump, and gave me a sore back on the way out.  This think was HUGE and must have weighed 100 pounds.

Somehow <$300 is a magic price point for me, so I troll for monitors 1900x1200 that are under $300.
I've found the consumer quality monitors (aka el cheapo) are just fine.  I've never had dead pixels, and getting a big monitor with lots of pixels does it for me.  So i'm no snob for "professional" monitors that cost twice as much.  Maybe viewing angle or evenness of display are better, but I've never noticed.

I recently bought this one in 05/2011 and am very happy with it:
HP LA2405wg Black / Silver 24" Height/Pivot/Swivel adjustable Widescreen LCD Monitor

HP LA2405wg Black / Silver 24" 5ms Height/Pivot/Swivel adjustable Widescreen LCD Monitor 300 cd/m2 DC 3000:1(1000:1)

http://www.newegg.com/Product/Product.aspx?Item=N82E16824176141
It even has a promo code, which I missed, for another $20 off, and free shipping.
I think it is being dumped because there is no HDMI port.  It has displayport, which only HP laptops really support.  Has a DVI and VGA and looks good sourced by either.  It is 1900x1200 and matches well with my older Sceptre monitor from 2008.   It is for sale from Amazon, but is currently only from 3rd parties who charge shipping 24 LA2405wg LCD Monitor.  It does seem that there are deals <$200 for 1900x1080 monitors, so this recomendation isn't for everyone.



I got this monster 02/2011 from tigerdirect for $249!!  Free shipping seems to come and go.
I-Inc iH-282HPB 28" Class Widescreen LCD Monitor

I-Inc iH-282HPB 28" Class Widescreen LCD Monitor - 1920 x 1200, 15000:1 Dynamic, 16:10, 3ms, VGA, HDMI

http://www.tigerdirect.com/applications/SearchTools/item-details.asp?EdpNo=4938558
Admittedly I had been looking for a 24", because that is about as big as my head and eyes comfortably take in when the monitor is a reasonable distance away.  I had been searching on 1900x1200 and didn't notice this was bigger.  It came in the mail and I thought there was a mistake and I'd bought a TV.  Box and monitor are huge.  It works great.  It has two HDMI connectors and a DVI adapter.  Not sure why they give it away.  Picture was bright, sharp, uniform.  Awesome.  Almost bought another but they are so big, you have to have room for them.  Two on your desk is probably too big for anyone.



I got this one for my son's gaming in 2/2010 for $228.  At the time it was the best deal on a 24" monitor that had an HDMI port so he could also hook it to his playstation as well as the computer.  It has a DVI and a HDMI port both, so it could do double duty.  His usage is purely entertainment.  He does no engineering (how sad). It is only 1900x1080, and it cemented my opinion that 1900x1200 is worth paying for.  It has a fast response time and has been a good monitor for him.  He does notice that my 1900x1200's are taller, and comments on it a lot.  However it was at least $50-100 cheaper than an equivalent 1900x1200.




I got this one in 10/2008.  It has been my workhorse all that time.
It was $270 at the time, from Amazon, newegg, and tigerdirect, but is unavailable now.  Had DVI and VGA inputs and speakers which I never used.
I wrote a review when i got it, because with my old Thinkpad laptop extender, the display blinked out black once or twice an hour for a few seconds.   Pretty annoying.  After some reading on the web, I decided that it was the fault of low DVI signal levels.  When I got a newer thinkpad and extender, the problem stopped.  It is now hooked to a desktop machine and has never done this again.

Monday, May 23, 2011

PCB design with gEDA notes

I've been using gEDA on ubuntu linux for schematics and PCB design and like it so far.
It had several key attributes.  Free and no limits on complexity or commercial use.

Found this site that may have some nice templates, making note
http://www.electronics-lab.com/blog/?p=6925
http://lowvoltagelabs.com/2010/11/16/arduino-shield-board-outline-in-geda-format/
Loaded it and it looks good, saved a lot of time finding the locations and sizes of
the connectors.

Sunday, May 22, 2011

Notes on the heavy duty motor shield for Arduino


This is a heavy duty motor shield for Arduino

It uses the basic motor shield from adafruit.com, same software, but instead of an hbridge
driver, it uses 25A 60V mosfets for drive.  Purpose is to drive
drill motors from the Arduino.

Here is the circuit of a half bridge.  The extra devices on the left are
to convert the input & enable structure to a N and P drive.  It is important
to have a HiZ mode when disabled, where N=0 and P=1 and both
MOSFETs are off.  I hope to simplify this circuit but i don't want to make
major modifications to the adafruit.com library.  This is the lash up prototype:



Here is  a photo of the Arduino, a canabalized up motor shield on top (this was one i modified for stacking and later blew out an Hbridge IC on, doh!) for control, a breadboard full of the NPN and PNP needed to convert the interface, a prototype high current MOSFET driver board and a drill motor.  The motor power supply is not connected in this photo.

Lets see if I can post the little video of the motor test program.  It revs the motor speed up, then reverses, then stops and repeats.  Watch the little black gear and make sure your sound is on to hear the fun.




Now to clean up the board to the form factor of a shield, it will be somewhat dense.


Saturday, May 14, 2011

Idea for laptop LCD repurposed as a photoblocking license plate cover

OK, here is an idea so horrible I had to share it, since I've been on the photoblocking topic lately.

Another possible anti-speed camera technology is to repurpose an old laptop as an LCD chopper.   The idea is that the backlight and cover of the laptop screen will be removed so that the screen becomes a see through license plate cover.   The laptop will be programmed to display a series of black stripes across the screen that will move so fast as to appear like a gray tinted screen.  To a camera that freezes the motion, some section of the plate will always be covered with a black stripe and be unreadable.

There are all kinds of issues.  In my state license plate covers are illegal, maybe elsewhere they are not.   I do see people with them all the time, so I guess the police haven't pulled over everyone.  The LCD screen would not be the right shape for the plate, although maybe one could be found that is acceptable.   The screen might be pretty dark and earn you a ticket anyway.   The LCD will be fragile and certainly would not hold up to northeast US weather.   But since when has sanity stopped an inventor?

I wouldn't be able to do field trials where I live, but just making note of the idea while I wait for more LEDs to come.  I'll develop this idea more later.

Friday, April 1, 2011

code.google.com project

Going to try to host my code on code.google.com to make it easier to share and use from my different machines.

http://code.google.com/p/arduino-java-xyzcnc/

Files can be accessed directly at this link
http://code.google.com/p/arduino-java-xyzcnc/downloads/list

I want to make one tweak to the Java GUI before uploading that part, still under construction

Monday, March 28, 2011

Arduino XYZ CNC Java GUI is working!

I was able to expand the GUI to talk to two serial ports at once.  I have the Arduino reading the serial encoders on COM10, and the Arduino with the motor shields on COM11.  Both Arduinos print back their coordinate to the serial port.

The positions are read back from the Arduinos to the GUI display.  The buttons fire off HPGL PR commands to the Arduino HPGL interpretor.  w00t!

The machine moves, the encoders increment.




Next step is to add some flow control to the GUI and the ability to spool in a large HPGL command in small chunks so as not to overflow the Arduino serial buffer and give it time to move from point to point.

The code is getting pretty long to post, so I'm setting up a download site

Saturday, March 26, 2011

Notes on Learning to Make a Java GUI for the CNC machine

Not sure if this is the way I will go, but I'm exploring using Java to create a small GUI to control the Arduino based XYZ CNC machine.  I did see some folks have already done this, so I may go back and use their code.
This is a place to store my notes as I explore this topic.

My hardware is an Arduino with two motor shields from Adafruit attached (see my post on modding the shield to stack) and another Arduino reading three rotary encoders (see my post on this).  These control a Zen toolworks 7x7 CNC machine.

I've written the code for the Arduino to respond to serial commands to move in straight line at constant velocity from current location to a new location.   Ideally this is all that ever needs to run on the Arduino.  I wrote a simple HPGL interpretor, but the serial communication wasn't working out. When I used the Arduino GUI to dump a serial file to the Arduino, the Arduino did not process the commands fast enough, obviously it has to move motors, etc, and the serial input would overrun the input buffer in the Arduino and trash the data.  The Arduino can't do this job all by itself.  i will never be able to send a whole HPGL file to the Arduino, it needs to be passed a bit at a time by a PC program.

So the goal here is to write a GUI that will allow the PC to feed the Arduino a file a bit at a time, and also have manual buttons to move the motors and display the encoder postions.  Maybe even the limit switches.  All the arduino will do is move from X,Y,Z to X,Y,Z point as commanded.

Downloaded Netbeans and Java JDK here:
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewFilteredProducts-SingleVariationTypeFilter

Found some information on talking to the serial port here:
http://java.sun.com/developer/Books/javaprogramming/cookbook/11.pdf

That book says I may need to download the Java Communication API, which I found here
http://www.oracle.com/technetwork/java/index-jsp-141752.html
but this looks to be for LINUX only.  The text says for windows...
  To use that, download javax.comm for the 'generic' platform (which provides the front-end javax.comm API only, without platform specific back-end implementations bundled). Then acquire the Windows binary implementation rxtx-2.0.7pre1 from http://www.rxtx.org.


Found a web page with specific instructions!  Here:
http://pradnyanaik.wordpress.com/2009/04/07/communicating-with-ports-using-javaxcomm-package-for-windows/

So I registered at sun and downloaded the generic package java communication API
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_SMI-Site/en_US/-/USD/ViewFilteredProducts-SingleVariationTypeFilter

Now I'm puzzled, only the comm.jar file is there, not the win32com.dll or the javax.comm.properties

Found another example that seems more clear;
http://edn.embarcadero.com/article/31915
Points to the same oracle page that got me only comm.jar.  hmmmm.
And rxtx.org points to a isp dead end page.

Friend sent me rxtx-2.1-7-bins-r2  dont know where he got it.  But no worries, it is on the web see below
Instructions were similar, but now i had a jar file and a dll.
README referred to this web page, which had the files on it
http://rxtx.qbang.org/wiki

Windows
RXTXcomm.jar goes in \jre\lib\ext (under java)
rxtxSerial.dll goes in \jre\bin

Then went here to use in netbeans
http://rxtx.qbang.org/wiki/index.php/Using_RXTX_In_NetBeans
I did the right click on libraries to add the jar file but i had already copied the files into the locations above, so i think i'm done

Went to the sample project
http://rxtx.qbang.org/wiki/index.php/Documented_interface_to_communicate_with_serial_ports_for_beginners,_including_example_project
Even mentions arduinos - w00t
downloaded the zip file  RXTXexample.zip
Bleh, not really sure how to use this with netbeans.  README talks about ant in linux.
Tried opening as a project in netbeans...no dice

Opened the project my friend sent, myRxTxTest2.  I will go back and figure out how he made this later, sorry for the trail that can't be followed.  Here is the basic Java code that makes up Main.java.  There is
also a GUI form that goes with it, but nothing earth shaking there.

//--------------------------------------------------------------------------------------------------
import java.io.*;
import java.util.*;
import gnu.io.*;
import java.awt.event.MouseAdapter;
//import javax.comm.*;
/**
 *
 * @author eric
 */
public class RealMain {
    Enumeration      portList;
    CommPortIdentifier portId;
    SerialPort      serialPort;
    OutputStream       outputStream;
    InputStream         inputStream;
    boolean      outputBufferEmptyFlag = false;
    Thread             readThread;
    Thread              writeThread;
    boolean             wrFlag=true;
    boolean             rdg=true;
    String              msgin;
    String              msginmod;


    public void Go(){
        //inForm inf = new inForm("MyForm");
        //inf.go();
        trash trh = new trash();


      
        trh.setVisible(true);


        try{
            portId= CommPortIdentifier.getPortIdentifier("COM11");
        }catch(Exception e){
            System.out.println("Error getting port ID"+ e);
            Enumeration ports = CommPortIdentifier.getPortIdentifiers();


            //tomw - addeed dump of all active ports
            System.out.println("Active ports found:");
            while(ports.hasMoreElements()){
                CommPortIdentifier port = (CommPortIdentifier) ports.nextElement();
                System.out.println(port.getName());
            }
        }
        try{
            serialPort = (SerialPort) portId.open("My RxTx test", 2000);
            System.out.println("Got Serial Port Open");
            System.out.println("type something in the console window to send it (15 characters max) - type exit to quit ");
        }catch(Exception e){
            System.out.println("Error opening port "+ e);
            System.exit(1);
        }
        try {
            outputStream = serialPort.getOutputStream();
        } catch (IOException e) {
            System.out.println("Error setting output stream "+e);
        }
        try {
            inputStream = serialPort.getInputStream();
        } catch (IOException e) {
            System.out.println("Error setting input stream "+e);
        }
        try {
            serialPort.setSerialPortParams(9600,
                                           SerialPort.DATABITS_8,
                                           SerialPort.STOPBITS_1,
                                           SerialPort.PARITY_NONE);
        } catch (UnsupportedCommOperationException e) {}


        ReadHandler RH = new ReadHandler();
        Thread RT = new Thread(RH);
        RT.start();
        InputStreamReader cmlIn = new InputStreamReader(System.in);
        BufferedReader brIn = new BufferedReader(cmlIn);
        PrintWriter pr = new PrintWriter(outputStream,true);
        while (rdg){
            try{
                msgin = brIn.readLine();
                System.out.println("You typed "+ msgin);
                try{                  
                    //pr.print(msgin);
                    //outputStream.write('w');
                    //outputStream.write(0x000a);
                   // pr.print(0x00);
                   // pr.println();
                    if(msgin.length()>15){
                        msginmod=msgin.substring(0, 15);
                        System.out.println("more than 15 characters - will truncate to " + msginmod);
                    }else{
                        msginmod=msgin;
                    }
                    pr.println(msginmod);
                }catch(Exception e){
                    System.out.println("error writing to device "+ e);
                }
                if (msgin.equalsIgnoreCase("exit")){
                    rdg=false;
                    System.out.println("leaving now");                
                    outputStream.close();
                    inputStream.close();
                    brIn.close();
                    pr.close();
                    serialPort.close();
                    System.exit(1);
                }
            }catch(Exception e){
                System.out.println("error reading line"+ e);
            }
        }
    }
    public void Write(){
        System.out.println("got here");
    }


    class ReadHandler implements Runnable {
        volatile boolean on;      
        public void run(){
            int c;
            String msgback;
            InputStreamReader IS = new InputStreamReader(inputStream);
            BufferedReader BR = new BufferedReader(IS);
            while(rdg){
                try{
                    msgback=BR.readLine();
                    System.out.println("line back is "+ msgback);
                }catch(Exception e){
                    //tomw - commented out, screen if filling with this message
                    //System.out.println("error reading back"+ e);
                }
            }
        }
    }


  
}
//--------------------------------------------------------------------------------------------------------

It complained it had non existing paths to my friends RXTXcomm.jar and others.  Trying to point it to my own files
OK - found that right click on Libraries in the project tree, hit properties, brings up the GUI to remove the broken links.  Still missing java.boot.jar  looks like i can ignore this.  Complains the port doesn't exist.
looks like the code points to a port /dev/ttySO, since he uses Linux, I'm still using windows. trying this instead:
Found some code at the bottom of this page that tells how to read what ports are active:
http://stackoverflow.com/questions/274179/nosuchportexception-using-rxtx-java-library-on-windows

    Enumeration ports = CommPortIdentifier.getPortIdentifiers();  

    while(ports.hasMoreElements()){  
        CommPortIdentifier port = (CommPortIdentifier) ports.nextElement();
        System.out.println(port.getName());
    }
}  


Bingo - I get:

COM1
COM11
LPT1

So changing the port to "COM11" where my Arduino is and error goes away, but the form flashes up then disappears immediately from within Netbeans, Duh - the arduino app was open and the port was busy.
Closed it and things are looking up!

For testing I made a tiny sketch for the Arduino to respond to serial inputs, turns off LED, etc

//-------------------------------------------------------------------------------------

// Test program for the Arduino
// for development of a serial interface GUI on the PC
// Just makes communication on the serial interface


char inByte = '0';         // incoming serial byte
char outByte = '0';        // outgoing serial byte
boolean contact = false;    //indicates a link partner was found


void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
  pinMode(13, OUTPUT);    
}


void loop()
{
  if (Serial.available()) {
    contact = true;
    inByte = Serial.read();
    
    if (inByte == 'U') digitalWrite(13, HIGH);   // set the LED on
    if (inByte == 'D') digitalWrite(13, LOW);    // set the LED off
    
    // mess with it a bit to show something happened
    outByte = inByte + 1;
    Serial.println(outByte);         
  } else {
    //spew junk to let the world know you want to talk
    if (!contact)   Serial.print(",");
  }
  
}

//-------------------------------------------------------------------

OK, some success.  The console window shows the responses from the Arduino.  The form is not working but at least it is talking to the Arduino from the Java console!!!  w00t!

Had to switch to my laptop, so brief recap of what i had to do to get netbeans back to this point.....
Download Java netbeans JDK
Download Java Communication API, and get the file comm.jar from the generic platform
Download  rxtx-2.1-7-bins-r2 from http://rxtx.qbang.org/wiki and put the RXTXcomm.jar and rxtxSerial.dll in the folders in netbeans where the README says
OK - back to our show.....

Have the very basics of the GUI working now by splicing together demo GUI program with the rxtx.   I can push a button on the GUI, send a 'U' to the serial interface and turn on the LED.   Awesome!  'D' turns it off.   The port initialization was stolen directly from the code i posted further up.   The Arduino sends back the position and the GUI displays it.  Left a place for the encoders to read back, that requires more work from a second serial port.



Using the basic GUI builder in Netbeans.  The form is just made with the form builder and the functions pasted into it's fields.

I'm in business.  Now the drudgery of making the full GUI, passing coordinate messages, spooling a HPGL file, etc to the real Arduino stepper motor control program.   I'll spare some details until I have a more complete interface put together and write that up.

Here is the Java and the Arduino programs.

package Serial_Comm_GUI;


//imports all the java rxtx libs
import java.io.*;
import java.util.*;
import gnu.io.*;
import java.awt.event.MouseAdapter;
//import javax.comm.*;


/**
 *
 * @author tomw
 */
public class RealMain {
    Form1 myform;
    boolean toggle = false;
    Enumeration      portList;
    CommPortIdentifier portId;
    SerialPort      serialPort;
    OutputStream       outputStream;
    InputStream         inputStream;
    boolean      outputBufferEmptyFlag = false;
    Thread             readThread;
    Thread              writeThread;
    boolean             wrFlag=true;
    boolean             rdg=true;
    String              msgin;
    String              msginmod;
    String              portName = "COM11";


    public void go() {


        // Pops up the GUI
        myform = new Form1(this);
        myform.setVisible(true);


        myform.setLabel2(portName);
        myform.setLabel11("contacting...");
        myform.setLabel7("contacting...");




        // Opens the serial port and configures it, handles errors
        try{
            portId= CommPortIdentifier.getPortIdentifier(portName);
            System.out.println(portName);
        }catch(Exception e){
            System.out.println("Error getting port ID"+ e);
            Enumeration ports = CommPortIdentifier.getPortIdentifiers();


            //tomw - addeed dump of all active ports
            System.out.println(portName);
            System.out.println("Port not Found - Active ports found:");
            while(ports.hasMoreElements()){
                CommPortIdentifier port = (CommPortIdentifier) ports.nextElement();
                System.out.println(port.getName());
            }
        }
        try{
            serialPort = (SerialPort) portId.open("My RxTx test", 2000);
            System.out.println("Serial Port Open");
            System.out.println("type in the console window to send commands");
        }catch(Exception e){
            System.out.println("Error opening port "+ e);
            System.exit(1);
        }
        try {
            outputStream = serialPort.getOutputStream();
        } catch (IOException e) {
            System.out.println("Error setting output stream "+e);
        }
        try {
            inputStream = serialPort.getInputStream();
        } catch (IOException e) {
            System.out.println("Error setting input stream "+e);
        }
        try {
            serialPort.setSerialPortParams(9600,
                                           SerialPort.DATABITS_8,
                                           SerialPort.STOPBITS_1,
                                           SerialPort.PARITY_NONE);
            myform.setLabel11("0:0:0");
        } catch (UnsupportedCommOperationException e) {}


        ReadHandler RH = new ReadHandler();
        Thread RT = new Thread(RH);
        RT.start();
        InputStreamReader cmlIn = new InputStreamReader(System.in);
        BufferedReader brIn = new BufferedReader(cmlIn);


    }




    public void longTextChange() {
        if (toggle == false) {
            myform.setLabel2("Oops!");
            toggle = true;
        } else   {
            myform.setLabel2("Ahhhh!");
            toggle = false;
        }
        System.out.println("You pushed me!!");
    }
    public void pushedUp(){
        PrintWriter pr = new PrintWriter(outputStream,true);
        pr.println('U');
        System.out.println("Up");
    }
    public void pushedDown(){
        PrintWriter pr = new PrintWriter(outputStream,true);
        pr.println('D');
        System.out.println("Down");
    }
    public void pushedRight(){
        PrintWriter pr = new PrintWriter(outputStream,true);
        pr.println('R');
        System.out.println("Right");
    }
    public void pushedLeft(){
        PrintWriter pr = new PrintWriter(outputStream,true);
        pr.println('L');
        System.out.println("Left");
     }
    public void pushedZup(){
        PrintWriter pr = new PrintWriter(outputStream,true);
        pr.println('Z');
        System.out.println("Z up");
     }
    public void pushedZdown(){
        PrintWriter pr = new PrintWriter(outputStream,true);
        pr.println('W');
        System.out.println("Z down");
     }


    class ReadHandler implements Runnable {
        volatile boolean on;
        public void run(){
            int c;
            String msgback;
            InputStreamReader IS = new InputStreamReader(inputStream);
            BufferedReader BR = new BufferedReader(IS);
            while(rdg){
                try{
                    msgback=BR.readLine();
                    System.out.println("Position "+ msgback);
                    myform.setLabel11(msgback);
                }catch(Exception e){
                    //tomw - commented out, screen if filling with this message
                    //System.out.println("error reading back"+ e);
                }
            }
        }
    }
}




//--------------------------------------------------------------------------------------------------------------------------------


// Test program for the Arduino
// for development of a serial interface GUI on the PC
// Just makes communication on the serial interface


char inByte = '0';         // incoming serial byte
char outByte = '0';        // outgoing serial byte
boolean contact = false;    //indicates a link partner was found
int stepperX = 0;
int stepperY = 0;
int stepperZ = 0;


void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
  pinMode(13, OUTPUT);    
}


void loop()
{
  if (Serial.available()) {
    contact = true;
    inByte = Serial.read();
    
     switch( inByte ) {
      case 'U' : 
        digitalWrite(13, HIGH);   // set the LED on
        stepperY++;
        break;
      case 'D' : 
        digitalWrite(13, LOW);    // set the LED off
        stepperY--;
        break;
      case 'R' : 
        for( int i=0; i<3 ; i++) {
          digitalWrite(13, LOW);    // set the LED off
          delay(300);
          digitalWrite(13, HIGH);    // set the LED on
          delay(300);
        }
        stepperX++;
        break; 
      case 'L' : 
        for( int i=0; i<5 ; i++) {
          digitalWrite(13, LOW);    // set the LED off
          delay(100);
          digitalWrite(13, HIGH);    // set the LED on
          delay(100);
        }    
        stepperX--;    
        break;    
      case 'Z' : 
        for( int i=0; i<10 ; i++) {
          digitalWrite(13, LOW);    // set the LED off
          delay(50);
          digitalWrite(13, HIGH);    // set the LED on
          delay(50);
        }        
        stepperZ++;
        break;  
      case 'W' : 
        for( int i=0; i<10 ; i++) {
          digitalWrite(13, LOW);    // set the LED off
          delay(50);
          digitalWrite(13, HIGH);    // set the LED on
          delay(150);
        }  
        stepperZ--;       
        break;   
      default :
        // ignore unknown letter command
        break;
     }
    
    Serial.print(stepperX);Serial.print(":");Serial.print(stepperY);Serial.print(":");Serial.println(stepperZ);    
  } else {
    //spew junk to let the world know you want to talk
    if (!contact)   Serial.print(",");
  }
  
}