How to calibrate orientation sensors in android - java

I'm trying to get data from my phone's gyros.
So far,the angles keep changing depends on the angle that i move my phone.
However, the azimuth angle for example, i want it to start counting from the position i started and not from the north direction --> i want it to start from 0.
my question is: how can i save the first data i get from the gyro so i could do "minus" from the rest of the data when i move the phone?
The code looks like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sm=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
rotationvector=sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);
sm.registerListener(this,rotationvector,SensorManager.SENSOR_DELAY_NORMAL);
rotationx=(TextView)findViewById(R.id.rotationx);
rotationy=(TextView)findViewById(R.id.rotationy);
rotationz=(TextView)findViewById(R.id.rotationz);
}
#Override
public void onSensorChanged(SensorEvent event) {
rotationx.setText(" " +event.values[0]);
rotationy.setText(" " +event.values[1]);
rotationz.setText(" " +event.values[2]);
}
The thing i want to do is like:
rotationx.setText(" " +event.values[0]-FirstAzimuthValue);
Thanks!
new code:
private boolean isFirstMeasure = true;
private float FirstAzimuthValue = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sm=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
rotationvector=sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);
sm.registerListener(this,rotationvector,SensorManager.SENSOR_DELAY_NORMAL);
rotationx=(TextView)findViewById(R.id.rotationx);
rotationy=(TextView)findViewById(R.id.rotationy);
rotationz=(TextView)findViewById(R.id.rotationz);
}
#Override
public void onSensorChanged(SensorEvent event) {
if (isFirstMeasure){
FirstAzimuthValue - event.values[0]; //error this line
isFirstMeasure = false;
}
rotationx.setText(" " +(event.values[0] - FirstAzimuthValue));
rotationy.setText(" " +event.values[1]);
rotationz.setText(" " +event.values[2]);
}

Why not just
private boolean isFirstMeasure = true;
private float firstAzimuthValue = 0;
// ...
#Override
public void onSensorChanged(SensorEvent event) {
if (isFirstMeasure) {
firstAzimuthValue = event.values[0];
isFirstMeasure = false;
}
rotationx.setText(" " + (event.values[0] - firstAzimuthValue));
rotationy.setText(" " +event.values[1]);
rotationz.setText(" " +event.values[2]);
}

Related

How to add a function when pressing the Record button in Record Activity?

Sorry for my poor English and beginner programing level.
I would like to add an Accelerometer sensor data record function when the camera is recording
The result I want is that when the user presses the camera record button, it will also record Accelerometer sensor data at the same time.
Here is my basic camera record code,
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(isCameraPresentInPhone())
{
Log.i("VIDEO_RECORD_TAG","Camera is detected");
getCameraPermission();
}
else
{
Log.i("VIDEO_RECORD_TAG","No camera is detected");
}
}
public void recordVideoButtonPressed(View view)
{
recordVideo();
}
private boolean isCameraPresentInPhone()
{
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY))
{
return true;
}
else
{
return false;
}
}
private void getCameraPermission()
{
if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)==PackageManager.PERMISSION_DENIED)
{
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_CODE);
}
}
private void recordVideo()
{
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);//初始化 Intent
startActivityForResult(intent, VIDEO_RECORD_CODE);//執行錄影 Activity
}
And here are my Accelerometer sensor data code
private SensorEventListener sensorEventListener = new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
float x = sensorEvent.values[0];
float y = sensorEvent.values[1];
float z = sensorEvent.values[2];
accelerationCurrentValue = Math.sqrt((x * x + y * y + z * z));
double changeInAccelleration = Math.abs(accelerationCurrentValue - accelerationPreviousValue);
accelerationPreviousValue = accelerationCurrentValue;

Fix the ambient Temperature in Android

