HP206C Temperature readings very wrong when temperature below 0

Have the high accuracy barometer sensor set up and working on my raspberry pi 3. Using the hp206c.py python scripts from GitHub no problem until the temperatures went below 0. The temperature now reads 42949672.62.

Can’t figure out why negative temperature values cause this.

Any ideas?

2 Likes

Alcedema,

I had a boss from many years ago who would always walk around telling everyone that “The Devil’s in the Details”.  :wink:

Unfortunately, there are very few details here, and since none of us have a degree in mind-reading, (:wink:), you’ll have to fill us in.

For example:

  1. What “high accuracy barometer sensor” are you talking about?  Who made it?  Where did you buy it?  How old is it?

    • A link to the sensor’s site and/or datasheets and/or both would be very helpful.
    • Even if you provide the name/model number of the sensor, people aren’t going to go searching for it - for one thing, they may not see the same things you found.  For these reasons, it’s essential that you tell us exactly what you’re doing and give us links to the same information you are using.
       
  2. Exactly HOW is this sensor “set up and working on my raspberry pi 3”?  How is it connected to the Pi?  Directly, or through a HAT like the Grove-Pi, Pivot-Pi, or via a GoPiGo robot?

  3. What operating system software are you using on the Pi?  Exactly what did you do to configure it to be able to use the sensor?  If you downloaded special software and/or drivers from the manufacturer’s site, please tell us which software and/or drivers and please give us a link to the site you downloaded them from.

  4. Please tell us, in detail, exactly what happened  to cause the problem.  Units are important as 0° Celsius and 0° Fahrenheit are two completely different temperatures!

    • For example:  Did it get wet or snowed on, (or condensation on it).
    • Likewise, if you can do something to make the problem go away, what did you do?
       
  5. What additional research have you done to solve the problem yourself.  What have you found?  What have you already tried?

Everyone here understands that you may not wish to start your very first posting here with a “wall of words” that, (you think), will bore everyone to tears.

Nothing could be further from the truth.  A detailed report of what the problem is and what you’ve done to try to solve it on your own tells everyone here that you’re serious and are willing to do your share of the work to solve the problem.

==================

A little secret:
What REALLY annoys people on forums like these aren’t the people with the “walls of words” who tell us what happened and what they did to fix it, but rather those who write things that sound like:  “Duh. . . it’s broke.  Fix it!” - and who sound like they expect everyone else to do all the work while they sit back and drink beer. :man_facepalming:

This is not to say that YOU are doing this.  I mention this as a bit of guidance going forward as there are any number of people on forums like this who have gotten so many “It don’t work, now fix it!” types of posts that, if the post lacks sufficient detail, they won’t even bother to answer.

Just remember my old boss, walking around drinking his huge mugs of triple-brewed, extra-strong espresso coffee  :exploding_head: , telling everyone that “The Devil’s In The Details!”

Thanks!

1 Like

or BrickPi since you tagged Lego Mindstorm correct?

1 Like

The temperature calculation:

t_raw = bus.read_i2c_block_data(self.address, self.HP20X_READ_T, 3)
		t=t_raw[0]<<16|t_raw[1]<<8|t_raw[2]
		if t&0x800000:
			t|=0xff000000;
		return t/100.0

It appears it reads three bytes, converts to a 24 bit value, then if the MSB is set (meaning the number is negative), it extends the negative value to be a four byte number, and finally returns the value divided by 100.

This is the datasheet:

Someone else will have to carry on - this is the limit for me.

2 Likes

The question, as i understood it, is that after the sensor was placed in a sub-freezing environment, the values went all to hell-and-gone.

I did not understand the question as being more like this:
+5, +4, +3, +2, +1, 0, 42878653837, 4762398476, (etc)

I understood it to be more like:
(falling temperatures)
+5, +4, +3, +2, +1, 0, (bizarre values)

(rising temperatures afterwards)
[all temperatures are bizarre values, and remain bizarre values, since the time the sensor went below 0°]

