Falsche Daten von BMP180

Hallo zusammen, ich mal wieder.

Folgendes Problem beschäftigt mich. Ich habe einen Aufbau mit einem Arduino Nano, einem DHT22 , einem BMP180 und einem kleinen Oled Display.
Der erste Code wirkt noch etwas unaufgeräumt, funktioniert auch einwandfrei
Alle 3 Sekunden wechselt das Display zwischen den Werten und das passt auch so

#include <BMP180I2C.h>



#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

//Temperatursensor
#include "DHT.h"
#define DHTPIN 4     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);

//oled-Display
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C


//Drucksensor
BMP180I2C bmp180(0x77);
float druck;


//Mehr Infos: https://arduino-projekte.webnode.at/meine-libraries/luftdrucksensor-bmp180/

// Define proper RST_PIN if required.
#define RST_PIN -1

SSD1306AsciiWire oled;

int warten = 3000;


//------------------------------------------------------------------------------
void setup() {

  // temperatursensor


  dht.begin();
  Serial.begin(9600);

  //oled Display

  Wire.begin();
  Wire.setClock(400000L);

  //Drucksensor

  //begin() initializes the interface, checks the sensor ID and reads the calibration parameters.
  if (!bmp180.begin())
  {
    Serial.println("begin() failed. check your BMP180 Interface and I2C Address.");
    while (1);
  }

  //reset sensor to default parameters.
  bmp180.resetToDefaults();

  //enable ultra high resolution mode for pressure measurements
  bmp180.setSamplingMode(BMP180MI::MODE_UHR);

  //Mehr Infos: https://arduino-projekte.webnode.at/meine-libraries/luftdrucksensor-bmp180/

#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0

  oled.setFont(Arial14);


}
//------------------------------------------------------------------------------
uint32_t m = micros();

void loop() {
  //start a temperature measurement
  if (!bmp180.measureTemperature())
  {
    Serial.println("could not start temperature measurement, is a measurement already running?");
    return;
  }

  //wait for the measurement to finish. proceed as soon as hasValue() returned true.
  do
  {

  } while (!bmp180.hasValue());

  Serial.print("Temperature: ");
  Serial.print(bmp180.getTemperature());
  Serial.println(" degC");

  //start a pressure measurement. pressure measurements depend on temperature measurement, you should only start a pressure
  //measurement immediately after a temperature measurement.
  if (!bmp180.measurePressure())
  {
    Serial.println("could not start perssure measurement, is a measurement already running?");
    return;
  }

  //wait for the measurement to finish. proceed as soon as hasValue() returned true.
  do
  {
    delay(100);
  } while (!bmp180.hasValue());
  druck = (bmp180.getPressure() / 100);
  Serial.print("Pressure: ");
  Serial.print(bmp180.getPressure() / 100);
  Serial.println(" hPa");


  //Mehr Infos: https://arduino-projekte.webnode.at/meine-libraries/luftdrucksensor-bmp180/



  // Temperaturmessung
  // Wait a few seconds between measurements.


  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  //oled.clear();

  oled.set2X();
  oled.setCursor(0, 0);
  oled.println("Temp:");
  //oled.set2X();
  oled.print(t);
  oled.print(" C");
  delay(warten);
  Serial.println(t);
  oled.clear();
  //oled.set1X();
  oled.setCursor(0, 0);
  oled.println("Hum:");
  //oled.set2X();
  oled.print(h);
  oled.print(" %");
  delay(warten);
  oled.clear();
  oled.setCursor(0, 0);
  oled.println("Press:");
  //oled.set2X();
  oled.print(druck);
  oled.print(" hPa");
  delay(warten);
  oled.clear();
  if (druck > 913)
  {
    oled.println("Hochdruck");
    delay(warten);
    oled.clear();
  }
  else
  {
    oled.println("Tiefdruck");
    delay(warten);
    oled.clear();
  }
}

