智能小车制作过程全纪录: 三、软件平台--- Java 平台串口通信

更多创客作品,请关注笔者网站园丁鸟,搜集全球极具创意,且有价值的创客作品
ROS机器人知识请关注,diegorobot
业余时间完成的一款在线统计过程分析工具SPC,及SPC知识分享网站qdo


嵌入式Linux上大部分都是有C/C++来做开发的,主要的原因还是为了效率,但本人最近几年用Java比较多所以决定用Java比较多所以决定还是用Java来开发,再者个人认为现在硬件的发展,对于实时性没有苛刻要求的环境Java足可以胜任了,所以言归正传,下面开始实际行动:

1、Java虚拟机的安装,OpenJava,Oracle Java都可以,这里用Oracle Java为例

a. Ubuntu本身是Apt-get是没有Oracle java的源的,所以首先的先添加源:

sudo sh -c 'echo “deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main” >> /etc/apt/sources.list
sudo sh -c 'echo “deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main” >> /etc/apt/sources.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886
b 用apt-get update安装即可,Ubuntu core安装Oracle Java时间比较久,要耐心等待
.sudo apt-get update
sudo apt-get install oracle-java8-installer

2、Java串口通信

Java串口通信用到了Rxtxcomm这个包,
下载地址:最新版本rxtx 2.2pre2 http://rxtx.qbang.org/wiki/index.php/Download
安装说明
http://rxtx.qbang.org/wiki/index.php/Installation_on_Linux
官方给出了详细的安装说明,但是按照这个安装说明,在调用这个包的时候提示jar包和动态链接库.so 文件不一致的问题,这是这个版本的一个bug,解决办法如下:
首先用apt-get 安装,已操作过的可以忽略此步骤
apt-get install librxtx-java
执行完此步骤后,会在/usr/lib/jni/目录下发现动态链接库文件librxtxSerial.so,这时候用cp命令将此文件拷贝到Java Home下
cp /usr/lib/jni/librxtxSerial.so /usr/lib/jvm/java-8-oracle/jre/lib/arm
接下来下载源码,按照官方按照教程,在源码目录执行如下命令:
sh ./configure
make

执行完后会发现源码目录下多出一个RXTXcomm.jar,在Java工程中直接引用即可,也可以到百度网盘下载https://pan.baidu.com/s/1jHD0aj0

执行完成后,在NanoPC T3调用官方示例中的listport还是找不到串口,后来研究代码发现Linux中的设备是用文件来表示的,所有的设备都是放在/dev目录下的,而NanoPC T3的串口是用ttySAC1,ttySAC3,ttySAC4这样的方式命名的,而rxtxcomm的串口查找没有匹配这种命名方式,可以看/src/gnu/io/RXTXCommDriver.java 577~581行的代码
智能小车制作过程全纪录: 三、软件平台--- Java 平台串口通信_第1张图片
只需要增加NanoPC T3的命名格式,重新编译一下就好了,改完后的代码如下:

					if(osName.equals("Linux"))
					{
						String[] Temp = {
						"ttyS", // linux Serial Ports
						"ttySA", // for the IPAQs
						"ttySAC",///for friendarm
						"ttyUSB", // for USB frobs
						"rfcomm",       // bluetooth serial device
						"ttyircomm", // linux IrCommdevices (IrDA serial emu)
						};
						CandidatePortPrefixes=Temp;
					}

现在可以调用官方sample中的connect打开串口了,打开串口3和4的方式如下:
connect("/dev/ttySAC3");
connect("/dev/ttySAC4");
官方connect函数代码如下:

    public void connect ( String portName ) throws Exception  
    {  
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);  
        if ( portIdentifier.isCurrentlyOwned() )  
        {  
            System.out.println("Error: Port is currently in use");  
        }  
        else  
        {  
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);  
              
            if ( commPort instanceof SerialPort )  
            {  
                SerialPort serialPort = (SerialPort) commPort;  
                serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);  
                  
                InputStream in = serialPort.getInputStream();  
                  
                InputStreamReader reader = new InputStreamReader(in);  
                OutputStream out = serialPort.getOutputStream();
                
                BufferedReader r = new BufferedReader(reader);  
                  
                //(new Thread(new ReaderSerial(r))).start();  
                //(new Thread(new WriterSerial(out))).start();
                
                rs=new ReaderSerial(r);
//                pool.execute(rs);
                rs.start();
                
                ws=new WriterSerial(out);
//                pool.execute(ws);
//               // ws.start();                                                
  
            }  
            else  
            {  
                System.out.println("Error: Only serial ports are handled by this example.");  
            }  
        }      
    }  

3、 最后针对小车驱动对串口通信重新包装了一下

SerialComm.java 串口操作的封装类
ReaderSerial.java 串口读的封装类
WriterSerial.java 串口写的类
DriverCMD.java 小车底盘控制命令类,配合Arduino 代码的串口命令

SerialComm.java

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

public class SerialComm {
	//private String  msg="";
	//private String lastmsg="";
	private  ReaderSerial rs=null;
	private WriterSerial ws=null;
	//ExecutorService pool = Executors.newCachedThreadPool(); 
	

	public void setMsg(String msg) {
		if (ws!=null){
			//System.out.println("******step 3");
			ws.setMsg(msg);			
			ws.writeSerial();
		}
			
	}

