Forum: Projekte & Code Micropython Wetterstation


von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Hier der erste, schnelle Versuch, eine Wetterstation als ESP32 
Accesspoint zu bauen. Der DS18b20 OneWire Sensor ist an Port 4 und muss 
mit 4k7 gegen 3.3V betrieben werden.

Vielleicht hat der ein oder andere einen Tipp, was man alles verbessern 
kann.

Ungünstig ist ein wenig, dass man die Webadresse in den Browser tippen 
muss:
http://192.168.4.1/

: Bearbeitet durch User
von Jack V. (jackv)


Lesenswert?

Christoph M. schrieb:
> Vielleicht hat der ein oder andere einen Tipp, was man alles verbessern
> kann.

Grundlegend würde ich es erstmal schlicht „Thermometer“ nennen, eine 
Wetterstation zeigt ja doch ein paar mehr Parameter an. Alternativ mit 
etwa einem BME280 noch Feuchtigkeit und Druck mit reinholen.

Die Werte kann man dann in Intervallen speichern (für so einfache 
Strukturen nehme ich meist plump CSV her: Timestamp, Temperatur, Druck, 
Feuchtigkeit). Da kann man dann hübsche Diagramme für den Verlauf draus 
erstellen und anzeigen lassen.

Eine Kleinigkeit noch: Die Einheit wäre °C. Wenn du es nicht direkt 
schreiben möchtest, ginge ° im HTML

Nicht zuletzt: Wenn du bereits ein lokales WLAN hast, wär’s vielleicht 
praktischer, wenn du den ESP dorthin verbinden lässt, statt einen 
eigenen AP aufzumachen. Dann könntest du mit allen Geräten im Netz die 
Temperaturen anschauen.

Das Script wurde ursprünglich für einen Pi Pico entworfen?

: Bearbeitet durch User
von Sebastian R. (sebastian_r569)


Lesenswert?

Christoph M. schrieb:
> Ungünstig ist ein wenig, dass man die Webadresse in den Browser tippen
> muss:

Schau mal, ob man irgendwo einen Hostnamen vergeben kann, dann wird es 
vielleicht etwas besser.

Statt des Alive-Counters vielleicht eine Anzeige, vor wie vielen 
Sekunden der letzte Wert empfangen wurde.

Ansonsten ja, zur Wetterstation gehört mehr als nur eine Temperatur. 
Zumindest ein zeitlicher Verlauf über die letzten X Stunden wäre 
vielleicht noch hilfreich. AlsZwischenschritt noch Höchst- und 
Tiefsttemperatur der letzten 24 Stunden.

von Christoph M. (mchris)


Lesenswert?

Erst einmal danke für eure Rückmeldungen. Ich werde mal sehen, was sich 
noch so machen lässt.

Jack V. schrieb:
> Eine Kleinigkeit noch: Die Einheit wäre °C.

Ich hatte ursprünglich
1
document.getElementById('internal_temp').textContent =  data.internal + ' °C';

aber wenn das '°' Zeichen eingefügt ist, macht der Browser aus mir 
unerklärlichen Gründen eine 'Ä' vor das '°' Zeichen. Deshalb habe ich es 
dann raus geworfen.

von Christoph M. (mchris)


Lesenswert?

Jack V. schrieb:
> Das Script wurde ursprünglich für einen Pi Pico entworfen?

Eigentlich wollte ich den PiPico-W dafür verwenden und meine 
Netzwerkeinstellungen im Rechner sind noch für den PiPico-W konfiguriert 
und ich wollte nicht alles neu einstellen. Ich denke, wenn man Messung 
und Übertragung des internen ESP32 Temperatursensors rauswirft, müsste 
es mit Microptyhon wahrscheinlich dann auch auf dem PiPico-W 
funktionieren.

von Fred F. (fred08151)


Lesenswert?

Meine ESPs haben einen BME280 und schicken die Daten alle 30 Minuten zur 
Datenbank auf dem Pi, dort lassen sie sich auch schöner visualisieren, 
z.B. mit Grafana.
Zudem kann man mit einem BME280 auch den Taupunkt berechnen, benötigen 
keinen Widerstand, wie der veraltete DS18b20, sondern lassen sich direkt 
mit 3,3V betreiben.

von Heinz R. (heijz)


Lesenswert?

wie wäre es mit einem Display direkt am ESP

Es gibt fertige 2,8" Displays, incl. verbautem ESP32, für unter 20€

von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Hier mal ein zweiter Versuch mit Uhrzeit. Die stimmt erstaunlicherweise, 
obwohl sie aus dem Mikrocontroller kommt.

Fred F. schrieb:
> Meine ESPs haben einen BME280 und schicken die Daten alle 30 Minuten zur
> Datenbank auf dem Pi, dort lassen sie sich auch schöner visualisieren,
> z.B. mit Grafana.

Grafana habe ich vor kurzem erst zufällig entdeckt. Ich hätte aber immer 
gerne "self contained" Systeme ohne äußere Abhängigkeiten. Deshalb ist 
das Beispiel als Accesspoint ausgeführt, dann braucht es gar kein 
externes Netz.
Das einzige Problem könnte jetzt die Uhrzeit sein. Irgendwie muss ja 
synchronisiert werden. Vielleicht gibt es eine Möglichkeit, dass wenn 
ein externes Gerät die ESP-Webseite nutzt, dass dann die Uhrzeit aus dem 
Gerät in den Mikrocontroller übertragen wird.

von Fred F. (fred08151)


Lesenswert?

Christoph M. schrieb:
> Das einzige Problem könnte jetzt die Uhrzeit sein. Irgendwie muss ja
> synchronisiert werden. Vielleicht gibt es eine Möglichkeit, dass wenn
> ein externes Gerät die ESP-Webseite nutzt, dass dann die Uhrzeit aus dem
> Gerät in den Mikrocontroller übertragen wird.

Natürlich könnte auch der Pi der optionale Client sein, der sich die 
Daten vom AP abholt. Den Timestamp hätte dann die Datenbank selbst 
genommen. Aber so könntest du über GPS oder DCF77 die Uhrzeit holen.
Sonst müsste der Client ja seine Uhrzeit mitteilen.
Und ob die stimmt, bestimmt dann der Client ?

: Bearbeitet durch User
von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Jack V. schrieb:
> Grundlegend würde ich es erstmal schlicht „Thermometer“ nennen, eine
> Wetterstation zeigt ja doch ein paar mehr Parameter an. Alternativ mit
> etwa einem BME280 noch Feuchtigkeit und Druck mit reinholen.

Da hast du wohl Recht. Mir geht es im ersten Schritt darum, die 
Webtechnologie zu testen. Deshalb ist das Programm sehr einfach gehalten 
und nutzt nur die Temperatursensoren. Wenn man den externen DS18b20 weg 
lässt, kann man immerhin noch die interne Chiptemperatur anzeigen. Da 
wäre eine interessante Frage, ob man aus der Chiptemperatur auch auf die 
Umgebungstemperatur zurück rechnen kann.

Ich habe vor kurzem mal einen Sensirion SCD41 CO2 Sensor geschenkt 
bekommen. Der zeigt auch die relative Feuchte und die Temperatur an. 
Allerdings macht der wohl eher Sinn als Raumklima-Sensor. Man kann 
tatsächlich im Verlauf verfolgen, dass das CO2 im Raum langsam ansteigt. 
Ich frage mich ja immer, woher eigentlich der neue Sauerstoff kommt, 
wenn man die Fenster nicht aufmacht. Scheinbar kann man die Aussenluft 
auch zur Kallibrierung benutzen, weil der CO2-Wert außen ziemlich 
konstant ist.

Google behauptet das:

"Die aktuelle CO2-Konzentration in der Atmosphäre liegt bei über 420 ppm 
(parts per million), mit aktuellen Tageswerten im Januar 2026 nahe 428 
ppm auf Hawaii, nach einem Jahresmittelwert von etwa 423,9 ppm für 2024 
und dem Trend steigender Werte. Dieser Wert liegt deutlich höher als die 
vorindustriellen ~280 ppm und steigt weiter an, was die Klimaerwärmung 
verstärkt"

: Bearbeitet durch User
von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Die Frage ist: gibt es jahreszeitliche Schwankungen des CO2 Wertes?
Wenn man den Sensor nach draußen legt, braucht er einige Zeit, um sich 
dem neuen Wert anzunähern und liegt zwischendurch zu tief. Am 
eingebauten Temperatursensor sieht man, dass es Zeit braucht, bis das 
Gehäuse die Außentemperatur annimmt. Wenn sich die Temperatur 
einigermaßen stabilisiert hat, kommt der Wert dann schon in den 
richtigen Bereich ( siehe Messwert ).

von A. (eloachim) Benutzerseite


Lesenswert?

Christoph M. schrieb:
> Ungünstig ist ein wenig, dass man die Webadresse in den Browser tippen
> muss:
> http://192.168.4.1/
Als Lösung bietet sich an, ein 'Captive Portal' aufzumachen. Wenn man 
sich dann mit dem WLAN der Wetterstation verbindet, erscheint auf dem 
Handy/PC die Meldung, dass man sich im Netzwerk anmelden soll. Macht man 
das, schickt die Wetterstation eben ihre Webseite.

von Helmut -. (dc3yc)


Lesenswert?

Fred F. schrieb:
> Zudem kann man mit einem BME280 auch den Taupunkt berechnen, benötigen
> keinen Widerstand, wie der veraltete DS18b20, sondern lassen sich direkt
> mit 3,3V betreiben.

Nein, den Taupunkt kann man damit nicht berechnen, da der BME280 nicht 
die Lufttemperatur misst, sondern die Chiptemperatur. Dieser Messwert 
taugt nur zur Korrektur von Feuchte und Druck (und ist meist 3-5 Grad 
höher). Leute, lest doch mal das Datenblatt! Aber die Lesekompetenz ist 
in Zeiten von Youtube nicht mehr so gefragt.

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

A. schrieb:
> Als Lösung bietet sich an, ein 'Captive Portal' aufzumachen.

Das scheint es in den Zügen der Deutschen Bahn zu geben. Da geht immer 
eine Standardseite auf, um sich anzumelden. Ich weiß aber nicht, wie man 
das im ESP realisiert.

von Rainer W. (rawi)


Lesenswert?

Christoph M. schrieb:
> Jack V. schrieb:
>> Eine Kleinigkeit noch: Die Einheit wäre °C.
>
> Ich hatte ursprünglich
> document.getElementById('internal_temp').textContent =  data.internal +
> ' °C';
>
> aber wenn das '°' Zeichen eingefügt ist, macht der Browser aus mir
> unerklärlichen Gründen eine 'Ä' vor das '°' Zeichen.

Die "unerklärlichen Gründe" werden wohl in der Zeichensatz-Kodierung zu 
suchen sein, d.h. in einer unpassenden Angabe "charset" im HTML-Code der 
Seite.
https://de.wikipedia.org/wiki/Zeichenkodierung

Im HTML-Code kannst du für das Gradzeichen besser "°" verwenden, 
also z.B.
1
... = data.internal + ' °C';

Helmut -. schrieb:
> Nein, den Taupunkt kann man damit nicht berechnen, da der BME280 nicht
> die Lufttemperatur misst, sondern die Chiptemperatur.

Du meinst, der Sensor für die relative Feuchte hat nicht die 
Chip-Temperatur? Oder der Wert für die ausgegebene relative Feuchte gilt 
bei dem Sensor für eine andere Temperatur, als für die gemessene?
Woher soll der BME280 die Temperatur wissen, wenn nicht von seinem 
Sensor?

Der Taupunkt ist unabhängig von der aktuellen Temperatur und hängt nur 
von der absoluten Feuchte der Luft ab.

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

Rainer W. schrieb:
> Im HTML-Code kannst du für das Gradzeichen besser "°" verwenden,
> also z.B.

Danke für den Hinweis. Ich hoffe ja immer noch darauf eine Möglichkeit 
zu finden das '°' Zeichen auf der Webpage ohne störendes Vorzeichen 
darstellen zu können.

von Andreas M. (amesser)


Lesenswert?

Christoph M. schrieb:
> Hier mal ein zweiter Versuch mit Uhrzeit. Die stimmt erstaunlicherweise,
> obwohl sie aus dem Mikrocontroller kommt.

Der ESP holt standardmäßig sich die Uhrzeit von einem Zeitserver...

