最简单DIY基于Android系统的万能蓝牙设备智能遥控器

10 篇文章 8 订阅
订阅专栏

51单片机物联网智能小车系列文章目录


第一篇:最简单DIY的51蓝牙遥控小车设计方案
第二篇:最简单DIY串口蓝牙硬件实现方案
第三篇:最简单DIY蓝牙PS2遥控器控制蓝牙智能小车
第四篇:最简单DIY基于51单片机的舵机控制器
第五篇:最简单DIY基于蓝牙、51单片机和舵机的钢铁爱国者机关枪控制器
第六篇:最简单DIY基于Android系统的万能蓝牙设备智能遥控器


文章目录

  • 51单片机物联网智能小车系列文章目录
  • 前言
  • 一、最简单DIY基于Android系统的万能蓝牙设备智能遥控器是什么?
  • 二、软件制作过程
    • 1.设计软件逻辑
    • 2.分析代码
  • 三、仿真与调试
    • 1.操控舵机云台:准备好硬件,上电,运行app。
    • 2. 操控智能小车
  • 总结


前言

    daodanjishui物联网核心原创技术之最简单DIY基于Android系统的万能蓝牙设备智能遥控器。
    市面上有各种开源智能手机舵机控制器app,但是有复杂的有简单的,如果想快速入门安卓app开发蓝牙设备万能遥控器,这个方案会给你一个快捷高效的方案。


一、最简单DIY基于Android系统的万能蓝牙设备智能遥控器是什么?

    在第五篇完成了51单片机多个舵机控制的设计的遥杆,读者好奇当时为什么不写控制多个舵机的PWM波的手机APP呢?那是因为学习是一个循序渐进的过程,掌握基本的技能才能去举一反三。到现在来看是为我第六篇博文是第五篇博文的升级版,可以手机app替代ESP32蓝牙遥杆控制舵机,并且互相不受影响。安卓手机app的java代码相当精妙,纯粹是自己的原创代码,如果不好好专研深入思考,是不可能写出这样的代码的,物联网技术就需要万物互联,那能不能写一个安卓app来替代单片机组成的硬件蓝牙遥控器,就是使用一个app能控制智能小车( 第一篇)又能控制钢铁爱国者机关枪( 第五篇)?答案是肯定的,这也是鸿蒙系统想要做到的思想。
    虽然市面上也有不少开源的蓝牙调试助手,但是跟硬件结合的代码却很少,特别是能遥控多个蓝牙设备的app更是少见,这个app还能实现在线调试硬件设备,能遥控我设计的智能小车和智能舵机云台,全方位开源原创,现在用文字的形式记录下来,这个代码蓝牙通信代码的改造,除了基本代码之外都是我原创的!这次源码进行了大幅度的升级,代码写得非常精简和奇妙,现在用文字的形式记录下来,对自己童年时代深刻地回忆和对未来技术的展望。“闭门造app”虽然有点痛苦,但是当你看到自己亲手做的app在手机上安装通过自制的遥控器遥控多个设备动起来的时候,你会发现一切的付出都是值得的!全家福如下图所示:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

万能遥控器控制智能小车优酷视频地址:https://v.youku.com/v_show/id_XNDk2MDkyMjI0OA==.html?spm=a2hbt.13141534.app.55!25!2555!255!25!25!255!27A

直接看视频

51智能蓝牙小车控制

万能遥控器控制舵机云台优酷视频地址:https://v.youku.com/v_show/id_XNDk2MDkyMDUwOA==.html?firsttime=0

直接看视频

钢铁爱国者机关枪控制

    功能描述:手机app发送指令控制智能小车或者智能云台,硬件将控制信息通过蓝牙返回给手机app显示,单片机解析控制指令,最后控制二自由度舵机转动或者小车运动,可玩性相当高,其实该app除了可以用蓝牙调试助手按键控制之外,也可以手机自带的重力传感器控制云台或者小车。

二、软件制作过程

1.设计软件逻辑

1.1明确小车控制协议:
(1)FFF\r\n是前进
(2)BBB\r\n是后退
(3)LLL\r\n是左转
(4)RRR\r\n是右转
(5)SSS\r\n是停止

1.2明确舵机控制协议:
(1)FFF\r\n是仰头
(2)BBB\r\n是低头
(3)LLL\r\n是左转
(4)RRR\r\n是右转
(5)SSS\r\n是切换机关开关

1.3准备一份蓝牙串口调试助手的app源码
首先强调一下这个app使用eclipse搭建的Android开发环境编写的Android4.3版本的app,如果想要定制高版本的app或者Android studio版本的源码请联系我。
部分源码如下:

package daodanjishui.Bluetooth;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
@SuppressLint("NewApi")
public class BluetoothService {
	// Debugging
	private static final String TAG = "BluetoothChatService";
	private static final boolean D = true;

	// Name for the SDP record when creating server socket
	private static final String NAME_SECURE = "蓝牙搜索";

	// Unique UUID for this application
	private static final UUID MY_UUID = UUID
			.fromString("00001101-0000-1000-8000-00805F9B34FB");

	// Member fields
	private final BluetoothAdapter mAdapter;
	private final Handler mHandler;
	private AcceptThread mSecureAcceptThread;
	private AcceptThread mInsecureAcceptThread;
	private ConnectThread mConnectThread;
	private ConnectedThread mConnectedThread;
	private int mState;

	// Constants that indicate the current connection state
	public static final int STATE_NONE = 0; // we're doing nothing
	public static final int STATE_LISTEN = 1; // now listening for incoming
												// connections
	public static final int STATE_CONNECTING = 2; // now initiating an outgoing
													// connection
	public static final int STATE_CONNECTED = 3; // now connected to a remote
													// device

	/**
	 * Constructor. Prepares a new BluetoothChat session.
	 * 
	 * @param context
	 *            The UI Activity Context
	 * @param handler
	 *            A Handler to send messages back to the UI Activity
	 */
	@SuppressLint("NewApi")
	public BluetoothService(Context context, Handler handler) {
		mAdapter = BluetoothAdapter.getDefaultAdapter();
		mState = STATE_NONE;
		mHandler = handler;
	}

	/**
	 * Set the current state of the chat connection
	 * 
	 * @param state
	 *            An integer defining the current connection state
	 */
	private synchronized void setState(int state) {
		if (D)
			Log.d(TAG, "setState() " + mState + " -> " + state);
		mState = state;

		// Give the new state to the Handler so the UI Activity can update
		mHandler.obtainMessage(BTconnect.MESSAGE_STATE_CHANGE, state, -1)
				.sendToTarget();
	}

	/**
	 * Return the current connection state.
	 */
	public synchronized int getState() {
		return mState;
	}

