No matching function for call

Moin,

ich nutze die PubSubClient.h, sowie die BlueDot_BME280.h

Nun wollte ich per client.publish("Haus/Luftdruck/Wohnzimmer", bme1.readPressure()); eine MQTT message absetzen, aber ich bekomme die Fehlermeldung:
"no matching function for call to 'PubSubClient::publish(const char[49], float)'"

In der BlueDot_BME280.h ist readPressure als float definiert: float readPressure(void);

Wo liegt der Fehler?

Beste Grüße,
Chris

Normaler weise zeigt es auch die Alternativen.
Wie wäre es mit "Ausführliche Meldungen aktivieren" und diese mal zu zeigen.

Ich sehe hier Arduino Client for MQTT dass kein float erwartet wird, sondern ein C-String.

C:\Users\Chris\AppData\Local\Temp\arduino_modified_sketch_889405\Bootsschuppen_Repeater_007.ino: In function 'void sendHttpData(String)':
C:\Users\Chris\AppData\Local\Temp\arduino_modified_sketch_889405\Bootsschuppen_Repeater_007.ino:55:31: warning: 'bool HTTPClient::begin(String, uint16_t, String)' is deprecated (declared at C:\Users\Chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:175) [-Wdeprecated-declarations]
     http.begin(host, port, url); //HTTP
                               ^
C:\Users\Chris\AppData\Local\Temp\arduino_modified_sketch_889405\Bootsschuppen_Repeater_007.ino:56:9: warning: unused variable 'httpCode' [-Wunused-variable]
     int httpCode = http.GET();
         ^
C:\Users\Chris\AppData\Local\Temp\arduino_modified_sketch_889405\Bootsschuppen_Repeater_007.ino: In function 'void loop()':
Bootsschuppen_Repeater_007:152:64: error: no matching function for call to 'PubSubClient::publish(const char [26], float)'
 client.publish("Haus/Luftdruck/Wohnzimmer", bme1.readHumidity());         // ------------------Daten senden-----------------
                                                                ^
C:\Users\Chris\AppData\Local\Temp\arduino_modified_sketch_889405\Bootsschuppen_Repeater_007.ino:152:64: note: candidates are:
In file included from C:\Users\Chris\AppData\Local\Temp\arduino_modified_sketch_889405\Bootsschuppen_Repeater_007.ino:5:0:
C:\Users\Chris\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.h:151:12: note: boolean PubSubClient::publish(const char*, const char*)
    boolean publish(const char* topic, const char* payload);
            ^
C:\Users\Chris\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.h:151:12: note:   no known conversion for argument 2 from 'float' to 'const char*'
C:\Users\Chris\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.h:152:12: note: boolean PubSubClient::publish(const char*, const char*, boolean)
    boolean publish(const char* topic, const char* payload, boolean retained);
            ^
C:\Users\Chris\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.h:152:12: note:   candidate expects 3 arguments, 2 provided
C:\Users\Chris\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.h:153:12: note: boolean PubSubClient::publish(const char*, const uint8_t*, unsigned int)
    boolean publish(const char* topic, const uint8_t * payload, unsigned int plength);
            ^
C:\Users\Chris\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.h:153:12: note:   candidate expects 3 arguments, 2 provided
C:\Users\Chris\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.h:154:12: note: boolean PubSubClient::publish(const char*, const uint8_t*, unsigned int, boolean)
    boolean publish(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained);
            ^
C:\Users\Chris\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.h:154:12: note:   candidate expects 4 arguments, 2 provided

Demnach will er anstelle von float wohl const char* haben?!
Wie stelle ich das nun wieder an?

Vielen Dank und beste Grüße,
Chris

Z.B. den Druck mit snprintf() in einen char-Array schreiben und den übergeben.

Ich fische im Trüben?!

