Android蓝牙控制arduino机器人自走小车

一直以来,Android蓝牙控制arduino机器人自走小车这个项目困惑我好久了,以前把机器人小车的蓝牙地址写死了。现在随着android学习的深入,终于把这个项目全部完善完成了。从andrroid端APP的开发到机器人小车的设计全部统统搞定,现在我具体介绍一下我的项目:

1.机器人端

用到了L298N驱动模块,板子用到的是arduino最小系统板子,蓝牙芯片用到的是HC-05;

工作原理:手机app端蓝牙和机器人端蓝牙建立链接,通过app端蓝牙发送一个字元,机器人蓝牙接收到这个字元以后作出相应的动作。

下面是arduino最小系统板子烧录的程序

<pre name="code" class="cpp">#include <SoftwareSerial.h>
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();
  }
} 


 现在是手机APP端的开发: 

首先让手机打开蓝牙功能,然后收索附近的蓝牙设备,把收索到的蓝牙设备的名称和地址显示在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<String> bluetoothDevices = new ArrayList<String>();
	private ArrayAdapter<String> 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<BluetoothDevice> pairedDevices = bluetoothAdapter
				.getBondedDevices();

		if (pairedDevices.size() > 0)
		{
			for (BluetoothDevice device : pairedDevices)
			{
				bluetoothDevices.add(device.getName() + ":"
						+ device.getAddress() + "\n");
			}
		}
		arrayAdapter = new ArrayAdapter<String>(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 ---");

    }

}

别忘记添加蓝牙权限

<uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

最后附上效果图和机器人图片


  • 13
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值