Receiving data of RS-232C device using java - java

I have recently purchased a USB Bar code scanner. It has 3 different interface selection options:
RS-232C
USB
Wand Emulation
The requirement is only to receive the scanned bar-code using RS-232C interface with the help of Java (Rxtx API).
So as far as I know, I will need a COM Port to be defined in RXTX to start interaction with the device
But the problem is I am not able to find out its COM Port while using in RS-232C interface.
Is there anything that I am missing while communicating a RS-232C port, How can I find the port number.
Please help me in this.
Update: As suggested I scanned my system for all the serial ports using the code below(using JSSC)
import jssc.SerialPortList;
public class Main {
public static void main(String[] args) {
String[] portNames = SerialPortList.getPortNames();
for(int i = 0; i < portNames.length; i++){
System.out.println(portNames[i]);
}
}
}
One thing to note: when I connect my barcode scanner and remove the scanner, there is no change in the port list obtained by the above code.
Output:
COM3
COM11
COM18
COM32
COM33
COM34
COM35
COM36
COM37
COM38
COM39
COM40
COM42
COM45
COM52
COM53
COM59
COM60
COM61
COM62
COM63
After the output I tried to listen each of the above port one by one using the following code:
import jssc.SerialPort;
import jssc.SerialPortException;
public class Main {
public static void main(String[] args) {
SerialPort serialPort = new SerialPort("COM63"); //manually setting all the ports above one by one
try {
serialPort.openPort();//Open serial port
byte[] buffer = serialPort.readBytes(10);
System.out.println(buffer.toString());
serialPort.closePort();//Close serial port
}
catch (SerialPortException ex) {
System.out.println(ex);
}
}
}
I got either the port is busy or no output (In the meanwhile I kept on scanning using my barcode scanner)

Here's a solution posted elsewhere on StackOverflow. Basically you need to cycle your available comports from your OS and display/select the intended one. If you're having trouble with this please post some code for us to review.

