NodeMCU BME280 Wunderground Taupunktsteuerung

Hallo Community

seit unzähligen Stunden zermatere ich mir jetzt den Kopf wo genau das Problem an meinem Programm ist.

Generell soll es sich mit dem WLAN verbinden und dort dann das aktuelle Wetter von Wunderground parsen.

Darüber hinaus fragt er einen BME280 im Innenbereich ab und soll die aktuellen werte auf einem OLED Display anzeigen.

soweit scheint auch alles zu funktionieren nur ich bekomme während des Loops keine veränderte Anzeige auf dem OLED hin. es ist so als ob es einfriert.

Es steckt natürlich noch ganz schön in den Kinderschuhen und ist auch ziemlich zusammen geklöppelt aber bevor das OLED nicht funktionert lohnt sich weitermachen auch nicht wirklich.

Ich hoffe ihr könnt mir sagen wo genau der Fehler ist. Ich befürchte das es irgendetwas mit dem parsen von wunderground zu tun hat, wenn ich nur einen sketch erstelle der das Oled im loop ansteuert funktioniert es tadellos.

#include <ESP8266WiFi.h>
#include <stdint.h>
#include "SparkFunBME280.h"
#include "Wire.h"
#ifndef min
#define min(x,y) (((x)<(y))?(x):(y))
#endif
#ifndef max
#define max(x,y) (((x)>(y))?(x):(y))
#endif
#include <ArduinoJson.h>
#include <SPI.h>
//#include <Adafruit_GFX.h>
//#include <Adafruit_PCD8544.h>
BME280 mySensorA;
#include <SPI.h>
#include <Wire.h>
#include <ACROBOTIC_SSD1306.h>



static const char SSID[] = "";
static const char PASSWORD[] = "";

// Use your own API key by signing up for a free developer account.
// www.wunderground.com/weather/api/
#define WU_API_KEY ""


// Country and city
#define WU_LOCATION "Germany/Holzwickede"



// 5 minutes between update checks. The free developer account has a limit
// on the number of calls so don't go wild.
#define DELAY_NORMAL (5*60*1000)
// 20 minute delay between updates after an error
#define DELAY_ERROR (20*60*1000)
#define WUNDERGROUND "api.wunderground.com"


// HTTP request
const char WUNDERGROUND_REQ[] =
"GET /api/" WU_API_KEY "/conditions/q/" WU_LOCATION ".json HTTP/1.1\r\n"
"User-Agent: ESP8266/0.1\r\n"
"Accept: */*\r\n"
"Host: " WUNDERGROUND "\r\n"
"Connection: close\r\n"
"\r\n";

void setup()
{
Serial.begin(9600);

//DISPLAY START *****************************************************************************
Wire.begin();
oled.init(); // Initialze SSD1306 OLED display
oled.clearDisplay(); // Clear screen
oled.setTextXY(0,0); // Set cursor position, start of line 0
oled.putString("Keller");
oled.setTextXY(1,0); // Set cursor position, start of line 1
oled.putString("Taupunkt");
oled.setTextXY(2,0); // Set cursor position, start of line 2
oled.putString("Steuerung");
// ******************************************************************************************


//***Set up sensor 'A'******************************//
//commInterface can be I2C_MODE or SPI_MODE
mySensorA.settings.commInterface = I2C_MODE;
mySensorA.settings.I2CAddress = 0x77;
mySensorA.settings.runMode = 3; // 3, Normal mode
mySensorA.settings.tStandby = 0; // 0, 0.5ms
mySensorA.settings.filter = 0; // 0, filter off
//tempOverSample can be:
// 0, skipped
// 1 through 5, oversampling *1, *2, *4, *8, *16 respectively
mySensorA.settings.tempOverSample = 1;
//pressOverSample can be:
// 0, skipped
// 1 through 5, oversampling *1, *2, *4, *8, *16 respectively
mySensorA.settings.pressOverSample = 1;
//humidOverSample can be:
// 0, skipped
// 1 through 5, oversampling *1, *2, *4, *8, *16 respectively
mySensorA.settings.humidOverSample = 1;

Serial.print("Program Started\n");
Serial.println("Starting BME280s... result of .begin():");
delay(10); //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
//Calling .begin() causes the settings to be loaded
Serial.print("Sensor A: 0x");
Serial.println(mySensorA.begin(), HEX);




// We start by connecting to a WiFi network
Serial.println();
Serial.println();
Serial.print(F("Connecting to "));
Serial.println(SSID);

WiFi.begin(SSID, PASSWORD);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(F("."));
}

