HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

So you want to build a robot that walks around and bumps into things. But that's not enough for you (this is the year 2000, after all); you also want to control your robot over the Internet. What's more, you want to use Java to control it.

We'll start by showing you the basics of controlling an electric motor over the Web. Specifically, we'll describe how to control radio control (RC) servo motors over the Web. Servos are electric motors popular for use in many applications, including robotics. The components of the system (see Figure 1 for an overview) include a front-end HTML form for entering commands to control the robot, and a Java servlet that accepts these commands and uses a free open-source Java software kit from FerretTronics to send them through a serial port to your robot. On the other end of the serial port receiving these commands will be a FerretTronics chip, the FT639 Servo Controller. The FT639 converts the serial data into electric pulses that a servo can understand. The FT639 sends the signal to the appropriate servo, which responds by moving to the position specified. We'll assume that your robot is attached to your serial port and that the computer you're using is running a Web server that supports Java servlets.

Figure 1
Figure 1:

Software
The software for controlling the robot has four parts: an HTML form, a Java servlet, the FerretTronics Java Development Kit (FTJDK) and JavaComm. These four components are listed in the same order that commands flow through the system: you enter the commands in the HTML form, then press the send button and they're posted to a Java servlet that uses the FTJDK to format the commands and send them on through the serial port using the JavaComm package (javax.comm.*) ­ the standard Java extension for communication ports.

HTML Form
Before anything, we need a way for a remote user to enter and send control commands to the robot. We chose to use a Web browser and an HTML form to post the commands to a Web server (see Figure 2). We could have chosen to use an applet to make a niftier graphical user interface for controlling the robot, but opted for standard HTML to keep things simple.

Figure 2
Figure 2:

The form has standard HTML controls for setting items, as follows:

  • Position: Moves the servo to a certain position.
  • Pin: Specifies which servo to move. An FT639 chip has five pins and a servo could be attached to any of them.
  • Pulse length: Sets the number of degrees the servo can rotate. If pulse length is set to short, the servo can turn 90 degrees. If it's set to long, the servo can turn 180 degrees.
  • Header length: Adjusts the zero position of the servo.
Servlet
After you press the send button on the HTML form, all the information is posted over the Internet to the Java servlet (see Listing 1). The servlet is installed on a Web server and the Web server is physically attached to your robot through a serial port. We're keeping this servlet simple, with limited error-checking, and avoiding performance issues. The servlet works, but isn't robust or efficient.

A few things will need to be set up on your Web server to get this servlet working. First, you'll need to get Java's serial port package (JavaComm). It's a standard Java extension package (javax.comm.*). The Windows and Solaris reference implementations are available on Sun's Web site (www.sun.com). Implementations for other operating systems are available, but you might have to dig around if you're using an operating system other than Windows or Solaris.

Three things you need to remember:

  1. Put the comm.jar file from the JavaComm package in the servlet engine's classpath.
  2. Ensure that the comm.jar file knows how to find the native code that's writing to the serial port (a DLL file on Windows).
  3. Check that the JavaComm code has access to its properties file, javax. comm.properties, which comes with JavaComm.

If these steps aren't followed and JavaComm isn't set up correctly, it won't be able to find any ports on your system and the servlet won't work. (See the documentation that comes with JavaComm and your servlet engine for more details.)

The final thing you need to get is the FTJDK ­ it's available at www.ferrettronics.com. You'll need to put the ftjdk.jar file in the servlet engine's classpath.

If you're not using Windows or if your robot isn't attached to COM2, you'll need to adjust the servlet code accordingly so that it accesses the correct serial port on your system, and then recompile the servlet like this:

if ( portId.getName().equals( "COM2" ) ) { .... }

Let's take a look at the servlet code, starting with the doPost method because that's the method that gets invoked when a remote HTML client presses its send button and posts its form data to the servlet. The first part of the code deals with finding and opening the serial port. It iterates through all the communication ports it finds on the system and stops when it finds the one specified. You may need to change this code to point to the port your robot is attached to (COM1, /dev/term/a, and so on). Next, the servlet code gets the form data, puts it into convenient variables, prints their values back to the HTML client and then calls the sendTo639 method. This method uses the FTJDK, to write the appropriate bytes to the serial port to control the servo.


A typical RC servomotor