I'm unfamiliar with those APIs, but fairly familiar with the electrical end of the COM port. There is no automatic "handshake" that indicates whether a device is attached or not, unlike a USB port. However, there are several status lines that are present in the interface.
In addition to the TD/RD signals (transmitted data/received data) there are RTS/CTS -- Request To Send and Clear To Send. RTS and CTS are such that they go "not ready" when nothing is connected.
The usual protocol is that the device asserts RTS and then the other end returns CTS to indicate that everything is ready. However, this is all complicated by the fact that the computer can appear as either a "device" or a "modem" (the only two things that RS-232 knows about). The result is that you can have several different configurations of pins and signals, depending on the assumed modes of the two pieces. (If you're lucky the scanner docs describe some of this.)
Further complicating things is that there are DSR/DTR signals -- Data Set (Modem) Ready and Data Terminal Ready. In most PC configurations these are ignored, but not always.
So, if you don't have luck soon with your scanning you may have to look at the pinouts and use a voltmeter and some jumpers to set you're physical port in a state that the scanner will find. Then there will be further experimentation to determine how to set up the status signals to get the scanner to talk.

Related

Problems with connecting to the serial port of the arduino using processing

First of all, I know this question has been asked a lot but I can't find any answer that solves my problem. So when I try to use processing to write stuff to the serial monitor of the Arduino it says that the port (in my case "com3") is busy. I have no idea with what it could be busy because I already set a delay on the reading of the serial-monitor.
Arduino code:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
// Serial.println("started");
// Serial.println();
}
void loop() {
if(Serial.available()){
char ch = (char) Serial.read();
Serial.println(ch);
ch = "";
delay(100);
}
Processing code:
import processing.serial.*;
Serial sPort;
String port;
void setup() {
port = Serial.list()[0];
sPort = new Serial(this, port, 9600);
//port.write("hey, its working");
}
I know it is really basic but I made the code as small as possible while still showing the problem
Thanks in advance
It seems, that you try to access the Serial port from your running Processing sketch at the same time as from the Arduino Serial Monitor.
It is important to note, that the Arduino IDE Serial Monitor is itself a process, that communicates with your Arduino. The Arduino can not, at the same time, talk to the Serial Monitor and another Program.
But you are halfway to monitor what your Arduino has to say. Use Processing instead.
You are already sending the message back. All you have to do is to log incoming Serial messages in your Processing app.
Just add this to your Processing draw loop:
if (sPort.available() > 0) {
print(sPort.readSring());
}
Close the Arduino Serial Monitor, run the Processing Sketch and you should see whatever you sent (using Serial.print in Arduino) in the Processing Console.
Serial.print, just like Serial.read are functions to communicate with any program on the computer once you plugged the USB cable. Serial Monitor is one of them, but there are many others and among them is Processing.

How to get to know what ports are taken?

I am creating a simple learning project (chat using sockets) in Java and today I faced a problem. Maybe the point is an obvious one for somebody, but I am confused with it
The purpose
To get to know (at least one of the following):
A list of the currently opened free/taken ports on a PC
Whether the port I want to use is locked
What I tried
I've created a simple raw-project and run two ServerSocket on one port. In this case I have caught a java.net.BindException with notification that "...Address already in use: JVM_Bind...". But in this way I am able to check the port avaliability only if my JVM has captured it. In case if other program listens to the port, I do not know anything about it. I am adding a code below.
public class Main {
public static void main(String[] args) throws IOException {
MyThread myThread = new MyThread();
ServerSocket serverSocket = new ServerSocket(5940);
myThread.start();
serverSocket.accept();
}
}
public class MyThread extends Thread {
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(5940);// exception is thrown here
serverSocket.accept();
} catch (IOException e) {
System.err.println("SECOND SERVER");
e.printStackTrace();
interrupt();
}
}
}
PS Any advice is warmly welcomed
I've created a simple raw-project and run two ServerSocket on one
port. In this case I have caught a java.net.BindException with
notification that "...Address already in use: JVM_Bind...". But in
this way I am able to check the port avaliability only if my JVM has
captured it. In case if other program listens to the port, I do not
know anything about it.
I think you're misinterpreting your result. I have every reason to believe that if the port you request is already bound by any process then your attempt to bind it will fail with a BindException. That takes care of
Whether the port I want to use is locked
. As for
A list of the currently opened free/taken ports on a PC
, there are system utilities that can get you that information, but it is useless to you. Whichever end initiates the connection (i.e. the client) needs to know in advance what port to try to connect to. It cannot get that from the server, because that presents a chicken & egg problem.
The usual approach is that the server listens to a specific port chosen by its developer or its admin, and that port number is provided to clients out of band -- often simply by it being a standard, well-known port number. That's how most of the basic network protocols work; for example, HTTP servers run on port 80 by default. If the wanted port happens to be unavailable when the server attempts to bind to it then that indicates a misconfiguration of the machine, and the server simply fails to start.
The client, on the other hand, does not need to choose a port number at all. The system will choose one for it automatically when it attempts to connect to the server.

Java check com port connection

