thedarkman / ESP8266-Climate-Display-PubSub

0 stars 0 forks source link

Alle Displayanzeigen auf 0 bzw. 0.00 #2

Closed phototobi closed 5 years ago

phototobi commented 5 years ago

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

thedarkman commented 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?

phototobi commented 5 years ago

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;

define STATE_TEMP 0

define STATE_HUM 1

define STATE_BARO 2

// how long to wait until switching state

define WAIT_SECONDS 5

// 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; } }

thedarkman commented 5 years ago

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"
phototobi commented 5 years ago

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

define TOPIC_TEMPERATURE "node/oled/outside"

define TOPIC_VOLTAGE "node/oled/water"

define TOPIC_HUMIDITY "node/oled/humidity"

define TOPIC_BAROMETRIC "node/oled/pressureout"

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

thedarkman commented 5 years ago

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)

phototobi commented 5 years ago

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?

/*

include

include

include

include

include

include

// OLED specific

define OLED_RESET 0 // GPIO0

Adafruit_SSD1306 display(OLED_RESET);

/* CONFIG *****/ // MQTT broker settings // IP address of the mqtt broker

define HOST "broker.shiftr.io"

define PORT 1883

// credentials needed for connection

define USERNAME "a5068421"

define PASSWORD ""

// Topics, change if yours are different

define TOPIC_TEMPERATURE "node/oled/outside"

define TOPIC_VOLTAGE "node/oled/water"

define TOPIC_HUMIDITY "node/oled/humidity"

define TOPIC_BAROMETRIC "

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;

define STATE_TEMP 0

define STATE_HUM 1

define STATE_BARO 2

// how long to wait until switching state

define WAIT_SECONDS 5

// 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; } }

phototobi commented 5 years ago

Weitere double currentWert4 = 0.0; anlegen

define STATE_Wert4 0

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!!

thedarkman commented 5 years ago

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

thedarkman commented 5 years ago

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.

phototobi commented 5 years ago

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