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 ...
随机推荐
- 一步步编写avalon组件01:弹出层组件
avalon2已经稳定下来,是时候教大家如何使用组件这个高级功能了. 组件是我们实现叠积木开发的关键. avalon2实现一个组件非常轻松,并且如何操作这个组件也比以前的avalon2,还是react ...
- linq 对Sum()函数的支持
首先看一段SQL语句: SELECT SUM(TASKAPPR) AS APPRCOUNT, SUM(TASKLOCKED) AS LOCKEDCOUNT, SUM(TASKCHECKED) AS C ...
- Visual Studio 换皮肤
通过字体和颜色修改 Visual Studio 提供了修改配色的入口,你完全可以根据自己的喜好进行自定义,下面就通过该方法把编辑器背景设置成 “豆沙绿”. 选择 工具 / 选项 / 环境 / 字体和颜 ...
- java基础十二[集合与泛型](阅读Head First Java记录)
集合 List 知道索引顺序的集合,ArrayList.LinkedList.Vector三个子类实现了List接口 ArrayList ArrayList没有排序方法,可以用Collection ...
- MVC 学习(二)之Linq to Sql 简单Demo
Linq to Entities 已经我的一篇博文中阐述了,这里阐述一下简单的Linq to Sql 的增删改查.Linq to sql 与Linq to Entities虽然同属于DataBase- ...
- 清除浮动的 why
如果你想第三个p不被前面的浮动层所影响,就对它进行清除如果没有清除,第三个层就会移到第一个p下面 记住!!浮动是用来布局的~你看你的网页设计图,好几个版块在一条线上就是要浮动了,不需要浮动就是版块跟前 ...
- VS发布网站详细步骤
1.打开你的VS2012网站项目,右键点击项目>菜单中 重新生成一下网站项目:再次点击右键>发布: 2.弹出网站发布设置面板,点击<新建..>,创建新的发布配置文件: 输入你自 ...
- Strict Standards: Only variables should be passed by reference
<?php $tag="1 2 3 4 5 6 7"; $tag_sel = array_shift(explode(' ', $tag)); print_r($tag_se ...
- 一些有意思的APP
1.简书:一个优雅的写作/阅读平台. 2.知乎:知识分享社区: 3.behance:设计者的圈子: 4.海词词典:电脑.手机同步查询的好帮手(电脑端快捷键:双击 Alt 弹出/关闭查询框,非常方便) ...
- oracle安装心得
1.官网下载 oracle 11g r2 2.官网下载的oracle包括两个文件夹file1和file2,需要将解压后的file2中的stage-components文件夹下的内容复制到file1-s ...