Christoph M. schrieb:
> Ungünstig ist ein wenig, dass man die Webadresse in den Browser tippen
> muss:

Wenn Du eine Fritz-Box hast, dann kannst Du in der Weboberfläche der 
Fritz-Box dem Gerät einen Namen zuordnen. Das Gerät ist dann unter 
"<name>.fritz.box" erreichbar.

Eventuell kann man bei dem ESP in den DHCP Optionen was einstellen, dann 
Übernehmen die Fritzbox/der Router die Vorgaben
- "host-name" -> der gewünschte Name
- "dhcp-client-identifier" -> die Mac Adresse des Gerätes, brauchen 
manche Fritzboxen sonst ignorieren die "host-name"

von Rainer W. (rawi)


Lesenswert?

Christoph M. schrieb:
> Ich hoffe ja immer noch darauf eine Möglichkeit
> zu finden das '°' Zeichen auf der Webpage ohne störendes Vorzeichen
> darstellen zu können.

Was suchst du jetzt noch?
Mit &deg; sollte auf der Webpage ein sauberes '°'-Zeichen (ohne 
irgendetwas davor) dargestellt werden. Oder die Web-Page 
Zeichenkodierung muss zur Einstellung in deinem Quellcode-Editor passen.

: Bearbeitet durch User
von Christoph M. (mchris)



Lesenswert?

Rainer W. schrieb:
> Was suchst du jetzt noch?
> Mit &deg; sollte auf der Webpage ein sauberes '°'-Zeichen (ohne
> irgendetwas davor) dargestellt werden. Oder die Web-Page
> Zeichenkodierung muss zur Einstellung in deinem Quellcode-Editor passen.

Als Editor verwende ich Thonny. Da weiß ich aber nicht, wie die 
Kodierung eingestellt ist.

Das obige Bild ergibt sich mit Deiner Anpassung. Wenn man hier im Forum 
die 'code' Tags aktiviert, sieht man lustigerweise das '°' Zeichen aber 
nicht mehr &deg;


    <script>
        function updateData() {
            fetch('/data')
                .then(response => response.json())
                .then(data => {
                    document.getElementById('internal_temp').textContent 
=  data.internal + ' &deg;C';
                    document.getElementById('external_temp').textContent 
= data.external + '  &deg;C';
                    document.getElementById('counter_value').textContent 
= 'Time: ' + data.counter;
                    document.getElementById('reset_count').textContent = 
'Checks: ' + data.resets;
                })
                .catch(err => console.log('Fetch error:', err));
        }

P.s.: Das erste Bild ist falsch und kann vom Moderator gelöscht werden. 
Leider kann man beim Editieren des Posts schon hochgeladene Files nicht 
löschen.

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

Andreas M. schrieb:
> Der ESP holt standardmäßig sich die Uhrzeit von einem Zeitserver...

Das kann er aber als Access-Point scheinbar nicht tun. So ist er aber 
konfiguriert.

von Rainer W. (rawi)


Lesenswert?

Christoph M. schrieb:
> Als Editor verwende ich Thonny. Da weiß ich aber nicht, wie die
> Kodierung eingestellt ist.

Dann guck dir den Quelltext vielleicht einmal mit Notepad++ an.

> Das obige Bild ergibt sich mit Deiner Anpassung.

Merkwürdig. Was steht denn im erzeugten HTML-Seitenquelltext?

: Bearbeitet durch User
von Helmut -. (dc3yc)


Lesenswert?

Rainer W. schrieb:
> Du meinst, der Sensor für die relative Feuchte hat nicht die
> Chip-Temperatur? Oder der Wert für die ausgegebene relative Feuchte gilt
> bei dem Sensor für eine andere Temperatur, als für die gemessene?
> Woher soll der BME280 die Temperatur wissen, wenn nicht von seinem
> Sensor?
>
> Der Taupunkt ist unabhängig von der aktuellen Temperatur und hängt nur
> von der absoluten Feuchte der Luft ab.

Also der Sensor misst die Chiptemperatur, die dazu dient, die Werte für 
Feuchte und Druck zu kompensieren. Die Chiptemperatur hat nichts mit der 
Umgebungstemperatur zu tun. Sie ist um einige Grad höher. Und laut 
meiner bevorzugten Wetterseite 
(https://www.wetterochs.de/wetter/feuchte.html) ist die 
Umgebungstemperatur sehr wohl für die Berechnung der Taupunkttemperatur 
notwendig.
Wie groß allerdings die Differenzen sind, falls die Chiptemperatur dazu 
benutzt wird, habe ich nicht nachvollzogen.

: Bearbeitet durch User
von Jack V. (jackv)


Lesenswert?

Am Anfang war doch noch ein DS18B20 im Spiel? Dessen Temperatur könnte 
man wieder zur Taupunktbestimmung heranziehen (wenn’s original ist – 
ansonsten würde man vorher gucken, wie genau der vorliegende Sensor 
tatsächlich ist).

Was das °-Problem angeht: Möglicherweise hilft es schon, im 
HTML-Dokument UTF-8 als verwendeten Zeichensatz anzugeben (besser wär’s 
noch auf HTTP-Ebene), um dann das Zeichen „as is“, also ohne die 
&deg;-Umschreibung benutzen zu können.

von Rainer W. (rawi)


Lesenswert?

Helmut -. schrieb:
> Und laut meiner bevorzugten Wetterseite
> (https://www.wetterochs.de/wetter/feuchte.html) ist die
> Umgebungstemperatur sehr wohl für die Berechnung der Taupunkttemperatur
> notwendig.

Na ja, alles der Reihe nach.
Benötigt wird die Temperatur, um die relative Feuchte in die absoluten 
umzurechnen. Jetzt ist es also die Frage, was die Software genau macht, 
um aus den Rohdaten des Sensors den Wert für die relative Feuchte 
auszurechnen, d.h. auf welche Temperatur sich der Wert bezieht. Die 
Umgebungstemperatur kennt der Sensor jedenfalls nicht, sondern nur die 
Chip-Temperatur.

Ob und wie man die absolute Feuchte dann weiter in den Taupunkt 
umrechnet, hat mit der Umgebungstemperatur nichts zu tun. Die absolute 
Feuchte der Luft ist ein von der Temperatur unabhängiger Wert.

von Ralf X. (ralf0815)


Lesenswert?

Rainer W. schrieb:
> Die
> Umgebungstemperatur kennt der Sensor jedenfalls nicht, sondern nur die
> Chip-Temperatur.

Genau, elektronische Thermometer können nirgens was taugen, weil selbst 
jahrelang haltende Knopfzellen die Fühler zum glühen bringen.
Und selbst wenn nicht, auf 0,01° sind die nie genau, also sofort in die 
Tonne treten.

von Bauform B. (bauformb)


Lesenswert?

Christoph M. schrieb:
> document.getElementById('internal_temp').textContent =  data.internal + ' 
&deg;C';

Evt. brauchst du für diese Konstruktion immer (unabhängig von ESP und 
Editor) eine Decoder-Funktion, etwas in dieser Art:

https://www.sampleexamples.com/2024/11/decoding-html-entities-in-javascript.html

Falls es .htmlContent statt .textContent gibt, wäre die Decodierung 
gratis, also:

document.getElementById('internal_temp').htmlContent


Edit: du könntest auch 273.15 addieren -> dann geht's ohne &deg; und 
ohne Vorzeichen ;)

: Bearbeitet durch User
von Thomas R. (singlefreiheit-01)


Lesenswert?

Helmut -. schrieb:
> Fred F. schrieb:
>> Zudem kann man mit einem BME280 auch den Taupunkt berechnen, benötigen
>> keinen Widerstand, wie der veraltete DS18b20, sondern lassen sich direkt
>> mit 3,3V betreiben.
>
> Nein, den Taupunkt kann man damit nicht berechnen, da der BME280 nicht
> die Lufttemperatur misst, sondern die Chiptemperatur. Dieser Messwert
> taugt nur zur Korrektur von Feuchte und Druck (und ist meist 3-5 Grad
> höher). Leute, lest doch mal das Datenblatt! Aber die Lesekompetenz ist
> in Zeiten von Youtube nicht mehr so gefragt.

Wo hat das von Helmut bei YT gefunden?

von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Bauform B. schrieb:
> Evt. brauchst du für diese Konstruktion immer (unabhängig von ESP und
> Editor) eine Decoder-Funktion, etwas in dieser Art:

Jetzt habe ich einfach mal das Ganze in zwei separate Files geteilt: Den 
Teil für den Webrowser (index.html mit html und javascript) und den 
Micropython Teil auf dem Microcontroller. Man kann das index.html File 
jetzt einfach auf dem lokalen Computer testen, indem man es einfach in 
den Browser schiebt. Jetzt ist das ganze so realisiert, dass nur noch 
die Zahl durch den WebSocket verändert wird, aber nicht mehr die 
Einheit.
Nach einigem Hin- und Her scheint mir das jetzt die beste Lösung und es 
funktioniert.

Vielleicht um Missverständnisse vorzubeugen: Beide Files "index.html" 
und "RaumklimaServer.py" müssen sich auf dem ESP befinden. Das 
index.html kann man aber ohne ESP lokal testen.

: Bearbeitet durch User
von Rick (rick)



Lesenswert?

Christoph M. schrieb:
> Die Frage ist: gibt es jahreszeitliche Schwankungen des CO2 Wertes?
Ja, die gibt es:
https://de.wikipedia.org/wiki/Keeling-Kurve

Christoph M. schrieb:
> Scheinbar kann man die Aussenluft
> auch zur Kallibrierung benutzen, weil der CO2-Wert außen ziemlich
> konstant ist.
Naja. Für mich sieht es fast so aus, also könnte man den CO2-Wert nehmen 
und daraus das aktuelle Jahr ermitteln...

von Christoph M. (mchris)


Lesenswert?

Rick schrieb:
> Christoph M. schrieb:
>> Die Frage ist: gibt es jahreszeitliche Schwankungen des CO2 Wertes?
> Ja, die gibt es:
> https://de.wikipedia.org/wiki/Keeling-Kurve

Das reicht leider nicht aus, um die oben gemessenen 474ppm zu erklären ( 
Höchstens die Abgase von den umgebenen Schornsteinen spielen eine 
Rolle).

Wenn nicht, kann ich mit der Außenluft den Sensor doch besser 
kalibrieren.

Aber eines lässt deine Kurve schon vermuten: Mit der Klimaleugnung wird 
es langsam schwierig.

von Udo K. (udok)


Angehängte Dateien:

Lesenswert?

Rick schrieb:
> Naja. Für mich sieht es fast so aus, also könnte man den CO2-Wert nehmen
> und daraus das aktuelle Jahr ermitteln...

Christoph M. schrieb:
> Aber eines lässt deine Kurve schon vermuten: Mit der Klimaleugnung wird
> es langsam schwierig.

Wenn man die Welt aus dem Blickwinkel einer Stubenfliege betrachtet.

: Bearbeitet durch User
von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Seit ein paar Jahren habe ich einen unbenutzten BME280 herum liegen. 
Hier die Integration. Aus irgendwelchen Gründen scheint die Feuchte bei 
0% zu liegen. Ob die Sensoren wohl altern?

von Richie (mikro123)


Lesenswert?

Christoph M. schrieb:
> Seit ein paar Jahren habe ich einen unbenutzten BME280 herum liegen.
> Hier die Integration. Aus irgendwelchen Gründen scheint die Feuchte bei
> 0% zu liegen. Ob die Sensoren wohl altern?

Du hast einen BMP280, keinen BME280...

von Rainer W. (rawi)


Lesenswert?

Richie schrieb:
> Du hast einen BMP280, keinen BME280...

Das sollte mit einem Blick auf den Sensor herauszukriegen sein. Der 
BME280 besitzt ein quadratisches Gehäuse, der BMP280 ein rechteckiges 
(Seitenverhältnis 4:5)

von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Rainer W. schrieb:
> Das sollte mit einem Blick auf den Sensor herauszukriegen sein. Der
> BME280 besitzt ein quadratisches Gehäuse, der BMP280 ein rechteckiges
> (Seitenverhältnis 4:5)

So sieht er aus.

von N. M. (mani)


Lesenswert?

Im DB des BME gibt es das Kapitel 5.2 "Register compatibility to 
BMP280".
https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf

Da sieht man sehr schön dass man die einfach anhand Register 0xD0 (Chip 
ID) Bit 7:0 auseinander halten kann.

Beim BMP:
0x56 / 0x57 (samples)
0x58 (mass production)

Beim BME: 0x60

Dann weiß man es sicher.

: Bearbeitet durch User
von Rainer W. (rawi)


Lesenswert?

Christoph M. schrieb:
> So sieht er aus.

Das wird nach der Gehäuseform ein BMP280 sein. Bei dem quadratischen 
Gehäuse des BME280 müssten alle vier Gehäusekanten gleich lang sein.

https://de.wikipedia.org/wiki/Quadrat

Die Beschriftung des Sensors ist auf dem Photo wegen Unschärfe und 
ungeeigneter Beleuchtungsrichtung leider nicht lesbar. Da müsstest du 
selber einmal gucken.

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

Danke für eure Antworten: Es ist ein BMP280.

von Christoph M. (mchris)


Lesenswert?

Udo K. schrieb:
> Wenn man die Welt aus dem Blickwinkel einer Stubenfliege betrachtet.

Du hast schon recht: Den meisten Leuten fällt es sehr schwer, den Faktor 
Zeit in ihre Betrachtungen mit einzubeziehen. Es fällt ihnen auch schwer 
zu verstehen, dass der Konsum einer Flasche Wodka in einer Stunde eine 
völlig andere Auswirkung als der Konsum einer Flasche Wodka in einem 
Jahr hat. Das ist ein wenig wie bei der Geschwindigkeit des CO2 
Anstiegs.

von Rainer W. (rawi)


Lesenswert?

Christoph M. schrieb:
> RaumklimaMitBME280.png

Die Anzeigen für Druck und Temperatur vom Bosch-Sensor sind noch 
vertauscht.

Damit der Wert für den Druck mit anderen Wetterdaten vergleichbar ist, 
müsstest du ihn noch mit der Höhe des Sensors über Normalnull auf 
Meeresspiegel umrechnen. Der örtliche Luftdruck hilft zur Beurteilung 
des Wetters relativ wenig.

: Bearbeitet durch User
von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Rainer W. schrieb:
> Die Anzeigen für Druck und Temperatur vom Bosch-Sensor sind noch
> vertauscht.

Danke für den Hinweis.
In der neuen Version habe ich einen Graph für die Temperaturen 
eingebaut.
Das ist nicht ganz einfach, weil der ESP mit Micropython recht viel 
Speicher verschwendet. Damit das funktioniert, darf nicht die gesamte 
Webpage wie im ursprünglichen Beispiel in eine Variable geladen werden, 
sonder das index.html muss stückweise raus gestreamt werden.

Der CO2 Sensor muss scheinbar nach jedem Start einlaufen. Der BM liegt 
etwa 1 Grad über dem DS was sich wohl mit den Anmerkungen weiter oben 
deckt.

Rainer W. schrieb:
> Damit der Wert für den Druck mit anderen Wetterdaten vergleichbar ist,
> müsstest du ihn noch mit der Höhe des Sensors über Normalnull auf
> Meeresspiegel umrechnen. Der örtliche Luftdruck hilft zur Beurteilung
> des Wetters relativ wenig.

Auch ein guter Hinweis. Da kenne ich mich aber nicht aus und im Moment 
bin ich eher noch mit der "programmtechnischen Infrastruktur" 
beschäftigt.

von 900ss (900ss)


Lesenswert?

Christoph M. schrieb:
> Damit das funktioniert, darf nicht die gesamte Webpage wie im
> ursprünglichen Beispiel in eine Variable geladen werden, sonder das
> index.html muss stückweise raus gestreamt werden.

Wenn ich das richtig sehe, benötigt die Webpage ~8kb. Und die jetzt 
nicht am Stück einzulesen sorgt dafür dass das RAM nicht überläuft?
Dann ist das RAM sehr stark am Limit. Praktisch gesehen voll.

Wieviel Werte merkst du dir denn für die Kurven? Vermutlich dann viel zu 
viel, in zu kurzen (unnötigen?) Abständen?

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

900ss schrieb:
> Wieviel Werte merkst du dir denn für die Kurven?

Im Moment gar keine, das kannst du ganz einfach in den paar Zeilen 
Server-Code sehen.

: Bearbeitet durch User
von 900ss (900ss)


Lesenswert?

Christoph M. schrieb:
> das kannst du ganz einfach in den paar Zeilen Server-Code sehen.

Das hab ich nach meiner schlauen Aussage gemacht ;) Dann hab ich es 
gesehen.