Jetzt habe ich die Schaltung um einen Taster und einen Pulldownwiderstand (1K) erweitert, um manuell zwischen den Anzeigen zu schalten.
Das funktioniert soweit. Allerdings habe ich zwei Probleme.

  1. Wenn der Arduino einen Reset erfährt, wird auf dem Display erst etwas angezeigt, wenn der Taster gedrückt wird. Ist ja eigentlich auch klar, da die Einzelnen States erst ausgewertet werden, nachdem der Taster gedrückt wurde. Gibt es da eine Möglichkeit, das zu umgehen?
  2. Die Druckanzeige stimmt ist um 60 hPa kleiner als beim vorherigen Sketch. Kann das mit dem Taster zusammenhängen, und wenn ja, wieso?
#include <BMP180I2C.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

//Temperatursensor
#include "DHT.h"
#define DHTPIN 4     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);

//oled-Display
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
SSD1306AsciiWire oled;


//Drucksensor
BMP180I2C bmp180(0x77);
float druck;

//Taster
#define tasterPin 3
#define debounce_delay 15 //Entprellzeit für den Taster in ms
bool led_state, tasterState, tasterState_alt;// Variablendeklaration (global)
uint8_t counter; //Zählt wie oft die Taste gedrückt wurde


// Define proper RST_PIN if required.
#define RST_PIN -1

int warten = 3000;


//------------------------------------------------------------------------------
void setup() {

  // temperatursensor
  dht.begin();
  Serial.begin(9600);

  //oled Display
  Wire.begin();
  Wire.setClock(400000L);

  //Drucksensor
  if (!bmp180.begin())
  {
    Serial.println("begin() failed. check your BMP180 Interface and I2C Address.");
    while (1);
  }

  //reset sensor to default parameters.
  bmp180.resetToDefaults();

  //enable ultra high resolution mode for pressure measurements
  bmp180.setSamplingMode(BMP180MI::MODE_UHR);

//oled.begin
#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0

  oled.setFont(Arial14);
 }
//------------------------------------------------------------------------------


uint32_t m = micros();

void loop() {

  //start a pressure measurement. pressure measurements depend on temperature measurement, you should only start a pressure
  //measurement immediately after a temperature measurement.
  if (!bmp180.measurePressure())
  {
    Serial.println("could not start perssure measurement, is a measurement already running?");
    return;
  }

  //wait for the measurement to finish. proceed as soon as hasValue() returned true.
  do
  {
    delay(100);
  } while (!bmp180.hasValue());
  druck = (bmp180.getPressure() / 100);


  // Temperaturmessung
  // Wait a few seconds between measurements.


  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  oled.set2X();


  //Taster auswerten
  static uint32_t debounce_time;
  if (millis() - debounce_time > debounce_delay)tasterState = digitalRead(tasterPin); //einlesen des Tasters

  if (tasterState != tasterState_alt) // bei Pegelwechsel
  {
    debounce_time = millis();
    oled.clear();
#ifdef DEBUG
    Serial.println(counter);
#endif
    if (!tasterState) //wenn Taster gedrückt
    {
      counter++;
      if (counter < 2 || counter > 3)counter = 1;
    }
    tasterState_alt = tasterState; // state aktualisieren
  }
  if (counter == 1)
  {
    oled.setCursor(0, 0);
    oled.println("Temp:");
    oled.print(t);
    oled.print(" C");
  }
  if (counter == 2)
  {
    oled.setCursor(0, 0);
    oled.println("Hum:");
    oled.print(h);
    oled.print(" %");
  }
  if (counter == 3)
  {
    oled.setCursor(0, 0);
    oled.println("Press:");
    oled.print(druck,1);
    oled.print(" hPa");
  }
}

Ich find den Fehler nicht. Hier noch der Aufbau. die beiden Kabel, welche aus dem Bild gehen sind die Stromversorgung für einen 2. Aufbau.

Dann werte deine States im Setup einmalig aus bzw. gib deiner counter Variable einen Wert > 0 im Setup mit und werte ebenfalls einmalig im Setup deine Sensoren aus.

Danke, darauf hätte ich auch kommen können. Ich hab den tasterState mal gesetzt, aber das kann ja nicht funktionieren.
Jetzt bleibt nur noch das Problem mit den falschen Daten

hier noch der Aufbau

Den I2C-Bus hast du falsch angeschlossen.
Damit das funktioniert, gehört der Bus auf A4 und A5.
Und der Taster und Sensor DHT auf D3 und D4.