@alcedema will have to add some substance to his question so that it can be answered properly.

4294967262 (before division by 100) is 0xFFFFFFDE which might be -0.34 (after division by 100) in signed-32 bit, but…

That sensor has more configuration parameters than fit on one page - interpreting the meaning of value returned depends on a lot more than just converting a signed-24 bit value as a signed 32-bit value.

2 Likes

Yep.

My calculator returns “-34”, but we don’t know if the number has been sign-extended since read or not.

We need better data from Alcedema.

We need to know what’s happening, what he’s doing, how he’s doing it, and exactly what data he’s getting back.

1 Like

Or that may be the value it returns when the temperature is “out of limits” set in the configuration.

@alcedema is going to have to study that sensor datasheet, study that program, and work out the meaning of that value.

This was the function that concerned me too (for me, from /root/GrovePi/Software/Python/grove_barometer_sensors/high_accuracy_hp206c_barometer/hp206c.py from git repo)

Apologies all, was late when I started this post. I’m using the Grove High Accuracy Barometer via I2C ( Grove - Barometer (High-Accuracy)– The Pi Hut ) on Raspberry PI OS (Bullseye). Python 3 version Python 3.9.2.

I am reading the temperature from the device every ~ 20 seconds and storing it in influxdb. Whenever the temperature becomes negative, the value changes to a positive of a much higher magnitude, as below…

1638479418957199000 0.21
1638479440429926000 0.2
1638479461807068000 0.16
1638479483277061000 0.13
1638479504686118000 0.11
1638479526094032000 0.11
1638479547565034000 0.08
1638479569038368000 0.12
1638479590447103000 0.12
1638479611918098000 0.11
1638479633389056000 0.06
1638479654990087000 0.03
1638479676431870000 0
1638479697805824000 42949672.92
1638479719214127000 42949672.89
1638479740589986000 42949672.86
1638479761965052000 42949672.85
1638479783693826000 42949672.83
1638479805069844000 42949672.8

...
1638482357645935000 42949672.6
1638482379021583000 42949672.6
1638482400429060000 42949672.61
1638482421869600000 42949672.6
1638482443277139000 42949672.59
1638485801038073000 0.01
1638485822509844000 0.03
1638487549741826000 0.02
1638487571439682000 0.03
1638487597869905000 0.02

Figuring out that function is unfortunately beyond me…!

1 Like

Don’t give up and you will learn and succeed. Learn how to print those bytes in hex, learn the difference between binary, decimal, integer, signed integer and learn that sensor data sheet to understand what it outputs.

It appears to me you have to understand that function well enough to understand why it does not output a negative temperature when the sensor returns a signed-24 bit integer . You need to learn about handling signed integers in Python.

2 Likes

Ain’t that the truth!

Me, the silly boy that I am, decided to work on updating the “remote camera robot” code that comes with the robot, so that it uses a joystick instead of a mouse.  Should be simple, right?

WRONG!

I found myself taking a “crash”  :wink:  course in not only Python, (which I had, maybe, twenty hours experience with), but also Python web services, browser side web polling and web push, JavaScript, and a few other things that I don’t remember right now - probably selective amnesia.

How did I feel about this?

picnic

Does this answer your question? :wink:

Nope. It’s not always easy, but like my trainer at the fitness club says “No Sweat, No Glory”.

The problem you seem to be experiencing is that the software, for whatever reason, is not handling signed numbers correctly.

For example, in “computer speak” numbers work like this:
If the highest bit is a “1”, than the number is in negative two’s complement form.  (these are signed 32 bit integer numbers)

“0d” = a decimal number and “0x” = a hexadecimal number.

[decimal]  becomes [hexadecimal]
 0d0015            0x00 00 00 FF
 0d0014            0x00 00 00 FE
 0d0013            0x00 00 00 FD

