Faster code for MS5611 variometer

Benjie

Senior Member
Hippy, for curiosity, I eliminated the n samples average and just compared last with this; it works almost as well giving much larger execution speed spectrum. in fact I had to increase the final pause from nothing to 200 ms.
Here the code:
Code:
#Picaxe 08M2
#Terminal 4800
#No_Data

setfreq m8
Symbol reserveW0     = w0
Symbol reserveW1     = w1

Symbol h.average     = w2 ; b5:b4
Symbol m.average     = w3 ; b7:b6
Symbol l.average     = w4 ; b9:b8

Symbol h.average.lsb = b4
Symbol m.average.lsb = b6
Symbol l.average.lsb = b8

Symbol h.average.msb = b5
Symbol m.average.msb = b7
Symbol l.average.msb = b9

Symbol m.last        = w5 ; b11:b10
Symbol l.last        = w6 ; b13:b12

Symbol diff          = w7 ; b15:b14

Symbol h.byte        = b16
Symbol m.byte        = b17
Symbol l.byte        = b18

Symbol counter       = b19

Symbol TONE_PERIOD = 5   ; 50ms
Symbol MIN_DIFF    = 50

Symbol SAMPLES       = 2

Symbol CMD_RESET     = $1E
Symbol CMD_D1_4096   = $48
Symbol CMD_ADC       = $00

PowerOnReset:

  HI2cSetup I2CMASTER, %11101110, I2CSLOW, I2CBYTE

MainLoop:

  Do
    h.average = 0
    m.average = 0
    l.average = 0
    'For counter = 1 To SAMPLES
      HI2cOut ( CMD_D1_4096 )
      Pause 20
      HI2cOut ( CMD_ADC )
      Pause 20
      HI2cIn ( h.byte, m.byte, l.byte )

      h.average = h.average + h.byte
      m.average = m.average + m.byte
      l.average = l.average + l.byte

    'Next

    ; Combine the numbers
    m.average = m.average + l.average.msb 
    h.average = h.average + m.average.msb

    ; Create m:l sum
    l.average.msb = m.average.lsb
    m.average     = h.average

    ; Find the average
    m.average = $100 / SAMPLES * m.average
    m.average = l.average / SAMPLES / 256 + m.average 
    l.average = $100 / SAMPLES * l.average 

    ; At this point the integer 24-bit average
    ; held in the m.average and l.average pair
    ; as -
    ;       m.average               l.average
    ;.---------------------. .---------------------.
    ;| xwvutsrq | ponmlkji | | hgfedcba | 00000000 |
    ;`---------------------' `---------------------'
    ;  m.avg.msb  m.avg.lsb    l.avg.msb  l.avg.lsb

    ; Now make the numbers lsb aligned -
    ;
    ;       m.average               l.average
    ;.---------------------. .---------------------.
    ;| 00000000 | xwvutsrq | | ponmlkji | hgfedcba |
    ;`---------------------' `---------------------'
    ;  m.avg.msb  m.avg.lsb    l.avg.msb  l.avg.lsb

    l.average.lsb = l.average.msb
    l.average.msb = m.average.lsb
    m.average.lsb = m.average.msb
    m.average.msb = 0

    ; Determine which is highest, this average or last

    If m.average > m.last Then ThisIsHigher
    If m.average < m.last Then LastIsHigher
    If l.average > l.last Then ThisIsHigher
    If l.average < l.last Then LastIsHigher

    BothTheSame:
      diff = 0
      Goto CalculatedDifference

    ThisIsHigher:
      ; Calculate diff = average - last
      m.last = m.average - m.last
      diff   = l.average - l.last
      ; Handle subtraction borrow
      If l.average < l.last Then
        m.last = m.last - 1
      End If
      ; Limit to maximum positive value
      If m.last > 0 Then
        diff = $7FFF
      Else
        diff = diff max $7FFF
      End If
      ; Reult is correctly positive
      Goto CalculatedDifference

    LastIsHigher:
      ; Calculate diff = last - average
      m.last = m.last - m.average
      diff   = l.last - l.average
      ; Handle subtraction borrow
      If l.last < l.average Then
        m.last = m.last - 1
      End If
      ; Limit to maximum positive value
      If m.last > 0 Then
        diff = $7FFF
      Else
        diff = diff max $7FFF
      End If
      ; Make negative, because average - last is
      diff = -diff
      Goto CalculatedDifference

    CalculatedDifference:
      ; last becomes latest average
      m.last = m.average
      l.last = l.average

    'If diff = 0 Then
      'SerTxd( "=")
    'Else
      w0 = diff : Gosub SignedWord
    'End If
    SerTxd( CR, LF )
Gosub GenerateTone
pause 200
  Loop
  
  GenerateTone:

  ; Negate diff because a rising pressure means
  ; a falling height
  diff = -diff
  If diff >= $8000  Then
    ; We are falling (negative)
    w0 = -diff
    If w0 > 70 Then
      Sound C.4, ( 50, TONE_PERIOD )
      Return
    End If
  Else
    ; We are rising (positive)
    w0 = diff
    If w0 > 55 Then
      Sound C.4, ( 110, TONE_PERIOD )
      Return
    End If
  End If
  ; We haven't returned, so haven't issued a tone so
  ; far. Issue silence so we have consistent timing.
  Sound C.4, ( 0, TONE_PERIOD )
  Return

SignedWord:
  If w0 >= $8000  Then
    w0 = -w0
    SerTxd( "-", #w0 )
  Else
    SerTxd( "+", #w0 )
  End If
  Return
 

hippy

Technical Support
Staff member
it works almost as well giving much larger execution speed spectrum.
Presumably just for curiosity, because 'works almost as well' with no practical gain isn't really an improvement.

I must admit I would have probably gone the other way, increasing the number of samples for averaging, but as long as it works.
 
Top