一直以来,Android蓝牙控制arduino机器人自走小车这个项目困惑我好久了,以前把机器人小车的蓝牙地址写死了。现在随着android学习的深入,终于把这个项目全部完善完成了。从andrroid端APP的开发到机器人小车的设计全部统统搞定,现在我具体介绍一下我的项目:
1.机器人端
用到了L298N驱动模块,板子用到的是arduino最小系统板子,蓝牙芯片用到的是HC-05;
工作原理:手机app端蓝牙和机器人端蓝牙建立链接,通过app端蓝牙发送一个字元,机器人蓝牙接收到这个字元以后作出相应的动作。
下面是arduino最小系统板子烧录的程序
#include
SoftwareSerial BT(10,11);
int MotorLeft1=6;
int MotorLeft2=7;
int MotorRight1=8;
int MotorRight2=9;
char val;
void setup()
{
BT.begin(9600);
pinMode(MotorLeft1, OUTPUT); // 引脚 6 (PWM)
pinMode(MotorLeft2, OUTPUT); // 引脚 7 (PWM)
pinMode(MotorRight1, OUTPUT); // 引脚 8 (PWM)
pinMode(MotorRight2, OUTPUT); // 引脚 9 (PWM)
}
void go()// 前进
{
digitalWrite(MotorRight1,LOW);
digitalWrite(MotorRight2,HIGH);
digitalWrite(MotorLeft1,LOW);
digitalWrite(MotorLeft2,HIGH);
}
void left() //左转
{
digitalWrite(MotorRight1,HIGH);
digitalWrite(MotorRight2,LOW);
digitalWrite(MotorLeft1,LOW);
digitalWrite(MotorLeft2,HIGH);
}
void right() //右转
{
digitalWrite(MotorRight1,LOW);
digitalWrite(MotorRight2,HIGH);
digitalWrite(MotorLeft1,HIGH);
digitalWrite(MotorLeft2,LOW);
}
void STOP() //停止
{
digitalWrite(MotorRight1,LOW);
digitalWrite(MotorRight2,LOW);
digitalWrite(MotorLeft1,LOW);
digitalWrite(MotorLeft2,LOW);
}
void back() //后退
{
digitalWrite(MotorRight1,HIGH);
digitalWrite(MotorRight2,LOW);
digitalWrite(MotorLeft1,HIGH);
digitalWrite(MotorLeft2,LOW);;
}
void loop()
{
if(BT.available() )
{
val = BT.read();
if (val =='W')
{
go();
delay(500);
}
else if (val == 'A')
{
left();
delay(500);
}
else if (val == 'D')
{
right();
delay(500);
}
else if (val == 'S')
{
back();
delay(500);
}
else if (val == 'Q')
STOP();
}
}
首先让手机打开蓝牙功能,然后收索附近的蓝牙设备,把收索到的蓝牙设备的名称和地址显示在ListView上,给ListView设置一个点击时间的监听器,当点击ListView上对应的蓝牙设备,通过SharedPreferences把点击的蓝牙设备address存起来,同时也通过Intent 跳入机器人小车的控制页面,进入机器人小车的控制页面通过取得SharedPreferences里面存的机器人蓝牙的地址,通过BluetoothSocket建立蓝牙链接就可以进行蓝牙之间的通信了;
Android代码如下:
package com.lanzhu1993.bluthtooth;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnItemClickListener
{
private static final String TAG = "Main";
private ListView lvDevices;
private BluetoothAdapter bluetoothAdapter;
private List bluetoothDevices = new ArrayList();
private ArrayAdapter arrayAdapter;
private BluetoothDevice device;
private SharedPreferences sp;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
lvDevices = (ListView) findViewById(R.id.list_search);
sp = getSharedPreferences("config", MODE_PRIVATE);
Set pairedDevices = bluetoothAdapter
.getBondedDevices();
if (pairedDevices.size() > 0)
{
for (BluetoothDevice device : pairedDevices)
{
bluetoothDevices.add(device.getName() + ":"
+ device.getAddress() + "\n");
}
}
arrayAdapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
bluetoothDevices);
lvDevices.setAdapter(arrayAdapter);
lvDevices.setOnItemClickListener(this);
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(receiver, filter);
}
public void onClick_Search(View view)
{
setProgressBarIndeterminateVisibility(true);
setTitle("正在扫描...");
if (bluetoothAdapter.isDiscovering())
{
bluetoothAdapter.cancelDiscovery();
}
bluetoothAdapter.startDiscovery();
}
@Override
public void onItemClick(AdapterView> parent, View view, int position,
long id)
{
String s = arrayAdapter.getItem(position);
String address = s.substring(s.indexOf(":") + 1).trim();
Log.v(TAG, "-------------->"+address);
Toast.makeText(MainActivity.this, address, 1).show();
Editor editor = sp.edit();
editor.putString("address", address);
editor.commit();
Intent intent = new Intent(MainActivity.this,Lanyakongzhi.class);
startActivity(intent);
finish();
}
private final BroadcastReceiver receiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() != BluetoothDevice.BOND_BONDED)
{
bluetoothDevices.add(device.getName() + ":"
+ device.getAddress() + "\n");
arrayAdapter.notifyDataSetChanged();
}
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
{
setProgressBarIndeterminateVisibility(false);
setTitle("连接蓝牙设备");
}
}
};
}
package com.lanzhu1993.bluthtooth;
import android.app.Activity;
import android.os.Bundle;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class Lanyakongzhi extends Activity {
private static final String TAG = "BLUEZ_CAR";
private static final boolean D = true;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
private SharedPreferences sp;
private String address;
Button mButtonF;
Button mButtonB;
Button mButtonL;
Button mButtonR;
Button mButtonS;
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Intent intent = new Intent();
String result = intent.getStringExtra("textViewLabel");
String address = result;
// private static String address = "result" ; // <==要连接的蓝牙设备MAC地址
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.kongzhi);
sp = getSharedPreferences("config", MODE_PRIVATE);
address = sp.getString("address", null);
if(TextUtils.isEmpty(address)){
Toast.makeText(Lanyakongzhi.this, "蓝牙地址为空", 1).show();
}
// //获取蓝牙数据
// Intent intent = new Intent();
// address = intent.getStringExtra("BTname");
// Toast.makeText(Lanyakongzhi.this, address, Toast.LENGTH_SHORT).show();
//前进
mButtonF=(Button)findViewById(R.id.btnF);
mButtonF.setOnTouchListener(new Button.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = event.getAction();
switch(action)
{
case MotionEvent.ACTION_DOWN:
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "W";
msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case MotionEvent.ACTION_UP:
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "0";
msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//后退
mButtonB=(Button)findViewById(R.id.btnB);
mButtonB.setOnTouchListener(new Button.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = event.getAction();
switch(action)
{
case MotionEvent.ACTION_DOWN:
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "S";
msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case MotionEvent.ACTION_UP:
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "0";
msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//左转
mButtonL=(Button)findViewById(R.id.btnL);
mButtonL.setOnTouchListener(new Button.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = event.getAction();
switch(action)
{
case MotionEvent.ACTION_DOWN:
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "A";
msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case MotionEvent.ACTION_UP:
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "0";
msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//右转
mButtonR=(Button)findViewById(R.id.btnR);
mButtonR.setOnTouchListener(new Button.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = event.getAction();
switch(action)
{
case MotionEvent.ACTION_DOWN:
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "D";
msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case MotionEvent.ACTION_UP:
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "0";
msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//停止
mButtonS=(Button)findViewById(R.id.btnS);
mButtonS.setOnTouchListener(new Button.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction()==MotionEvent.ACTION_DOWN)
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
String message = "Q";
byte[] msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
return false;
}
});
if (D)
Log.e(TAG, "+++ ON CREATE +++");
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available.", Toast.LENGTH_LONG).show();
finish();
return;
}
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(this, "Please enable your Bluetooth and re-run this program.", Toast.LENGTH_LONG).show();
finish();
return;
}
if (D)
Log.e(TAG, "+++ DONE IN ON CREATE, GOT LOCAL BT ADAPTER +++");
}
@Override
public void onStart() {
super.onStart();
if (D) Log.e(TAG, "++ ON START ++");
}
@Override
public void onResume() {
super.onResume();
if (D) {
Log.e(TAG, "+ ON RESUME +");
Log.e(TAG, "+ ABOUT TO ATTEMPT CLIENT CONNECT +");
}
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Socket creation failed.", e);
}
mBluetoothAdapter.cancelDiscovery();
try {
btSocket.connect();
Log.e(TAG, "ON RESUME: BT connection established, data transfer link open.");
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
Log .e(TAG,"ON RESUME: Unable to close socket during connection failure", e2);
}
}
// Create a data stream so we can talk to server.
if (D)
Log.e(TAG, "+ ABOUT TO SAY SOMETHING TO SERVER +");
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
String message = "1";
byte[] msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
}
@Override
public void onPause() {
super.onPause();
if (D)
Log.e(TAG, "- ON PAUSE -");
if (outStream != null) {
try {
outStream.flush();
} catch (IOException e) {
Log.e(TAG, "ON PAUSE: Couldn't flush output stream.", e);
}
}
try {
btSocket.close();
} catch (IOException e2) {
Log.e(TAG, "ON PAUSE: Unable to close socket.", e2);
}
}
@Override
public void onStop() {
super.onStop();
if (D)Log.e(TAG, "-- ON STOP --");
}
@Override
public void onDestroy() {
super.onDestroy();
if (D) Log.e(TAG, "--- ON DESTROY ---");
}
}