【问题标题】:Java - Convert Serial Port Byte Array Into Int?Java - 将串行端口字节数组转换为 Int?
【发布时间】:2012-04-19 23:46:39
【问题描述】:

我正在尝试在我的 java 界面中制作应变仪显示数字。

我有应变计电路工作,它将其电压发送到微控制器(PIC16F877A)程序进行模数转换,然后在串行端口上输出数字。如果你有兴趣,这里是代码:

unsigned short analog;            //Variable for analog voltage
long tlong;
unsigned char ch;                    //

void main() {
  USART_Init(19200);              //set baude rate

  ADCON1 = 0;                     //All PORTA pins as analog, VDD as Vref
  TRISA  = 0xFF;                  //All PORTA is input

  do {
    analog = ADC_Read(2) >> 2;    //Read 10-bit ADC from AN2 and discard 2 LS bit

    tlong = (long)analog * 5000;  // Convert the result in millivolts
    tlong = tlong / 1023;         // 0..1023 -> 0-5000mV
    ch = tlong / 1000;            // Extract volts (thousands of millivolts) from result

    USART_Write(48+ch);           // Write result in ASCII format
    USART_Write('.');

    ch = (tlong / 100) % 10;      // Extract hundreds of millivolts
    USART_Write(48+ch);           // Write result in ASCII format

    ch = (tlong / 10) % 10;       // Extract tens of millivolts
    USART_Write(48+ch);           // Write result in ASCII format

    ch = tlong % 10;              // Extract digits for millivolts
    USART_Write(48+ch);           // Write result in ASCII format
    USART_Write(' ');
    USART_Write(' ');
    USART_Write(' ');

    Delay_ms(1000);
  } while (1);
}

这并不完美,因为当我移动应变计时,输出数字不会改变它们应该的方式。如果有人对此有任何想法,将不胜感激。

但我还是继续前进并将这些数字发送到我的 java 程序中。我在网上找到了这个并对其进行了修改以适合我的设计:

import java.io.*;
import java.util.*; 
import gnu.io.*;


public class SimpleRead implements Runnable, SerialPortEventListener {
    static CommPortIdentifier portId;
    static Enumeration portList;

InputStream inputStream;
SerialPort serialPort;
Thread readThread;
static byte[] readBuffer;
public static int result2;

public static void main(String[] args) {
    portList = CommPortIdentifier.getPortIdentifiers();
    System.out.println("portList... " + portList);

    while (portList.hasMoreElements()) {
        portId = (CommPortIdentifier) portList.nextElement();
        if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
            System.out.println("port identified is Serial.. "
                    + portId.getPortType());
            if (portId.getName().equals("COM4")) {
                System.out.println("port identified is COM4.. "
                        + portId.getName());
                // if (portId.getName().equals("/dev/term/a")) {
                SimpleRead reader = new SimpleRead();
            } else {
                System.out.println("unable to open port");
            }
        }
    }
}

public SimpleRead() {
    try {
        System.out.println("In SimpleRead() contructor");
        serialPort = (SerialPort) portId.open("SimpleReadApp1111",500);
        System.out.println(" Serial Port.. " + serialPort);
    } catch (PortInUseException e) {
        System.out.println("Port in use Exception");
    }
    try {
        inputStream = serialPort.getInputStream();
        System.out.println(" Input Stream... " + inputStream);
    } catch (IOException e) {
        System.out.println("IO Exception");
    }
    try {
        serialPort.addEventListener(this);

    } catch (TooManyListenersException e) {
        System.out.println("Tooo many Listener exception");
    }
    serialPort.notifyOnDataAvailable(true);
    try {

        serialPort.setSerialPortParams(19200, SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

        // no handshaking or other flow control
        serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);

        // timer on any read of the serial port
        serialPort.enableReceiveTimeout(500);

        System.out.println("................");

    } catch (UnsupportedCommOperationException e) {
        System.out.println("UnSupported comm operation");
    }
    readThread = new Thread(this);
    readThread.start();
}