Let's take a closer look at the sendTo639 method. After it formats the parameters for the FTJDK. it then creates an Ft639 object from the FTJDK, connects it to a SerialPort object from JavaComm and finally sends the appropriate commands to configure the FT639 chip or to move a servo attached to one of the FT639's pins. An Ft639 object from the FTJDK knows how to translate these requests into bytestreams that a real FT639 chip can understand. The Ft639 object sends these bytes to the connected serial port when one of its methods is called. That's all there is to it. The bytes will flow out the serial port and eventually reach an FT639 chip. The FT639 translates the bytes to electric signals that a servo can understand and sends these signals out on one of its pins. The servo will then move to whatever position the remote HTML client requested.

The FTJDK
FTJDK is special software that can translate your commands into a form that a FT639 servo controller chip can understand. It also contains classes for some of the other chips that FerretTronics offers. These include the FT649 chip that serves as a serial router and lets you control up to five devices through a serial port. The FTJDK also contains software for a switch input chip ­ the FT629, which helps get feedback from your robot ­ and support for the FT609, a stepper motor logic chip.

FTJDK Design
When designing the FTJDK, we decided it would be best to allow the developer to access the object that's attached to the device being controlled without having to worry about where the chip is in the circuit hierarchy of FT639s, FT649 router chips and other chips. This is important since an FT639 could be several levels away from the serial port via multiple nested FT649+ chips. We originally designed the FTJDK so that developers were required to indicate the path the command would need to take through the circuit, but changed it to glue devices together with proxies. The proxies remember the correct path and let developers call methods directly on the FT639 or another control chip. (This is attached to the electric motor or other device that you're controlling.)

The downside of this arrangement is that the user of the FTJDK needs to re-create the physical hardware connections in the software so that the objects know where they should forward commands. For a large array of FT649s and FT639s this may be somewhat burdensome, but we feel the initial work is well worth the effort as it removes the need to include the routing information in the command every time you want to move a different servo. To redress the shortcomings of this design, a future version of the FTJDK will come with a GUI allowing you to create your circuit visually and then generate the code that glues the devices together.

Figure 3 is a diagram of the entire system. On the left is the software that we've described above. On the right is the hardware we'll describe now.

Figure 3
Figure 3:

The Hardware
Many of you may cringe at the thought of dealing with hardware and electronics, but don't worry. It's easy to build the electronics in this project ­ it requires just a few components: an FT639 and circuit board, two resistors, a diode and a serial cable. We also sell a kit with step-by-step directions that contains everything you need to build the simple robot described in this article.

The robot in this article consists of a single RC servo and isn't very powerful or interesting, but it could become so if you treat it as a building block. Our example can be extended to create just about anything. The servo is controlled via the FerretTronics FT639, which is in turn controlled by the Java servlet described above. The FT639 has eight pins ­ one for the ground connection, one for the positive power supply (+5 volts) and one that is connected to the transmit line of the RS-232 connector from the host computer (the serial line). The remaining five pins are used to control up to five servos.

The connection to the serial port is the most complicated aspect of the hardware. It requires two resistors that act to reduce the voltage from the serial port. Additionally, a single diode is placed in line with the serial line to prevent a negative voltage from the host computer entering the circuit. You also need to connect the ground from the serial port to the ground used by the FT639. Finally, the RS-232 protocol on the host machine must be set to 2400 baud, 8 data bits, 1 stop bit and no parity. Don't worry about setting the RS-232 protocol if you're using the FTJDK ­ it takes care of setting the correct protocol before it sends any data over the serial port.

RC hobby servos have three wires terminating at a single connector. One wire is the ground, another is the +5 volt supply and the third is for the control signal. The control signal line is connected directly to the FT639. The ground and V++ wires are connected to the same power supply as the FT639.

Conclusion
We've described a very simple ­ you might say useless! ­ application in which an RC servo is controlled via the Internet. The FT639 can control up to five RC servos, however, and the ability to control five servos adds a lot more flexibility to the design of a robot. Some examples of real-world projects you can make with this framework include a remote controllable Web-cam mount, a robotic arm, a six-legged robot, an XY plotter and any animatronic project like an animated skeleton, dinosaur or face.

Resources

  1. FerretTronics: www.ferrettronics.com
  2. Article Supplement: http://weasel.ferrettronics.com/jdj/article_supp.html
  3. JavaComm: www.javasoft.com/products/javacomm/index.html
  4. FTJDK: www.ferrettronics.com/ftjdk.com
Author Bios
Darrel Riekhof, a Java consultant based in Tucson, Arizona, has worked for several companies including IBM, MCI, Blue Cross Blue Shield Association and Intel. He's also an owner of FerretTronics, Inc.[email protected]