Jau danke...verdrahtet war es richtig, nur falsch gezeichnet

Ok, das sieht besser aus. :wink:
Was dein Problem mit den falschen Daten betrifft, liegt vermutlich daran, dass du den Sensor blockierend (for-Schleife) auswertest. Sorry do-while Schleife.
Da ich mit dem BMP180 noch nicht gemacht habe, nur eine Vermutung.

Hab jetzt gerade die beiden Sketches nochmals verglichen. Es gibt da einen Korrekturfaktor mit der Temperatur. Da ich beim 2. Sketch die Temperatur vom Sensor nicht ausgewertet habe hat der natürlich keine Temperatur zum rechnen rsp. er nimmt irgendwas, was halt da ist.
Jetzt stimmts wieder.
So sieht der fertige Sketch aus

#include <BMP180I2C.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

//Temperatursensor
#include "DHT.h"
#define DHTPIN 4     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);

//oled-Display
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
SSD1306AsciiWire oled;


//Drucksensor
BMP180I2C bmp180(0x77);
float druck;

//Taster
#define tasterPin 3
#define debounce_delay 15 //Entprellzeit für den Taster in ms
bool led_state, tasterState, tasterState_alt;// Variablendeklaration (global)
uint8_t counter; //Zählt wie oft die Taste gedrückt wurde


// Define proper RST_PIN if required.
#define RST_PIN -1

int warten = 3000;


//------------------------------------------------------------------------------
void setup() {

  // temperatursensor
  dht.begin();
  Serial.begin(9600);

  //oled Display
  Wire.begin();
  Wire.setClock(400000L);

  //Drucksensor
  if (!bmp180.begin())
  {
    Serial.println("begin() failed. check your BMP180 Interface and I2C Address.");
    while (1);
  }

  //reset sensor to default parameters.
  bmp180.resetToDefaults();

  //enable ultra high resolution mode for pressure measurements
  bmp180.setSamplingMode(BMP180MI::MODE_UHR);

//oled.begin
#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0

  oled.setFont(Arial14);
  counter=1;
 }
//------------------------------------------------------------------------------


uint32_t m = micros();

void loop() {

  //start a temperature measurement
  if (!bmp180.measureTemperature())
  {
    Serial.println("could not start temperature measurement, is a measurement already running?");
    return;
  }

  //wait for the measurement to finish. proceed as soon as hasValue() returned true.
  do
  {

  } while (!bmp180.hasValue());

  Serial.print("Temperature: ");
  Serial.print(bmp180.getTemperature());
  Serial.println(" degC");

  
  
  //start a pressure measurement. pressure measurements depend on temperature measurement, you should only start a pressure
  //measurement immediately after a temperature measurement.
  if (!bmp180.measurePressure())
  {
    Serial.println("could not start perssure measurement, is a measurement already running?");
    return;
  }

  //wait for the measurement to finish. proceed as soon as hasValue() returned true.
  do
  {
    delay(100);
  } while (!bmp180.hasValue());
  druck = (bmp180.getPressure() / 100);


  // Temperaturmessung
  // Wait a few seconds between measurements.


  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  oled.set2X();


  //Taster auswerten
  static uint32_t debounce_time;
  if (millis() - debounce_time > debounce_delay)tasterState = digitalRead(tasterPin); //einlesen des Tasters

  if (tasterState != tasterState_alt) // bei Pegelwechsel
  {
    debounce_time = millis();
#ifdef DEBUG
    Serial.println(counter);
#endif
    if (!tasterState) //wenn Taster gedrückt
    {
      oled.clear();
      counter++;
      if (counter < 2 || counter > 3)counter = 1;
    }
    tasterState_alt = tasterState; // state aktualisieren
  }
  if (counter == 1)
  {
    oled.setCursor(0, 0);
    oled.println("Temp:");
    oled.print(t);
    oled.print(" C");
  }
  if (counter == 2)
  {
    oled.setCursor(0, 0);
    oled.println("Hum:");
    oled.print(h);
    oled.print(" %");
  }
  if (counter == 3)
  {
    oled.setCursor(0, 0);
    oled.println("Press:");
    oled.print(druck,1);
    oled.print(" hPa");
  }
}