Allerdings ist das RAM trotzdem komplett an Ende. Vielleicht ist das so 
in solch einer Anwendung. Ich weiß das nicht. Ich dachte nur an ggfs. 
sehr (zu) große Arrays. Das scheint aber nicht der Fall.

Nachtrag: Ich hab auch erst einmal mit MP gearbeitet. :) Das war der 
Benchmark von Norbert. Wenn ich jetzt sehe dass dieser kleine Webserver 
den ESP32 schon "überfordert" mit dem RAM dann bin ich mittelmäßig 
begeistert. Ich fand dein Projekt eigentlich ziemlich interessant. 
Gerade weil es auch mit MP realisiert ist.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

900ss schrieb:
> Nachtrag: Ich hab auch erst einmal mit MP gearbeitet. :) Das war der
> Benchmark von Norbert. Wenn ich jetzt sehe dass dieser kleine Webserver
> den ESP32 schon "überfordert" mit dem RAM dann bin ich mittelmäßig
> begeistert.

Da wäre die Frage wie viel freier Speicher im ESP ›ohne alles‹ verfügbar 
ist.
Und wer am meisten davon braucht.

Als Referenz: Ein RP2040 hat (jetzt musste ich gerade nachsehen) 241520 
Bytes RAM, ein RP2350 493040 Bytes RAM. Dazu mehr als reichlich Speicher 
im FLASH-Filesystem für statische Daten.
Damit lässt sich schon einiges reißen. ;-)

von Jack V. (jackv)


Lesenswert?

900ss schrieb:
> Wenn ich jetzt sehe dass dieser kleine Webserver
> den ESP32 schon "überfordert" mit dem RAM dann bin ich mittelmäßig
> begeistert.

Webserver, Access-Point, Python-Interpreter und das Script selbst – das 
ist schon ’n eindrucksvoller Stapel für ’nen kleinen Microcontroller. Je 
nachdem, welcher ESP32 hier zum Einsatz kommt, könnte man einen mit mehr 
RAM nehmen. Oder zusätzlichen Speicher via SPI oder so dranklöppeln.

Norbert schrieb:
> Da wäre die Frage wie viel freier Speicher im ESP ›ohne alles‹ verfügbar
> ist.

Je nach konkretem Modell wohl 256kB bis 768kB SRAM. Manche haben dann 
noch PSRAM bis 16MB.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Jack V. schrieb:
> Je nach konkretem Modell wohl 256kB bis 768kB SRAM.

Mehr als genug für einen Flug zum Mond, oder Doom.
µPy selbst will weniger als 20kB für 'sich'
Und wie gesagt, größere statische Dinge können mit 'nem Dreizeiler 
bequem aus dem FLASH geladen und verarbeitet werden. Knappes halbes Meg 
braucht 30ms.

von Christoph M. (mchris)


Lesenswert?

900ss schrieb:
> Nachtrag: Ich hab auch erst einmal mit MP gearbeitet. :) Das war der
> Benchmark von Norbert. Wenn ich jetzt sehe dass dieser kleine Webserver
> den ESP32 schon "überfordert" mit dem RAM dann bin ich mittelmäßig
> begeistert. Ich fand dein Projekt eigentlich ziemlich interessant.
> Gerade weil es auch mit MP realisiert ist.
Dieses Projekt mache ich tatsächlich um ein wenig die Limits von 
Micropython zu erforschen. Und bin ganz froh wenn Leute wie du mit 
einiger Programmiererfahrung da auch ein wenig dran basteln. Es ist halt 
wie bei jedem neuen System, mit dem man sich beschäftigt: Man muss die 
Untiefen und Tricks kennen. Erst dann lässt sich das ganze vernünftig 
verwenden.

Norbert schrieb:
> Da wäre die Frage wie viel freier Speicher im ESP ›ohne alles‹ verfügbar
> ist.
> Und wer am meisten davon braucht.

Bis jetzt habe ich nur begrenzt viel optimiert, außer ein paar mal 
gc.collect() und das Streaming der Webseite eingeführt.
Eigentlich gefällt mir die Verwendung von Microdot auch nicht, weil ich 
denke, das sollte einfacher gehen und es ist mir etwas zu dick. Das 
Hauptfile "micrdot.py" hat ja knapp 60Kb. Um es kleiner zu machen, 
schlagen die ja vor, es in Bytecode vorzukompilieren:
https://microdot.readthedocs.io/en/latest/intro.html

Der BME-Treiber hat auch 10KB und der SCD41 Treiber hat auch 13KB. Die 
könnte man wahrscheinlich alle vorkompilieren und damit Platz sparen. 
Bis jetzt habe ich das noch nicht gemacht, weil es auch noch so ging.

Eigentlich wäre mir fast ein PiPico2-W lieber, aber ich liebäugle noch 
damit ESP-Now für einen externen Sensor zu verwenden.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Christoph M. schrieb:
> Das
> Hauptfile "micrdot.py" hat ja knapp 60Kb. Um es kleiner zu machen,
> schlagen die ja vor, es in Bytecode vorzukompilieren

Das verkleinert es aber nicht. Nur der erstmalige Compile-Vorgang wird 
übersprungen. (Und der Speicher etwas weniger zerklüftet.)
Aber 60+10+13KB sind nu auch nicht die Welt.
Was sagt denn ein Soft Reset gefolgt von:
1
import gc;print(gc.mem_free())
im Terminal?

Hast du mal schrittweise die Module initialisiert und den jeweiligen RAM 
Verbrauch ausgegeben?

von Christoph M. (mchris)


Lesenswert?

Norbert schrieb:
> Was sagt denn ein Soft Reset gefolgt von:import gc;print(gc.mem_free())

MicroPython v1.26.1 on 2025-09-11; Generic ESP32 module with ESP32
Type "help()" for more information.
>>> import gc;print(gc.mem_free())
151664
>>> import network
>>> print(gc.mem_free())
138688
>>> import uasyncio as asyncio
>>> print(gc.mem_free())
135104
>>> from microdot import Microdot
>>> print(gc.mem_free())
118160
>>> import esp32
>>> print(gc.mem_free())
114096
>>> import machine
>>> print(gc.mem_free())
109680
>>> import onewire
>>> print(gc.mem_free())
104288
>>> import ds18x20
>>> print(gc.mem_free())
98864
>>> import scd4x
>>> print(gc.mem_free())
78624
>>> import gc
>>> print(gc.mem_free())
67600
>>> import time
>>> print(gc.mem_free())
61888
>>> from bme280_float import *
>>> print(gc.mem_free())
47168

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Christoph M. schrieb:
>>>> import gc;print(gc.mem_free())
> 151664

Das ist ja gleich zu Beginn schon übel. Was zum Teufel frisst denn 100K 
bevor es überhaupt los geht? (bezogen auf die avisierten 256kB die Jack 
erwähnte)
Hat das etwas mit dem komischen RTOS zu tun? Ich muss fragen, hab' diese 
Dinger nicht.
Alles in allem scheint das ESP Zeug ja mit beiden Händen aus dem vollen 
RAM Vorrat zu schöpfen.

18K für network und 18k für microdot hört sich OK an.
Aber 15K für einen primitiven Sensor? Rettet das module nebenbei noch 
die Welt? ;-)

von Christoph M. (mchris)


Lesenswert?

Norbert schrieb:
> Das ist ja gleich zu Beginn schon übel. Was zum Teufel frisst denn 100K
> bevor es überhaupt los geht? (bezogen auf die avisierten 256kB die Jack
> erwähnte)

Tja, leider habe ich keine Ahnung.

Beim PiPico2-W sieht's deutlich besser aus:

MicroPython v1.27.0 on 2025-12-09; Raspberry Pi Pico 2 W with RP2350
Type "help()" for more information.
>>> import gc;print(gc.mem_free())
441328

von Norbert (der_norbert)


Lesenswert?

Eben!
Aber das sieht auf dem ESP sowieso komisch aus.
Hab' mal ein einfaches:
1
#!/python
2
from gc import mem_free
3
4
avail = mem_free()
5
def usage():
6
    global avail
