Hallo,
ich habe ein Problem mit meinem ESP8266 und MQTT.
Ich nutze Arduino IDE und die PubSubClient Bibliothek.
MQTT funktioniert soweit. Ich kann Sensordaten empfangen und Nachrichten
an den ESP8266 kommen auch an.
Das einzige was nicht funktioniert ist eine variable per MQTT zu setzen.
Ziel: Ich möchte die Meldezeiten der Sensordaten über eine variable
einstellen.
Umsetzung (vereinfacht, da Prüfung funktionieren):
1
loop() {
2
checkMQTT();
3
}
4
5
volatile int idleTime = 60000; // jede Minute
6
volatile unsigned int lastRun = millis();
7
8
void checkMQTT() {
9
if( millis() - lastRun > idleTime) {
10
// publish sensor data
11
char[10] msg;
12
itoa(idleTime, msg, 10);
13
client.publish(TOPIC_IDLETIME, msg, true);
14
}
15
}
16
17
void callback(char* topic, byte* payload, unsigned int length) {
18
char msg[length+1];
19
for (int i = 0; i < length; i++) {
20
Serial.print((char)payload[i]);
21
msg[i] = (char)payload[i];
22
}
23
msg[length] = '\0';
24
25
if(topic == SET_IDLE) {
26
idleTime = atoi(msg);
27
char[10] msg1;
28
itoa(idleTime, msg1, 10);
29
client.publish(TOPIC_IDLETIME, msg1, true);
30
}
31
}
Wenn ich den Wert 300000 über MQTT sende, dann erhalte ich direkt die
Antwort 300000 über den publish in der callback routine.
Leider bleibt aber idleTime auf 1 Minute da ich danach auf dem topic
TOPIC_IDLETIME 60000 erhalte und auch die Sensordaten jede Minute
kommen.
Habe schon versucht die Variable idleTime static zu setzen aber auch
kein Erfolg. Ich dachte bisher - und so hat es auch immer funktioniert -
das volatile die variable nicht weg optimiert.
idleTime wird nirgendwo anders im code verändert.
Woran könnte das liegen, was muss ich ändern?
Besten Dank für eure Hilfe.
Gruß
Jörg
Jörg schrieb:> void callback(char* topic, byte* payload, unsigned int length) {
...
> if(topic == SET_IDLE) {
Da topic ein char * ist, vermute ich, dass es ein String ist. Strings
kann man in C nicht mit einem einfachen == vergleichen.
Eric B. schrieb:> Jörg schrieb:>> void callback(char* topic, byte* payload, unsigned int length) {> ...>> if(topic == SET_IDLE) {>> Da topic ein char * ist, vermute ich, dass es ein String ist.
Bei MQTT werden alle Nachrichten mit einem "Topic" versendet, der ein
String ist.
> Strings kann man in C nicht mit einem einfachen == vergleichen.
Man vergleicht damit nicht den Inhalt des Strings, sondern die Adresse.
Ein char* ist ja ein Zeiger auf einen char. Es steht also eine Adresse
drin. Bei einem Vergleich wird entspreichend auch diese Adresse
verglichen, nicht der Inhalt des String.
Interessant wäre noch, wie SET_IDLE definiert ist.
Rolf M. schrieb:>> Strings kann man in C nicht mit einem einfachen == vergleichen.>> Man vergleicht damit nicht den Inhalt des Strings, sondern die Adresse.
Genau. ein strcmp() oder stncmp() an der Stelle löst wahrscheinlich das
Problem des TO.
Hallo,
ok, wie ich geschrieben habe, wurde der code vereinfacht.
Ich habe ja geschrieben, dass die Prüfungen stimmen, da ich den
Quelltext zu Hause habe, hab ich es vereinfacht.
1
void checkMQTT() {
2
if( millis() - lastRun > idleTime) {
3
// publish sensor data
4
char[10] msg;
5
itoa(idleTime, msg, 10);
6
client.publish(TOPIC_IDLETIME, msg, true);
7
8
lastRun = millis();
9
10
}
11
}
lastRun = millis habe ich vergessen zu erwähnen, ist aber drin, sonst
würde ich ja nie jede Minute einen Wert über MQTT erhalten.
strcmp verwende ich auch in der if-clause. Das funktioniert ja auch.
Wenn ich einen Wert publishe über topic SET_IDLE, dann melde die
Anwendung auch über MQTT topic TOPIC_IDLETIME die neue Einstellung, die
ich gesendet habe.
Aber max. eine Minute später erhalte ich eine Nachricht über die
Sensordaten und zum Schluss nochmals den Wert TOPIC_IDLETIME.
An dieser Stelle ich der Wert aber wieder auf dem initialen Wert.
Und genau das verstehe ich nicht.
Gruß
Jörg
Mit Codefragmenten, die grob so ähnlich ist wie das, was du tatsächlich
machst und den ganzen Prosa-Beschreibungen dazu werden wir hier nicht
weiter kommen. Zeige echten Code, der nicht so funktioniert, wie
erwartet, dann hat man auch eine Chance, herauszufinden, warum er nicht
funktioniert.
richtig. Vielleicht resettet der ESP auch ständig und startet dann
wieder mit dem 60s voreingestelltem Wert. Lass mal im setup() eine
Glocke läuten um irgendwie anzuzeigen das ein Reset ausgeführt wurde. Im
Broker müsste man das auch sehen wenn der geschwätzig ist.
OH MANN,
# in der subscription vergessen...
Dann funktioniert es auch auf Anhieb.
Fehler 1: Falsche Bedienung MQTT.fx; Publish auf falsches topic.
Fehler 2: # im topic von client.subscribe() vergessen.
Danke für eure Mühen!