2017-10-17 27 views
0

Dans mon projet de robot mobile, qui ont 2 servomoteurs pour faire pivoter la caméra dans deux plans, je veux les contrôler dans mon application Android par rotation du smartphone (grâce à des lectures lacet/hauteur/rouler depuis l'accéléromètre du smartphone).Tâche périodique (message à envoyer via Bluetooth)

Pour cela, je dois envoyer des données sur ces trois angles via Bluetooth à Arduino. Ainsi, par exemple paquet de données d'échantillon ressemble à:

"Y: 100, P: 20, R 45" où [Y-lacet, tangage-P, R-roll].

code

qui est chargé d'envoyer cette commande/message à Arduino ->bl.sendData("A:"+String.format("%.0f",azimut) + ",P:" + String.format("%.0f",pitch) + ",R:" + String.format("%.0f",roll) + ".");

Je veux que ce message soit envoyé cyclique dans toutes les 200 ms (quand je suis dans cette activité) -> (maintenant est envoyé à chaque fois que le bouton "ENVOYER": D est cliqué).

Je dois aussi mentionner que, sauf ce message à Arduino application envoyer un autre message quand je touche joystick virtuel dans cette même activité pour contrôler la direction de mon robot mobile et je veux qu'il y ait pas de conflit entre l'envoi de deux messages)

Alors, comment puis-je l'obtenir? Un exemple de code?

C'est le code d'Android Studio (à propos de cette activité):

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; 
      } 
     } 

    } 
} 
+0

https://guides.codepath.com/android/Repeating-Periodic-Tasks – jdv

+0

@jdv Je ne sais pas quand je devrais insérer cette partie du code dans MyActivity/code -> '// Nous devons l'utiliser Gestionnaire paquet importer android.os.Handler; // Créer l'objet Handler (sur le thread principal par défaut) Handler handler = new Handler(); // Définir le bloc de code à exécuter privé Runnable runnableCode = new Runnable() { '' cd –

+0

@jdv @Override public void run() {// faire ici quelque chose sur le thread principal Log.d ("Handlers", "Appelé sur le thread principal"); // Répéter le même bloc de code exécutable encore 2 secondes // 'this' fait référence à l'objet Runnable handler.postDelayed (this, 2000); } }; // Lancer la tâche initiale exécutable en publiant via le gestionnaire handler.post (runnableCode); ' –

Répondre

0

@jdv Nous vous remercions de l'aide maintenant, je sais comment le faire ->

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; 
           } 
       } 
} 

Je demande donc la fonction startRepeatingTask(); lorsque Bluetooth est connecté, car autrement, des erreurs apparaissent.

Mais maintenant j'ai une autre question, je ne veux pas créer un nouveau sujet, alors pouvez-vous me dire quelle fonction est appel lorsque je pousse sur le bouton d'accueil de mon smartphone et le bouton de retour?

onResume dans les deux cas ou dans le cas HOME une autre fonction?