Чтение неправильного значения из последовательного порта - PullRequest
1 голос
/ 18 июля 2011

Мне нужно прочитать 12-значный номер метки из считывателя RFID и распечатать его на консоли. Когда я использую эту программу для чтения тега, я получаю странное расстояние между ними.

например. Мой номер тега 4400E6EF1A57. Когда я продолжаю сканировать этот тег, в окне консоли отображается следующее:

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

Похоже, что есть длинная строка из 0 и 1, которая считывается, и только некоторые из них являются фактическими идентификаторами тегов. Я не знаю, в каком порядке я читаю эти 0 и 1.

Вот мой код: (Некоторые встроенные компоненты SQL и JDBC могут игнорироваться)

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;
    }
}
}

Ответы [ 2 ]

1 голос
/ 18 июля 2011

Поток дает вам то, что у него есть, и вы добавляете новые строки:

System.out.print(newtuple + "\n");

вам нужен какой-то буфер, например BufferedInputStream.

0 голосов
/ 18 июля 2011

См. http://download.oracle.com/javase/6/docs/api/java/io/InputStream.html#available() inputtream.available - возвращает количество байтов, которое вы можете прочитать без блокировки (blocking = ожидание большего количества байтов)

while (inputStream.available() > 0) {
  int numBytes = inputStream.read(readBuffer);
}

В какой-то момент времени у вас есть (например,) 3 байта во внутреннем буфере, готовые для чтения.Вы читаете его, проверяете с помощью while (), что не больше ready байтов, и вы вышли из цикла.Чем вы печатаете 3 байта и ставите '\ n' ... Это причина ваших сломанных идентификаторов.Вы должны читать до тех пор, пока не заполните буфер нужного размера, блокируясь и ожидая, когда ваше устройство / com-порт предоставит достаточно байтов.

Используйте метод чтения (buf, off, len)

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");
}

Он будет внутренне блокироваться до тех пор, пока не будет прочитано необходимое количество байтов, или вернется раньше, если входной поток сообщит «я готов» до того, как будет достигнута сумма.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...