Konvertierung atof()

Hallo zusammen,
ich wäre dankbar wenn mir jemand auf die Sprünge helfen könnte.
Ich habe eine Temperaturregelung geschrieben, welche einen Temperatur-Sollwert (im Code SollTemp) im Wertebereich 0 bis 25 über MQTT übermittelt bekommt. Der Wert kommt auch an, wird jedoch von der Regelung nicht ausgewertet. Ich vermute dass das Problem bei atof() Zeile 38 liegt, bin mir jedoch nicht sicher.
Dank und Gruß
Thomas

/*
PIN Belegung:
Gnd = Gnd BMP
3V = VIN BMP
D1 = SCL BMP
D2 = SDA BMP = 4
D5 = Relais = 14
D6 = LED Gruen = 12
D7 = LED Rot = 13
*/

//Bibliotheken
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
Adafruit_BMP085 bmp; // I2C

WiFiClient espClient;  
PubSubClient client(espClient); 

//WLAN Variablen
#define wifi_ssid "WLAN-xxxxx"
#define wifi_password "xxxxx"
#define mqtt_server "192.168.2.115"
   
//MQTT Variablen
#define Temperatur_topic "esp01/Temperatur"               //Temperatur
#define Schalter_topic "esp01/Schalter"                   //Schaltbefehl vom NodeRed
#define Soll_Temperatur_topic "esp01/Soll_Temperatur"     //Temperatur SOLL- Wert vom Node Red
#define Relais_Status_topic "esp01/Relais_Status"         //Status Heizung an Node Red
#define Regler_Status_topic "esp01/Regler_Status"         //Status Regelung an Node Red

const int Green = 12;                                     //LED AUS
const int Red = 13;                                       //LED EIN
const int Relais = 14;                                    //Heizung ist EIN
const int Schalter = 15;                                  //nur zum testen ob Regelung EIN ist!
float SollTemp = atof("Soll_Temperatur_topic");           //Konvertiere Temperatur Soll-Wert String to float

//###############################################################
    
 void setup() {  
  Serial.begin(115200);   
  setup_wifi();
  
  // MQTT Broker Port festlegen   
  client.setServer(mqtt_server, 1883); 
  client.setCallback(callback);  
  
  // GPIO PINS definieren ...
  pinMode(Green, OUTPUT);
  pinMode(Red, OUTPUT);
  pinMode(Relais, OUTPUT);
  pinMode(Schalter, OUTPUT);                              

  // ... und erstmal auf LOW setzen
  analogWrite(Green, 1);
  analogWrite(Red, 0);
  digitalWrite(Relais, LOW);
  digitalWrite(Schalter, LOW);

 
  // BMP280 verbinden
  if (!bmp.begin()) 
  {
    Serial.println(F("Sensorfehler!"));
    while (1);
  }

}  

//###############################################################
   
 void loop() {  
  if (!client.connected()) {  
    reconnect();  
  }
  client.loop();

  //Variablen zur Berechnung der Realtemperatur abzüglich Fehler
  float a = (bmp.readTemperature());
  float b = 1.3;
  float Temperatur = a - b;
  client.publish(Temperatur_topic, String(Temperatur).c_str(), true);         //sende Temperatur an MQTT

  // Temperaturregler  aktiviert
  if (digitalRead(Schalter) == HIGH){
  client.publish(Regler_Status_topic, "EIN");                                 //melde an MQTT dass Regler_Status EIN geschaltet wurde
  }                   
  else{
  client.publish(Regler_Status_topic, "AUS");                                 //melde an MQTT dass Regler_Status AUS geschaltet wurde
  }
  delay(100);
   
  // Temperaturregler  
  if ((Temperatur <= (SollTemp)) && (digitalRead(Schalter) == HIGH)){ 
  analogWrite(Green, 0);
  analogWrite(Red, 1);                              
  digitalWrite(Relais, HIGH);
  client.publish(Relais_Status_topic, "EIN");                                 //melde an MQTT dass EIN geschaltet wurde

  }                   
  else{
  analogWrite(Green, 1);
  analogWrite(Red, 0);                                           
  digitalWrite(Relais, LOW);
  client.publish(Relais_Status_topic, "AUS");                                 //melde an MQTT dass EIN geschaltet wurde
  }
 delay(500);
}
 