	/**
	 * Start the chat service. Specifically start AcceptThread to begin a
	 * session in listening (server) mode. Called by the Activity onResume()
	 */
	public synchronized void start() {
		if (D)
			Log.d(TAG, "start");

		// Cancel any thread attempting to make a connection
		if (mConnectThread != null) {
			mConnectThread.cancel();
			mConnectThread = null;
		}

		// Cancel any thread currently running a connection
		if (mConnectedThread != null) {
			mConnectedThread.cancel();
			mConnectedThread = null;
		}

		setState(STATE_LISTEN);

		// Start the thread to listen on a BluetoothServerSocket
		if (mSecureAcceptThread == null) {
			mSecureAcceptThread = new AcceptThread(true);
			mSecureAcceptThread.start();
		}
		if (mInsecureAcceptThread == null) {
			mInsecureAcceptThread = new AcceptThread(false);
			mInsecureAcceptThread.start();
		}
	}

	/**
	 * Start the ConnectThread to initiate a connection to a remote device.
	 * 
	 * @param device
	 *            The BluetoothDevice to connect
	 * @param secure
	 *            Socket Security type - Secure (true) , Insecure (false)
	 */
	public synchronized void connect(BluetoothDevice device, boolean secure) {
		if (D)
			Log.d(TAG, "connect to: " + device);

		// Cancel any thread attempting to make a connection
		if (mState == STATE_CONNECTING) {
			if (mConnectThread != null) {
				mConnectThread.cancel();
				mConnectThread = null;
			}
		}

		// Cancel any thread currently running a connection
		if (mConnectedThread != null) {
			mConnectedThread.cancel();
			mConnectedThread = null;
		}

		// Start the thread to connect with the given device
		mConnectThread = new ConnectThread(device, secure);//开启一个线程去连接远程蓝牙设备
		mConnectThread.start();
		setState(STATE_CONNECTING);
	}

	/**
	 * Start the ConnectedThread to begin managing a Bluetooth connection
	 * 
	 * @param socket
	 *            The BluetoothSocket on which the connection was made
	 * @param device
	 *            The BluetoothDevice that has been connected
	 */
	@SuppressLint({ "NewApi", "NewApi" })
	public synchronized void connected(BluetoothSocket socket,
			BluetoothDevice device, final String socketType) {
		if (D)
			Log.d(TAG, "connected, Socket Type:" + socketType);

		// Cancel the thread that completed the connection
		if (mConnectThread != null) {
			mConnectThread.cancel();
			mConnectThread = null;
		}

		// Cancel any thread currently running a connection
		if (mConnectedThread != null) {
			mConnectedThread.cancel();
			mConnectedThread = null;
		}

		// Cancel the accept thread because we only want to connect to one
		// device
		if (mSecureAcceptThread != null) {
			mSecureAcceptThread.cancel();
			mSecureAcceptThread = null;
		}
		if (mInsecureAcceptThread != null) {
			mInsecureAcceptThread.cancel();
			mInsecureAcceptThread = null;
		}

		// Start the thread to manage the connection and perform transmissions
		mConnectedThread = new ConnectedThread(socket, socketType);
		mConnectedThread.start();

		// Send the name of the connected device back to the UI Activity
		Message msg = mHandler.obtainMessage(BTconnect.MESSAGE_DEVICE_NAME);//开启连接蓝牙设备的线程之后,还要返回设备的名字给主线程
		Bundle bundle = new Bundle();
		bundle.putString(BTconnect.DEVICE_NAME, device.getName());
		msg.setData(bundle);
		mHandler.sendMessage(msg);

		setState(STATE_CONNECTED);
	}

	/**
	 * Stop all threads
	 */
	public synchronized void stop() {
		if (D)
			Log.d(TAG, "stop");

		if (mConnectThread != null) {
			mConnectThread.cancel();
			mConnectThread = null;
		}

		if (mConnectedThread != null) {
			mConnectedThread.cancel();
			mConnectedThread = null;
		}

		if (mSecureAcceptThread != null) {
			mSecureAcceptThread.cancel();
			mSecureAcceptThread = null;
		}

		if (mInsecureAcceptThread != null) {
			mInsecureAcceptThread.cancel();
			mInsecureAcceptThread = null;
		}
		setState(STATE_NONE);
	}

	/**
	 * Write to the ConnectedThread in an unsynchronized manner
	 * 
	 * @param out
	 *            The bytes to write
	 * @see ConnectedThread#write(byte[])
	 */
	public void write(byte[] out) {
		// Create temporary object
		ConnectedThread r;
		// Synchronize a copy of the ConnectedThread
		synchronized (this) {
			if (mState != STATE_CONNECTED)
				return;
			r = mConnectedThread;
		}
		// Perform the write unsynchronized
				
		r.write(out);
		
	}

	/**
	 * Indicate that the connection attempt failed and notify the UI Activity.
	 */
	private void connectionFailed() {
		// Send a failure message back to the Activity
		Message msg = mHandler.obtainMessage(BTconnect.MESSAGE_TOAST);
		Bundle bundle = new Bundle();
		bundle.putString(BTconnect.TOAST, "Unable to connect device");
		msg.setData(bundle);
		mHandler.sendMessage(msg);

		// Start the service over to restart listening mode
		BluetoothService.this.start();
	}

	/**
	 * Indicate that the connection was lost and notify the UI Activity.
	 */
	private void connectionLost() {
		// Send a failure message back to the Activity
		Message msg = mHandler.obtainMessage(BTconnect.MESSAGE_TOAST);
		Bundle bundle = new Bundle();
		bundle.putString(BTconnect.TOAST, "Device connection was lost");
		msg.setData(bundle);
		mHandler.sendMessage(msg);

		// Start the service over to restart listening mode
		BluetoothService.this.start();
	}

	/**
	 * This thread runs while listening for incoming connections. It behaves
	 * like a server-side client. It runs until a connection is accepted (or
	 * until cancelled).
	 */
	@SuppressLint("NewApi")
	private class AcceptThread extends Thread {
		// The local server socket
		private final BluetoothServerSocket mmServerSocket;
		private String mSocketType;

