【原创文章,转载请注明出处,谢谢】
arduino官网有篇文章,自己研究了半天才偶然发现,真是。。。踏破铁鞋无觅处。。。
最近好久没认真研究arduino了,这几天又想起这个事打算实验下,现把过程记录在下面。
我使用的是64位的Ubuntu系统。
首先,下载Rxtx,Rxtx是一个用于多平台串口和并口通讯的java扩展包:
http://rxtx.qbang.org/wiki/index.php/Main_Page
解压后,将RXTXcomm.jar,复制到 jdk/lib下,将x86_64/的 librxtxSerial.so复制到 jdk/amd64/lib 下。
然后在eclipse中右键单击项目,选择“build path”,选择“add external jars”,找到前面的jar包,确定。
注:我在实际测试中发现,在java程序中调用CommPortIdentifier.getPortIdentifiers()取不到通过usb链接的arduino,原因不明,网上有人认为是rxtx新版本的bug。解决办法是在调用该方法之前,增加下面这行代码:
System.
setProperty( "gnu.io. rxtx.SerialPort s", "/dev/ttyACM0")
其中的“/dev/ttyACM0”可以通过别的方法得到,比如直接查看arduino专用的IDE的右下角,会有连接到哪个串口的提示,再比如,在用于processing语言的PDE中,使用下面的方法打印所有已连接串口设备也可以找到:
println(Serial.list());
java代码如下,read和write方法分别用于从arduino“读”数据和向arduino“写”数据。
【注意】向arduino写数据时,要在建立链接后至少让线程sleep 1 秒之后再继续操作。
package com.xiaomi.micloud.utils;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Enumeration;public class ArduinoSerial {
private SerialPort serialPort;
private InputStream in;
private OutputStream out;public ArduinoSerial(SerialPort serialPort) throws IOException {
this.serialPort = serialPort;
this.in = serialPort.getInputStream();// 得到输入流
this.out = serialPort.getOutputStream();// 得到输出流
}public void read() {
try {
// 进行输入输出操作
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}public void write() throws InterruptedException {
try {
Thread.sleep(2000);// 链接后暂停2秒再继续执行
System.out.println("connected!");
// 进行输入输出操作
OutputStreamWriter writer = new OutputStreamWriter(out);
BufferedWriter bw = new BufferedWriter(writer);
for (int i = 0; i < 3; i++) {
bw.write("a");
bw.flush();
}
bw.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}public void close() throws IOException {
in.close();
out.close();
}public static void main(String[] args) {
try {
System.setProperty("gnu.io.rxtx.SerialPorts", "/dev/ttyACM0");
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
CommPortIdentifier portId = null;
while (portList.hasMoreElements()) {
CommPortIdentifier tmpPortId = (CommPortIdentifier) portList.nextElement();
System.out.println(tmpPortId.getName());
// 如果端口类型是串口则判断名称
if (tmpPortId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (tmpPortId.getName().startsWith("/dev")) {
portId = tmpPortId;
}
}
}
if (portId == null) {
System.out.println("not detected");
}
SerialPort serialPort = (SerialPort) portId.open("ArduinoSerial", 1000);// 打开串口的超时时间为1000ms
// 设置串口速率为9600,数据位8位,停止位1们,奇偶校验无
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
ArduinoSerial testObj = new ArduinoSerial(serialPort);
testObj.read();
testObj.close();
serialPort.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
以下是在arduino上运行的程序,
这段代码将使arduino板在收到从java程序发送的数据时,令位于13号数字接口的LED闪烁一次。
void setup() {
pinMode(13,OUTPUT);
Serial.begin(9600);
}void loop() {
if(Serial.available()){
int readByte = Serial.read();
Serial.println((char)readByte);
digitalWrite(13,HIGH);
delay(400);
digitalWrite(13,LOW);
delay(400);
digitalWrite(13,HIGH);
delay(400);
digitalWrite(13,LOW);
delay(400);
}
}
下面这段代码比较简单,将使arduino板向串口循环写入数据,然后java程序可运行read()方法获取数据:
注意:由于java程序中用的是in.readLine()获取数据,所以arduino程序发送的数据必须以“\n\r”结尾,或者直接用Serial.println()方法。
void setup() {
Serial.begin(9600);
}void loop() {
Serial.print("a");
Serial.println("b");
//等效于Serial.print("ab\n\r");
delay(1000);
}
//TODO 下一步是实验通过一个USB Hub链接多个arduino板,估计只是多识别到几个串口而已。