Serial.println();
Serial.println(F("WiFi connected"));
Serial.println(F("IP address: "));
Serial.println(WiFi.localIP());
}

// ***********************************************************************************


static char respBuf[4096];

bool showWeather(char *json);



void loop()
{
oled.clearDisplay();
delay (1000);
oled.setTextXY(0,0);
oled.putString("Test1");
oled.setTextXY(1,0);
oled.putString("Test2");
oled.setTextXY(2,0);
oled.putString("Test3");
oled.clearDisplay();
Serial.print("SChleife");


float h_innen = mySensorA.readFloatHumidity();
// Read temperature as Celsius
float t_innen = mySensorA.readTempC();
// set text color / Textfarbe setzen
// set text cursor position / Textstartposition einstellen


//Start with temperature, as that data is needed for accurate compensation.
//Reading the temperature updates the compensators of the other functions
//in the background.
Serial.print("Temperature: ");
Serial.print(mySensorA.readTempC(), 2);
Serial.println(" degrees C");


Serial.print("Pressure: ");
Serial.print(mySensorA.readFloatPressure(), 2);
Serial.println(" Pa");

Serial.print("Altitude: ");
Serial.print(mySensorA.readFloatAltitudeMeters(), 2);
Serial.println("m");


Serial.print("%RH: ");
Serial.print(mySensorA.readFloatHumidity(), 2);
Serial.println(" %");



// TODO check for disconnect from AP

// Open socket to WU server port 80
Serial.print(F("Connecting to "));
Serial.println(WUNDERGROUND);

// Use WiFiClient class to create TCP connections
WiFiClient httpclient;
const int httpPort = 80;
if (!httpclient.connect(WUNDERGROUND, httpPort)) {
Serial.println(F("connection failed"));
delay(DELAY_ERROR);
return;
}

// This will send the http request to the server
Serial.print(WUNDERGROUND_REQ);
httpclient.print(WUNDERGROUND_REQ);
httpclient.flush();

// Collect http response headers and content from Weather Underground
// HTTP headers are discarded.
// The content is formatted in JSON and is left in respBuf.
int respLen = 0;
bool skip_headers = true;
while (httpclient.connected() || httpclient.available()) {
if (skip_headers) {
String aLine = httpclient.readStringUntil('\n');
//Serial.println(aLine);
// Blank line denotes end of headers
if (aLine.length() <= 1) {
skip_headers = false;
}
}
else {
int bytesIn;
bytesIn = httpclient.read((uint8_t *)&respBuf[respLen], sizeof(respBuf) - respLen);
Serial.print(F("bytesIn ")); Serial.println(bytesIn);
if (bytesIn > 0) {
respLen += bytesIn;
if (respLen > sizeof(respBuf)) respLen = sizeof(respBuf);
}
else if (bytesIn < 0) {
Serial.print(F("read error "));
Serial.println(bytesIn);
}
}
delay(1);
}
httpclient.stop();

if (respLen >= sizeof(respBuf)) {
Serial.print(F("respBuf overflow "));
Serial.println(respLen);
delay(DELAY_ERROR);
return;
}
// Terminate the C string
respBuf[respLen++] = '\0';
Serial.print(F("respLen "));
Serial.println(respLen);
//Serial.println(respBuf);

if (showWeather(respBuf)) {
delay(DELAY_NORMAL);
}
else {
delay(DELAY_ERROR);
}

}