		@SuppressLint({ "NewApi", "NewApi" })
		public AcceptThread(boolean secure) {
			BluetoothServerSocket tmp = null;

			// Create a new listening server socket
			try {
				tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
						MY_UUID);
			} catch (IOException e) {
				Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);
			}
			mmServerSocket = tmp;
		}

		@SuppressLint({ "NewApi", "NewApi", "NewApi", "NewApi", "NewApi" })
		public void run() {
			if (D)
				Log.d(TAG, "Socket Type: " + mSocketType
						+ "BEGIN mAcceptThread" + this);
			setName("AcceptThread" + mSocketType);

			BluetoothSocket socket = null;

			// Listen to the server socket if we're not connected
			while (mState != STATE_CONNECTED) {
				try {
					// This is a blocking call and will only return on a
					// successful connection or an exception
					socket = mmServerSocket.accept();
				} catch (IOException e) {
					Log.e(TAG, "Socket Type: " + mSocketType
							+ "accept() failed", e);
					break;
				}

				// If a connection was accepted
				if (socket != null) {
					synchronized (BluetoothService.this) {
						switch (mState) {
						case STATE_LISTEN:
						case STATE_CONNECTING:
							// Situation normal. Start the connected thread.
							connected(socket, socket.getRemoteDevice(),
									mSocketType);
							break;
						case STATE_NONE:
						case STATE_CONNECTED:
							// Either not ready or already connected. Terminate
							// new socket.
							try {
								socket.close();
							} catch (IOException e) {
								Log.e(TAG, "Could not close unwanted socket", e);
							}
							break;
						}
					}
				}
			}
			if (D)
				Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);

		}

		public void cancel() {
			if (D)
				Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this);
			try {
				mmServerSocket.close();
			} catch (IOException e) {
				Log.e(TAG, "Socket Type" + mSocketType
						+ "close() of server failed", e);
			}
		}
	}

	/**
	 * This thread runs while attempting to make an outgoing connection with a
	 * device. It runs straight through; the connection either succeeds or
	 * fails.
	 */
	@SuppressLint({ "NewApi", "NewApi" })
	private class ConnectThread extends Thread {
		private final BluetoothSocket mmSocket;
		private final BluetoothDevice mmDevice;
		private String mSocketType;

		@SuppressLint({ "NewApi", "NewApi", "NewApi" })
		public ConnectThread(BluetoothDevice device, boolean secure) {
			mmDevice = device;
			BluetoothSocket tmp = null;
			mSocketType = secure ? "Secure" : "Insecure";

			// Get a BluetoothSocket for a connection with the
			// given BluetoothDevice
			try {
				if (secure) {
					tmp = device
							.createRfcommSocketToServiceRecord(MY_UUID);
				} else {
					tmp = device
							.createInsecureRfcommSocketToServiceRecord(MY_UUID);
				}
			} catch (IOException e) {
				Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
			}
			mmSocket = tmp;
		}

		@SuppressLint({ "NewApi", "NewApi", "NewApi" })
		public void run() {
			Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
			setName("ConnectThread" + mSocketType);

			// Always cancel discovery because it will slow down a connection
			mAdapter.cancelDiscovery();

			// Make a connection to the BluetoothSocket
			try {
				// This is a blocking call and will only return on a
				// successful connection or an exception
				mmSocket.connect();
			} catch (IOException e) {
				// Close the socket
				try {
					mmSocket.close();
				} catch (IOException e2) {
					Log.e(TAG, "unable to close() " + mSocketType
							+ " socket during connection failure", e2);
				}
				connectionFailed();
				return;
			}

			// Reset the ConnectThread because we're done
			synchronized (BluetoothService.this) {
				mConnectThread = null;
			}

			// Start the connected thread
			connected(mmSocket, mmDevice, mSocketType);
		}

		public void cancel() {
			try {
				mmSocket.close();
			} catch (IOException e) {
				Log.e(TAG, "close() of connect " + mSocketType
						+ " socket failed", e);
			}
		}
	}

	/**
	 * This thread runs during a connection with a remote device. It handles all
	 * incoming and outgoing transmissions.
	 */
	@SuppressLint("NewApi")
	private class ConnectedThread extends Thread {
		private final BluetoothSocket mmSocket;
		private final InputStream mmInStream;
		@SuppressLint("NewApi")
		private final OutputStream mmOutStream;
		private  ByteArrayOutputStream out = new ByteArrayOutputStream();

		public ConnectedThread(BluetoothSocket socket, String socketType) {//蓝牙连接线程
			Log.d(TAG, "create ConnectedThread: " + socketType);
			mmSocket = socket;
			InputStream tmpIn = null;
			OutputStream tmpOut = null;

			// Get the BluetoothSocket input and output streams
			try {
				tmpIn = socket.getInputStream();
				tmpOut = socket.getOutputStream();
			} catch (IOException e) {
				Log.e(TAG, "temp sockets not created", e);
			}

			mmInStream = tmpIn;
			mmOutStream = tmpOut;
		}

		public void run() {
			Log.i(TAG, "BEGIN mConnectedThread");
			byte[] buffer = new byte[1024];
			int bytes;

			
			/*
			// Keep listening to the InputStream while connected
			while (true) {
				try {
					// Read from the InputStream
					bytes = mmInStream.read(buffer);//从输入流读取字节到字节数组buffer,如果读取的数组过长,那么返回的信息就会断断续续
					// Send the obtained bytes to the UI Activity
					//mHandler.obtainMessage(BTconnect.MESSAGE_READ, bytes,-1, buffer).sendToTarget();//发消息到主线程					
   		     
					    ByteArrayOutputStream out = new ByteArrayOutputStream();
	                    // 根据读取的长度写入到os对象中
	                    out.write(buffer, 0, bytes);
	                    out.flush();//强制输出到控制台                                                  
	                    //返回消息到主线程
	    				Message msg=new Message();		        
	    		        msg.what=BTconnect.MESSAGE_READ;
	    		        String result=new String(out.toByteArray());
	    		        msg.obj = result;		       
	    		        mHandler.sendMessage(msg);//将消息发回手机主线程查看 
	    		        out.reset();//清空缓冲区
	    		        
					
				} catch (IOException e) {
					Log.e(TAG, "disconnected", e);
					connectionLost();
					break;
				}
			}
			*/
			
		       while (true) {
	                try {
	                    // Read from the InputStream
	                    if( (bytes = mmInStream.read(buffer)) > 0 )
	                    {
		                    byte[] buf_data = new byte[bytes];
					    	for(int i=0; i<bytes; i++)
					    	{
					    		buf_data[i] = buffer[i];
					    	}
							String s = new String(buf_data);
							Message msg = new Message();
							msg.obj = s;
							//msg.what = 1;
							 msg.what=BTconnect.MESSAGE_READ;
							//LinkDetectedHandler.sendMessage(msg);
							 mHandler.sendMessage(msg);//将消息发回手机主线程查看
	                    }
	                } catch (IOException e) {
	                	try {
							mmInStream.close();
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
	                    break;
	                }
	            }
			
			
		}

		/**
		 * Write to the connected OutStream.
		 * 
		 * @param buffer
		 *            The bytes to write
		 */
		@SuppressLint("NewApi")
		public void write(byte[] buffer) {
			try {
				    mmOutStream.write(buffer);//直接写给蓝牙模块
				    System.out.println("----发送指令到蓝牙模块--------"+new String(buffer));
			
				    //ByteArrayOutputStream out = new ByteArrayOutputStream();
                    // 根据读取的长度写入到os对象中
                    //out.write(buffer, 0, buffer.length);
                    //out.flush();//强制输出到控制台   
				    
				    
                    //返回消息到主线程
    				Message msg=new Message();		        
    		        msg.what=BTconnect.MESSAGE_WRITE;
    		       // String result=new String(out.toByteArray());  
    		        msg.obj = new String(buffer);//存入消息		       
    		        mHandler.sendMessage(msg);//将消息发回BTconnect主线程查看 
    		        
    		       // out.reset();//清空缓冲区          
				// Share the sent message back to the UI Activity
				//mHandler.obtainMessage(BTconnect.MESSAGE_WRITE, -1, -1,buffer.toString()).sendToTarget();//在返回写出的信息到主线程。
			} catch (IOException e) {
				Log.e(TAG, "Exception during write", e);
			}
		}

		public void cancel() {
			try {
				mmSocket.close();
			} catch (IOException e) {
				Log.e(TAG, "close() of connect socket failed", e);
			}
		}
	}
}

