Project

General

Profile

Revision 1946

Added Java code to listen to serial port. Also included development notes (DEV-NOTES.txt) which describe the process I had to go through to get serial ports to work in Java.

View differences:

trunk/code/projects/calibration_platform/server/DEV-NOTES.txt
1
DEV-NOTES - Development notes for the cal_sta_server Java code
2
Author: John Sexton
3
Date: 3/20/11
4

  
5

  
6
SUMMARY:
7
-Tried to install Sun's Java Comm API, doesn't work for 64-bit machines.
8
-Changed from open source IcedTea Java 6 to Sun's Java 6.
9
-Tried to install RXTX library. Need special version for 64-bit. Does not
10
   allow you to open any port, only can open what it scans.
11
-Downloaded RXTX source code, added "arduino" and "robot" port prefixes
12
   to RXTX library, compiled it and installed it on Marvin.
13

  
14
USEFUL JAVA LOCATIONS:
15
/usr/lib/jvm -
16
   location of java installations
17

  
18
/usr/lib/jvm/java-6-sun/jre/lib/ext -
19
   java extension .jar files (like RXTXcomm.jar) go here (for Sun's Java)
20

  
21
/usr/lib/jvm/java-6-sun/jre/lib/amd64 -
22
   the librxtx______.so files go here (for Sun's Java + 64-bit)
23

  
24
   /usr/lib/jvm/java-6-sun/jre/lib/amd64
25
                     ^               ^
26
                Sun's Java       64-bit architecture
27

  
28

  
29
USEFUL WEBSITES:
30
http://en.wikibooks.org/wiki/Serial_Programming/Serial_Java -
31
   General overview of serial programming in Java.
32

  
33
http://download.oracle.com/docs/cd/E17802_01/products/products/javacomm/reference/api/index.html -
34
   API for javax.comm / gnu.io
35

  
36
http://www.capybara.org/~dfraser/archives/29 -
37
   Article describing how to edit RXTX source code to add port prefixes.
38

  
39
http://rxtx.qbang.org/wiki/index.php/Main_Page -
40
   RXTX development wiki. Very good resource for installing and obtaining
41
   source code.
42

  
43
http://www.cloudhopper.com/opensource/rxtx/ -
44
   Location of 64-bit compiled binaries for RXTX library.
45

  
46

  
47

  
48

  
49

  
50
NOTES:
51

  
52
Java does not play nice with serial ports right out of the box. You must
53
install additional libraries to gain the ability to speak to serial ports
54
in Java. The most common library that I found is the JAVA COMMUNICATIONS
55
API LIBRARY.
56

  
57

  
58
== Sun's Java Communications API ==
59

  
60
Sun does a very poor job of maintaining this library (after all, they
61
support platform-independent development and this is difficult when a
62
serial port inherently relies on the underlying hardware). My first
63
attempts to successfully listen over a serial port involved using Sun's
64
implementation of the Java Communications API. It was difficult to find a
65
good download of this online, but I eventually ended up using an Oracle
66
website (http://www.oracle.com/technetwork/java/index-jsp-141752.html) to
67
obtain the library. Followed installation instructions and successfully
68
installed, but when I tried to run a program I got an error which cited
69
the ELF compiled binary file. Also mentioned the word size might be wrong.
70
This error was confirmed online where I found support for the fact that
71
Sun/Oracle only supports 32-bit versions of the Java Communications API
72
and doesn't support windows. All of these limitations led me to abandon
73
using Sun's version.
74

  
75

  
76
== RXTX Library ==
77

  
78
I found an open source library called the RXTX library which follows the
79
Java Communications API exactly (except it's called 'gnu.io' instead of
80
'javax.comm'). The development website
81
(http://rxtx.qbang.org/wiki/index.php/Main_Page) was very useful. I was
82
able to successfully install the RXTX library, but when I tried to run
83
sample code, Java seg-faulted (OMG... XD). In an attempt to fix this, I
84
removed the open source IcedTea java and installed Sun's Java, but the
85
error still remained. I then traced the error back to the Thread function,
86
so I believe the problem is not actualy with the RXTX functionality that
87
we need and instead has to do with using threads with the RXTX library.
88

  
89
I proceeded to write a small Java program to test the
90
RXTX library, and discovered that you can only address ports which the
91
library finds on its own. This was a problem because the library only
92
looked for a few prefixes and did not show the 'arduino' or the 'robot#'
93
nodes in the /dev folder. I found an article online
94
(http://www.capybara.org/~dfraser/archives/29) which describes how
95
to edit the source code for the RXTX library to include more ports. I
96
used the link included in the article to obtain the source code, but when
97
I edited the necessary source file (RXTXCommDriver.java), recompiled it
98
into a .jar file again (had to remove a 'import javax.comm.*' line from
99
the source file which seemed strange to me), and transfered it into the
100
proper directory (/usr/lib/jvm/java-6-sun/jre/lib/ext) it did not work.
101
Java threw an error which I can't remember the content of at the moment
102
(but it wasn't a seg-fault like the thread error). To obtain a better copy
103
of the source code, I again resorted to the RXTX development wiki
104
(http://rxtx.qbang.org/wiki/index.php/Main_Page). I downloaded a recent
105
copy of the source code, unzipped it, ran '/configure', and ran 'make'.
106
I received some errors, but there was still a brand new 'RXTXComm.jar'
107
file in the folder now, so I proceeded to install it
108
(replace the RXTXComm.jar file in the
109
/usr/lib/jvm/java-6-sun/jre/lib/ext folder). To my relief, my test program
110
did NOT throw an error this time. I did get a warning that looked like this:
111

  
112
WARNING:  RXTX Version mismatch
113
        Jar version = RXTX-2.2
114
        native lib Version = RXTX-2.2pre2 
115

  
116
(versions are not the same as the versions I saw, but I did have a mismatch
117
warning). To solve this, I just went back to the development wiki and
118
found the version that made these two lines agree (turned out to be 
119
rxtx-2.2pre2). Now (finally), my little test program can find the 'arduino'
120
and 'robot#' ports and listen to them!
121

  
122
Hope this helps for anyone who has to take this project up after me!
trunk/code/projects/calibration_platform/server/cal_sta_server/SimpleRead.java
1
import gnu.io.*;
2

  
3
public class SimpleRead {
4

  
5
	static CommPortIdentifier portId;
6
    static Enumeration	      portList;
7
    InputStream		      inputStream;
8
    SerialPort		      serialPort;
9
    Thread		      readThread;
10

  
11
    public static void main(String[] args) {
12
    boolean		      portFound = false;
13
    String		      defaultPort = "/dev/ttyUSB0";
14

  
15
 	if (args.length > 0) {
16
	    defaultPort = args[0];
17
	} 
18
   
19
	portList = CommPortIdentifier.getPortIdentifiers();
20

  
21
	while (portList.hasMoreElements()) {
22
	    portId = (CommPortIdentifier) portList.nextElement();
23
	    if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
24
		if (portId.getName().equals(defaultPort)) {
25
		    System.out.println("Found port: "+defaultPort);
26
		    portFound = true;
27
		    SimpleRead reader = new SimpleRead();
28
		} 
29
	    } 
30
	} 
31
	if (!portFound) {
32
	    System.out.println("port " + defaultPort + " not found.");
33
	} 
34

  
35
    Opens
36
    } 
37

  
38
    /**
39
     * Constructor declaration
40
     *
41
     *
42
     * @see
43
     */
44
    public SimpleRead() {
45
	try {
46
	    serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
47
	} catch (PortInUseException e) {}
48

  
49
	try {
50
	    inputStream = serialPort.getInputStream();
51
	} catch (IOException e) {}
52

  
53
	try {
54
	    serialPort.addEventListener(this);
55
	} catch (TooManyListenersException e) {}
56

  
57
	serialPort.notifyOnDataAvailable(true);
58

  
59
	try {
60
	    serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, 
61
					   SerialPort.STOPBITS_1, 
62
					   SerialPort.PARITY_NONE);
63
	} catch (UnsupportedCommOperationException e) {}
64

  
65
	readThread = new Thread(this);
66

  
67
	readThread.start();
68
    }
69

  
70
    /**
71
     * Method declaration
72
     *
73
     *
74
     * @see
75
     */
76
    public void run() {
77
	try {
78
	    Thread.sleep(20000);
79
	} catch (InterruptedException e) {}
80
    } 
81

  
82
    /**
83
     * Method declaration
84
     *
85
     *
86
     * @param event
87
     *
88
     * @see
89
     */
90
    public void serialEvent(SerialPortEvent event) {
91
	switch (event.getEventType()) {
92

  
93
	case SerialPortEvent.BI:
94

  
95
	case SerialPortEvent.OE:
96

  
97
	case SerialPortEvent.FE:
98

  
99
	case SerialPortEvent.PE:
100

  
101
	case SerialPortEvent.CD:
102

  
103
	case SerialPortEvent.CTS:
104

  
105
	case SerialPortEvent.DSR:
106

  
107
	case SerialPortEvent.RI:
108

  
109
	case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
110
	    break;
111

  
112
	case SerialPortEvent.DATA_AVAILABLE:
113
	    byte[] readBuffer = new byte[20];
114

  
115
	    try {
116
		while (inputStream.available() > 0) {
117
		    int numBytes = inputStream.read(readBuffer);
118
		} 
119

  
120
		System.out.print(new String(readBuffer));
121
	    } catch (IOException e) {}
122

  
123
	    break;
124
	}
125
    } 
126

  
127
}
trunk/code/projects/calibration_platform/server/cal_sta_server/SimpleSerial.java
1
import java.io.*;
2
import java.util.Enumeration;
3
import gnu.io.*;
4

  
5
import java.lang.Character;
6

  
7
public class SimpleSerial {
8

  
9
	public static void main(String[] args) {
10
		
11
		String port_path = "/dev/ttyUSB0";
12
/*
13
		FileInputStream port_stream;
14
		
15
		try {
16
			port_stream = new FileInputStream(port_path);
17
		} catch (IOException e) {
18
			System.out.print(e);
19
		}
20
		
21
		port_stream.getFD()
22
*/
23
		
24
		
25
		Enumeration ports = CommPortIdentifier.getPortIdentifiers();
26
		CommPortIdentifier port = null, arduino = null;
27
		
28
		SerialPort ser = null;
29
		InputStream inSt = null;
30
		
31
		while (ports.hasMoreElements()) {
32
			
33
			port = (CommPortIdentifier)ports.nextElement();
34
			
35
			System.out.println(port.getName());
36
			
37
			if (port.getName().equals("/dev/arduino")) {
38
				arduino = port;
39
			}
40
			
41
		}
42
		
43
		System.out.println(arduino.getName());
44
		
45
		try{
46
			ser = (SerialPort) arduino.open("cal_sta_server", 2000);
47
		} catch (PortInUseException e) {System.out.print(e);}
48
		
49
		try {
50
		    inSt = ser.getInputStream();
51
		} catch (IOException e) {System.out.print(e);}
52
		
53
		try {
54
		    ser.setSerialPortParams(19200, SerialPort.DATABITS_8, 
55
						   SerialPort.STOPBITS_1, 
56
						   SerialPort.PARITY_NONE);
57
		} catch (UnsupportedCommOperationException e) {}
58
		
59
		while (true) {
60
			
61
			try {
62
				if (inSt.available() > 0) {
63
					System.out.print((char)inSt.read());
64
				}
65
			} catch (IOException e) {System.out.print(e);}
66
			
67
		}
68
		
69
	}
70

  
71
}

Also available in: Unified diff