Sensordaten vom MPL3115a2 werden nur beim ersten Loop korrekt ausgegeben

Hallo zusammen.
Ich bin zum ersten mal im Arduino Forum unterwechs und somit noch nicht so vertraut mit der Materie.

Mein aktuelles Problem besteht darin, dass ich mit ein Temperatur / Luftdruck Sketch, welchen ich für den EPS8266 und MPL3115A2 angepasst habe, nicht korrekt nutzen kann.
Demnach werden beim ersten Durchlauf die korrekten Sensordaten ausgegeben, jedoch danach nur noch die temperatur.
Leider komme ich nicht von selbst auf den fehler.
Es kommt mir fast so vor, als wenn die Adafruit_MPL3115A2.h hier etwas im Hintergrund verändert.

Anbei der Code meines Sketchs:

/*
  Rui Santos
  Complete project details at Complete project details at https://RandomNerdTutorials.com/cloud-weather-station-esp32-esp8266/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

*/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Adafruit_MPL3115A2.h>
#include <Wire.h>
Adafruit_MPL3115A2 baro = Adafruit_MPL3115A2();
const char* ssid = "FRITZ!Box 7590 OE";
const char* password = "********";

//Your Domain name with URL path or IP address with path
const char* serverName = "http://********/esp-post-data.php";

// Keep this API Key value to be compatible with the PHP code provided in the project page.
// If you change the apiKeyValue value, the PHP file /esp-post-data.php also needs to have the same key
String apiKeyValue = "********";
String sensorName = "MPL3115A2";
String sensorLocation = "Gewaechshaus";


//#define SEALEVELPRESSURE_HPA (1013.25)



unsigned long timerDelay = 10000;

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

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
  

  if (! baro.begin()) {
    Serial.println("Couldnt find sensor");
    return;
  }
  
}

