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 à:
code"Y: 100, P: 20, R 45" où [Y-lacet, tangage-P, R-roll].
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;
}
}
}
}
https://guides.codepath.com/android/Repeating-Periodic-Tasks – jdv
@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 –
@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); ' –