Android Tutorial Orientation and accelerometer

The attached program displays the values of the different sensors:

sensors.png


It creates a PhoneSensors object for each type of sensor.
As you can see in the attached code, two Maps are used to hold the phone sensors and the other required data. This way there is no need to write any duplicate code.

A better method for finding the orientation values: https://www.b4x.com/android/forum/threads/orientation-and-accelerometer.6647/page-6#post-476271
 

Attachments

  • SensorsExample.zip
    7.5 KB · Views: 1,591
Last edited:

Cableguy

Expert
Licensed User
Longtime User
Hi Erel, I have an issue....
I force my main Activitie to be portrait, and all the other 4 activities I have in the current project, but only the main one stays in portrait mode when I rotate my device....
 

Jim Brown

Active Member
Licensed User
Longtime User
Hello Erel

The orientation sensor seems to have an impact on the overall timing of an app. It seems to steal quite a bit of operation time
Could you look at adding options to set the polling rate?

Have a look at this example to see what I mean
Here, a ball is set to roll when the phone is tilted (NOTE: operate in landcape mode). On my Samsung Galaxy S there are notable delays as the ball travels
I have set the timer to 10ms interval in order to allow some leeway for the orientation sensor but there is still a significant impact when polling the sensor

B4X:
'AccelBall
Sub Process_Globals
    Dim Orientation As PhoneOrientation
   Dim time As Timer
End Sub

Sub Globals
   Dim can As Canvas
   Dim ballx,bally,ballsize As Float
   Dim targety As Float
End Sub

Sub Activity_Create(FirstTime As Boolean)
   ballx=80 : bally=Activity.Height-Activity.Height/2
   ballsize=42 : targety=bally
   can.Initialize(Activity)
   time.Initialize("Timer1",10)
End Sub

Sub Activity_Resume
    Orientation.StartListening("Orientation") 
   time.Enabled=True
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    Orientation.StopListening
   time.Enabled=False
End Sub

Sub Timer1_Tick
   can.DrawColor(Colors.Black)
   bally=bally+(targety-bally)/2.0
   can.DrawLine(ballx,0,ballx,Activity.Height,Colors.Red,1.0)
   can.DrawCircle(ballx+ballsize,bally,ballsize,Colors.White,True,0.0)
   Activity.Invalidate
End Sub

Sub Orientation_OrientationChanged (Azimuth As Float, Pitch As Float, Roll As Float)
   targety=targety-Pitch
   If targety<ballsize Then targety=ballsize
   If targety>(Activity.Height-ballsize) Then targety=(Activity.Height-ballsize)
End Sub
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You should not redraw the whole activity each time.
The Accelerometer is more useful for this task.

This code works smoothly: Before running it go to Project - Orientation Supported and choose Landscape only.
B4X:
'AccelBall
Sub Process_Globals
    Dim Accelerometer As PhoneAccelerometer
    Dim timer1 As Timer
    Dim speed As Float
    Dim position As Int
    Dim positionY As Int
End Sub

Sub Globals
    Dim can As Canvas
    Dim rect1 As Rect
End Sub

Sub Activity_Create(FirstTime As Boolean)
    If firstTime Then
        timer1.Initialize("Timer1",30)
    End If
    positionY = 100%y - 100dip
    can.Initialize(Activity)
    can.DrawLine(0,positionY + 21dip, 100%x, positionY + 21dip,Colors.Red,1.0)
    position = 50%x
    rect1.Initialize(0, positionY - 20dip, 40dip, positionY + 20dip)
End Sub

Sub Activity_Resume
    Accelerometer.StartListening("Accelerometer")
    timer1.Enabled = True
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    Accelerometer.StopListening
    timer1.Enabled = False
End Sub

Sub Timer1_Tick
    can.DrawCircle(position, positionY, 20dip, Colors.Black, True, 0)
    activity.Invalidate2(rect1)
    position = position + speed
    If position > 100%x + 20dip Then position = -18dip
    If position < -20dip Then position = 100%x + 18dip
    rect1.Left = position - 20dip
    rect1.Right = position + 40dip
    can.DrawCircle(position, positionY, 20dip, Colors.White, True, 0)
    activity.Invalidate2(rect1)
End Sub

Sub Accelerometer_AccelerometerChanged (X As Float, Y As Float, Z As Float)
    speed = speed + Y * 0.5
End Sub
 

Jim Brown

Active Member
Licensed User
Longtime User
Thank you as usual Erel

I take it 'dirty rects' is the way forward for updating the screen whilst maintaining relatively smooth performance?
Is this because the draw routines need to be system-friendly (not stealing too much processing power)?


In general, what would be the best solution if you needed to redraw the whole screen, say in a scrolling game environment?
I am guessing this would have to be done with a 2D OpenGL library ?
 

mshihrer

Member
Licensed User
Longtime User
I'm having trouble running this example. I get this error:

Compiling code. Error
Error parsing program.
Error description: Unknown type: phonesensors
Are you missing a library reference?
Occurred on line: 16
Dim ps As PhoneSensors 'This object is only used to access the type constants.

In the IDE, I have Core, GPS, and Phone(vers 1.31) selected.
Am I missing a reference?

Be nice if there was a "project" option in the IDE to have the references already setup.
 

alfcen

Well-Known Member
Licensed User
Longtime User
The latest Phone library version is 1.32.
Please make sure to copy the new library files into the Libraries folder underneath C:\Program Files\Anywhere Software\Basic4android
 

peacemaker

Expert
Licensed User
Longtime User
I added to this Erel's sample showing the average of accelerometer's X, Y, Z; tested vibrations at several conditions - interesting feature.
It looks like the accel sensor gives about 3-4 outputs per second. I think it should be several speed variants.

But the main is that in emulator and real device - the same situation: after 1-2 mins of logging the sensor speed logging is slower and app hangs. But after some seconds it's possible to be "force" killed.

:( so impossible to use the sensor permanently in applications ?
 

mistermentality

Active Member
Licensed User
Longtime User
I want to rewrite an app inventor app using B4A that checks the sensors for movement and if none has been found for X amount of minutes it warns someone but....

Using the example code from this thread both the acceleration and orientation results are never stationary, even when on a totally flat non moving surface such as a stone floor the accelerometer for example will vary from say .7 to .9 and so on.

Doesn't this mean that an app checking for non movement will always show as having detected movement?

Dave
 

mistermentality

Active Member
Licensed User
Longtime User
Thanks for the reply. I wasn't sure if any one else had this problem as it hadn't been mentioned but yes I will have to measure the average values I think as every sensor is constantly changing even when stationary.

Dave
 

jota

Active Member
Licensed User
Longtime User
gyroscope sensor

Good testing the example tells me not to support the gyroscope sensor, however I have programs that work correctly compass. Is it possible that there is a bug in this library? thanks

-------------------------------------------------------------

Buenas probando el ejemplo me dice que no soporta el sensor gyroscope, sin embargo tengo programas de brujula que funcionan correctamente. ¿ es posible que haya un fallo en esta libreria ? Gracias
 

NeoTechni

Well-Known Member
Licensed User
Longtime User
I'm getting some odd readings.

When I try the light sensor, I get 5 when covered, 22 when not covered, and it reports 3,000 as the max value. When I convert the detected value to a percent based on the max value, I basically get 0 (garbage)
 
Top