NodeMCU BME280 Wunderground Taupunktsteuerung

Was bedeutet die Aussage "fruchtlos"?
Zeige doch mal den neuen Sketch. Der könnte mehr aussagen.

Gruß Tommy

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

Grundsätzlich ist das mit den Funktionen richtig so, du musst nur die Variablen, die auch außerhalb der Funktion ihre Gültigkeit behalten sollen, als "global" definieren, also oberhalb des Setup.
So kannst du die Inhalte an allen Stellen deines Sketches nutzen.
Und dann wie Tommy schreibt, einen aktuellen Sketch posten, damit wir auch das sehen können, was du siehst.

Das mit den Funktionen mache ich dann heute Abend nochmal und Poste den aktuellen Sketch.

Habe gestern auch noch ein wenig gegoogelt nach oled freeze

Bin wohl nicht der einzige mit dem Problem aber wenn mein Englisch mich da nicht im Stich lässt gibt es dafür wohl scheinbar auch keine wirkliche Lösung.

Wie seht ihr das ?

so habe mich mal an den funktion versucht. aber jetzt geht gar nichts mehr >:(

#include <ESP8266WiFi.h>
//#include <stdint.h>
#include "SparkFunBME280.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 <Adafruit_GFX.h>
//#include <Adafruit_PCD8544.h>
#include <SPI.h>
#include <Wire.h>
#include <ACROBOTIC_SSD1306.h>
BME280 mySensorA;

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


// 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 ""
 // 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);
//***********************************
float h_innen = 0;
float t_innen = 0;


void anzeige()
{
  //******* OLED Ansteuerung************
  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);
}
void bmeauslesen()
{
  //******* BME auslesen **************
  h_innen = mySensorA.readFloatHumidity();  
  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(" %");
}

void wunderground()
{
  //****** 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;


}


void loop()
{
anzeige;
delay (1000);
bmeauslesen;
delay (1000);
wunderground;
delay (1000);
}

CyrixTheDragon:
so habe mich mal an den funktion versucht. aber jetzt geht gar nichts mehr >:(

Gibt doch sicher eine Fehlermeldung !

Der Aufruf deiner Funktionen ist fehlerhaft.

Da fehlen jeweils am Ende die Klammern "()".
Hatte ich leider in deinem Beispiel übersehen.

Beispiel:

anzeige();

Ne Fehlermeldung gab es keine ist so durch gelaufen. Ja das mir den klammern klinkt logisch :slight_smile: ich hatte das in einem Beispiel mal gesehen das dann in der klammer noch werte oder variablen angegeben waren ?

Werde das morgen mal in der Mittagspause ausprobieren und noch einmal berichten.

HotSystems:
Gibt doch sicher eine Fehlermeldung !

Der Aufruf deiner Funktionen ist fehlerhaft.

Da fehlen jeweils am Ende die Klammern "()".
Hatte ich leider in deinem Beispiel übersehen.

Beispiel:

anzeige();

Gibt keine Fehlermeldung. Ist für den Compiler formal nicht falsch.

Gruß Tommy

Tommy56:
Gibt keine Fehlermeldung. Ist für den Compiler formal nicht falsch.

Das ist dann von der IDE-Version abhängig.

In der IDE 1.6.5 gibt es eine Meldung.

Bei mir auch in der 1.6.5 nicht (alla Ausgaben auf ausführlich, alle Warnungen), nur eine Warnung.
Die sieht man aber nur, wenn man bewußt danach sucht. Sonst rast die zu schnell durch.

dual.ino: In function 'void setup()':
dual.ino:30:11: warning: statement is a reference, not call, to function 'printArr' [-Waddress]
dual.ino:30:11: warning: statement has no effect [-Wunused-value]

Das war der Code:

uint32_t uvar = 0xd;
uint8_t garr[32];

uint8_t *uLongToBin(uint32_t val, uint8_t *arr) {
uint8_t i=0, wert;

  memset(arr,0,32);
  while (val) {
    wert = val % 2;
    arr[i++] = wert;
    val = val / 2;
    Serial.print("Wert: "); Serial.println(wert);
  }
  return arr;
}

void printArr(uint8_t *arr) {
  for (int8_t i=31; i >= 0; i--) {
    Serial.print(arr[i]);
    if (i%4 == 0) Serial.print(" ");
  }  
}

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  uLongToBin(uvar,garr);
  printArr;
}

