Digitaler Luftdrucksensor mit I²C Schnittstelle (MPL115A2)

Durch die neuste [tippy title="MEMS"]micro-electro-mechanical system[/tippy]-Technologie sind nun auch endlich bezahlbare Luftdrucksensoren zu bekommen.

Für gerade mal 1,90€ erhält man einen recht genauen und günstigen Luftdrucksensor.

Der Messbereich geht von 50kPa-115kPa, also ideal für kleine Wetterstationen oder als Höhenmesser.

Durch den integrierten Temperatursensor und den fest einprogrammierten Polynom-Koeffizienten lässt sich über einen entsprechenden Algorithmus der Luftdruck inkl. Temperaturkompensation ausgeben.

Der Aufbau ist “dank” LGA wieder etwas frickelig, aber da es nur 8-Pads sind lässt sich schnell mit etwas Lackdraht und einer ruhigen Hand ein “Dead-Bug” aufbauen, zudem fälltder Pitch mit 1,25mm recht grob aus:

Auslesen des Sensors

Das Auslesen des Sensor gestaltet sich recht einfach. Die 7-Bit I²C-Adresse des Sensors lautet “0×60″. Unter Verwendung der Library von Peter Fleury muss man darauf achten, dass die Adresse in 8-Bit angegeben wird. Dementsprechend lautet der Aufruf für die Adressierung:
i2c_start(0xC0);

Bevor man den tatsächlichen Luftdruck erhält muss man zunächst den “RAW-Wert” durch den Kompensationsalgorithmus jagen. Hierfür liest man zunächst die im MPL115A2 hinterlegten Kompensations-Koeffizienten aus:

[sourcecode language="cpp"]int16_t  coeff[6];

/* Read compensation registers */
i2c_start(0xC0+I2C_WRITE);
i2c_write(0×04); //Coeff registers
i2c_start(0xC0+I2C_READ);

for(i = 0; i < 6; i++){
coeff[i] = i2c_readAck() << 8;
if(i < 5)
coeff[i] |= i2c_readAck() & 0x00FF;
else
coeff[i] |= i2c_readNak() & 0x00FF;
}
i2c_stop();
[/sourcecode]

Anschließen liest man den Temperaturwert und den Druck aus dem Sensor aus und übergibt diese Parameter an den Kompensations-Algorithmus:

[sourcecode language="cpp"]
uint16_t pressure;

i2c_start(0xC0+I2C_WRITE);
i2c_write(0×12); //Start Temp. and Pressure conversion

i2c_write(val); //Dummy Byte, this is necessary!
i2c_stop();

_delay_ms(5); //Wait at least 3ms for conversion

i2c_start(0xC0+I2C_WRITE);
i2c_write(0×00); //Pressure Register High-Byte
i2c_start(0xC0+I2C_READ);
pressure = i2c_readAck() << 8; //Read High-Byte
pressure |= i2c_readNak(); //Read Low-Byte
i2c_stop();
pressure = pressure >> 6; //Shift to right for 10 Bit Value
[/sourcecode]

Probleme/Ungenauigkeiten

Was mir wärend der Arbeit mit dem Sensor aufgefallen ist, und was auch Freescale selbst “zugegeben” hat, ist die “Ungenauigkeit” des integrierten Temperatursensors.

Laut Datenblatt ist der Temperaturwert bei 25°C “472″ bei -5.35 Counts/°C. Ich kann zwar nicht sagen ob es bei allen Sensoren so ist, aber bei mir beträgt der RAW-Wert der Temperatur “530″ bei 25°C. Dementsprechend wird nach den Algorithmus laut Datenblatt ein Temperaturwert erzeugt, der 1o° unter dem tatsächlichen Wert liegt. Wenn man diesen “Offset” entsprechen anpasst, scheint es aber hinzukommen.

Laut Freescale ist der interne Temperatursensor auch nicht dafür gedacht eine absolute Temperatur auszugeben, sondern lediglich dafür integriert um die Temperaturabhängigkeit des Sensors zu kompensieren. Die neue/erweiterte Revision des Sensors (MPL3115A) wird über einen genauen Temperaturwert verfügen. Für eure Designs rate ich also eher dazu einen separaten Temperatur-Sensor zu verbauen, was ja preislich kaum ein Problem darstellt.

Berechnung des kompensierten Luftdrucks

Um den temperatur-kompensierten Luftdruck zu erhalten gibt es von Freescale eine Application-Note (AN3785), welche den Algorithmus beschreibt. Jedoch ist in der AN ein Fehler (welcher vermutlich nicht bei allen C-Compilern auffällt).

Nachdem der Druck und die Temperatur ausgelesen wurden, werden diese Werte in das Polynom eingesetzt. Dabei ist in dem von Freescale angegebenen Algorithmus ein kleiner Fehler bei einer Schiebeoperation. Die Zeile

siPcomp = ((S16)lt3>>13);

Müsste nach C99-Standart lauten:

siPcomp = ((S16)(lt3>>13));

Daraus erhält man dann den kompensierten Luftdruck in der aktuellen höhe. Gängig ist, dass bei Wetterstationen der Luftdruck auf Normal-Null angegeben wird. Dementsprechen muss der Luftdruck entsprechend auf NN umgerechnet werden.

In Vereinfachter Form beträgt der Luftdruck bei NN etwa:

p_abs = p0 * e^(-h/7990m)

Die absolute Höhe des Standortes bekommt man z.B über Google-Maps raus. Mein Standort liegt z.B. 14m über NN. Beideutet:

P0 = 997 hPa / e^(-14/7990m) = 997 hPa / 0,99825 = 998,7 hPa

Der Sensor hat laut Datenblatt eine Genauigkeit von ±1 kPa (also ±10 hPa). Wie ich anhand einer lokalen Wetterstation (http://www.ach-du-schan.de) sehen konnte, zeigt mein Sensor auch ziemlich genau 10 hPa zu wenig an. Diesen Offset habe ich einfach auf den kompensieren Wert addiert, was in einem relativ genauem Wert resultiert (1008 hPa).

Links

MPL115A Produktseite

Dieser Beitrag wurde unter Basteleien abgelegt und mit , , , , , , , , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Hinterlasse eine Antwort