Measuring barometric pressure with the BMP180 and determining ambient temperature by correlation

Weather stations normally are able to measure the barometric pressure and will give you a weather trend based on the trend of the barometric pressure during the last couple of hours.

To measure the barometric pressure with my Raspberry Pi, I use the Bosch BMP180 pressure sensor. A very good Python library and a tutorial for using the the Bosch BMP180 (which is software compatible to the older BMP085) together with the Raspberry Pi is provided by Adafruit.

Only thing you have to be aware of, if you are going to measure the barometric pressure is, that the sensor will give you absolute values, but since the pressure is also changing over altitude, and you want to be able to compare the values of different location, the barometric pressure normally is normalized to sea level.

To calculate the normalized sea level barometric pressure,  you have to know the altitude above sea level of the place, where you are measuring the barometric pressure. This calculation is included in the Python script at the end of this page. I use it to read and also store the barometric pressure values in a RRDtool database and create graphes, accordingly I do for outside temperature and humidity.

pressure

The BMP180 does not only measure the pressure, it also measures the temperature. First of all, I did not want to use the temperature values from the sensor and so I put it directly inside the case of the Raspberry Pi, so that there are no additional cables around the Raspberry Pi and that the sensor itself is protected from the dust.

But then, I thought it would be nice to have both inside temperatures, the one from the lower floor (from the FRITZ!Dect200) and the one from the upper floor in one diagram, but still, I wanted to keep the sensor inside the case, because of the reasons I’ve mentioned before.

Of course, the temperature readings from the BMP180 are much to high inside the case of the Raspberry Pi. But what also is true, is that the measured temperature is a correlation between the outside ambient temperature and the temperature of the CPU. And the later one, you can also measure easily.

So, you have two known and one unknown variables, only thing left to do now is to find an equation, so can use the known variables to calculate the value of the unknown variable. At least a reasonable approximation should be possible. Since there are different add-on boards available for the Raspberry Pi which also contain temperature sensors, I was convinced that someone should have faced the same situation already. Fortunately, this was the case and a similar project found a very good approximation.

ambient = temp - ((cpu_temp - temp)/FACTOR)

For finally using the approximation, you have to measure the ambient temperature with a additional thermometer, read the current CPU temperature and the temperature from the sensor, and then calculate the value of FACTOR. If you do this multiple times and calculate an average, you should get a quite good value that should provide a satisfying approximation. From my experience, the readings should be around +/- 0.5°C around the real temperature.

cputemp

insidetemp2

You can clearly see the correlation between the CPU temperature and the calculated ambient temperature. Unfortunately, the CPU temperature is quite noisy and this noise also appears on the ambient temperature. Of course, you could do a simple low pass filtering of the results, but then you have to measure the temperatures quite often to avoid a longer delay between the last reading and the present value. I decided to leave it without filtering and measure the temperatures only every five minutes.

Below, you can find my Python script, which includes the reading from the BMP180 (or the older BMP085), the normalizing of the pressure to sea level, the temperature correction and the writing to the database.

#!/usr/bin/python

import os
import rrdtool
import Adafruit_BMP.BMP085 as BMP085

sensor = BMP085.BMP085(mode=BMP085.BMP085_ULTRAHIGHRES)

try:
	# Read the current temperature
	temp = sensor.read_temperature()
	# Read the current barometric pressure level
	pressure = sensor.read_pressure()
except:
	sys.exit(-1)

# Calculate the ambient temperature
cpu_temp = os.popen('vcgencmd measure_temp').readline()
cpu_temp = cpu_temp.replace("temp=","")
cpu_temp = cpu_temp.replace("'C\n","")
cpu = float(cpu_temp)
ambient = temp-((cpu-temp)/1.425)

# Set the altitude of your current location in meter
altitude = 229
psea = pressure / pow(1.0 - altitude/44330.0, 5.255)
psea = psea/100.0

# insert data into round-robin-database
data = "N:%.2f:%.2f" % (ambient, psea)
rrdtool.update("%s/pressure.rrd" % (os.path.dirname(os.path.abspath(__file__))), data)