Closed phototobi closed 5 years ago
Hi, schwer, kannst ja mal in den einzelnen callback methoden serial prints einbauen und schauen ob die werte da auch ankommen. Ansonsten, in ZEile 271 haste geändert?
Hallo nochmal, stehe noch ganz am Anfang mit dem Kram hier: Wie geht das mit den Serial Print outs? /* CONFIG END *****/
// Multiple WiFi connections ESP8266WiFiMulti multi;
// Create an ESP8266 WiFiClient class to connect to the MQTT server. WiFiClient client; PubSubClient mqtt(client);
double currentTemp = 0.0; double currentVoltage = 0.0; double currentHum = 0.0; double currentBaro = 0.0; const int timeout = 5;
// Define some display states int state = 0;
// how long to wait until switching state
// millis of last switch long lastSwitch = 0;
// ICONS const unsigned char temp_icon [] = { 0x08, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0xF8, 0x14, 0x00, 0x14, 0xF8, 0x14, 0x00, 0x14, 0xF8, 0x14, 0x00, 0x14, 0x00, 0x22, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x22, 0x00, 0x1C, 0x00 }; const unsigned char humidity [] = { 0x00, 0x80, 0x01, 0xC0, 0x01, 0xC0, 0x03, 0x60, 0x03, 0x60, 0x06, 0x30, 0x06, 0x30, 0x0E, 0x38, 0x1C, 0x1C, 0x18, 0x0C, 0x30, 0x06, 0x30, 0x06, 0x18, 0x0C, 0x1C, 0x1C, 0x0F, 0xF8, 0x07, 0xF0 }; const unsigned char pressure [] = { 0x00, 0x3C, 0x00, 0x47, 0x00, 0xC1, 0x00, 0x83, 0x01, 0x02, 0x04, 0xFE, 0x08, 0x00, 0x1F, 0xFC, 0x08, 0x00, 0x24, 0x00, 0x40, 0x00, 0xFF, 0xE8, 0x40, 0x04, 0x2F, 0xFE, 0x00, 0x04, 0x00, 0x08 };
void barocallback(double p) { currentBaro = p; }
void humcallback(double h) { currentHum = h; }
void tempcallback(double t) { currentTemp = t; }
void lipocallback(double v) { currentVoltage = v; }
void callback(char topic, byte payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]);
//Serial.print(currentBaro);
//Serial.print(currentHum);
//Serial.print(currentTemp);
//Serial.print(currentVoltage);
}
Serial.println();
// we know there will be only double data as payload, so ...
double dValue = atof((char *) payload);
if(strcmp(topic, TOPIC_TEMPERATURE) == 0)
tempcallback(dValue);
else if(strcmp(topic, TOPIC_VOLTAGE) == 0)
lipocallback(dValue);
else if(strcmp(topic, TOPIC_HUMIDITY) == 0)
humcallback(dValue);
else if(strcmp(topic, TOPIC_BAROMETRIC) == 0)
barocallback(dValue);
}
/*
void setup() { Serial.begin(9600);
multi.addAP(ssid1, password1); multi.addAP(ssid2, password2); multi.addAP(ssid3, password3);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 64x48)
// Clear the buffer. display.clearDisplay(); display.dim(1); display.setTextWrap(false); // show "welcome" screen display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(14,0); display.print("ESP"); display.setCursor(8,17); display.print("8266"); display.setTextSize(1); display.setCursor(11,40); display.print("Climate"); display.display(); delay(2000);
display.clearDisplay(); display.setTextWrap(true); Serial.println("Connecting Wifi..."); display.setCursor(0,4); display.print("Connecting Wifi"); display.display(); delay(500);
display.setTextWrap(false); int fake = 3; while(fake != 0) { display.setCursor(23,display.height()-8); display.setTextColor(BLACK); display.print("..."); display.display(); delay(400); display.setTextColor(WHITE); display.setCursor(23,display.height()-8); display.print("."); display.display(); delay(250); display.print("."); display.display(); delay(250); display.print("."); display.display(); delay(500); fake--; } int c = 0; while(multi.run() != WL_CONNECTED || c >= timeout) { Serial.println("next wifi connect try in 1s"); delay(1000); c++; } if(c >= timeout) while(1); // WDT reset
// remove 3 dots (if there are some) display.setCursor(23,display.height()-8); display.setTextColor(BLACK); display.print("..."); display.setTextColor(WHITE); display.setCursor(5,display.height()-8); display.print("connected"); display.display(); delay(500); Serial.println(""); Serial.println("WiFi connected"); Serial.print("WiFi SSID: "); Serial.println(WiFi.SSID()); Serial.print("IP address: "); Serial.println(WiFi.localIP());
mqtt.setServer(HOST, PORT); mqtt.setCallback(callback);
display.clearDisplay(); display.setCursor(8,15); display.print("fetching"); display.setCursor(20,24); display.print("data"); display.display(); delay(1500); }
void reconnect() { // Loop until we're reconnected while (!mqtt.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (mqtt.connect("ESP8266-OLED", USERNAME, PASSWORD)) { Serial.println("connected"); // ... and resubscribe mqtt.subscribe("node/oled/#"); } else { Serial.print("failed, rc="); Serial.print(mqtt.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } }
void loop() { // make sure we're connected if (!mqtt.connected()) { reconnect(); } mqtt.loop();
// show the values drawValues(); long now = millis(); if(lastSwitch == 0) lastSwitch = now; int waited = now - lastSwitch; // time to switch display values? if(waited >= WAIT_SECONDS * 1000) { lastSwitch = now; state++; if(state > 2) state = 0; } }
Das kompiliert so?
also
int h = (currentBaro);
sollte
int h = (int) currentBaro;
sein.
Ansonsten so das serial logging machen:
void barocallback(double p) {
currentBaro = p;
Serial.print("callback baro: ");
Serial.println(currentBaro);
}
void humcallback(double h) {
currentHum = h;
Serial.print("callback hum: ");
Serial.println(currentHum);
}
void tempcallback(double t) {
currentTemp = t;
Serial.print("callback temp:");
Serial.println(currentTemp);
}
void lipocallback(double v) {
currentVoltage = v;
Serial.print("callback voltage: ");
Serial.println(currentVoltage);
}
PS: Kannst Du noch den Teil der Config posten wo Du diese TOPIC_TEMPERATURE
und so setzt?
Also den Teil:
// Topics, change if yours are different
#define TOPIC_TEMPERATURE "weatherStation/temperature"
#define TOPIC_VOLTAGE "weatherStation/voltage"
#define TOPIC_HUMIDITY "weatherStation/humidity"
#define TOPIC_BAROMETRIC "weatherStation/barometric"
Hallo, kompilieren ging tatsächlich, habe aber deinen Rat befolgt und abgeändert. Leider noch ohne Auswirkung.
Das mit dem Serial Monitor Logging hatte ich mir schon so, wie Du es schreibst, gedacht. Allerdings kam nix dabei rum. Aber habe leider nicht Serial.println(currentTemp); sondern Serial.print(currentTemp); benutzt, was vermutlich nicht klappen kann, oder?
Nur die bereits bekannten Messages arrived vom broker mit den Werten:
Attempting MQTT connection...connected Message arrived [node/oled/water] 12.3 Message arrived [node/oled/humidity] 75 20:57:41.879 -> Message arrived [node/oled/pressureout] 1012 20:57:41.879 -> Message arrived [node/oled/outside] 10.1
// Topics, change if yours are different
Aber wenn ich doch im Serial Monitor die Werte sehe, müsste doch //Topics passen oder? Ausserdem sehe ich im Broker, dass der Pubclient angemeldet ist und auf die Werte "subscribed"
Noch eine Frage, Auf dem Display steht bei h 0 % bei t 0.00 °C bei p 0 und bei v habe ich umgebogen und dort steht 0.00 °C. Es kann nicht an der Anzahl der Stellen liegen? decimals?
Echt toll das Du mir soviel hilfst.
Alle anderen Ausgaben z.B. mit EspEasy sehen einfach nach nix aus. Da ist Deine Lösung echt richtig schön. Auf der Basis würde ich wenn ich es dann mal verstanden habe geg. weitere Werte dazu bauen, geg auch Strings um den Status von Fenstern anzuzeigen-> Balkontür offen oder sowas. Aber soweit bin ich halt noch nicht. Habe bislang nur mit Tasmota und Espurna und node-red experimentiert. Daher meine naiven Fragen.
Vielen lieben Dank noch mal
Das mit dem Serial Monitor Logging hatte ich mir schon so, wie Du es schreibst, gedacht. Allerdings kam nix dabei rum. Aber habe leider nicht Serial.println(currentTemp); sondern Serial.print(currentTemp); benutzt, was vermutlich nicht klappen kann, oder?
Naja, Serial.print(currentTemp);
schreibt nur den Wert von currentTemp
, ohne Zeilenumbruch und Serial.println(currentTemp)
eben mit Zeilenumbruch. Das ist der einzige Unterschied. Mit Zeilenumbruch ist es dann einfacher zu erkennen wo der eine Wert aufhört und der nächste anfängt ...
Nunja, die Ausgaben
Attempting MQTT connection...connected
Message arrived [node/oled/water] 12.3
Message arrived [node/oled/humidity] 75
20:57:41.879 -> Message arrived [node/oled/pressureout] 1012
20:57:41.879 -> Message arrived [node/oled/outside] 10.1
kommen eh die Werte verarbeitet werden. Daher wären die Ausgaben von dieser Änderung interessant:
void barocallback(double p) {
currentBaro = p;
Serial.print("callback baro: ");
Serial.println(currentBaro);
}
void humcallback(double h) {
currentHum = h;
Serial.print("callback hum: ");
Serial.println(currentHum);
}
void tempcallback(double t) {
currentTemp = t;
Serial.print("callback temp:");
Serial.println(currentTemp);
}
void lipocallback(double v) {
currentVoltage = v;
Serial.print("callback voltage: ");
Serial.println(currentVoltage);
}
Ansonsten wüsste ich auch nicht mehr. Poste doch mal dein komplettes .ino file (ohne WLAN passwort)
Ich fress einen Besen. Es klappt!! Und was wars ich hatte bei den Topics nen / vor dem node/oled. Nehme ich den weg, klappt der Callback und auch die Anzeige. Merkwürdig, das trotzdem die Topics ausgegeben wurden. Egal, hauptsache es klappt Der Knaller!!#Vielen Dank
Was muss ich denn machen, wenn ich weitere "Seiten definieren will?
/*
// OLED specific
Adafruit_SSD1306 display(OLED_RESET);
/* CONFIG *****/ // MQTT broker settings // IP address of the mqtt broker
// credentials needed for connection
// Topics, change if yours are different
node/oled/pressureout"
// Multi WiFi const char ssid1 = "FRITZ!Box Fon WLAN 7360"; const char ssid2 = "Android-Tobi"; const char ssid3 = "SSID_3"; const char password1 = ""; const char password2 = ""; const char password3 = "PASSWORD_3"; /* CONFIG END *****/
// Multiple WiFi connections ESP8266WiFiMulti multi;
// Create an ESP8266 WiFiClient class to connect to the MQTT server. WiFiClient client; PubSubClient mqtt(client);
double currentTemp = 0.0; double currentVoltage = 0.0; double currentHum = 0.0; double currentBaro = 0.0; const int timeout = 5;
// Define some display states int state = 0;
// how long to wait until switching state
// millis of last switch long lastSwitch = 0;
// ICONS const unsigned char temp_icon [] = { 0x08, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0xF8, 0x14, 0x00, 0x14, 0xF8, 0x14, 0x00, 0x14, 0xF8, 0x14, 0x00, 0x14, 0x00, 0x22, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x22, 0x00, 0x1C, 0x00 }; const unsigned char humidity [] = { 0x00, 0x80, 0x01, 0xC0, 0x01, 0xC0, 0x03, 0x60, 0x03, 0x60, 0x06, 0x30, 0x06, 0x30, 0x0E, 0x38, 0x1C, 0x1C, 0x18, 0x0C, 0x30, 0x06, 0x30, 0x06, 0x18, 0x0C, 0x1C, 0x1C, 0x0F, 0xF8, 0x07, 0xF0 }; const unsigned char pressure [] = { 0x00, 0x3C, 0x00, 0x47, 0x00, 0xC1, 0x00, 0x83, 0x01, 0x02, 0x04, 0xFE, 0x08, 0x00, 0x1F, 0xFC, 0x08, 0x00, 0x24, 0x00, 0x40, 0x00, 0xFF, 0xE8, 0x40, 0x04, 0x2F, 0xFE, 0x00, 0x04, 0x00, 0x08 };
void barocallback(double p) { currentBaro = p; Serial.print("callback baro: "); Serial.println(currentBaro); }
void humcallback(double h) { currentHum = h; Serial.print("callback hum: "); Serial.println(currentHum);
}
void tempcallback(double t) { currentTemp = t; Serial.print("callback temp:"); Serial.println(currentTemp);
}
void lipocallback(double v) { currentVoltage = v; Serial.print("callback voltage: "); Serial.println(currentVoltage); }
void callback(char topic, byte payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]);
}
Serial.println();
// we know there will be only double data as payload, so ...
double dValue = atof((char *) payload);
if(strcmp(topic, TOPIC_TEMPERATURE) == 0)
tempcallback(dValue);
else if(strcmp(topic, TOPIC_VOLTAGE) == 0)
lipocallback(dValue);
else if(strcmp(topic, TOPIC_HUMIDITY) == 0)
humcallback(dValue);
else if(strcmp(topic, TOPIC_BAROMETRIC) == 0)
barocallback(dValue);
}
/*
void setup() { Serial.begin(9600);
multi.addAP(ssid1, password1); multi.addAP(ssid2, password2); multi.addAP(ssid3, password3);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 64x48)
// Clear the buffer. display.clearDisplay(); display.dim(1); display.setTextWrap(false); // show "welcome" screen display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(14,0); display.print("ESP"); display.setCursor(8,17); display.print("8266"); display.setTextSize(1); display.setCursor(11,40); display.print("Climate"); display.display(); delay(2000);
display.clearDisplay(); display.setTextWrap(true); Serial.println("Connecting Wifi..."); display.setCursor(0,4); display.print("Connecting Wifi"); display.display(); delay(500);
display.setTextWrap(false); int fake = 3; while(fake != 0) { display.setCursor(23,display.height()-8); display.setTextColor(BLACK); display.print("..."); display.display(); delay(400); display.setTextColor(WHITE); display.setCursor(23,display.height()-8); display.print("."); display.display(); delay(250); display.print("."); display.display(); delay(250); display.print("."); display.display(); delay(500); fake--; } int c = 0; while(multi.run() != WL_CONNECTED || c >= timeout) { Serial.println("next wifi connect try in 1s"); delay(1000); c++; } if(c >= timeout) while(1); // WDT reset
// remove 3 dots (if there are some) display.setCursor(23,display.height()-8); display.setTextColor(BLACK); display.print("..."); display.setTextColor(WHITE); display.setCursor(5,display.height()-8); display.print("connected"); display.display(); delay(500); Serial.println(""); Serial.println("WiFi connected"); Serial.print("WiFi SSID: "); Serial.println(WiFi.SSID()); Serial.print("IP address: "); Serial.println(WiFi.localIP());
mqtt.setServer(HOST, PORT); mqtt.setCallback(callback);
display.clearDisplay(); display.setCursor(8,15); display.print("fetching"); display.setCursor(20,24); display.print("data"); display.display(); delay(1500); }
void reconnect() { // Loop until we're reconnected while (!mqtt.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (mqtt.connect("ESP8266-OLED", USERNAME, PASSWORD)) { Serial.println("connected"); // ... and resubscribe mqtt.subscribe("node/oled/#"); } else { Serial.print("failed, rc="); Serial.print(mqtt.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } }
void loop() { // make sure we're connected if (!mqtt.connected()) { reconnect(); } mqtt.loop();
// show the values drawValues(); long now = millis(); if(lastSwitch == 0) lastSwitch = now; int waited = now - lastSwitch; // time to switch display values? if(waited >= WAIT_SECONDS * 1000) { lastSwitch = now; state++; if(state > 2) state = 0; } }
Weitere double currentWert4 = 0.0; anlegen
case STATE_Wert4: if((currentWert4 >= 0 || currentWer4 > -10) && currentWert4 < 10) display.print(" "); if(currentWert4 < -10) decimals = 1; display.println(currentWert4, decimals); display.print(" "); display.print(char(167)); display.print("C"); display.drawBitmap(0,display.height()-16, temp_icon, 16, 16, WHITE); break;
So wahrscheinlich?
Und wie geht sowas mit Strings?
Vielen Dank nochmal für die ganze Mühe!!
Und was wars ich hatte bei den Topics nen / vor dem node/oled. Nehme ich den weg, klappt der Callback und auch die Anzeige. Merkwürdig, das trotzdem die Topics ausgegeben wurden. Egal, hauptsache es klappt
Die topics wurde ausgegeben weil er zu allem subscribed was in "node/oled/#" gepostet wird. # bedeutet quasi alles. Wenn er also jetzt die topic "node/oled/outside" empfängt, Dein define aber
#define TOPIC_TEMPERATURE "/node/oled/outside"
War, dann trifft der Vergleich in
if(strcmp(topic, TOPIC_TEMPERATURE) == 0)
tempcallback(dValue);
nie zu und die callback methode die den aktuellen Wert setzt wird nicht aufgerufen und der Wert für currentTemp
nie anders als 0 gesetzt und deswegen kann die drawValues()
Methode auch nix anderes als 0 anzeigen.
Was muss ich denn machen, wenn ich weitere "Seiten definieren will?
Pro neuer Seite einen neuen State definieren und natürlich die Abbruchbedingung für die Schleife des states ändern. Aber, jede Seite ist quasi Pixelschubserei, sprich man muss die Werte, Icon und Längen beachten. Ich denke da müsstest Du erstmal die drawValues()
Method vollkommen verstehen. Also was jeder einzelne Schritt da macht. Dann wirst Du Dir auch die Frage nach dem "wie geht das für Strings" beantworten können.
Verstehe mich nicht falsch, ich helfe gerne bei konkreten Problemen/Fragen, aber ein wenig Eigeninitiative zum Lernen kann auch nicht schaden.
PS: Das ist mein erstes OLED Projekt ;)
PPS: Wenn du nur weitere Temperaturen haben willst, kannst du natürlich alles von der ersten kopieren. Aber dann wird es auch schwer die zu unterscheiden und für einen Text ist ja kein Platz auf dem kleinen Display. Ich habe dafür Mal vor Jahren ein LCD mit 20x4 Zeichen benutzt. Da hat man mehr Platz. Oder ein größeres OLED wenn es mehr Infos sein sollen.
Hallo, danke noch mal für die ganze Mühe. Ich denke, dass ich so nun alleine weiterkommen werde. Ich dachte auch erst mal nicht an weitere Temperaturen sondern Statusmeldungen. Oder ich schreibe dazwischen einfach was dann als nächstes kommt. Mal sehen. Habe wie gesagt bislang nur an fertigen espurna`s oder tasmotas rumgebaut. Für die Anzeige habe ich erstmalig Arduino IDE installiert. Ist also alles Neuland, macht aber Lust sich da tiefer einzuarbeiten.
Geg. komme ich noch mal mit einer gezielten Frage gemäß deines Angebots. Aber Dauernerven wollte ich natürlich nicht.
Besten Dank und viele Grüße aus Königswinter
Hi,
danke für den Link mit der geforkten SSD1306. Das Display funktioniert nun zauberhaft schön, der mqtt Broker wird verbunden. Auf die Topics wird subscribed aber auf dem Display kommt nix an: Connecting Wifi... next wifi connect try in 1s next wifi connect try in 1s next wifi connect try in 1s
20:57:39.849 -> WiFi connected 20:57:39.849 -> WiFi SSID: FRITZ!Box Fon WLAN 7360 20:57:39.849 -> IP address: 192.168.2.4 Attempting MQTT connection...connected Message arrived [node/oled/water] 12.3 Message arrived [node/oled/humidity] 75 20:57:41.879 -> Message arrived [node/oled/pressureout] 1012 20:57:41.879 -> Message arrived [node/oled/outside] 10.1
Hast Du vielleicht noch einen Tipp parat. Das einzige was ich angepasst habe sind die Topics und h / 100 zu teilen, da ich schon in hPa fertig anliefere.
case STATE_BARO: int h = (currentBaro);
Besten Dank