7
    use = avail - (curr:=mem_free())
8
    avail = curr
9
    print(use, avail)
10
11
import os
12
usage()
13
import sys
14
usage()
15
import machine
16
usage()
17
import uasyncio
18
usage()
19
import onewire
20
usage()
21
import ds18x20
22
usage()
23
import time
24
usage()

laufen lassen. Auf den Picos brauchen zumindest diese imports nur sehr, 
sehr wenig Speicher. Möglicherweise alles ›frozen‹ modules.
1
32 240960
2
16 240944
3
0 240944  # machine ist immer drin
4
96 240848
5
704 240144
6
368 239776
7
48 239728

: Bearbeitet durch User
von Jo (emsig)


Lesenswert?

Helmut -. schrieb:
> Fred F. schrieb:
>> Zudem kann man mit einem BME280 auch den Taupunkt berechnen, benötigen
>> keinen Widerstand, wie der veraltete DS18b20, sondern lassen sich direkt
>> mit 3,3V betreiben.
>
> Nein, den Taupunkt kann man damit nicht berechnen, da der BME280 nicht
> die Lufttemperatur misst, sondern die Chiptemperatur. Dieser Messwert
> taugt nur zur Korrektur von Feuchte und Druck (und ist meist 3-5 Grad
> höher). Leute, lest doch mal das Datenblatt! Aber die Lesekompetenz ist
> in Zeiten von Youtube nicht mehr so gefragt.

Im Datenblatt steht "can also be used for estimation of the ambient 
temperature". Es hängt u.a. davon ab, ob man den Chip kontinuierlich 
betreibt oder z.B. nur alle paar Sekunden oder gar nur alle paar 
Minuten. Ich selbst verwende den BME280 zur Messung der 
Raumtemperatur/-feuchtigkeit und des Luftdrucks. Das geht problemlos und 
auch hinreichend genau, weil ich die Messungen im Abstand von ca. 30 s 
mache und die Spannungsversorgung zwischen den Messungen unterbreche. 
Während der sehr kurzen Messung hat der Chip schlichtweg keine Zeit, um 
warm zu werden. Mit den Messwerten könnte man auch den Taupunkt 
berechnen.

: Bearbeitet durch User
von Richie (mikro123)


Lesenswert?

Jack V. schrieb:
> Norbert schrieb:
>> Da wäre die Frage wie viel freier Speicher im ESP ›ohne alles‹ verfügbar
>> ist.
>
> Je nach konkretem Modell wohl 256kB bis 768kB SRAM. Manche haben dann
> noch PSRAM bis 16MB.

Genau genommen (PSRAM):
ESP32: 4MB ohne Tricks, 8MB mit Tricks
ESP32-S2: 10,5MB
ESP32-S3: 32MB
ESP32-P4: 64MB

von Richie (mikro123)


Lesenswert?

Was den Speicherverbrauch unter Micropython angeht:

Wenn die Module vom Dateisystem importiert werden, dann werden die 
zuerst ins RAM geladen und geparst. Danach wird daraus Bytecode 
generiert.
Sowohl das Parsen als auch der Bytecode brauchen RAM.
Daher der Verbrauch.
Wenn man aus den Modulen vorcompilierten Bytecode erzeugt (mpy-cross: 
.py zu .mpy), dann entfällt der Parse-Schritt und man spart schonmal 
RAM.
Wenn man dann noch die .mpy Files in das Micropython-Image implementiert 
("frozen"), dann wird der Bytecode direkt aus dem Flash ausgeführt.

Zumindest für das "Endprodukt" empfiehlt sich das, da dadurch viel 
Speicher gespart wird und ausserdem auch die Heapfragmentierung deutlich 
reduziert wird.

von Norbert (der_norbert)


Lesenswert?

Richie schrieb:
> Genau genommen (PSRAM):

Nur, PSRAM kann man vielleicht noch am ehesten mit einer RAM-Disk 
vergleichen. Soweit ich weiß steht das als normaler (echter) RAM 
Arbeitsspeicher gar nicht zur Verfügung.
Mit einer MMU könnte man aber swapping einführen. (Wenn man Zeit hat)

Richie schrieb:
> Wenn man aus den Modulen vorcompilierten Bytecode erzeugt (mpy-cross:
> .py zu .mpy), dann entfällt der Parse-Schritt und man spart schonmal
> RAM.

…welcher jedoch nach der erstmaligen Kompilation nach dem Start sofort 
wieder frei gegeben wird.

Richie schrieb:
> Wenn man dann noch die .mpy Files in das Micropython-Image implementiert
> ("frozen"), dann wird der Bytecode direkt aus dem Flash ausgeführt.

Das spart tatsächlich RAM!

von Richie (mikro123)


Lesenswert?

Norbert schrieb:
> Nur, PSRAM kann man vielleicht noch am ehesten mit einer RAM-Disk
> vergleichen. Soweit ich weiß steht das als normaler (echter) RAM
> Arbeitsspeicher gar nicht zur Verfügung.
> Mit einer MMU könnte man aber swapping einführen. (Wenn man Zeit hat)

Nein, das ist nicht richtig.
Die ESP32 beherrschen transparentes XIP (Execute in Place), mit 
(einstellbarem) Caching, wie auch bei den größeren und neueren STM32.
Daher steht das gesamte PSRAM auch Micropython voll umfänglich zur 
Verfügung.
Ich kann daher - ausser bei absoluten Minimal-Projekten - für 
Micropython PSRAM bei den ESP32 definitv anraten.

> Richie schrieb:
>> Wenn man aus den Modulen vorcompilierten Bytecode erzeugt (mpy-cross:
>> .py zu .mpy), dann entfällt der Parse-Schritt und man spart schonmal
>> RAM.
>
> …welcher jedoch nach der erstmaligen Kompilation nach dem Start sofort
> wieder frei gegeben wird.

Ja, aber den Heap durchaus fragmentiert, insbesondere, wenn er so klein 
ist.

von Christoph M. (mchris)


Lesenswert?

Richie schrieb:
> Genau genommen (PSRAM):
> ESP32: 4MB ohne Tricks, 8MB mit Tricks

Ich habe ein ESP32 WROOM
https://documentation.espressif.com/esp32-wroom-32_datasheet_en.pdf
Falls ich nichts übersehe, steht da nichts von PSRAM.

von Norbert (der_norbert)


Lesenswert?

Christoph M. schrieb:
> MicroPython v1.26.1 on 2025-09-11; Generic ESP32 module with ESP32
> Type "help()" for more information.
>>>> import gc;print(gc.mem_free())
> 151664

Richie schrieb:
> Genau genommen (PSRAM):
> ESP32: 4MB ohne Tricks, 8MB mit Tricks
> ESP32-S2: 10,5MB
> ESP32-S3: 32MB
> ESP32-P4: 64MB

Richie schrieb:
> Nein, das ist nicht richtig.
> Die ESP32 beherrschen transparentes XIP (Execute in Place), mit
> (einstellbarem) Caching, wie auch bei den größeren und neueren STM32.
> Daher steht das gesamte PSRAM auch Micropython voll umfänglich zur
> Verfügung.

Hmmm, dann bekomme ich diese drei Aussagen aber nicht korrekt aligned

von Richie (mikro123)


Lesenswert?

Norbert schrieb:
> Christoph M. schrieb:
>> MicroPython v1.26.1 on 2025-09-11; Generic ESP32 module with ESP32
>> Type "help()" for more information.
>>>>> import gc;print(gc.mem_free())
>> 151664

> Hmmm, dann bekomme ich diese drei Aussagen aber nicht korrekt /aligned/

Wieso?
Christoph hat ein Modul ohne externes PSRAM.
Deshalb habe ich ja geraten, für Micropython etwas MIT PSRAM zu nehmen.

PSRAM ist beim ESP32xx immer über SPI angebunden, daher gibt es auch 
genügend Module/Boards ohne.

von Richie (mikro123)


Lesenswert?

Christoph M. schrieb:
> Richie schrieb:
>> Genau genommen (PSRAM):
>> ESP32: 4MB ohne Tricks, 8MB mit Tricks
>
> Ich habe ein ESP32 WROOM
> https://documentation.espressif.com/esp32-wroom-32_datasheet_en.pdf
> Falls ich nichts übersehe, steht da nichts von PSRAM.

Ja, das ist schon klar.
Daher habe ich ja auch empfohlen, für Projekte mit Micropython ein Modul 
oder ein Board mit PSRAM zu nehmen.
Für Entwicklung ist das sowieso sinnvoll, da kann man dann anfangs 
erstmal etwas Lauffähiges erstellen, was man hinterher dann optimiert.
Und braucht auch nicht bei jeder Änderung eine neue Micropythonfirmware 
aus Platzgründen erstellen.

von Norbert (der_norbert)


Lesenswert?

Richie schrieb:
> Wieso?
> Christoph hat ein Modul ohne externes PSRAM.
> Deshalb habe ich ja geraten, für Micropython etwas MIT PSRAM zu nehmen.

Ahh, OK. Ich entnahm (fälschlicherweise) deiner Auflistung, dass alle 
ESP32 mind. 4MB PSRAM hätten.

> ESP32: 4MB ohne Tricks

von Christoph M. (mchris)


Lesenswert?

Richie schrieb:
> Wieso?
> Christoph hat ein Modul ohne externes PSRAM.
> Deshalb habe ich ja geraten, für Micropython etwas MIT PSRAM zu nehmen.

Ich habe noch zwei Module ESP32S3 n8r2, aber sie treiben mich zum 
Wahnsinn.

Bei dem einen kommt das:

MicroPython v1.19.1 on 2022-06-18; ESP32S3 module with ESP32S3
Type "help()" for more information.
>>> import gc; print(gc.mem_free())
154800
>>>

Also habe ich vermutlich vor einiger Zeit vermutlich v1.19.1 ohne PSRAM 
support dort installiert.

Beim anderen bekomme ich nach
esptool.py --chip esp32s3 --port /dev/ttyACM0 erase_flash

esptool.py --port /dev/ttyACM0 --baud 460800 write_flash 0x1000 
ESP32_GENERIC_S3-20251209-v1.27.0.uf2

von hier https://micropython.org/download/ESP32_GENERIC_S3/

den Fehler im Serial Terminal:

invalid header: 0xffffffff
invalid header: 0xffESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x7 (TG0WDT_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x4004883e
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff

von Christoph M. (mchris)


Lesenswert?

Christoph M. schrieb:
> Ich habe noch zwei Module ESP32S3 n8r2, aber sie treiben mich zum
> Wahnsinn.

Manchmal hat man Tomaten auf den Augen: Die Startadresse war falsch.

so geht es:

esptool.py --chip esp32s3 --port /dev/ttyACM0 erase_flash
esptool.py --port /dev/ttyACM0 --baud 460800 write_flash 0 
ESP32_GENERIC_S3-20251209-v1.27.0.bin


Und es sind volle 2MB in Micropython zur Verfügung:

MicroPython v1.27.0 on 2025-12-09; Generic ESP32S3 module with ESP32S3
Type "help()" for more information.
>>> import gc
>>> print(gc.mem_free())
2046832

von Richie (mikro123)


Lesenswert?

Norbert schrieb:
> Richie schrieb:
>> Wieso?
>> Christoph hat ein Modul ohne externes PSRAM.
>> Deshalb habe ich ja geraten, für Micropython etwas MIT PSRAM zu nehmen.
>
> Ahh, OK. Ich entnahm (fälschlicherweise) deiner Auflistung, dass alle
> ESP32 mind. 4MB PSRAM hätten.
>
>> ESP32: 4MB ohne Tricks

Das bedeutet, dass der (alte) ESP32 zwar 8MB PSRAM ansteuern, aber nur 
4MB in den Adressraum einblenden kann.
Ist also sowas wie Bankswitching.

von Richie (mikro123)


Lesenswert?

Christoph M. schrieb:
> Beim anderen bekomme ich nach
> esptool.py --chip esp32s3 --port /dev/ttyACM0 erase_flash
>
> esptool.py --port /dev/ttyACM0 --baud 460800 write_flash 0x1000
> ESP32_GENERIC_S3-20251209-v1.27.0.uf2

Das ist die falsche Firmware. Die setzt einen UF2 Bootloader voraus:

https://github.com/adafruit/tinyuf2

Du musst die .bin nehmen.

von Richie (mikro123)


Lesenswert?

Christoph M. schrieb:
> Christoph M. schrieb:
>> Ich habe noch zwei Module ESP32S3 n8r2, aber sie treiben mich zum
>> Wahnsinn.
>
> Manchmal hat man Tomaten auf den Augen: Die Startadresse war falsch.

Nein, das war die falsche Firmware.

> so geht es:
>
> esptool.py --chip esp32s3 --port /dev/ttyACM0 erase_flash
> esptool.py --port /dev/ttyACM0 --baud 460800 write_flash 0
> ESP32_GENERIC_S3-20251209-v1.27.0.bin

Jetzt stimmt sie :)