public void run() {
    try {
        System.out.println("In run() function ");
        Thread.sleep(500);
        // System.out.println();
    } catch (InterruptedException e) {
        System.out.println("Interrupted Exception in run() method");
    }
}

public void serialEvent(SerialPortEvent event) {

    // System.out.println("In Serial Event function().. " + event +
    // event.getEventType());
    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:
        readBuffer = new byte[500];

        try {

            while (inputStream.available()>0) {

                int numBytes = inputStream.read(readBuffer);

            //   System.out.println("Number of bytes read " + numBytes);
                System.out.print(new String(readBuffer));
            }



        } catch (IOException e) {
            System.out.println("IO Exception in SerialEvent()");
        }
        break;
    }
    // System.out.println();
/*  String one = new String(readBuffer);
    char two = one.charAt(0);
    System.out.println("Character at three: " + two);*/
}

}

它读取的数字范围与前面的代码相同(一个串行端口,所以我无法测试它是否是相同的数字),尽管它有时会给我一些奇怪的数字,比如 .692 而不是 .692,它会说 320 ,那么下一个数字是 43,那么可能只有一个 '.'会出现,但很快就会恢复正常。我认为这是一个缓冲区问题,上面写着“readBuffer = new byte[500]”,我将大小更改为 500(最初是 8),结果稍微好一点。

无论如何,我必须将输出转换为整数才能对其进行一些数学运算,并且作为整数,我可以轻松过滤掉所有奇怪的数据。所以最终,我现在的问题是我会将这些输出数据转换为可用的整数吗?主要问题是我什至不确定它在我的 java 程序中的哪个位置读取串行端口号。我假设变量是 readBuffer,但是当我尝试使用它的地方时,我会遇到错误,通常是类型不匹配。

所以任何帮助都会很棒,谢谢!

【问题讨论】:

    标签: java serial-port integer microcontroller


    【解决方案1】:

    我进一步研究了您上面的代码,我认为在上面的代码中流是:

    <x.xxx >,所以如果你每次读取 8 个字节,那将是一个数据条目。如果你使用 inputstreamreader if 会将字节转换为字符...

    查看http://docs.oracle.com/javase/1.4.2/docs/api/java/io/InputStreamReader.html

    【讨论】:

    • 这正是流应该是的,通常它输出 0.200-1.000,尽管就像我说的,我偶尔会得到奇怪的整数,甚至小数本身。非常感谢您的建议,我明天将尝试实现 inputstreamreader!
    【解决方案2】:

    很难从提供的信息中猜测,但您说:

    “给我奇怪的数字,而不是 .692,它会说 320”

    主要问题是我什至不确定它在我的 java 程序中的哪个位置读取串行端口号

    如果您尝试从接收到的字节缓冲区中读取整数,这在我看来是字节顺序问题。如果您尝试从接收到的字节缓冲区读取浮点数据,也可能是浮点类型的 IEEE 标准不匹配。但我建议不要使用浮点类型,而只使用整数。

    如果您使用的是 java 5+,请使用 nio 包中的 ByteBuffer 类,如下所示:

        byte[] readBuffer = getBufferFromyourCode();
        ByteBuffer buffer = ByteBuffer.wrap(readBuffer); //wrap received byte buffer
        buffer.order(ByteOrder.LITTLE_ENDIAN);//set correct endiannes
        Integer version = buffer.getInt();// read first 4 bytes
        Integer length = buffer.getInt(); // read next 4 bytes
        byte[] rowMsg = new byte[length];// length = bytes to read
        buffer.get(rowMsg); // copies 'length' bytes in rowMsg
        String msg = new String(rowMsg); // convert to String
        System.out.println("Version "+version+" message received");
        System.out.println("Length: "+length);
        System.out.println("text: "+msg);
    

    注意字节顺序设置,尝试大端和小端,看看你从缓冲区读取的值是否正常。 在此处查看有关字节序的更多信息:http://en.wikipedia.org/wiki/Endiannes

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-22
      • 2011-09-04
      • 1970-01-01
      • 2014-12-27
      • 2011-09-16
      相关资源
      最近更新 更多