//###############################################################
   
 void setup_wifi() {  
  delay(10);
    
  // Per WLAN mit dem Netzwerk verbinden  
  Serial.println();  
  Serial.print("Connecting to ");  
  Serial.println(wifi_ssid);  
  WiFi.begin(wifi_ssid, wifi_password);  
  while (WiFi.status() != WL_CONNECTED) {  
   Serial.print("."); 
   delay(500);  
  }
    
  Serial.println("");  
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");  
  Serial.println(WiFi.localIP());
 
 }  

//###############################################################

  //Nachrichtenverarbeitung
  void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Nachricht empfangen von topic: ");
  Serial.print(topic);
  Serial.print(". Nachricht: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  if (String(topic) == "esp01/Schalter") {
    Serial.print("Changing output to ");
    
    if(messageTemp == "on"){                  //wenn eingegangene Nachricht  = on
      digitalWrite(Schalter, HIGH);           //schalte Schalter EIN
      delay(200);
    }
    else if(messageTemp == "off"){            //wenn eingegangene Nachricht = off
       digitalWrite(Schalter, LOW);           //schalte Schalter AUS
      delay(200);
    }
  }
}

//###############################################################

 void reconnect() {
  
  // Schleife bis zur nächsten Verbindung
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    
    // Erzeuge zufällige Client ID
    String clientId = "ESP8266-";
    clientId += String(random(0xffff), HEX);
    
    // Verbindung herstellen
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      
      // Verbindung hergestellt
      // ... and resubscribe
      client.subscribe(Schalter_topic);
      client.subscribe(Soll_Temperatur_topic);
    } else {
        Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 5 seconds");
        // Wait 5 seconds before retrying
        delay(5000);
      }
   }
}

du hast definitiv recht :wink:

Verstehst du, was die Callback-Funktion macht?

???

Den empfangenen Wert im seriellen Monitor anzeigen lassen.
Dann siehst du, was da übertragen wird.

Gegenprüfung durch Angabe eines festen Wertes am Empfängersketch.

atof() ist dazu da einen C String wie "43.5" in eine Zahl zu konvertieren

atof() lässt Sie keine falsche Eingabe erkennen (sagt 0).
Wenn das wichtig ist, kann strtod() helfen. ➜ https://www.cplusplus.com/reference/cstdlib/strtod/

Ich gebe zu leider nicht.

Im Serial Monitor wird mir genau der Wert angezeigt den ich im Node Red Dashbord eingebe, also dann 18 dann 18 usw.

Genau das will ich ja. Ich gebe einen ganzzahligen Wert ohne Dezimalstellen als Sollwert vor. Der Sensor gibt jedoch einen Wert mit 2 Dezimalstellen an. Die beiden will ich nun vergleichen dazu will ich dem Sensorwert die 2 Dezimalstellen entfernen.

Abschneiden der Nachkommastellen --> weise dem Wert einer int-Variable zu.
oder runden --> nutze round().

Gruß Tommy

Hab Round probiert, es geht nicht, ich raff es nicht ... :pensive:

Fehlermeldung:
"ISO C++ forbids comparison between pointer and integer [-fpermissive]"

/*
PIN Belegung:
Gnd = Gnd BMP
3V = VIN BMP
D1 = SCL BMP
D2 = SDA BMP = 4
D5 = Relais = 14
D6 = LED Gruen = 12
D7 = LED Rot = 13
*/

//Bibliotheken
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
Adafruit_BMP085 bmp; // I2C

WiFiClient espClient;  
PubSubClient client(espClient); 

//WLAN Variablen
#define wifi_ssid "WLAN-xxxx"
#define wifi_password "xxxx"
#define mqtt_server "192.168.2.115"
   
//MQTT Variablen
#define Temperatur_topic "esp01/Temperatur"               //Temperatur
#define Schalter_topic "esp01/Schalter"                   //Schaltbefehl vom NodeRed
#define Soll_Temperatur_topic "esp01/Soll_Temperatur"     //Temperatur SOLL- Wert vom Node Red
#define Relais_Status_topic "esp01/Relais_Status"         //Status Heizung an Node Red
#define Regler_Status_topic "esp01/Regler_Status"         //Status Regelung an Node Red