von Norbert (der_norbert)


Lesenswert?

Richie schrieb:
> Das bedeutet, dass der (alte) ESP32 zwar 8MB PSRAM ansteuern, aber nur
> 4MB in den Adressraum einblenden kann.
> Ist also sowas wie Bankswitching.

Danke. Gut zu wissen.
Gibt es eigentlich verlässliche Benchmarks** wie sich die 
Geschwindigkeit des gemappten PSRAM vom internen, statischen RAM 
unterscheidet?
Für den Fall, dass ich mir doch einmal ein solches Teil zulegen sollte.

**read-only, read/write, linear access, random access

von Christoph M. (mchris)


Lesenswert?

Norbert schrieb:
> Für den Fall, dass ich mir doch einmal ein solches Teil zulegen sollte.
Dann könntest du dir auch einen ESP32-S3-WROOM-1-N8R8 überlegen, der hat 
8M Flash und 8M PSRam. Wobei der Grund für mich die SIMD MACs sind, die 
den ESP32-S3 schwach KI-fähig machen. Ob Micropython was damit anfangen 
kann, weiß ich aber nicht.

von Norbert (der_norbert)


Angehängte Dateien:

Lesenswert?

Habe gerade mal zum Spaß einen rp2350 auf 240MHz (ESP32 speed) gesetzt.
Hier ist die gemessene Lesegeschwindigkeit für das interne RAM (100KB. 
BYTE, HALFWORD und WORD Transfers):
1
# uploading ›pico_RAM_DMA.py‹ to Pi Pico…
2
 CPU @ 240 MHz
3
 BYTE    : 520 µs   192.3 MB/s
4
 HALFWORD: 259 µs   386.1 MB/s
5
 WORD    : 131 µs   763.4 MB/s

Dann das Datenblatt des ESP PSRAM chips ESP-PSRAM64H genommen und etwas 
drauf herumgerechnet.
Das Quad-SPI darf bei wahlfreiem Zugriff mit 84MHz getaktet werden.
Was zusammen mit dem unvermeidlichen Adress-Setup (14 Zyklen) zu einer 
maximalen Geschwindigkeit von kleiner 42MB/s führt. Aber nur wenn 
sequentiell, in aufsteigender Richtung und reichlich viel am Stück 
gelesen wird.
Bei Random (WORD) Zugriff liegt man bei ~15MB/s.

Abhängig von der XIP cache Größe wird das die erzielbare Geschwindigkeit 
mehr als deutlich senken, sobald der (limitierte) cache nicht ausreicht. 
Der muss sowohl FLASH als auch PSRAM bedienen.

Nur mal so als Info…

von Christoph M. (mchris)


Lesenswert?

Norbert schrieb:
> Nur mal so als Info…

Möglicherweise wäre ein allgemeiner Benchmark der Hardwareunabhängig auf 
beiden Plattformen läuft, nicht schlecht.

von Christoph M. (mchris)


Lesenswert?

Sowas:
1
import gc
2
import time
3
4
gc.collect()
5
N = 100000
6
7
def bench_list_write():
8
    lst = []
9
    t0 = time.ticks_ms()
10
    for i in range(N):
11
        lst.append(i)
12
    t1 = time.ticks_ms()
13
    dt = time.ticks_diff(t1, t0)
14
    print("List append:", N, "items in", dt, "ms")
15
    print("Per append:", dt * 1000 / N, "µs")
16
17
print("Ram",gc.mem_free())
18
bench_list_write()
19
print("Ram",gc.mem_free())

(ESP32 S3 n8r2)
Ram 2061280
List append: 100000 items in 718 ms
Per append: 7.18 µs
Ram 1325376

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

Irgendwas ist faul in der Micropython-Implementierung. Wenn man ein 
großes Byte-Array initialisiert, wird die Ausgabe von gc.mem_free() 
extrem langsam:
1
>>> import gc
2
>>> ba = bytearray(100000)  # Creates 100KB of null bytes (0x00)
3
>>> print(gc.mem_free()) # hier geht es mehrere Sekunden, bis das Ergebnis angezeig wird
4
1379696

von Norbert (der_norbert)


Lesenswert?

Christoph M. schrieb:
> Irgendwas ist faul …

Offensichtlich, denn:
1
#!python
2
#!/micropython
3
import gc
4
from time import ticks_us,ticks_diff
5
6
def test():
7
    t0 = ticks_us()
8
    ba = bytearray(100_000)
9
    t1 = ticks_us()
10
    n = gc.mem_free()
11
    t2 = ticks_us()
12
    print(f'free:{n} bytes' )
13
    print(f'{ticks_diff(t1,t0)} µs')
14
    print(f'{ticks_diff(t2,t1)} µs')
15
16
test()
1
free:140976 bytes
2
2557 µs
3
6529 µs
Auf nem ollen rp2040 bei 125MHz

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Christoph M. schrieb:
> Möglicherweise wäre ein allgemeiner Benchmark der Hardwareunabhängig auf
> beiden Plattformen läuft, nicht schlecht.

Yep. Aber meiner arbeitet mit DMA und mangels ESP kann ich das Zeug 
nicht darauf anpassen. Wenn's der's denn überhaupt kann/zulässt.

von Norbert (der_norbert)


Lesenswert?

Christoph,
Hier ist mal ein Quickie welcher auf beiden RP2xx0 prima läuft.
Hat aber nur eine überschaubare Geschwindigkeit, da µPy auf dem ESP wohl 
noch kein Extensa Assembler anbietet.
SIZE müsstest du größtmöglich anpassen, damit auch wirklich im PSRAM 
gearbeitet wird. (850_000 vielleicht?)
1
#!/python
2
# vim: fileencoding=utf-8: ts=4: sw=4: expandtab:
3
from machine import freq as cpufreq
4
from time import ticks_us,ticks_diff
5
6
MEG = const(1_000_000)
7
SIZE = const(100_000) # zwei mal genutzt
8
9
@micropython.viper
10
def memcpyB(src: ptr8, dest: ptr8, size:int):
11
    idx: int = size
12
    while (idx:=idx-1) >= 0:
13
        dest[idx] = src[idx]
14
15
@micropython.viper
16
def memcpyHW(src: ptr16, dest: ptr16, size:int):
17
    idx: int = size//2
18
    while (idx:=idx-1) >= 0:
19
        dest[idx] = src[idx]
20
21
@micropython.viper
22
def memcpyW(src: ptr32, dest: ptr32, size:int):
23
    idx: int = size//4
24
    while (idx:=idx-1) >= 0:
25
        dest[idx] = src[idx]
26
27
def test():
28
    cpufreq(240*MEG)
29
    t0 = ticks_us()
30
    ba1 = bytearray(SIZE)
31
    ba2 = bytearray(SIZE)
32
    t1 = ticks_us()
33
    memcpyB(ba1, ba2, SIZE)
34
    t2 = ticks_us()
35
    memcpyHW(ba1, ba2, SIZE)
36
    t3 = ticks_us()
37
    memcpyW(ba1, ba2, SIZE)
38
    t4 = ticks_us()
39
40
    print(f'CPU:  {cpufreq()/MEG:8} MHz')
41
    print(f'alloc:{ticks_diff(t1,t0):8} µs')
42
    print(f'BYTE: {ticks_diff(t2,t1):8} µs')
43
    print(f'HALF: {ticks_diff(t3,t2):8} µs')
44
    print(f'WORD: {ticks_diff(t4,t3):8} µs')
45
46
test()
47
cpufreq(125*MEG)
1
CPU:       240 MHz
2
alloc:    2825 µs
3
BYTE:    13368 µs
4
HALF:     7096 µs
5
WORD:     3549 µs

von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Norbert schrieb:
> Hat aber nur eine überschaubare Geschwindigkeit, da µPy auf dem ESP wohl
> noch kein Extensa Assembler anbietet.

Für den Vergleich wäre es vermutlich besser, Viper nicht zu verwenden. 
Dann dürften die Ergebnisse auch vergleichbarer sein.
Das File habe ich leicht verändert, weil der ESP keine 125MHz hat.
1
DUT: ESP32 S3 n8r2
2
3
mem_free 2058592
4
copy size 100000
5
6
CPU:       240 MHz
7
alloc:   35529 µs
8
BYTE:    18814 µs
9
HALF:    12966 µs
10
WORD:    10750 µs
11
12
mem_free 1861632

von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Es gibt sehr viel Hardware mit dem ESP.
So könnte man das CYD für die Anzeige der Wetterdaten verwenden.
Es hat auch einen SD-Kartenslot, auf dem man die Daten loggen könnte. 
Allerdings hat es kein zusätzliches PS-RAM.

von Richie (mikro123)


Lesenswert?

Christoph M. schrieb:
> Es gibt sehr viel Hardware mit dem ESP.
> So könnte man das CYD für die Anzeige der Wetterdaten verwenden.
> Es hat auch einen SD-Kartenslot, auf dem man die Daten loggen könnte.
> Allerdings hat es kein zusätzliches PS-RAM.

Ähnliche Teile gibt es ja auch mit einem ESP32-S3 sowie PSRAM und 
verschieden großen Displays. Da muss man nicht die "Ursprungs"-Version 
nehmen.

von Richie (mikro123)


Angehängte Dateien:

Lesenswert?

Christoph M. schrieb:
> Norbert schrieb:
>
1
> DUT: ESP32 S3 n8r2
2
> 
3
> mem_free 2058592
4
> copy size 100000
5
> 
6
> CPU:       240 MHz
7
> alloc:   35529 µs
8
> BYTE:    18814 µs
9
> HALF:    12966 µs
10
> WORD:    10750 µs
11
> 
12
> mem_free 1861632
13
>

Auf einem S3 mit 8MB PSRAM sind die Werte leicht anders (habe noch eine 
kleine Detailinformationsausgabe eingebaut):
1
ID ............: b'\xf4\x12\xfa\xcb\x1f\xcc'
2
Platform ......: esp32
3
Version .......: 3.4.0; MicroPython v1.27.0 on 2026-01-25
4
Memory
5
   total ......: 8126.5 KB
6
   usage ......: 7.15625 KB (0.08171568%)
7
   free .......: 8119.328 KB (99.91982%)
8
ROM
9
   total ......: 14336.0 KB
10
   usage ......: 84.0 KB (99.41406%)
11
   Free .......: 14252.0 KB (0.5859375%)
12
system name ...: esp32
13
node name .....: esp32
14
release .......: 1.27.0
15
version .......: v1.27.0 on 2026-01-25
16
machine .......: Generic ESP32S3 module with Octal-SPIRAM with ESP32S3
17
Frequency .....: 240000000
18
19
mem_free 8314272
20
copy size 100000
21
22
CPU:       240 MHz
23
alloc:   19316 µs
24
BYTE:    14918 µs
25
HALF:     9850 µs
26
WORD:     6171 µs
27
28
mem_free 8118800
29
MicroPython v1.27.0 on 2026-01-25; Generic ESP32S3 module with Octal-SPIRAM with ESP32S3

von Norbert (der_norbert)


Lesenswert?

Christoph M. schrieb:
> Für den Vergleich wäre es vermutlich besser, Viper nicht zu verwenden.

Nein, da kann ich nicht zustimmen.
Denn wir wollen den Datendurchsatz des RAM/PSRAM bestimmen.
Und dazu muss man so wenig wie möglich Overhead haben. Guter Viper code 
erzeugt im Rahmen der Möglichkeiten einen anständigen internen Assembler 
Code.

Aber selbst Handgeschriebener Assembler hat ein 7:4 Verhältnis bezogen 
auf einen LDR/STR Schleifendurchgang.
Einzig DMA zeigt (annähernd) präzise den möglichen Durchsatz.
Dennoch, hier mal (nur für ARM) eine Assembler Routine, die in den 
vorigen Code eingefügt werden muss:
1
#!python
2
@micropython.asm_thumb
3
def memcpyAsm(r0,r1,r2):            # src: ptr32, dest: ptr32, size:int):
4
    asr     (r2,r2,2)               # size //= 4