client.publish("Haus/Luftfeuchtigkeit/Wohnzimmer", snprintf(msg, 50, "Luftfeuchtigkeit BME280 %.2f", bme1.readHumidity());

Any hint?

Okay, bin wieder weiter gekommen:

 snprintf(msg, 50, bme1.readHumidity());
 client.publish("Haus/Luftdruck/Wohnzimmer", msg); 

Funzt aber immer noch nicht.
Hat jemand einen Tipp?

Gefunden :slight_smile:

  snprintf(msg, 50, "%.2f", bme1.readHumidity());
  client.publish("Haus/Luftdruck/Wohnzimmer", msg);

oder

char msg[30];
dtostrf(bme1.readHumidity(),3,2,msg);
client.publish("Haus/Luftdruck/Wohnzimmer", msg); 

Yep, genau so.

Kleine Anmerkung:
Dein Puffer msg muss in diesem Fall 50 Zeichen haben. Wenn die Zahlen üblicherweise kürzer sind, liegt da Sparpotential.
Der Formatierung der Zahl mit %X.Yf kannst Du bei X auch eine Gesamtlänge incl. Punkt mitgeben. Ich weiß nicht, ob das mqtt mit Leerzeichen in der Nummer umgehen kann. Falls nicht, kannst Du auch mit linksbündigen Nullen auffüllen: %07.2f - sieben Zeichen insgesamt, vier vor dem Punkt (ggf. mit 0 aufgefüllt), der Punkt und zwei dahinter.

Hier noch eine Ergänzung zu dem Thema:
C Referenz -printf Formatierungszeichen-. (hs-esslingen.de)

Was mir noch aufgefallen ist: Irgendwo scheint es einen Rundungsfehler zu geben!
Auf dem seriellen Monitor kommt: 23,813, in MQTT kommt 23,812
Auf dem seriellen Monitor kommt: 24,313, in MQTT kommt 24,312
Auf dem seriellen Monitor kommt: 23,563, in MQTT kommt 23,562

Woran liegt's?
Der serielle Monitor rundet auf drei Stellen, und snprintf schneidet die Zahl einfach ab, nehme ich an?! Gut dann mach ich es halt beides auf vier Stellen :laughing:

...is natürlich Quatsch. 3 Stellen sind eigentlich schon fast zwei zu viel. Ich lasse es bei 3 Stellen...

Jetzt wird die Sache interessant!
In MQTT sind mir bisher keine Probleme mit Leerzeichen aufgefallen, das sieht ganz normal aus.
Hier mal die entscheidenden Stellen aus dem Code:

#define MSG_BUFFER_SIZE  (50)
char msg[MSG_BUFFER_SIZE];

snprintf(msg, 50, "%.2f", bme1.readHumidity());
client.publish("Bootsschuppen/Luftfeuchtigkeit/RepeaterBME280_01", msg);

snprintf(msg, 50, "%.2f", bme1.readPressure());
client.publish("Bootsschuppen/Luftdruck/RepeaterBME280_01", msg);

snprintf(msg, 50, "%.2f", bme1.readTempC());
client.publish("Bootsschuppen/Temperatur/T41RepeaterBME280_01", msg); 

snprintf(msg, 50, "%.3f", temp1);
client.publish("Bootsschuppen/Temperatur/T63RepeaterUnter1260e", msg);

snprintf(msg, 50, "%.3f", temp2);
client.publish("Bootsschuppen/Temperatur/T64RepeaterÜber1260e", msg);

snprintf(msg, 50, "%.3f", temp3);
client.publish("Bootsschuppen/Temperatur/T65Innen", msg);

snprintf(msg, 50, "%.3f", temp4);
client.publish("Bootsschuppen/Temperatur/T66Aussen", msg); 

aktuelle Werte sind:

Bootsschuppen/Temperatur/T63RepeaterUnter1260e     "21.750"
Bootsschuppen/Temperatur/T64RepeaterÜber1260e      "21.625"
Bootsschuppen/Temperatur/T65Innen                  "21.750"
Bootsschuppen/Temperatur/T66Aussen                 "21.438"
Bootsschuppen/Luftfeuchtigkeit/RepeaterBME280_01   "46.57"
Bootsschuppen/Luftdruck/RepeaterBME280_01          "1006.39"
Bootsschuppen/Temperatur/T41RepeaterBME280_01      "22.37"  

Im Winter können die Temperaturen natürlich auch noch negativ werden!

Mit Vorzeichen (für den Winter) müsste ich die 50 doch auf 7 eindampfen können, richtig?

MIndestens 8.
Vorzeichen
2 Stellen vor dem Komma
Komma
3 Stellen nach dem Komma
Abschliessendes \0

Im Übrigen:

Du weist, das da auch Toleranzen noch mit reinspielen?
Beim BME280 für die Temp 1°C zwischen 0 und 65°C
etc. pp.

Richtig (unter der Annahme, dass es nie kälter als -99.999°C wird :slight_smile: )!
Der Buffer braucht dann mit acht Zeichen eines mehr für die abschließende \0.

Mist - zu langsam.

Richtig, den Abschluss hatte ich vergessen. Hab's eben noch selber gelesen und wollte es noch auf 8 korrigieren. Gut, ihr ward schneller, dann lasse ich es so für die Nachwelt stehen.

Was mir noch nicht so ganz klar ist, (bin ja wieder Jungfrau, nach anhaltender Abstinenz zum programmieren :roll_eyes:)
Warum wird am Anfang die Buffer Size auf 50 Zeichen deklariert, und unten dann nochmal die 50 im snprintf(); angegeben? Ich kann an beiden Stellen auf 8 runter, richtig?
Wenn ich jetzt oben die Buffer Size auf 8 einstelle, was bewirken dann andere Werte im snprintf();?
Könnte ich z.B. bei der Luftfeuchtigkeit runter auf 6?
Und bei der T41RepeaterBME280_01 (die hat nur zwei Nachkommastellen) runter auf 7?

Nee, vier Temperaturen kommen von DS18b20, die gebe ich mit drei Nachkommastellen aus (die eine Temperatur vom BME280 nur mit zwei Nachkommastellen).
Ausgelesen wurde nur 1x, aber dann auch verschiedenen Wegen ausgegeben.
Ich habe in der Zwischenzeit die Nachkommastellen testweise erhöht, und dann sah es so aus:
Seriell: 23,8125 und MQTT 23,8125
Bei Seriell wurde auf 23,813 gerundet und bei MQTT wurde bei 23,812 abgeschnitten.

Oben sagst Du wie gross der buffer ist.
Im snprintf weiss das keiner, wie weit geschrieben werden darf.
Du könntest ja auch nur bis 10 schreiben wollen, daher gibst Du an, bis wohin maximal geschrieben werden kann.
Gehst Du in snprintf über sizeof(array) hinaus, kommt es zu komischen Effekten. :wink:

Wenn das da oben die Temperaturen sind.. kann es sein, das die nicht 12bit resolution machen?
[edit]
Was ich meine steht im Datenblatt unter "Operation—Measuring Temperature" - Mir erscheint der Sprung 23,8 ->24,5 sehr verdächtig. - Alles andere danach ist nichts.
[/edit]
Die Genauigkeit ist übrigens auch da mit +-0,5°C bei -10 bis +85

Das hat nichts mit den Sensoren zu tun.
I tried this:

  float temp3 = 77.8125000;
  Serial.println(temp3, 3);
  snprintf(msg, 10, "%.3f", temp3);
  client.publish("Bootsschuppen/Temperatur/T65Innen", msg);

Ausgabe:
Serieller Monitor: 77.813
MQTT: 77.812