1.4准备一份重力传感器的app源码
部分代码如下:

package daodanjishui.Bluetooth;



import java.util.Enumeration;
import org.join.wfs.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.Camera.Size;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.view.SurfaceHolder.Callback;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import android.widget.CompoundButton.OnCheckedChangeListener;

/**
 * This is the main Activity that displays the current chat session.
 */
@SuppressLint("HandlerLeak")
public class BTconnect extends Activity {
	//下面是重力传感器添加
	//ToggleButton transButton;
	Button button3,button4,button5,button6,button7,button8;
	SensorManager sensorManager;// 管理器对象
	private Sensor gyroSensor;// 陀螺 传感器对象
	private Sensor acceSensor;// 加速度
	private Sensor quatSensor;// 旋转矢量
	private TextView tv_X;
	private TextView tv_Y;
	private TextView tv_Z;
	boolean transFlag = false;//重力传感器开关
	
	// Debugging
		private static final String TAG = "BTconnect";
		private static final boolean D = true;

		// Message types sent from the BluetoothChatService Handler
		public static final int MESSAGE_STATE_CHANGE = 1;
		public static final int MESSAGE_READ = 2;
		public static final int MESSAGE_WRITE = 3;
		public static final int MESSAGE_DEVICE_NAME = 4;
		public static final int MESSAGE_TOAST = 5;

		// Key names received from the BluetoothChatService Handler
		public static final String DEVICE_NAME = "device_name";
		public static final String TOAST = "toast";

		// Intent request codes
		private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
		private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
		private static final int REQUEST_ENABLE_BT = 3;

		// Layout Views
		private TextView mTitle;
		TextView  textView0,textView1,textView2;
		// Name of the connected device
		private String mConnectedDeviceName = null;
		// String buffer for outgoing messages
		private static StringBuffer mOutStringBuffer;
		// Local Bluetooth adapter
		private BluetoothAdapter mBluetoothAdapter = null;
		// Member object for the chat services
		private static BluetoothService mChatService = null;
		int cout = 0;
		private Button button=null;
		private Button button2=null;
		private EditText editText=null;
		private boolean Bluetooth_connect_flag=false;
	
	
	
	public void projectinit() {

		sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
		gyroSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
		acceSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		quatSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
		if (gyroSensor == null) {
			Toast.makeText(BTconnect.this, "您的设备不支持陀螺仪~~~", Toast.LENGTH_SHORT).show();
		} else {			
			/**
			 * 注册监听器
			 */
			sensorManager.registerListener(sensoreventlistener, gyroSensor,
					SensorManager.SENSOR_DELAY_GAME);
			sensorManager.registerListener(sensoreventlistener, acceSensor,
					SensorManager.SENSOR_DELAY_GAME);
			sensorManager.registerListener(sensoreventlistener, quatSensor,
					SensorManager.SENSOR_DELAY_GAME);

		}
	}	
		
		private SensorEventListener sensoreventlistener = new SensorEventListener() {
			private long acceTime;
			private float[] acce = { 0, 0, 0, };	
			byte command;
			int value = 0x00;
			private int count1 = 0;

			@SuppressWarnings("deprecation")
			@Override
			public void onSensorChanged(SensorEvent event) {
							
				float[] values = event.values;
			

				if (event.sensor == acceSensor) {//加速度
					acce[0] = values[0];
					acce[1] = values[1];
					acce[2] = values[2];
					this.acceTime = event.timestamp;
				}
			
				 tv_X.setText("X-acce:" + Float.toString(acce[0]));//手机左右加速度,x
				 tv_Y.setText("Y-acce:" + Float.toString(acce[1]));//手机前后加速度,y
				 tv_Z.setText("Z-acce:" + Float.toString(acce[2]));//手机上下加速度,平放静止手机这个值是9.8,z

				if (count1 >= 10) {//延时采集数据
					  textView2.setText("重力手势的状态是:"+transFlag);					
					if (transFlag){
						//sendCmd(command, value);//如果手势开关打开了,就发送手势参数给蓝牙模块
						//sendMessage(value+"");//
						//在这里写逻辑
						if(acce[0]<-5&&acce[1]<-2&&acce[2]>0){//右转,acce[0]=x,acce[1]=y,acce[2]=z
							sendMessage("RRR"+"\r\n");
						}else if(acce[0]>5&&acce[1]<-2&&acce[2]>0){//左转
							sendMessage("LLL"+"\r\n");
						}else if(acce[0]<1&&acce[0]>-1&&acce[1]<-3&&acce[2]>0){//前进
							sendMessage("FFF"+"\r\n");
						}else if(acce[0]<1&&acce[0]>-1&&acce[1]>3&&acce[2]>0){//后退
							sendMessage("BBB"+"\r\n");
						}else if(acce[0]<1&&acce[0]>-1&&acce[1]>-1&&acce[1]<1&&acce[2]>0){//停止
							sendMessage("SSS"+"\r\n");
						}else
							sendMessage("SSS"+"\r\n");//停止
					}
					count1=0;
				}
				count1++;
						
				
			}

			@Override
			public void onAccuracyChanged(Sensor sensor, int accuracy) {
				// TODO Auto-generated method stub
			}

		};	
		

	@SuppressLint("NewApi")
	@Override
	public void onCreate(Bundle savedInstanceState) {	
		super.onCreate(savedInstanceState);
		if (D)
			Log.e(TAG, "+++ ON CREATE +++");

		// Set up the window layout
		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		setContentView(R.layout.bluetooth);
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.custom_title);
		
