android之蓝牙控制小四轴飞行器
来源:互联网 发布:sqoop导入数据到oracle 编辑:程序博客网 时间:2024/05/18 18:42
本app基于匿名开源小四轴app( http://www.anotc.com/Product/Overview/8 )改编。匿名小四轴接上串口蓝牙模块后,可直接使用本app控制。其它飞控修改通信协议后方可使用。本app改编后可用于控制蓝牙智能小车,感兴趣的小伙伴可以试试看。使用飞行器测试时,请千万注意安全。
蓝牙连接界面,需打开手机蓝牙才可进行下一步操作。上面文本框显示当前蓝牙连接状况;中间大图是我们的logo;左下蓝牙图标,单击可选择要连接的串口蓝牙设备;右下六边形图标,单击可跳转至下图飞行器控制界面。
中上三个全表盘飞机图标,动画实时显示飞行器当前横滚角、航向角和俯仰角;中间半表盘指针图标,显示飞行器当前油门值;中下图标,单击可解锁飞控,再次单击可锁定飞控,如此反复;两侧文本框,实时显示飞控的加速度计和陀螺仪数值;左侧箭头图标,上下为油门加、减,左右控制横滚角;右侧箭头图标,上下控制俯仰角,左右控制航向角。
控制部分源码:
package com.example.seuxiaosi; import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.content.pm.ActivityInfo;import android.graphics.Bitmap;import android.graphics.Matrix;import android.graphics.Paint;importandroid.graphics.drawable.BitmapDrawable;import android.os.Bundle;import android.os.Handler;import android.util.DisplayMetrics;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;import android.view.View.OnTouchListener;import android.view.WindowManager;import android.widget.Button;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.TextView;import android.annotation.SuppressLint; public class MyControl extends Activity { //用于图像旋转的变量 privateImageView mImageView_yaw; privateImageView mImageView_rol; privateImageView mImageView_pit; privateImageView mImageView_thr; privateMatrix mMatrix = new Matrix(); privatefloat mAngle_thr = 0; BitmapmBitmap; Paintpaint = new Paint(); privateint thrTF = 0;// //自定义按键监听事件类 mImageListentermImageButtonListener = new mImageListenter(); //设置油门, yaw,pit,rol的初始值 privateint VAL_THR = 1000; privateint VAL_YAW = 1500, VAL_ROL = 1500, VAL_PIT = 1500; //数据显示 TextView acc_x_show , acc_y_show , acc_z_show , gyr_x_show , gyr_y_show , gyr_z_show ; //图片按钮变量 privateImageButton image; //飞控解锁 LOCK=0——锁定,LOCK=1——解锁 privateint LOCK = 0; //时间管理器 Timersend_timer = new Timer(); privatefinal Handler myHandler = new Handler(); //handler可以分发Message对象和Runnable对象到主线程中 //handler中的执行时间过长会出错!!!!!!!!!! privatefinal Runnable myRunable = new Runnable() { @Override publicvoid run() { //TODO Auto-generated method stub //0.1秒后调用此Runnable对象,用于控制数据的更新 myHandler.postDelayed(this,100); //控制界面数据的更新 acc_x_show.setText("X:" + MainActivity.VAL_ACC_X); acc_y_show.setText("Y:" + MainActivity.VAL_ACC_Y); acc_z_show.setText("Z:" + MainActivity.VAL_ACC_Z); gyr_x_show.setText("X:" + MainActivity.VAL_GYR_X); gyr_y_show.setText("Y:" + MainActivity.VAL_GYR_Y); gyr_z_show.setText("Z:" + MainActivity.VAL_GYR_Z); mRotate_yaw();//旋转图像 mRotate_pit(); mRotate_rol(); if(LOCK== 1){ if(thrTF== 1) VAL_THR+= 2; elseif(thrTF == 2) VAL_THR-= 2; mRotate_thr_up(); } } }; @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //横屏模式 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //保持屏幕长亮 getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.activity_my_control); ImageButtonmImageButton; acc_x_show = (TextView)findViewById(R.id.acc_x); acc_y_show = (TextView)findViewById(R.id.acc_y); acc_z_show = (TextView)findViewById(R.id.acc_z); gyr_x_show = (TextView)findViewById(R.id.gyr_x); gyr_y_show = (TextView)findViewById(R.id.gyr_y); gyr_z_show = (TextView)findViewById(R.id.gyr_z); //用于旋转图像 mImageView_yaw = (ImageView)findViewById(R.id.yaw_image); mImageView_rol = (ImageView)findViewById(R.id.rol_image); mImageView_pit = (ImageView)findViewById(R.id.pit_image); mImageView_thr = (ImageView)findViewById(R.id.thr_image); DisplayMetrics dm =new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); //按钮监听器 mImageButton= (ImageButton) findViewById(R.id.thr_up); mImageButton.setOnTouchListener(mImageButtonListener); mImageButton= (ImageButton) findViewById(R.id.thr_down); mImageButton.setOnTouchListener(mImageButtonListener); mImageButton= (ImageButton) findViewById(R.id.rol_you); mImageButton.setOnTouchListener(mImageButtonListener); mImageButton= (ImageButton) findViewById(R.id.rol_zuo); mImageButton.setOnTouchListener(mImageButtonListener); mImageButton= (ImageButton) findViewById(R.id.pit_qian); mImageButton.setOnTouchListener(mImageButtonListener); mImageButton= (ImageButton) findViewById(R.id.pit_hou); mImageButton.setOnTouchListener(mImageButtonListener); mImageButton= (ImageButton) findViewById(R.id.yaw_zuo); mImageButton.setOnTouchListener(mImageButtonListener); mImageButton= (ImageButton) findViewById(R.id.yaw_you); mImageButton.setOnTouchListener(mImageButtonListener); mImageButton= (ImageButton) findViewById(R.id.suo); mImageButton.setOnClickListener(newView.OnClickListener(){ @Override publicvoid onClick(View v) { //TODO Auto-generated method stub image= (ImageButton) findViewById(R.id.suo); if(LOCK== 0){ LOCK= 1;//解锁状态置1 //发送解锁命令 MainActivity.Send_Command((byte)0xa1); image.setImageResource(R.drawable.jie); } else{ //发送锁定命令 MainActivity.Send_Command((byte)0xa0); image.setImageResource(R.drawable.suo); VAL_THR= 1000;//油门置0 mRotate_thr_up(); LOCK= 0;//解锁状态置0 } } }); //延迟1秒后执行任务send_task,然后经过0.05秒再次执行send_task,用于循环任务 send_timer.schedule(send_task,1000,50); //每0.1秒执行一次runnable myHandler.postDelayed(myRunable,100); } classmImageListenter implements OnTouchListener{ @Override publicboolean onTouch(View v, MotionEvent event) { //TODO Auto-generated method stub if(LOCK== 1){ //yaw按钮 if(v.getId()== R.id.yaw_zuo){ if(event.getAction()== MotionEvent.ACTION_DOWN) VAL_YAW= 1200; if(event.getAction()== MotionEvent.ACTION_CANCEL) VAL_YAW= 1500; if(event.getAction()== MotionEvent.ACTION_UP) VAL_YAW= 1500; } if(v.getId()== R.id.yaw_you){ if(event.getAction()== MotionEvent.ACTION_DOWN) VAL_YAW= 1800; if(event.getAction()== MotionEvent.ACTION_CANCEL) VAL_YAW= 1500; if(event.getAction()== MotionEvent.ACTION_UP) VAL_YAW= 1500; } //pit按钮 if(v.getId()== R.id.pit_qian){ if(event.getAction()== MotionEvent.ACTION_DOWN) VAL_PIT= 1650; if(event.getAction()== MotionEvent.ACTION_CANCEL) VAL_PIT= 1500; if(event.getAction() ==MotionEvent.ACTION_UP) VAL_PIT= 1500; } if(v.getId()== R.id.pit_hou){ if(event.getAction()== MotionEvent.ACTION_DOWN) VAL_PIT= 1350; if(event.getAction()== MotionEvent.ACTION_CANCEL) VAL_PIT= 1500; if(event.getAction()== MotionEvent.ACTION_UP) VAL_PIT= 1500; } //rol按钮 if(v.getId()== R.id.rol_zuo){ if(event.getAction()== MotionEvent.ACTION_DOWN) VAL_ROL= 1200; if(event.getAction()== MotionEvent.ACTION_CANCEL) VAL_ROL= 1500; if(event.getAction()== MotionEvent.ACTION_UP) VAL_ROL= 1500; } if(v.getId()== R.id.rol_you){ if(event.getAction()== MotionEvent.ACTION_DOWN) VAL_ROL= 1800; if(event.getAction()== MotionEvent.ACTION_CANCEL) VAL_ROL= 1500; if(event.getAction()== MotionEvent.ACTION_UP) VAL_ROL= 1500; } //油门 if(v.getId()== R.id.thr_up){ if(VAL_THR >= 2000) {VAL_THR= 2000;}//执行空语句 else{ if(event.getAction()== MotionEvent.ACTION_DOWN) thrTF= 1; //{VAL_THR+= 15; mRotate_thr_up();} if(event.getAction()== MotionEvent.ACTION_CANCEL) thrTF= 0; if(event.getAction()== MotionEvent.ACTION_UP) thrTF= 0; } } if(v.getId()== R.id.thr_down){ if(VAL_THR<= 1000) {VAL_THR= 1000;} else{ if(event.getAction()== MotionEvent.ACTION_DOWN) thrTF= 2; if(event.getAction()== MotionEvent.ACTION_CANCEL) thrTF= 0; if(event.getAction() ==MotionEvent.ACTION_UP) thrTF= 0; } } } returnfalse; } } TimerTasksend_task = new TimerTask(){ //Timer是一种线程设施,用于安排以后在后台线程中执行的任务。 //可安排任务执行一次,或者定期重复执行,可以看成一个定时器,可以调度TimerTask。 //TimerTask是一个抽象类,实现了Runnable接口,所以具备了多线程的能力。 byte[] bytes = new byte[25]; public void run () { byte sum=0; bytes[0] = (byte) 0xaa; bytes[1] = (byte) 0xaf; bytes[2] = (byte) 0x03; bytes[3] = (byte) 20; bytes[4] = (byte)(VAL_THR/0xff);//取商 油门 bytes[5] = (byte)(VAL_THR%0xff);//取余数 bytes[6] = (byte)(VAL_YAW/0xff);//航向 bytes[7] = (byte) (VAL_YAW%0xff); bytes[8] = (byte)(VAL_ROL/0xff);//横滚 bytes[9] = (byte) (VAL_ROL%0xff); bytes[10] = (byte)(VAL_PIT/0xff);//俯仰 bytes[11] = (byte) (VAL_PIT%0xff); bytes[12] = 1; bytes[13] = 2; bytes[14] = 3; bytes[15] = 4; bytes[16] = 0; bytes[17] = 0; bytes[18] = 0; bytes[19] = 0; bytes[20] = 0; bytes[21] = 0; bytes[22] = 0; bytes[23] = 0; for(int i=0;i<24;i++) sum +=bytes[i]; bytes[24] = sum; MainActivity.SendData_Byte(bytes);//发送数据 } }; protected void onDestroy(){ if(send_timer != null) //注销定时器 { send_timer.cancel(); send_timer= null; } super.onDestroy(); } //自定义图像旋转函数 private void mRotate_yaw(){ mBitmap = ((BitmapDrawable)(getResources().getDrawable(R.drawable.yaw2))).getBitmap(); mMatrix.setRotate(MainActivity.VAL_ANG_Z,mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);//旋转角度设置 paint= new Paint(); //设置抗锯齿,防止过多的失真 paint.setAntiAlias(true); mBitmap= Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(),mMatrix, true); mImageView_yaw.setImageBitmap(mBitmap); } private void mRotate_rol(){ mBitmap =((BitmapDrawable)(getResources().getDrawable(R.drawable.rol2))).getBitmap(); mMatrix.setRotate(MainActivity.VAL_ANG_X, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);//旋转角度设置 paint= new Paint(); //设置抗锯齿,防止过多的失真 paint.setAntiAlias(true); mBitmap= Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(),mMatrix, true); mImageView_rol.setImageBitmap(mBitmap); } private void mRotate_pit(){ mBitmap= ((BitmapDrawable)(getResources().getDrawable(R.drawable.pit2))).getBitmap(); mMatrix.setRotate(-MainActivity.VAL_ANG_Y,mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);//旋转角度设置 paint= new Paint(); //设置抗锯齿,防止过多的失真 paint.setAntiAlias(true); mBitmap= Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(),mMatrix, true); mImageView_pit.setImageBitmap(mBitmap); } private void mRotate_thr_up(){ if(LOCK== 1){ mBitmap= ((BitmapDrawable)(getResources().getDrawable(R.drawable.zhen))).getBitmap(); mAngle_thr = (float)(VAL_THR-1000)*180/1000; mMatrix.setRotate(mAngle_thr,mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);//旋转角度设置 paint= new Paint(); //设置抗锯齿,防止过多的失真 paint.setAntiAlias(true); mBitmap= Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(),mMatrix, true); mImageView_thr.setImageBitmap(mBitmap); } } }
eclipse工程源码下载地址:
http://download.csdn.net/detail/qq_21478795/9538237
1 0
- android之蓝牙控制小四轴飞行器
- 飞行器 控制原理
- 意念控制飞行器
- 飞行器制导控制课程设计
- 智能家电之蓝牙控制
- Android控制蓝牙票据打印
- Android 蓝牙编程控制机器人
- 四轴飞行器姿态控制
- android之蓝牙
- Android之蓝牙操作
- android之蓝牙
- Android开发之蓝牙
- Android开发之蓝牙
- android 蓝牙之:ibeacon
- android 之连接蓝牙
- android学习之蓝牙
- Android蓝牙之聊天
- android蓝牙开发之经典蓝牙
- 汇编语言(五) 汇编代码在内存中的结构( 8086 + masm 编译器)
- 【数据表间关联关系】 一对多、多对一、一对一、多对多
- GUI(图形用户界面)
- JAVA内存结构之运行时栈帧结构
- Arrays.asList不能remove、add等,抛UnsupportedOperationException
- android之蓝牙控制小四轴飞行器
- Solr4.4入门,介绍Solr的安装、IK分词器的配置及高亮查询结果(一)
- leetcode #79 in cpp
- jsp页面中的post提交方式
- Solr中配置文件schema.xml之copyField 与multiValued用途
- PlantUML 使用
- 压缩图片尺寸
- 大型网站架构演化发展历程
- Android 上自定义的复式折线图(二)