Reading wrong value from serial port - java

I have to read the 12-digit tag number from an RFID reader and print it to console. When I use this program to read the tag I get some weird spacing in between.
E.g. My tag number is 4400E6EF1A57. When I keep scanning this tag, the console window shows the following:
4400E6EF1
A57
4400E
6EF1A57
4400E6EF1A57
4400E6EF1
A57
4400E6EF1A57
4400
E6EF1A57
4
400E6EF1A57
4400E6EF1A
57
4
400E6EF1A57
4400E6EF1A5
7
4400E6EF1A57
4400E6EF1
A57
4400E6EF1A57
4400E
6EF1A57
4400
E6EF1A57
4400E6EF1A57
4400E6EF1A57
4400E6EF
1A57
4400E
6EF1A57
It appears to be that there is a long string of 0's and 1's that gets read in and only a few of those are the actual tag IDs. I don't know in what order I am reading these 0's and 1's.
Here is my code: (Some SQL and JDBC stuff incorporated, can ignore)
import java.io.*;
import java.util.*;
import gnu.io.*;
import java.sql.*;
public class trying5 implements Runnable, SerialPortEventListener {
static Enumeration portList;
static CommPortIdentifier portId;
SerialPort serialPort;
InputStream inputStream;
Thread readThread;
Connection con;
public static void main(String[] args) {
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (portId.getName().equals("COM3")) {
trying5 reader = new trying5();
}
}
}
}
public trying5() {
try {
serialPort = (SerialPort) portId.open("trying5Application", 2000);
}
catch (PortInUseException e)
{
System.out.println(e);
}
try {
inputStream = serialPort.getInputStream();
}
catch (IOException e)
{
System.out.println(e);
}
try {
serialPort.addEventListener(this);
}
catch (TooManyListenersException e)
{
System.out.println(e);
}
serialPort.notifyOnDataAvailable(true);
try {
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
}
catch (UnsupportedCommOperationException e)
{
System.out.println(e);
}
readThread = new Thread(this);
readThread.start();
}
public void run() {
try {
Thread.sleep(20000);
}
catch (InterruptedException e)
{
System.out.println(e);
}
}
public void serialEvent(SerialPortEvent event) {
switch(event.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
byte[] readBuffer = new byte[20];
// print to console
try {
while (inputStream.available() > 0) {
int numBytes = inputStream.read(readBuffer);
}
String newtuple = new String(readBuffer);
usercon newcon = new usercon(con, newtuple);
System.out.print(newtuple + "\n");
} catch (IOException e)
{
System.out.println(e);
}
break;
}
}
}

See http://download.oracle.com/javase/6/docs/api/java/io/InputStream.html#available()
inputstream.available - returns how many bytes you can read without blocking (blocking = waiting for more bytes)
while (inputStream.available() > 0) {
int numBytes = inputStream.read(readBuffer);
}
At some moment of time you have (for example) 3 bytes in the internal buffer, ready to be read. You read it, check with while() that there is not more ready bytes and you are out of the loop. Than you print the 3 bytes and put '\n' ...
That is the cause of your broken ids. You should read up until you fill the buffer of proper size, blocking and waiting when your device/com-port will provide enough bytes.
Use the read(buf,off,len) method
byte[] buf = new byte[12];
int len = is.read(buf,0,buf.length);
if (len != buf.length ) {
throw new RuntimeException("the stream is closed and i failed to read enough data");
}
It will block internally till the needed amount of bytes read or will return earlier if the input stream will report "i'm done" before the amount is reached.

The stream gives you what it has, and you add newlines:
System.out.print(newtuple + "\n");
you need a buffer of some sort, like BufferedInputStream.

Related

Java Multithreading for IVRS with GSM Modem rxtx (playing voice file making event listener stop working)

