Temperaturschalter mit Raspberry Pico, DHT22 und Neopixel
Auch wenn der Bytespeicher pandemiebedingt nicht mehr unbedingt Ort der Entwicklung war, so ist dieses Projekt doch mit viel Hilfe und Feedback aus dem #elektronik:erfurt.chat Matrix-Raum entstanden und verdient damit auch einen Artikel hier im Bytespeicher-Blog.
Ziel
Zur Beheizung eines Gewächshauses soll eine China-Diesel-Campingheizung um eine Temperaturschaltung erweitert werden. Der Autor hat keinen direkten Zugriff auf die Heizung und muss mit folgenden Annahmen arbeiten:
-
Das Bedienterminal der Heizung wird mit 12 V versorgt. Diese sind vor Ort vorhanden.
-
Die Heizung schaltete sich durch 5 s Druck auf ein ‚Ein/Aus‘-Taster ein und befindet sich bereits im gewünschten Betriebsmodus.
-
Die Heizung schaltet sich durch 5 s Druck auf den ‚Ein/Aus‘-Taster wieder aus.
-
Umgebungsbedingungen sind worst case -25 ºC bis +70 ºC und hohe Luftfeuchtigkeit.
-
Zieltemperature ist 3 ºC (einschalten) und 10 ºC (ausschalten)
Bauteilbeschaffung
Der Autor möchte aus persönlichen Gründen gerne in Python programmieren und um das Ändern von Parametern durch ungeübte Anwender zu erleichtern soll der zu verwendende Microcontroller als USB-Massenspeicher am PC mit Software-Updates zu versorgen sein. Ein Vorschlag aus dem Chat war der Raspberry Pi Pico, der sogleich für bescheidene 3,95 EUR von berrybase.de geordert wurde. Der Bequemlichkeit halber wurde im gleichen Shop noch eine Streifenlochrasterplatine, Stiftleisten, ein TIP22 MOSFET, ein DC/DC Spannungswandler und ein DHT22 Modul in den Warenkorb gepackt. Der günstigere DHT11 mag leider keine Minustemperaturen.
Ein Neopixel-Ring mit 8 RGB-LEDs und ein Streifen 12 V LEDs waren noch im eigenen Lager verfügbar.
Kosten aller nötigen Bauteile beläuft sich auf <16 EUR.
Konzept
-
Der Pico soll mit Micrpython programmiert werden, benötigt also eine Micropython Firmware.
-
Der DHT22 liefert Temperatur- und Luftfeuchtigkeitswerte über einen Digitalpin und benötigt 3,3 V als Versorgung.
-
Ein Digitalpin (mit 3,3 V) steuert den TIP122 MOSFET am Basispin um die Emitter-Collector-Strecke leitend zu schalten. Dort kann dann die 12 V Spannung zur Heizung geschaltet werden und den Ein/Aus-Taster ersetzen.
-
Parallel zum Tasterausgang werden 12 V LEDs zur Visualisierung geschaltet.
-
In Ermangelung eines echten Displays werden die Neopixel (addressierbaren Mehrfarb-LEDs) in Farbe und Anzahl die gemessene Temperatur visualisieren
Umsetzung Elektronik
Die nötige Schaltung wurde auf der Streifenlochrasterplatine aufgebaut. Das ist nicht ganz ideal, weil eigentlich nur der TIP122 Pins zum Durchstecken hat. Der Neopixelring hat Lötpads NUR auf der Unterseite, die 12 V LEDs NUR oben. Der DC/DC- Wandler immerhin oben UND unten sowie Löcher, der Pico wahlweise Halbloch-Kantenkontakte und Löcher für Stiftleisten.
Trotzdem wurden alle Komponenten auf der Oberseite (ohne Leiterstreifen) der Platine positioniert. Der Pico bekam Stiftleisten, der Spannungswandler Einzelpins in den Löchern und der Neopixelring handgebogene 90-Grad-Drahtstücke als Ersatzpins. Auch der TIP122 wurde 90 º gebogen und der LED-Streifen aufgeklebt.
Kabelstückchen wurden so angefertig, dass sie (fast) nur auf der Oberseite verlegt und mit 90 Grad gebogenen Enden durchgesteckt und auf der Unterseite verlötet wurden. Lediglich die Pads des LED-Streifens wurden auf der Oberseite angelötet.
Auf der Unterseite wurden soweit möglich (und eher ungeschickt) die vorhandenen Leitungsstreifen benutzt. Wo ein Auftrennen nötig war, wurde mit dem Fräser des Proxxon-Rotationstools vorsichtig die Kupferschicht entfernt.
Zum Test wurde zuerst der Pico nur via USB versorgt und erst kurz vor Schluss mit dem Ausgang des DC/DC- Wandlers verbunden. Dazu wurde diese (vorher!) auf 5 V getrimmt und an den VSYS-Eingang angeschlossen. Die 12 V Versorgung und der 12 V Schaltausgang wird final mittels Lüsterklemmen realisiert, zum Testen bekam die Platine aber einfach 2 dicke Lotpunkte am Rand für die Klemmen eines Labornetzteils.
Der DHT22 speist sich aus dem 3v3 Pin des Pico. Den oft beschriebene externe Pullup-Widerstand gegen VCC habe ich nicht verbaut, da angeblich schon einer im Modul sitzt und zusätzlich auch der Pico den Eingang mit internem Pullup betreibt.
Zwischen Pico-Pin und TIP122-Basis sitzt ein 1k Ohm Widerstand zur Strombegrenzung, um den Pico nicht unnötig zu belasten (3,3 V / 1 kOhm = 3,3 mA). Mit einem Gain-Faktor von ca. 1000 ergibt sich immernoch eine Schaltfähigkeit von 3,3 A bei 12 V. Der Heizungsschalter sollte weit weniger benötigen. Der Collector wird an 12 V, der Emitter auf die Ausgangsklemme und parallel an den 12 V Eingang der LEDs gelegt.
VCC des Neopixel-Rings wird an VSYS des Pico geklemmt, welcher entweder via USB oder vom Spannungswandler mit 5 V versorgt wird. Wichtig: Die Schaltung darf nur via 12 V ODER via USB angeschlossen werden. Niemals beides!
Update: Der Versuch, beim Schreiben dieses Artikels noch mal die Daten vom Pico zu sichten, scheiterte an der Weigerung des Notebooks, den Energiebedarf am USB-Port zu stillen. Ohne Eingangsspannung am DC/DC-Wandler erzeugt dessen Ausgangsseite scheinbar eine zu große Last am VSYS des Pico. Hier muss mit einer noch zu findenden Diode dem Stromfluß Einhalt geboten werden.
Alle Masse-Pads werden verbunden, sowohl über die 12 V als auch die 5-V-Domäne, da der TIP122 von beiden abhängig ist.
Umsetzung Software
Vorgeplänkel
Die Vorstellung, wie der Raspberry Pi Pico programmiert wird wich leider stark von der Realität ab. Anhand der Beschreibung und einem flüchtigen Überfliegen des Handbuchs ging ich davon aus, dass er sich als USB-Mass-Storage Device anmeldet, man ein in Micropython geschriebenes Source-File hochlädt und der Controller es anschließend ausführt. So was ich das z.B. von den CircuitPython Controllern von Adafruit gewohnt.
Leider war alles komplizierter. Nur der BOOTSEL Modus, den man durch drücken eines Tasters vor dem Einstecken via USB erreicht, meldet das Gerät als USB-Mass-Storage an. Hier kopiert man aber nur das Firmware-Image, dass man zur Benutzung von Micropython (im Gegensatz zur Programmierung mittels C wie bei Arduino) benötigt.
Im Normalmodus meldet sich das Gerät erst einmal gar nicht, weil Windows 7 (oder 8) keine Treiber dafür findet. Dies wird auch in der Dokumentation nicht erwähnt. Die nötigen USB-Serial-Treiber fand ich dann auch nicht mal manuell, sondern musste ein Tool namens Zadig nutzen, um die passenden Treiber zu finden und zu installieren. Solche in der Originaldoku unerwähnten Tools, die auch gleich Root-Rechte haben wollen, haben so ein Geschmäckle.
Auch danach meldet sich der Normal-Mode nicht als USB-Mass-Storage, sondern als serielle Verbindung, über die IDEs wie das offizielle Thonny oder VS Code mit Erweiterungen wie Pico Go auf die Daten und die Debug-Console zugreifen können. Thonny speichert/lädt Dateien dann direkt vom Pico, VS Code schickt einzelne Dateien oder erlaubt Zugriff via lokalen FTP Server.
Beides ist nervig zu nutzen, weil sich Windows-typisch der Pico bei jedem 2ten Neustart als ein anderer virtueller COM-Port anmeldet und von den IDEs nicht mehr automatisch verbunden wird. Hier empfiehlt sich ganz klar (wie immer) das Arbeiten unter Linux oder möglicherweise Windows 10/11.
Statt das offizielle MircoPython ließe sich für Folgeprojekte wohl auch CircuitPython installieren, was den USB-Mass-Storage auch im Normalmodus anbietet.
Programmierung
Der Quellcode ist auf Github verfügbar.
Der eigentliche Python-Code besteht im wesentlichen aus 3 Teilen:
Das DHT22 Interface
danjperron/PicoDHT22: Micropython DHT22 class using PIO liefert hier die Vorlage. Es wird das PIO Modul des Pico benutzt, um mittels Assembler-ähnlichen Kommandos eine State-Machine zu programmieren, die sich um das Timing der Kommunikation zum DHT22 kümmert.
Das Neopixel Interface
Hier bekommen wir Hilfe von blaz-r/pi_pico_neopixel: Pi Pico library for NeoPixel led-strip written in MicroPython. Works with ws2812b (RGB) and sk6812 (RGBW). Auch hier wird das PIO Modul mit den programmierbaren State-Machines für die Kommunikation benutzt. Es stehen Komfortfunktionen zur Verfügung, z.B. zum Setzen eines Teilstücks des LED-Rings in einer Farbe, was wir gut für die Temperaturanzeige benutzen können.
main.py
Nach dem Import der DHT22
und neopixel
module sowie dem machine
modul für die Pins können die Bibliotheksobjekte initialisert werden wie es in den jeweiligen Beispielen angegeben ist:
pixels = Neopixel(8, 0, 27, "RGB")
für die Neopixel mit 8 LEDs im Ring, state-machine #0, pin GP27 und Farbwerte im RGB Format.
dht_sensor=DHT22(Pin(2, Pin.IN, Pin.PULL_UP), None, dht11=False, smID=4)
für den DHT22 Sensor an Pin GP02 (mit Pullup), ohne schaltbarer Versorgung, als DHT22, nicht DHT11 und mit state-machine #4.
Der letzte Parameter hat einiges an Nerven gekostet. Obwohl in der Beschreibung als unabhängig beschrieben, kommen sich zwei state-machines bei gleichzeitiger Nutzung in die Quere. Wichtig ist hier die Auswahl zweier state-machines in unterschiedlichen PIO-Modulen. Wer das erklären kann, schreibe gerne in die Kommentare.
In der ewigen Schleife des Hauptprogramms wird dann der DHT22 Sensor ausgelesen und anhand der Temperatur der Ausgang zum TIP122 geschaltet. Dazu gibt es eine einfache Statusvariable und ein doppelte Bedingung für die An-/Abschalttemperatur.
t = 0 if (T<THL) else (len(TEMPS)-1) if (T>(THH - 0.1)) else int((T - THL)/color_step) + 1
p = 0 if (T<THL) else (NUM_LEDS-1) if (T>(THH - 0.1)) else int((T - THL) / led_step) + 1
Ein bisschen Formel-Magic errechnet aus der Temperatur und der Distanz aus An- und Abschalttemperatur einen Wert für die Anzahl der zu beleuchtenden Pixel und einen Farbwert aus einer hart codierten Farbtabelle mit einem blau-zu-rot Gradienten. Ein Pixel bleibt dabei immer blau wenn der Minimum-Wert unterschritten wird und alle Pixel leuchten rot oberhalb des Maximum Wertes.
Abschluss
Werden alle Dateien auf den Pico geladen (und main.py heißt auch tatsächlich main.py), führt dieser den Code nach dem nächsten Neustart automatisch aus.
Damit endet der Artikel, aber wohl nicht die Entwicklung. Nachdem zum Einbau die Heizungssteuerung geöffnet wurde, liegt der Verdacht nahe, dass der Schalter nicht 12 V sondern 5 V oder 3.3 V schaltet. Eine kleine Änderung ist also nötig, das Konzept bliebt aber valide.
Für neue Projekte steht auf dem Plan, definitiv CircuitPython statt MicroPython zu testen. USB-Mass-Storage Support für den Code sollte das Handling erleichtern, angeblich sind aber dafür einige speziellere Funktionen der Hardware nicht verfügbar.
- [Veranstaltung] Python Kurs 2022 – Ausfall der nächsten Kurstage - 16. Mai 2022
- [Veranstaltung] Python Kurs 2022 – Teil 8 - 3. Mai 2022
- [Veranstaltung] Python Kurs 2022 – Teil 7 - 19. April 2022