[. . .]

 0d0003            0x00 00 00 03
 0d0002            0x00 00 00 02
 0d0001            0x00 00 00 01
 0d0000            0x00 00 00 00
 0d-0001           0xFF FF FF FF
 0d-0002           0xFF FF FF FE
 0d-0003           0xFF FF FF FD

and so on.

0xFF FF FF FF - after you take the two’s complement - becomes 0x00 00 00 01. Because the highest bit is set, you add a minus sign, therefore it becomes -1.

If it were an unsigned 32 bit integer, it would become 4,294,967,295 - which is obviously not the same as “-1”.

You can see, (by looking at this), that the obvious problem is that Python doesn’t know that the number you’re getting from the sensor is a signed floating-point number.  Instead, it thinks it’s an unsigned integer which gives you the bizarre numbers.

You should also notice that, as the sensor gets colder, that large number gets smaller.

I do not know, (nor do I care), how negative floating point numbers are handled in Python - that’s a whole college course unto itself - and you don’t need to know either.  Python handles that for you behind the scenes.

What you DO have to know is how to tell Python that the number you’re getting from the sensor is a float (floating point) number, and Python will do the rest, converting the numbers into a form that makes sense.

You also need to look at the data sheet so that you can understand the kinds of values that this sensor is giving you.  Once you understand that, you can tell Python how to make sense of it.

Exactly how to do that in your particular case is a challenge you will need to accept for yourself.

Let us know what you discover!

1 Like

Did you by any chance notice no mention of floating point in

1 Like

No! Sorry, but not the case here.

2 Likes

One thing is that Raspberry Pi O/S Bullseye is not supported by the Grove libraries - they’ve changed many things in many ways that break backwards compatibility with a lot of stuff.

Try this again with Raspbian Buster.

There are a number of articles about people like yourself who have tried the Grove-Pi with Bullseye and had nothing but grief and there is a link to Buster in each one.

Viz.:

This may be sufficient to make things work the way they should.

1 Like

Jim, please trust me on this one - we don’t know how they got a ???BrickPi??? running GrovePi software on Bullseye, but it appears to be working just fine with this sensor.

The problem appears to be that the software was not tested with negative Celsius temperatures and perhaps python3, but

Switching to a Buster based OS will just end up back at this same function

Proof:

#!/usr/bin/env python



t_raw = (0xFF, 0xFF, 0xDE)
t=t_raw[0]<<16|t_raw[1]<<8|t_raw[2]
val = t
if t&0x800000:
    print(hex(t))
    t|=0xff000000;
    print(t,hex(t))
    us = (1<<32)
    print(us,hex(us))
    val = -1 * (us - t)
    print(val)

print("temp:", (val/100.0))


$ python3 trytemp.py 
0xffffde
4294967262 0xffffffde
4294967296 0x100000000
-34
temp: -0.34


Look at that, you made me solve it instead of the poster learning something.

3 Likes

I beg to differ, whilst this also helps I have been delving into this head first all day and its amazing what I’ve had to learn, transferable between all languages. Thanks all!

3 Likes

Yes I did, but absent comment from the OP, I wasn’t sure if he understood the difference between the representation of a positive number and a negative number, so I wanted him to understand why the number he was getting, (in hex), ended up being the bizarre number he saw.

. . . and every single word of it is absolutely correct.

However, (in my own both limited and humble opinion), shouldn’t Python handle the type conversion internally?  As you said before in other postings, these things should be “black boxes” - stuff goes in the top, you turn the crank, and answers come out the bottom.

All we, (he), needs to know is.  (Again, my own humble opinion here)

  • What the sensor thinks that number is.
  • How to communicate that to Python, so it can handle it appropriately.

As you mentioned, he’s going to have to spend some time with the datasheet and Python to figure out how to get those two beasties to talk together.

2 Likes

Known limitation of python with two schools of thought on the solution ctypes and pure python

2 Likes

no problem, but it has absolutely nothing to do with floats and especially nothing to do with float representation in Python.

That is the point of my consternation

2 Likes