Ubuntu的RXTX无法识别USB串口设备

7

我正在将一个设备与librxtx-java连接到Ubuntu。这段代码之前在10.04下运行正常,但在12.04下无法检测到连接到计算机的USB串口。

java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
while ( portEnum.hasMoreElements() )
{
    CommPortIdentifier portIdentifier = portEnum.nextElement();
    System.out.println( portIdentifier.getName() + " - " + getPortTypeName(portIdentifier.getPortType()) );
}

尽管已安装适当的librxtx-java库并且设备被识别(dmesg | tail在一行中显示USB“串行设备转换器已检测”),但此代码部分从未进入while循环。

更新:

似乎Ubuntu 12.04 64位无法使用任何usb-serial设备(尽管它们在dmesg中显示并显示为/dev/ttyUSB,但似乎不仅是Java的问题)。

1个回答

14

我已经安装了 Ubuntu 11.10 内核版本为 3.0.0-12-generic-pae 和 librxtx-java 版本为 2.2pre2-8。使用下面的代码,它能正确地列出我的串行端口。现在,您已经正确地安装了 USB 转串口转换器吗?您需要检查转换器使用哪个端口。使用下面的示例应用程序,您可以尝试类似于 java -cp /usr/share/java/RXTXcomm.jar:. GetCommPorts 2 的命令。

请确保您在 /dev/ 目录下的 ttySXX 或 ttyUSBXX 文件中拥有正确的权限。

crw-rw---- 1 root dialout 4, 65 2012-02-29 01:08 /dev/ttyS1
crw-rw---- 1 root dialout 4, 66 2012-02-29 01:08 /dev/ttyS2

这些串行端口显示在我的系统中,想要运行应用程序的用户应该在 dialout 用户组中。要将自己添加到该组,请使用以下命令:

sudo usermod -aG dialout your_username

注意:您需要注销并重新登录才能使更改生效。

sudo usermod -a -G dialout username

你现在应该已经在“dialout”组中了。

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;

public class GetCommPorts
{
    static Enumeration<CommPortIdentifier>            portList;
    static CommPortIdentifier portId;
    static SerialPort                 serialPort;
    static OutputStream          outputStream;
    static boolean                    outputBufferEmptyFlag = false;    


    public static class SerialReader implements SerialPortEventListener
    {
        private InputStream in;
        private byte[] buffer = new byte[1024];

        public SerialReader(InputStream in)
        {           
            this.in = in;           
        }