bool showWeather(char *json)
{
StaticJsonBuffer<3*1024> jsonBuffer;

// Skip characters until first '{' found
// Ignore chunked length, if present
char *jsonstart = strchr(json, '{');
//Serial.print(F("jsonstart ")); Serial.println(jsonstart);
if (jsonstart == NULL) {
Serial.println(F("JSON data missing"));
return false;
}
json = jsonstart;

// Parse JSON
JsonObject& root = jsonBuffer.parseObject(json);
if (!root.success()) {
Serial.println(F("jsonBuffer.parseObject() failed"));
return false;
}

// Extract weather info from parsed JSON
JsonObject& current = root["current_observation"];
const float temp_f = current["temp_f"];
Serial.print(temp_f, 1); Serial.print(F(" F, "));
const float temp_c = current["temp_c"];
Serial.print(temp_c, 1); Serial.print(F(" C, "));
const char *humi = current[F("relative_humidity")];
Serial.print(humi); Serial.println(F(" RH"));
const char *weather = current["weather"];
Serial.println(weather);
const char *pressure_mb = current["pressure_mb"];
Serial.println(pressure_mb);
const char *observation_time = current["observation_time_rfc822"];
Serial.println(observation_time);
delay (100);
//Date/time string looks like this
//Wed, 27 Jun 2012 17:27:14 -0700
//012345678901234567890
// 1 2
// LCD has 14 characters per line so show date on one line and time on the
// next. And shorten the date so it fits.
char date[14+1];
const char *time;
//Wed, 27 Jun 12
memcpy(date, observation_time, 12);
memcpy(&date[12], &observation_time[14], 2);
date[14] = '\0';
//17:27:14 -0700
time = &observation_time[17];

return true;


}

Hallo,
Ich habe mir jetzt nicht das ganze Listing durchgesehen, was mir aber gleich einmal auffällt: das OLED-Display wird zum Beginn des Loop gelöscht,… Danach eine Sekunde im Delay verbracht (keine OLED - Ausgabe möglich!!)
Dann die Ausgabe berechnet und angesteuert, um danach wieder eine Sekunde lang gelöscht zu werden…
Wenn schon ein Delay(1000), dann wechsle doch einfach einmal “oled.clearDisplay();” mit
“Delay (1000)”…
Lg, Robert

Ich habe versucht, deinen Sketch zu lesen.
Leider ist der sehr unübersichtlich, es fehlen sämtliche Einrüchungen (Strg+T).
Allerdings finde ich ich deinem Sketch keine Werteübergabe vom Sensor an das Display.
Mag sein , dass ich es nur nicht finden kann.

Du solltest deinen Sketch besser strukturieren und auch Funktionen verwenden, das macht es übersichtlicher.

Ich dachte eigentlich das 1 Sekunde ausreicht um das Display zu clearen und neuen Text zu Posten.

Allerdings funktioniert auch das clearen nicht. Es steht nach wie vor der Text aus dem Setup im Display.

Gibt es eine Möglichkeit unterprogramme zu erstellen und diese dann im loop aufzurufen ?

CyrixTheDragon:
Gibt es eine Möglichkeit unterprogramme zu erstellen und diese dann im loop aufzurufen ?

Unterprogramme nicht aber Funktionen kannst du aus der Loop aufrufen.

Man kann Funktionen erstellen.

Wenn aber noch nicht mal das clear funktioniert, dann solltest Du das als Erstes beseitigen, bevor Du an Funktionen denkst.

Gruß Tommy

CyrixTheDragon:
Allerdings funktioniert auch das clearen nicht. Es steht nach wie vor der Text aus dem Setup im Display.

Und du kümmerst dich scheinbar auch nicht um unsere Antworten.
In Post #2 hatte ich geschrieben, dass es keine Werteübergabe an das Display gibt.
Das solltest du noch mal prüfen und den Sketch besser lesbar (formatiert) hier einstellen.

Das keine Werte ausgegeben werden im Display ist mir bewusst.Bevor ich mich daran begebe müsste erst einmal irgendetwas auf dem Display passieren :wink:

Es ist leider noch sehr unübersichtlich da der Sketch aus 3 Programmen zusammengewürfelt ist.

Von dem Teil der die wetterdaten parst habe ich leider so gar keine Ahnung. Da ist vieles dabei was mir ein ? Ins Gesicht zaubert.

Hallo,
"müsste erst einmal irgendetwas auf dem Display passieren"

Dann sorge doch erst einmal dafür...
Schreibe doch erst einmal einen Sketch, NUR für das Display.
So kannst Du sehen, ob es denn einwandfrei funktioniert.
Das wirst Du dann verstehen, und überträgst es in Deinen jetzigen Sketch.
Gruß und Spaß
Andreas

CyrixTheDragon:
Das keine Werte ausgegeben werden im Display ist mir bewusst.Bevor ich mich daran begebe müsste erst einmal irgendetwas auf dem Display passieren :wink:

Ach und warum schickst du uns immer in die falsche Richtung.
Du wurdest schon darum gebeten, den Sketch aufzuräumen, warum machst du das nicht.
Da steigt man so nicht durch, du schon garnicht.