I have implemented a program to receive call using gsm modem. Upon Detecting "RING" call is answered an audio clip is played by calling a function from inside DATA_AVAILABLE EVENT HANDLER. But the event handler stops working after this. After the audio is complete Event Handler does not show any data received event anymore.
Why does the event listener stops working. Am I doing it wrong by playing the audio from inside the event handler? I was thinking about setting a variable true or false from inside data_received event handler and create custom event handler to listen to change to that variable to do playback of audio can these both work simultaneously in anyway?
How to create a multi threading solution So that Serial I/O is not interrupted and Audio Playback and Audio Sampling Can be done in a synchronised manner to detect dtmf tones.
Is there any way that serial port events can be listened to constantly without interruption and run a function for audio sampling and audio playback at specific time
Call Accepted in this case of switch and thread is started inside play() function
case SerialPortEvent.DATA_AVAILABLE:
StringBuffer sb = new StringBuffer();
byte[] readBuffer = new byte[2048];
try {
while (inputStream.available() > 0)
{
int numBytes = inputStream.read(readBuffer);
sb.append(new String(readBuffer,0,numBytes));
System.out.println(numBytes);
System.out.println(sb);
}
System.out.println("Data Available");
if((sb.toString()).contains("RING")){
System.out.println("Enter Inside if RING Loop");
//play();
send("ATA\r\n");
//welcomeMessage();
}
if((sb.toString()).contains("CARRIER")){
hangup();
//Thread.sleep(1000);
closePort();
outCommand();
System.out.println("Enter Inside if NO CARRIER Loop");
}
//print response message
System.out.print(sb.toString());
} catch (IOException e) {
}
break;
public void play() {
try {
new Thread() {
public void run() {
for(int i=0;i<1;i++)
welcomeMessage();
}
}.start();
} catch (Throwable e) {
e.printStackTrace();
}
}
Full Code
package sample;
import java.io.*;
import java.util.*;
import javax.sound.sampled.*;
import javazoom.jl.player.*;
import java.io.FileInputStream;
import gnu.io.*;
import java.io.*;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import org.apache.log4j.chainsaw.Main;
import sun.audio.*;
public class GSMConnect implements SerialPortEventListener,
CommPortOwnershipListener {
private static String comPort = "COM3"; // This COM Port must be connect with GSM Modem or your mobile phone
private String messageString = "";
private CommPortIdentifier portId = null;
private Enumeration portList;
private InputStream inputStream = null;
private OutputStream outputStream = null;
private SerialPort serialPort;
String readBufferTrial = "";
/** Creates a new instance of GSMConnect */
public GSMConnect(String comm) {
this.comPort = comm;
}
public boolean init() {
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (portId.getName().equals(comPort)) {
System.out.println("Got PortName");
return true;
}
}
}
return false;
}
public void checkStatus() {
send("AT+CREG?\r\n");
}
public void dial(String phoneNumber) {
try {
//dial to this phone number
messageString = "ATD" + phoneNumber + ";\r\n";
outputStream.write(messageString.getBytes());
System.out.println("Called ");
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String cmd) {
try {
outputStream.write(cmd.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessage(String phoneNumber, String message) {
char quotes ='"';
send("AT+CMGS="+quotes + phoneNumber +quotes+ "\r\n");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// send("AT+CMGS=\""+ phoneNumber +"\"\r\n");
send(message + '\032');
System.out.println("Message Sent");
}
public void hangup() {
send("ATH\r\n");
}
public void welcomeMessage(){
// open the sound file as a Java input stream
String gongFile = "C:\\Users\\XXXX\\Desktop\\1-welcome.wav";
}*/
try{
FileInputStream fis = new FileInputStream("C:\\Users\\XXXX\\Desktop\\7001110.mp3");
Player playMP3 = new Player(fis);
playMP3.play();
System.out.print("welcomeMessage() Read");
}catch(Exception e){
System.out.println(e);
}
}
public void play() {
try {
new Thread() {
public void run() {
for(int i=0;i<1;i++)
welcomeMessage();
}
}.start();
} catch (Throwable e) {
e.printStackTrace();
}
}
public void connect() throws NullPointerException {
if (portId != null) {
try {
portId.addPortOwnershipListener(this);
serialPort = (SerialPort) portId.open("MobileGateWay", 2000);
serialPort.setSerialPortParams(115200,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
} catch (PortInUseException | UnsupportedCommOperationException e) {
e.printStackTrace();
}
try {
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
/** These are the events we want to know about*/
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
serialPort.notifyOnRingIndicator(true);
} catch (TooManyListenersException e) {
e.printStackTrace();
}
//Register to home network of sim card
send("ATZ\r\n");
} else {
throw new NullPointerException("COM Port not found!!");
}
}
public void serialEvent(SerialPortEvent serialPortEvent) {
System.out.println("serialPortEvent.getEventType()"+serialPortEvent.getEventType());
switch (serialPortEvent.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
// System.out.println("Ringing");
if( serialPortEvent.getNewValue() )
{
System.out.println("Ring Indicator On");
}
else
{
System.out.println("Ring Indicator Off");
}
break;
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
case SerialPortEvent.DATA_AVAILABLE:
StringBuffer sb = new StringBuffer();
byte[] readBuffer = new byte[2048];
try {
while (inputStream.available() > 0)
{
int numBytes = inputStream.read(readBuffer);
sb.append(new String(readBuffer,0,numBytes));
System.out.println(numBytes);
System.out.println(sb);
}
System.out.println("Data Available");
if((sb.toString()).contains("RING")){
System.out.println("Enter Inside if RING Loop");
//play();
send("ATA\r\n");
//welcomeMessage();
}
if((sb.toString()).contains("CARRIER")){
hangup();
//Thread.sleep(1000);
closePort();
outCommand();
System.out.println("Enter Inside if NO CARRIER Loop");
}
//print response message
System.out.print(sb.toString());
} catch (IOException e) {
}
break;
}
}
public void outCommand(){
System.out.print(readBufferTrial);
}
public void ownershipChange(int type) {
switch (type) {
case CommPortOwnershipListener.PORT_UNOWNED:
System.out.println(portId.getName() + ": PORT_UNOWNED");
break;
case CommPortOwnershipListener.PORT_OWNED:
System.out.println(portId.getName() + ": PORT_OWNED");
break;
case CommPortOwnershipListener.PORT_OWNERSHIP_REQUESTED:
System.out.println(portId.getName() + ": PORT_INUSED");
break;
}
}
public void closePort(){
serialPort.close();
}
public static void main(String args[]) {
GSMConnect gsm = new GSMConnect(comPort);
if (gsm.init()) {
try {
System.out.println("Initialization Success");
gsm.connect();
Thread.sleep(5000);
gsm.checkStatus();
Thread.sleep(5000);
// System.out.println("Before Auto Answer");
// gsm.send("ATS0=5");
// gsm.dial("87XXXXXSS");
// Thread.sleep(7500);
// System.out.println("After Auto Answer set");
// gsm.sendMessage("8XXXXXS56", "Trial Success Call me");
// gsm.sendMessage("80XXXXS56", "Trial Success Call me");
// gsm.sendMessage("8XXXXSXS6", "Trial Success Call me");
// Thread.sleep(5000);
// gsm.sendMessage("+919XXXXXXS3", "Third Msg");
// Thread.sleep(1000);
// gsm.dial("9XXXXS773");
// gsm.dial("871XXXXS5");
// Thread.sleep(1000);
// gsm.welcomeMessage();
// Thread.sleep(1000);
// gsm.welcomeMessage();// for turning on Echo ATE1&W
// Thread.sleep(20000);
// welcomeMessage();
// gsm.hangup();
// Thread.sleep(1000);
// gsm.closePort();
// gsm.outCommand();
// System.exit(1);
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println("Can't init this card");
}
}
}
Short of spending a good amount of time reproducing your environment I can give you two suggestions on how you might look into this.
a) Place a try-catch Throwable around your entire handler--often throwing exceptions can break event dispatchers
B) print out a debug statement when you enter and exit your event handler and ensure they are paired and that you get an exit after your last enter--a thread locking up will sometimes stop future events from being dispatched.
By the way you have an empty catch statement in one place--those scare the crap out of me because they often mask problems in ways that can waste days of your time. If you absolutely know you want to silently eat an exception there and you expect that exception to occur enough that it would pollute your logs to log it, please put a comment saying so.

Reading from a port in Java

Here is the scenario:
1. I have a GSM modem which is connected to my computer, It's working I can read and send SMS via the built-in program.
2. The port assign to my gsm modem is COM11 . I saw it from DeviceManager -> modems -> myModem-> Advance -> AdvancePortSettings.
3. I write the Java code to read incomming message.
The code is as follows:
public class PScanner implements SerialPortEventListener, Runnable {
CommPortIdentifier pid = null;
SerialPort sp;
BufferedReader input;
OutputStream output;
public PScanner() {
try {
Enumeration e = CommPortIdentifier.getPortIdentifiers();
while (e.hasMoreElements()) {
CommPortIdentifier cpi = (CommPortIdentifier) e.nextElement();
if (cpi.getName().equals("COM11")) {
pid = cpi;
break;
}
}
sp = (SerialPort) pid.open(getClass().getName(), 2000);
sp.setSerialPortParams(115200, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
InputStream is = sp.getInputStream();
input = new BufferedReader(new InputStreamReader(is));
output = sp.getOutputStream();
sp.addEventListener(this);
sp.notifyOnDataAvailable(true);
new Thread(this).start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public synchronized void serialEvent(SerialPortEvent oEvent) {
System.out.println("serialEvent CallBack");
}
public synchronized void close() {
if (sp != null) {
sp.removeEventListener();
sp.close();
}
}
#Override
public void run() {
try {
Thread.sleep(20000);
} catch (InterruptedException ex) {
Logger.getLogger(PScanner.class.getName()).log(Level.SEVERE, null, ex);
} finally {
System.out.println("done");
}
}
}
When I send an SMS on the GSM modem, I am not getting in serialEvent() call back method.
Do anyone know what is going on? I am not getting any error or exceptions.
This isn't a definitive answer, but your code has made several question marks appear above my head.
To answer why you're not getting anything in the method listening on the SerialEvent, it might be that you are adding the listener after the event has happened.
Try moving sp.addEventListener(this); further up, just after 'pid.open'.
However think a bit about what the thread is doing. All your code is in the constructor of your class, then at the end of the constructor, after everything has happened, you call thread.start(), so none of your code is running in a separate thread. Your run method actually does nothing except send the thread to sleep after everything has happened.
Move all your code from the constructor to the run() method if you want it to run in a separate thread.
The following code , is to send and read message using a GSM module, this may help you
import java.sql.*;
import java.io.*;
import java.util.*;
import java.text.*;
import gnu.io.*;
public class SerialComm implements SerialPortEventListener
{
int result=0;
static CommPortIdentifier portId=null;
Enumeration portList=null;
static InputStream inputStream=null;
static OutputStream out=null;
static SerialPort serialPort=null;
static int srate=9600;//B-Rate
String data=null;
int i=0;
String number="";
int status=0;
public String recvdData="aa";
String pswd="";
String actualpswd="";
public static void main(String args[])
{
SerialComm obj=new SerialComm();
}
public SerialComm()
{
try
{
if(this.detectPort())
{
if(this.initPort())
{
//Thread.sleep(2000);
// sendMessage();
}
}
}
catch(Exception e)
{
System.out.println("Error in SerialComm()-->"+e);
}
}
public boolean detectPort()
{
boolean portFound = false;
//String defaultPort = "/dev/ttyUSB0";
String defaultPort = "COM1";
try
{
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements())
{
CommPortIdentifier portID = (CommPortIdentifier) portList.nextElement();
if (portID.getPortType() == CommPortIdentifier.PORT_SERIAL)
{
if (portID.getName().equals(defaultPort))
{
this.portId=portID;
System.out.println("Found port: "+portId.getName());
portFound = true;
break;
}
}
}
if (!portFound)
{
System.out.println("port " + defaultPort + " not found.");
}
}
catch(Exception e)
{
portFound = false;
}
return portFound;
}
public boolean initPort()
{
try
{
serialPort = (SerialPort) portId.open("SerialCommApp", 2000);
}
catch (PortInUseException e)
{
System.out.println("Port in use-->"+e);
}
try
{
inputStream = serialPort.getInputStream();
out=serialPort.getOutputStream();
}
catch (IOException e)
{
System.out.println("IO Error-->"+e);
}
try
{
serialPort.addEventListener(this);
}
catch (TooManyListenersException e)
{
System.out.println("Too many LIstener-->"+e);
}
serialPort.notifyOnDataAvailable(true);
try
{
serialPort.setSerialPortParams(srate, SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT);
}
catch (UnsupportedCommOperationException e)
{
System.out.println("Error while setting parameters-->"+e);
}
System.out.println("Port Initialized....");
return true;
}
public synchronized void serialEvent(SerialPortEvent event)
{
switch (event.getEventType())
{
case SerialPortEvent.DATA_AVAILABLE:
System.out.println("DATA_AVAILABLE");
byte[] readBuffer = new byte[1024];
int numBytes=1024;
data="";
try
{
Thread.sleep(100);
while (inputStream.available() > 0)
{
numBytes = inputStream.read(readBuffer);//count of reading data
data=data+new String(readBuffer,0,numBytes);
data=data.trim();
this.recvdData+=data;
}
System.out.println("data=========="+this.recvdData);
}
catch (Exception e)
{
System.out.println("Exception in serial event-->"+e);
}
break;//break from switch case 1:
}//end of switch
}
Method to read Message
public void sendMessage(String num, String msg) {
try{
System.out.println("Sending Message");
this.recvdData="";
String dq=String.valueOf((char)34);
String mysms="AT+CMGS="+dq+num+dq;
out.write(mysms.getBytes());
out.write(13);
Thread.sleep(500);
mysms=msg;
out.write(mysms.getBytes());
out.write(26);
out.write(13);
Thread.sleep(500);
if(this.recvdData.contains("OK"))
{
return;
}else if(this.recvdData.contains(">")){
out.write(26);
out.write(13);
sendMessage(num,msg);
}else{
sendMessage(num,msg);
}
return;
}catch(Exception e){
System.out.println(e);
}
}
Check these code, i got the output by using this code,

Java/Arduino - Read data from the Serial Port

I've got a program in Java where I have to read the information that an Arduino is sending.
I took the Java code from here. Now, I didn't really understand how it works, but I tried to modify it and I got this:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.util.Enumeration;
public class Serial implements SerialPortEventListener {
SerialPort serialPort;
private static final String PORT_NAMES[] = {
"/dev/tty.usbserial-A9007UX1", // Mac OS X
"/dev/ttyUSB0", // Linux
"COM3", // Windows
};
private BufferedReader input;
private static OutputStream output;
private static final int TIME_OUT = 2000;
private static final int DATA_RATE = 115200;
public void initialize() {
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
for (String portName : PORT_NAMES) {
if (currPortId.getName().equals(portName)) {
portId = currPortId;
break;
}
}
}
if (portId == null) {
System.out.println("Could not find COM port.");
return;
}
try {
serialPort = (SerialPort) portId.open(this.getClass().getName(),TIME_OUT);
serialPort.setSerialPortParams(DATA_RATE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
output = serialPort.getOutputStream();
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
}
catch (Exception e) {
System.err.println(e.toString());
}
}
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=input.readLine();
System.out.println(inputLine);
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
public Serial(String ncom){
if(Integer.parseInt(ncom)>=3 && Integer.parseInt(ncom)<=9)
PORT_NAMES[2] = "COM" + ncom;
initialize();
Thread t=new Thread() {
public void run() {
try {Thread.sleep(1000000);} catch (InterruptedException ie) {}
}
};
t.start();
System.out.println("Serial Comms Started");
}
public synchronized void send(int b){
try{
output.write(b);
}
catch (Exception e) {
System.err.println(e.toString());
}
}
public synchronized int read(){
int b = 0;
try{
b = (int)input.read();
}
catch (Exception e) {
System.err.println(e.toString());
}
return b;
}
}
I create the object Serial with the COM port I need in the main program, then I use Serial.read and Serial.write when I need it.
Serial.write works great, Arduino gets the data and show it in a LCD Display. The problem is Serial.read. When the program is running, it keep read from serial port (around every 40 ms), but that doesn't mean Arduino sent something. Arduino sends a byte only when a button is pushed. So, when the Java code is running, it throws "n" Exception before read something, and this couses so much lag.
I know I need something like Serial.available(), I tried input.available(), but it doesn't work. I don't know how to solve this problem.
If you have a code that working, I'd be so much grateful if you could give it to me. I just need two methods, read and write, I don't care how the code works :D
EDIT:
I changed the Serial class, now it has again this method as apremalal said
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=null;
if (input.ready()) {
inputLine = input.readLine();
panel.read(inputLine);
}
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
and in the other class (Panel in this case) I've got this:
public void read(String data){
System.out.println(data);
System.out.println(data == "255");
if(data == "255")
//code here
}
It print the values correctly but data == "255" is always false, even if I really get a 255
....I tried to do Integer.parseInt but nothing changed. Why the hell?
EDIT 2: Ok solved :\
public void read(String data){
serialRead = Integer.parseInt(data);
if(serialRead == 255)
//code here
}
Now it's work..don't know why I had to do this... meh whatever :)
You don't want to specifically write a read function it's already there in the sample code.As TheMerovingian pointed out you can check the input Buffer before reading.Here is the working code which I have used in one of my projects.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.util.Enumeration;
public class SerialTest implements SerialPortEventListener {
SerialPort serialPort;
/** The port we're normally going to use. */
private static final String PORT_NAMES[] = { "/dev/tty.usbserial-A9007UX1", // Mac OS X
"/dev/ttyUSB0", // Linux
"COM35", // Windows
};
private BufferedReader input;
private OutputStream output;
private static final int TIME_OUT = 2000;
private static final int DATA_RATE = 9600;
public void initialize() {
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
//First, Find an instance of serial port as set in PORT_NAMES.
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
for (String portName : PORT_NAMES) {
if (currPortId.getName().equals(portName)) {
portId = currPortId;
break;
}
}
}
if (portId == null) {
System.out.println("Could not find COM port.");
return;
}
try {
serialPort = (SerialPort) portId.open(this.getClass().getName(),
TIME_OUT);
serialPort.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// open the streams
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
output = serialPort.getOutputStream();
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
System.err.println(e.toString());
}
}
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=null;
if (input.ready()) {
inputLine = input.readLine();
System.out.println(inputLine);
}
} catch (Exception e) {
System.err.println(e.toString());
}
}
// Ignore all the other eventTypes, but you should consider the other ones.
}
public static void main(String[] args) throws Exception {
SerialTest main = new SerialTest();
main.initialize();
Thread t=new Thread() {
public void run() {
//the following line will keep this app alive for 1000 seconds,
//waiting for events to occur and responding to them (printing incoming messages to console).
try {Thread.sleep(1000000);} catch (InterruptedException ie) {}
}
};
t.start();
System.out.println("Started");
}
}
EDIT : serialEvent function is responsible for reading the buffer.
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
String inputLine=null;
if (input.ready()) {
inputLine = input.readLine();
System.out.println(inputLine);
}
} catch (Exception e) {
System.err.println(e.toString());
}
}
// Ignore all the other eventTypes, but you should consider the other ones.
}
The BufferedReader class has a ready() method that returns True if "the buffer is not empty, or if the underlying character stream is ready." and False otherwise. So you could add a check in the read() method to make sure there is data to be read before trying to read.
public synchronized int read(){
int b = 0;
try{
if (input.ready()) {
b = (int)input.read();
}
}catch (Exception e) {
System.err.println(e.toString());
}
return b;
}
It looks like the code has a try-catch in place to handle if those things fail, which is possibly what causes your lag because try-catch are quite expensive. So the input.ready() check should result in fewer exceptions.