I am looking for a bit of efficient code that can assist me in monitoring if a com port is still open using the RX/TX libraries.
Lets say I have a hardware device that communicates to the PC using a virtual com port and that device can be plugged in and out at any time. I want to show a connection status on the pc.
I have tried this with something like a buffered reader below and it registered that the device gets disconnected but I have to re-open the port from scratch in another method.
I am looking from something short like comPort.isOpen () or something?
// Set the value of is running
Start.isRunning = true;
// Check to see if the device is connected
while (Start.isRunning) {
// Try to connect to the device
try {
// Create a Buffered Reader
BufferedReader reader = new BufferedReader(
new InputStreamReader(serialPort.getInputStream()));
// Read the output
if (Character.toString((char) reader.read()).equalsIgnoreCase(
"^")) {
// Set the connected flag
Start.CONNECTED_FLAG = true;
// Set the connected fag
AddComponents.TFconnected.setText("Connected");
}
// Close the reader
reader.close();
// Let the thread sleep
Thread.sleep(500);
}
// Catch a error if the device is disconnected
catch (Exception err) {
// Set the connected flag
Start.CONNECTED_FLAG = false;
// Set the connected fag
AddComponents.TFconnected.setText("Disconnected");
// Let the thread sleep
Thread.sleep(500);
}
}
Disclaimer: Consider this a partial answer because I do not have intimate knowledge of the workings of serial ports, and my tests could not produce anything useful. Posting here regardless in the hopes any of this is helpful.
Unfortunately, as far as I know, there is no way to receive any kind of "connection / disconnection" event messages. Sadly, as I am not intimately familiar with the workings of serial ports, I cannot give you a full and proper explanation. However, from some research, one of the answers posted in that forum had this to say:
There's no event by the system to inform you of [a disconnection event] because that would require exclusive use of the COM port. If you have a SerialPort object created and have opened a port you should get a CDChanged when a devices is plugged in and unplugged from the serial port. That assumes the device follows the pins standards; not all devices do.
Note that the poster, and the link I've provided, are discussing this within the context of C#. However this seems to be related to how the ports work in general, regardless of language, so I am somewhat confident the same can be applied to RXTX Java.
There are some events you can attempt to listen for. In my tests I was only ever able to receive the DATA_AVAILABLE event, however my setup is a bit different (Raspberry PI) and I can't at the moment physically disconnect the device from the port, I can only attempt to block the device file (which may explain the failure of my test).
If you would like to attempt the event listening yourself, have your class implement SerialPortListener, register for the desired events, check the events in your serialEvent method. Here is an example:
public class YourClass implements SerialPortListener{
private SerialPort serialPort;
// ... serial port gets set up at some point ...
public void registerEvents(){
serialPort.addEventListener(this);
// listen to all the events
serialPort.notifyOnBreakInterrupt(true);
serialPort.notifyOnCarrierDetect(true);
serialPort.notifyOnCTS(true);
serialPort.notifyOnDataAvailable(true);
serialPort.notifyOnDSR(true);
serialPort.notifyOnFramingError(true);
serialPort.notifyOnOutputEmpty(true);
serialPort.notifyOnOverrunError(true);
serialPort.notifyOnParityError(true);
serialPort.notifyOnRingIndicator(true);
}
#Override
public void serialEvent(SerialPortEvent event) {
System.out.println("Received event. Type: " + event.getEventType() + ", old value: " + event.getOldValue() + ", new value: " + event.getNewValue());
}
}
If that ultimately fails, I believe the only other alternative is similar to your current solution; attempt to read from the port, and if it fails, consider it disconnected, and set your indicator accordingly. At each iteration, if it is disconnected, attempt to reconnect; if reconnect succeeds, reset your indicator to "connected".
Sorry I cannot be of more assistance. Hopefully some of that may lead to something useful.
Side Note:
If you want to DRY up your code slightly, put the Thread.sleep(500) in a finally block instead, since it appears to be executed regardless.

Dynamically find other hosts in a LAN in Java

A while ago I developed a little LAN chat app. in Java which allows chatting with other hosts, send images, etc. Although it was created just for fun, now it's being used where I work.
Currently, there is no "chat server" on the app. where each client registers, updates it's status, etc. (I liked the idea of symmetric design and not depending on a server running on some other machine).
Instead, each host is a client/server which has a hosts.properties file with the hostname of the other hosts, and - for instance - broadcasts to each one of them when sending a massive message/image/whatever.
In the beginning there were just a couple of hosts, so this hosts.properties file wasn't an issue. But as the amount of users increased, the need of updating that file was a bit daunting. So now I've decided to get rid of it, and each time the app. starts, dynammically find the other active hosts.
However, I cannot find the correct way of implement this. I've tried starting different threads, each one of them searching for other hosts in a known range of IP addresses. Something like this (simplified for the sake of readability):
/** HostsLocator */
public static void searchForHosts(boolean waitToEnd) {
for (int i=0; i < MAX_IP; i+= MAX_IP / threads) {
HostsLocator detector = new HostsLocator(i, i+(MAX_IP / threads - 1)); // range: from - to
new Thread(detector).start();
}
}
public void run() {
for (int i=from; i<=to; i++)
findHosts( maskAddress + Integer.toString(i) );
}
public static boolean findHosts(String IP) {
InetAddress address = InetAddress.getByName(IP);
if ( address.isReachable(CONNECTION_TIME_OUT) )
// host found!
}
However:
With a single thread and a low value in CONNECTION_TIME_OUT (500ms) I get wrong Host Not Found status for for hosts actually active.
With a high value in CONNECTION_TIME_OUT (5000ms) and only one single thread takes forever to end
With several threads I've also found problems similar like the first one, due to collisions.
So... I guess there's a better way of solving this problem but I couldn't find it. Any advice? Thanks!
You could try UDP Broadcast to a specific port. All running instances of your app on the network could listen to that port and then respond with a message identifying them as a host.
You could do this a lot easier using UDP. Check this tutorial for examples.
Use Bonjour/Zeroconf.
The jmdns project has all you need.
For finding all hosts in lan in java execute commands from java and add the result to JList
Here is the small code that will help to you to read all hosts in lan in windows there will be other commands for other os take look at the following code
try {
Runtime rt = Runtime.getRuntime();
FileWriter write=new FileWriter("mylist.txt");
BufferedWriter writer=new BufferedWriter(write);
Process pr = rt.exec("net view");
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line=null;
String hosts="";
while((line=input.readLine()) != null) {
Thread.sleep(100);
if((!(line.equals("")))&&(!(line.equalsIgnoreCase("Server Name Remark")))&&(!(line.equalsIgnoreCase("-------------------------------------------------------------------------------")))&&(!(line.equalsIgnoreCase("The command completed successfully."))))
{
line=line.replace('\\',' ');
line=line.trim();
listModel.addElement(line);
hosts=hosts+line.trim()+",";
hosts=hosts.trim();
}
}
writer.write(hosts);
writer.close();
} catch(Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
Each host keeps track of all the hosts they have met. When you shut down, save the known hosts to file and reuse the next time you start up.
Every so many minutes, send each of the known hosts a list of all known hosts.
That way
a) No network scanning
b) A new host will spread around the network
Then when a new host joins, he just needs to know 1 other host to learn about everyone.
A host that isn't seen for a week, or is seen from a new IP is dropped from the list of updated.
You could attempt to use DNS service discovery
There seems to be a project on sourceforge (that I have not looked at, beyond doing a cursory search...)

