0

在我的移动机器人项目中,它有 2 个伺服电机来在两个平面上旋转相机,我想通过旋转智能手机(通过智能手机加速度计的偏航/俯仰/滚动读数)在我的 android 应用程序中控制它们。

为此,我必须通过蓝牙将这三个角度的数据发送到 Arduino。因此,例如示例数据包如下所示:

"Y:100,P:20,R:45" 其中 [Y-yaw, P-pitch,R-roll]。

负责将此命令/消息发送到 Arduino 的代码 ->bl.sendData("A:"+String.format("%.0f",azimut) + ",P:" + String.format("%.0f",pitch) + ",R:" + String.format("%.0f",roll) + ".");

我希望此消息每 200 毫秒循环发送一次(当我在此活动中时)->(现在每次单击“发送”按钮时发送:D)。

我还必须提到,当我在同一活动中触摸虚拟操纵杆以控制我的移动机器人的方向时,除了向 Arduino 应用程序发送另一条消息外,我希望发送两条消息之间没有冲突)

那么我怎样才能得到它呢?一些示例代码?

这是来自 Android Studio 的代码(关于这个活动):

  package com.samplecompass;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements SensorEventListener {
    private cBluetooth bl = null;
    private String address = "00:11:35:94:61:19";
    private StringBuilder sb = new StringBuilder();
    private Button send;


    Float azimutF;
    Float pitchF;
    Float pitchMax=0.0f;
    Float azimut;  // View to draw a compass
    Float pitch;
    Float roll;
    int zgoda=0;
    int zgodaa=1;
    int znak=1;
    private TextView mPitch;





    private SensorManager mSensorManager;
    Sensor accelerometer;
    Sensor magnetometer;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bl = new cBluetooth(this, mHandler);
        bl.checkBTState();
        mPitch = (TextView) findViewById(R.id.Pitch);
        send = (Button) findViewById(R.id.send);

        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);


        send.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                zgodaa=0;
                //bl.sendData("Hello");
            }
        });
    }

    private final Handler mHandler =  new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case cBluetooth.BL_NOT_AVAILABLE:
                    Log.d(cBluetooth.TAG, "Bluetooth is not available. Exit");
                    Toast.makeText(getBaseContext(), "Bluetooth is not available", Toast.LENGTH_SHORT).show();
                    finish();
                    break;
                case cBluetooth.BL_INCORRECT_ADDRESS:
                    Log.d(cBluetooth.TAG, "Incorrect MAC address");
                    Toast.makeText(getBaseContext(), "Incorrect Bluetooth address", Toast.LENGTH_SHORT).show();
                    break;
                case cBluetooth.BL_REQUEST_ENABLE:
                    Log.d(cBluetooth.TAG, "Request Bluetooth Enable");
                    BluetoothAdapter.getDefaultAdapter();
                    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(enableBtIntent, 1);
                    break;
                case cBluetooth.BL_SOCKET_FAILED:
                    Toast.makeText(getBaseContext(), "Socket failed", Toast.LENGTH_SHORT).show();
                    finish();
                    break;
                case cBluetooth.RECIEVE_MESSAGE:                                                    // if message is recieved
                    byte[] readBuf = (byte[]) msg.obj;
                    String strIncom = new String(readBuf, 0, msg.arg1);                 // create string from bytes array
                    sb.append(strIncom);                                                // append string
                    int endOfLineIndex = sb.indexOf("\r\n");                            // determine the end-of-line
                    if (endOfLineIndex > 0) {                                           // if end-of-line,
                        String sbprint = sb.substring(0, endOfLineIndex);               // extract string
                        sb.delete(0, sb.length());                                      // and clear
                        //txtArduino.setText("Data from Arduino: " + sbprint);          // update TextView

                    }
                    break;
            }
        };
    };

    protected void onResume() {
        super.onResume();
        bl.BT_Connect(address);
        //bl.sendData("Hello World");
        mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
        mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI);
    }

    protected void onPause() {
        super.onPause();
        bl.BT_onPause();
        mSensorManager.unregisterListener(this);
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {  }

    float[] mGravity;
    float[] mGeomagnetic;

    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
            mGravity = event.values;
        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
            mGeomagnetic = event.values;

        if (mGravity != null && mGeomagnetic != null) {
            float R[] = new float[9];
            float I[] = new float[9];
            boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
            if (success) {
                float orientation[] = new float[3];
                SensorManager.getOrientation(R, orientation);
                if(zgoda==0) {
                    azimutF = -orientation[0] * 360 / (2 * 3.14159f) - 90;
                    pitchF  = orientation[1]*360/(2*3.14159f);
                }
                zgoda=1;
                azimut =  -orientation[0]*360/(2*3.14159f) - azimutF; // orientation contains: azimut, pitch and roll
                pitch  =  -1*(orientation[1]*360/(2*3.14159f));
                if(pitchMax<pitch){ pitchMax=pitch;}

                /**if (Math.round(pitch) == 0) {
                    if(znak==1) znak=-1;
                    else if(znak==-1) znak=1;
                }**/
                roll   =  -orientation[2]*360/(2*3.14159f);
                mPitch.setText(String.valueOf("Azimut: " + String.format("%.0f",azimut)) + String.valueOf("Znak:" + pitchMax) + String.valueOf("Pitch:" + String.format("%.0f",pitch)) + String.valueOf("Roll:" + String.format("%.0f",roll)));
                if(zgodaa== 0) {bl.sendData("A:"+String.format("%.0f",azimut) + ",P:" + String.format("%.0f",pitch) + ",R:" + String.format("%.0f",roll) + ".");}
                zgodaa=1;
            }
        }

    }
}
4

1 回答 1

0

@jdv 谢谢你的帮助,现在我知道怎么做了->

    public class MainActivity extends Activity implements SensorEventListener {

    private Handler handler
    ...

    protected void onCreate(Bundle savedInstanceState) {  
    handler = new Handler();     
    ...
    }

    Runnable mStatusChecker = new Runnable() {
        @Override
        public void run() {
            try {
                bl.sendData("A:"+i+String.format("%.0f",azimut) + ",P:" + String.format("%.0f",pitch) + ",R:" + String.format("%.0f",roll) + ".");; //this function can change value of mInterval.
            } finally {
                // 100% guarantee that this always happens, even if
                // your update method throws an exception
                handler.postDelayed(mStatusChecker, 1000);
            }


        }
    };

    void startRepeatingTask() {
        mStatusChecker.run();
    }

    void stopRepeatingTask() {
        mHandler.removeCallbacks(mStatusChecker);
    }

     private final Handler mHandler =  new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case cBluetooth.BL_OK:
                    startRepeatingTask();
                    Toast.makeText(getBaseContext(), "BL_OK", 
                    Toast.LENGTH_SHORT).show();
                    break;
                              }
              }
}

所以我startRepeatingTask();在连接蓝牙时调用函数,否则会弹出错误。

但是现在我有另一个问题,我不想创建新主题,那么当我按下智能手机的主页按钮和返回按钮时,你能告诉我哪个函数被调用吗?

onResume 在这两种情况下还是在 HOME 另一个功能的情况下?

于 2017-10-17T16:25:33.243 回答