void loop() {
  //Send an HTTP POST request every 10 minutes
  if ((millis() - lastTime) > timerDelay) {
    //Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;

      // Your Domain name with URL path or IP address with path
      http.begin(serverName);

      // Specify content-type header
      http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    
      float pascals = baro.getPressure();
      pascals = pascals/100,0;
      Serial.print(pascals); Serial.print(" hpa");
      float altm = baro.getAltitude();
      Serial.print(altm); Serial.print("   meters");
      float tempC = baro.getTemperature();
     Serial.print(tempC); Serial.println("*C");
      
      // Prepare your HTTP POST request data
     String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
                            + "&location=" + sensorLocation + "&value1=" + String(tempC)
                            + "&value2=" + String(pascals) + "&value3=" + String(altm) + "";
      Serial.print("httpRequestData: ");
      Serial.println(httpRequestData);

      // You can comment the httpRequestData variable above
      // then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
      //String httpRequestData = "api_key=tPmAT5Ab3j7F9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";

      // Send HTTP POST request
      int httpResponseCode = http.POST(httpRequestData);
    
      // If you need an HTTP request with a content type: text/plain
     // http.addHeader("Content-Type", "text/plain");
      //int httpResponseCode = http.POST("Hello, World!");

     // If you need an HTTP request with a content type: application/json, use the following:
     // http.addHeader("Content-Type", "application/json");
     //int httpResponseCode = http.POST("{\"value1\":\"19\",\"value2\":\"67\",\"value3\":\"78\"}");

       if (httpResponseCode>0) {
       Serial.print("HTTP Response code: ");
       Serial.println(httpResponseCode);
      }
     else {
       Serial.print("Error code: ");
       Serial.println(httpResponseCode);
      }
      http.end();
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}

Wie gesagt, wurde der Sketch ursprünglich für den BME280 geschrieben.
Das komplette Programm mit Code für die Datenbank und HTML-Seite findet man unter der im Code angegebenen URL.

Gruß
Domenico

Das return ist wirkungslos, die Prozedur wäre danach sowieso verlassen worden. Vielleicht wird deshalb diese Fehlermeldung übersehen?

Woher kommt dieses dämliche Komma? Wird das von der Forum Software erzeugt? Sonst könnte die Konstante als 100,000.0 interpretiert werden, womit pascals ziemlich sicher 0 bleiben dürfte.

Hallo DrDiettrich,

danke erst ein mal für die Antwort.
Das “return;” habe ich aus einem Sketch so übernommen.
Das Komma habe ich eingefügt.
Ich dachte, dass so keine Nachkommastellen ausgegeben würden.
Dennoch gibt das entfernen beider genannten Punkte keine Besserung.
Ich habe hier ein mal die Ausgabe aus dem Seriel-Monitor beigefügt:

Connected to WiFi network with IP Address: ***************
10 Sekuden (timerDelay variable), es dauert 10 Sekunden bis zur Darstellung.
1013.88 hpa-6.50   meters22.56*C 
httpRequestData: api_key=*********&sensor=MPL3115A2&location=Gewaechshaus&value1=22.56&value2=1013.88&value3=-6.50
HTTP Response code: 200
2621.18 hpa25347.38   meters22.50*C
httpRequestData: api_key=*********&sensor=MPL3115A2&location=Gewaechshaus&value1=22.50&value2=2621.18&value3=25347.38
HTTP Response code: 200

Wie man sieht, wird die erste Abfrage mit korrekten Werten ausgegeben, jede weitere hat dann andere Werte.

Gruß
Domenico

Der Komma Operator führt das Links vom Komma aus - und verwirft das Ergebnis - und gibt das Ergebnis des rechten Ausdrucks zurück.

Er macht also erst “pascals = pascals / 100”. Was eine Integer-Division statt der evtl. gewünschten Float-Division ist. Die ‘0’ rechts vom Komma bewirkt nichts und es sollte eine Warnung deswegen geben

Wenn du keine Nachkommastellen willst dann musst du das Ergebnis einem Integer zuweisen. Dadurch werden Nachkommastellen automatisch abgeschnitten. Davor kann man auch 0.5 addieren wenn man ein einfaches Runden möchte.

Oder man rechnet gleich in Ganzzahlen wenn das zu einem richtigen Ergebnis führt.

Danke für die Antwort.

das scheint alles plausibel zu sein.
Dennoch bewirkt irgend etwas diese unterschiedlichen Ausgaben.
Komisch ist auch, dass der Code

float pascals = baro.getPressure();
      pascals = pascals/100;
      Serial.print(pascals); Serial.print(" hpa");

Auch falsche werte ausgibt.
Werden die Daten denn nicht jedes mal neu vom Sensor abgerufen und dann gleich verarbeitet?
Ich habe schon überlegt, ob da beim 2. Durchlauf der Wert in den Variabeln vor erneutem Auslesen nicht gelöscht wird?

Gruß
Domenico

Habe hier noch den Original Sketch von Adafruit, welcher die Werte korrekt ausgibt.
Hier sieht man auch woher ich den “return;” Befehl habe:

#include <Wire.h>
#include <Adafruit_MPL3115A2.h>

// Power by connecting Vin to 3-5V, GND to GND
// Uses I2C - connect SCL to the SCL pin, SDA to SDA pin
// See the Wire tutorial for pinouts for each Arduino
// http://arduino.cc/en/reference/wire
Adafruit_MPL3115A2 baro = Adafruit_MPL3115A2();

void setup() {
  Serial.begin(9600);
  Serial.println("Adafruit_MPL3115A2 test!");
}

void loop() {
  if (! baro.begin()) {
    Serial.println("Couldnt find sensor");
    return;
  }
  
  float pascals = baro.getPressure();
  pascals = pascals/100,0;
  // Our weather page presents pressure in Inches (Hg)
  // Use http://www.onlineconversion.com/pressure.htm for other units
  Serial.print(pascals); Serial.println(" Inches (Hg)");

  float altm = baro.getAltitude();
  Serial.print(altm); Serial.println(" meters");

  float tempC = baro.getTemperature();
  Serial.print(tempC); Serial.println("*C");

  delay(250);
}

Gruß
Domenico

In loop() ist das return auch sinnvoll. Das bewirkt dass die Funktion wieder von vorne anfängt und ständig überprüft wird ob der Sensor initialisiert wurde.
In setup() verhält sich das anders

Da wird auch nicht mit Interrupts gearbeitet. Bei Deiner Version ist unklar, welchen Einfluß die Interrupts haben und ob für alle Zugriffe auf nicht-atomare gemeinsam verwendete Variablen die Interrupts abgeschaltet werden.

Der steht dort auch in loop(), wo er Sinn macht, und nicht wie bei Dir in setup().

Danke für eure Hinweise.
Für mich ist das nicht zu lösen.
Der einzige Unterschied zum Beispielcode von Adafruit ist die einbindung der WIFI Funktion und Speicherung / Aufruf in / aus der Datenbank.

Kann die PHP Datei aus dem Programm die Daten umrechnen?

esp-post-data.php:

<?php
  include_once('esp-database.php');

  // Keep this API Key value to be compatible with the ESP code provided in the project page. If you change this value, the ESP sketch needs to match
  $api_key_value = "*************";

  $api_key= $sensor = $location = $value1 = $value2 = $value3 = "";

  if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $api_key = test_input($_POST["api_key"]);
    if($api_key == $api_key_value) {
      $sensor = test_input($_POST["sensor"]);
      $location = test_input($_POST["location"]);
      $value1 = test_input($_POST["value1"]);
      $value2 = test_input($_POST["value2"]);
      $value3 = test_input($_POST["value3"]);

      $result = insertReading($sensor, $location, $value1, $value2, $value3);
      echo $result;
    }
    else {
      echo "Wrong API Key provided.";
    }
  }
  else {
    echo "No data posted with HTTP POST.";
  }

  function test_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
  }

