Barometer

Variante 1:

Bei dieser Variante kommt der Drucksensor BMP085 zum Einsatz. Achtung: Dieser wird mit 3.3V betrieben! Also Vorsicht beim Verbinden mit dem Arduino.

Experiment mit dem Drucksensor:

Mit dem Drucksensor kann zum Beispiel der absolute Temperaturnullpunkt (T = 0 K = – 273 °C) bestimmt werden. Dabei bedient man sich des Gasgesetzes p · V = n · k · T (k … Boltzmannkonstante, n … Teilchenanzahl, p … Druck, V … Volumen, T … Temperatur).

Im Falle einer isochoren Zustandsänderung (Volumen V = konstant), reduziert sich das Gasgesetz zu p/T = konstant.

Misst man nun den Druck p in Abhängigkeit von der Temperatur T und überträgt diese in ein Diagramm, so muss man zur Ermittlung des absoluten Temperaturnullpunkts lediglich die Gerade extrapolieren. An jener Stelle mit p = 0 Pa befindet sich dann der absolute Temperaturnullpunkt!


Arduino-Code:

// BMP085_output
// by Filipe Vieira
// Simple example of library usage with almost every BMP085 and lib features being used.

#include <Wire.h>
#include <BMP085.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display. ACHTUNG: Adresse kann auch 0x3F sein !!!


// Anschlüsse:
// GND - GND
// VCC - 5V
// SDA - ANALOG Pin 4
// SCL - ANALOG pin 5



BMP085 dps = BMP085();
long Temperature = 0, Pressure = 0, Altitude = 0;


// =======================
// ======== SETUP ========
// =======================

void setup(void)
  {
   Serial.begin(9600);
   Wire.begin();
   delay(1000);
	
   dps.init();   
  
   showall();
  
   Serial.println("Registers dump");
   Serial.println("==========================================================");
   dumpRegisters();
   Serial.println("Calibration data");
   Serial.println("==========================================================");
   dps.dumpCalData();
  
   delay(1000);
  
   lcd.begin();                      // initialize the lcd

   // Print a message to the LCD.
   lcd.backlight();
   lcd.setCursor(0,0);
   lcd.print("T =");
   lcd.setCursor(0,1);
   lcd.print("p =");
   lcd.setCursor(13,0);
   lcd.print("C");
   lcd.setCursor(13,1);
   lcd.print("Pa");  
  }
 

// ===============================
// ======== HAUPTSCHLEIFE ========
// ===============================

void loop(void)
   {
    dps.getTemperature(&Temperature); 
    dps.getPressure(&Pressure);
    dps.getAltitude(&Altitude);
  
    Serial.print("Temp(C):");
    Serial.print(Temperature);
  
    /*
    Serial.print("  Alt(m):");
    Serial.print(Altitude/100);
    */
  
    Serial.print("Pressure(Pa):");
    Serial.println(Pressure);
  
    // Ausgabe auf dem LCD-Schirm
    // ==========================

    lcd.setCursor(4,0);
    lcd.print("      ");
    lcd.setCursor(4,0);
    lcd.print(Temperature);
    
    lcd.setCursor(4,1);
    lcd.print("      ");
    lcd.setCursor(4,1);
    lcd.print(Pressure);
  
    delay(200);
   }



void showall(void)
   { 
    Serial.println("Current BMP085 settings");
    Serial.println("==========================================================");
    Serial.print("device address                  = 0x");
    Serial.println(dps.getDevAddr(), HEX);
    Serial.print("Mode                            = ");
    switch (dps.getMode())
       {
        case MODE_ULTRA_LOW_POWER: 
           Serial.println("MODE_ULTRA_LOW_POWER");
        break;
        case MODE_STANDARD: 
           Serial.println("MODE_STANDARD");
        break;    
        case MODE_HIGHRES: 
           Serial.println("MODE_HIGHRES");
        break;    
        case MODE_ULTRA_HIGHRES:     
           Serial.println("MODE_ULTRA_HIGHRES");
        break; 
       }  
   }


void dumpRegisters()
   {
    byte ValidRegisterAddr[]={0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,0xF6,0xF7,0xF8,0xF9}; 
    byte _b, i, totregisters = sizeof(ValidRegisterAddr);
    
    Serial.println("---dump start---");
    Serial.println("Register address|Register data");
    Serial.println("Reg.address(hex,dec) Reg.data(bin,hex,dec)");
  
    for (i=0;i<totregisters;i++)
       {    
        Serial.print("0x");
        Serial.print(ValidRegisterAddr[i], HEX);
        Serial.print(",");
        Serial.print(ValidRegisterAddr[i], DEC);
        Serial.print(",");
    
        dps.readmem(ValidRegisterAddr[i], 1, &_b);
    
        Serial.print("b");
        print_bits(_b);
        Serial.print(",0x");
        Serial.print(_b,HEX);
        Serial.print(",");
        Serial.println(_b,DEC);  
       }
    Serial.println("---dump end---");
   }

