安卓-PC-Arduino3方通信实现
请仔细理解相关参数,如端口设置、IP设置、COM口设置......等等.....不要盲目COPY.....这涉及手机、电脑和一个单片机,其中一台电脑作为服务器并与单片机相连,负责通过网络与客户端通信(socket)和通过数据线与单片机通过COM口通信(我实验时用的是COM9,其他电脑可能不同需要调整:具体在设备管理器中查看)。
1、Arduino端搭建实现:(这里默认大家都会该系列单片机的代码烧写)
//////////////////////////////////////////////////////////
//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;//将所电位调高关闭所有灯
}
}
硬件烧入代码
2、服务器代码:
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并在具体实现中采取措施实现的数据的同步。 A\SerialBuffer
A
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
B
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的构造方法以及初始化串口
//从串口读取数据,往串口写入数据以及关闭串口的函数 C\ SerialBean
C
分别把这3个文件放在D盘中然后分别编译:如下(一定要注意-d后面有一个空格+一个点+一个空格).
三个java文件编译好之后,你将在D盘看到一个serial文件夹,里面有相应的3个class文件。然后把原来的java文件删除或者移到别的地方(非常重要,不然会在编译服务器和客户端时报错)。然后把服务器代码放到D:盘编译如下:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import serial.*;
import serial.ReadSerial; public class MyServer implements Runnable{
public int num=0;
//服务器连接
public static ServerSocket serverSocket;
//连接
public static Socket socket;
//端口
public static final int PORT = 8888;
public void run() {
SerialBean SB = new SerialBean(9);//硬件通信部分,构造一个COM9通信口
SB.Initialize();//初始化该通信端 DataInputStream dis = null;
DataOutputStream dos = null;
try {
serverSocket = new ServerSocket(PORT);
System.out.println("正在等待客户端连接...");
//这里处于等待状态,如果没有客户端连接,程序不会向下执行
while(true){
socket = serverSocket.accept();
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
if((num++)==0){
System.out.println("----客户端已成功连接!----");
//得到客户端的IP
System.out.println("客户端的IP =" + socket.getInetAddress());
//得到客户端的端口号
System.out.println("客户端的端口号 =" + socket.getPort());
//得到本地端口号
System.out.println("本地服务器端口号=" + socket.getLocalPort());
}else{
//读取数据
String clientStr = dis.readUTF();
if(clientStr.equals("close"))break;
//写出数据
dos.writeUTF(clientStr);
System.out.println("客户端:" + clientStr);
SB.WritePort(clientStr);//将从客户端独到的信息读到COM端口中
}
}
SB.ClosePort();//关闭通信端口
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {//我们把流的关闭写在finally里,即使读写出现问题,我们也能正常的关闭流!
try {
if (dis != null)
dis.close();
if (dos != null)
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args){
Thread desktopServerThread = new Thread(new MyServer());
desktopServerThread.start();
}
}
服务器代码 (我这里采用port = 8888 ,COM是COM9 你在实验时,要注意COM是否要修改,这取决于你的电脑(属性-资源管理器-端口)
3、客户端(安卓APP)代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.himi" android:versionCode="1" android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
1、AndroidManifest.xml(主xml文件)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">这里输入文字发给服务器</string>
<string name="app_name">SocketConnect</string>
<string name="send">发送</string>
<string name="get">这里显示服务器发来的信息!</string>
</resources>
2、res/values/strings.xml(资源文件)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" > <Button
android:id="@+id/BTN"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="链接" /> <EditText
android:id="@+id/ET1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/ET2"
android:layout_alignParentTop="true"
android:layout_marginTop="20dp"
android:ems="10"
android:hint="IP" /> <EditText
android:id="@+id/ET2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ET1"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:ems="10"
android:hint="PORT" /> </RelativeLayout>
3、res/layout/mains.xml(界面文件1)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="@string/hello" />
<EditText android:id="@+id/edit" android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button android:id="@+id/Btn_commit" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="@string/send" />
<TextView android:layout_width="fill_parent" android:id="@+id/tv"
android:layout_height="wrap_content" android:text="@string/get" />
</LinearLayout>
4、res/layout/main.xml(界面文件2)
package com.himi; import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket; import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView; public class MainActivity extends Activity {
private Button btn_ok, btn;
private EditText edit, et1, et2;
private TextView tv;
// Socket用于连接服务器获取输入输出流
private Socket socket;
// 服务器server/IP地址
private String ADDRESS = "10.203.8.167";
// 服务器端口
private int PORT = 8888; DataInputStream dis = null;
DataOutputStream dos = null; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.mains);// 加载登陆窗口 et1 = (EditText) findViewById(R.id.ET1);// 登陆窗口元素
et2 = (EditText) findViewById(R.id.ET2);
btn = (Button) findViewById(R.id.BTN);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v1) {
Log.e("Himi", "btn-begin");
if(true){
// TODO Auto-generated method stub if(et1.getText().toString()!=null)ADDRESS = et1.getText().toString();
if(et2.getText().toString()!=null)PORT = Integer.parseInt(et2.getText().toString());
Log.e("Himi", "string right");
try {
// 阻塞函数,正常连接后才会向下继续执行
socket = new Socket(ADDRESS, PORT);
setContentView(R.layout.main);// 加载控制窗口
socket.close();
tv = (TextView) findViewById(R.id.tv);// 对话窗口元素
edit = (EditText) findViewById(R.id.edit);
btn_ok = (Button) findViewById(R.id.Btn_commit);
btn_ok.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Log.e("Himi", "btn-ok-begin");
try {
// 阻塞函数,正常连接后才会向下继续执行
Socket socket1 = new Socket(ADDRESS, PORT);
dis = new DataInputStream(socket1
.getInputStream());
dos = new DataOutputStream(socket1
.getOutputStream());
Log.e("Himi", "bdsffdsfsdfsin");
// 向服务器写数据
dos.writeUTF(edit.getText().toString());
String temp = "I say:";
temp += edit.getText().toString();
temp += "\n";
temp += "Server say:";
// 读取服务器发来的数据
temp += dis.readUTF();
tv.setText(temp);
} catch (IOException e) {
Log.e("Himi", "Stream error!");
e.printStackTrace();
} finally {
try {
if (dis != null)
dis.close();
if (dos != null)
dos.close();
if(socket!=null)
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Log.e("Himi", "btn-ok-end");
}
});
} catch (IOException e) {
Log.e("Himi", "Stream error!");
//e.printStackTrace();
}
}//if(v1==)end
}//onclieck()end
});
}
}
5、Activity文件,客户端端主程序



