基本上有兩種常用的方法:
- 使用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占用吧