RFID based reading and writing in JAVA

I have to make a RFID based attendance system where i have to write into the database once reading from the tag and finding out which student it is.My query is how do i take input from the RFID tag.Does the input buffer classes of JAVA provided are enough for the input and output or do i have to take a different approach.
You can use the Java Communications API for this. I am working on the same and java comm api and rxtx work perfectly well for this. I have a program written for this. Here you go:
import java.io.*;
import java.util.*;
import javax.comm.*;
public class SimpleRead implements Runnable, SerialPortEventListener {
static CommPortIdentifier portId;
static Enumeration portList;
InputStream inputStream;
SerialPort serialPort;
Thread readThread;
public static void main(String[] args) {
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (portId.getName().equals("COM13")) {
// if (portId.getName().equals("/dev/term/a")) {
SimpleRead reader = new SimpleRead();
}
}
}
}
public SimpleRead() {
try {
serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
} catch (PortInUseException e) {System.out.println(e);}
try {
inputStream = serialPort.getInputStream();
} catch (IOException e) {System.out.println(e);}
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
System.out.println(e);
}
serialPort.notifyOnDataAvailable(true);
try {
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
System.out.println(e);
}
readThread = new Thread(this);
readThread.start();
}
public void run() {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {System.out.println(e);}
}
public void serialEvent(SerialPortEvent event) {
switch(event.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
byte[] readBuffer = new byte[20];
try {
while (inputStream.available() > 0) {
int numBytes = inputStream.read(readBuffer);
}
System.out.print(new String(readBuffer));
} catch (IOException e) {System.out.println(e);}
break;
}
}
}
It has been a last years since
I worked with RFID (ThinkMagic reader) and Java but every reader I
used at the time had its own proprietary API.
The JAR was only accessible with the purchase of the reader.
Times may have changed, may be open source readers / implementations but check out the
vendor site for your current make and model. The APIs are very straightforward once you have access to them.