const int Green = 12;                                     //LED AUS
const int Red = 13;                                       //LED EIN
const int Relais = 14;                                    //Heizung ist EIN
const int Schalter = 15;                                  //nur zum testen ob Regelung EIN ist!


//###############################################################
    
 void setup() {  
  Serial.begin(115200);   
  setup_wifi();
  
  // MQTT Broker Port festlegen   
  client.setServer(mqtt_server, 1883); 
  client.setCallback(callback);  
  
  // GPIO PINS definieren ...
  pinMode(Green, OUTPUT);
  pinMode(Red, OUTPUT);
  pinMode(Relais, OUTPUT);
  pinMode(Schalter, OUTPUT);                              

  // ... und erstmal auf LOW setzen
  analogWrite(Green, 1);
  analogWrite(Red, 0);
  digitalWrite(Relais, LOW);
  digitalWrite(Schalter, LOW);

 
  // BMP280 verbinden
  if (!bmp.begin()) 
  {
    Serial.println(F("Sensorfehler!"));
    while (1);
  }

}  

//###############################################################
   
 void loop() {  
  if (!client.connected()) {  
    reconnect();  
  }
  client.loop();

  //Variablen zur Berechnung der Realtemperatur abzüglich Fehler
  float a = (bmp.readTemperature());
  float b = 1.3;
  float Temperatur_float = a - b;
  Serial.print("Temperatur Sensor: ");
  Serial.println(Temperatur_float);

  int IstTemp = round(Temperatur_float);
  
  client.publish(Temperatur_topic, String(Temperatur_float).c_str(), true);   //sende Temperatur an MQTT

  delay(200);

  // Temperaturregler  aktiviert
  if (digitalRead(Schalter) == HIGH){
  client.publish(Regler_Status_topic, "EIN");                                 //melde an MQTT dass Regler_Status EIN geschaltet wurde
  }                   
  else{
  client.publish(Regler_Status_topic, "AUS");                                 //melde an MQTT dass Regler_Status AUS geschaltet wurde
  }
  delay(100);
   
  // Temperaturregler  
  if (((IstTemp) <= (Soll_Temperatur_topic)) && (digitalRead(Schalter) == HIGH)){ 
  analogWrite(Green, 0);
  analogWrite(Red, 1);                              
  digitalWrite(Relais, HIGH);
  client.publish(Relais_Status_topic, "EIN");                                 //melde an MQTT dass EIN geschaltet wurde

  }                   
  else{
  analogWrite(Green, 1);
  analogWrite(Red, 0);                                           
  digitalWrite(Relais, LOW);
  client.publish(Relais_Status_topic, "AUS");                                 //melde an MQTT dass EIN geschaltet wurde
  }
 delay(500);
}
 
//###############################################################
   
 void setup_wifi() {  
  delay(10);
    
  // Per WLAN mit dem Netzwerk verbinden  
  Serial.println();  
  Serial.print("Connecting to ");  
  Serial.println(wifi_ssid);  
  WiFi.begin(wifi_ssid, wifi_password);  
  while (WiFi.status() != WL_CONNECTED) {  
   Serial.print("."); 
   delay(500);  
  }
    
  Serial.println("");  
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");  
  Serial.println(WiFi.localIP());
 
 }  

//###############################################################

  //Nachrichtenverarbeitung
  void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Nachricht empfangen von topic: ");
  Serial.print(topic);
  Serial.print(". Nachricht: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  if (String(topic) == "esp01/Schalter") {
    Serial.print("Changing output to ");
    
    if(messageTemp == "on"){                  //wenn eingegangene Nachricht  = on
      digitalWrite(Schalter, HIGH);           //schalte Schalter EIN
      delay(200);
    }
    else if(messageTemp == "off"){            //wenn eingegangene Nachricht = off
       digitalWrite(Schalter, LOW);           //schalte Schalter AUS
      delay(200);
    }
  }
}

//###############################################################

 void reconnect() {
  
  // Schleife bis zur nächsten Verbindung
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    
    // Erzeuge zufällige Client ID
    String clientId = "ESP8266-";
    clientId += String(random(0xffff), HEX);
    
    // Verbindung herstellen
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      
      // Verbindung hergestellt
      // ... and resubscribe
      client.subscribe(Schalter_topic);
      client.subscribe(Soll_Temperatur_topic);
    } else {
        Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 5 seconds");
        // Wait 5 seconds before retrying
        delay(5000);
      }
   }
}

