基本上有兩種常用的方法:
- 使用Java Communications,它原本是Sun公司維護的,不過似乎現在已經沒有人再做了,在Oracle網站上只能找到API的說明書但卻沒有下載點。
- 使用RXTX,語法跟Java Communications很像但寫法有一點不一樣,使用RXTX可以讓Java使用Serial port(序列阜),達到經由Serial port來傳送資料給Arduino或從Arduino接收資料。
- 2016/11/27 更新,第三種方法,使用Ardulink,請參考Ardulink - Arduino的Java控制方案。
- 為了開發,要放在Java JDK安裝目錄下的bin資料夾下面,參考自
- 放在C:\Windows\System32下(當然,是指在Windows平台下)。
上面的提到的資料中,第二個資料是RXTX官方的例子,使用了兩個thread分別執行Serial port的輸入及輸出,使用者可以即時看到接收到的資料和即是的打上資料送出去,需要注意的是,其中這行
serialPort.setSerialPortParams(57600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
中的57600是Serial port的通訊速率( baud rate),需要自行修改成與Arduino板子中程式所定的通訊速率一樣,例如Arduino程式的
Serial.begin(9600)
中的9600,不然在接收和傳送訊息時會有問題。
因為覺得官方的例子優雅又實用,為了怕以後忘記,特轉載在最底下(57600已改成9600),可配合我寫的Arduino程式(SerialLightLevelControl)用Serial port的方式用電腦打數字進Console中控制LED燈的亮暗程度。
SerialLightLevelControl:
RXTX的官方範例:SerialLightLevelControl:
byte ledPin = 6;>
int lightLevel = 0;
char inputLightLevel[4];
byte i;
char tempChr;
byte maxDigit = 3; //Because atoi() can only hadle number with digit less than 3;
byte maxAnalogOutput=255;
void setup() {
Serial.begin(9600);
Serial.println("LED ready.");
}
void loop() {
//Check if Serial port has message in.
if (Serial.available()) {
i = 0; //count reset;
while ((tempChr = Serial.read()) != '\n') {
if (tempChr >= '0' && tempChr <= '9' && i < maxDigit) { //check whether message is a number or not.
inputLightLevel[i] = tempChr;
i++;
}
}
inputLightLevel[i] = '\0';
lightLevel = atoi(inputLightLevel); //Use atoi() to transfer string or char[] to number.
if (lightLevel > maxAnalogOutput) lightLevel = maxAnalogOutput;
Serial.print("Light level : ");
Serial.println(lightLevel);
}
analogWrite(ledPin, lightLevel);
}
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class TwoWaySerialComm
{
public TwoWaySerialComm()
{
super();
}
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();
OutputStream out = serialPort.getOutputStream();
(new Thread(new SerialReader(in))).start();
(new Thread(new SerialWriter(out))).start();
}
else
{
System.out.println("Error: Only serial ports are handled by this example.");
}
}
}
/** */
public static class SerialReader implements Runnable
{
InputStream in;
public SerialReader ( InputStream in )
{
this.in = in;
}
public void run ()
{
byte[] buffer = new byte[1024];
int len = -1;
try
{
while ( ( len = this.in.read(buffer)) > -1 )
{
System.out.print(new String(buffer,0,len));
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}
}
/** */
public static class SerialWriter implements Runnable
{
OutputStream out;
public SerialWriter ( OutputStream out )
{
this.out = out;
}
public void run ()
{
try
{
int c = 0;
while ( ( c = System.in.read()) > -1 )
{
this.out.write(c);
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}
}
public static void main ( String[] args )
{
try
{
(new TwoWaySerialComm()).connect("COM3");
}
catch ( Exception e )
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
你好:
回覆刪除我用你提供的程式Arduino , Java , RXTX
1 LED沒會亮,我認為是Arduino無法跑到analogWrite(ledPin, lightLevel)
2 Arduino的con無法開啟,可能是Java占用吧