	public SerialComm()  
    {  
        super();  
    }  
      
    public void connect ( String portName ) throws Exception  
    {  
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);  
        if ( portIdentifier.isCurrentlyOwned() )  
        {  
            System.out.println("Error: Port is currently in use");  
        }  
        else  
        {  
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);  
              
            if ( commPort instanceof SerialPort )  
            {  
                SerialPort serialPort = (SerialPort) commPort;  
                serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);  
                  
                InputStream in = serialPort.getInputStream();  
                  
                InputStreamReader reader = new InputStreamReader(in);  
                OutputStream out = serialPort.getOutputStream();
                
                BufferedReader r = new BufferedReader(reader);  
                  
                //(new Thread(new ReaderSerial(r))).start();  
                //(new Thread(new WriterSerial(out))).start();
                
                rs=new ReaderSerial(r);
//                pool.execute(rs);
                rs.start();
                
                ws=new WriterSerial(out);
//                pool.execute(ws);
//               // ws.start();                                                
  
            }  
            else  
            {  
                System.out.println("Error: Only serial ports are handled by this example.");  
            }  
        }      
    }  
    public static void listPorts()  
    {  
        @SuppressWarnings("unchecked")  
        java.util.Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();  
        while ( portEnum.hasMoreElements() )   
        {  
            CommPortIdentifier portIdentifier = portEnum.nextElement();  
            System.out.println(portIdentifier.getName()  +  " - " +  getPortTypeName(portIdentifier.getPortType()) );  
        }         
    }  
      
    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";  
        }  
    	//return "";
    }        
}

ReaderSerial.java

import java.io.BufferedReader;
import java.io.IOException;

public class ReaderSerial extends Thread{

	BufferedReader in;  
    
    public ReaderSerial ( BufferedReader in )  
    {  
        this.in = in;  
    }  
      
    public void run ()  
    {  
        try  
        {  
            String line;  
            while ((line = in.readLine()) != null){  
                System.out.println(line);  
            }  
        }  
        catch ( IOException e )  
        {  
            e.printStackTrace();  
        }
    }
}

WriterSerial.java

public class WriterSerial/* extends Thread*/{

	private OutputStream out;  
    private String msg="";
    //private String lastmsg="";
      
    public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
		System.out.println("******step 4 this.msg= "+this.msg);
	}

	public WriterSerial ( OutputStream out)  
    {  
        this.out = out;  
    }  
      
	public void writeSerial(){
		if (msg != null && msg.length() != 0) {
			System.out.println("******before write,  the msg is " + msg);
			try {
				out.write(this.msg.getBytes());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
} 

DriverCMD.java

public class DriverCMD {
	private SerialComm driverCMDComm;
	private String stopcar="5";
	private String forward="1";
	private String backward="2";	
	private String right="3";
	private String left="4";
	private String automate="6";
	private String manual="7";
	
	public void openSAC(String portName){
		driverCMDComm=new SerialComm();
		try {
			driverCMDComm.connect(portName);
			System.out.println("******the SAC "+portName+" has been opened!");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void stop(){
		driverCMDComm.setMsg(stopcar);
	}
	public void forward(){
		//System.out.println("******step 2");
		driverCMDComm.setMsg(forward);		
	}
	public void backward(){
		driverCMDComm.setMsg(backward);
	}
	public void right(){
		driverCMDComm.setMsg(right);
	}
	public void left(){
		driverCMDComm.setMsg(left);
	}
	public void manual(){
		driverCMDComm.setMsg(manual);
	}
	public void automate(){
		driverCMDComm.setMsg(automate);
	}
	
	public void mycmd(String cmdstr){
		
		System.out.println("******"+cmdstr);
		try{
			if(cmdstr.equals("FORWARD")){
				forward();
				Thread.sleep(2000);	
				stop();
			}
			if(cmdstr.equals("BACKWARD")){
				backward();
				Thread.sleep(2000);	
				stop();
			}
			if(cmdstr.equals("RIGHT")){
				right();
				Thread.sleep(1000);	
				stop();
			}
			if(cmdstr.equals("LEFT")){
				left();
				Thread.sleep(1000);	
				stop();
			}
			if(cmdstr.equals("EXIT")){
				System.exit(0);
			}
			if(cmdstr.equals("STOP")){
				stop();
			}
			if(cmdstr.equals("MANUAL")){
				manual();
			}
			if(cmdstr.equals("AUTOMATE")){
				automate();
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.exit(0);
		}
		
	}
	
	public void test(){
		
		try {
			System.out.println("******step 1");
			forward();
			Thread.sleep(3000);			
			backward();
			Thread.sleep(3000);
			right();
			Thread.sleep(3000);
			left();
			Thread.sleep(3000);
			stop();
			Thread.sleep(3000);
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.exit(0);
		}
	}
}

在main函数中可以按照如下方法调用:

public class Test {
  public static void main(String[] args) {
	// TODO Auto-generated method stub
	SerialComm.listPorts();  	
	
	DriverCMD driver =new DriverCMD();		
	driver.openSAC("/dev/ttySAC3");
	driver.test();
	//......
}

}

你可能感兴趣的:(机器人,机器学习,linux)