VARIOMETER using GY63/MS5611 barometer

hippy

Technical Support
Staff member
I attach the data..
It's all looking good as there's no jumps in the first, third or fourth columns. The second is the noisy byte so that is expected to jump about.
Code:
34177 96  43778 43777 floor
34176 118 43776 43774 +80 cm
34173 48  43770 43770 +180 cm
For the first column ( raw sensor ) -

A decrease of 1 for 0 to 80, -1 => 80
A decrease of 4 for 0 to 180, -1 => 45

For the third column ( adjusted to offset 16-bit )-

A decrease of 2 for 0 to 80, -1 => 40
A decrease of 8 for 0 to 180, -1 => 22.5

For the fourth column ( averaged offset 16-bit ) -

A decrease of 3 for 0 to 80, -1 => 26.7
A decrease of 7 for 0 to 180, -1 => 25.7

That's not looking too bad. We could roughly say a decrease of 1 represents a rise of 26 cm. That's pretty close to the 250mm predicted.

As to 'grnd' in the code - That was just preparing for the next step so we can store what your floor level is, 'ground', then calculate the pressure drop above that. For example, 'grnd' at 43777 -
Code:
34177 96  43778 43777 | 43777 - 43777 = 0 | floor
34176 118 43776 43774 | 43777 - 43774 = 3 | +80 cm   3 x 26 = 78
34173 48  43770 43770 | 43777 - 43770 = 7 | +180 cm  7 x 26 = 182
I would say we are getting there. I think there might be an easy way to do it all with 32-bit maths, from sensor reading up.

Can't comment on your other code. haven't had time to study it yet.
 

Benjie

Senior Member
In a couple of days I'll receive the FM transmitter and I will be able to experiment the sound information moving up and down 10 m.
 

Benjie

Senior Member
Hi Hippy,
now it works well. I had to trim the pauses and the sound parameters. It responds well for altitude variations of .40 meter/sec with different tone depending on the direction. At present the repetition rate of the tones depends on the pauses. I'll make some attempt to setfreq at m8 to double the repetition rate and create a pause between sound pulses inversely proportional to the value of "diff".
Here the current code:
Code:
#Picaxe 08M2
#Terminal 4800
#No_Data

Symbol this = w1 : Symbol this.msb = b3 : Symbol this.lsb = b2
Symbol last = w2 : Symbol last.msb = b5 : Symbol last.lsb = b4
Symbol avrg = w3
Symbol avrg1 = w4
Symbol diff = b0
Symbol grnd = w5
Symbol CMD_RESET   = $1E
Symbol CMD_D1_4096 = $48
Symbol CMD_ADC     = $00
Symbol beat = b1
PowerOnReset:

  HI2cSetup I2CMASTER, %11101110, I2CSLOW, I2CBYTE

MainLoop:

  Do
'first reading store avrg

    HI2cOut ( CMD_D1_4096 )
    Pause 10
    HI2cOut ( CMD_ADC )
    Pause 10

    HI2cIn ( this.msb, this.lsb, b0 )
    this = this Min $3000 - $3000 Max $7FFF * 2 + bit7 

    If avrg = 0 Then
      avrg = this
    Else
      w0   = this / 2
      avrg = avrg / 2 + w0 
      If grnd = 0 Then
        grnd = avrg
      End If
    End If

    Pause 100

'second reading store avrg1

       HI2cOut ( CMD_D1_4096 )
    Pause 15
    HI2cOut ( CMD_ADC )
    Pause 15

    HI2cIn ( last.msb, last.lsb, b0 )
    last = last Min $3000 - $3000 Max $7FFF * 2 + bit7 

      avrg1 = last
      w0   = last / 2
      avrg1 = avrg1 / 2 + w0

  
select case avrg1
    
case = avrg
    diff = 0 : sound 4,(0,10)
case > avrg
      diff = avrg1 - avrg 
      if diff  >= 2 then 
          sound 4,(30,10) 
      else 
          sound 4,(0,10)  
      endif
case < avrg
      diff = avrg - avrg1 
      if diff >= 2 then 
          sound 4,(110,10)
      else 
          sound 4, (0,10)  
      endif
end select
pause 100

  loop
 

hippy

Technical Support
Staff member
I'll take your word for it working but I'm not entirely sure how it's working or what you are actually measuring or comparing.
Code:
avrg1 = last
w0 = last / 2
avrg1 = avrg1 / 2 + w0
All that would seem to be achieving is ...
Code:
avrg1 = last / 2 * 2
But, if it works, it works !
 

Benjie

Senior Member
Your note has been taken.
Here the latest version while waiting for the FM transmitter ( I temporarely connected an earphone).
Code:
#Picaxe 08M2
#Terminal 9600
#No_Data

Symbol this = w1 : Symbol this.msb = b3 : Symbol this.lsb = b2
Symbol last = w2 : Symbol last.msb = b5 : Symbol last.lsb = b4
Symbol ripo = w3 : Symbol ripo.msb = b7 : Symbol ripo.lsb = b6

Symbol inter = w4 : Symbol inter.msb = b9 : Symbol inter.lsb = b8
Symbol diff = b0
Symbol CMD_RESET   = $1E
Symbol CMD_D1_4096 = $48
Symbol CMD_ADC     = $00

PowerOnReset:

setfreq m8
  HI2cSetup I2CMASTER, %11101110, I2CSLOW, I2CBYTE

MainLoop:

  Do

    HI2cOut ( CMD_D1_4096 )
    Pause 20
    HI2cOut ( CMD_ADC )
    Pause 20

    HI2cIn ( this.msb, this.lsb, b0 )
    this = this Min $3000 - $3000 Max $7FFF * 2 + bit7 
      
 ; set initial value of ripo    
        if ripo = 0 then 
        ripo = this
        endif
; activate a two tones sound : goes up or goes down with a gap of +- 2 
        select case this    
        case = ripo
    diff = 0 : sound 4,(0,1)
        case > ripo
      diff = this - ripo 
      if diff  >= 2 then 
          sound 4,(20,5)
      else 
          low 4  
      endif
        case < ripo
      diff = ripo - this 
      if diff >= 2 then 
          sound 4,(120,5)
      else 
          low 4 
      endif
        end select
  ; save the pressure reading for next reading comparison
        let ripo = this
  ; modulate  frequency of readings and the sound pulses interval prpoprtional to 1/diff     
    select case diff
    case =< 2 : inter = 300
    case < 10 : inter = 3000 / diff
    case >= 10 : inter = 300
    end select    
        
    Pause inter
  loop
 