Ahhh, ok.
Danke für die Rückmeldung.

Mach das nicht. So.
Du solltest Dir angewöhnen mit 0 anzufangen zu zählen.
Mal als Beispiele:

byte b=255;
b++;
Serial.println(b);

oder:

array elemente[2]={1,2};
Serial.println(elemente[1]);

Und Du selbst merkst doch, das Du mehr vergleichen musst:

-> Wobei <2 auch 1 ist und Du damit den counter zwangsweise bei 1 wieder mit 1 beschreibst.
Auch das:

oder gar später noch mit dem delay(100) da drin ist nicht notwendig und unterbricht den Programmlauf nur unnötg.
Ich denke, da sind noch einige Dinge drin die zu verändern sind...

Solche Hinweise nehme ich dankbar entgegen. Ich stehe ja noch ziemlich weit unten in der Nahrungsleiter....Momentan bin ich froh, dass das dingens erstmal läuft. Und jetzt gehts an die Verbesserung des Codes. Und da helfen solche Anstupser natürlich extrem. Ich werde es die Tage mal noch überarbeiten und schauen, was ich da alles noch verbessern kann.
Besten Dank für den Beitrag.

Das Delay habe ich drinnen, weil im Datenblatt Conversion time mit ca. 75ms angegeben ist

wie könnte ich das besser lösen?

Mit einer Abfrage via if.
Mit while läufst Du ja ewig in der Schleife solange !bmp180.hasValue() wahr ist
Das kannst Du aber auch nutzen und auf wahr testen und dann den Wert übernehmen.
Ungefähr wie folgt:

if (bmp180.hasValue())
{
t=bmp180.temperature();
}

Ich muss mal in den Code schaun, was Du da so machst...

Ich hab mal was angefangen - erstmal nur ganz grob.
Schau mal, ob das was wird und Du das gleiche Ergebnis bekommst.

#include <BMP180I2C.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

//Temperatursensor
#include "DHT.h"
#define DHTPIN 4     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);

//oled-Display
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
SSD1306AsciiWire oled;


//Drucksensor
BMP180I2C bmp180(0x77);
int druck;
int t;
int h;

//Taster
constexpr byte tasterPin {3};
constexpr uint32_t debounce_delay {15}; //Entprellzeit für den Taster in ms
bool led_state, tasterState, tasterState_alt;// Variablendeklaration (global)
uint8_t counter; //Zählt wie oft die Taste gedrückt wurde


// Define proper RST_PIN if required.
constexpr int8_t RST_PIN {-1};


//------------------------------------------------------------------------------
void setup()
{
  // temperatursensor
  dht.begin();
  Serial.begin(9600);
  //oled Display
  Wire.begin();
  Wire.setClock(400000L);
  //Drucksensor
  if (!bmp180.begin())
  {
    Serial.println("begin() failed. check your BMP180 Interface and I2C Address.");
    while (1);
  }
  //reset sensor to default parameters.
  bmp180.resetToDefaults();
  //enable ultra high resolution mode for pressure measurements
  bmp180.setSamplingMode(BMP180MI::MODE_UHR);
  //oled.begin
  if (RST_PIN > 0)
  { oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN); }
  else // RST_PIN >= 0
  { oled.begin(&Adafruit128x64, I2C_ADDRESS); }
  oled.setFont(Arial14);
}


