PC-PC-单片机(Arduino)通信实例
请仔细理解相关参数,如端口设置、IP设置、COM口设置......等等.....不要盲目COPY.....这涉及2台电脑和一个单片机,其中一台电脑作为服务器并与单片机相连,负责通过网络与客户端通信(socket)和通过数据线与单片机通过COM口通信(我实验时用的是COM9,其他电脑可能不同需要调整:具体在设备管理器中查看)。
1、Arduino板待烧入代码:(这里硬件的代码没啥好说的,只要你会写个简单Arduino代码并且自己烧过就知道该怎么做啦)
//////////////////////////////////////////////////////////
//Arduino 1.0.x-----Arduino Uno----COM9
//使用3-10号引脚连接8个LED
//////////////////////////////////////////////////////////
int incomingByte = ; //输入的数据存储变量
int count=;
void setup() {
Serial.begin();// opens serial port, sets data rate to 9600 bps
for(int i=;i<=;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=;
}//第一次操作说明,count为了第一次限制
if (Serial.available() > ){
incomingByte = Serial.read();//读取
Serial.println(incomingByte, DEC);//写入
}//从COM口读取数据 switch (incomingByte)//数据处理并对引脚进行调控
{
case ://输入0时将3-10号引脚设为高电位,使所有的灯灭
for(int i=;i<=;i++){
digitalWrite(i,HIGH);
}break;
case ://输入1从3-10号引脚电位依次设低电位维持0.5s,然后设为高电位,实现流水灯效果
for(int i=;i<=;i++){
digitalWrite(i,LOW);
delay();
digitalWrite(i,HIGH);
}break;
case ://输入2流水灯,和输入1时方向相反
for(int i=;i>=;i--){
digitalWrite(i,LOW);
delay();
digitalWrite(i,HIGH);
}break;
case : digitalWrite(,LOW);break;//输入3,将3号电位调低,只让3号引脚的灯亮
case : digitalWrite(,LOW);break; //.....
case : digitalWrite(,LOW);break; //.....
case : digitalWrite(,LOW);break; //.....
case : digitalWrite(,LOW);break; //.....
case : digitalWrite(,LOW);break; //.....
case : digitalWrite(,LOW);break; //.....
case : digitalWrite(,LOW);break;//.....
default:
for(int i=;i<=;i++){
digitalWrite(i,HIGH);
}break;//将所电位调高关闭所有灯
}
}
2、服务器和客户端代码:
package serial;
public class SerialBuffer{
private String Content = "";
private String CurrentMsg, TempContent;
private boolean available = false;
private int LengthNeeded = ;
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(, LengthNeeded);
TempContent = Content.substring(LengthNeeded);
Content = TempContent;
LengthNeeded = ;
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并在具体实现中采取措施实现的数据的同步。
A\SerialBuffer
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是一个进程,它不断的从指定的串口读取
//数据并将其存放到缓冲区中
B\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 = ;
int InitFail = -;
try{
portId = CommPortIdentifier.getPortIdentifier(PortName);
try{
serialPort = (SerialPort)portId.open("Serial_Communication", );
} catch (PortInUseException e){
return InitFail;
}//打开一个串口 try{
in = serialPort.getInputStream();
out = serialPort.getOutputStream();
} catch (IOException e){
return InitFail;
}//读写流实例化 try{
serialPort.setSerialPortParams(,
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 = ; i < Msg.length(); i++)
out.write(Msg.charAt(i));
} catch (IOException e) {}
}//本函数向串口发送一个字符串。参数Msg是需要发送的字符串 public void ClosePort(){
RT.stop();
serialPort.close();
}//本函数停止串口检测进程并关闭串口
}
//SerialBean是本类库与其他应用程序的接口。
//该类库中定义了SerialBean的构造方法以及初始化串口
//从串口读取数据,往串口写入数据以及关闭串口的函数
C\ SerialBean
分别把这3个文件放在D盘中然后分别编译:如下(一定要注意-d后面有一个空格+一个点+一个空格).

