Faster code for MS5611 variometer

Benjie

Senior Member
#1
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
#2
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