        @Override
        /** 
         *  treat \n as end of block.
         */
        public void serialEvent(SerialPortEvent ev)
        {
            int data;

            try
            {
                int len = 0;
                while ( (data = in.read()) > -1)
                {
                    if (data == '\n')
                    {
                        break;
                    }
                    buffer[len++] = (byte) data;
                }
                System.out.println(new String(buffer, 0, len));
            }
            catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.exit(-1);
            }           
        }       
    }

    public static class SerialWriter implements Runnable
    {
        OutputStream out;

        public SerialWriter(OutputStream out)
        {
            this.out = out;
        }

        @Override
        public void run()
        {           
            try
            {
                int c = 0;
                while ( (c = System.in.read()) > -1)
                {
                    this.out.write(c);
                }
            }
            catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.exit(-1);
            }

        }

    }

    private static String getPortTypeName ( int portType )
    {
        switch ( portType )
        {
        case CommPortIdentifier.PORT_I2C:
            return "I2C";
        case CommPortIdentifier.PORT_PARALLEL:
            return "Parallel";
        case CommPortIdentifier.PORT_RAW:
            return "Raw";
        case CommPortIdentifier.PORT_RS485:
            return "RS485";
        case CommPortIdentifier.PORT_SERIAL:
            return "Serial";
        default:
            return "unknown type";
        }
    }

    private static void listPorts()
    {
        @SuppressWarnings("unchecked")
        java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();

        while ( portEnum.hasMoreElements() ) 
        {
            CommPortIdentifier portIdentifier = portEnum.nextElement();
            System.out.println(portIdentifier.getName()  +  " - " +  getPortTypeName(portIdentifier.getPortType()) );           

            if (portIdentifier.getPortType() == 1)
            {
                try
                {
                    serialPort =  (SerialPort) portIdentifier.open(portIdentifier.getName(), 3000);
                }
                catch (PortInUseException e)
                {
                    System.err.print("port in use");
                    continue;
                }

                System.out.println("Baud is " + serialPort.getBaudRate());    
                System.out.println("Bits is " + serialPort.getDataBits());    
                System.out.println("Stop is " + serialPort.getStopBits());    
                System.out.println("Par is " + serialPort.getParity());
                serialPort.close();
            }
        }
    }

    private static int doReadWrite(String portName)
    {
        CommPortIdentifier portIdentifier;

        try
        {
            portIdentifier = CommPortIdentifier.getPortIdentifier(portName);

            if (portIdentifier.isCurrentlyOwned())
            {
                System.err.println("error: port is currently in use");
                return -1;
            }

            SerialPort sport = (SerialPort) portIdentifier.open(portName, 3000);
            sport.setSerialPortParams(57600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

            InputStream in = sport.getInputStream();
            OutputStream out = sport.getOutputStream();         

            (new Thread(new SerialWriter(out))).start();

            sport.addEventListener(new SerialReader(in));
            sport.notifyOnDataAvailable(true);
        }
        catch (NoSuchPortException e)
        {
            e.printStackTrace();
            return -1;
        } 
        catch (PortInUseException e)
        {
            e.printStackTrace();
            return -1;
        }
        catch (UnsupportedCommOperationException e)
        {
            e.printStackTrace();
            return -1;
        }
        catch (IOException e)
        {
            e.printStackTrace();
            return -1;
        }
        catch (TooManyListenersException e)
        {
            e.printStackTrace();
            return -1;
        }

        return 0;       
    } 

    static void showHelp()
    {
        System.out.println("Usage " + GetCommPorts.class.getName() + "N");
        System.out.println("1 read and write from the serial port");
        System.out.println("2 list all serial ports in the system");
        System.out.println("default show this help ");
    }


    public static void main(String[] args)
    {
        int operation = 0;

        try
        {
            if (args.length != 1)
            {
                showHelp();
                return;
            }
            operation = Integer.parseInt(args[0]);
        }
        catch (NumberFormatException e)
        {

        }       

        switch (operation)
        {
        case 1:
            doReadWrite("/dev/ttyUSB0");
            break;
        case 2:
            listPorts();
            break;
        default:
            showHelp();
        }

    }


}

这个应用程序的输出:

$ java -cp /usr/share/java/RXTXcomm.jar:. GetCommPorts 2
/dev/ttyS1 - Serial
Baud is 9600
Bits is 8
Stop is 1
Par is 0
/dev/ttyS0 - Serial
Baud is 9600
Bits is 8
Stop is 1
Par is 0

":. GetCommPorts "/dev/usb-serial-converter-port" "这段代码是做什么用的?在Eclipse中有相应的设置吗?在升级之前,没有使用该选项也能正常工作,我想知道这是否与非sun jdk有关?" - NoBugs
1
另外,请确保您拥有端口的读写权限。在我的系统中,我有这个 crw-rw---- 1 root dialout 4, 64 2012-03-10 10:58 /dev/ttyS0。因此,想要运行此Java应用程序的用户应该在dialout组中。我正在使用内核3.0.0-12-generic-pae。 - Jasonw
3
将我的用户添加到 "dialout" 中,并重新启动,似乎解决了问题!感谢你的帮助。 - NoBugs
耶!最终,我们一起战胜了这个错误。很高兴听到这个好消息。干杯! - Jasonw
1
这个答案结束了几个小时的徒劳研究。尽管有可能会导致这个问题被保护,但我不得不说“非常感谢”。 - Mad Physicist
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接