三个java文件编译好之后,你将在D盘看到一个serial文件夹,里面有相应的3个class文件。然后把原来的java文件删除或者移到别的地方(非常重要,不然会在编译服务器和客户端时报错)。然后把服务器代码放到刚才的D盘编译 && 客户端代码放到另一台电脑编译(如下图)
import java.util.Scanner;
import java.io.*;
import java.net.*;
import serial.*;
import serial.ReadSerial; public class EchoServer{
private int port = ;
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();
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();
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();
}
}
服务器代码 (这里我用的是port=8000,COM9)如果硬件的com口不一样要做相应调整
//网络通信客户端实现
import java.net.*;
import java.io.*;
import java.util.*; public class EchoClient{
private String host="localhost";
private int port=;
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();
}
}
}//对话函数
}
客户端代码 (这里我用的网络IP为192.168.16.101,port和服务器一制为8000,如果你在做测试时对应网络IP要改为主机IP(网络-详细信息-IPv4)


接着分别启动主机和服务器就可以实现PC通过网络远程控制单片机啦!


PC-PC-单片机(Arduino)通信实例的更多相关文章
- 一个关于小程序与单片机的通信实例(TCP/IP)
前言 这是一个18年初的创业项目的核心功能要求,我们当时打算做一个共享类的项目,项目的主题是共享图书,线下的形式租借图书,我们当时是考虑做一个借书柜的形式,然后线下生产投放借书柜,这些借书柜本身能存放 ...
- 自制单片机之十七……PC与单片机RS-232串口的通讯和控制
这次我们来试着一步步的去掌握PC与单片机通过RS-232进行通讯和控制. 先说说我硬件的情况.我用的PC是个二手的IBM240小本本,十寸屏,赛扬400,机子很老了.但也有它的优点:1.串口,并口,P ...
- 同一个PC只能运行一个应用实例(考虑多个用户会话情况)
原文:同一个PC只能运行一个应用实例(考虑多个用户会话情况) class Program { private static Mutex m; [STAThread] static void Main( ...
- Android单片机与蓝牙模块通信实例代码
Android单片机与蓝牙模块通信实例代码 参考路径:http://www.jb51.net/article/83349.htm 啦啦毕业了,毕业前要写毕业设计,需要写一个简单的蓝牙APP进行交互,通 ...
- labview与单片机串口通信
labview与单片机串口通信 VISA是虚拟仪器软件体系结构的缩写(即Virtual Instruments Software Architecture),实质上是一个I/O口软件库及其规范的总 ...
- PIC18F45K80串口1和串口2异步收发通信实例
PIC18F45K80串口1和串口2异步收发通信实例 一:配置串口1初始化函数 首先打开技术手册,查看异步串口的操作流程以及配置. 需要将串口对应引脚的方向寄存器设置为输入
- Flex通信-与Java实现Socket通信实例
Flex通信-与Java实现Socket通信实例 转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...
- ARM你必须知道的事儿——为啥“PC = PC + 8”?
为啥是“PC = PC + 8”: “PC = PC + 8”其实这样写容易让人蒙了.“PC = PC + 8”真正含义应该是: 执行处代码地址 = PC - 8: 也就是说,”PC指向的地址“领先“ ...
- Linux下简单的socket通信实例
Linux下简单的socket通信实例 If you spend too much time thinking about a thing, you’ll never get it done. —Br ...
随机推荐
- Karma +Jasmine+ require JS进行单元测试并生成测试报告、代码覆盖率报告
1. 关于Karma Karma是一个基于Node.js的JavaScript测试执行过程管理工具(Test Runner). 该工具可用于测试所有主流Web浏览器,也可集成到CI(Continuou ...
- dubbo properties
DUBBO配置项的优先级: java -D优先于 Spring配置,Spring配置优先于 properties文件的配置,这也符合一般项目的规则. 覆盖策略: JVM启动-D参数优先,这样可以使用户 ...
- Multipart to single part feature
Multipart to single part feature Explode Link: http://edndoc.esri.com/arcobjects/8.3/?URL=/arcobject ...
- 英语语法 It all started the summer before second grade when our moving van pulled into her neighborhood
It all started the summer before second grade when our moving van pulled into herneighborhood It all ...
- scala学习心得3
在scala中可以定义函数字面量参数,定义方式如下:
- javascript 命令方式 测试例子
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- hdu 2202 最大三角形 (凸包)
最大三角形 Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- Select查询语句2
一.模糊查询 1.语法结构 select*from table_name where column like '%context%' 在使用like运算符时如果不使用通配符“%”,则like的作用与= ...
- 音痴又音痴的LT (vector)
http://acm.nyist.net/JudgeOnline/problem.php?pid=1261 分析:若是每次都想用sort继而来查第k个数,那会T的特别惨~ C++内置函数upperbo ...
- Daily Scrum 12.4
今日完成任务: 对数据库完成了整理,以下是整理的内容: # 表 改动 原因 1 Answer 保留credit列,作为投票数 建议改名为vote,同意? 2 Answer qid.uid设置为外码 ...