{"id":1964,"date":"2025-09-04T17:14:32","date_gmt":"2025-09-04T15:14:32","guid":{"rendered":"https:\/\/elv001.staging.360vier.net\/?p=1964"},"modified":"2026-04-15T12:51:35","modified_gmt":"2026-04-15T10:51:35","slug":"python-raspberry-pi-sensoren-messwerterfassung","status":"publish","type":"post","link":"https:\/\/de.elv.com\/elvjournal\/python-raspberry-pi-sensoren-messwerterfassung\/","title":{"rendered":"Einstieg in Python (Teil 9): Sensoren und Messwerterfassung"},"content":{"rendered":"\n<p class=\"has-gray-light-color has-text-color has-link-color has-h-5-font-size wp-elements-2af75c8b732bdf3b0ea2373bdb2c25dc\"><strong>Einstieg in Python (Teil 9)<\/strong><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Programmieren lernen f\u00fcr Einsteiger: <strong>Sensoren und Messwerterfassung<\/strong><\/h1>\n\n\n\n<p><strong>Bereits in Teil 5 dieser Serie wurde erl\u00e4utert, wie man mit Python analoge Messwerte erfassen kann. Dazu wurde der Raspberry Pi mit einem externen Analog-Digital-Wandler ausgestattet. Dies erm\u00f6glichte die Messung analoger Strom- und Spannungswerte. Wesentlich interessanter ist jedoch der Einsatz von Sensoren, mit denen nahezu jeder physikalische Wert wie Temperatur, Feuchte, Druck, Beleuchtungsst\u00e4rke, Bewegung usw. erfasst werden k\u00f6nnen. In diesem Beitrag soll daher die Auswertung und Verarbeitung von Sensorsignalen mit Python im Fokus stehen. Zudem sollen spezielle Signalverarbeitungstechniken genauer betrachtet werden.<\/strong><\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Messwerterfassung mit Sensoren<\/h2>\n\n\n\n<p>Der Raspberry Pi ist eine der vielseitigsten Plattformen zur Messwerterfassung mit Sensoren. Durch die Kombination von Python-Programmierung und GPIO-Pins lassen sich zahlreiche physikalische Gr\u00f6\u00dfen erfassen und verarbeiten. Sensoren k\u00f6nnen \u00fcber verschiedene Schnittstellen mit dem Raspberry Pi verbunden werden:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>GPIO (General Purpose Input\/Output):<\/strong> direkte digitale Ansteuerung von Sensoren<\/li>\n\n\n\n<li><strong>I2C (Inter-Integrated Circuit):<\/strong> serielles Kommunikationsprotokoll f\u00fcr Sensoren wie das <a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https:\/\/www.bosch-sensortec.com\/media\/boschsensortec\/downloads\/datasheets\/bst-bme280-ds002.pdf\">BME280<\/a>-Modul (Temperatur, Luftdruck, Feuchte)<\/li>\n\n\n\n<li><strong>SPI (Serial Peripheral Interface):<\/strong> Hochgeschwindigkeitsprotokoll f\u00fcr Sensoren wie den <a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https:\/\/www.alldatasheet.com\/datasheet-pdf\/pdf\/304549\/MICROCHIP\/MCP3008.html#:~:text=Part%20%23%3A%20MCP3008.%20Download.%20File%20Size%3A%20777Kbytes.%20Page%3A,Converters%20with%20SPI%20Serial%20Interface.%20Manufacturer%3A%20Microchip%20Technology.\">MCP3008-AD-Wandler<\/a><\/li>\n\n\n\n<li><strong>UART (Universal Asynchronous Receiver-Transmitter):<\/strong> Kommunikation mit seriellen Sensoren oder Modulen wie GPS<\/li>\n<\/ul>\n\n\n\n<p>Neben diesen universellen Bussystemen haben sich auch noch einige spezielle Schnittstellen etabliert. Diese sind vor allem beim Anschluss von Sensoren an den Raspberry Pi weitverbreitet. Sie sollen daher im Folgenden genauer betrachtet werden. Die universellen Schnittstellen und ihre Anwendungen werden dann in sp\u00e4teren Artikeln ausf\u00fchrlicher erl\u00e4utert.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Messwerterfassung mit Python<\/h2>\n\n\n\n<p>Eine der wichtigsten Spezialschnittstellen ist der sogenannte Eindraht oder \u201eOne-Wire-Bus&#8220;. Der One-Wire-Bus nutzt ein serielles Kommunikationsprotokoll, das mit nur einer Datenleitung (plus Masse) auskommt. Es wurde von Dallas Semiconductor (heute Maxim Integrated) entwickelt und wird h\u00e4ufig f\u00fcr den Anschluss von Sensoren und Speicherbausteinen verwendet.<br>Ein bekanntes Beispiel ist der <a href=\"https:\/\/www.alldatasheet.com\/datasheet-pdf\/pdf\/58557\/DALLAS\/DS18B20.html\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">DS18B20<\/a>-Temperatursensor, der \u00fcber den One-Wire-Bus mit Mikrocontrollern oder dem Raspberry Pi kommunizieren kann. Das Protokoll erm\u00f6glicht den Betrieb mehrerer Ger\u00e4te an einer einzigen Leitung durch eine eindeutige 64-Bit-Adresse pro Ger\u00e4t. Die Vorteile des One-Wire-Busses sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Einfache Verdrahtung (nur eine Datenleitung)<\/li>\n\n\n\n<li>Energieversorgung \u00fcber die Datenleitung m\u00f6glich (sogenannte \u201eparasit\u00e4re Versorgung&#8220;)<\/li>\n\n\n\n<li>Kosteng\u00fcnstig und effizient f\u00fcr einfache Sensoranwendungen<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p>Eingesetzt wird der One-Wire-Bus vor allem in Temperaturmessungen, Identifikationssystemen und Datenloggern. Der DS18B20-Temperatursensor verf\u00fcgt \u00fcber drei Pins <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">(Bild 1)<\/mark>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>VCC (3,3 V oder 5 V)<\/li>\n\n\n\n<li>GND (Masse)<\/li>\n\n\n\n<li>DO (Datenleitung)<\/li>\n<\/ul>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<figure class=\"wp-block-image size-full is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"816\" height=\"764\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild02_python_teil9.jpg\" alt=\"Bild 1: Temperatur\u0002sensor DS18B20\" class=\"wp-image-3335\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild02_python_teil9.jpg 816w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild02_python_teil9-300x281.jpg 300w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild02_python_teil9-768x719.jpg 768w\" sizes=\"auto, (max-width: 816px) 100vw, 816px\" \/><figcaption class=\"wp-element-caption\">Bild 1: Temperatursensor DS18B20<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>Zus\u00e4tzlich zum Sensor selbst wird noch ein 4,7-k\u2126-Pull-up-Widerstand zwischen VCC und DQ ben\u00f6tigt. <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">Bild 2<\/mark> zeigt den Aufbau.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"1035\" height=\"1338\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild03_python_teil9.jpg\" alt=\"Bild 2: DS18B20-Temperatursensor am Raspberry Pi\" class=\"wp-image-3336\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild03_python_teil9.jpg 1035w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild03_python_teil9-232x300.jpg 232w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild03_python_teil9-768x993.jpg 768w\" sizes=\"auto, (max-width: 1035px) 100vw, 1035px\" \/><figcaption class=\"wp-element-caption\">Bild 2: DS18B20-Temperatursensor am Raspberry Pi<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">One-Wire-Schnittstelle aktivieren<\/h2>\n\n\n\n<p>Um die One-Wire-Schnittstelle zu nutzen, muss man auf dem Raspberry Pi die Datei <code>\/boot\/config.txt<\/code> \u00f6ffnen und am Ende den Eintrag <code>dtoverlay=w1-gpio<\/code> hinzuf\u00fcgen. Danach kann das One-Wire-Interface freigeschaltet werden <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">(Bild 3)<\/mark>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"583\" height=\"273\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-112827.png\" alt=\"Bild 3: Freischalten des One-Wire-Interfaces\" class=\"wp-image-2386\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-112827.png 583w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-112827-300x140.png 300w\" sizes=\"auto, (max-width: 583px) 100vw, 583px\" \/><figcaption class=\"wp-element-caption\">Bild 3: Freischalten des One-Wire-Interfaces\n<\/figcaption><\/figure>\n\n\n\n<p>Anschlie\u00dfend sollte der Raspberry Pi neu gestartet werden. Nach dem Neustart sind die erforderlichen Module zu laden:<\/p>\n\n\n\n<pre class=\"wp-block-code has-secondary-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>sudo modprobe w1-gpio\nsudo modprobe w1-therm<\/code><\/pre>\n\n\n\n<p>Dann kann man das Verzeichnis des Sensors pr\u00fcfen:<\/p>\n\n\n\n<pre class=\"wp-block-code has-secondary-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>cd \/sys\/bus\/w1\/devices\/<\/code><\/pre>\n\n\n\n<p>Hier sollte nach Eingeben des Befehls eine Datei zu sehen sein, z. B. 10-XXXXXXXXXXXX. Damit kann man nun die Temperatur auslesen:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>cat \/sys\/bus\/w1\/devices\/10-XXXXXXXXXXXX\/w1_slave<\/code><\/pre>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>In der Anweisung muss nat\u00fcrlich der oben ermittelte Dateiname verwendet werden. Die Ausgabe enth\u00e4lt eine Zeile mit <code>t=XXXXX<\/code>, wobei xxxxx die Temperatur in Milligrad Celsius (1\/1000\u00b0C) ist. So bedeutet z. B. t=21125 einen Temperaturwert von 21,125 \u00b0C. <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">Bild 4<\/mark> zeigt die vollst\u00e4ndige Befehlsfolge in der Shell.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"772\" height=\"212\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-112917.png\" alt=\"Bild 4: Abfrage des DS18x20 in der Shell\" class=\"wp-image-2388\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-112917.png 772w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-112917-300x82.png 300w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-112917-768x211.png 768w\" sizes=\"auto, (max-width: 772px) 100vw, 772px\" \/><figcaption class=\"wp-element-caption\">Bild 4: Abfrage des DS18x20 in der Shell<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Python-Code f\u00fcr automatische Messung<\/h2>\n\n\n\n<p>Das Abfragen des Sensors in der Shell liefert zwar bereits einen codierten Temperaturwert, jedoch stellt dies im Allgemeinen nicht das gew\u00fcnschte Endergebnis dar. Die universelle Programmiersprache Python kann nat\u00fcrlich auch hier Abhilfe schaffen. Ein einfaches Python-Skript zum Auslesen der Temperatur kann folgenderma\u00dfen aussehen:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>import os\nimport glob\nimport time\n\n# Sensorverzeichnis finden\nbase_dir = \"\/sys\/bus\/w1\/devices\/\"\ndevice_folder = glob.glob(base_dir + \"10*\")&#91;0]\ndevice_file = device_folder + \"\/w1_slave\"\n\ndef read_temp_raw():\n    with open(device_file, \"r\") as f:\n        return f.readlines()\n\ndef read_temp():\n    lines = read_temp_raw()\n    while lines&#91;0].strip()&#91;-3:] != \"YES\":\n        time.sleep(0.2)\n        lines = read_temp_raw()\n    temp_output = lines&#91;1].split(\"t=\")\n    if len(temp_output) &gt; 1:\n        temp_c = float(temp_output&#91;1]) \/ 1000.0\n        return temp_c\n\nwhile True:\n    print(\"Temperatur: {:.2f}\u00b0C\".format(read_temp()))\n    time.sleep(1)<\/code><\/pre>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">Bild 5<\/mark> zeigt die Ausgabe in der Thonny-Shell. Zus\u00e4tzlich wird der Temperaturverlauf im Plotter grafisch dargestellt.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"1037\" height=\"688\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-112958.png\" alt=\"Bild 5: Auslesen der aktuellen Temperatur mit Python\" class=\"wp-image-2389\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-112958.png 1037w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-112958-300x199.png 300w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-112958-768x510.png 768w\" sizes=\"auto, (max-width: 1037px) 100vw, 1037px\" \/><figcaption class=\"wp-element-caption\">Bild 5: Auslesen der aktuellen Temperatur mit Python<\/figcaption><\/figure>\n\n\n\n<p>Das Programm liest die Werte von einem Temperatursensor, in diesem Falle dem DS18B20, \u00fcber den One-Wire-Bus aus. Die Temperaturwerte werden aus der oben vorgestellten Datei im Systemverzeichnis <code>\/sys\/bus\/w1\/devices\/<\/code> entnommen. Zun\u00e4chst werden dazu die erforderlichen Libraries eingebunden:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>import os\nimport glob\nimport time<\/code><\/pre>\n\n\n\n<p><code>os<\/code> erm\u00f6glicht den Zugriff auf Betriebssystemfunktionen, <code>glob<\/code> wird verwendet, um das Verzeichnis des Sensors automatisch zu finden. Das Basisverzeichnis selbst wird direkt angegeben. Dort wird die erforderliche Datei automatisch gesucht:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>base_dir = \"\/sys\/bus\/w1\/devices\/\"\ndevice_folder = glob.glob(base_dir + \"10*\")&#91;0]\ndevice_file = device_folder + \"\/w1_slave\"<\/code><\/pre>\n\n\n\n<p>Dabei ist <code>base_dir<\/code> das Verzeichnis, in dem sich die One-Wire-Ger\u00e4te befinden. Die Anweisung <code>glob.glob(base_dir + \"10*\")<\/code> sucht nach einem Unterordner, dessen Name mit &#8222;10&#8220; beginnt (dies ist die Standardkennung f\u00fcr DS18B20-Sensoren). Die Anweisung <code>device_folder[0]<\/code> nimmt das erste gefundene Verzeichnis. <code>Device_file<\/code> ist der Dateipfad zur Datei <code>w1_slave<\/code>, welche die Sensordaten enth\u00e4lt. Dann werden die Rohdaten aus der Datei gelesen:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>def read_temp_raw():\n    with open(device_file, \"r\") as f:\n        return f.readlines()<\/code><\/pre>\n\n\n\n<p>\u201eOpen\u201c \u00f6ffnet die Datei <code>w1_slave<\/code> und liest ihren Inhalt aus. Die Datei enth\u00e4lt zwei Zeilen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Die erste Zeile zeigt, ob der Wert g\u00fcltig ist (&#8222;YES&#8220; bedeutet g\u00fcltig).<\/li>\n\n\n\n<li>Die zweite Zeile enth\u00e4lt den Temperaturwert in tausendstel Grad Celsius (t=XXXXX).<\/li>\n<\/ul>\n\n\n\n<p>Anschlie\u00dfend kann man den Temperaturwert auslesen und verarbeiten:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>def read_temp():\n    lines = read_temp_raw()\n    while lines&#91;0].strip()&#91;-3:] != \"YES\":\n        time.sleep(0.2)\n        lines = read_temp_raw()<\/code><\/pre>\n\n\n\n<p>Der Befehl <code>Read_temp_raw()<\/code> liest die Datei <code>w1_slave<\/code> ein. <code>While lines[0].strip()[-3:] != \"YES\"<\/code> pr\u00fcft, ob die erste Zeile mit &#8222;YES&#8220; endet. Falls nicht, wartet das Programm 0,2 Sekunden und liest die Datei erneut. Dies stellt sicher, dass der Sensorwert g\u00fcltig ist.<br>Nun kann man die Temperatur extrahieren und umrechnen:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>    temp_output = lines&#91;1].split(\"t=\")\n    if len(temp_output) &gt; 1:\n        temp_c = float(temp_output&#91;1]) \/ 1000.0\n        return temp_c<\/code><\/pre>\n\n\n\n<p>In der Zeile <code>lines[1].split(\"t=\")<\/code> wird die zweite Zeile am Marker &#8222;t=&#8220; aufgetrennt. Der Temperaturwert findet sich nach diesem Marker. \u00dcber <code>float(temp_output[1]) \/ 1000.0<\/code> wird der Wert von tausendstel Grad Celsius in Grad Celsius konvertiert. \u00dcber <code>Return temp_c<\/code> wird anschlie\u00dfend der Temperaturwert zur\u00fcckgegeben. Die Ausgabe der Temperatur erfolgt in der \u00fcblichen Endlosschleife.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Klima und Luftfeuchte<\/h2>\n\n\n\n<p>Allgemein versteht man unter \u201eFeuchte\u201c das Vorhandensein von Wasser in einem Gas oder Feststoff. Von besonderer Bedeutung ist die relative Luftfeuchtigkeit, sie wird als prozentuales Verh\u00e4ltnis aus dem aktuellen Wassergehalt zur maximal m\u00f6glichen absoluten Feuchte, der sogenannten S\u00e4ttigungsfeuchte angegeben. Neben der Temperatur ist die relative Feuchte der wichtigste Parameter, wenn es um die Beurteilung eines Raumklimas geht. Selbst wenn in einem Wohnraum eine angenehme Temperatur von z. B. 21\u00b0C herrscht, f\u00fchlt man sich bei zu hoher oder zu geringer Luftfeuchte nicht wohl.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>Dar\u00fcber hinaus spielt die Luftfeuchtigkeit auch in der Bauphysik eine wichtige Rolle. Zu hohe Luftfeuchtigkeit, z. B. in Kellerr\u00e4umen, f\u00fchrt zu F\u00e4ulnis und Schimmelbildung und kann so ernst zu nehmende Bausch\u00e4den verursachen. Andererseits kann zu geringe Feuchte zur Sch\u00e4digung von Zimmerpflanzen und zu allgemein mangelndem Wohlbefinden f\u00fchren. <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">Bild 6<\/mark> zeigt Sch\u00e4den in einem Kellerraum, die durch dauerhaft zu hohe Luftfeuchtewerte entstanden sind. Diese h\u00e4tten durch den Einsatz einer Feuchte\u00fcberwachung mit dem Raspberry Pi zusammen mit einem DHT11-Sensor fr\u00fchzeitig erkannt werden k\u00f6nnen.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"2087\" height=\"1472\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild06_python_teil9.jpg\" alt=\"Bild 6: Feuchtesch\u00e4den in einem Kellerraum \u2013 fr\u00fch erkannt mit DHT11 und Python\" class=\"wp-image-3349\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild06_python_teil9.jpg 2087w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild06_python_teil9-300x212.jpg 300w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild06_python_teil9-1600x1129.jpg 1600w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild06_python_teil9-768x542.jpg 768w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild06_python_teil9-1536x1083.jpg 1536w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild06_python_teil9-2048x1444.jpg 2048w\" sizes=\"auto, (max-width: 2087px) 100vw, 2087px\" \/><figcaption class=\"wp-element-caption\">Bild 6: Feuchtesch\u00e4den in einem Kellerraum \u2013 fr\u00fch erkannt mit DHT11 und Python<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p>Der <a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https:\/\/www.mouser.com\/datasheet\/2\/758\/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf\">DHT11<\/a> ist ein Temperatur- und Luftfeuchtigkeitssensor, der \u00fcber eine digitale Schnittstelle mit dem Raspberry Pi 5 verbunden werden kann. Er verf\u00fcgt genau wie der DS18x20 \u00fcber ein einfaches digitales Interface. Der Sensor hat prinzipiell vier Pins. Wenn er auf einem Modul montiert ist, werden davon meist jedoch nur drei herausgef\u00fchrt, da der vierte Pin ohne Funktion (\u201enot connected\u201c) ist:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Pin 1:<\/strong> VCC \u2192 3,3 V oder 5 V vom Raspberry Pi<\/li>\n\n\n\n<li><strong>Pin 2:<\/strong> DATA \u2192 ein GPIO-Pin des Raspberry Pi (z. B. GP104, Pin 7)<\/li>\n\n\n\n<li><strong>Pin 3:<\/strong> (NC) \u2192 unbenutzt<\/li>\n\n\n\n<li><strong>Pin 4:<\/strong> GND \u2192 GND vom Raspberry Pi<\/li>\n<\/ul>\n\n\n\n<p>Wird eine DHT11-Modul-Version verwendet, hat der Sensor also nur drei Pins. In diesem Fall entspricht Pin 3 dem vierten Pin (GND) in der obigen Liste.<\/p>\n\n\n\n<p>Neben dem DHT11 existiert auch eine verbesserte Version, der <a href=\"https:\/\/www.alldatasheet.com\/datasheet-pdf\/pdf\/1132459\/ETC2\/DHT22.html\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">DHT22<\/a> <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">(siehe Bild 7)<\/mark>. Dieser verf\u00fcgt \u00fcber eine h\u00f6here Genauigkeit und einen erweiterten Messbereich. F\u00fcr die meisten Anwendungen sollte allerdings der DHT11 ausreichend sein <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">(Bild 8)<\/mark>.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"1043\" height=\"559\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild07_python_teil9.jpg\" alt=\"Bild 7: DHT11 und DHT22\" class=\"wp-image-3344\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild07_python_teil9.jpg 1043w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild07_python_teil9-300x161.jpg 300w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild07_python_teil9-768x412.jpg 768w\" sizes=\"auto, (max-width: 1043px) 100vw, 1043px\" \/><figcaption class=\"wp-element-caption\">Bild 7: DHT11 und DHT22<\/figcaption><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"1043\" height=\"559\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild08_python_teil9.jpg\" alt=\"Bild 8: Pinbelegung des DHT11 und eines DHT11-Moduls\" class=\"wp-image-3339\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild08_python_teil9.jpg 1043w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild08_python_teil9-300x161.jpg 300w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild08_python_teil9-768x412.jpg 768w\" sizes=\"auto, (max-width: 1043px) 100vw, 1043px\" \/><figcaption class=\"wp-element-caption\">Bild 8: Pinbelegung des DHT11 und eines DHT11-Moduls<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p>Hinweis: Falls der Sensor direkt verwendet wird, ist ein Pull-up-Widerstand von 10 k\u2126 zwischen DATA und VCC empfehlenswert. Damit wird ein dauerhaft stabiles Signal gew\u00e4hrleistet. Bei Modulen ist dieser Widerstand meist schon intern vorhanden. <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">Bild 9<\/mark> zeigt den Anschluss des Sensors an den Raspberry Pi.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"1069\" height=\"1161\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild10_python_teil9.jpg\" alt=\"Bild 9: Anschluss des DHT11 an den Raspberry Pi\" class=\"wp-image-3347\" style=\"width:383px;height:auto\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild10_python_teil9.jpg 1069w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild10_python_teil9-276x300.jpg 276w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild10_python_teil9-768x834.jpg 768w\" sizes=\"auto, (max-width: 1069px) 100vw, 1069px\" \/><figcaption class=\"wp-element-caption\">Bild 9: Anschluss des DHT11 an den Raspberry Pi<\/figcaption><\/figure>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">DHT11 am Raspberry Pi<\/h2>\n\n\n\n<p>Das digitale Ausgangssignal des DHT11-Sensors macht den Einsatz am Raspberry Pi besonders einfach. Man kann den Sensor sogar bis zu ca. 10 Meter entfernt von einem Raspberry Pi anschlie\u00dfen, ohne dass Signalst\u00f6rungen auftreten. Dadurch kann die Luftfeuchtigkeit und Temperatur an Orten gemessen werden, an denen z. B. keine Stromversorgung f\u00fcr den Raspberry Pi verf\u00fcgbar ist. Nachdem der DHT11 mit dem Raspberry Pi verbunden ist, kann mithilfe eines Python-Skripts die aktuelle Temperatur und Luftfeuchtigkeit ausgelesen werden. Dazu kann eine DHT-Bibliothek verwendet werden, die den Umgang mit diesem Sensor stark vereinfacht.<br>Zu Beginn sollte man sicherstellen, dass der Raspberry Pi auf dem neuesten Stand ist:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>sudo apt update\nsudo apt upgrade -y<\/code><\/pre>\n\n\n\n<p>Dann werden die ben\u00f6tigten Pakete (nach)installiert:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>sudo apt install python3 python3-pip python3-venv<\/code><\/pre>\n\n\n\n<p>Mit der letzten Anweisung wird die Verwendung von \u201eVirtuellen Umgebungen&#8220; (siehe n\u00e4chste Seite) auf dem Raspberry Pi erm\u00f6glicht.<br>Zun\u00e4chst wird ein Projektverzeichnis erstellt, in dem die Python-Umgebung und das Skript gespeichert werden:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>mkdir ~\/dht11\ncd ~\/dht11<\/code><\/pre>\n\n\n\n<p>Dort wird die virtuelle Python-Umgebung erstellt<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>python3 -m venv env<\/code><\/pre>\n\n\n\n<p>und aktiviert<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>source env\/bin\/activate<\/code><\/pre>\n\n\n\n<p>Dieser Befehl muss bei jeder Verwendung des Skripts erneut ausgef\u00fchrt werden. Dann kann man die DHT-Bibliothek installieren:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>python3 -m pip install adafruit-circuitpython-dht<\/code><\/pre>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Python-Skript zum Auslesen des DHT11-Sensors<\/h2>\n\n\n\n<p>Das Programm zum Auslesen des DHT11-Sensors kann dann wie folgt aussehen:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>import time, board, adafruit_dht\n\ndhtDevice = adafruit_dht.DHT11(board.D17)\n\ntry:\n    while True:\n        try:\n            temperature_c = dhtDevice.temperature\n            humidity = dhtDevice.humidity\n            print(\"Temp: {:.1f}\u00b0C Humidity: {}%\".\n            format(temperature_c, humidity))\n            time.sleep(2.0)\n        except RuntimeError as error:\n            print(error.args&#91;0])\n            time.sleep(2.0)\n            continue\nexcept KeyboardInterrupt as error:\n    print(\"CTRL-C pressed. Deiniting everything...\")\n    dhtDevice.exit()<\/code><\/pre>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>Bevor das Programm in Thonny gestartet werden kann, muss dort die virtuelle Umgebung aktiviert werden<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\"> (Bild 10)<\/mark>.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"1156\" height=\"1266\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild_10_python_teil9.jpg\" alt=\"Bild 10: Aktivieren der \u201eVirtuellen Umgebung\u201c in Thonny\" class=\"wp-image-3353\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild_10_python_teil9.jpg 1156w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild_10_python_teil9-274x300.jpg 274w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/bild_10_python_teil9-768x841.jpg 768w\" sizes=\"auto, (max-width: 1156px) 100vw, 1156px\" \/><figcaption class=\"wp-element-caption\">Bild 10: Aktivieren der \u201eVirtuellen Umgebung\u201c in Thonny<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div class=\"wp-block-group has-gray-lightest-100-background-color has-background is-layout-constrained wp-container-core-group-is-layout-29a8626f wp-block-group-is-layout-constrained\" style=\"padding-top:0;padding-right:var(--wp--preset--spacing--20);padding-bottom:0;padding-left:var(--wp--preset--spacing--20)\">\n<h2 class=\"wp-block-heading\">Wozu braucht man beim Raspberry Pi \u201eVirtuelle Umgebungen\u201c?<\/h2>\n\n\n\n<p>Virtuelle Umgebungen beim Raspberry Pi (und generell in Linux und Python) sind n\u00fctzlich, weil sie helfen, Abh\u00e4ngigkeiten sauber zu verwalten:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Vermeidung von Abh\u00e4ngigkeitskonflikten<\/strong><br>Beim Entwickeln von Projekten mit Python ben\u00f6tigt man oft verschiedene Bibliotheken. Manche Projekte erfordern unterschiedliche Versionen derselben Bibliothek, was zu Konflikten f\u00fchren kann. Eine virtuelle Umgebung isoliert die Abh\u00e4ngigkeiten jedes Projekts, sodass sie sich nicht gegenseitig beeinflussen.<\/li>\n\n\n\n<li><strong>Schutz des Systems<\/strong><br>Wenn man Bibliotheken global installiert (sudo pip install &#8230;), k\u00f6nnen wichtige Systemkomponenten \u00fcberschrieben oder besch\u00e4digt werden. Eine virtuelle Umgebung stellt sicher, dass \u00c4nderungen innerhalb des Projekts bleiben und das Betriebssystem nicht angetastet wird.<\/li>\n\n\n\n<li><strong>Portabilit\u00e4t und Reproduzierbarkeit<\/strong><br>Mit einer virtuellen Umgebung kann man eine Liste aller installierten Pakete (requirements.txt) speichern und das Set-up auf einem anderen System (z. B. einem anderen Raspberry Pi) identisch wiederherstellen. Das erleichtert die Zusammenarbeit und das erneute Einrichten eines Projekts.<\/li>\n\n\n\n<li><strong>Verschiedene Python-Versionen nutzen<\/strong><br>Manchmal ben\u00f6tigt ein Projekt eine spezielle Python-Version. Eine virtuelle Umgebung erm\u00f6glicht es, unterschiedliche Versionen parallel zu nutzen, ohne das gesamte System umzustellen.<\/li>\n<\/ol>\n<\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>Danach kann das Programm gestartet werden und die gew\u00fcnschten Temperatur- und Luftfeuchtewerte werden angezeigt <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">(Bild 11)<\/mark>.<br>Zum Testen kann man den Sensor beispielsweise anhauchen. Dann sollten die Luftfeuchtewerte tempor\u00e4r deutlich ansteigen und anschlie\u00dfend wieder abfallen <strong>(siehe Bild 11)<\/strong>. Die Temperatur dagegen steigt und f\u00e4llt in diesem Fall nur minimal. Beim vorsichtigen Anblasen mit einem Haarf\u00f6hn dagegen steigt die Temperatur stark an, w\u00e4hrend die Feuchtewerte nahezu konstant bleiben.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"871\" height=\"419\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-121848.png\" alt=\"Bild 11: Messwerte in Thonny\" class=\"wp-image-2408\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-121848.png 871w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-121848-300x144.png 300w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-121848-768x369.png 768w\" sizes=\"auto, (max-width: 871px) 100vw, 871px\" \/><figcaption class=\"wp-element-caption\">Bild 11: Messwerte in Thonny\n<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Mittelung, Filterung und Signalkonditionierung<\/h2>\n\n\n\n<p>Bei der Arbeit mit Sensoren erh\u00e4lt man oft verrauschte, schlecht skalierte oder mit hochfrequenten Einstrahlungen behaftete Rohsignale. In der Sensordatenerfassung und Signalverarbeitung sind daher Mittelung, Filterung und Signalkonditionierung grundlegende Techniken, um Rauschen zu reduzieren, n\u00fctzliche Informationen hervorzuheben und Signale f\u00fcr die weitere Analyse vorzubereiten. Mit Python ist man f\u00fcr diese Techniken bestens ger\u00fcstet. <br>Mittelung dient dazu, zuf\u00e4lliges Rauschen zu reduzieren, indem mehrere Messungen kombiniert werden. Ein Beispiel ist der gleitende Durchschnitt (\u201eMoving Average&#8220;), bei dem der Mittelwert \u00fcber ein Fenster von Datenpunkten berechnet wird, z. B. zur<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Gl\u00e4ttung von Temperaturschwankungen<\/li>\n\n\n\n<li>Mittelung von Helligkeitswerten zur Ermittlung von Sonneneinstrahlungswerten f\u00fcr eine Solaranlage<\/li>\n\n\n\n<li>Mittelung von Feuchtedaten zur Steuerung einer Bew\u00e4sserungsanlage<\/li>\n<\/ul>\n\n\n\n<p>Filter entfernen gezielt bestimmte Frequenzanteile eines Signals. Hierzu k\u00f6nnen verschiedene Filtertypen eingesetzt werden:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Tiefpassfilter (Low-pass):<\/strong> L\u00e4sst niedrige Frequenzen durch, filtert hochfrequentes Rauschen heraus<\/li>\n\n\n\n<li><strong>Hochpassfilter (High-pass):<\/strong> Entfernt langsame Trends und bel\u00e4sst schnelle Schwankungen<\/li>\n\n\n\n<li><strong>Bandpassfilter:<\/strong> L\u00e4sst nur einen bestimmten Frequenzbereich passieren<\/li>\n<\/ul>\n\n\n\n<p>Wichtige Anwendungen sind hier:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rauschunterdr\u00fcckung in Audiosignalen<\/li>\n\n\n\n<li>Gl\u00e4ttung von rauschbehafteten Sensordaten<\/li>\n\n\n\n<li>Entfernen unerw\u00fcnschter Signalfrequenzen in drahtlosen \u00dcbertragungssystemen<\/li>\n<\/ul>\n\n\n\n<p>Bei der Signalkonditionierung (Signal Conditioning) werden Rohsignale so angepasst, dass sie f\u00fcr die weitere Verarbeitung geeignet sind. Dazu geh\u00f6ren:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Verst\u00e4rkung<\/strong> zur Erh\u00f6hung der Signalst\u00e4rke<\/li>\n\n\n\n<li><strong>D\u00e4mpfung:<\/strong> Reduzierung der Signalst\u00e4rke, z. B. um \u00dcbersteuerungen zu vermeiden<\/li>\n\n\n\n<li><strong>Konvertierung:<\/strong> \u00c4nderung des Signalformats (z. B. analog zu digital, bin\u00e4re Codierung etc.)<\/li>\n\n\n\n<li><strong>Offset-Korrektur:<\/strong> Entfernt systematische Fehler im Signal<\/li>\n<\/ul>\n\n\n\n<p>Beispiele:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Anpassung eines Sensorsignals, bevor es von einem Mikrocontroller weiterverarbeitet wird<\/li>\n\n\n\n<li>Normierung von Spannungssignalen bei Analog-Digital-Wandlern<\/li>\n<\/ul>\n\n\n\n<p>Eine der einfachsten Methoden ist das gleitende Mittel. <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">Bild 12<\/mark> zeigt eine Visualisierung von Daten zusammen mit einem gleitenden Durchschnitt.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"730\" height=\"376\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-121924.png\" alt=\"Bild 12: Daten mit einem gleitenden Durchschnitt\" class=\"wp-image-2409\" style=\"width:499px;height:auto\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-121924.png 730w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-121924-300x155.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><figcaption class=\"wp-element-caption\">Bild 12: Daten mit einem gleitenden Durchschnitt<\/figcaption><\/figure>\n\n\n\n<p>Das zugeh\u00f6rige Programm (Running_average.py) sieht so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>import numpy as np\nimport matplotlib.pyplot as plt\n\nN=100\n\n# Erstelle die x-Werte\nx = np.linspace(0, 10, N)\n\n# Ersetze die Sinuswerte durch Zufallszahlen\ny = np.sin(x)+0.5*np.random.rand(N) # 50 Zufallszahlen zwischen 0 und 1\n\n# Definiere die Fenstergr\u00f6\u00dfe f\u00fcr den gleitenden Durchschnitt\nwindow = 9\n\n# Berechne den gleitenden Durchschnitt\naverage_y = &#91;]\nfor ind in range(len(y) - window + 1):\n    average_y.append(np.mean(y&#91;ind:ind+window]))\n\n# Erg\u00e4nze die NaN-Werte am Anfang, damit die L\u00e4ngen \u00fcbereinstimmen\nfor ind in range(window - 1):\n    average_y.insert(0, np.nan)\n\n# Plotten der Daten\nplt.figure(figsize=(10, 5))\nplt.plot(x, y, 'y.-', label='Originaldaten')\nplt.plot(x, average_y, 'r.-', label='Running average')\nplt.grid(linestyle=':')\nplt.legend()\nplt.show()<\/code><\/pre>\n\n\n\n<p>Das Python-Programm demonstriert die Anwendung des gleitenden Durchschnitts zur Gl\u00e4ttung verrauschter Daten. Es beginnt mit der Erzeugung einer simulierten Datenreihe, die aus einer Sinuswelle mit hinzugef\u00fcgtem Zufallsrauschen besteht:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>y = np.sin(x)+0.5*np.random.rand(N)<\/code><\/pre>\n\n\n\n<p>Dieses Rauschen soll reale Messungen nachbilden, die oft von unerw\u00fcnschten Schwankungen \u00fcberlagert sind. Der Kern des Programms ist die Berechnung des gleitenden Durchschnitts. Hierbei wird ein \u201eFenster\u201c definierter Gr\u00f6\u00dfe (in diesem Fall 9 Datenpunkte) \u00fcber die Datenreihe geschoben. F\u00fcr jede Position des Fensters wird der Mittelwert der darin enthaltenen Werte berechnet. Diese Mittelwerte bilden die gegl\u00e4ttete Datenreihe:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>average_y.append(np.mean(y&#91;ind:ind+window]))<\/code><\/pre>\n\n\n\n<p>Der gleitende Durchschnitt dient dazu, kurzfristige Schwankungen und Ausrei\u00dfer in den Daten zu reduzieren und den zugrunde liegenden Trend hervorzuheben. Dieses Vorgehen ist neben der Auswertung von Sensordaten auch n\u00fctzlich bei der Analyse von Zeitreihen, wie beispielsweise Aktienkursen oder Wetterdaten, bei denen kurzfristige Schwankungen die Erkennung langfristiger Trends erschweren k\u00f6nnen.<br>Da der gleitende Durchschnitt f\u00fcr die ersten Datenpunkte nicht berechnet werden kann (da noch nicht gen\u00fcgend vorhergehende Werte vorhanden sind), werden am Anfang der gegl\u00e4tteten Datenreihe NaN-Werte (Not a Number) eingef\u00fcgt:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>average_y.insert(0, np.nan)<\/code><\/pre>\n\n\n\n<p>Abschlie\u00dfend werden die Originaldaten und der gleitende Durchschnitt in einem Diagramm dargestellt. Dies erm\u00f6glicht einen visuellen Vergleich der verrauschten Originaldaten mit der gegl\u00e4tteten Version. Das Diagramm<strong> (Bild 12)<\/strong> zeigt, wie der gleitende Durchschnitt das Rauschen reduziert und den zugrunde liegenden Sinuswellen-Trend deutlicher sichtbar macht.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Praktische Anwendung des gleitenden Durchschnitts<\/h2>\n\n\n\n<p>Neben dem Herausfiltern von Rauschen aus Zeitreihendaten kann die Mittelung dabei helfen, saisonale Zyklen in den Daten sichtbar zu machen. Diese Methode wird in vielen Bereichen eingesetzt &#8211; von der Physik \u00fcber Umweltwissenschaften bis hin zur Finanzwelt. Um einen gleitenden Durchschnitt zu berechnen, ist das folgende Vorgehen empfehlenswert:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Definieren einer Fenstergr\u00f6\u00dfe (z. B. 2 bis n\u22121, wobei n&gt;2 die Anzahl der Datenpunkte im Fenster ist)<\/li>\n\n\n\n<li>Berechnen des Durchschnitts innerhalb dieses Fensters<\/li>\n\n\n\n<li>Verschieben des Fensters um einen Datenpunkt und Wiederholen des Vorgangs, bis das Ende der Datenreihe erreicht ist<\/li>\n<\/ol>\n\n\n\n<p>Das folgende Programm zeigt eine Anwendung f\u00fcr den DHT11-Sensor (DHT11_averaging.py):<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>import time\nimport adafruit_dht\nimport board\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Initialisierung des DHT22 Sensors\nsensor = adafruit_dht.DHT11(board.D17) # D4 ist der GPIO-Pin\n\n# Listen f\u00fcr die Daten\ntemperature_readings = &#91;]\nwindow_size = 5 # Fenstergr\u00f6\u00dfe f\u00fcr die Mittelung\nsmoothed_readings = &#91;]\n\ntry:\n    # 50 Messungen durchf\u00fchren\n    for i in range(50):\n        try:\n            # Temperaturdaten auslesen\n            temp_c = sensor.temperature\n            temperature_readings.append(temp_c)\n\n            # Berechne den gleitenden Durchschnitt, wenn genug Daten vorhanden sind\n            if len(temperature_readings) &gt;= window_size:\n                window = temperature_readings&#91;-window_size:]\n                average = np.mean(window)\n                smoothed_readings.append(average)\n            else:\n                smoothed_readings.append(np.nan) # Nicht genug Daten f\u00fcr Mittelung\n\n            print(f\"{temp_c:.2f}\u00b0C, Gegl\u00e4ttet: {smoothed_readings&#91;-1]:.2f}\u00b0C\")\n\n            time.sleep(2) # 2 Sekunden warten zwischen den Messungen\n\n        except RuntimeError as error:\n            # Fehler beim Lesen ignorieren\n            print(f\"Lesefehler: {error}\")\ntime.sleep(2) # 2 Sekunden warten zwischen den Messungen\n\n# Plot der Rohdaten und gegl\u00e4tteten Daten\nplt.figure(figsize=(10, 5))\nplt.plot(temperature_readings, 'k.-', label='Rohdaten')\nplt.plot(smoothed_readings, 'r.-', label='Gleitender Durchschnitt')\nplt.xlabel('Messung')\nplt.ylabel('Temperatur (\u00b0C)')\nplt.title('Temperaturmessung mit gleitendem Durchschnitt')\nplt.legend()\nplt.grid(linestyle=':')\nplt.show()\n\nexcept KeyboardInterrupt as error:\n    print(\"CTRL-C pressed - Ending...\")\n    sensor.exit()<\/code><\/pre>\n\n\n\n<p>In <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">Bild 13<\/mark> sind Originaldaten und der gegl\u00e4ttete Messwertverlauf zu sehen. Das Programm liest zun\u00e4chst Temperaturdaten vom DHT11-Sensor und gl\u00e4ttet sie dann mit einem gleitenden Durchschnitts-Verfahren. Dazu wird zun\u00e4chst der Sensor am GPIO-Pin D17 initialisiert, anschlie\u00dfend werden die Messwerte in einer Liste abgespeichert. Nach jeder Messung wird gepr\u00fcft, ob gen\u00fcgend Daten f\u00fcr den gleitenden Durchschnitt vorhanden sind. Ist dies der Fall, wird der Mittelwert der letzten 5 Messungen berechnet und in einer weiteren Liste gespeichert. Die gemessenen und gegl\u00e4tteten Temperaturen werden in der Konsole ausgegeben und nach 50 Messungen in einem Diagramm dargestellt. Das Diagramm zeigt die Rohdaten und den gegl\u00e4tteten Durchschnitt, um den Effekt der Gl\u00e4ttung zu verdeutlichen. Fehler beim Lesen des Sensors werden dabei abgefangen und ignoriert:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>except RuntimeError as error:\n    # Fehler beim Lesen ignorieren\n    print(f\"Lesefehler: {error}\")<\/code><\/pre>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>Beim Dr\u00fccken von Strg+C wird das Programm beendet. Bei der praktischen Anwendung sollte man beachten, dass mit zunehmender Fenstergr\u00f6\u00dfe die Kurve immer \u201eglatter\u201c wird. Allerdings treten dann jedoch Verz\u00f6gerungen auf (Peaks und T\u00e4ler verschieben sich nach hinten, siehe <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">Bild 13<\/mark>). Es ist daher h\u00e4ufig sinnvoll, verschiedene Fenstergr\u00f6\u00dfen zu testen, um die beste Balance f\u00fcr gegebene Daten zu finden.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full is-resized is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"847\" height=\"399\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-122013.png\" alt=\"Bild 13: Originaldaten und gegl\u00e4tteter Messwertverlauf\" class=\"wp-image-2410\" style=\"width:602px;height:auto\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-122013.png 847w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-122013-300x141.png 300w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-122013-768x362.png 768w\" sizes=\"auto, (max-width: 847px) 100vw, 847px\" \/><figcaption class=\"wp-element-caption\">Bild 13: Originaldaten und gegl\u00e4tteter Messwertverlauf\n<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Filterung von Messwerten<\/h2>\n\n\n\n<p>In der Signalverarbeitung werden sowohl Hoch-, Tief- als auch Bandpassfilter eingesetzt, um bestimmte Frequenzbereiche eines Signals gezielt durchzulassen oder zu d\u00e4mpfen. Diese Methoden helfen dabei, St\u00f6rungen zu entfernen oder relevante Informationen aus einem Signal herauszufiltern. Ein Tiefpassfilter l\u00e4sst niedrige Frequenzen passieren und d\u00e4mpft hohe Frequenzen. Er wird h\u00e4ufig verwendet, um Rauschen (oft hochfrequent) zu reduzieren oder Signale zu gl\u00e4tten.<br><br><strong>Beispiele:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Gl\u00e4ttung von Messwerten bei einem Optosensor, um schnelle, unerw\u00fcnschte Schwankungen zu eliminieren<\/li>\n\n\n\n<li>Reduktion von St\u00f6rungen bei Audiosignalen<\/li>\n<\/ul>\n\n\n\n<p>Ein Hochpassfilter dagegen l\u00e4sst hohe Frequenzen passieren und d\u00e4mpft niedrige Frequenzen. Er wird verwendet, um langsame Trends oder Driften aus einem Signal zu entfernen.<br><br><strong>Beispiele:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Erkennung schneller Signal\u00e4nderungen, z. B. bei Bewegungssensoren<\/li>\n\n\n\n<li>Entfernen von Gleichstromanteilen in Audiosignalen<\/li>\n\n\n\n<li>Reduktion von langsamen Signaldriften, z. B. bei thermischen Einfl\u00fcssen<\/li>\n<\/ul>\n\n\n\n<p>Da Tiefp\u00e4sse ein \u00e4hnliches Verhalten wie Mittelungen zeigen, soll hier exemplarisch eine Hochpassfilterung vorgestellt werden. Ein Python-Programm zur Hochpassfilterung kann wie folgt aussehen:<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>import numpy as np\nimport matplotlib.pyplot as plt\nfrom scipy.signal import butter, lfilter\n\n# Hochpassfilter-Definition\ndef butter_highpass(cutoff, fs, order=5):\n    nyquist = 0.5 * fs # Nyquist-Frequenz\n    normal_cutoff = cutoff \/ nyquist\n    b, a = butter(order, normal_cutoff, btype='high', analog=False)\n    return b, a\n\ndef highpass_filter(data, cutoff, fs, order=5):\n    b, a = butter_highpass(cutoff, fs, order=order)\n    y = lfilter(b, a, data)\n    return y\n\n# Filtereinstellungen\nfs = 100.0 # Abtastrate (Hz)\ncutoff = 10.0 # Grenzfrequenz (50 Hz)\norder = 2 # Filterordnung\n\n# Simuliere Optosensordaten mit St\u00f6rungen im niedrigen Frequenzbereich\nt = np.linspace(0, 5, int(fs * 5)) # Zeitachse f\u00fcr 5 Sekunden\nlow_freq_noise = np.sin(2 * np.pi * 5 * t) # Niederfrequentes Rauschen (5 Hz)\nhigh_freq_signal = np.sin(2 * np.pi * 100 * t) # Hochfrequentes Signal (100 Hz)\nsensor_data = low_freq_noise + high_freq_signal # Signal + niederfrequentes Rauschen\n\n# Hochpassfilter anwenden\nfiltered_data = highpass_filter(sensor_data, cutoff, fs, order)\n\n# Daten visualisieren\nplt.figure(figsize=(12, 6))\nplt.plot(t, sensor_data, label='Rohdaten (mit niederfrequentem Rauschen)', color='red', alpha=0.6)\nplt.plot(t, 3*filtered_data, label='Gefilterte Daten (Hochpass 50 Hz)', color='blue', linewidth=2)\nplt.xlabel('Zeit (s)')\nplt.ylabel('Signalwert')\nplt.title('50-Hz-Hochpassfilter f\u00fcr Sensor-Daten')\nplt.legend()\nplt.grid(True)\nplt.show()<\/code><\/pre>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>In <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">Bild 14<\/mark> erkennt man, dass niederfrequente Signalanteile praktisch vollst\u00e4ndig herausgefiltert werden, w\u00e4hrend die h\u00f6herfrequenten Signale erhalten bleiben. Das Programm simuliert und filtert Optosensordaten, die durch niederfrequente St\u00f6rungen beeinflusst sind. Es erzeugt ein synthetisches Signal, das aus einem hochfrequenten Nutzsignal und einem niederfrequenten \u201eRauschen\u201c besteht.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"783\" height=\"398\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-122055.png\" alt=\"Bild 14: Originaldaten und gegl\u00e4tteter Messwertverlauf\" class=\"wp-image-2412\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-122055.png 783w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-122055-300x152.png 300w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-122055-768x390.png 768w\" sizes=\"auto, (max-width: 783px) 100vw, 783px\" \/><figcaption class=\"wp-element-caption\">Bild 14: Originaldaten und gegl\u00e4tteter Messwertverlauf<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p>Anschlie\u00dfend wird ein Hochpassfilter angewendet, um das niederfrequente Rauschen zu entfernen. Die Funktionsweise basiert auf einem Filter, dessen Grenzfrequenz und Ordnung einstellbar sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>fs = 100.0 # Abtastrate (Hz)<\/li>\n\n\n\n<li>cutoff = 10.0 # Grenzfrequenz (50 Hz)<\/li>\n\n\n\n<li>order = 2 # Filterordnung<\/li>\n<\/ul>\n\n\n\n<p>Das gefilterte Signal wird anschlie\u00dfend zusammen mit den Rohdaten in einem Diagramm dargestellt, um die Wirksamkeit des Filters zu demonstrieren.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Signalkonditionierung<\/h2>\n\n\n\n<p>Signalkonditionierung bezeichnet die Verarbeitung und Anpassung von Signalen, um sie f\u00fcr die weitere Analyse, Messung oder Steuerung nutzbar zu machen. Dabei werden die rohen Ausgangssignale eines Sensors so ver\u00e4ndert, dass sie den Anforderungen des Messsystems entsprechen &#8211; zum Beispiel eines Raspberry Pi 5 oder eines Mikrocontrollers, wie dem Pi Pico.<br><br>Die Ziele der Signalkonditionierung sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Anpassung der Signalst\u00e4rke durch Verst\u00e4rken oder Abschw\u00e4chen des Signals<\/li>\n\n\n\n<li>Skalierung von Messwerten auf bestimme Wertebereiche<\/li>\n\n\n\n<li>Linearisierung zur Umwandlung eines nicht-linearen Signals in ein lineares Verh\u00e4ltnis<\/li>\n\n\n\n<li>Trennung des Signals, um St\u00f6rungen oder R\u00fcckkopplungen zu vermeiden (\u201eIsolierung\u201c)<\/li>\n\n\n\n<li>Anpassung des Signaltyps, z. B. von A\/D-Wandlerwerten zu realen Temperaturen oder Helligkeiten etc.<\/li>\n<\/ul>\n\n\n\n<p>H\u00e4ufig auftretende Anwendung sind z. B.:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bei einem Optosensor am Raspberry Pi kann die Signalkonditionierung notwendig sein, um das Lichtsignal in ein klares, digitales Signal umzuwandeln.<\/li>\n\n\n\n<li>In Audiosystemen wird die Signalkonditionierung genutzt, um St\u00f6rger\u00e4usche herauszufiltern und die Lautst\u00e4rke anzupassen.<\/li>\n\n\n\n<li>In industriellen Anwendungen werden Messsignale von Temperatur- oder Drucksensoren verst\u00e4rkt und gefiltert, bevor sie verarbeitet werden.<\/li>\n<\/ul>\n\n\n\n<p>Das folgende Programm f\u00fchrt eine Offset-Korrektur, Filterung, Zentrierung auf die Nulllinie, Verst\u00e4rkung und Normalisierung durch. Dabei werden lediglich \u201ematplotlib\u201c und \u201eNumPy\u201c als Bibliotheken verwendet.<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><code>import numpy as np\nimport matplotlib.pyplot as plt\n\n# 1. Simuliertes Sensorsignal (Sinuswelle + Rauschen)\nnp.random.seed(0) # F\u00fcr reproduzierbare Ergebnisse\ntime = np.linspace(0, 1, 500) # 1 Sekunde mit 500 Messpunkten\nsignal = 2 * np.sin(2 * np.pi * 5 * time) # Reines Sinussignal mit 5 Hz\nnoise = 0.5 * np.random.randn(500) # Zuf\u00e4lliges Rauschen\nraw_signal = signal + noise\n\n# 2. Offset zum urspr\u00fcnglichen Signal hinzuf\u00fcgen\noffset = 3.0 # Konstanter Offset\noffset_signal = raw_signal + offset\n\n# 3. Verst\u00e4rkung des Signals\ngain = 2.0\namplified_signal = offset_signal * gain\n\n# 4. Tiefpassfilterung (gleitender Mittelwert)\nwindow_size = 30\nfiltered_signal = np.convolve(amplified_signal, np.ones(window_size)\/window_size, mode='valid')\n\n# 5. Normalisierung des Signals (Skalierung zwischen 0 und 1)\nnormalized_signal = (filtered_signal - np.min(filtered_signal)) \/ (np.max(filtered_signal) - np.min(filtered_signal))\n\n# 6. Zentrierung auf die Nulllinie (Mittelwert abziehen)\ncentered_signal = normalized_signal - np.mean(normalized_signal)\n\n# 7. Weitere Verst\u00e4rkung des konditionierten Signals (20-fach)\nfinal_gain = 20.0\nprocessed_signal = centered_signal * final_gain\n\n# 8. Visualisierung\nplt.figure(figsize=(12, 6))\n# plt.plot(time, raw_signal, label=\"Rohsignal mit Rauschen\", alpha=0.5)\nplt.plot(time, offset_signal, color='red', alpha=0.7)\nplt.plot(time&#91;:len(processed_signal)], processed_signal, color='blue', linewidth=2)\nplt.xlabel('Zeit (s)')\nplt.ylabel('Signalst\u00e4rke')\nplt.title('Signalkonditionierung: Offset, Zentrierung, Verst\u00e4rkung und Normalisierung')\nplt.legend()\nplt.grid(True)\nplt.show()<\/code><\/pre>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-blue-color\">Bild 15<\/mark><strong> <\/strong>zeigt die Programmausgabe. Man erkennt, dass die Signalamplitude entsprechend der Verst\u00e4rkung zugenommen hat. Der Offset des Signals wurde entfernt, d. h. das konditionierte Signal (blau) ist nun symmetrisch zur Nulllinie. Zudem wurde das Signal auf Werte zwischen -10 und +10 normalisiert.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full is-style-bordered\"><img loading=\"lazy\" decoding=\"async\" width=\"722\" height=\"368\" src=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-122142.png\" alt=\"Bild 15: Signalkondi\u0002tionierung\" class=\"wp-image-2414\" srcset=\"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-122142.png 722w, https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Screenshot-2025-09-05-122142-300x153.png 300w\" sizes=\"auto, (max-width: 722px) 100vw, 722px\" \/><figcaption class=\"wp-element-caption\">Bild 15: Signalkonditionierung<\/figcaption><\/figure>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Zusammenfassung und Ausblick<\/h2>\n\n\n\n<p>In der modernen Mess- und Sensortechnik spielt Python eine zentrale Rolle, insbesondere in Verbindung mit Plattformen wie dem Raspberry Pi. Die Programmiersprache Python erm\u00f6glicht eine einfache Ansteuerung verschiedenster Sensoren, wie dem DS18x20 oder dem Feuchtigkeitssensor DHT11. Dank zahlreicher Bibliotheken k\u00f6nnen Daten effizient erfasst, verarbeitet und visualisiert werden. Typische Anwendungen umfassen Temperaturmessungen, Luftfeuchtigkeits\u00fcberwachung und die Analyse von Sensordaten in Echtzeit. Zudem wurde in diesem Artikel die Datenaufbereitung umfassend betrachtet. Dazu geh\u00f6ren die Mittelung von Messwerten, die Rauschreduzierung und die Anpassung der Daten an bestimmte Wertebereiche usw.<br><br>Alle Grafiken und Messwerte wurden dazu mithilfe der MatPlotLibrary angezeigt und dargestellt. Neben dieser Bibliothek existieren allerdings noch weitere Anwendungen, die interessante und vielseitige Grafikdarstellungen erlauben. Eine der wichtigsten Varianten hierzu ist tkinter, die Standard-GUI-Bibliothek (Graphical User Interface) f\u00fcr Python. Sie bietet einfache M\u00f6glichkeiten zur Erstellung von Desktop-Anwendungen. So k\u00f6nnen z. B. eigene Fenster f\u00fcr die Ausgabe von Messwerten oder selbst definierte \u201eDisplays\u201c aufgebaut werden. Tkinter ist dabei einfach zu erlernen und eignet sich auch f\u00fcr Anf\u00e4nger, die mit der GUI-Programmierung beginnen m\u00f6chten. Zudem erm\u00f6glicht tkinter die Verarbeitung von Ereignissen wie z. B. Mausklicks und Tastatureingaben, um auf Benutzerinteraktionen zu reagieren.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Erg\u00e4nzungen und Anregungen<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Kann man beide Sensoren (DS18x20 und DHT11) gemeinsam an einem Raspberry Pi betreiben?\n<ul class=\"wp-block-list\">\n<li>Wie m\u00fcsste das zugeh\u00f6rige Programm aussehen?<\/li>\n\n\n\n<li>Wie viele Sensoren w\u00e4ren maximal m\u00f6glich?<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Wie s\u00e4he ein Programm zur Signalkonditionierung f\u00fcr den DS18x20 aus, mit den folgenden Eigenschaften:\n<ul class=\"wp-block-list\">\n<li>Mittelung von jeweils 100 Messwerten<\/li>\n\n\n\n<li>Zentrierung der Temperatur auf 25 \u00b0C (Raumtemperatur)<\/li>\n\n\n\n<li>Rauschreduzierung auf \u00b10,2 \u00b0C<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Material<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Raspberry Pi mit Netzteil<\/li>\n\n\n\n<li>Breadboard und Jumper-Kabel<\/li>\n\n\n\n<li>DS18x20-Sensor<\/li>\n\n\n\n<li>DHT11-Sensor oder -Modul<\/li>\n<\/ul>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-gray-lightest-100-background-color has-background\" style=\"padding-top:var(--wp--preset--spacing--20);padding-right:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20);padding-left:var(--wp--preset--spacing--20)\"><strong>\u00dcber den Autor<br><\/strong>Dr. G\u00fcnter Spanner ist als Autor zu den Themen Elektronik, Sensortechnik und Mikrocontroller einem weiten Fachpublikum bekannt. Schwerpunkt seiner hauptberuflichen T\u00e4tigkeit f\u00fcr verschiedene Gro\u00dfkonzerne wie Siemens und ABB ist die Projektleitung im Bereich Entwicklung und Technologie-Management. Der Dozent fu\u0308r Physik und Elektrotechnik hat zudem zahlreiche Fachartikel und Bu\u0308cher vero\u0308ffentlicht sowie Kurse und Lernpakete erstellt.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sensoren smart auslesen: So bindet man DS18B20 (One-Wire) und DHT11 am Raspberry Pi an, liest Daten mit Python aus und gl\u00e4ttest Messwerte per Mittelung &#038; Filtern \u2013 inkl. Code, Plot und Praxis-Tipps f\u00fcr zuverl\u00e4ssige Messungen.<\/p>\n","protected":false},"author":5,"featured_media":864,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[34],"tags":[323,322,320,321,326,325,324,327],"post-author":[137],"class_list":["post-1964","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python-micropython","tag-dht11-raspberry-pi","tag-ds18b20-python","tag-gleitender-durchschnitt-python","tag-messwerterfassung-python","tag-one-wire-aktivieren","tag-raspberry-pi-sensoren","tag-sensor-daten-filtern","tag-signalverarbeitung-raspberry-pi","post-author-dr-guenter-spanner"],"acf":[],"info":{"thumbnail":{"url":"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/header_phyton_teil11.jpg","alt":""},"teaserImage":{"ID":2327,"id":2327,"title":"liste-beitrag_python_t11","filename":"Liste-Beitrag_python_t11-1.jpg","filesize":57435,"url":"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Liste-Beitrag_python_t11-1.jpg","link":"https:\/\/de.elv.com\/elvjournal\/python-raspberry-pi-sensoren-messwerterfassung\/liste-beitrag_python_t11-2\/","alt":"","author":"5","description":"","caption":"","name":"liste-beitrag_python_t11-2","status":"inherit","uploaded_to":1964,"date":"2025-09-04 12:43:10","modified":"2025-09-04 12:43:10","menu_order":0,"mime_type":"image\/jpeg","type":"image","subtype":"jpeg","icon":"https:\/\/elvjournal.elv.com\/wp-includes\/images\/media\/default.png","width":312,"height":198,"sizes":{"thumbnail":"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Liste-Beitrag_python_t11-1-250x198.jpg","thumbnail-width":250,"thumbnail-height":198,"medium":"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Liste-Beitrag_python_t11-1-300x190.jpg","medium-width":300,"medium-height":190,"medium_large":"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Liste-Beitrag_python_t11-1.jpg","medium_large-width":312,"medium_large-height":198,"large":"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Liste-Beitrag_python_t11-1.jpg","large-width":312,"large-height":198,"1536x1536":"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Liste-Beitrag_python_t11-1.jpg","1536x1536-width":312,"1536x1536-height":198,"2048x2048":"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Liste-Beitrag_python_t11-1.jpg","2048x2048-width":312,"2048x2048-height":198,"gform-image-choice-sm":"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Liste-Beitrag_python_t11-1.jpg","gform-image-choice-sm-width":300,"gform-image-choice-sm-height":190,"gform-image-choice-md":"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Liste-Beitrag_python_t11-1.jpg","gform-image-choice-md-width":312,"gform-image-choice-md-height":198,"gform-image-choice-lg":"https:\/\/elvjournal.elv.com\/wp-content\/uploads\/Liste-Beitrag_python_t11-1.jpg","gform-image-choice-lg-width":312,"gform-image-choice-lg-height":198}},"categories":[{"id":34,"name":"Python &amp; MicroPython","slug":"python-micropython"}],"authors":[{"id":137,"name":"Dr. G\u00fcnter Spanner","slug":"dr-guenter-spanner"}],"document":false,"epaper":"","date":"4. September 2025","excerpt":"Sensoren smart auslesen: So bindet man DS18B20 (One-Wire) und DHT11 am Raspberry Pi an, liest Daten mit Python aus und gl\u00e4ttest Messwerte per Mittelung & Filtern \u2013 inkl. Code, Plot und Praxis-Tipps f\u00fcr zuverl\u00e4ssige Messungen."},"_links":{"self":[{"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/posts\/1964","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/comments?post=1964"}],"version-history":[{"count":10,"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/posts\/1964\/revisions"}],"predecessor-version":[{"id":13301,"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/posts\/1964\/revisions\/13301"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/media\/864"}],"wp:attachment":[{"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/media?parent=1964"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/categories?post=1964"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/tags?post=1964"},{"taxonomy":"post-author","embeddable":true,"href":"https:\/\/de.elv.com\/elvjournal\/wp-json\/wp\/v2\/post-author?post=1964"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}