安卓与ESP8266串口WIFI模块的通信实现
软件简介结合一个控制实例,简要介绍一下安卓客户端软件。主界面非常简洁,左边一个方向控制盘,和右边4个Button。方向盘是一个自定义的View,可以转动任意角度,程序里只响应4个方向,已经足够。四个Button分别对应相应的功能键。通信实现原理使用基于tcp协议的socket通信。串口WiFi模块配置成tcp Service模式,然后安卓连接串口wifi模块的热点,客...
软件简介
结合一个控制实例,简要介绍一下安卓客户端软件。
主界面非常简洁,左边一个方向控制盘,和右边4个Button。方向盘是一个自定义的View,可以转动任意角度,程序里只响应4个方向,已经足够。四个Button分别对应相应的功能键。
通信实现原理
使用基于tcp协议的socket通信。串口WiFi模块配置成tcp Service模式,然后安卓连接串口wifi模块的热点,客户端作为tcp client 连接。连接成功后就可以相互发送数据。
具体实现
串口WiFi模块配置成tcp Service模式,IP设置为192.168.4.1,端口号3824。
(安卓需要先连接到串口WiFi模块所创建的热点。)
客户端的连接方式如下:
private void Connect() {
// 开启线程来发起网络请求
new Thread(new Runnable() {
@Override
public void run() {
try {
socket = new Socket();
socket.connect(new InetSocketAddress(HOST, PORT), 4000);
if(socket != null){
Message message = new Message();
message.what = CONNECTED_RESPONSE;
handler.sendMessage(message);
}
}catch (IOException ex) {
ex.printStackTrace();
Message message = new Message();
message.what = RESPONSE_TIMEOUT;
handler.sendMessage(message);
}
}
}).start();
}
网络操作需要在非UI线程中进行。程序开启一个线程进行连接操作,连接结果通过一个Handler通知主线程,以便UI更新连接状态指示。
连接成功之后,就可以发送数据:
private void TCPSend(final String data) {
if(socket == null)
return;
// 开启线程来发起网络请求
new Thread(new Runnable() {
@Override
public void run() {
try {
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.println(data);
writer.flush();
}catch (IOException ex){
ex.printStackTrace();
Message message = new Message();
message.what = SEND_RESPONSE;
// 将服务器返回的结果存放到Message中
message.obj = "操作失败!";
handler.sendMessage(message);
}
}
}).start();
}
同样的,开启一个线程来进行网络操作,结果也是通过Handler通知主线程。
UI交互界面的响应
网络操作结果的响应通过一个Handler来完成:
private Handler handler = new Handler() {
// 在这里进行UI操作,将结果显示到界面上
public void handleMessage(Message msg) {
switch (msg.what) {
case CONNECTED_RESPONSE:
bt_connect.setTextColor(Color.parseColor("#216F02"));
bt_connect.setText("已连接");
bt_connect.setClickable(false);
disconnect.setTextColor(Color.BLACK);
disconnect.setClickable(true);
break;
case RESPONSE_TIMEOUT:
Toast.makeText(getApplicationContext(),"连接失败!", Toast.LENGTH_SHORT).show();
case RECEIVER_RESPONSE:
case SEND_RESPONSE:
default:
break;
}
}
};
如果连接成功,那么"连接"Button将变成灰色"已连接",且不可点击,"断开连接"将变成可点击,以表明当前是连接状态。
如果连接失败,就弹出一个Toast通知用户:
Button的点击响应如下:
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_connect:
Connect();
break;
case R.id.button_disconnect:
try {
socket.close();
}catch (IOException e){
e.printStackTrace();
}
socket = null;
bt_connect.setTextColor(Color.BLACK);
bt_connect.setText("连接");
bt_connect.setClickable(true);
disconnect.setTextColor(Color.GRAY);
disconnect.setClickable(false);
break;
case R.id.button_auto:
TCPSend("auto\r\n");
btnAuto.setEnabled(false);
btnDisAuto.setEnabled(true);
break;
case R.id.button_dis_auto:
TCPSend("hand\r\n");
btnDisAuto.setEnabled(false);
btnAuto.setEnabled(true);
break;
default:
break;
}
}
为防止重复的点击操作,在点击相应按钮后,根据当前状态,把相应的按钮设置成可点击或不可点击状态。
方向操纵杆的响应:
rockerViewLeft.setOnShakeListener(RockerView.DirectionMode.DIRECTION_4_ROTATE_45, new RockerView.OnShakeListener() {
@Override
public void onStart() {
mLogLeft.setText("停");
}
@Override
public void direction(RockerView.Direction direction) {
String message = "";
switch (direction) {
case DIRECTION_LEFT:
message = "左转";
TCPSend("left\r\n");
break;
case DIRECTION_RIGHT:
message = "右转";
TCPSend("right\r\n");
break;
case DIRECTION_UP:
message = "前进";
TCPSend("forward\r\n");
break;
case DIRECTION_DOWN:
message = "后退";
TCPSend("back\r\n");
break;
case DIRECTION_CENTER:
default:
break;
}
mLogLeft.setText(message);
}
@Override
public void onFinish() {
mLogLeft.setText("停");
TCPSend("stop\r\n");
}
});
操纵杆红点会跟随触摸位置而改变,上方有相应的状态指示,并且松手后会自动滑回中间的停止状态。
END
更多推荐
所有评论(0)