請仔細理解相關參數,如端口設置、IP設置、COM口設置......等等.....不要盲目COPY.....這涉及2臺電腦和一個單片機,其中一臺電腦做爲服務器並與單片機相連,負責經過網絡與客戶端通訊(socket)和經過數據線與單片機經過COM口通訊(我實驗時用的是COM9,其餘電腦可能不一樣須要調整:具體在設備管理器中查看)。java
一、Arduino板待燒入代碼:(這裏硬件的代碼沒啥好說的,只要你會寫個簡單Arduino代碼而且本身燒過就知道該怎麼作啦)git
////////////////////////////////////////////////////////// //Arduino 1.0.x-----Arduino Uno----COM9 //使用3-10號引腳鏈接8個LED ////////////////////////////////////////////////////////// int incomingByte = 0; //輸入的數據存儲變量 int count=1; void setup() { Serial.begin(9600);// opens serial port, sets data rate to 9600 bps for(int i=3;i<=10;i++)//打開3-10號引腳 pinMode(i,OUTPUT); } void loop() { while(count){ Serial.println("please input 0 1 2 3 4 5 6 7 8 9 a"); count=0; }//第一次操做說明,count爲了第一次限制 if (Serial.available() > 0){ incomingByte = Serial.read();//讀取 Serial.println(incomingByte, DEC);//寫入 }//從COM口讀取數據 switch (incomingByte)//數據處理並對引腳進行調控 { case 48://輸入0時將3-10號引腳設爲高電位,使全部的燈滅 for(int i=3;i<=10;i++){ digitalWrite(i,HIGH); }break; case 49://輸入1從3-10號引腳電位依次設低電位維持0.5s,而後設爲高電位,實現流水燈效果 for(int i=3;i<=10;i++){ digitalWrite(i,LOW); delay(500); digitalWrite(i,HIGH); }break; case 50://輸入2流水燈,和輸入1時方向相反 for(int i=10;i>=3;i--){ digitalWrite(i,LOW); delay(500); digitalWrite(i,HIGH); }break; case 51: digitalWrite(3,LOW);break;//輸入3,將3號電位調低,只讓3號引腳的燈亮 case 52: digitalWrite(4,LOW);break; //..... case 53: digitalWrite(5,LOW);break; //..... case 54: digitalWrite(6,LOW);break; //..... case 55: digitalWrite(7,LOW);break; //..... case 56: digitalWrite(8,LOW);break; //..... case 57: digitalWrite(9,LOW);break; //..... case 97: digitalWrite(10,LOW);break;//..... default: for(int i=3;i<=10;i++){ digitalWrite(i,HIGH); }break;//將所電位調高關閉全部燈 } }
二、服務器和客戶端代碼:服務器
package serial; public class SerialBuffer{ private String Content = ""; private String CurrentMsg, TempContent; private boolean available = false; private int LengthNeeded = 1; public synchronized String GetMsg(int Length){ LengthNeeded = Length; notifyAll(); if (LengthNeeded > Content.length()){ available = false; while (available == false){ try{ wait(); } catch (InterruptedException e) {} } } CurrentMsg = Content.substring(0, LengthNeeded); TempContent = Content.substring(LengthNeeded); Content = TempContent; LengthNeeded = 1; notifyAll(); return CurrentMsg; }//本函數從串口(緩衝區)中讀取指定長度的一個字符串。 //參數Length指定所返回字符串的長度。 public synchronized void PutChar(int c){ Character d = new Character((char) c); Content = Content.concat(d.toString()); if (LengthNeeded < Content.length()){ available = true; } notifyAll(); } } //SerialBuffer.java (用來保存從串口所接收數據的緩衝區) //在往緩衝區寫入數據或者是從緩衝區讀取數據的時候,必須保證數據的同步, //所以GetMsg和PutChar函數均被聲明爲synchronized並在具體實現中採起措施實現的數據的同步。
package serial; import java.io.*; public class ReadSerial extends Thread { private SerialBuffer ComBuffer; private InputStream ComPort; public ReadSerial(SerialBuffer SB, InputStream Port){ ComBuffer = SB; ComPort = Port; }//本函數構造一個ReadSerial進程, //參數SB指定存放傳入數據的緩衝區, //參數Port指定從串口所接收的數據流 public void run(){ int c; try{ while (true){ c = ComPort.read(); ComBuffer.PutChar(c); } } catch (IOException e) {} } } //ReadSerial.java (從串口讀取數據的程序) //ReadSerial是一個進程,它不斷的從指定的串口讀取 //數據並將其存放到緩衝區中
package serial; import java.io.*; import java.util.*; import gnu.io.*; public class SerialBean { static String PortName; CommPortIdentifier portId; SerialPort serialPort; static OutputStream out; static InputStream in; SerialBuffer SB; ReadSerial RT; public SerialBean(int PortID){ PortName = "COM" + PortID; }// 本函數構造一個指向特定串口的SerialBean //該串口由參數PortID所指定。PortID = 1 表示COM1 public int Initialize(){ int InitSuccess = 1; int InitFail = -1; try{ portId = CommPortIdentifier.getPortIdentifier(PortName); try{ serialPort = (SerialPort)portId.open("Serial_Communication", 2000); } catch (PortInUseException e){ return InitFail; }//打開一個串口 try{ in = serialPort.getInputStream(); out = serialPort.getOutputStream(); } catch (IOException e){ return InitFail; }//讀寫流實例化 try{ serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); } catch (UnsupportedCommOperationException e){ return InitFail; }//設置串行端口通信參數 } catch (NoSuchPortException e){ return InitFail; } SB = new SerialBuffer(); RT = new ReadSerial(SB, in); RT.start(); // return success information return InitSuccess; }//本函數初始化所指定的串口並返回初始化結果。若是初始化成功返回1,不然返回-1。 //初始化的結果是該串口被SerialBean獨佔性使用,其參數被設置爲9600, N, 8, 1。 //若是串口被成功初始化,則打開一個進程讀取從串口傳入的數據並將其保存在緩衝區中。 public String ReadPort(int Length){ String Msg; Msg = SB.GetMsg(Length); if(Msg==null)Msg="ssdfsdf"; return Msg; }//本函數從串口(緩衝區)中讀取指定長度的一個字符串。參數Length指定所返回字符串的長度 public void WritePort(String Msg){ int c; try{ for (int i = 0; i < Msg.length(); i++) out.write(Msg.charAt(i)); } catch (IOException e) {} }//本函數向串口發送一個字符串。參數Msg是須要發送的字符串 public void ClosePort(){ RT.stop(); serialPort.close(); }//本函數中止串口檢測進程並關閉串口 } //SerialBean是本類庫與其餘應用程序的接口。 //該類庫中定義了SerialBean的構造方法以及初始化串口 //從串口讀取數據,往串口寫入數據以及關閉串口的函數
分別把這3個文件放在D盤中而後分別編譯:以下(必定要注意-d後面有一個空格+一個點+一個空格).網絡
三個java文件編譯好以後,你將在D盤看到一個serial文件夾,裏面有相應的3個class文件。而後把原來的java文件刪除或者移到別的地方(很是重要,否則會在編譯服務器和客戶端時報錯)。而後把服務器代碼放到剛纔的D盤編譯 && 客戶端代碼放到另外一臺電腦編譯(以下圖)socket
import java.util.Scanner; import java.io.*; import java.net.*; import serial.*; import serial.ReadSerial; public class EchoServer{ private int port = 8000; private ServerSocket serverSocket; public EchoServer()throws IOException{ serverSocket = new ServerSocket(port); System.out.println("服務器啓動"); }//構造函數 private PrintWriter getWriter(Socket socket)throws IOException{ OutputStream socketOut=socket.getOutputStream(); return new PrintWriter(socketOut,true); }//write函數 private BufferedReader getReader(Socket socket)throws IOException{ InputStream socketIn=socket.getInputStream(); return new BufferedReader(new InputStreamReader(socketIn)); }//read函數 public void service(){ Scanner scanner=new Scanner(System.in); SerialBean SB = new SerialBean(9); SB.Initialize(); while(true){ Socket socket=null; try{ socket=serverSocket.accept(); System.out.println("New connection accepted"+ socket.getInetAddress()+":"+socket.getPort()); BufferedReader br=getReader(socket); PrintWriter pw=getWriter(socket); String clientMsg=null,portMsg=null; while((clientMsg=br.readLine())!=null){ System.out.println(clientMsg); pw.println("~!:"+clientMsg); if(clientMsg.equals("bye"))break; portMsg = SB.ReadPort(9); System.out.println(portMsg); SB.WritePort(clientMsg); } SB.ClosePort(); }catch(IOException e){ e.printStackTrace(); }finally{ try{ if(socket!=null)socket.close(); }catch(IOException e){ e.printStackTrace(); } } } }//服務函數 public static void main(String args[])throws IOException{ new EchoServer().service(); } }
//網絡通訊客戶端實現 import java.net.*; import java.io.*; import java.util.*; public class EchoClient{ private String host="localhost"; private int port=8000; private Socket socket; public EchoClient()throws IOException{ InetAddress addr=InetAddress.getByName("192.168.16.101");socket =new Socket(addr,port);//採用網絡 //socket = new Socket(host,port);//本地通訊,就是服務器和客戶端在同一個電腦(一臺電腦測試時用) }//構造函數 public static void main(String args[])throws IOException{ new EchoClient().talk(); }//main函數 private PrintWriter getWriter(Socket socket)throws IOException{ OutputStream socketOut=socket.getOutputStream(); return new PrintWriter(socketOut,true); }//重寫write函數 private BufferedReader getReader(Socket socket)throws IOException{ InputStream socketIn=socket.getInputStream(); return new BufferedReader(new InputStreamReader(socketIn)); }//重寫read函數 public void talk()throws IOException{ try{ BufferedReader br=getReader(socket); PrintWriter pw=getWriter(socket); BufferedReader localReader=new BufferedReader( new InputStreamReader(System.in)); String msg=null; while((msg=localReader.readLine())!=null){ pw.println(msg); System.out.println(br.readLine()); if(msg.equals("bye"))break; } }catch(IOException e){ e.printStackTrace(); }finally{ try{ socket.close(); }catch(IOException e){ e.printStackTrace(); } } }//對話函數 }
接着分別啓動主機和服務器就能夠實現PC經過網絡遠程控制單片機啦!ide