inputstream.available() is 0 always

I have no idea of what is happening to my code. i am getting no errors and no response as well. I am writing the data to the serialport and waiting for the response by activating port.notifyOnDataAvailable(true); but this event is not triggered and inputstream.available() returns 0 always. What might be wrong ? I am using RXTX in linux.
EDIT
package testConn;
import forms_helper.global_variables;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.comm.*;
import java.util.*;
/** Check each port to see if it is open. **/
public class openPort implements SerialPortEventListener {
static Enumeration portList;
static CommPortIdentifier portId;
static String messageString;
public static SerialPort serialPort;
static OutputStream outputStream;
InputStream inputStream;
static boolean outputBufferEmptyFlag = false;
private BufferedReader is;
private PrintStream os;
public void open() {
Enumeration port_list = CommPortIdentifier.getPortIdentifiers();
while (port_list.hasMoreElements()) {
// Get the list of ports
CommPortIdentifier port_id = (CommPortIdentifier) port_list.nextElement();
if (port_id.getName().equals("/dev/ttyS1")) {
// Attempt to open it
try {
SerialPort port = (SerialPort) port_id.open("PortListOpen", 20000);
System.out.println("Opened successfully:"+port);
try {
int baudRate = 9600; //
port.setSerialPortParams(
baudRate,
SerialPort.DATABITS_7,
SerialPort.STOPBITS_1,
SerialPort.PARITY_EVEN);
port.setDTR(true);
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
System.out.println("properties are set");
} catch (UnsupportedCommOperationException e) {
System.out.println(e);
}
try {
//input = new SerialReader(in);
port.addEventListener(this);
System.out.println("listeners attached" + this);
} catch (TooManyListenersException e) {
System.out.println("too many listeners");
}
port.notifyOnDataAvailable(true);
//port.notifyOnOutputEmpty(true);
//sendMessage(port,"#PL");
//port.close ();
try {
is = new BufferedReader(new InputStreamReader(port.getInputStream()));
} catch (IOException e) {
System.err.println("Can't open input stream: write-only");
is = null;
}
try {
os = new PrintStream(port.getOutputStream(), true);
} catch (IOException ex) {
Logger.getLogger(openPort.class.getName()).log(Level.SEVERE, null, ex);
}
try {
inputStream = port.getInputStream();
System.out.println("inputstream" + inputStream.available());
outputStream = (OutputStream) port.getOutputStream();
os = new PrintStream(port.getOutputStream(), true, "US-ASCII");
} catch (IOException e) {
System.out.println(e);
}
//set the created variables to global variables
global_variables.port = port;
global_variables.inputStream = inputStream;
System.out.println(inputStream);
System.out.println(outputStream);
global_variables.outputStream = outputStream;
global_variables.os = os;
} catch (PortInUseException pe) {
System.out.println("Open failed");
String owner_name = port_id.getCurrentOwner();
if (owner_name == null) {
System.out.println("Port Owned by unidentified app");
} else // The owner name not returned correctly unless it is
// a Java program.
{
System.out.println(" " + owner_name);
}
}
}
}
}
public static void sendMessage(SerialPort port, String msg) {
if (port != null) {
System.out.println(msg);
try {
byte[] bytes = msg.getBytes("US-ASCII");
try {
global_variables.outputStream.write(bytes);
System.out.println(bytes.length);
global_variables.outputStream.flush();
} catch (IOException ex) {
Logger.getLogger(openPort.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(openPort.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Opened successfully:"+msg.getBytes());
//global_variables.outputStream.write(msg.getBytes());
//global_variables.outputStream.flush();
//global_variables.os.print(msg);
System.out.println(global_variables.outputStream);
try {
Thread.sleep(2000); // Be sure data is xferred before closing
System.out.println("read called");
//SimpleRead read = new SimpleRead();
//int read = global_variables.inputStream.read();
//System.out.println("read call ended"+read);
} catch (Exception e) {
}
}
}
public void serialEvent(SerialPortEvent event) {
System.out.println(event.getEventType());
String line;
try {
line = is.readLine();
if (line == null) {
System.out.println("EOF on serial port.");
System.exit(0);
}
os.println(line);
} catch (IOException ex) {
System.err.println("IO Error " + ex);
}
switch (event.getEventType()) {
/*
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
System.out.println("event.getEventType()");
break;
*
*/
case SerialPortEvent.DATA_AVAILABLE:
System.out.println("inside event handler data available");
byte[] readBuffer = new byte[20];
try {
while (inputStream.available() > 0) {
int numBytes = inputStream.read(readBuffer);
}
System.out.print(new String(readBuffer));
System.exit(1);
} catch (IOException e) {
System.out.println(e);
}
break;
}
}
} // PortListOpen
I am opening the port on main method and sending the message on a button click event inside the application.
.available() can not be used in inter-process communication (serial included), since it only checks if there is data available (in input buffers) in current process.
In serial communication, when you send a messaga and then immediately call available() you will mostly get 0 as serial port did not yet reply with any data.
The solution is to use blocking read() in a separate thread (with interrupt() to end it):
Thread interrupt not ending blocking call on input stream read
To partially answer your question.
From the javadocs
The available method for class
InputStream always returns 0.
http://download.oracle.com/javase/6/docs/api/java/io/InputStream.html#available()
So that part at least is as expected
By using a PrintStream you are suppressing exceptions that you need to know about in any request/response scenario.
Most probably you haven't even sent anything yet.

Categories

Resources