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);
}
}
}
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.
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.
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.
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);
}
}
}