void checkSensor()
{
  static byte measureType = 0;
  switch (measureType)
  {
    case 0:
      //start a temperature measurement
      if (!bmp180.measureTemperature())
      {
        Serial.println("could not start temperature measurement, is a measurement already running?");
        return;
      }
      measureType++;
      break;
    case 1:
      if (bmp180.hasValue())
      {
        t = bmp180.getTemperature() * 10;
        Serial.print("Temperature: ");
        Serial.print(t / 10);
        Serial.print(',');
        Serial.print(t - (t / 10 * 10));
        Serial.println(" degC");
        measureType++;
      }
      break;
    case 2:
      //start a pressure measurement. pressure measurements depend on temperature measurement, you should only start a pressure
      //measurement immediately after a temperature measurement.
      if (!bmp180.measurePressure())
      {
        Serial.println(F("could not start pressure measurement, is a measurement already running?"));
        return;
      }
      measureType++;
      break;
    case 3:
      //wait for the measurement to finish. proceed as soon as hasValue() returned true.
      if (bmp180.hasValue())
      {
        druck = (bmp180.getPressure() / 100);
        measureType++;
      }
      break;
    case 4:
      {
        // Temperaturmessung
        // Wait a few seconds between measurements.
        // Reading temperature or humidity takes about 250 milliseconds!
        // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
        int value = dht.readHumidity();
        if (!isnan(value))
        { h = value; }
        // Read temperature as Celsius (the default)
        value = dht.readTemperature();
        if (!isnan(value))
        { t = value; }
        measureType++;
      }
      break;
    default:
      measureType = 0;
      break;
  }
}

void value2oled()
{
  static byte lastCounter = 255;
  if (lastCounter != counter)
  {
    char buffer[15] = {"              "};
    oled.setCursor(0, 0);
    oled.print(buffer);
    oled.setCursor(0, 0);
    switch (counter)
    {
      case 0:
        snprintf(buffer, sizeof(buffer - 1), "Temp: %i,%i C", t / 10, t - (t / 10) * 10);
        break;
      case 1:
        snprintf(buffer, sizeof(buffer - 1), "Hum: %i,%i %%", h / 10, h - (h / 10) * 10);
        break;
      case 2:
        snprintf(buffer, sizeof(buffer - 1), "Press: %i ",  druck);
        break;
    }
    oled.print(buffer);
    lastCounter = counter;
  }
}

void loop()
{
  checkSensor();
  oled.set2X();
  //Taster auswerten
  static uint32_t debounce_time;
  if (millis() - debounce_time > debounce_delay)
  {
    tasterState = digitalRead(tasterPin);  //einlesen des Tasters
  }
  if (tasterState != tasterState_alt) // bei Pegelwechsel
  {
    debounce_time = millis();
#ifdef DEBUG
    Serial.println(counter);
#endif
    if (!tasterState) //wenn Taster gedrückt
    {
      counter++;
      if (counter > 3)
      {
        counter = 0;
      }
    }
    tasterState_alt = tasterState; // state aktualisieren
  }
  value2oled();
}

Nicht wundern, ich hab die float-Werte umgeschrieben. Evtl. passt es nicht. Nicht problematisch, aber es wird...

Also, folgendes passiert:

  • Wenn ich den Sketch hochlade kompiliert der einwandfrei
  • Nach dem Hochladen und dem reset wird auf dem Display "T" ausgegeben
  • Nach dem Drücken des Tasters schaltet die anzeige durch wie beim Original
    • es wird aber nur jeweils in der ersten Zeile der erste Buchstabe angezeigt...also "T", "H" und "P", sonst nichts
  • Nach dem dritten Mal drücken kommt ein leerer Bildschirm, und dann gehts wieder von vorne los

Das wird daran liegen weil counter++ gemacht wird und wenn dieser > 3 ist auf 0 gesetzt wird. Probiere ihn mal wenn counter > 3 , counter = 1

Ups - seit einer Stunde eien Antwort.
Das kommt davon, weil du nicht auf meinen Post geantwortet hast - ich schau später drau. Vermutlich hab ich beim snprintf nen Fehler drin.
Na mal sehen...

@skippolino In meinem Code Zeile 174 counter >3 auf counter >2 ändern - fertig.

NEIN!
Wenn, dann ist der counter anders zu bauen!

Ist ja kein Wettbewerb.....und es ist Sonntag und schönes Wetter...geniess das Leben. Das Problem wird auch morgen noch da sein :wink:

Das löst das Problem mit dem leeren Screen ( da hat dir deine 0 wohl einen Streich gespielt), aber es wird immer noch nur der erste Buchstaben auf der ersten Zeile ausgegeben

Nein. Ich habe deinen Zaehler nicht berücksichtigt und den vergessen zurückzustellen :wink:
Rest schau ich nachher.

Ich habs mal probiert nachzuvollziehen, was du da programmiert hast, ist mir aber noch zu hoch, was da genau passiert. :crazy_face: