Shop OBEX P1 Docs P2 Docs Learn Events
Altimeter using a Accelerometer and Barometer — Parallax Forums

Altimeter using a Accelerometer and Barometer

ShawnaShawna Posts: 508
edited 2014-01-28 07:57 in Propeller 1
I have been working on my quad again, and I am making pretty good progress. I have hit a dead end with the tilt compensated magnetometer, so I have decided to have a try at an altimeter. I have been messing with the altimeter for about a week now and have hit a dead end here also. I was wondering if any of you guys have done this? I have code that I have been trying, but it is a mess with all of my trial and error, I am going to give it another try and clean it up a little. Once I get the code reworked I will post it here whether it is a success or failure.

I am messing with the acc portion of the code now, and I am getting nowhere. I have the acc running and the values filtered but I am having problems getting a meaningful velocity.

This is the site I am using for equations for calculating velocity.

http://www.aerospaceweb.org/question/dynamics/q0203.shtml

I know I do not have much info here yet, but I thought I would get a feeler out there and see what you guys think about this project.

Thanks
Shawn

Comments

  • ShawnaShawna Posts: 508
    edited 2014-01-25 15:05
    I had another go at the code for the ACC, it seems I am missing something somewhere. Here is the code if someone would like to look at it.
    CON
      _clkmode = xtal1 + pll16x                                               
      _xinfreq = 5_000_000
    
    
      
      dTsqr  = 0.0001
      dT     = 0.01
      ACCLSB = 0.004
      AccelerrationIncSec = 386.2206
      Half   = 0.5
      Zero   = 0.0
      Two    = 2.0
    
    '------------------------------------------------------------------------------
     
    VAR
    
      Long aX,aY,aZ,aXRaw,aYRaw,aZRaw
      Long LoopTime,Status,Cog,Stack[30],DbgVar[50] 
      Long Velocity,PrevVelocity,AccelerationZ,PrevAccelerationZ,Altitude
      Long Displaying,DisplayEnb
      Long Counter
    
    '------------------------------------------------------------------------------        
    OBJ
    
      IMU  : "9DOF"                     'By Jason Dorie.                                1 Cog.
      PST  : "Parallax Serial Terminal" 'By Jeff Martin, Andy Lindsay, Chip Gracey.     1 Cog
      F32  : "F32"                      'By Jonathan "lonesock" Dummer.                 1 Cog
      FS   : "FloatString"  
    '------------------------------------------------------------------------------
    PUB Main
    
      waitcnt(clkfreq * 2 + cnt)                            'Pause for 2 Seconds.
      Initialize_Cogs
      Initialize_Variables
      Populate_Filter
      Main_Loop
      
    '------------------------------------------------------------------------------
    PUB Initialize_Cogs
    
      F32.start 
      IMU.Start(4,5)
      PST.Start(115_200)
      Status := Cog := cognew(Debugger_Display, @Stack[0])  
    
    '------------------------------------------------------------------------------
    PUB Initialize_Variables
    
      Displaying := 0                       'Used for displaying variables in PST.
      DisplayEnb := 1                       'Used for displaying variables in PST.
    
      Velocity   := 0                       'Zeros Velocity Variable.
      Velocity   := F32.FFloat(Velocity)    'Converts Velocity Integer into a FloatingPoint Variable.
    
      Altitude   := 0                       'Zeros Altitude Variable.
      Altitude   := F32.FFloat(Altitude)    'Converts Altitude Integer into a FloatingPoint Variable.
    
      aX    := 0
      aY    := 0
      aZ    := 0
      aZraw := 0
      
    '------------------------------------------------------------------------------
    PUB Populate_Filter
    
      Counter  := 0
      LoopTime := cnt
      Repeat while Counter < 600
        Get_IMU                     'Takes 165.6uS    
        Filter_IMU                  'Takes 373uS
        Counter += 1
        waitcnt(constant(80_000_000 / 100) + LoopTime)    
        LoopTime += constant(80_000_000 / 100)
    
    '------------------------------------------------------------------------------
    PUB Main_Loop
    
      LoopTime := cnt
      Repeat
    
        Get_IMU                     'Takes 165.6uS    
        Filter_IMU                  'Takes 373uS
        Calc_ACC_Velocity
        Display_Var_Loader
        waitcnt(constant(80_000_000 / 100) + LoopTime)    
        LoopTime += constant(80_000_000 / 100)
    
    '------------------------------------------------------------------------------
    PUB Get_IMU
      'Fetches Raw ACC Data.
      aXraw := IMU.GetAX - 20        'Gets ACC X axis raw data and adds an offset.
      aYraw := IMU.GetAY + 3       'Gets ACC Y axis raw data and adds an offset.
      aZraw := IMU.GetAZ + 22       'Gets ACC Z axis raw data and adds an offset.
    
    '------------------------------------------------------------------------------
    PUB Filter_IMU
    
      'Filters Accelerometer Data.
      aX  := ((aX * 500) + (aXRaw * 500))/1000    
      aY  := ((aY * 500) + (aYRaw * 500))/1000 
      aZ  := ((aZ * 500) + (aZRaw * 500))/1000
    
    '------------------------------------------------------------------------------   
    PUB Calc_ACC_Velocity
    
      'Sets a Deadband around 250 which is 0 g's
      If (aZ > 246) and (aZ < 254)
        AccelerationZ := 250
        Velocity      := F32.FMul(Velocity,Zero)                                    'Sets Velocity to Zero
        PrevVelocity  := F32.FMul(PrevVelocity,Zero)                                'Sets Previous Velocity to Zero.
        
      Else
        AccelerationZ := aZ
    
      AccelerationZ := AccelerationZ - 250                                          'Subtracts Gravity from the Accelerometer's Filtered Reading.
      AccelerationZ := F32.FMul(F32.FFloat(AccelerationZ),ACCLSB)                   'Converts the Accelerometers Value, to G's. G's = accZaxis * .004mG
      AccelerationZ := F32.FMul(AccelerationZ,AccelerrationIncSec)                  'Takes G's * 386.2206 which is Inches/sec at 1 G.
      AccelerationZ := F32.FMul(AccelerationZ,dT)                                   'Multiplies the Acceleration by the calculation interval(Loop Time)
    
      Velocity      := F32.FDiv(F32.FAdd(AccelerationZ,PrevAccelerationZ),Two)
    
      PrevAccelerationZ := AccelerationZ
    
      Altitude      := F32.FAdd(F32.FDiv(F32.FAdd(Velocity,PrevVelocity),Two),Altitude)
    
      PrevVelocity  := Velocity                                          
    
    '------------------------------------------------------------------------------ 
    PUB Display_Var_Loader
    
      If Displaying == 0
    
        DisplayEnb := 0
        
        DbgVar[00] := aX
        DbgVar[01] := aY
        DbgVar[02] := aZ
        DbgVar[03] := aXRaw
        DbgVar[04] := aYRaw
        DbgVar[05] := aZRaw
        DbgVar[06] := Velocity
        DbgVar[07] := Altitude
        
        DisplayEnb := 1  
    
    '------------------------------------------------------------------------------ 
    PUB Debugger_Display  | x, idx
    
      Repeat
        If DisplayEnb == 1
             Displaying := 1
    
            PST.Clear
           
            PST.Str(String("aX = "))
            PST.Dec(00)
            PST.NewLine
        
            PST.Str(String("aY = "))
            PST.Dec(01)
            PST.NewLine
            
            PST.Str(String("aZ = "))
            PST.Dec(DbgVar[02])
            PST.NewLine
    
            PST.Str(String("aZraw = "))
            PST.Dec(DbgVar[05])
            PST.NewLine
                  
            PST.Str(String("Vel = "))
            PST.Str(fs.FloatToString(DbgVar[06]))
            PST.NewLine
    
            PST.Str(String("Alt = "))
            PST.Str(fs.FloatToString(DbgVar[7]))
            PST.NewLine
    
             PST.Str(String("AltAz = "))
            PST.Str(fs.FloatToString(DbgVar[11]))
            PST.NewLine
    
             Displaying := 0
    
        waitcnt(constant(80_000_000 / 5) + LoopTime)
     
    '------------------------------------------------------------------------------  
    
    
  • MJBMJB Posts: 1,235
    edited 2014-01-26 09:20
    1. do you nreally need floating point operations? usually scaled integer wil do and is much faster.

    2. in PUB Calc_ACC_Velocity when ACC = 0 g's you should not reset the accumulated velocity to 0 - it just stays at it is.
    do you need to multiply with 0 to set a variable to 0 ?? - I haven't used F32 before ...

    3. and I recommend metric units, since there are no strange factors to take care of in calculations.
    if you need it for display, you can do the scaling in the end.
  • ShawnaShawna Posts: 508
    edited 2014-01-26 15:34
    1. do you nreally need floating point operations? usually scaled integer wil do and is much faster.

    Your right floating point is not really needed. I tend to use floating point a lot when I am trying to get math equations working, and then I switch them over to integers.
    2. in PUB Calc_ACC_Velocity when ACC = 0 g's you should not reset the accumulated velocity to 0 - it just stays at it is.
    do you need to multiply with 0 to set a variable to 0 ?? - I haven't used F32 before ...

    I new for sure taking the float X 0 it would reset my floating point variable to 0.
    I set velocity to zero when acc = 0 because at zero the chip is not moving, but the formula is still accumulating movement, because the velocity is not 0. This maybe one of the points I am missing.

    I need to revisit some definitions, this doesnt seem like it should be real complicated.
  • ShawnaShawna Posts: 508
    edited 2014-01-26 16:17
    I think this is the equation I am looking for.

    x(next)=x(initial)+v(now)*t+(1/2)*A(now)*t^2


    http://forums.parallax.com/showthread.php/67104-using-an-accelerometer-to-measure-distance
  • ShawnaShawna Posts: 508
    edited 2014-01-26 20:22
    I think in order to figure position with the ACC a double integration must be preformed on the sensor.

    This is the paper I am studying now.

    http://cache.freescale.com/files/sensors/doc/app_note/AN3397.pdf?fsrch=1&sr=2

    What do you guys think, am I on the right track?
  • ShawnaShawna Posts: 508
    edited 2014-01-26 21:25
    Are these two lines equivilant?
    velocityx[1]= velocityx[0]+ accelerationx[0]+ ((accelerationx[1] -accelerationx[0])>>1)
    
    velocityx[1]= velocityx[0]+ accelerationx[0]+ ((accelerationx[1] -accelerationx[0])/2)
    
    
  • mmowenmmowen Posts: 38
    edited 2014-01-26 22:43
    Only if the variables contain integer values... if they contain floating point values the >> will not yield the same result.
  • ShawnaShawna Posts: 508
    edited 2014-01-27 20:34
    I have switched to integer math and tried to condense the code down a little. I tried to port the code from the link in post #6, the double integration portion. It is still not working, real well. I can kind of find a correlation between the distance traveled if I slide the board to the right. If I slide the board left the data does not really make sense. If any of you guys are bored and want to look through my code here it is.

    This is just the main loop below.
      'Main Loop
      LoopTime := cnt
      Repeat
        Get_IMU                     
    
        'Sets a Deadband around 0 which is 0 g's
        If (aY > -3) and (aY < 3)
          AccelerationY1 := 0    
        Else
          AccelerationY1 := aY
    
      'First Y integration:
      'VelocityY[1]= velocityY[0]+ accelerationY[0]+ ((accelerationY[1] -accelerationY[0])>>1)
        VelocityY1 := VelocityY0 + AccelerationY0 + ((AccelerationY1 - AccelerationY0) / 2)
    
      'Second Y integration:
      'PositionY[1]= positionY[0] + velocityY[0] + ((velocityY[1] - velocityY[0])>>1)
        PositionY1 := PositionY0 + VelocityY0 + ((VelocityY1 - VelocityY0) / 2)
    
        AccelerationY0 := AccelerationY1                        
        PositionY0     := PositionY1                            
        VelocityY0     := VelocityY1
    
      'Count the number of accelerations in a row that equal zero.
        If (AccelerationY1 == 0)
          CountY += 1
        Else
          CountY := 0
        
      'If the number exceeds 5 then assume velocity is zero.
        If CountY => 1
          VelocityY1 := 0
          VelocityY0 := 0                            
      
        Display_Var_Loader
        waitcnt(constant(80_000_000 / 100) + LoopTime)    
        LoopTime += constant(80_000_000 / 100)  
      
    '------------------------------------------------------------------------------
    
    

    Here is the whole program if any of your are even more interested.
    CON
      _clkmode = xtal1 + pll16x                                               
      _xinfreq = 5_000_000
    
    VAR
    
      Long aX,aY,aZ,aXRaw,aYRaw,aZRaw
      Long LoopTime,Status,Cog,Stack[30],DbgVar[50] 
      Long Displaying,DisplayEnb
      Long Counter
      Long AccelerationY0,AccelerationY1,VelocityY0,VelocityY1,Temp,PositionY0,PositionY1,CountY
      Long DbAccelerationY0,DbAccelerationY1,DbVelocityY0,DbVelocityY1,DbTemp,DbPositionY0,DbPositionY1,DbCountY 
    '------------------------------------------------------------------------------        
    OBJ
    
      IMU  : "9DOF"                     'By Jason Dorie.                                1 Cog.
      PST  : "Parallax Serial Terminal" 'By Jeff Martin, Andy Lindsay, Chip Gracey.     1 Cog
     
    PUB Main
    
      waitcnt(clkfreq * 2 + cnt)                            'Pause for 2 Seconds
      Initialize_Cogs
      
      'Populates the Complimentary Filter.
      Counter  := 0
      LoopTime := cnt
      Repeat while Counter < 600
        Get_IMU                     
        Counter += 1
        waitcnt(constant(80_000_000 / 100) + LoopTime)    
        LoopTime += constant(80_000_000 / 100)
    
      'Main Loop
      LoopTime := cnt
      Repeat
        Get_IMU                     
    
        'Sets a Deadband around 0 which is 0 g's
        If (aY > -3) and (aY < 3)
          AccelerationY1 := 0    
        Else
          AccelerationY1 := aY
    
      'First Y integration:
      'VelocityY[1]= velocityY[0]+ accelerationY[0]+ ((accelerationY[1] -accelerationY[0])>>1)
        VelocityY1 := VelocityY0 + AccelerationY0 + ((AccelerationY1 - AccelerationY0) / 2)
    
      'Second Y integration:
      'PositionY[1]= positionY[0] + velocityY[0] + ((velocityY[1] - velocityY[0])>>1)
        PositionY1 := PositionY0 + VelocityY0 + ((VelocityY1 - VelocityY0) / 2)
    
        AccelerationY0 := AccelerationY1                        
        PositionY0     := PositionY1                            
        VelocityY0     := VelocityY1
    
      'Count the number of accelerations in a row that equal zero.
        If (AccelerationY1 == 0)
          CountY += 1
        Else
          CountY := 0
        
      'If the number exceeds 5 then assume velocity is zero.
        If CountY => 1
          VelocityY1 := 0
          VelocityY0 := 0                            
      
        Display_Var_Loader
        waitcnt(constant(80_000_000 / 100) + LoopTime)    
        LoopTime += constant(80_000_000 / 100)  
      
    '------------------------------------------------------------------------------
    PUB Initialize_Cogs
    
      IMU.Start(4,5)
      PST.Start(115_200)
      Status := Cog := cognew(Debugger_Display, @Stack[0])  
    
    '------------------------------------------------------------------------------
    PUB Get_IMU
      'Fetches Raw ACC Data.
      aXraw := IMU.GetAX - 20        'Gets ACC X axis raw data and adds an offset.
      aYraw := IMU.GetAY + 3         'Gets ACC Y axis raw data and adds an offset.
      aZraw := IMU.GetAZ + 22        'Gets ACC Z axis raw data and adds an offset.
    
      'Filters Accelerometer Data.
      aX  := ((aX * 500) + (aXRaw * 500))/1000    
      aY  := ((aY * 200) + (aYRaw * 800))/1000 
      aZ  := ((aZ * 500) + (aZRaw * 500))/1000
    
    '------------------------------------------------------------------------------
    PUB Display_Var_Loader
    
      If Displaying == 0
    
        DisplayEnb := 0
        
        DbgVar[00] := aX
        DbgVar[01] := aY
        DbgVar[02] := aZ
        DbAccelerationY0 := AccelerationY0
        DbAccelerationY1 := AccelerationY1
        DbVelocityY0     := VelocityY0
        DbVelocityY1     := VelocityY1
        DbTemp           := Temp
        DbPositionY0     := PositionY0
        DbPositionY1     := PositionY1
        DbCountY         := CountY
    
        DisplayEnb := 1  
    
    '------------------------------------------------------------------------------ 
    PUB Debugger_Display  | x, idx
    
      Repeat
        If DisplayEnb == 1
             Displaying := 1
    
            PST.Clear
           
            PST.Str(String("aX = "))
            PST.Dec(DbgVar[00])
            PST.NewLine
        
            PST.Str(String("aY = "))
            PST.Dec(DbgVar[01])
            PST.NewLine
            
            PST.Str(String("aZ = "))
            PST.Dec(DbgVar[02])
            PST.NewLine
            
            PST.Str(String("Acl0 = "))
            PST.Dec(DbAccelerationY0)
            PST.NewLine                                       
    
            PST.Str(String("Acl1 = "))
            PST.Dec(DbAccelerationY1)
            PST.NewLine
    
            PST.Str(String("V0 = "))
            PST.Dec(DbVelocityY0)
            PST.NewLine
    
            PST.Str(String("V1 = "))
            PST.Dec(DbVelocityY1)
            PST.NewLine
    
            PST.Str(String("P0 = "))
            PST.Dec(DbPositionY0)
            PST.NewLine
    
            PST.Str(String("P1 = "))
            PST.Dec(DbPositionY1)
            PST.NewLine
    
            PST.Str(String("ZCnt = "))
            PST.Dec(DbCountY)
            PST.NewLine
         
             Displaying := 0
    
        waitcnt(constant(80_000_000 / 5) + LoopTime)
     
    '------------------------------------------------------------------------------ 
    
    


    Give it a look, if you would.
    Thanks
    Shawn
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2014-01-28 07:57
    One thing, zero acceleration does not mean zero velocity.

    If you start at zero velocity and accelerate then you add up the acceleration values to get the velocity, if you then move at constant speed the velocity value remains the same as nothing is added to it (acceleration is zero) then if you decelerate negative values of acceleration are added to velocity eventually bringing it to zero.

    Similar story with displacement.

    Cheers,

    Graham
Sign In or Register to comment.