		tv_X = (TextView) findViewById(R.id.tvX);
		tv_Y = (TextView) findViewById(R.id.tvY);
		tv_Z = (TextView) findViewById(R.id.tvZ);
		button3 = (Button) findViewById(R.id.button3);
		button3.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
	           if(transFlag==false)
	        	   transFlag=true;
	           else
	        	   transFlag=false;
	           Toast.makeText(BTconnect.this, "transFlag="+transFlag,Toast.LENGTH_SHORT).show(); //显示消息提示
				
			}
			
		});
		
		
		
		button4 = (Button) findViewById(R.id.button4);//前进
		button4.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				if(Bluetooth_connect_flag){				
					 BTconnect.sendMessage("FFF"+"\r\n");//加入\r\n的字符串才能触发stm32串口1中断
					}else{
						Toast.makeText(BTconnect.this, "蓝牙还有没有连接上",Toast.LENGTH_SHORT).show(); // 显示消息提示
					}				
			}
			
		});
		button5 = (Button) findViewById(R.id.button5);//向左
		button5.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				if(Bluetooth_connect_flag){				
					 BTconnect.sendMessage("LLL"+"\r\n");//加入\r\n的字符串才能触发stm32串口1中断
					}else{
						Toast.makeText(BTconnect.this, "蓝牙还有没有连接上",Toast.LENGTH_SHORT).show(); // 显示消息提示
					}
				
			}
			
		});
		button6 = (Button) findViewById(R.id.button6);//向右
		button6.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				if(Bluetooth_connect_flag){				
					 BTconnect.sendMessage("RRR"+"\r\n");//加入\r\n的字符串才能触发stm32串口1中断
					}else{
						Toast.makeText(BTconnect.this, "蓝牙还有没有连接上",Toast.LENGTH_SHORT).show(); // 显示消息提示
					}
				
			}
			
		});
		button7 = (Button) findViewById(R.id.button7);//向后
		button7.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				if(Bluetooth_connect_flag){				
					 BTconnect.sendMessage("BBB"+"\r\n");//加入\r\n的字符串才能触发stm32串口1中断
					}else{
						Toast.makeText(BTconnect.this, "蓝牙还有没有连接上",Toast.LENGTH_SHORT).show(); // 显示消息提示
					}
				
			}
			
		});
		button8 = (Button) findViewById(R.id.button8);//停止
		button8.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				if(Bluetooth_connect_flag){				
					 BTconnect.sendMessage("SSS"+"\r\n");//加入\r\n的字符串才能触发stm32串口1中断
					}else{
						Toast.makeText(BTconnect.this, "蓝牙还有没有连接上",Toast.LENGTH_SHORT).show(); // 显示消息提示
					}
				
			}
			
		});
		projectinit(); // 初始化传感器监听
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // 保持屏幕常亮			
		  textView0= (TextView) findViewById(R.id.textView0); 
		  textView1= (TextView) findViewById(R.id.textView1);
		  textView2= (TextView) findViewById(R.id.textView2);
		  textView1.setText("等待机器人的回应");	
		  textView2.setText("手势开关的状态是:"+transFlag);	
		  editText=(EditText)findViewById(R.id.editText1);
		     button=(Button)findViewById(R.id.button1);
		     
		 	button.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View arg0) {
					if(Bluetooth_connect_flag){
					Toast.makeText(BTconnect.this, "提交蓝牙指令是:"+editText.getText().toString(),Toast.LENGTH_SHORT).show(); // 显示消息提示
					//ipname=editText.getText().toString();
					 BTconnect.sendMessage(editText.getText().toString()+"\r\n");//加入\r\n的字符串才能触发stm32串口1中断
					 editText.setText("");
					}else{
						Toast.makeText(BTconnect.this, "蓝牙还有没有连接上",Toast.LENGTH_SHORT).show(); // 显示消息提示
					}
				}
			});
			
		 	
		 	 button2=(Button)findViewById(R.id.button2);
		 	 button2.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View arg0) {
					     Intent serverIntent = null;			
						// Launch the DeviceListActivity to see devices and do scan
						serverIntent = new Intent(BTconnect.this, DeviceListActivity.class);
						startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);//注意有返回值
				}
			});
		 	
		
		// Set up the custom title
		mTitle = (TextView) findViewById(R.id.title_left_text);
		mTitle.setText(R.string.app_name);
		mTitle = (TextView) findViewById(R.id.title_right_text);	
		
		//mTitle.setText(getIpAddress());			
		// Get local Bluetooth adapter
		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		// If the adapter is null, then Bluetooth is not supported
		if (mBluetoothAdapter == null) {
			Toast.makeText(this, "Bluetooth is not available",
					Toast.LENGTH_LONG).show();
			finish();
			return;
		}
		
		
	}
	
		
	@SuppressLint("NewApi")
	@Override
	public void onStart() {
		super.onStart();
		if (D)
			Log.e(TAG, "++ ON START ++");

		// If BT is not on, request that it be enabled.
		// setupChat() will then be called during onActivityResult
		if (!mBluetoothAdapter.isEnabled()) {
			/*Intent enableIntent = new Intent(
					BluetoothAdapter.ACTION_REQUEST_ENABLE);
			startActivityForResult(enableIntent, REQUEST_ENABLE_BT);*/
			
			//历史蓝牙连接上之后自动跳转到 主窗口

			// Otherwise, setup the chat session
		} else {
			if (mChatService == null)
				setupChat();
		}
	}

	@Override
	public synchronized void onResume() {
		super.onResume();
		if (D)
			Log.e(TAG, "+ ON RESUME +");

		// Performing this check in onResume() covers the case in which BT was
		// not enabled during onStart(), so we were paused to enable it...
		// onResume() will be called when ACTION_REQUEST_ENABLE activity
		// returns.
		if (mChatService != null) {
			// Only if the state is STATE_NONE, do we know that we haven't
			// started already
			if (mChatService.getState() == BluetoothService.STATE_NONE) {
				// Start the Bluetooth chat services
				mChatService.start();
			}
		}
	}

	@SuppressLint("NewApi")
	private void setupChat() {
		Log.d(TAG, "setupChat()");

		// Initialize the BluetoothChatService to perform bluetooth connections
		mChatService = new BluetoothService(this, mHandler);
		// Initialize the buffer for outgoing messages
		mOutStringBuffer = new StringBuffer("");		
	}

	@Override
	public synchronized void onPause() {
		super.onPause();
		if (D)
			Log.e(TAG, "- ON PAUSE -");
	}

	@Override
	public void onStop() {
		super.onStop();
		if (D)
			Log.e(TAG, "-- ON STOP --");
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		// Stop the Bluetooth chat services
		if (mChatService != null)
			mChatService.stop();
		if (D)
			Log.e(TAG, "--- ON DESTROY ---");
	}

	@SuppressLint("NewApi")
	private void ensureDiscoverable() {
		if (D)
			Log.d(TAG, "ensure discoverable");
		if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {//打开蓝牙
			Intent discoverableIntent = new Intent(
					BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
			discoverableIntent.putExtra(
					BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
			startActivity(discoverableIntent);
		}
	}

	
	public static void sendMessage(String message) {
		// Check that we're actually connected before trying anything
		if (mChatService.getState() != BluetoothService.STATE_CONNECTED) {
//			Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT)
//					.show();
			return;
		}

		
		// Check that there's actually something to send
		if (message.length() > 0) {
			// Get the message bytes and tell the BluetoothChatService to write
			byte[] send = message.getBytes();
			mChatService.write(send);
			
			// Reset out string buffer to zero and clear the edit text field
			mOutStringBuffer.setLength(0);
		}
	}

	// The Handler that gets information back from the BluetoothChatService
	private final Handler mHandler = new Handler() {//接收BluetoothChatService发回来的消息并且解析这些消息,提取数据,如果是获取蓝牙设备返回的消息,需要用这个
	//但是如果是单纯发送数据到蓝牙设备的话,直接用sendMessage(String message)就可以了
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MESSAGE_STATE_CHANGE:
				if (D)
					Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
				switch (msg.arg1) {
				case BluetoothService.STATE_CONNECTED://连接成功了就可以跳转到监控界面了
					mTitle.setText(R.string.title_connected_to);
					mTitle.append(mConnectedDeviceName);
					Bluetooth_connect_flag=true;
					//startActivity(new Intent (BTconnect.this, CameraTest.class) );//连接成功了就可以跳转到监控界面了
					break;
				case BluetoothService.STATE_CONNECTING:
					mTitle.setText(R.string.title_connecting);
					break;
				case BluetoothService.STATE_LISTEN:
				case BluetoothService.STATE_NONE:
					mTitle.setText(R.string.title_not_connected);
					break;
				}
				break;
			case MESSAGE_DEVICE_NAME:
				// save the connected device's name
				mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);//BTconnect.DEVICE_NAME
				Toast.makeText(getApplicationContext(),
						"Connected to " + mConnectedDeviceName,
						Toast.LENGTH_SHORT).show();//显示连接到的是哪个蓝牙设备
				break;
			case MESSAGE_TOAST:
				Toast.makeText(getApplicationContext(),
						msg.getData().getString(TOAST), Toast.LENGTH_SHORT)
						.show();
				break;
			case  MESSAGE_READ:
				//Toast.makeText(getApplicationContext(),msg.getData().toString(), Toast.LENGTH_SHORT).show();							
				//System.out.println("收到的蓝牙消息是"+msg.getData().toString());
				Object result1 = msg.obj;
				System.out.println("收到蓝牙模块的消息是:"+result1); 
				
				//Toast.makeText(getApplicationContext(),"recive from BT:"+result1, Toast.LENGTH_SHORT).show();	
				 textView1.setText("recive from BT:"+result1);	

				break;
			case MESSAGE_WRITE:	
				Object result = msg.obj;
                //result=msg.getData().getString("result");
                System.out.println("send to BT:"+result); 
                //Toast.makeText(getApplicationContext(),"send to BT:"+result, Toast.LENGTH_SHORT).show();
				//Toast.makeText(getApplicationContext(),"send to BT:"+msg.getData().toString(), Toast.LENGTH_SHORT).show();
				break;
			}
		}
	};

	public void onActivityResult(int requestCode, int resultCode, Intent data) {//接收DeviceListActivity界面返回的结果
		if (D)
			Log.d(TAG, "onActivityResult " + resultCode);
		switch (requestCode) {//请求码
		case REQUEST_CONNECT_DEVICE_SECURE://请求连接设备,startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);//注意有返回值
			// When DeviceListActivity returns with a device to connect
			if (resultCode == Activity.RESULT_OK) {//请求成功了
				connectDevice(data, true);
			}
			break;
		case REQUEST_CONNECT_DEVICE_INSECURE:
			// When DeviceListActivity returns with a device to connect
			if (resultCode == Activity.RESULT_OK) {
				connectDevice(data, false);
			}
			break;
		case REQUEST_ENABLE_BT:
			// When the request to enable Bluetooth returns
			if (resultCode == Activity.RESULT_OK) {
				// Bluetooth is now enabled, so set up a chat session
				setupChat();
			} else {
				// User did not enable Bluetooth or an error occured
				Log.d(TAG, "BT not enabled");
				Toast.makeText(this, R.string.bt_not_enabled_leaving,
						Toast.LENGTH_SHORT).show();
				finish();
			}
		}
	}

	@SuppressLint({ "NewApi", "NewApi" })
	private void connectDevice(Intent data, boolean secure) {
		// Get the device MAC address
		String address = data.getExtras().getString(
				DeviceListActivity.EXTRA_DEVICE_ADDRESS);//获取意图返回的设备地址
		// Get the BLuetoothDevice object
		BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);//去连接蓝牙设备
		// Attempt to connect to the device
		mChatService.connect(device, secure);//去连接蓝牙设备
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.option_menu, menu);				
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {//链接蓝牙的第一步
		Intent serverIntent = null;
		switch (item.getItemId()) {
		case R.id.secure_connect_scan:
			// Launch the DeviceListActivity to see devices and do scan
			serverIntent = new Intent(this, DeviceListActivity.class);
			startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);//注意有返回值
			return true;
		}
		return false;
	}
	

	
}