Keith Fligg, who has been interested in electronics and robotics since childhood, currently works as a system architect using the Shlaer-Mellor Method, building real-time embedded software architectures in C++ and Java. He's also part owner of FerretTronics, Inc. [email protected]

	

Listing 1 

/** 
 * @(#)Ft639Servlet.java 
 */ 

import com.ferrettronics.device.Ft639; 
import java.io.*; 
import java.util.*; 
import javax.comm.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 

/** 
 * This is a sample servlet that takes input from 
 * a form, parses and processes it, and sends 
 * commands to a serial port to control 
 * an FT639 and attached servos. 
 */ 
public class Ft639Servlet extends HttpServlet 
{ 

  ////////// Data 

  SerialPort serialPort = null; 

  ////////// Methods 

  public void init( ServletConfig config ) 
  throws ServletException 
  { 
    super.init( config ); 
  } 

  /** 
   * Send data to port in response to the POSTed 
   * form.  Write a "confirmation" to the client. 
   */ 
  public void doPost( HttpServletRequest req, 
                      HttpServletResponse res ) 
  throws ServletException, IOException 
  { 
    // Set the "content type" header of response. 
    res.setContentType( "text/html" ); 
    // Get responsešs PrintWriter to return text 
    // to the client. 
    PrintWriter toClient = res.getWriter(); 
    // Find the serial port that the FT639 is 
    // attached to. In this example, it is 
    // attached to 'COM2'. We enumerate through 
    // all the ports, and stop when we find it. 
    Enumeration portList = 
      CommPortIdentifier.getPortIdentifiers(); 
    CommPortIdentifier portId = null; 
    while ( portList.hasMoreElements() ) 
    { 
      portId = 
      (CommPortIdentifier)portList.nextElement(); 
      if ( portId.getPortType() == 
           CommPortIdentifier.PORT_SERIAL ) 
      { 
        // Windows 
        if ( portId.getName().equals( "COM2" ) ) 
        { 
          try { 
            serialPort = 
              (SerialPort)portId.open( 
                "Sample639", // App Name 
                2000 );      // Timeout 
            break; 
          } catch ( PortInUseException piue ) { 
            toClient.println( 
              "Exception:<br>" + piue + "<p>" ); 
            piue.printStackTrace(); 
            System.exit( -1 ); 
          } 
        } // end if 
      } // end if 
    } // end while 
    // Get pin. 
    String strPin = null; 
    String [] pinArray = 
      req.getParameterValues( "pin" ); 
    if ( pinArray != null ) strPin = pinArray[0]; 
    // Get pos. 
    String strPos = null; 
    String [] posArray = 
      req.getParameterValues( "pos" ); 
    if ( posArray != null ) strPos = posArray[0]; 

    // Pulse Length and Header Length support 
    // not included in this code. 

    toClient.println( "<html>" ); 
    toClient.println( "<title>Got it!</title>" ); 
    toClient.println( "Pin=" + strPin + "<p>" ); 
    toClient.println( "Pos=" + strPos + "<p>" ); 
    toClient.println( "Serial Port =" + 
                      serialPort + "<p>" ); 
    try { 
      sendTo639( strPin, strPos ); 
    } catch ( Exception excp ) { 
      toClient.println( 
        "Exception:<br>" + excp + "<p>" ); 
    } 
    toClient.println( "</html>" ); 
    // Close the writer; the response is done. 
    toClient.close(); 
    if ( serialPort != null ) serialPort.close(); 
  } 

  /** 
   * Send data to 639. 
   * 
   * @param sPin  Specifies the 639 pin that the 
   *              servo is attached to. 
   * @param sPos  Specifies the position to move 
   *              the servo to. 
   */ 
  public void sendTo639( String sPin, 
                         String sPos ) 
  throws Exception 
  { 
    if ( serialPort == null ) 
    { 
      throw new Exception( 
        "Serial port is null!!" ); 
    } 
    int pin = Integer.parseInt( sPin ); 
    int pos = Integer.parseInt( sPos ); 

    // Some error checking on pin and pos values 
    // could go here!! 

    // Create a 639 and 
    // connect it to the serial port. 
    Ft639 ft639 = new Ft639(); 
    ft639.connectTo( serialPort ); 
    // Move the servo 
    ft639.setServoPosition( pin, pos ); 
  } 

} 

// EOF 



 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.