I successfully made an app to measure the ambient temperature in Android studio. But the next step doesn't want to work. here's the point:
when I start the app the temperature should be shown in 1 textView (works so far). Then it should stay with this temperature but it changes. I only want to check the temperature once.
when I click on submit it shall do the same with the second textView.
I did this successfully with the time but with the temperature, it won't work. And my second question is, I did a lot of research and it looks like the temperature will always be shown in °c. Can I change that so the people who want it in °F can have it this way?
Code for the temperature without change the value and with the button for getting the temperature on textView2:
MainActivity:
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private TextView textView, textView2;
private Button button;
private SensorManager sensorManager;
private Sensor tempSensor;
private Boolean isTemperatureSensorAvailable;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
textView2 = findViewById(R.id.textView2);
button = findViewById(R.id.button);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if(sensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE) !=null) {
tempSensor = sensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
isTemperatureSensorAvailable = true;
}else{
textView.setText("Temperature Sensor is not available");
isTemperatureSensorAvailable = false;
}
}
#Override
public void onSensorChanged(SensorEvent event) {
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
protected void onResume(){
super.onResume();
if(isTemperatureSensorAvailable){
sensorManager.registerListener(this,tempSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}
#Override
protected void onPause(){
super.onPause();
if(isTemperatureSensorAvailable){
sensorManager.unregisterListener(this);
}
}
private void update_text_unit()//Run from button
{
boolean toogle = false;
float temperature = 0;
float C_temp = 0;
float F_temp =0;
//Get sensor data
Sensor temp = sensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
F_temp = (C_temp * (9/5) +32);//Convert to °F
if(toogle = true) {
textView2.setText("Temp is:" + C_temp + "°C");
toogle = false;
}
else {
textView2.setText("Temp is:" + F_temp + "°F");
toogle = true;
}
}
}
I hope someone can help me going into a better direction.
Thanks for your help.
In the first code you have a section which is on sensor changed so this will run each time causing your issue. In you oncreate all the API to get the temperature once and chuck it to the text view as a string. For °C to °F you will need to convert. I would just do this manually:
(X°C × 9/5) + 32 = result_°F
Where X is the input temperature and result is the output in °F.
Here is an example of the button temp change feature not exactly sure how you read the temp so the line of Sensor.gettemp will probably need to change. Run this from a button push, it will update your text view
private void update_text_unit()//Run from button
{
boolean toogle = false;
float temperature = 0;
float C_temp = 0;
float F_temp =0;
//Get sensor data
C_temp = Sensor.gettemp();
F_temp = (C_temp * (9/5) +32);//Convert to °F
if(toogle = true) {
yourtextview.setText("Temp is:" + C_temp + "°C");
toogle = false;
}
else {
yourtextview.setText("Temp is:" + F_temp + "°F");
toogle = true;
}
}

Display Temperature value with air pressure and altitude

Iam displaying my temperature sensor values in text view and also displaying air pressure from air pressure sensor with altitude in another two text view
the problem is that the first text view display air pressure instead of displaying temperature and the other text views display correct values of air pressure and altitude and i named the text view id correct but when i run the app it dosnt display temperature in first text view in the same activity and if i separate them in two activities it work good but i want to dislapy them in same activity and this is my code
public class TemperatureActivity extends Activity
implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mSensor;
private boolean isSensorPresent;
private TextView mTemperatureValue;
private TextView mPressureValue;
private TextView mAltitudeValue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager =
(SensorManager)this.getSystemService
(Context.SENSOR_SERVICE);
mTemperatureValue =
(TextView)findViewById(R.id.temperaturetext);
if(mSensorManager.getDefaultSensor
(Sensor.TYPE_AMBIENT_TEMPERATURE) != null) {
mSensor = mSensorManager.getDefaultSensor
(Sensor.TYPE_AMBIENT_TEMPERATURE);
isSensorPresent = true;
} else {
mTemperatureValue.setText("Ambient Temperature Sensor is not available!");
isSensorPresent = false;
}
mPressureValue =
(TextView)findViewById(R.id.pressuretext);
mAltitudeValue =
(TextView)findViewById(R.id.altitudetext);
mSensorManager = (SensorManager)
this.getSystemService(Context.SENSOR_SERVICE);
if(mSensorManager.getDefaultSensor
(Sensor.TYPE_PRESSURE) != null) {
mSensor = mSensorManager.getDefaultSensor
(Sensor.TYPE_PRESSURE);
isSensorPresent = true;
} else {
isSensorPresent = false;
mPressureValue.setText("Pressure Sensor is not available!");
mAltitudeValue.setText("Cannot calculate altitude, as pressure
Sensor is not available!");
}
}
#Override
protected void onResume() {
super.onResume();
if(isSensorPresent) {
mSensorManager.registerListener(this, mSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
#Override
protected void onPause() {
super.onPause();
if(isSensorPresent) {
mSensorManager.unregisterListener(this);
}
}
#Override
public void onSensorChanged(SensorEvent event) {
mTemperatureValue.setText("Temperature in degree Celsius is " +
event.values[0]);
float pressure = event.values[0];
mPressureValue.setText("Pressure in mbar is " +
pressure);
float altitude = SensorManager.getAltitude
(SensorManager.PRESSURE_STANDARD_ATMOSPHERE,
pressure);
mAltitudeValue.setText("Current altitude is " +
altitude);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
#Override
public void onSensorChanged(SensorEvent event) {
mTemperatureValue.setText("Temperature in degree Celsius is " +
event.values[0]);
float pressure = event.values[0];
mPressureValue.setText("Pressure in mbar is " +
pressure);
float altitude = SensorManager.getAltitude
(SensorManager.PRESSURE_STANDARD_ATMOSPHERE,
pressure);
mAltitudeValue.setText("Current altitude is " +
altitude);
}
Completely broken. Every sensor event, you're writing the same value to multiple fields. You get one event per sensor. You should update the temperature only when you get a temperature event, the pressure only when you get a pressure event, etc.

how to create an save sensor data in a csv file in internal memory

I'm trying to get the accelerometer data in a file on internal storage , i tried many ways they but i get errors like java.io.FileNotFoundException: Value.csv: open failed: EROFS (Read-only file system) or ESIDIR.
#RequiresApi(api = Build.VERSION_CODES.N)
public class MainActivity extends Activity implements SensorEventListener,View.OnClickListener {
private TextView xText, yText, zText;
private Sensor sensor;
private SensorManager sManager;
private Button startB, stopB;
private boolean mInitialized;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Create sensor manager
sManager = (SensorManager) getSystemService(SENSOR_SERVICE);
// Accelerometer sensor
sensor = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//Register sensor Listener
sManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
// assign Textview
xText = (TextView) findViewById(R.id.xText);
Button startButton = (Button) findViewById(R.id.startB);
Button stopButton = (Button) findViewById(R.id.stopB);
startButton.setOnClickListener(this);
stopButton.setOnClickListener(this);
mInitialized = false;
}
public void onResume() {
super.onResume();
sManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
sManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int acc) {
}
public void onSensorChanged(SensorEvent event) {
xText.setText(" X :" + Float.toString(event.values[0]) + "\n" +
" Y :" + Float.toString(event.values[1]) + "\n" +
" Z :" + Float.toString(event.values[2]));
try {
writeToCsv(Float.toString(event.values[0]), Float.toString(event.values[1]), Float.toString(event.values[2]));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.startB:
sManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
break;
case R.id.stopB:
sManager.unregisterListener(this);
break;
}
}
public void writeToCsv(String x, String y, String z) throws IOException {
Calendar c = Calendar.getInstance();
File path = Environment.getDataDirectory();
boolean success = true;
if (!path.exists()) {
success = path.mkdir();
}
if (success) {
String csv = "Value.csv";
FileWriter file_writer = new FileWriter(csv, true);
String s = c.get(Calendar.HOUR) + "," + c.get(Calendar.MINUTE) + "," + c.get(Calendar.SECOND) + "," + c.get(Calendar.MILLISECOND) + "," + x + "," + y + "," + z + "\n";
file_writer.append(s);
file_writer.close();
}
}
}
File path = Environment.getDataDirectory();
Will deliver path /data. Which is not readable and not writable as you have seen. Change to for instance
File path = getFilesDir();

Java/Android : passing accelerometer value from onSensorChanged method to onCreateSetContentView()

I'm new on Java and Android programming language and this is the first platform that I studied.
I want to ask, how can I access the event.values[1] in this method?
public void onSensorChanged(SensorEvent event) {synchronized (this){
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
return;
mAccVals.x = (float) (event.values[1] * FILTERING_FACTOR + mAccVals.x * (1.0 - FILTERING_FACTOR));
//mAccVals.y = (float) ((-event.values[1] * FILTERING_FACTOR + mAccVals.y * (1.0 - FILTERING_FACTOR)));
mAccVals.z = (float) (event.values[2] * FILTERING_FACTOR + mAccVals.z * (1.0 - FILTERING_FACTOR));
scene.camera().position.x = mAccVals.x * .2f;
scene.camera().position.z = mAccVals.z * .8f;
scene.camera().target.x = -scene.camera().position.x;
scene.camera().target.z = -scene.camera().position.z;
}
I want to get event.values[1] and then display it on a textview
protected void onCreateSetContentView()
{
setContentView(R.layout.custom_layout_example);
LinearLayout ll = (LinearLayout) this.findViewById(R.id.scene1Holder);
ll.addView(_glSurfaceView);
TextView myTextView = (TextView) findViewById(R.id.splashTitle);
myTextView.setText("Test " + event.values[1] );
return;
}
There's any suggestion how can I solve this problem?
Thanks in advance
Create a field in your Activity and assign it to your R.id.splashTitle:
TextView mTextView;
...
protected void onCreateSetContentView() {
mTextView = (TextView) findViewById(R.id.splashTitle);
...
}
Then set it's text in onSensorChanged() as follows:
public void onSensorChanged(SensorEvent event) {
mTextView.setText("Test " + event.values[1]);
...
}
Or you may store most recent sensor's values in a field:
// Class field
float[] mSensorValues;
// In onSensorChanged()
mSensorValues = event.values;
// In onCreateSetContentView()
myTextView.setText("Test " + mSensorValues[1]);
To preserve right sequense of onCreate and onSensorChanged you may use an approach described in documentation:
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}

Categories