1.5组合代码。缺省代码说明:整个安卓工程一个三个文件,非常简洁,很适合二次开发或者学习,目前给出了两个最重要的文件,还剩下一个蓝牙设备列表的文件,如果耐心够的读者慢慢看两个代码也能收获很多,说不定还能再现我这个app出来,毕竟代码关键的地方都写了注释,这个代码我编写了一周,如果感兴趣的读者想要我全部的源码,麻烦到我指定的地方下载工程吧,尊重原创,尊重劳动成果,我能保证的是我的app绝对是靠谱的,能控制所指定的硬件。

2.分析代码

    首先强调一下这个app使用eclipse搭建的Android开发环境编写的Android4.3版本的app,如果想要定制高版本的app或者Android studio版本的源码请联系我,其实用什么软件开发程序都是次要的,关键是你设计产品的逻辑。记得我的老师说过,其实开发语言只是工具而已,关键还是你自己心中是否有完整的运行逻辑机制。
    其实给出的源码我写上了完整的注释了,就说说读者能学到什么内容吧?这份源码可以学习的地方很多的,比如handler,蓝牙的调用和使用,主界面更新UI,activity参数传递,回调函数的使用,IO流控制,字节传输,重力传感器的调用和使用,私人通信协议的定制和解析判断,蓝牙通信反馈设计等等,如果要实现安卓手机app来控制蓝牙设备,那么我这个源码绝对物超所值!


三、仿真与调试

1.操控舵机云台:准备好硬件,上电,运行app。

1.1刚开始运行app可以看到正下方显示了三个方向的手机重力加速度和重力手势开关状态和蓝牙连接状态
在这里插入图片描述
1.2然后启动智能小车或者是钢铁爱国者机关枪,再打开手机蓝牙,再点击“设置蓝牙”,出现
在这里插入图片描述
1.3上面的图会看到我历史上连接好的设备,如果记性好是可以直接连上正在通电的HC-05蓝牙设备了,新安装软件如下显示,再也没有历史信息了。
在这里插入图片描述
1.4那么我们需要点击“搜索设备”,这个功能还是很人性化的,可以帮助用户搜寻需要连接的蓝牙设备,比如我这里有智能小车和爱国者机关枪,那它们名字是一样的,但是mac地址不一样,也是可以区分开来的。搜索结果如下所示
在这里插入图片描述
1.5最后点击搜索出来的蓝牙信息,点击输入密码1234,不行就输入0000,即可连上,出现下图所示,已连接。
在这里插入图片描述
在这里插入图片描述
1.6连上之后 ,就可以开始控制蓝牙设备了,这个万能遥控器可以使用三种模式控制:第一种是指令发送;第二种是方向按键控制;第三种是重力传感器控制。非常人性化,也方便用户调试,另外蓝牙设备反馈可以在手机app显示出来,这是很多app没有的功能。

剩下的事情就交给视频来说明了。

2. 操控智能小车

这里就交给视频说明吧。类似上面操控智能舵机云台一样的道理。

总结

    说了那么多,无非就是想强调这份源码可以学习的地方很多的,比如handler,蓝牙的调用和使用,主界面更新UI,activity参数传递,回调函数的使用,IO流控制,字节传输,重力传感器的调用和使用,私人通信协议的定制和解析判断,蓝牙通信反馈设计等等,如果要实现安卓手机app来控制蓝牙设备,那么我这个源码绝对物超所值!
    现代生活中蓝牙设备原来越多,所以手机智能蓝牙控制app的开发永不停止,除了蓝牙之外WIFI的应用也很广泛,那么下一期我将推出万能wifi app控制器,并且使用该控制器控制WiFi设备,敬请期待。