Es ist leider noch sehr unübersichtlich da der Sketch aus 3 Programmen zusammengewürfelt ist.

Hatte ich oben schon bestätigt.
Also klein anfangen und nicht irgend etwas zusammenkopieren, was du nicht verstehst.

Von dem Teil der die wetterdaten parst habe ich leider so gar keine Ahnung. Da ist vieles dabei was mir ein ? Ins Gesicht zaubert.

Dann mach erst das, wovon du Ahnung hast.
Wir helfen immer gern, aber wenn wir falsche Informationen bekommen, vergeht uns die Lust.

Ja es ist sehr unübersichtlich werde das heute abend entsprechend ändern.

Eigentlich funktioniert soweit ja alles ich kriege nur aus mir schleiherhaften gründen keine Anzeige aufs Display. Er fragt den bme ab parst die wetterwetterdaten und die weitere Verarbeitung sollte auch nicht das Problem werden.

Wenn ich nur einen Sketch für das Display schreibe funktioniert alles reibungslos.

CyrixTheDragon:
Wenn ich nur einen Sketch für das Display schreibe funktioniert alles reibungslos.

Setze die einzelnen Sensorauswertungen in eigene Funktionen. Dann wird es übersichtlicher und du kannst diese nacheinander ansprechen bzw. schnell wieder auskommentieren (//).

So jetzt endlich eine aufgeräumtere und sortierte Fassung des Sketches

#include <ESP8266WiFi.h>
#include <stdint.h>
#include "SparkFunBME280.h"
#include "Wire.h"
#ifndef min
#define min(x,y) (((x)<(y))?(x):(y))
#endif
#ifndef max
#define max(x,y) (((x)>(y))?(x):(y))
#endif
#include <ArduinoJson.h>
#include <SPI.h>
//#include <Adafruit_GFX.h>
//#include <Adafruit_PCD8544.h>
BME280 mySensorA;
#include <SPI.h>
#include <Wire.h>
#include <ACROBOTIC_SSD1306.h>


// WLAN Daten 
//***********************************************
static const char SSID[]     = "MeineSSID";
static const char PASSWORD[] = "meinkennwort;
//***********************************************

// Wunderground Daten
//***********************************************
 // Use your own API key by signing up for a free developer account.
 // http://www.wunderground.com/weather/api/
  #define WU_API_KEY "meinwundergroundapi"
 // Country and city
  #define WU_LOCATION "Germany/Holzwickede"
  // 5 minutes between update checks. The free developer account has a limit
  // on the  number of calls so don't go wild.
  #define DELAY_NORMAL    (5*60*1000)
  // 20 minute delay between updates after an error
  #define DELAY_ERROR     (20*60*1000)
  #define WUNDERGROUND "api.wunderground.com"
// HTTP request
const char WUNDERGROUND_REQ[] =
    "GET /api/" WU_API_KEY "/conditions/q/" WU_LOCATION ".json HTTP/1.1\r\n"
    "User-Agent: ESP8266/0.1\r\n"
    "Accept: */*\r\n"
    "Host: " WUNDERGROUND "\r\n"
    "Connection: close\r\n"
    "\r\n";
//********************************************************

void setup()
{
  Serial.begin(9600);
  
//DISPLAY START ******************************************
  Wire.begin();  
  oled.init();                      // Initialze SSD1306 OLED display
  oled.clearDisplay();              // Clear screen
  oled.setTextXY(0,0);              // Set cursor position, start of line 0
  oled.putString("Keller");
  oled.setTextXY(1,0);              // Set cursor position, start of line 1
  oled.putString("Taupunkt");
  oled.setTextXY(2,0);              // Set cursor position, start of line 2
  oled.putString("Steuerung");
// ********************************************


//***BME280 initalisieren***********************************
  mySensorA.settings.commInterface = I2C_MODE;
  mySensorA.settings.I2CAddress = 0x77;
  mySensorA.settings.runMode = 3; //  3, Normal mode
  mySensorA.settings.tStandby = 0; //  0, 0.5ms
  mySensorA.settings.filter = 0; //  0, filter off
  //tempOverSample can be:
  //  0, skipped
  //  1 through 5, oversampling *1, *2, *4, *8, *16 respectively
  mySensorA.settings.tempOverSample = 1;
  //pressOverSample can be:
  //  0, skipped
  //  1 through 5, oversampling *1, *2, *4, *8, *16 respectively
    mySensorA.settings.pressOverSample = 1;
  //humidOverSample can be:
  //  0, skipped
  //  1 through 5, oversampling *1, *2, *4, *8, *16 respectively
  mySensorA.settings.humidOverSample = 1;

  Serial.print("Program Started\n");
  Serial.println("Starting BME280s... result of .begin():");
  delay(10);  //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
  //Calling .begin() causes the settings to be loaded
  Serial.print("Sensor A: 0x");
  Serial.println(mySensorA.begin(), HEX);
//****************************************
  
 
 
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print(F("Connecting to "));
  Serial.println(SSID);

  WiFi.begin(SSID, PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }

  Serial.println();
  Serial.println(F("WiFi connected"));
  Serial.println(F("IP address: "));
  Serial.println(WiFi.localIP());
}

// ************Wunderground*****************
static char respBuf[4096];
bool showWeather(char *json);
//****************************************



void loop()
{
  //******* OLED Ansteuerungv*****************
  oled.clearDisplay();
  delay (1000);
  oled.setTextXY(0,0);         
  oled.putString("Test1");
  oled.setTextXY(1,0);         
  oled.putString("Test2");
  oled.setTextXY(2,0);         
  oled.putString("Test3");
  Serial.print("test Displayanzeige");
  delay (10000);

  //******* BME auslesen *********
  float h_innen = mySensorA.readFloatHumidity();  
  float t_innen = mySensorA.readTempC();
  Serial.print("Temperature: ");
  Serial.print(mySensorA.readTempC(), 2);
  Serial.println(" degrees C");
  
  Serial.print("Pressure: ");
  Serial.print(mySensorA.readFloatPressure(), 2);
  Serial.println(" Pa");

  Serial.print("Altitude: ");
  Serial.print(mySensorA.readFloatAltitudeMeters(), 2);
  Serial.println("m");

  Serial.print("%RH: ");
  Serial.print(mySensorA.readFloatHumidity(), 2);
  Serial.println(" %");

  //****** Wunderground parsen ******

  // Open socket to WU server port 80
  Serial.print(F("Connecting to "));
  Serial.println(WUNDERGROUND);

  // Use WiFiClient class to create TCP connections
  WiFiClient httpclient;
  const int httpPort = 80;
  if (!httpclient.connect(WUNDERGROUND, httpPort)) {
    Serial.println(F("connection failed"));
    delay(DELAY_ERROR);
    return;
  }

  // This will send the http request to the server
  Serial.print(WUNDERGROUND_REQ);
  httpclient.print(WUNDERGROUND_REQ);
  httpclient.flush();

  // Collect http response headers and content from Weather Underground
  // HTTP headers are discarded.
  // The content is formatted in JSON and is left in respBuf.
  int respLen = 0;
  bool skip_headers = true;
  while (httpclient.connected() || httpclient.available()) {
    if (skip_headers) {
      String aLine = httpclient.readStringUntil('\n');
      //Serial.println(aLine);
      // Blank line denotes end of headers
      if (aLine.length() <= 1) {
        skip_headers = false;
      }
    }
    else {
      int bytesIn;
      bytesIn = httpclient.read((uint8_t *)&respBuf[respLen], sizeof(respBuf) - respLen);
      Serial.print(F("bytesIn ")); Serial.println(bytesIn);
      if (bytesIn > 0) {
        respLen += bytesIn;
        if (respLen > sizeof(respBuf)) respLen = sizeof(respBuf);
      }
      else if (bytesIn < 0) {
        Serial.print(F("read error "));
        Serial.println(bytesIn);
      }
    }
    delay(1);
  }
  httpclient.stop();

  if (respLen >= sizeof(respBuf)) {
    Serial.print(F("respBuf overflow "));
    Serial.println(respLen);
    delay(DELAY_ERROR);
    return;
  }
  // Terminate the C string
  respBuf[respLen++] = '\0';
  Serial.print(F("respLen "));
  Serial.println(respLen);
  //Serial.println(respBuf);

  if (showWeather(respBuf)) {
    delay(DELAY_NORMAL);
  }
  else {
    delay(DELAY_ERROR);
  }

}

bool showWeather(char *json)
{
  StaticJsonBuffer<3*1024> jsonBuffer;

  // Skip characters until first '{' found
  // Ignore chunked length, if present
  char *jsonstart = strchr(json, '{');
  //Serial.print(F("jsonstart ")); Serial.println(jsonstart);
  if (jsonstart == NULL) {
    Serial.println(F("JSON data missing"));
    return false;
  }
  json = jsonstart;

  // Parse JSON
  JsonObject& root = jsonBuffer.parseObject(json);
  if (!root.success()) {
    Serial.println(F("jsonBuffer.parseObject() failed"));
    return false;
  }

  // Extract weather info from parsed JSON
  JsonObject& current = root["current_observation"];
  const float temp_f = current["temp_f"];
  Serial.print(temp_f, 1); Serial.print(F(" F, "));
  const float temp_c = current["temp_c"];
  Serial.print(temp_c, 1); Serial.print(F(" C, "));
  const char *humi = current[F("relative_humidity")];
  Serial.print(humi);   Serial.println(F(" RH"));
  const char *weather = current["weather"];
  Serial.println(weather);
  const char *pressure_mb = current["pressure_mb"];
  Serial.println(pressure_mb);
  const char *observation_time = current["observation_time_rfc822"];
  Serial.println(observation_time);
   delay (100);
  //Date/time string looks like this
  //Wed, 27 Jun 2012 17:27:14 -0700
  //012345678901234567890
  //          1         2
  // LCD has 14 characters per line so show date on one line and time on the
  // next. And shorten the date so it fits.
  char date[14+1];
  const char *time;
  //Wed, 27 Jun 12
  memcpy(date, observation_time, 12);
  memcpy(&date[12], &observation_time[14], 2);
  date[14] = '\0';
  //17:27:14 -0700
  time = &observation_time[17];
 return true;
}

Also ich habe gerade noch einmal getestet bis wohin das Programm mit dem Display funktioniert. Sobald ich den Wunderground Part mit ins Programm nehme steht die Displayanzeige still und es steht nur noch der Text aus dem Setup im Display.

Dann solltest Du einen eigenen Sketch für das Auslesen der Wunderground-Daten bauen und diesen Teil erst mal separat testen.

Gruß Tommy

Wie oft willst du denn wire.h und spi.h einbinden? Schmeiß mal alle Libraries raus die du nicht unbedingt brauchst…

Stimmt sehe ich auch gerade erst saß ich die beiden 2 mal eingebunden habe.

@Thommy für sich alleine läuft das parsen von wunderground super. Das läuft auch in dem Sketch hier 1a nur das oled Display tut halt nicht was es soll sondern bleibt bei der Anzeige stehen die ich im Setup definiert habe.

Werde heute Abend mal wire.h und spi.h raushauen

Und warum machst du es nicht wie in Post #11 geschrieben und setzt für den Sensor und das Oled eigene Funktionen ein.
Dadurch wird das Ganze übersichtlicher und du kannst es besser testen, indem du einzelne Funktionen deaktivierst bzw. wieder aktivierst.
Da du alles in der Loop stehen hast, ist das schwer überschaubar.

@HotSystems

das mit den Funktionen habe ich versucht aber dann geht leider gar nichts mehr. Wahrscheinlich mache ich das aber auch einfach falsch. verstehe ich das richtig das man dann einfach alles in eine neue funktion packt

z.B.:

void bmeauslesen()
{
  //******* BME auslesen ********************************************
  float h_innen = mySensorA.readFloatHumidity();  
  float t_innen = mySensorA.readTempC();
  Serial.print("Temperature: ");
  Serial.print(mySensorA.readTempC(), 2);
  Serial.println(" degrees C");
  
  Serial.print("Pressure: ");
  Serial.print(mySensorA.readFloatPressure(), 2);
  Serial.println(" Pa");

  Serial.print("Altitude: ");
  Serial.print(mySensorA.readFloatAltitudeMeters(), 2);
  Serial.println("m");

  Serial.print("%RH: ");
  Serial.print(mySensorA.readFloatHumidity(), 2);
  Serial.println(" %");
}

und dann im loop nur noch sage

void loop()
{
bmeauslesen;
}

sorry :confused: würde das echt gerne besser können aber stehe noch relativ am Anfang

Ich habe gerade die doppelten Bibliotheken entfernt und das definierte delay Normal und Error mal gegen fixe ms Werte ausgetauscht. leider ist auch das fruchtlos...