Hallo ,
MQTT hab ich bisher nicht verwendet,insofern hab ich das nicht ganz verstanden was Du vorhast.

was willst Du eigentlich mit der Zeile bezwecken.

Du definierst eine variable SollTemp als float und weist Ihr den Wert von atof("yxz") zu , wobei xyz eine Zeichenkette ohne eine Zahl ist.

Wo soll denn der Wert von SollTemp letztlich her kommen. ? Deiner Aussagen nach kommt der über MQTT rein. Nur finde ich das nirgends, das müsste ja irgendwie in/durch die callback zugewiesen werden, oder bin ich da auf dem Holzweg.
Letztlich geht es dir doch um die Zeile

bei der anscheinend was nicht richtig funktioniert. Dabei liegt Temperatur als float vor und SollTemp ebenfalls , aber sicher mit dem Wert 0

Last dir das doch mal anzeigen unmittelbar vor dem Vergleich anzeigen.

Serial.print(Sollwert); Serial.print(SollTemp);

Heinz

Ich bin jetzt ebenfalls über #3 gestolpert. Warum sehe ich im Bereich Nachrichtenverarbeitung da inhaltlich nichts, was Deine Soll-Temperatur verarbeiten kann.

Das muss doch irgendwie soo aussehen:
Und erst dann macht es Sinn sich das mit dem SerMon zu debuggen....

//###############################################################

  //Nachrichtenverarbeitung
  void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Nachricht empfangen von topic: ");
  Serial.print(topic);
  Serial.print(". Nachricht: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i],HEX) Serial.print(" ");
    messageTemp += (char)message[i];
    Serial.println(messageTemp);
  }
  Serial.println();

  if (String(topic) == "esp01/Schalter") {
    Serial.print("Changing output to ");
    
    if(messageTemp == "on"){                  //wenn eingegangene Nachricht  = on
      digitalWrite(Schalter, HIGH);           //schalte Schalter EIN
      delay(200);
    }
    else if(messageTemp == "off"){            //wenn eingegangene Nachricht = off
       digitalWrite(Schalter, LOW);           //schalte Schalter AUS
      delay(200);
    }
  }
  if (String(topic) == ("Soll_Temperatur_topic");
  {
    // Hier werte messageTemp aus!
  }
}
//###############################################################

Und dann gehe mal in den ersten Post und ändere den Betreff - atif ist nichts. :wink:

Hallo zusammen,
danke für die Unterstützung, ich habs noch mal komplett neu geschrieben , die letzten beiden Antworten haben mich auf den richtigen Weg gebracht.
Wen's interessiert hier noch mal der funktionierende Code und das Dashboard im NodeRed.

/*
13.02.2022

PIN Belegung:
Gnd = Gnd BMP
3V = VIN BMP
D1 = SCL BMP
D2 = SDA BMP = 4
D5 = Relais = 14
D6 = LED Green = 12
D7 = LED Red = 13
*/

//Bibliotheken
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
Adafruit_BMP085 bmp; // I2C

WiFiClient espClient;  
PubSubClient client(espClient); 

//WLAN
#define WIFI_SSID "WLAN-xxx"
#define WIFI_PASSWORD "xxx"
   
//MQTT
#define MQTT_SERVER "192.168.2.115"
#define MQTT_TOPIC_SENSOR "esp01/Sensor"                             
#define MQTT_TOPIC_SCHALTER "esp01/Schalter"                         
#define MQTT_TOPIC_REGLER_STATUS "esp01/Regler_Status"               
#define MQTT_TOPIC_RELAIS_STATUS "esp01/Relais_Status"               
#define MQTT_TOPIC_SOLL_TEMP "esp01/SollTemp"                        

const int Green = 12;                                               
const int Red = 13;                                       
const int Relais = 14;                                    
bool Regler_var = false;                                  
float TempSoll = 0.00;

