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
原创粉丝点击