5
    sub     (r2,r2,1)
6
    label   (loop)
7
    data    (2,0b0101100010000011)  #2    ldr     (r3, [r0,r2])
8
    data    (2,0b0101000010001011)  #2    str     (r3, [r1,r2])
9
    sub     (r2,r2,1)               #1
10
    bpl     (loop)                  #2/1
11
    
12
13
14
    
15
    t4 = ticks_us()
16
    memcpyAsm(ba1, ba2, SIZE)
17
    t5 = ticks_us()
18
19
    print(f'CPU:    {cpufreq()/MEG:6} MHz')         # CPU:       240 MHz
20
    print(f'alloc:  {ticks_diff(t1,t0):6} µs')      # alloc:    2286 µs
21
    print(f'BYTE:   {ticks_diff(t2,t1):6} µs')      # BYTE:    10539 µs
22
    print(f'HALF:   {ticks_diff(t3,t2):6} µs')      # HALF:     5686 µs
23
    print(f'WORD:   {ticks_diff(t4,t3):6} µs')      # WORD:     2845 µs
24
    print(f'WORDasm:{ticks_diff(t5,t4):6} µs')      # WORDasm:   791 µs

von Norbert (der_norbert)


Lesenswert?

Richie, Christoph,

auf dem ESP32 solltet ihr die Größe der src/dest array sehr deutlich 
vergrößern um sicher zu stellen, dass auch wirklich PSRAM genutzt wird.
Bei 2MB sollte SIZE vielleicht so bei 850_000 … 900_000 liegen.
Die Zeiten kann man dann ja bequem durch 8.5 … 9.0 teilen um auf 
vergleichbare Werte zu kommen.

Aber selbst bei den kleinen 100kB scheint der ESP bei gleicher 
Taktfrequenz ja schon um den Faktor 3.5 (bzw. 2.0) langsamer zu sein.

: Bearbeitet durch User
von Richie (mikro123)


Lesenswert?

Norbert schrieb:
> Christoph M. schrieb:
>> Irgendwas ist faul …
>
> Offensichtlich, denn:
>
1
#!python
2
> #!/micropython
3
> import gc
4
> from time import ticks_us,ticks_diff
5
> 
6
> def test():
7
>     t0 = ticks_us()
8
>     ba = bytearray(100_000)
9
>     t1 = ticks_us()
10
>     n = gc.mem_free()
11
>     t2 = ticks_us()
12
>     print(f'free:{n} bytes' )
13
>     print(f'{ticks_diff(t1,t0)} µs')
14
>     print(f'{ticks_diff(t2,t1)} µs')
15
> 
16
> test()
17
>
>
1
> free:140976 bytes
2
> 2557 µs
3
> 6529 µs
4
>
> Auf nem ollen rp2040 bei 125MHz

Auf einem S3 mit 8MB PSRAM bei 240MHz:
1
free:8189072 bytes
2
6718 µs
3
2059 µs
4
MicroPython v1.27.0 on 2026-01-25; Generic ESP32S3 module with Octal-SPIRAM with ESP32S3

von Norbert (der_norbert)


Lesenswert?

Ja, das war bei 125MHz.
Da dauert alloc länger, gc kürzer.
Bei 240MHz wären's auf einem rp2040 1321µs und  3373µs.

Aber ich sehe gerade, dass der S3 octalSPI hat, das erklärt die etwas 
besseren Werte im Vergleich zum S2.

Dennoch, mich würde mal eine große RAM Schaufelei interessieren.

von Richie (mikro123)


Lesenswert?

Mit
1
SIZE = const(4_000_000) # zwei mal genutzt

ergibt sich:
1
ID ............: b'\xf4\x12\xfa\xcb\x1f\xcc'
2
Platform ......: esp32
3
Version .......: 3.4.0; MicroPython v1.27.0 on 2026-01-25
4
Memory
5
   total ......: 8126.5 KB
6
   usage ......: 7.15625 KB (0.08171568%)
7
   free .......: 8119.328 KB (99.91982%)
8
ROM
9
   total ......: 14336.0 KB
10
   usage ......: 84.0 KB (99.41406%)
11
   Free .......: 14252.0 KB (0.5859375%)
12
system name ...: esp32
13
node name .....: esp32
14
release .......: 1.27.0
15
version .......: v1.27.0 on 2026-01-25
16
machine .......: Generic ESP32S3 module with Octal-SPIRAM with ESP32S3
17
Frequency .....: 240000000
18
19
mem_free 8314272
20
copy size 4000000
21
22
CPU:       240 MHz
23
alloc:  739315 µs
24
BYTE:   603220 µs
25
HALF:   392375 µs
26
WORD:   245440 µs
27
28
mem_free 297552
29
MicroPython v1.27.0 on 2026-01-25; Generic ESP32S3 module with Octal-SPIRAM with ESP32S3

von Richie (mikro123)


Lesenswert?

Als Ergänzung:

Wenn Micropython mit PSRAM-Unterstützung kompiliert wird, dann wird 
ausschließlich PSRAM für den Heap genutzt.
Das interne SRAM steht dann voll dem ESP-IDF zur Verfügung. Also für 
WLAN oder Socket Buffer, für SSL und anderen Kram. Auch liegt ja noch 
ein FreeRTOS darunter.

Wenn man also große Geschwindigkeit und wenig RAM braucht, dann nimmt 
man besser einen ESP32xx ohne PSRAM.

Ein paar nähere Details:
https://github.com/micropython/micropython/issues/8940

von Norbert (der_norbert)


Angehängte Dateien:

Lesenswert?

Das ist gar nicht mal so schlecht.
Wenn ich mich nicht verrechnet haben, ist das nur 1.5 bis 2.2 mal 
langsamer als internes RAM.
Hätte ich nicht gedacht.
 Vermutlich ist die OctalSPI Anbindung dafür verantwortlich. Wenn jetzt 
noch mem-zu-mem DMA auf den ESPs ginge, dann hätten wir noch besser 
vergleichbare Ergebnisse.
Aber trotzdem, unter den Umständen werde ich mir vielleicht mal einen S3 
in die Schublade legen.
Hab' mal für die Bequemlichkeit eine neue Version (mit Durchsatz 
Berechnung) angehängt. Der ARM Assembler Teil ist auskommentiert.

von Christoph M. (mchris)


Lesenswert?

Norbert schrieb:
> Vermutlich ist die OctalSPI Anbindung dafür verantwortlich.

Bisher hatte ich nicht die Octal-SPRAM Version installiert. Wie stellt 
man fest, auf welche Art das SPRAM angeschlossen ist.

Der angezeigte Speicher scheint zu stimmen, aber mit obigem Benchmark 
"memcopy2.py" kann man die SIZE nicht mehr viel größer als 10K stellen, 
sonst gibt es einen Fehler.

[code]
ESP32 S3 n8r2
SIZE=const(10*KILO)
MicroPython v1.27.0 on 2025-12-09; Generic ESP32S3 module with 
Octal-SPIRAM with ESP32S3

CPU: Generic ESP32S3 module with Octal-SPIRAM with ESP32S3 @ 240.0 MHz
alloc:     270 µs
BYTE:     1269 µs      7.9 MB/s
HALF:      596 µs     16.8 MB/s
WORD:      308 µs     32.5 MB/s
[/coce]

von Norbert (der_norbert)


Lesenswert?

Christoph M. schrieb:
> esptool.py --chip esp32s3 --port /dev/ttyACM0 erase_flash
> esptool.py --port /dev/ttyACM0 --baud 460800 write_flash 0
> ESP32_GENERIC_S3-20251209-v1.27.0.bin
>
> Und es sind volle 2MB in Micropython zur Verfügung:
>
> MicroPython v1.27.0 on 2025-12-09; Generic ESP32S3 module with ESP32S3
> Type "help()" for more information.
>>>> import gc
>>>> print(gc.mem_free())
> 2046832




Christoph M. schrieb:
> Bisher hatte ich nicht die Octal-SPRAM Version installiert. Wie stellt
> man fest, auf welche Art das SPRAM angeschlossen ist.
>
> Der angezeigte Speicher scheint zu stimmen, aber mit obigem Benchmark
> "memcopy2.py" kann man die SIZE nicht mehr viel größer als 10K stellen,
> sonst gibt es einen Fehler.

Hmmm, also mem_free zeigt über 2MB, aber es lassen sich nur 20kB 
allokieren? Das passt irgendwie nicht aufeinander. Leider kann ich 
mangels Controller nichts testen.
Ich würde ein Terminal aufmachen und von Hand ein paar bytearrays in 
ansteigender Größe anlegen.

Oh, eines noch…
> 308 µs
Wir benutzen seit mehr als drei Jahrzehnten recht erfolgreich UTF-8.
Solltest du in deiner Umgebung (OS/IDE/Terminal) auch mal versuchen. ;-)

von Christoph M. (mchris)


Lesenswert?

Norbert schrieb:
> Wir benutzen seit mehr als drei Jahrzehnten recht erfolgreich UTF-8.

Drück mal oben auf dein File "filecopy2.py" anstatt auf Codeansicht, 
dann siehst du das Problem. Ich habe es vom "Raw-File" kopiert ..

von Norbert (der_norbert)


Lesenswert?

Christoph M. schrieb:
> Norbert schrieb:
>> Wir benutzen seit mehr als drei Jahrzehnten recht erfolgreich UTF-8.
>
> Drück mal oben auf dein File "filecopy2.py" anstatt auf Codeansicht,
> dann siehst du das Problem. Ich habe es vom "Raw-File" kopiert ..

Tja, das ist dann wohl ein weiteres Problem dieser Website.
Keine UTF-8 Angabe im Header.
Aber Rechtsklick ›Ziel speichern unter…‹ funktioniert.

von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Hier mal zurück zum Thema "Wetterstation".
Die Idee ist, einen BME an einen ESP32 (oder noch besser an einen 
ESP8266) anzuschließen und die Daten dann per ESPNOW zu übertragen.
ESPNOW ist wesentlich stromsparender als WIFI und man könnte den Sensor 
schlafen legen und alle 5 Minuten für ein paar Millisekunden aufwachen 
lassen. Dadurch dürfte der Stromverbrauch recht gering werden.
Ob Micropython dafür wirklich geeignet ist, wäre allerdings fraglich. 
Gibt es überhaupt einen Powerdown und Aufwachmechanismus?
Vielleicht könnte man das Arduino-Framework dafür besser verwenden.

(In dem angehängten Beispiel muss man erst die MAC-Adresse des Displays 
auslesen und in den Sender-Code eintragen, sonst nimmt der Empfänger 
keine Datenpakete an)

von Helmut H. (helmuth)


Lesenswert?

Christoph M. schrieb:
> Ob Micropython dafür wirklich geeignet ist, wäre allerdings fraglich.
> Gibt es überhaupt einen Powerdown und Aufwachmechanismus?
https://docs.micropython.org/en/latest/library/esp.html#esp.deepsleep

von Richie (mikro123)


Lesenswert?

Christoph M. schrieb:
> ESPNOW ist wesentlich stromsparender als WIFI und man könnte den Sensor
> schlafen legen und alle 5 Minuten für ein paar Millisekunden aufwachen
> lassen. Dadurch dürfte der Stromverbrauch recht gering werden.

Genaugenommen ist ESP-NOW ein Protokoll ab LinkLayer aufwärts.
Es kann mit Wi-Fi ebenso wie mit Bluetoot-LE genutzt werden.
Mit Wi-Fi als PhysicalLayer werden die Daten in 802.11 Management Action 
Frames verpackt.

> Ob Micropython dafür wirklich geeignet ist, wäre allerdings fraglich.
> Gibt es überhaupt einen Powerdown und Aufwachmechanismus?
> Vielleicht könnte man das Arduino-Framework dafür besser verwenden.

Ungeeignet ist Micropython sicherlich nicht in jedem Fall.
Aber nur Du weisst, wieviel Energie bei Dir zur Verfügung steht.

Für eine erste Abschätzung:
https://github.com/glenn20/upy-esp32-experiments/blob/main/ESPNowvsWifiEnergyUsage/README.md

von Christoph M. (mchris)


Angehängte Dateien:

Lesenswert?