esp-database.php

<?php
  $servername = "localhost";

  // REPLACE with your Database name
  $dbname = "*************";
  // REPLACE with Database user
  $username = "*************";
  // REPLACE with Database user password
  $password = "*************";

  function insertReading($sensor, $location, $value1, $value2, $value3) {
    global $servername, $username, $password, $dbname;

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
    }

    $sql = "INSERT INTO SensorData (sensor, location, value1, value2, value3)
    VALUES ('" . $sensor . "', '" . $location . "', '" . $value1 . "', '" . $value2 . "', '" . $value3 . "')";

    if ($conn->query($sql) === TRUE) {
      return "New record created successfully";
    }
    else {
      return "Error: " . $sql . "<br>" . $conn->error;
    }
    $conn->close();
  }
  
  function getAllReadings($limit) {
    global $servername, $username, $password, $dbname;

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
    }

    $sql = "SELECT id, sensor, location, value1, value2, value3, reading_time FROM SensorData order by reading_time desc limit " . $limit;
    if ($result = $conn->query($sql)) {
      return $result;
    }
    else {
      return false;
    }
    $conn->close();
  }
  function getLastReadings() {
    global $servername, $username, $password, $dbname;

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
    }

    $sql = "SELECT id, sensor, location, value1, value2, value3, reading_time FROM SensorData order by reading_time desc limit 1" ;
    if ($result = $conn->query($sql)) {
      return $result->fetch_assoc();
    }
    else {
      return false;
    }
    $conn->close();
  }

  function minReading($limit, $value) {
     global $servername, $username, $password, $dbname;

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
    }

    $sql = "SELECT MIN(" . $value . ") AS min_amount FROM (SELECT " . $value . " FROM SensorData order by reading_time desc limit " . $limit . ") AS min";
    if ($result = $conn->query($sql)) {
      return $result->fetch_assoc();
    }
    else {
      return false;
    }
    $conn->close();
  }

  function maxReading($limit, $value) {
     global $servername, $username, $password, $dbname;

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
    }

    $sql = "SELECT MAX(" . $value . ") AS max_amount FROM (SELECT " . $value . " FROM SensorData order by reading_time desc limit " . $limit . ") AS max";
    if ($result = $conn->query($sql)) {
      return $result->fetch_assoc();
    }
    else {
      return false;
    }
    $conn->close();
  }

  function avgReading($limit, $value) {
     global $servername, $username, $password, $dbname;

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
    }

    $sql = "SELECT AVG(" . $value . ") AS avg_amount FROM (SELECT " . $value . " FROM SensorData order by reading_time desc limit " . $limit . ") AS avg";
    if ($result = $conn->query($sql)) {
      return $result->fetch_assoc();
    }
    else {
      return false;
    }
    $conn->close();
  }