代码工程下载链接:https://gf.bilibili.com/item/detail/1107736114
点我直接跳转
花5个积分apk安装包试用链接

安卓手机与蓝牙模块联合调试(五)-- 编写自己的蓝牙控制界面控制单片机(上篇,Android 代码实现)
菜鸟江涛的博客
09-18 1万+
(1)安卓手机与蓝牙模块联合调试(一)—— 蓝牙模块的串口通讯 (2)安卓手机与蓝牙模块联合调试(二)—— 单片机蓝牙控制LED灯亮灭(上) (3)安卓手机与蓝牙模块联合调试(三)—— 单片机蓝牙控制LED灯亮灭(下) (4)安卓手机与蓝牙模块联合调试(四)—— 单片机数据上传至蓝牙(STC89C52 + DS18b20) 本教程的项目地址:1989Jiangtao/BluetoothS.........
android 遥控器方向,最简单DIY基于Android系统万能蓝牙设备智能遥控器
weixin_33594971的博客
05-25 1237
前几期的开源代码中,我分享了最简单DIY51蓝牙遥控小车设计方案:https://www.cirmall.com/circuit/20409 使用蓝牙调试助手来控制的智能小车;还分享了最简单DIY串口蓝牙硬件实现方案——ESP32充当电脑串口蓝牙遥控蓝牙设备:https://www.cirmall.com/circuit/20409 ;还分享了最简单DIY基于蓝牙51单片机的钢铁爱国者机关枪控...
Android遥控器开发
u010663063的专栏
09-09 1万+
接到公司的一个预研项目,开发一个Android端的万能遥控器,就是网上随意可以下到的遥控精灵类似的软件。经过将近一个星期的捣鼓,终于达到与遥控精灵差不多的效果,特将开发的一些难点与大家分享一下。(由于本人职位特殊性,工程不方便上传,见谅) 首先,开发这样一款遥控器需要哪些知识?如果您毕业于电子信息类专业,会一点单片机,知道频率什么的,然后初中学的三角函数没有忘记,最后,您还会开发Android
手机蓝牙遥控器设计
02-08
设计一个基于蓝牙无线通信的简易电脑遥控器。根据 USB 基本通信协议以及蓝牙基本传输数据方式,利用 Android 手机自带的蓝牙功能向蓝牙模块传送在手机上获取的数据,实现在手机屏幕上滑动或者点击就可以像 USB 鼠标一下控制电脑或是对 PPT播放控制等功能
android 蓝牙遥控开发
最新发布
weixin_36885892的博客
06-28 44
Android蓝牙遥控开发 在Android开发中,蓝牙技术被广泛应用于各种应用场景,其中之一就是蓝牙遥控开发。通过蓝牙遥控可以实现对设备的远程控制,例如控制智能家居设备、遥控小车等。本文将介绍如何在Android应用中开发蓝牙遥控功能。 蓝牙权限 在AndroidManifest.xml文件中添加蓝牙权限: 登录后复制 ...
我也DIY一个Android遥控器-全部开源
热门推荐
Android/Linux的专栏
09-18 4万+
记得宋宝华在「设备驱动开发详解」提出一个这样的理论「软件和硬件互相渗透对方的领地」,这次证明还是确实是这样,使用上层APP软件加上简单的更为简单的硬件设计就可以完成一个遥控器了。
《手机蓝牙遥控器设计》PDF
08-30
《手机蓝牙遥控器设计》
android开发红外遥控器
04-14
怎样用android开发红外万能遥控器
基于Android系统蓝牙遥控APP
04-17
用于连接小车上的蓝牙模块,实现对小车的遥控。这个APP是通过JAVA代码来编写的,实际上就是一个通过Android Studio的编译生成的APK文件。小车蓝牙和手机端成功完成配对,使用手机APP上的键盘控制给小车发送指令,...
android9.0ble补丁蓝牙语音遥控器支持补丁.rar
07-21
目前通过ble hal实现从hidraw中读取遥控器语音数据,在Android框架层上就通过配置文件将ble hal导入到音频框架中,并通过绑定Android原生已有的耳麦设备来完成audio音频策略选择,通过apk检测ble连接状态,通知audio...
基于安卓系统手机WiFi的家用智能遥控器开发
01-19
摘要:文章主要介绍基于安卓系统手机WiFi的家用智能遥控器客户端的开发。通过在安卓手机上开发遥控器界面,并载入多个不同品牌不同型号设备遥控器指令数据包,借助WiFi转红外模块译码成与家电相匹配的红外信号,使...
Android-万能遥控器-实现了类似小米万能遥控器的基本功能还可以遥控电脑
08-13
万能遥控器-实现了类似小米万能遥控器的基本功能,还可以遥控电脑
蓝牙遥控器软件,可以将你的手机变成一部电脑遥控器,使用手机可以控制电脑的鼠标操作、键盘的输入,如果你的手机具有手写功能,还可以将你的手机变成手写板。
07-07
【软件功能】 蓝牙遥控器软件,可以将你的手机变成一部电脑遥控器,使用手机可以控制电脑的鼠标操作、键盘的输入,如果你的手机具有手写功能,还可以将你的手机变成手写板。 这个软件分为两部分,一个是安装到手机上,另一个安装在电脑上。 手机端: 软件文件名为BtRemoteControl.jar,它要求安装的手机具有java功能,并支持MIDP2.0,具有蓝牙功能。 电脑端: 要想在电脑上运行遥控器,要求安装蓝牙驱动程序widcomm驱动或IVT BlueSoleil驱动。 同时,还要求电脑上安装.net运行库2.0,如果你的电脑没有安装,必须先安装Microsoft .NET Framework 2.0 。 【使用说明】 电脑端的安装使用: 蓝牙遥控器电脑端在电脑上安装后,双击图标桌面上产生的图标。 首先在“请选择接受遥控的蓝牙虚拟串口”后面,选择蓝牙的虚拟串口名字,软件里已经包括了从com1到com20的串口名字,请根据自己机器上的蓝牙虚拟串口名字选择,如果你无法确定,可以用手机上的蓝牙遥控器软件测试1下。 选择好串口名字后,点下“打开串口”按钮,将显示“蓝牙串口状态:"已打开,这时就可以接受手机方的控制了。 手机端的安装使用: 和其它的JAVA程序在手机上的安装过程一样,先用蓝牙、红外线或数据线将手机与电脑连接,将BtRemoteControl.jar安装到手机,在手机的功能表里就会出现“蓝牙遥控器”标志,运行软件,会出现“启动蓝牙”选择,运行该选择,软件将搜索周围准备接受遥控的电脑上的蓝牙设备,搜索片刻后,将显示搜到蓝牙设备,并接着显示蓝牙设备上的蓝牙虚拟串口服务是否存在。 如果搜索后显示未找到蓝牙设备,请检查你的手机是否启动了蓝牙,你的电脑上的蓝牙驱动程序是否启动,蓝牙设备是否插好。 在找到蓝牙设备蓝牙上的虚拟串口后,手机上将会有如下3个菜单选择: 发送测试:用来测试电脑上的蓝牙虚拟串口是否可以接受数据,同时可以测试出蓝牙虚拟串口的名字,供电脑方的遥控软件设置使用,按下这个按钮,就可以向电脑的虚拟串口发送1个数据,测试串口。 控制鼠标和键盘:选择了这个菜单,将显示遥控鼠标、键盘界面.这个选择有3个功能,用户可以按下#号键,在这三个功能之间切换,这三个功能: 1、遥控鼠标。手机方向键的上下左右四个键,控制鼠标上下左右移动,按下0键,遥控单击鼠标右键,按下9键,遥控单击鼠标左键,按下ok键,遥控双击鼠标左键。按下1,3,7个键,调整鼠标移动的距离,1键是短距离,3键是中距离,7键是长距离。 2、遥控鼠标自动移动。按下上下左右四个方向键,鼠标将按照操作自动上下左右移动,一直到屏幕的边缘才停止,按下*号键,停止自动运行。 3、遥控键盘。按下手机上的0到9号键,将向电脑发送命令0到9,在电脑上,可以进行设置,当接到命令时如何控制键盘。电脑端的操作如下图,选择接到命令时,要按下的按键,点“添加”按钮,就可以添加成功,选择后,殿下“删除”按钮,就可以删除: 文字输入:按下这个菜单,将可以输入文字到电脑。在手机中输入文字,然后点下“发送文字”按钮,就可以将文字发送到电脑了。
RoMote:开源Roku遥控器。 将您的Android设备变成Roku Player和Roku TV的控制中心
05-11
RoMote 开源Roku遥控器。 将您的Android设备变成Roku Player和Roku TV的控制中心。 执照 RoMote: Open source Roku remote. Copyright 2016 William Seemann Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, so
安卓蓝牙遥控器APK及源码.zip_安卓蓝牙app_安卓蓝牙遥控app_蓝牙app源码_蓝牙遥控APK
07-15
控制小车运动的安卓上位机app ,能够实现小车前进,后退,加速减速等控制
Android蓝牙遥控器(字符串形式)应用例程——bluetoothdemo/BluetoothUnv
08-04
实现功能: (1)打开应用,显示主界面,检测蓝牙功能是否打开,否则询问打开; (2)打开蓝牙功能后,点击“连接设备:”下的按钮选择已匹配的蓝牙设备进行连接; (3)若蓝牙设备未匹配,可点击旁边的 […] 按钮打开系统蓝牙设置界面,进行蓝牙匹配; (4)点击中央的上、下、左、右和中间按钮,可发送不同的蓝牙字符串消息; (5)蓝牙消息内容可通过点击 [设置] 按钮在设置界面中设置,设置的数据重启应用后依然有效; (6)其中,中间按钮具有长按按下、长按释放和点击三种不同效果; (7)本应用还附带来电监听功能,有来电时,会自动发送蓝牙消息; (8)点击 [退出] 按钮,关闭蓝牙连接,并且关闭安卓设备蓝牙功能。
基于Android平台的电器(智能家用)遥控器设计
01-13
在本项目中,我们探讨的是一个基于Android平台的智能家用电器遥控器的设计。这个应用程序的主要目的是为用户提供一种方便的方式,通过手机控制各种家用电器,尤其是电视和音箱。下面将详细阐述设计的关键点。 首先...
写文章