Danke für eure Hinweise bezüglich des "deep sleep".
Hier der Sendercode für einen BME280 und die Ergebnisse der 
Strommessung.
1
ESP32 sender for BME280 with sleep
2
3
Measured values on a ESP32 WROOM development board
4
5V power supply at Vin, red power on board led on
5
11 mA   ESP Sleep (red power LED on)
6
40 mA   ESP ON, Wifi Off
7
112 mA  ESP ON  Wifi ON

Am besten soll der Sensor im Batteriebetrieb ein Jahr lang 
funktionieren. Da sind die 11mA natürlich unbrauchbar. Ich weiß nicht, 
ob die OnBoard LED und der LDO so viel Strom zieht. Da wären die ESP8266 
ESP01 wahrscheinlich besser geeignet, nur vermutlich etwas klein für 
Micropython. Vielleicht müsste man mit einem externen Attiny13 o.ä. den 
Wakeup Prozess steuern und über einen externen Transistor die 
Stromversorgung des ESP32 vollständig abklemmen, damit man in den 
Micro-Amperbereich, der für die Batterieversorgung notwendig ist, 
vorzustoßen. Besser wäre vielleicht noch eine kleine Solarzelle mit 
Goldcap als Stromversorgung.

von Jo (emsig)


Lesenswert?

Christoph M. schrieb:
> Am besten soll der Sensor im Batteriebetrieb ein Jahr lang
> funktionieren.

Das ist doch mal eine Ansage.

> Da sind die 11mA natürlich unbrauchbar. Ich weiß nicht,
> ob die OnBoard LED und der LDO so viel Strom zieht.

Ja klar, damit geht das natürlich nicht.

Eine grundsätzliche Frage wäre, ob man an dem Sensor überhaupt einen ESP 
verbauen will. Wenn es der einzige Sensor bleiben soll und die 
Stromversorgung unproblematisch ist, dann ist das völlig OK. Bei 
mehreren oder sogar vielen Sensoren wäre aber zu überlegen, diese mit 
einem Atmega328 zu betreiben und die Messungen über simple 433Mhz-Sender 
an eine Zentrale zu übermitteln. Damit lassen sich dann die einzelnen 
Sensoren tatsächlich über Monate oder Jahre (je nach Messintervall) mit 
einer Batterieladung autonom betreiben, wohingegen Sammlung, 
Archivierung und Aufbereitung der Daten (z.B. Grafana) zentral erfolgen, 
wo die Stromversorgung unproblematisch ist.

Für den Sensor empfehle ich einen preisgünstigen Pro-Mini-Klon. Die LED 
muss natürlich entfernt werden, den die ist der größte Stromfresser 
überhaupt. Der verbaute LDO ist i.d.R. auch nicht geeignet; als Ersatz 
dient ein MCP1700-3302E. Als Batterien verwende ich 3xAA. Die Daten 
sammle ich mit einem RTL-SDR an einem RPi ein und kann gleichzeitig noch 
viele andere Sensor-Daten erfassen (z.B. fertig gekaufte 
Bewegungsmelder). Läuft seit 6 Jahren problemlos und wäre meine 
Empfehlung.

Nichtsdestotrotz kann man das auch mit ESP8266 und ESPNOW hinbekommen. 
Unter dem Strich ist das aber nicht einfacher. Und wenn man gleich ein 
Board wie den Pro-Mini von Rocketscream verwendet, entfällt auch die 
Bastelei mit dem LDO, denn einen MCP1700-3302E hat das Board schon von 
Haus aus.

Nachtrag+sorry: Auf dem Pro-Mini geht das leider nicht mit Micropython.

: Bearbeitet durch User
von Jack V. (jackv)


Lesenswert?

Christoph M. schrieb:
> Hier der Sendercode für einen BME280 und die Ergebnisse der
> Strommessung.

Laut 
https://lastminuteengineers.com/esp32-sleep-modes-power-consumption/ 
wären im Deep Sleep zweistellige μA gut erreichbar. Damit sollte man mit 
einer entsprechenden Batterie auch schon etwas hinkommen – teuer wird 
halt das Übertragen. Vielleicht wäre da einer der ESP mit Zigbee (etwa 
C6) eine mögliche Lösung?

von Christoph M. (mchris)



Lesenswert?

Jo schrieb:
> Eine grundsätzliche Frage wäre, ob man an dem Sensor überhaupt einen ESP
> verbauen will.

Es könnte schon sein, dass der ESP nicht die optimale Wahl ist. Ich 
finde aber das Prinzip "Gleichteilkonzept" nicht schlecht. Möglichst 
immer die gleichen Bauteile verwenden, das verringert die Lagerhaltung 
und die Zahl der Bestellvorgänge. Wenn es mit dem ESP ging, wäre das 
seht gut. Vielleicht ließe sich der ESP32 direkt an 2xAA ohne 
Spannungsregler betreiben, dann wäre es sogar noch einfacher als der 
Pro-Mini, den du vorgeschlagen hast.

Jack V. schrieb:
> https://lastminuteengineers.com/esp32-sleep-modes-power-consumption/
> wären im Deep Sleep zweistellige μA gut erreichbar.

Der obige Aufbau ist mit einem ESP32 Breakout ohne Spannungsregler aber 
mit BME280. Da es ständig Brown-Outs gab ist noch ein ziemlich großer 
3300uF in der Versorgung. Im DeepSleep braucht das ganze ca. 150uA. 
Allerdings gibt es ein im Moment unerklärliches Problem: Nach dem 
Aufwachen bricht die Versorgungsspannung stark ein. Versorgt wird das 
ganze über ein Labornetzteil mit Laborkabeln. Der Zuleitungswiderstand 
sollte eigentlich nicht zu hoch sein.
Es dauert insgesamt fast 1,3 Sekunden bis die LED geblinkt hat (mangenta 
Signal). Das wäre natürlich schlecht für den Langzeitbetrieb, wenn der 
Sensor jedes mal über eine Sekunde laufen müsste.

Das Testprogramm sieht im Moment so aus:
1
import network, espnow, machine
2
from machine import Pin, I2C
3
import time, struct
4
from bme280_float import *
5
import re
6
7
SLEEP_TIME_MS = 3_000 #seconds * 1000
8
9
led = Pin(2, Pin.OUT)
10
led.on()
11
time.sleep(0.1)
12
led.off()
13
14
machine.deepsleep(SLEEP_TIME_MS)

: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

Im Moment sieht es danach aus, als wenn der ESP-Wifi Treiber Zeit in der 
Größenordnung von einer Sekunde braucht, um zu initialisieren. Das 
treibt den Stromverbrauch dann in die Höhe.

Ich weis nicht genau, wie viel Kapazität eine AA-Batterie hat. Bei 
angenommenen 2000mAh und 100mA Verbrauch beim Senden ergäbe sich eine 
Laufzeit von 20 Stunden.
Wenn man jetzt noch ein Tastverhältnis von 100 annimmt (1 Sekunde an 200 
Sekunden aus, ca. 3 Minuten ) dann kommt man auf 2000 Stunden, was in 
etwa einem Vierteljahr entspricht. Das ist leider nicht ganz die 
gewünschte Zielmarke.

Hier habe ich noch einen guten Link zum Deep-Sleep gefunden:
https://lastminuteengineers.com/esp32-deep-sleep-wakeup-sources/

Gibt es eigentlich fertige, käufliche Klimasensoren mit ESP für z.B. 
Homeautomation?

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Christoph M. schrieb:
> Ich weis nicht genau, wie viel Kapazität eine AA-Batterie hat. Bei
> angenommenen 2000mAh und 100mA Verbrauch beim Senden ergäbe sich eine
> Laufzeit von 20 Stunden.
> Wenn man jetzt noch ein Tastverhältnis von 100 annimmt (1 Sekunde an 200
> Sekunden aus, ca. 3 Minuten ) dann kommt man auf 2000 Stunden, was in
> etwa einem Vierteljahr entspricht. Das ist leider nicht ganz die
> gewünschte Zielmarke.

Snarky remark: Wenn du ein Jahr brauchst, nimm halt vier Batterien.

Aber mal ernsthaft, dickes Wifi mit diesem Stromverbrauch passen nicht 
sehr gut zu einer besonders Energie-sparenden Anwendung. Da böte sich 
vielleicht eher etwas im LoRa Bereich an.

von Christoph M. (mchris)


Lesenswert?

Norbert schrieb:
> Aber mal ernsthaft, dickes Wifi mit diesem Stromverbrauch passen nicht
> sehr gut zu einer besonders Energie-sparenden Anwendung. Da böte sich
> vielleicht eher etwas im LoRa Bereich an.

Mit dem Tastverhältnis kann man viel machen und ESPNOW sollte etwas 
energiesparender sein als der volle WLAN-Stack. Der ESP kann auch BPSK, 
damit sollte es sehr viel energiesparendere Möglichkeiten geben.
Was LoRa anbelangt verschmiert es die Sendeleistung durch Chirps über 
eine breiteren Frequenzbereich und die Reichweite wird im wesentlichen 
durch die Dauer bei niedriger Sendeleistung erreicht.

Eigentlich hätte der ESP auch BLE, aber das wird von Micropython eher 
schlecht unterstützt, meine ich.

: Bearbeitet durch User
von Jack V. (jackv)


Lesenswert?

Christoph M. schrieb:
> Eigentlich hätte der ESP auch BLE, aber das wird von Micropython eher
> schlecht unterstützt, meine ich.

https://docs.micropython.org/en/latest/library/bluetooth.html#bluetooth.BLE

Das sieht für mich auf dem ersten Blick nun nicht soo unbrauchbar aus.

von Christoph M. (mchris)


Lesenswert?

Norbert schrieb:
> Snarky remark: Wenn du ein Jahr brauchst, nimm halt vier Batterien.

Hier muss vielleicht noch ergänzt werden, dass zwar eine Batterie 
2000mAh hat, aber für 3V ja zwei Batterien benötigt werden. Damit währen 
8 Batterien erforderlich und das ist ein ziemliches Paket. Es muss also 
Strom gespart werden.

von Rainer W. (rawi)


Lesenswert?

Christoph M. schrieb:
> Allerdings gibt es ein im Moment unerklärliches Problem: Nach dem
> Aufwachen bricht die Versorgungsspannung stark ein.

Das wird nur eine Folgeerscheinung sein. Wahrscheinlich zieht nach dem 
Aufwachen irgendwer heftig Strom und der Innenwiderstand deiner 
Versorgung ist dafür zu groß.
Warum misst du nicht die Stromaufnahme an einer soliden Versorgung und 
lässt sie dir, zusammen mit irgendwelchem, eindeutig dem Programmablauf 
zuordenbarem, GPIO-Gehampel, auf dem Oszi anzeigen?
Das könnte Licht hinter "unerklärlich" bringen.

: Bearbeitet durch User
von Christoph M. (mchris)



Lesenswert?

Rainer W. schrieb:
> Das wird nur eine Folgeerscheinung sein. Wahrscheinlich zieht nach dem
> Aufwachen irgendwer heftig Strom und der Innenwiderstand deiner
> Versorgung ist dafür zu groß.

Es war tatsächlich eine Art Fehler des Messaufbaus: Das Labornetzteil 
ist an sich eine zuverlässige Stromversorgung. Um den Strom zu messen 
war ein einigermaßen gutes SDM3065X Multimeter in die Leitung 
geschaltet. Da es auf Autorange stand, macht es eine Bereichsumschaltung 
bei der man auch ein Relais klicken hört, wenn der Strom von 150uA auf 
100mA springt. Unerwarteterweise wird da scheinbar auch auf einen 
andereren Shunt umgeschaltet, was zum sichtbaren Spannungseinbruch der 
Versorgung geführt hat.

Im Anhang jetzt eine Messung mit 1Ohm Shunt und Oszilloskop. Der 
Stromverbrauch beim Senden ist echt hoch und wie man im Bild ablesen 
kann, geht der in der Spitze bis 500mA.
Mit dieser Messung kann man aber jetzt die Batterielebensdauer über das 
Integral der Stromaufnahme ausrechnen.
Ursprünglich hatte ich einen Fehler in Micropython im Verdacht, deshalb 
ist diese Version mit dem Arduino-Framework gemacht, damit ich einen 
Fehler von Micropython ausschließen konnte.
Es hat mich auch einige Zeit gekostet herauszufinden, dass man nach dem 
Sendebefehl nicht gleich in den DeepSleep gehen darf, weil die Daten im 
Hintergrund noch gesendet werden müssen. Deshalb ist an der 
entsprechenden Stelle ein empirisch ermitteltes 20ms Delay.