Benjie

Senior Member
Hello Hippy,
back to this project, I read the thread "MPL3115A2 altimeter failed due to software" where in the post #1 this code is reported:
Code:
#picaxe 14M2
SETFREQ M8
LET w0 = 0
LET b6 = 0
HI2CSETUP I2CMaSTER,0XC0 ,I2CFAST_8,I2CBYTE
HI2COUT 0x26,(0xB8)                '0xA9 is 32 samples 0xB8 is 128,set standby
HI2COUT 0x26,(0x04)                'Reset
PAUSE 200
main:
HI2CSETUP I2CMaSTER,0XC0 ,I2CFAST_8,I2CBYTE
HI2COUT 0x13,(0x07)                'Enable data flags
HI2COUT 0x26,(0xB9)                '0xA9 is 32 samples 0xB8 is 128,set active
DO
    HI2CIN 0x00,(b6)
    SERTXD (#b6,13,10)            'gets 0xC1
    LET b6 = b6 & 0x08
LOOP UNTIL b6 > 0
HI2CIN 0x01,(b1) 
HI2CIN 0x02,(b0)
HI2CSETUP I2CMaSTER,0Xe2 ,I2CFAST_8,I2CBYTE
BINTOASCII w0,b7,b2,b3,b4,b5
HI2COUT 0x76,(b2,b3,b4,b5) 
SERTXD (#pinC.0,",",#pinC.4,",",#w0,13,10)
PAUSE 900
GOTO main
The data sheet of the sensor can be read at https://cdn.sparkfun.com/datasheets/Sensors/Pressure/MPL3115A2.pdf.

That code is very similar, except the addresses, to the one I use with the MS5611.
Do you note, by any chance, a difference justifying the inability of my code to use the byte b0 completely and not just the bit7?
That byte is the key for resolution.
Thank you.
 

hippy

Technical Support
Staff member
That code is very similar, except the addresses, to the one I use with the MS5611.
Do you note, by any chance, a difference justifying the inability of my code to use the byte b0 completely and not just the bit7?
That byte is the key for resolution.
The MPL3115A2 and the issues the user was having with that seem to be entirely irrelevant to the issues you are having with the MS5611.

Your MS5611 code works, returns data which has values which would seem to be correct, the problems all rest in how you are handling and using that data.

We seem to be caught going round in circles; not using the raw 24-bit data the MS5611 returns because that is somewhat hard to deal with, but not willing to accept the reduction of resolution which using 16-bit data requires, though as best I remember there should be no loss of resolution which would materially affect things.

I am also lost as to where we are with this project; in post #33 you say "now it works well", but presumably doesn't. And your question on b0 and bit7 is a little abstract and without context. I am guessing you are talking about averaging and truncating and reducing the 8 lsb's down to just 1 lsb, but am unclear to what end or why you are asking.

I still think a big part of the problem is that you haven't got to grips with what you need to do, haven't, in principle, determined and defined how to get from your raw input data to what you need to output, are therefore trying to implement something which hasn't been determined and defined. And there are added layers of complication in that you want to use 24-bit data as 16-bit without loss of resolution, which simply isn't possible without restricting the range of values available, and the raw 24-bit data includes noise variance which needs to be removed, averaged out.

As far as I can see these are all algorithmic issues but you haven't determined what the algorithm should be, what the implementation should be to deliver the algorithm for what has been determined and defined, so are therefore struggling with the implementation, clutching at straws in the hope of it falling into shape. Like pushing a balloon into a box, one part goes in but some other part pops out.

It seems you may be stuck at the end of a blind alleyway, bashing your head against the wall, when you really need to back-track and go down a more fruitful path.

I think it probably needs a complete reset. Forget all what you've done so far and start again afresh. With the MS5611 or perhaps using the MPL3115A2 which seems to deliver a raw altitude reading, which could simplify things greatly.
 

Benjie

Senior Member
OK, hope I have correctly interpreted your message.
The last code works but the sensitivity to pressure changes is barely sufficient. In fact it provides a meaningful reaction at changes greater than 1 meter....read difference in lsb+bit7 from reference position to a 1 meter above or below. The same application using Arduino provides a 10 fold better, stable and repeatable performance.

Let's start from zero.
I just read the full 24 bit raw data in static conditions:

the least byte value jumps from 30 to more than 254 in an erratic way. No matter how I stabilize the electrical and environmental conditions.

From such behavior the least 7 bits (b0) are in my case useless.
The altimeter designs that I found in the web look like they can use the full 24 bit data. The way they convert such long word into a meaningful stable value is to me irrelevant since whatever algorithm they adopt it cannot cope with an almost random 7 bit cue.
I have no idea of the why of such random behavior but I do not believe that it is normal: there must be something in the code which prevents a stable reading of b0 otherwise why should a 24 bit ADC be used?

Talking about the pressure range to be covered I prefer for the time being to forget about and just assume that the sensor is used at sea level with altitude variations of less than few meters.
Let's first understand if the the raw information I get in static operation is correct or not.
Hope we can understand each other,
Thank you Hippy
 

hippy

Technical Support
Staff member
I just read the full 24 bit raw data in static conditions:

the least byte value jumps from 30 to more than 254 in an erratic way. No matter how I stabilize the electrical and environmental conditions.
But is that jumping between 30 to 254 a +/-224 change, or is it a +/-32 change, which would be about eight times smaller ?

This focus on the lsb is I think part of the problem. As mentioned before, perhaps in another thread, you cannot look at the lsb of a number in isolation.

An lsb jumping between $01 and $FE looks like a big jump (+253), and it would be if it were the lsb of a number going from $0001 to $00FF, but it's not if it's -3 because the number were changing from $0101 to $00FE.

Thus, whatever the lsb is doing is meaningless without the context of what the whole number is doing, knowing what the other bytes are.

I suspect there may be nothing wrong at all, just that you haven't got your head around the issue of multi-byte numbers, are still thinking of the numbers having this separate lsb byte when you can't think of it like that, have to think of it as just a part of the whole, having no significance in itself.

Looking at Post #81 at the top of the page, it seems we were getting there. I think you are imagining there's more wrong than there is, and I can understand why. I think you just have to break the obsession with the lsb being important.

I am amazed it's only six week since working on this because I've forgotten exactly where we were at. I am sure I had some code which would do full and accurate 24-bit averaging of the raw data so I'll see if I can dig that out.

I will agree with you. Getting it to work consistently when static will be a good first first step, then seeing if we can get it to accurately and consistently work a metre and two metres up.
 

Benjie

Senior Member
Hippy, just look at this code and record: anytime Pl.msb exceed 255, Ph.lsb is correctly incremented by 1.
Code:
#Picaxe 08M2
#Terminal 4800
#No_Data

Symbol Ph = w1 : Symbol Ph.msb = b3 : Symbol Ph.lsb = b2
Symbol Pl = w2 : Symbol Pl.msb = b5 : Symbol Pl.lsb = b4


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

PowerOnReset:


setfreq m4
  HI2cSetup I2CMASTER, %11101110, I2CSLOW, I2CBYTE
  HI2cOut ( CMD_RESET)
MainLoop:

  Do
    
    HI2cOut ( CMD_D1_4096 )
    Pause 20
    HI2cOut ( CMD_ADC )
    Pause 20

      HI2cIn ( Ph.msb,Ph.lsb,Pl.msb) : Pl.lsb=0
'debug
sertxd(#Ph.lsb,tab,#Pl.msb,cr,lf)

    Pause 200

  loop
Have a look to the sertxd list and the records of the 3rd and following lines: composing the value of a word of 9 bit composed with the last bit of Ph.lsb and Pl.msb would give in sequence: 1534, 740, 739, 757, 1632. While the 3 middle values look consistent and sufficiently stable, anytime the value #1024 bit toggles, there is a large jump on the Pl.msb.
This is what I cannot explain.

In the code of post #85 I used Ph.lsb and bit7 of Pl.msb. Because of the random change of bit7 I had to forget differences of less than 2 (if diff >= 2 then ) thus reducing further the resolution.
I understand that the output is a 24bit wide word divided in 3 bytes of 8 bits; once a byte exceed its maximum of 254 the next byte is incremented by 1. Maybe it is where I misunderstand the technics. Is it so?
 

Attachments

hippy

Technical Support
Staff member
If we assume the Ph.msb remains the same we can treat Ph.lsb and Pl.msb as a single 16-bit word (third column). If we take all those words we get an average of 36643. If we take the results you get and look at how they differ from the average we get (fourth column) -
Note: Just spotted that the signs are inverted, but doesn't really matter.
Code:
143   8   36616   +27
143  54   36662   -19
143 118   36726   -83
143   0   36608   +35
142 228   36580   +63
142 246   36598   +45
143  98   36706   -63
143  48   36656   -13
143   4   36612   +31
143  62   36670   -27
It seems there is a cyclic effect, sometimes lower, sometimes higher.

The main questions are; is that cyclic variance expected or not, and is the cyclic variance within the range of what would be expected ?

The easiest way to tell would be to compare how this sensor behaves with others, but we don't have two sensors to compare.

It might be worth modifying the Arduino code so that reports what the individual sensor readings are, checking to see if that shows the same variance, because its accurate results may simply be because it is doing something we are not doing.

In the absence of anything to compare with, as the first two bytes, Ph.msb and Ph.lsb, are pretty consistent when we show them in other tests, we can presume they are what the sensor is reporting and there is no reason to believe the third Pl.msb isn't what the sensor has determined and reported.

So, unless there's something we are missing, this variance is happening naturally, it is there, an actual pressure variance, or noise, or whatever.

It does seem that the variance can be quite large, varying from -83 to +63 here, but whether that really is a large variance depends on what those values represents.

As best I can tell from the graphs in the datasheet, the ADC reading is about 7000000 at 800 mbar, 5000000 at 500 mbar. From that a single bit change in the ADC reading seemingly represents a 0.00015 mbar change. I recall that matches with past calculations.

And, given the best I can tell there is something like a 0.118 mbar change per metre change in elevation, each of those 0.00015 mbar changes represents an effective change of about 1.2 mm.

So from that, your sensor, albeit static, imagines it is moving up or down by +/-95mm, +/-9.5cm.

That is a pretty small amount for something which has such a large overall range and averaging should remove any variance if it is cyclic.

I would therefore ignore the variance, see what the averaged data reports, see how consistent the averaged data is when static.

I am working on the principle that it doesn't matter if it thinks it is jumping up and down by any amount providing the average is correct. That is, the averaged result is what's important, not instantaneous readings or changes from one to another.

The only way we can tell is by trying it, seeing how an averaged result behaves, then take it from there. I'll see if I can find that averaging code.
 
Last edited:

hippy

Technical Support
Staff member
The attached code will calculate an accurate 24-bit average of the 24-bit sensor readings. For example, for four sensor readings -
Code:
Raw =   $415367   4281191
        $422126   4333862
        $4167F9   4286457
        $4182E1   4293345

Sum = $01065F67  17194855

Avg =   $4197D9   4298713
First we split those raw 24-bit numbers into 8-bit bytes, and total each set of bytes into 16-bit words -
Code:
.-------.-------.-------.
|  $41  |  $53  |  $67  |
|  $42  |  $21  |  $26  |
|  $41  |  $67  |  $F9  |
|  $41  |  $82  |  $E1  |
`-------^-------^-------'
.-------.-------.-------.
| $0105 | $015D | $0267 |
`-------'-------'-------'
Then we add those up to give us a 32-bit number -
Code:
.-------.
| $0105 |
'-.-----^-.
  | $015D |
  `-.-----^-.
    | $0267 |
    `-------'
.-----------.
| $01065F67 |
`-----------'
That number here is the sum of four samples so we need to divide it by four. We can achieve that by shifting it right by two bits -
Code:
$01065F67 = 0000 0001 0000 0110 0101 1111 0110 0111
            |_      |__                         |_
              |        |                          |
            0000 0000 0100 0001 1001 0111 1101 1001 = $004197D9

                      0100 0001 1001 0111 1101 1001 =   $4197D9
That 24-bit average can then be processed further, but at the moment we are just interested in what the averages are.
Code:
#Picaxe 08M2
#Terminal 4800
#No_Data

; Comment the line below to disable SERTXD output
#Define USE_SERTXD

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 h.byte        = b10
Symbol m.byte        = b11
Symbol l.byte        = b12

Symbol counter       = b13

Symbol SAMPLES       = 8

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

PowerOnReset:

  HI2cSetup I2CMASTER, %11101110, I2CSLOW, I2CBYTE
  HI2cOut ( CMD_RESET)
  Pause 10

MainLoop:

  Do
    h.average = 0
    m.average = 0
    l.average = 0
    For counter = 1 To SAMPLES
      HI2cOut ( CMD_D1_4096 )
      Pause 10
      HI2cOut ( CMD_ADC )
      Pause 10
      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
      #IfDef USE_SERTXD
        SerTxd( #counter, TAB, "  " )
        b0 = h.byte : Gosub HexByte
        b0 = m.byte : Gosub HexByte
        b0 = l.byte : Gosub HexByte
        SerTxd( CR, LF )
      #EndIf
    Next

    #IfDef USE_SERTXD
      ; Show the raw averages
      SerTxd( "h", TAB )
      w0 = h.average : Gosub HexWord
      SerTxd( CR,LF, "m", TAB, "  " )
      w0 = m.average : Gosub HexWord
      SerTxd( CR,LF, "l", TAB, "    " )
      w0 = l.average : Gosub HexWord
      SerTxd( CR,LF )
    #EndIf

    ; 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
 
    #IfDef USE_SERTXD
      ; show the sum
      SerTxd( "Sum", TAB )
      w0 = m.average : Gosub HexWord
      w0 = l.average : Gosub HexWord
      SerTxd( CR,LF )
    #EndIf

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

    #IfDef USE_SERTXD
      ; Show the averages
      SerTxd( "Avg", TAB, "  " )
      w0 = m.average     : Gosub HexWord
      b0 = l.average.msb : Gosub HexByte
      SerTxd( CR,LF )
    #EndIf
    
    #IfDef USE_SERTXD
      SerTxd( "===", TAB, "========", CR,LF )
    #EndIf

    Pause 5000
  Loop

HexWord:
  b2 = b1 / 16 : Gosub Nibble
  b2 = b1      : Gosub Nibble
HexByte:
  b2 = b0 / 16 : Gosub Nibble
  b2 = b0
Nibble:
  b2 = b2 & $0F + "0"
  If b2 > "9" Then : b2 = b2 + 7 : End If
  SerTxd( b2 )
  Return
 

Benjie

Senior Member
Have loaded your code and recorded the Avg output with two sensors (I had one spare) and at 3 positions: desk level, high about 80cm above desk and low 80 cm below desk.
I am not able to resolve the value of letters, pls illuminate me; once this solved and understood, we can proceed further.
 

Attachments

hippy

Technical Support
Staff member
Have loaded your code and recorded the Avg output with two sensors (I had one spare) and at 3 positions: desk level, high about 80cm above desk and low 80 cm below desk.
I really don't know. It seems there's a reasonable difference between your 'low' and 'desk' readings, and the decreasing value would be correct for rising altitude, but no real discernible differences between 'desk' and 'high'. And that's the same for both sensors.

I don't believe my averaging calculations are faulty but you could post some data from between the "===" markers and I can check the numbers.

Assuming it's right there is more variance than I would expect in the average.

Taking one 'desk' reading at random, $861C32, that's 8789042 decimal, and from the datasheet graphs would seem just shy of 1300 mbar, which is way higher than typical sea level expectations at a normal room temperature, and sensor 2 reads even higher, but of course we aren't using calibrated or compensated data.

I'm not familiar with the GY-63 or MS5611, and no one else seems to have used it with a PICAXE, so there's nothing to compare the behaviour you get with. It presumably can work or the manufacturer wouldn't sell it, and it appears it does work for some. So it's not clear why it doesn't work with a PICAXE in this case.

Some report "amazing performance" though it appears you're not the only one reporting some odd behaviour -

http://www.freesteel.co.uk/wpblog/2014/11/26/ms5611-altitude-sensor-very-sensitive-to-own-working-temperature
https://www.raspberrypi.org/forums/viewtopic.php?t=150312
https://www.rcgroups.com/forums/showthread.php?2792627-Barometer-Drift-Problem-(-Temperature-Dependent-)
https://community.st.com/s/question/0D50X00009XkX3xSAF/problem-with-ms5611-barometer-pressure-reading

That first link is quite interesting, and suggests the pressure reading is highly temperature sensitive and temperature is highly dependent on sampling rate and stability of sampling rate. Another link I found suggest even sampling more than twice a second causes self-heating changes.

Seems it's like trying to measure how tall a jelly is while juggling it on a roller coaster.

I don't know; maybe these particular boards aren't that great, we could be measuring too frequently or not often enough, aren't allowing enough time between triggering and sampling, aren't sampling regularly enough, averaging may be making things worse rather than better, we are likely suffering from not applying any compensation, and maybe there are supply voltage and ripple effects as well.

And then I found this, which is a good reference of how stable ( or not ) results are for someone else, and demonstrates how ridiculously sensitive it is to light -


I'm not sure where to go from here.
 

Benjie

Senior Member
I really don't know. It seems there's a reasonable difference between your 'low' and 'desk' readings, and the decreasing value would be correct for rising altitude, but no real discernible differences between 'desk' and 'high'. And that's the same for both sensors.

I don't believe my averaging calculations are faulty but you could post some data from between the "===" markers and I can check the numbers.

Assuming it's right there is more variance than I would expect in the average.

Taking one 'desk' reading at random, $861C32, that's 8789042 decimal, and from the datasheet graphs would seem just shy of 1300 mbar, which is way higher than typical sea level expectations at a normal room temperature, and sensor 2 reads even higher, but of course we aren't using calibrated or compensated data.

I'm not familiar with the GY-63 or MS5611, and no one else seems to have used it with a PICAXE, so there's nothing to compare the behaviour you get with. It presumably can work or the manufacturer wouldn't sell it, and it appears it does work for some. So it's not clear why it doesn't work with a PICAXE in this case.

Some report "amazing performance" though it appears you're not the only one reporting some odd behaviour -

http://www.freesteel.co.uk/wpblog/2014/11/26/ms5611-altitude-sensor-very-sensitive-to-own-working-temperature
https://www.raspberrypi.org/forums/viewtopic.php?t=150312
https://www.rcgroups.com/forums/showthread.php?2792627-Barometer-Drift-Problem-(-Temperature-Dependent-)
https://community.st.com/s/question/0D50X00009XkX3xSAF/problem-with-ms5611-barometer-pressure-reading

That first link is quite interesting, and suggests the pressure reading is highly temperature sensitive and temperature is highly dependent on sampling rate and stability of sampling rate. Another link I found suggest even sampling more than twice a second causes self-heating changes.

Seems it's like trying to measure how tall a jelly is while juggling it on a roller coaster.

I don't know; maybe these particular boards aren't that great, we could be measuring too frequently or not often enough, aren't allowing enough time between triggering and sampling, aren't sampling regularly enough, averaging may be making things worse rather than better, we are likely suffering from not applying any compensation, and maybe there are supply voltage and ripple effects as well.

And then I found this, which is a good reference of how stable ( or not ) results are for someone else, and demonstrates how ridiculously sensitive it is to light -


I'm not sure where to go from here.
 

hippy

Technical Support
Staff member
Hippy havé a look to this YouTube
Yes; it does seem to be that it should be easy.

The issue is why it isn't proving to be so easy and, as noted, it's not just yourself having problems.

It seems to me it should be as easy as wiring it up, taking a reading and that's it. It's the reason I was convinced that it was more likely an issue of understanding the data rather than the data you were seeing being meaningless or unusable. It seems I was wrong about that and I can only apologise for that, but analysing things from afar is always a difficult job especially with no experience of the parts being used.

In a couple of weeks I will get a working Arduino assembled with the MS5611. The code will be the one of the YouTube. Will see if it really works as shown
That seems the best course. Having something to compare with will really help in determining what is going on.

If it doesn't work with that it would seem that it's an issue with the particular boards you have. If it does work it would seem there is some difference in how it does it and how we are doing it with a PICAXE.

An analysis of how it does it against what we are doing with the PICAXE could reveal why it doesn't work with a PICAXE, what we have to do to make it work.
 

Benjie

Senior Member
Hippy, so far I have supplied the circuit with the 3X1.5V batteries of the prototype board. By doing so I was supplying also the MS5611.
Now I connected a 7.4V battery with a 7805 voltage regulator. The measured voltage is 4.9V.
Look at the same series of output and compare with the one of post #93.
There is quite a difference. looks like the problem was the supply voltage.
 

Attachments

hippy

Technical Support
Staff member
looks like the problem was the supply voltage
It's only taken three months but I guess we're getting there :)

The MS5611 chip itself appears rated for 1V8 to 3V6 operation so I'm surprised it has issues even if the 3V3 regulator wasn't giving full whack at 4V5. Perhaps it's not the exact same chip as the datasheet or maybe self-heating has worse, more noisy effects at lower voltages.

It does look a lot better but from looking at the averages of the averages it still appears there is some drift as readings are taken, the back on the desk last reading isn't in the same ballpark as the first on the desk reading.

I would guess that temperature and self-heating is playing a part so we might have to do something more to sort that out. As it's all addition, multiplication, and division by powers of two, that might not be too bad if we have to.

It might be worth reading and checking temperature as an aside so we can see what that is doing, so we can make a better call on that. There might be some simpler tricks which aren't perfect but gets us to another level of better accuracy and repeatability.

Then again, what we have, just having it rising and falling, may be enough for what we want to do.

I would guess that's the next step, seeing if we can connect a piezo, get it to go 'whee' as it rises, "whoo' as it falls over the couple of metres you can easily test with, using just last and current readings; back to where we started from.

The great thing is that we are making progress. More so than I was anticipating in the short term; so that's very good news.
 

Benjie

Senior Member
It's only taken three months but I guess we're getting there :)

The MS5611 chip itself appears rated for 1V8 to 3V6 operation so I'm surprised it has issues even if the 3V3 regulator wasn't giving full whack at 4V5. Perhaps it's not the exact same chip as the datasheet or maybe self-heating has worse, more noisy effects at lower voltages.

It does look a lot better but from looking at the averages of the averages it still appears there is some drift as readings are taken, the back on the desk last reading isn't in the same ballpark as the first on the desk reading.

I would guess that temperature and self-heating is playing a part so we might have to do something more to sort that out. As it's all addition, multiplication, and division by powers of two, that might not be too bad if we have to.

It might be worth reading and checking temperature as an aside so we can see what that is doing, so we can make a better call on that. There might be some simpler tricks which aren't perfect but gets us to another level of better accuracy and repeatability.

Then again, what we have, just having it rising and falling, may be enough for what we want to do.

I would guess that's the next step, seeing if we can connect a piezo, get it to go 'whee' as it rises, "whoo' as it falls over the couple of metres you can easily test with, using just last and current readings; back to where we started from.

The great thing is that we are making progress. More so than I was anticipating in the short term; so that's very good news.
It's only taken three months but I guess we're getting there :)

The MS5611 chip itself appears rated for 1V8 to 3V6 operation so I'm surprised it has issues even if the 3V3 regulator wasn't giving full whack at 4V5. Perhaps it's not the exact same chip as the datasheet or maybe self-heating has worse, more noisy effects at lower voltages.

It does look a lot better but from looking at the averages of the averages it still appears there is some drift as readings are taken, the back on the desk last reading isn't in the same ballpark as the first on the desk reading.

I would guess that temperature and self-heating is playing a part so we might have to do something more to sort that out. As it's all addition, multiplication, and division by powers of two, that might not be too bad if we have to.

It might be worth reading and checking temperature as an aside so we can see what that is doing, so we can make a better call on that. There might be some simpler tricks which aren't perfect but gets us to another level of better accuracy and repeatability.

Then again, what we have, just having it rising and falling, may be enough for what we want to do.

I would guess that's the next step, seeing if we can connect a piezo, get it to go 'whee' as it rises, "whoo' as it falls over the couple of metres you can easily test with, using just last and current readings; back to where we started from.

The great thing is that we are making progress. More so than I was anticipating in the short term; so that's very good news.
 

Benjie

Senior Member
Hippy, the MS5611 is mounted on a module which provides the step down of the 5V supply to the required 3.3V operation. I am not sure if the pull- resistors are included: I will analize it. I will be out of town for a week so be patient about the progress. I am however confident tha we are on the right track.
 

Benjie

Senior Member
Hippy, the MS5611 is mounted on a module which provides the step down of the 5V supply to the required 3.3V operation. I am not sure if the pull- resistors are included: I will analize it. I will be out of town for a week so be patient about the progress. I am however confident tha we are on the right track.
There is a further simplification: the variometer is asked to detect altitude changes in a range of 200m maximum; this means that the most significant byte will always remain the same within that altitude variation. It can therefore be forgot in the average calculation. In other words the m.average and l.average should be sufficient to cover 200m altitude change at whatever initial altitude.
 

Benjie

Senior Member
There is a further simplification: the variometer is asked to detect altitude changes in a range of 200m maximum; this means that the most significant byte will always remain the same within that altitude variation. It can therefore be forgot in the average calculation. In other words the m.average and l.average should be sufficient to cover 200m altitude change at whatever initial altitude.
To avoid the condition where the value of m.byte plus l.byte may go below zero, it is enough to add $127 to m.byte anytime it is less than say $110. Flying above the takeoff can only reduce the air pressure value.
 

hippy

Technical Support
Staff member
the most significant byte will always remain the same within that altitude variation. It can therefore be forgot in the average calculation.
I'm not convinced that is true. Each bit of the reading is equivalent to 0.00015 mbar, or as calculated earlier, 1.2 mm of height. A 16-bit value holds a maximum of 65535, so that gives a maximum working range of about 78642 mm; 78 metres.

I suspect you haven't seen the msb change because you have taken it 100 metres up.

The code for averaging wouldn't be greatly simplified, or execution speed improved, anyway, because we have to use 24-bit maths to accumulate the multiple 16-bit values before dividing by the number of samples to get the average. The calculations are all additions and then bit shifting so there's no great improvements to be had.

Besides; the averaging code is written and it appears to work. There doesn't appear to be much to gain from applying that optimisation and I don't believe it is worth risking an optimisation which may not be sound and may cause problems later.

The best approach is to 'do it properly' in a mathematically sound manner with no trickery which might come to trip us up. Handling 24 or 32-bit maths is not much more difficult than handling 16-bit so we might as well put the effort in to do that.

By the time we come to handle increase or decreased height for tone generation, we probably will be dealing with 16-bit signed data which is easy to handle. It's better to let it naturally become 16-bit data than try and force that prematurely through clever tricks.
 

Benjie

Senior Member
Wise considerations.
Will be back home by the end of the week anecdotal will design the before...after conditions to asset the change.
Will report progress.
 

Benjie

Senior Member
In your post #92 you talk about a 4 readings average while the “sample” is 8. In fact at the end of the code:
Code:
HexWord:
  b2 = b1 / 16 : Gosub Nibble
  b2 = b1      : Gosub Nibble
HexByte:
  b2 = b0 / 16 : Gosub Nibble
  b2 = b0
You divide by 16 to make the two bit shift.
My question: you add the readings 8 times not 4. Am I correct?
In case I’m correct, shoul we try to add 4 times only to speed-up the process? Always in attempt to increase the speed: is it worth to rise the freq. to 8 MHz and/or increase the I2cout from slow to fast?
 

hippy

Technical Support
Staff member
In your post #92 you talk about a 4 readings average while the “sample” is 8.
The example given in Post 92 was just to make it easier to comprehend and verify the principles being used in the code.

In the actual code it is indeed 8 samples, with a divide by 8.

In fact at the end of the code:
HexWord:
...
You divide by 16 to make the two bit shift.
That code is purely for printing hexadecimal numbers, nothing to do with the averaging as such. A word value is split into four nibbles, a byte value into two, and each nibble is then printed as hexadecimal characters.

The actual division of the summed numbers to create the average is around line 90 in the source code -
Code:
m.average = $100 / SAMPLES * m.average
m.average = l.average / SAMPLES / 256 + m.average 
l.average = $100 / SAMPLES * l.average
With 8 samples, $100 / 8 = 32, so what we actually have is -

m = 32 * m
m = l / 8 / 256 + m
l = 32 * l

For example -
Code:
          m                   l
.------------------. .------------------.
| -----qponmlkjihg | | fedcba9876543210 |
`------------------' `------------------'
                                          m = 32 * m
.------------------. .------------------.
| qponmlkjihg----- | | fedcba9876543210 |
`------------------' `------------------'
                       `-.-'
               .----<----'                m = l / 8 / 256 + m
             .-^-.
.------------------. .------------------.
| qponmlkjihgfedcb | | fedcba9876543210 |
`------------------' `------------------'
                                          l = 32 * l
.------------------. .------------------. 
| qponmlkjihgfedcb | | a9876543210----- |
`------------------' `------------------'
                                          Giving -
.------------------. .----------. .-----.
| qponmlkjihgfedcb | | a9876543 | | 210 | 24-bit average with a
`------------------' `----------' `-----'  3-bit binary fraction
My question: you add the readings 8 times not 4. Am I correct?
That is correct.

In case I’m correct, shoul we try to add 4 times only to speed-up the process?
What should be done is to find a balance between averaging to remove noise and the time taken to do that.

One really needs to determine how noisy the results are at various sampling numbers, find how well the averaging is working, and measure the time taken.

Always in attempt to increase the speed: is it worth to rise the freq. to 8 MHz and/or increase the I2cout from slow to fast?
That can come later. The main thing is to get the code working, doing what it's meant to. Optimisations can be done once we have the code working. Then we can then see if optimisations improve things or make them worse.

Speed of execution is not necessarily a thing we need to worry over so don't get fixated on that. In fact, a slower speed may be more advantageous than a faster speed seeing as we want to measure amount of altitude change over time.
 

hippy

Technical Support
Staff member
Code:
m.average = $100 / SAMPLES * m.average
m.average = l.average / SAMPLES / 256 + m.average
l.average = $100 / SAMPLES * l.average
I did wonder if I had got that right so had to test it on paper and I realised the example given wasn't entirely clear that bits were being put in the right places. I have rewritten that and also shown it does work for 8, 4 and 2 samples, and would presumably work for more.
Code:
          m                   l           8 samples of 24-bit data
.------------------. .------------------.
| -----nmlkjihgfed | | cba9876543210xyz |
`------------------' `------------------'
                                          m = 32 * m
.------------------. .------------------.
| nmlkjihgfed----- | | cba9876543210xyz |
`------------------' `------------------'
                       `-.-'
               .----<----'                m = l / 8 / 256 + m
             .-^-.
.------------------. .------------------.
| nmlkjihgfedcba98 | | cba9876543210xyz |
`------------------' `------------------'
                                          l = 32 * l
.------------------. .------------------. 
| nmlkjihgfedcba98 | | 76543210xyz----- |
`------------------' `------------------'
                                          Giving -
.------------------. .----------. .-----.
| nmlkjihgfedcba98 | | 76543210 | | xyz | 24-bit average with a
`------------------' `----------' `-----'  3-bit binary fraction
Code:
          m                   l           4 samples of 24-bit data
.------------------. .------------------.
| ------nmlkjihgfe | | dcba9876543210xy |
`------------------' `------------------'
                                          m = 64 * m
.------------------. .------------------.
| nmlkjihgfe------ | | dcba9876543210xy |
`------------------' `------------------'
                       `--.-'
               .----<-----'               m = l / 4 / 256 + m
            .--^-.
.------------------. .------------------.
| nmlkjihgfedcba98 | | dcba9876543210xy |
`------------------' `------------------'
                                          l = 64 * l
.------------------. .------------------. 
| nmlkjihgfedcba98 | | 76543210xy------ |
`------------------' `------------------'
                                          Giving -
.------------------. .----------. .-----.
| nmlkjihgfedcba98 | | 76543210 | | xy  | 24-bit average with a
`------------------' `----------' `-----'  2-bit binary fraction
Code:
          m                   l           2 samples of 24-bit data
.------------------. .------------------.
| -------nmlkjihgf | | edcba9876543210x |
`------------------' `------------------'
                                          m = 128 * m
.------------------. .------------------.
| nmlkjihgf------- | | edcba9876543210x |
`------------------' `------------------'
                       `--.--'
              .-----<-----'              m = l / 2 / 256 + m
           .--^--.
.------------------. .------------------.
| nmlkjihgfedcba98 | | edcba9876543210x |
`------------------' `------------------'
                                          l = 128 * l
.------------------. .------------------. 
| nmlkjihgfedcba98 | | 76543210x------- |
`------------------' `------------------'
                                          Giving -
.------------------. .----------. .-----.
| nmlkjihgfedcba98 | | 76543210 | | x   | 24-bit average with a
`------------------' `----------' `-----'  1-bit binary fraction
 

Benjie

Senior Member
Hippy, here is the sertxd of your post #92.
The top output are taken at an interval of 10 seconds while the unit was "warmed-up" by 10 minutes.
the bottom reading are also taken at 10 second interval but 4 minutes after the top ones.
I do not understand the continuous drift.
Can the sertxd modified to show actual average in full decimal form?
I assembled the project in the final physical arrangement, see photo.
 

Attachments

hippy

Technical Support
Staff member
Three of the four averaged numbers look pretty consistent ...

864D4C = 8801612 decimal
864D4E = 8801614
864D4E = 8801614
864E0C = 8801804

It should be possible to print the average numbers as a decimal value, but would have to find the algorithm for that. Given it's just for testing and static, it's easier to ignore the msb -

w0 = m.lsb * 256 + l.msb
SerTxd( # w0 )

That should give ...

864D4E = 19790 decimal
864D4E = 19790
864E0C = 19980
864D4C = 19788
 

Benjie

Senior Member
Hippy, I run your code of post #92 disabling the #define USE_SERTXD but adding just one sertxd line to understand the averages after the "; Find the average" section.
When you look at the results you notice that the l.average is useless. The m.average is quite stable and change by two digits when moving the sensor up or down by some 80 cm. I think that this is the best we can get......not the maximum but workable.
The conditions were:
stabilized supply voltage at +5.00V
sensor warmed-up for 20 min.
sensor not moving
sensor kept in the dark
constant ambient temperature

The change of m.average between the two set of records indicates that despite all stabilizations the sensor is drifting as recorded in previous tests.
 

Attachments

hippy

Technical Support
Staff member
When you look at the results you notice that the l.average is useless.
It's not. It's just that you are likely printing l.average as a word and assuming its bit 0 has a 1 value. It doesn't. Its bit 8 has a 1 value, its bit 0 is a 1/256th value.

The integer 24-bit average value, as binary %xwvutsrqponmlkjihgfedcba, gets stored in the m.average and l.average words as below -
Code:
       m.average               l.average
.---------------------. .---------------------.
| xwvutsrq | ponmlkji | | hgfedcba | -------- |
`---------------------' `---------------------'
  m.avg.msb  m.avg.lsb    l.avg.msb  l.avg.lsb
Thus the 16-bit lsb's of the average are held in m.average.msb and l.average.lsb, not in l.average

It would help if you indicated exactly what code you are using to produce the results you are getting then it's easier to tell what it is you are showing, easier to tell what those numbers actually represent.

It would be even better to use the code suggested in Post #111, slightly corrected because I missed the .average out ...

w0 = m.average.lsb * 256 + l.average.msb
SerTxd( # w0 )

... to print the average as a decimal. Otherwise you are probably going to keep confusing yourself.
 

hippy

Technical Support
Staff member
Use this code to show the 24-bit hexadecimal average and the 16-bit decimal average -
Code:
      ; Show the 24-bit hex averages
      SerTxd( "Avg", TAB, "  " )
      w0 = m.average     : Gosub HexWord
      b0 = l.average.msb : Gosub HexByte
      ; Show the 16-bit decimal average
      b1 = m.average.lsb
      b0 = l.average.msb
      SerTxd( TAB, #w0, CR,LF )
 

Benjie

Senior Member
Below is the code I used to get the first 3 columns of the result list.
In bold-italic the added sertxd line to your code. The last two columns show the l.average instead of l.average.msb and l.average.lsb.
Code:
#Picaxe 08M2
#Terminal 4800
#No_Data

; Comment the line below to disable SERTXD output
#Define USE_SERTXD

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 h.byte        = b10
Symbol m.byte        = b11
Symbol l.byte        = b12

Symbol counter       = b13

Symbol SAMPLES       = 8

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

PowerOnReset:

  HI2cSetup I2CMASTER, %11101110, I2CSLOW, I2CBYTE
  HI2cOut ( CMD_RESET)
  Pause 10

MainLoop:

  Do
    h.average = 0
    m.average = 0
    l.average = 0
    For counter = 1 To SAMPLES
      HI2cOut ( CMD_D1_4096 )
      Pause 10
      HI2cOut ( CMD_ADC )
      Pause 10
      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
      '#IfDef USE_SERTXD
        'SerTxd( #counter, TAB, "  " )
        b0 = h.byte : Gosub HexByte
        b0 = m.byte : Gosub HexByte
        b0 = l.byte : Gosub HexByte
        'SerTxd( CR, LF )
      '#EndIf
    Next
#rem
    #IfDef USE_SERTXD
      ; Show the raw averages
      SerTxd( "h", TAB )
      w0 = h.average : Gosub HexWord
      SerTxd( CR,LF, "m", TAB, "  " )
      w0 = m.average : Gosub HexWord
      SerTxd( CR,LF, "l", TAB, "    " )
      w0 = l.average : Gosub HexWord
      SerTxd( CR,LF )
    #EndIf
    #endrem

    ; 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
 
    '#IfDef USE_SERTXD
      ; show the sum
      'SerTxd( "Sum", TAB )
      w0 = m.average : Gosub HexWord
      w0 = l.average : Gosub HexWord
      'SerTxd( CR,LF )
    '#EndIf

    ; Find the average
    m.average = $100 / SAMPLES * m.average
    m.average = l.average / SAMPLES / 256 + m.average 
    l.average = $100 / SAMPLES * l.average 
sertxd(#m.average,tab,#l.average.msb,tab,#l.average.lsb,cr,lf)
    #IfDef USE_SERTXD
      ; Show the averages
      SerTxd( "Avg", TAB, "  " )
      w0 = m.average     : Gosub HexWord
      b0 = l.average.msb : Gosub HexByte
      SerTxd( CR,LF )
    #EndIf
    
    '#IfDef USE_SERTXD
      'SerTxd( "===", TAB, "========", CR,LF )
    '#EndIf

    Pause 1000
  Loop

HexWord:
  b2 = b1 / 16 : Gosub Nibble
  b2 = b1      : Gosub Nibble
HexByte:
  b2 = b0 / 16 : Gosub Nibble
  b2 = b0
Nibble:
  b2 = b2 & $0F + "0"
  If b2 > "9" Then : b2 = b2 + 7 : End If
  SerTxd( b2 )
  Return
 

Benjie

Senior Member
The result applying your code of post #114 is joined.
Increasing the sample from 8 to 16 we may achieve the wanted result.
 

Attachments

hippy

Technical Support
Staff member
The result applying your code of post #114 is joined.
Those results do not make sense ...
Code:
      hex    dec
Avg 46987 289159
The hex values are all 5 digit when they should be six using the code in post #114, and likewise your decimal values are 6 digits when they can at most be 5 digits. And not a single A-F digit in any value doesn't seem likely.

However you are reporting the results you don't seem to be using the code in Post #114.

It would also be better if you just copy and pasted what appears in the editor, put them within [code]..[/code] tags when posting, rather than posting an image of the results. Then your results can be copy and pasted into other programs to analyse what results you have rather than having to laboriously copy every result by hand.

Increasing the sample from 8 to 16 we may achieve the wanted result.
I would suggest going straight to "Symbol SAMPLE = 128" which is the maximum number of samples the current code can handle.

If that doesn't provide consistent averages when the sensor is static then it has to be presumed that self-heating effects are coming into play and it will be necessary to read the temperature and compensate for that.
 
Last edited:

Benjie

Senior Member
Sorry Hippy, I made some confusion.
The correct result with 8 samples is the first.
The second (assuming I made the correct code changes, pls verify) is for 16 samples. I converted to decimal only the first and the last record and it sound quite good if we exclude the last decimal digit.
Code:
#Picaxe 08M2
#Terminal 4800
#No_Data

; Comment the line below to disable SERTXD output
#Define USE_SERTXD

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 h.byte        = b10
Symbol m.byte        = b11
Symbol l.byte        = b12

Symbol counter       = b13

Symbol SAMPLES       = 16

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

PowerOnReset:

  HI2cSetup I2CMASTER, %11101110, I2CSLOW, I2CBYTE
  HI2cOut ( CMD_RESET)
  Pause 10

MainLoop:

  Do
    h.average = 0
    m.average = 0
    l.average = 0
    For counter = 1 To SAMPLES
      HI2cOut ( CMD_D1_4096 )
      Pause 10
      HI2cOut ( CMD_ADC )
      Pause 10
      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 


      ; Show the averages
      SerTxd( "Avg", TAB, "  " )
      w0 = m.average     : Gosub HexWord
      b0 = l.average.msb : Gosub HexByte
      ; Show the 16-bit decimal average
      b1 = m.average.lsb
      b0 = l.average.msb
      SerTxd( TAB, #w0, CR,LF )

    Pause 1000
  Loop

HexWord:
  b2 = b1 / 16 : Gosub Nibble
  b2 = b1      : Gosub Nibble
HexByte:
  b2 = b0 / 16 : Gosub Nibble
  b2 = b0
Nibble:
  b2 = b2 & $0F + "0"
  If b2 > "9" Then : b2 = b2 + 7 : End If
  SerTxd( b2 )
  Return
 

Attachments

hippy

Technical Support
Staff member
The correct result with 8 samples is the first.
The second (assuming I made the correct code changes, pls verify) is for 16 samples.
It seems rather unlikely that the average readings in the first list ( using 8 samples ) would be exactly the same in the second list ( using 16 samples ).

I converted to decimal only the first and the last record and it sound quite good if we exclude the last decimal digit.
Why not simply provide the results as reported by the program ?

And please provide the results as copy and pasted text rather than as images. It makes it far more difficult to see and understand what's going on the way you are doing it.

Also, please change the reporting code to -
Code:
    ; Show the 24-bit hex averages
    SerTxd( "Avg(", #SAMPLES, ")", TAB )
    w0 = m.average     : Gosub HexWord
    b0 = l.average.msb : Gosub HexByte
    ; Show the 16-bit decimal average
    b1 = m.average.lsb
    b0 = l.average.msb
    SerTxd( TAB, #w0, CR,LF )
it sound quite good if we exclude the last decimal digit.
I have no idea given we have only limited data and it's not entirely clear if what you are reporting reflects what you say it does.

One thing which seems clear is that the static reading has a rising trend over time. That is presumably a result of self-heating.
 

Benjie

Senior Member
Copied and pasted the code and here the result after 25 min of warm-up. Pause between loops is 100.

Avg(16) 85A91B 43291
Avg(16) 85A929 43305
Avg(16) 85A930 43312
Avg(16) 85A935 43317
Avg(16) 85A909 43273
Avg(16) 85A8F8 43256
Avg(16) 85A8E5 43237
Avg(16) 85A8E4 43236
Avg(16) 85A8B7 43191
Avg(16) 85A8A1 43169
Avg(16) 85A89C 43164
Avg(16) 85A8A2 43170
Avg(16) 85A8A1 43169
Avg(16) 85A893 43155
Avg(16) 85A8AE 43182
Avg(16) 85A8C4 43204
Avg(16) 85A8B5 43189
Avg(16) 85A8C6 43206
Avg(16) 85A8C3 43203
Avg(16) 85A8AD 43181
 
Top