Периодическая задача (сообщение для отправки через Bluetooth)

В моем проекте мобильного робота, который имеет 2 серводвигателя для вращения камеры в двух плоскостях, я хочу управлять ими в своем приложении для Android, вращая смартфон (через показания рыскания / шага / крена от акселерометра смартфона).

Для этого я должен отправить данные об этих трех углах через Bluetooth в 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;
            }
        }

    }
}

1 ответ

@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(); когда Bluetooth подключен, иначе появятся ошибки.

Но теперь у меня есть еще один вопрос, я не хочу создавать новую тему, так что вы можете сказать мне, какая функция вызывается, когда я нажимаю кнопку "Домой" смартфона и кнопку "Назад"?

onResume в обоих случаях или в случае HOME другая функция?

Другие вопросы по тегам