void loop() {
  
}

In der letzten Zeile im Setup sind die Klammern gelöscht.

Gruß Tommy

So habe gerade mal die klammern hinzufügt. Jetzt läuft der Sketch auch wieder wie vorher ohne die Funktionen.

Das oled steht weiterhin still.
Interessant ist allerdings das obwohl ich die Funktion wunderground danach auskommentiert habe //wunderground (); läuft die Funktion weiter... ????

Der Funktionsname alleine ist die Adresse der Funktion. Das braucht man für Funktionszeiger. Die Warnung sagt genau was falsch ist. Die sollte man immer aktivieren

Wenn du den Funktionsaufruf auskommentierst merkt der Compiler dass sie nicht verwendet wird und übersetzt sie nicht

Und warum wird dann trotzdem die Funktion ausgeführt wenn ich den Aufruf auskommentiere?

Kann nicht sein. Da machst du irgendwas anderes als du denkst

Ich kommentiere den Aufruf der Funktion im loop aus lasse neu kompilieren und übertrage. Kann es sein das meine Funktion wunderground aus mehreren Funktionen besteht ?

Warum postest du nicht den aktuellen Sketch.

Dann sehen wir evtl. auch das, was du siehst und können einen evtl. Fehler.

So ist es doch nur stochern im Trüben.

#include <ESP8266WiFi.h>
//#include <stdint.h>
#include "SparkFunBME280.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 <Adafruit_GFX.h>
//#include <Adafruit_PCD8544.h>
#include <SPI.h>
#include <Wire.h>
#include <ACROBOTIC_SSD1306.h>
BME280 mySensorA;

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


// 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 ""
 // 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);
//***********************************
float h_innen = 0;
float t_innen = 0;


void anzeige()
{
  //******* OLED Ansteuerung************
  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);
}
void bmeauslesen()
{
  //******* BME auslesen **************
  h_innen = mySensorA.readFloatHumidity();  
  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(" %");
}

void wunderground()
{
  //****** 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;


}


void loop()
{
anzeige();
delay (1000);
bmeauslesen();
delay (1000);
//wunderground();
delay (1000);
}

Kennst du eigentlich die Funktion Strg+T in der IDE.

Solltest du unbedingt mal ausführen, dann ist der Sketch formatiert und besser lesbar.

Was passiert den jetzt mit der Anzeige ?

Nein das kannte ich bisher noch nicht
Habe immer selber versucht das alles halbwegs gescheit einzurücken.

Das Oled zeigt immer noch den Setup Text an und aktualisiert nicht. Aber es wird trotzdem das aktuelle Wetter von wunderground geparst und seriell ausgegeben.

CyrixTheDragon:
Das Oled zeigt immer noch den Setup Text an und aktualisiert nicht.

Ok, das musst du noch untersuchen, wodran es liegen kann.

Aber es wird trotzdem das aktuelle Wetter von wunderground geparst und seriell ausgegeben.

Das läuft über eine eigene Funktion "showWeather", der Aufruf steht ca. in Zeile 119.

Wird denn im Serial-Monitor der Text "test Displayanzeige" angezeigt ?

Dein Problem könnte auch an diesem Code liegen.

// ************Wunderground************
static char respBuf[4096];
bool showWeather(char *json);
//***********************************
float h_innen = 0;
float t_innen = 0;

Die Anordnung ist sehr ungewöhnlich.
Die Variablen-Definition (float) solltest du nach oben, zu den übrigen Variablen setzen.
Die beiden anderen Zeilen im "Wunderground" Rahmen sind besser im Setup oder Loop aufgehoben.

Wie sieht das denn im Original aus ?