von Christoph M. (mchris)


Lesenswert?

Im Zeitalter der KI kann man den Oszilloskop-Screenshot einfach in 
ChatGPT werfen.
Es kommt dann auf 22mA Durchschnitt während der ON-Phase.
Mit 300 Sekunden Duty-Cycle behauptet es dann:

* **2×AA alkaline** → **~9 months**
* **2×AA lithium** → **~14 months**
* **Average ESP32 current ≈ 270 µA**

Die 22mA scheinen mir aber nicht so recht hinzukommen. Die lange flache 
Linie im vorderen Bereich müsste bei 100mV/div eher bei 40mA als bei 
20mA liegen. Damit würde sich dann die Batterielebensdauer halbieren.

: Bearbeitet durch User
von Jack V. (jackv)


Lesenswert?

Christoph M. schrieb:
> Im Zeitalter der KI kann man den Oszilloskop-Screenshot einfach in
> ChatGPT werfen.

Kann man machen. Kaffeesatzlesen ist allerdings umweltfreundlicher.

Du weißt, dass es Sprachmodelle sind, die mit Rechnen und Logik 
allenfalls rudimentär zurechtkommen?

Tipp am Rande: Wenn du zumindest für Screenshots das Grid heller 
anzeigen lässt, ist’s für Andere deutlich angenehmer, drüberzuschauen 
und sie auszuwerten.

: Bearbeitet durch User
von Heinz R. (heijz)


Lesenswert?

Jack V. schrieb:
> Kann man machen. Kaffeesatzlesen ist allerdings umweltfreundlicher.

immer diese KI-Hasser :-) man muss da halt leider auch mit der Zeit 
gehen

Ich musste z.B. diese Woche eine große Tabelle die ich nur als jpg hatte 
in Excel importieren - geht mit KI in 30 Sekunden oder per hand in 2 
Stunden

von Jack V. (jackv)


Lesenswert?

Heinz R. schrieb:
> Ich musste z.B. diese Woche eine große Tabelle die ich nur als jpg hatte
> in Excel importieren - geht mit KI in 30 Sekunden oder per hand in 2
> Stunden

So Xerox-Style? Referenz: 
https://www.dkriesel.com/en/blog/2013/0802_xerox-workcentres_are_switching_written_numbers_when_scanning

Mal ernsthaft: Modellen, die nicht mal in der Lage sind, zuverlässig das 
Auftreten eines bestimmten Buchstabens in einem Wort richtig zu zählen, 
einen schlechten Screenshot eines Oszis vorzusetzen und zu glauben, da 
käme was Sinnvolles raus, ist dann doch schon sehr naiv, finde ich.

von 900ss (900ss)


Lesenswert?

KI ist halt auch nur ein Mensch ;)

von Norbert (der_norbert)


Lesenswert?

Jack V. schrieb:
> Mal ernsthaft: Modellen, die nicht mal in der Lage sind, zuverlässig das
> Auftreten eines bestimmten Buchstabens in einem Wort richtig zu zählen,
> einen schlechten Screenshot eines Oszis vorzusetzen und zu glauben, da
> käme was Sinnvolles raus, ist dann doch schon sehr naiv, finde ich.

KI ist eben der neue Gott. Und ein Großteil der Bevölkerung hat sich 
mangels besseren Wissens dieser neuen Religion zugewandt. Die 
Ernüchterung kommt – wie bei allen anderen Religionen – erst viel, viel 
später. Und einige werden dennoch daran festhalten und weiter hoffen und 
beten. Zumindest bis ein neuer Austauschgott gefunden ist. Selber denken 
ist nachweislich anstrengend, betreutes Denken hingegen viel bequemer.

von Christoph M. (mchris)


Lesenswert?

Hier geht es weiter zur KI-Diskussion:
Beitrag "Programmieren mit KI"

von Christoph M. (mchris)



Lesenswert?

Interessant ist, den Sensor von draußen auf der Fensterbank nach drinnen 
zu legen. Die Feuchte zeigt dann erst einmal einen Anstieg.
Ich habe noch eine Batteriespannungsüberwachung dran gebaute. Sie nutzt 
die interne 1.1V Referenz und der Pin muss dann über einen 
Spannungsteiler angeschlossen werden. Damit der nicht dauernd Strom 
zieht, ist er einen einen Ausgangspin angeschlossen, der auf HIGH 
geschaltet werden muss um zu messen. Die Batteriespannung scheint 
Temperaturabhängig zu sein. Sie steigt in der Wärme langsam an 
(zumindest sieht das der ADC so).

Der Temperatursensor wird mit dem angehängten Arduino-Skript betrieben 
und der Empfänger ist Micropython auf dem CYD das die Daten per serielle 
Schnittstelle an den PC weiterleiten und dort online mit einem von der 
KI-erzeugten Python-Script dargestellt werden.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Christoph M. schrieb:
> Andreas M. schrieb:
>> Der ESP holt standardmäßig sich die Uhrzeit von einem Zeitserver...
>
> Das kann er aber als Access-Point scheinbar nicht tun. So ist er aber
> konfiguriert.

Ein Stand-alone AP sicher nicht, woher auch. "Normale" APs haben 
üblicherweise auch einen LAN-Anschluss, dann haben sie das Problem 
nicht.

Theoretisch könnte auch einer der (dauerhaft verbundenen) Clients die 
Zeit liefern, denn Netz ist Netz, da sind alle gleichberechtigt 
verbunden (sofern man das nicht durch Routing oder "client isolation" 
o.ä. verhindert).

von Christoph M. (mchris)


Lesenswert?

Frank E. schrieb:
> Ein Stand-alone AP sicher nicht,

Der ESP hat auch eine eingebaute RTC. Man könnte die Uhrzeit einmal über 
den Browser des Endgerätes setzten. Ein Javascript Programm kann ja die 
Uhrzeit des Browsers auslesen. Damit könnte die Webseite die der ESP zur 
Verfügung stellt, einfach auch die Uhrzeit auslesen.

von Christoph M. (mchris)



Lesenswert?

Hier sind die erweiterten Messungen, nachdem ich den Sensor wieder auf 
die Fensterbank gelegt habe.

Diesmal auch mit csv-File, welches vom Python-Script auf dem PC 
abgespeichert wird.

Man sieht wie draußen die Batteriespannung abfällt. Der letzte Eintrag 
war von 11:09:40. Der Erste 08:54:42. Damit ist der Sensor als etwas 
über zwei Stunden gelaufen. Die zwei AA Batterien sind ohne 
Spannungsregler direkt am Versorgungspin des ESP32-WROOM. Ich vermute, 
dass die Batterien von meinigen vorigen Versuchen schon etwas leer waren 
und da die Zykluszeit hier 3 Sekunden statt 300 Sekunden war, würde 
dürfte die Entladung ewas 100x schneller gewesen sein.

Interessant ist das der Counter: Scheinbar wird der bei niedrigen 
Batteriesspannungen auf 0 gesetzt. Als Ursache würde ich vermuten, das 
bei einem Brown-Out auch die Variablen im RTC-Ram auf 0 gesetzt werden.

von Heinz R. (heijz)


Lesenswert?

Norbert schrieb:
> KI ist eben der neue Gott. Und ein Großteil der Bevölkerung hat sich
> mangels besseren Wissens dieser neuen Religion zugewandt.

Vor 30 Jahren hättest vermutlich auch Handys eine neue Religion genannt?

Heute hats fast jeder

von Christoph M. (mchris)



Lesenswert?

Hier noch das Micropython-Empfängerprogramm, die PC-Visualisierung und 
das Bild des Außensensors. Man sieht noch den abstehenden 1 Ohm Shunt, 
den ich zur Messung der Stromaufnahme benutzt habe.

von Ralf X. (ralf0815)


Lesenswert?

Christoph M. schrieb:
> Hier noch das Micropython-Empfängerprogramm, die PC-Visualisierung und
> das Bild des Außensensors. Man sieht noch den abstehenden 1 Ohm Shunt,
> den ich zur Messung der Stromaufnahme benutzt habe.

Was bringt Dich dazu, für das Foto das ungeeignete png-Format zu nutzen?

von Rainer W. (rawi)


Lesenswert?

Christoph M. schrieb:
> Unerwarteterweise wird da scheinbar auch auf einen
> andereren Shunt umgeschaltet, was zum sichtbaren Spannungseinbruch der
> Versorgung geführt hat.

Wieso "unerwarteterweise"?
Um bei der Messung kleiner Ströme über einen Shunt nicht in den Bereich 
von Kontaktspannungen zu kommen, MUSS man den Shunt umschalten oder in 
anderer Weise dafür sorgen, dass der Spannungsabfall bei wechsel zu 
hohen Strömen nicht zu groß wird.

Mit einem Multimeter wirst du sowieso nicht die Zeitauflösung erreichen, 
die erforderlich ist, um Änderungen der Stromaufnahme in einzelnen 
Programmbereichen detailliert zu erfassen. Das reicht nur für eine 
Grobunterscheidung, aber schon die Einzelphasen bei WLAN-Aktivität 
werden dir damit entgehen. Das Oszi ist da deutlich die bessere Wahl.

Christoph M. schrieb:
> Die Batteriespannung scheint Temperaturabhängig zu sein. Sie steigt in
> der Wärme langsam an (zumindest sieht das der ADC so).

Eine Messung ist nur der Vergleich mit einem Bezugswert.
Solange du sowohl die Temperatur der Batterie als auch die der 
ADC-Referenz änderst, weißt du nicht, wer von den beiden sich wie stark 
mit der Temperatur ändert - die Batteriespannung oder die 
Referenzspannung. Allenfalls die Zeitkonstante könnte ein Hinweis sein. 
Du könntest den ADC auch mit ein wenig Heißluft einmal etwas 
herausfordern.

: Bearbeitet durch User
von Christoph M. (mchris)



Lesenswert?

Rainer W. schrieb:
> Mit einem Multimeter wirst du sowieso nicht die Zeitauflösung erreichen,
> die erforderlich ist, um Änderungen der Stromaufnahme in einzelnen
> Programmbereichen detailliert zu erfassen. Das reicht nur für eine
> Grobunterscheidung, aber schon die Einzelphasen bei WLAN-Aktivität
> werden dir damit entgehen. Das Oszi ist da deutlich die bessere Wahl.

Die Messung ist ja oben gemacht:
https://www.mikrocontroller.net/attachment/688861/ESPNOW_sender_1Ohm_recieverON.png

Im Moment versuche ich es gerade mit einer anderen Methode, die 
bezüglich der Batterielebensdauer aussagekräftiger sein könnten: Einfach 
neue Varta Batterien mit einem verkürzten Deep-Sleep mit einer Dauer von 
3 Sekunden leer laufen lassen und schauen, wie lange das geht. Im Moment 
sind es schon 8 Stunden, was bei einem später vorgesehen Deep-Sleep von 
300 Sekunden dann grob überschlagen 800 Stunden wären (ohne 
Berücksichtigung der 150uA Deep-Sleep Stromaufnahme).
Bei der letzten Messung hatte ich Batterien eines anderen Herstellers. 
Die Messkurven deute ich im Moment so, dass die Varta nicht so 
temperaturabhängig ist.

: Bearbeitet durch User
von Dirk B. (dirkb2)


Lesenswert?

Christoph M. schrieb:
> Die Frage ist: gibt es jahreszeitliche Schwankungen des CO2 Wertes?

Es kann sich in windstillen Nächten auch CO2 am Boden konzentrieren.

Dann hat man vor Sonnenaufgang durchaus 600 - 800 ppm.

von Christoph M. (mchris)


Lesenswert?

Dirk B. schrieb:
> Christoph M. schrieb:
>> Die Frage ist: gibt es jahreszeitliche Schwankungen des CO2 Wertes?
>
> Es kann sich in windstillen Nächten auch CO2 am Boden konzentrieren.
>
> Dann hat man vor Sonnenaufgang durchaus 600 - 800 ppm.

Danke für den Hinweis. Mein Sensor ist eher auf Dachhöhe, aber 
vielleicht gibt es da ja auch irgendwelche Effekte. Wenn ich dazu komme, 
werde ich mal einen Feinstaubsensor mit anschließen. Der dürfte dann mit 
den umliegenden Kaminen korrelieren.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.