安卓-PC-Arduino3方通信实现的更多相关文章
- C语言PIC16 serial bootloader和C#语言bootloader PC端串口通信程序
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 新PIC16 Boot ...
- C语言PIC32 serial bootloader和C#语言bootloader PC端串口通信程序
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 今天介绍下我新完成的为 ...
- C语言dsPIC / PIC24 serial bootloader和C#语言bootloader PC端串口通信程序
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 新dsPIC/PIC2 ...
- C语言PIC18 serial bootloader和C#语言bootloader PC端串口通信程序
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 新PIC18 Boot ...
- C语言RL78 serial bootloader和C#语言bootloader PC端串口通信程序
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 前段时间完成的hype ...
- 前端H5与安卓和ios之间通信
在一些app场景中,经常看到app里面嵌套H5页面, 安卓和ios提供一个空壳子,方法两者互相调用.上一周就是写H5页面让安卓和ios调用使用,中间传参,接受参数.通过 window.wx 对象调用一 ...
- C语言RH850 F1L serial bootloader和C#语言bootloader PC端串口通信程序
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程 ...
- C语言RH850 F1KM serial bootloader和C#语言bootloader PC端串口通信程序
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 今天我要介绍的RH85 ...
- android中利用Socket实现手机客户端与PC端进行通信
1. 项目截图
随机推荐
- nginx配置文件注释
#定义Nginx运行的用户和用户组user www www; #nginx进程数,建议设置为等于CPU总核心数.worker_processes 8; #全局错误日志定义类型,[ debug | in ...
- Asp.net Page指令
Page指令为编译器编译页面时使用的指令 指令的格式为 <%@ [Directive] [Attribute=value]%> <%@ Page Language="C#& ...
- Ajax 结构及使用
AJAX AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术. AJAX = 异步 JavaSc ...
- 手机抓包xcode自带命令行工具配合wireshark实现
三.最佳方式:rvictl命令 优点:简单,而且可以抓所有网络接口的数据: 缺点:似乎没有,要求手机iOS5以上不算要求吧?如果说缺点,就是这个命令是Xcode的Command Line Tools ...
- iOS9的新特性以及适配方案
新的iOS 9系统比iOS8更稳定,功能更全面,而且还更加开放.iOS 9加入了更多的新功能,包括更加智能的Siri,新加入的省电模式.iOS 9为开发者提供5000个全新的API. 1. 限制HTT ...
- C# 获取地址栏的地址(URL)
原文地址:http://blog.csdn.net/dingxingmei/article/details/8448009 设当前页完整地址是:http://www.jb51.net/aaa/bbb. ...
- 技术英文单词贴--C
C category 种类,分类,范畴 cols 列数目 comma 逗号 component 组件,部件,成分 configure 配置,安装 configuration 配置,布局,构造 cons ...
- c语言检测文件是否存在int __cdecl access(const char *, int);
最近写代码,遇到很多地方需要判断文件是否存在的.网上的方法也是千奇百怪,“百家争鸣”. fopen方式打开的比较多见,也有其他各种方式判断文件是否存在的,由于其他方法与本文无关,所以不打算提及. 笔者 ...
- Python学习第八天(os)
os主要是实现文件夹的创建和管理功能 os.mkdir(path) 创建目录 os.chdir(path)改变当前工作目录 os.fchdir() 通过文件描述符改变工作目录 os.chroot() ...
- 学习python之练习(一)
#1.计算1000以内3与5的倍数的总和 import math nums = 0 for i in range(0,1000): if i%3 == 0 or i%5 == 0 : if i != ...