void print_bits(byte val)
   {
    int i;
  
    for(i=7; i>=0; i--) 
       Serial.print(val >> i & 1, BIN);
   }

/* void print_unit16(uint16_t val){
  int i;
  for(i=15; i>=0; i--) 
    Serial.print(val >> i & 1, BIN);
} 
*/

 


Variante 2:

Die zweite Variante verwendet den Drucksensor SPX3058D. Im Gegensatz zum BMP085 handelt es sich hierbei um einen Differenzdrucksensor. Liegt auf beiden Eingängen des SPX3058D derselbe Druck an, so zeigt der Sensor p = 0 Pa an. Er misst also den Differenzdruck der beiden Eingänge.

 

 


Arduino-Code:

// ================================================================
// Programm zur Messung des Differenzdrucks mit dem Sensor SPX3058D
// ================================================================

#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // ACHTUNG: set the LCD address to 0x20 or 0x27 for a 16 chars and 2 line display!!!

// Anschlüsse Display:
// ===================
// GND - GND
// VCC - 5V
// SDA - ANALOG Pin 4
// SCL - ANALOG Pin 5

// Anschlüsse Drucksensor:
// =======================
// GND - GND
// VCC - 5V
// vOutPlus - ANALOG PIN 0
// vOutMinus - ANALOG PIN 1


float vOutMinus, vOutPlus;
float x, offset;
float pressure_mbar, pressure_kPa;
int i;


// =========================
// ======== SETUP ==========
// =========================

void setup()
   {
    Serial.begin(9600);
    
    // Kalibrierung des Sensors auf 0
    // ==============================
    
    delay(100);
    
    vOutPlus = 0.0;
    vOutMinus = 0.0;    
    
    for (i = 1; i <= 5; i++)
       {
        vOutPlus = vOutPlus + analogRead(0);
        vOutMinus = vOutMinus + analogRead(1);
       }
       
    vOutPlus = vOutPlus / 5.0;
    vOutMinus = vOutMinus / 5.0;
    
    offset = vOutPlus - vOutMinus;
    
    
    lcd.init();             // initialize the lcd

    // Print a message to the LCD.
    lcd.backlight();
    lcd.setCursor(0,0);
    lcd.print("Druckdifferenz");
    lcd.setCursor(12,1);
    lcd.print("mbar");
        
   }


// =================================
// ======== HAUPTSCHLEIFE ==========
// =================================

void loop()
   {
    analogReference(DEFAULT);
    delay(20);   // wait, there could be a capacitor at AVref.

    vOutPlus = 0.0;
    vOutMinus = 0.0;    
    
    for (i = 1; i <= 5; i++)
       {
        vOutPlus = vOutPlus + analogRead(0);
        vOutMinus = vOutMinus + analogRead(1);
       }
       
    vOutPlus = vOutPlus / 5.0;
    vOutMinus = vOutMinus / 5.0;
    
    // Calculation the pressure for 10% accuracy.
    // Valid for -500 mbar to +600 mbar.

    // x = (vOutMinus - vOutPlus) + 5; // difference and offset
    
    x = (vOutMinus - vOutPlus) + offset; // difference and offset

    // Ausgleichsfunktion für den Sensor SPX3058D 
    // ==========================================
    
    if (x > 0)
       pressure_mbar = (x * 5.0) + (x * x / 13.0); 
    else
       pressure_mbar = (x * 4.0) - (x * x / 24.0);

    pressure_kPa = pressure_mbar / 10.0;

    // Ausgabe am seriellen Monitor:

    Serial.print (F("Pressure = "));
    Serial.print(pressure_mbar,2);
    Serial.println(F(" mbar"));  
    
    // Ausgabe am Display:
    
    lcd.setCursor(0,1);
    lcd.print("           ");
        
    if (pressure_mbar >= 0)
       {
        lcd.setCursor(0,1);
        lcd.print(pressure_mbar,2);
       }
    else
       {
        lcd.setCursor(0,1);
        lcd.print("-");
        lcd.setCursor(1,1);
        lcd.print(-pressure_mbar,2); 
       }
       
    delay(100);
  
   }