//--- SETUP ---
    
 void setup() {  
  Serial.begin(115200);   
  setup_wifi();
  
  // MQTT Broker Port festlegen   
  client.setServer(MQTT_SERVER, 1883);
  client.setCallback(callback);  
  
  // GPIO PINS definieren ...
  pinMode(Green, OUTPUT);
  pinMode(Red, OUTPUT);
  pinMode(Relais, OUTPUT);
     
  // ... und erstmal auf LOW setzen
  analogWrite(Green, 1);
  analogWrite(Red, 0);
  digitalWrite(Relais, LOW);

  // BMP280 verbinden
  if (!bmp.begin()) 
  {
    Serial.println(F("Sensorfehler!"));
    while (1);
  }

}  

//--- LOOP ---
   
 void loop() {  
  if (!client.connected()) {  
    reconnect();  
  }
  client.loop();

  //Variablen zur Berechnung der Realtemperatur abzüglich Fehler
  float a = (bmp.readTemperature());
  float b = 1.3;
  float Temperatur_korr = a - b;
  client.publish(MQTT_TOPIC_SENSOR, String(Temperatur_korr).c_str(), true);             //sende Sensorwert an NodeRed
  
  //Temperaturregler
  if (((Temperatur_korr) <= (TempSoll)) && ((Regler_var) == true)){
  analogWrite(Green, 0);
  analogWrite(Red, 1);                              
  digitalWrite(Relais, HIGH);
  client.publish(MQTT_TOPIC_RELAIS_STATUS, "EIN");
  }
  else{
  analogWrite(Green, 1);
  analogWrite(Red, 0);                                           
  digitalWrite(Relais, LOW);
  client.publish(MQTT_TOPIC_RELAIS_STATUS, "AUS");
  }
  
  Serial.print("Temperatur IST: ");
  Serial.println(Temperatur_korr);
  Serial.print("Temperatur Soll: ");
  Serial.println(TempSoll);
  Serial.print("Regler Status: ");
  Serial.println(Regler_var);
  Serial.println(" ");
  delay(500);
}
 
//--- WLAN ---
   
 void setup_wifi() {  
  delay(10);
    
  // Per WLAN mit dem Netzwerk verbinden  
  Serial.println();  
  Serial.print("Connecting to ");  
  Serial.println(WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {  
   Serial.print("."); 
   delay(500);  
  }
    
  Serial.println("");  
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");  
  Serial.println(WiFi.localIP());
 
 }  

//--- NACHRICHTENVERARBEITUNG ---

void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Nachricht empfangen von topic: ");
  Serial.print(topic);
  Serial.print(". Nachricht: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();
  
  if (String(topic) == MQTT_TOPIC_SCHALTER) {
    
    if(messageTemp == "on"){                  
      Regler_var = true;                      
      Serial.print("Regler: ");
      Serial.println(Regler_var);
      client.publish(MQTT_TOPIC_REGLER_STATUS, "EIN");
      delay(200);
    }
    else if(messageTemp == "off"){           
      Regler_var = false;                     
      Serial.print("Regler: ");
      Serial.println(Regler_var);
      client.publish(MQTT_TOPIC_REGLER_STATUS, "AUS");
      delay(200);
    }
  }
  if (String(topic) == MQTT_TOPIC_SOLL_TEMP) {
    TempSoll = messageTemp.toFloat();
    Serial.print("TempSoll: ");
    Serial.println(TempSoll);
  }
}

//--- RECONNECT ---

 void reconnect() {
  
  // Schleife bis zur nächsten Verbindung
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    
    // Erzeuge zufällige Client ID
    String clientId = "ESP8266-";
    clientId += String(random(0xffff), HEX);
    
    // Verbindung herstellen
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      
      // Verbindung hergestellt
      // ... and resubscribe
      client.subscribe(MQTT_TOPIC_SCHALTER);
      client.subscribe(MQTT_TOPIC_SOLL_TEMP);
    } else {
        Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 5 seconds");
        // Wait 5 seconds before retrying
        delay(5000);
      }
   }
   
}

Gruß
Thomas

Hallo,
schön das es geklappt hat, danke für die Rückmeldung,
Heinz

Bist du dir hier sicher ?
Du verwendest doch digitale Pins. Oder möchtest du die Helligkeit verändern ?

Ja das war Absicht, die LED-s sollen nur "glimmen".

Ok, alles klar.