Issues receiving in RXTX

I've been using RXTX for about a year now, without too many problems. I just started a new program to interact with a new piece of hardware, so I reused the connect() method I've used on my other projects, but I have a weird problem I've never seen before.
The Problem
The device works fine, because when I connect with HyperTerminal, I send things and receive what I expect, and Serial Port Monitor(SPM) reflects this.
However, when I run the simple HyperTerminal-clone I wrote to diagnose the problem I'm having with my main app, bytes are sent, according to SPM, but nothing is received, and my SerialPortEventListener never fires. Even when I check for available data in the main loop, reader.ready() returns false. If I ignore this check, then I get an exception, details below.
Relevant section of connect() method
// Configure and open port
port = (SerialPort) CommPortIdentifier.getPortIdentifier(name)
.open(owner,1000)
port.setSerialPortParams(baud, databits, stopbits, parity);
port.setFlowControlMode(fc_mode);
final BufferedReader br = new BufferedReader(
new InputStreamReader(
port.getInputStream(),
"US-ASCII"));
// Add listener to print received characters to screen
port.addEventListener(new SerialPortEventListener(){
public void serialEvent(SerialPortEvent ev) {
try {
System.out.println("Received: "+br.readLine());
} catch (IOException e) { e.printStackTrace(); }
}
});
port.notifyOnDataAvailable();
Exception
java.io.IOException: Underlying input stream returned zero bytes
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:268)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.read(BufferedReader.java:157)
at <my code>
The big question (again)
I think I've eliminated all possible hardware problems, so what could be wrong with my code, or the RXTX library?
Edit: something interesting
When I open HyperTerminal after sending a bunch of commands from java that should have gotten responses, all of the responses appear immediately, as if they had been put in the buffer somewhere, but unavailable.
Edit 2: Tried something new, same results
I ran the code example found here, with the same results. No data came in, but when I switched to a new program, it came all at once.
Edit 3
The hardware is fine, and even a different computer has the same problem. I am not using any sort of USB adapter.
I've started using PortMon, too, and it's giving me some interesting results. HyperTerminal and RXTX are not using the same settings, and RXTX always polls the port, unlike HyperTerminal, but I still can't see what settings would affect this. As soon as I can isolate the configuration from the constant polling, I'll post my PortMon logs.
Edit 4
Is it possible that some sort of Windows update in the last 3 months could have caused this? It has screwed up one of my MATLAB mex-based programs once.
Edit 5
I've also noticed some things that are different between HyperTerminal, RXTX, and a separate program I found that communicates with the device (but doesn't do what I want, which is why I'm rolling my own program)
HyperTerminal - set to no flow control, but Serial Port Monitor's RTS and DTR indicators are green
Other program - not sure what settings it thinks it's using, but only SPM's RTS indicator is green
RXTX - no matter what flow control I set, only SPM's CTS and DTR indicators are on.
From Serial Port Monitor's help files (paraphrased):
the indicators display the state of the serial control lines
RTS - Request To Send
CTS - Clear To Send
DTR - Data Terminal Ready
OK, sorry it's taken me so long to come back to this question. Here's how I got things working.
Note: This method will NOT work for everyone, please read below before copy/pasting into your own code
public void connect(CommPortIdentifier portId) throws Failure {
if (portId == null)
throw new Failure("No port set");
try { port = (SerialPort) portId.open(getClass().getName(), 10000); }
catch (PortInUseException e) {
throw new Failure("Port in use by " + e.currentOwner,e); }
try {
port.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
port.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN
| SerialPort.FLOWCONTROL_RTSCTS_OUT);
} catch (UnsupportedCommOperationException e) { throw new Failure(e); }
port.setRTS(true);
// More setup
}
So, in my case, the problem was that my particular device requires RTS flow control. Other devices may require different things (CTS, XON/XOFF), so check that device's manual. By default, RXTX disables all flow control mechanisms (unlike Hypertrm or other programs). Enabling each one is a two-step process.
Once you have a SerialPort object, call the setFlowControlMode() method, and bitwise-OR ('|') the necessary SerialPort.FLOWCONTROL_ constants
Set the appropriate flow control to true or false (like I did with port.setRTS(true))
For the others with similar problems, if this doesn't work, I suggest
Using a serial port monitoring program like Serial Port Monitor and/or PortMon (both Windows) to see what is actually going on.
Emailing the RXTX developers at rxtx#qbang.org (they are very helpful)
There is a simpler solution to this problem. This is what I did:
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while (keepRunning) {
try {
while ((br.ready()) && (line = br.readLine()) != null) {
....
}
If you check that the buffer "is ready" before you read it there should be no problem.
Ok, I do realize this thread is extremely old, but none of these solutions worked for me. I had the same problem and I tried everything to fix it, to no avail. Then I did some research on what causes the problem, and, when not dealing with Serial Communication, it happens at the end of a file. So, I figured I needed to add an ending to whatever is being received by the Java Application, specifically, a line return (\n). And sure enough, it fixed the problem for me! Hopefully this helps someone new, as I'm not expecting this to help anyone already on this thread...
(might be too simple, but might as well start somewhere...)
Is the port in use? Rather than:
port = (SerialPort) CommPortIdentifier.getPortIdentifier(name)
.open(owner,1000)
what about:
CommPortIdentifier portIdentifier;
try {
portIdentifier = CommPortIdentifier.getPortIdentifier(name);
} catch (NoSuchPortException nspe) {
// handle?
}
if (portIdentifier.isCurrentlyOwned()) {
// handle?
}
port = portIdentifier.open(owner, 1000);
if (!(port instanceof SerialPort)) {
// handle?
}
Are you swallowing any exceptions?
I tried RXTX a few months ago and ran into similar problems. I suggest two things:
Create a virtual comport using com0com. Enable trace logging. Compare the logs for when you use Hyperterminal versus when you run your own program. The difference will highlight what you are doing wrong.
In my humble opinion, RXTX's design is flawed and its implementation is quite buggy (take a look at its source-code, what a mess!). I've published an alternative library at http://kenai.com/projects/jperipheral with the following caveats: It's Windows-only and there are no pre-built binaries. Both of these will change in the near future. If you are interested in trying it out send me an email using http://desktopbeautifier.com/Main/contactus and I'll send you a pre-built version.
If anyone is still getting java.io.IOException: Underlying input stream returned zero bytes after you've read your characters using br.readline() for RXTX (even when you are checking first to see if br.readline() == null), just do this simple fix with a try/catch:
String line;
while (true){
try{
line = br.readLine();
}catch(IOException e){
System.out.println("No more characters received");
break;
}
//Print the line read
if (line.length() != 0)
System.out.println(line);
}
I've done some searching and it appears that this is the best/easiest way to get around this problem.
EDIT : I take that back. I tried this and still ended up having some problems. I'd recommend working with the raw InputStream directly, and implementing your own read/readLine method using InputStream.read(). That worked for me.

Categories

Resources