热门文章

  • 最简单DIY基于STM32单片机的WIFI智能小车设计方案 20587
  • 高性价比WIFI图传方案快速入门教程 16713
  • 最简单DIY基于51单片机的舵机控制器 16178
  • 最简单DIY基于STM32单片机的蓝牙智能小车设计方案 11971
  • 注释最详细、代码最简单的STM32+摄像头+显示屏的颜色跟踪电路软硬件方案 10534

分类专栏

  • ESP32 Arduino IDE开发 9篇
  • 51单片机智能小设计 10篇
  • ESP8266和ESP32 Arduino物联网智能彩灯控制 7篇
  • ESP8266 AT固件物联网控制 11篇
  • STM32库函数开发 8篇
  • 基于ESP32CAM物联网照相机系统 9篇
  • ESP8266和ESP32物联网智能小车开发 2篇
  • ESP8266收费开源项目专栏

最新评论

  • STM32F103ZET6单片机双串口互发程序设计与实现

    daodanjishui: 文章后面有下载地址。

  • STM32F103ZET6单片机双串口互发程序设计与实现

    Rocket_YQL: 串口1和串口2的代码有吗谢谢了

  • 最简单DIY基于STM32单片机的蓝牙智能小车设计方案

    好家伙VCC: 喜欢博主的文章,我当时是一个小白,一步一步踩坑过来,我后面回顾学习路线,做了PID-控制-遥控-避障-跟随循迹的项目,大家可以一起学习交流一下:这是文章:https://blog.csdn.net/qq_46187594/article/details/138110155?spm=1001.2014.3001.5502

  • 注释最详细、代码最简单的STM32+摄像头+显示屏的颜色跟踪电路软硬件方案

    daodanjishui: 下载地址更新了,欢迎大家到我哔哩哔哩工坊下载源码。表情包

  • 物联网时代下程序员如何搞副业赚钱

    普通网友: 你的博客内容深入浅出,总是让我不再感到学习的困难,每一篇博文都是我学习的宝库。【我也写了一些相关领域的文章,希望能够得到博主的指导,共同进步!】

最新文章

  • 物联网时代下程序员如何搞副业赚钱
  • 最简单DIY基于STM32的远程控制电脑系统②(无线遥杆+按键控制)
  • 最简单DIY基于STM32的远程控制电脑系统①(电容触摸+按键控制)
2024年1篇
2022年5篇
2021年47篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

daodanjishui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

玻璃钢生产厂家广东中庭商场美陈哪家好湖州商场卡通雕塑美陈玻璃钢雕塑价格行情郑州标牌玻璃钢人物雕塑设计湖南多彩玻璃钢雕塑哪家便宜北京景区玻璃钢雕塑供应商六安玻璃钢雕塑加工北京朝阳玻璃钢玻璃钢雕塑厂家河南常见商场美陈研发出口玻璃钢雕塑厂厦门玻璃钢卡通雕塑报价玻璃钢动物牛雕塑公司六盘水玻璃钢雕塑公司广安玻璃钢海豚雕塑价格运城玻璃钢室外抽象雕塑公司常州玻璃钢人物雕塑价格景洪玻璃钢雕塑呼市商场室外美陈公司深圳发光小品玻璃钢雕塑现货邯郸动漫玻璃钢雕塑户外玻璃钢雕塑价钱富锦玻璃钢雕塑潼南玻璃钢雕塑甘肃玻璃钢雕塑多少钱西红柿玻璃钢雕塑价格商场内部美陈鞍山口碑好的沈阳玻璃钢花盆瑶海玻璃钢雕塑厂家玻璃钢花盆制作视频六安玻璃钢雕塑定制香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化