?>

Gruß
Domenico

Hmmm
float pascals = baro.getPressure();
Natürlich ist ( pascals / 100) dann eine Float Division

Das mit der unwirksamen ,0 stimmt natürlich, incl. Warnung.

Eventuell sollte das ursprünglich 100.0 heißen. Macht bei float Sinn.

Gruß, Jürgen

Hallo zusammen.
Ich habe die Zeile auch schon auskommentiert, aber es bleibt bei dieser ersten, korrekten Schleife.
Ab dem 2. Durchlauf werden die Werte, bis auf die temperatur verändert.
Das ist eigentlich unlogisch, da laut Code ja immer wieder die aktuellen Werte ausgelesen werden müssten.
Übrigens bekomme ich bei der /100,0 keinen fehlercode.

Gruß
Domenico

Dann hast du deine Meldungen nicht aktiviert!

"E:\\Programme\\arduino/portable/avr-gcc/avr-gcc-10.0.0_2019-12-16_-mingw32/bin/avr-g++" -c -g -Os -Wall -Wextra -std=gnu++17 -fno-exceptions -fpermissive -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -fno-sized-deallocation -Wall -Wno-volatile -pedantic -Wl,-u,vfprintf "-IE:\\Programme\\arduino\\portable\\packages\\arduino\\hardware\\avr\\1.8.3\\cores\\arduino" "-IE:\\Programme\\arduino\\portable\\packages\\arduino\\hardware\\avr\\1.8.3\\variants\\standard" "-IE:\\Programme\\arduino\\portable\\sketchbook\\libraries\\Streaming" "E:\\temp\\Arduino\\sketch\\sketch_may04a.ino.cpp" -o "E:\\temp\\Arduino\\sketch\\sketch_may04a.ino.cpp.o"
E:\Programme\arduino\portable\sketchbook\sketch_may04a\sketch_may04a.ino: In function 'void setup()':
E:\Programme\arduino\portable\sketchbook\sketch_may04a\sketch_may04a.ino:10:14: warning: right operand of comma operator has no effect [-Wunused-value]
   10 |   pi = pi/3,0;
     |              ^
C
  |

Meinst du die Hinweise im unteren Fenster (Orange dargestellt)?
Ansonsten wüsste ich nicht, wo diese angezeigt werden sollen.

Gruß
Domenico

Bisher konnte ich hier keine Lösung finden.
Scheint ein etwas komplizierteres Problem zu sein.

Gruß
Domenico

Ja.
Unter Datei->Voreinstellungen konfigurierbar.

image

Danke, da war es nicht eingeschaltet.
Habe es nun erledigt.

Gruß
Domenico

Hallo,

ich habe heute herausgefunden, dass der Wert für “pascals” sich nicht mehr verfälscht, wenn ich den Wert “altm” auf 0 setze.
Also wird irgendwo etwas mit der Höhe und dem Luftdruck berechnet.
Was das für einen Sinn macht ist mir rätselhaft.
Es sei denn, man will hier überhaupt keinen Luftdruck ausgeben und hat nur die Höhe und Luftfeuchtigkeit errechnet.
Da kenne ich mich dann auch nicht so gut aus.

Gruß
Domenico