{"id":1243,"date":"2019-06-09T11:27:07","date_gmt":"2019-06-09T09:27:07","guid":{"rendered":"http:\/\/zirbitzkogel.at\/blog\/?p=1243"},"modified":"2020-08-12T22:29:18","modified_gmt":"2020-08-12T20:29:18","slug":"magic-mirror-automatisch-ein-und-ausschalten","status":"publish","type":"post","link":"http:\/\/zirbitzkogel.at\/blog\/2019\/06\/09\/magic-mirror-automatisch-ein-und-ausschalten\/","title":{"rendered":"Magic Mirror automatisch ein- und ausschalten mit dem Abstandssensor VL53L0X"},"content":{"rendered":"<p>F\u00fcr mein privates <a href=\"http:\/\/zirbitzkogel.at\/blog\/2019\/06\/09\/magic-mirror-fuer-ikeak-kallax-regal-selber-bauen\/\" target=\"_blank\" rel=\"noopener noreferrer\">MagicMirror-Projekt<\/a> m\u00f6chte ich, dass sich das Display nur dann einschaltet, wenn eine Person mindestens ein bis zwei Sekunden lang davor steht und sich n\u00e4her als 100 cm befindet. Um eine Person nur grob zu detektieren, w\u00fcrde ein <a href=\"https:\/\/de.wikipedia.org\/wiki\/Pyroelektrischer_Sensor\" target=\"_blank\" rel=\"noopener noreferrer\">Passive Infrared (PIR) Sensor<\/a> ausreichen. Wenn man aber die genaue Position bzw. den Abstand der Person zum Display ben\u00f6tigt, um z.B. Fehleinschaltungen zu vermeiden, ist ein PIR-Sensor fehl am Platz. Ein Ultraschall-Sensor zur Abstandsmessung w\u00e4re da schon besser geeignet. Ich wollte jedoch etwas anderes ausprobieren.<\/p>\n<p><span style=\"background-color: #ffff99;\"><strong>UPDATE am 15.12.2019:<\/strong>\u00a0Ich habe das Relais zum Ein- und Ausschalten des Bildschirms entfernt und verwende jetzt ein reine Software-L\u00f6sung (<a href=\"#update\" rel=\"noopener\">Details am Ende dieses Beitrags<\/a>).<\/span><\/p>\n<h1>Messprinzip von Time-of-Flight-Sensoren<\/h1>\n<p>Um die Anwesenheit und den Abstand der Person zum Display sehr genau zu bestimmen eignen sich sogenannte <strong>Time-of-Flight (ToF)<\/strong> Sensoren. Diese ToF-Sensoren senden mittels LED oder Laser einen kurzen (unsichtbaren Infrarot-) Lichtimpuls aus, der von einem Objekt vor dem Sensor reflektiert und wieder empfangen wird. Anhand der hochgenau gemessenen Flugzeit des Lichtimpulses l\u00e4sst sich die Entfernung des Objekts typischerweise mit einer Genauigkeit im Millimeter-Bereich bestimmen. Das Funktionsprinzip und der Zusammenhang zwischen Flugzeit und Abstand ist in der folgenden Abbildung erkl\u00e4rt.<\/p>\n<figure id=\"attachment_1281\" aria-describedby=\"caption-attachment-1281\" style=\"width: 2127px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0789.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1281\" src=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0789.jpg\" alt=\"Prinzip der Abstandsmessung\" width=\"2127\" height=\"1486\" srcset=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0789.jpg 2127w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0789-300x210.jpg 300w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0789-768x537.jpg 768w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0789-1024x715.jpg 1024w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0789-386x270.jpg 386w\" sizes=\"(max-width: 2127px) 100vw, 2127px\" \/><\/a><figcaption id=\"caption-attachment-1281\" class=\"wp-caption-text\">Prinzip der Abstandsmessung mittels Time-of-Flight-Sensor<\/figcaption><\/figure>\n<p>Meine erste Idee war, den ToF-Sensor f\u00fcr den Beobachter unsichtbar hinter dem Spiegel anzubringen, wie in der folgenden Abbildung skizziert. Theoretisch sollte dies mit einem leistungsstarken ToF-Sensor bei ausreichend d\u00fcnnem und nicht verunreinigten Glas prinzipiell funktionieren.<\/p>\n<figure id=\"attachment_1280\" aria-describedby=\"caption-attachment-1280\" style=\"width: 1374px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0788.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1280\" src=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0788.jpg\" alt=\"Prinzip der Personendetektion und Abstandsmessung\" width=\"1374\" height=\"1474\" srcset=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0788.jpg 1374w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0788-280x300.jpg 280w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0788-768x824.jpg 768w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0788-955x1024.jpg 955w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_0788-252x270.jpg 252w\" sizes=\"(max-width: 1374px) 100vw, 1374px\" \/><\/a><figcaption id=\"caption-attachment-1280\" class=\"wp-caption-text\">Prinzip der Personendetektion und Abstandsmessung mittels Time-of-Flight-Sensor<\/figcaption><\/figure>\n<p>Wie ich durch mehrere Versuche herausgefunden habe, funktioniert der von mir verwendetet ToF-Sensor bei Anbringung hinter dem Spiegel leider nicht zufriedenstellend. Zum einen werden durch die Spiegelfolie der gesendete und empfangene Lichtimpuls so stark ged\u00e4mpft, dass sie Sensitivit\u00e4t des Sensors zu gering ist und zum anderen wird der Lichtimpuls durch das Glas stark gestreut, was zu falschen Messergebnissen f\u00fchrt. Am Ende habe ich den Sensor deshalb an der Spiegelaussenseite angebracht. Dazu sp\u00e4ter mehr.<\/p>\n<h1>Anschluss des ToF-Sensors und Aktivierung des I2C-Busses<\/h1>\n<p>Ein kosteng\u00fcnstiger ToF-Sensor f\u00fcr Abstandsmessungen von ca. 50 bis 2000 Millimeter ist der <a href=\"https:\/\/www.st.com\/resource\/en\/datasheet\/vl53l0x.pdf\" class=\"mtli_attachment mtli_pdf\" target=\"_blank\" rel=\"noopener noreferrer\">VL53L0X von STMicroelectronics<\/a>. Der Sensor selbst ist nur 4.4 x 2.4 x 1.0 mm gro\u00df und verwendet eine Laser-Diode, die in dem f\u00fcr den Menschen unsichtbaren Infrarot-Bereich mit einer Wellenl\u00e4nge von 940 nm arbeitet. Der <em>Standard-Entfernungsmessbereich<\/em> geht von ca. 50 bis 1000 mm, die maximale messbare Entfernung unter optimalen Bedingungen im <em>Long Range Mode<\/em> betr\u00e4gt 2000 mm. F\u00fcr eigene Experimente empfiehlt es sich, einen auf ein Breadboard aufgel\u00f6teten Sensor zu kaufen, den es bereits ab ca. 10 Euro gibt.<\/p>\n<figure id=\"attachment_1283\" aria-describedby=\"caption-attachment-1283\" style=\"width: 1925px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_9737-1.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1283\" src=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_9737-1.jpg\" alt=\"Time-of-Flight-Sensor\" width=\"1925\" height=\"1926\" srcset=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_9737-1.jpg 1925w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_9737-1-150x150.jpg 150w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_9737-1-300x300.jpg 300w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_9737-1-768x768.jpg 768w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_9737-1-1024x1024.jpg 1024w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/IMG_9737-1-270x270.jpg 270w\" sizes=\"(max-width: 1925px) 100vw, 1925px\" \/><\/a><figcaption id=\"caption-attachment-1283\" class=\"wp-caption-text\">Der verwendete Time-of-Flight-Sensor VL53L0X<\/figcaption><\/figure>\n<p>Da die MagicMirror-Software bei mir auf einem <a href=\"https:\/\/de.wikipedia.org\/wiki\/Raspberry_Pi\" target=\"_blank\" rel=\"noopener noreferrer\">Raspberry Pi<\/a> l\u00e4uft liegt es nahe, dass ich auch den ToF-Sensor an den selben Raspberry Pi anschlie\u00dfe sowie auch ein Relais, mit dem sich das Display des MagicMirrors ein- und ausschalten l\u00e4sst. Der ToF-Sensor VL53L0X ist \u00fcber die <a href=\"https:\/\/de.wikipedia.org\/wiki\/I\u00b2C\" target=\"_blank\" rel=\"noopener noreferrer\">I2C-Schnittstelle<\/a> und das Relais \u00fcber einen <a href=\"https:\/\/de.wikipedia.org\/wiki\/Allzweckeingabe\/-ausgabe\" target=\"_blank\" rel=\"noopener noreferrer\">GPIO-Pin<\/a> angeschlossen. Die folgenden Abbildung zeigt den Schaltplan (anstelle des Displays ist ein Motor als Verbraucher dargestellt).<\/p>\n<figure id=\"attachment_1447\" aria-describedby=\"caption-attachment-1447\" style=\"width: 1924px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/MagicMirror_Steckplatine-1.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1447\" src=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/MagicMirror_Steckplatine-1.jpg\" alt=\"Abstandsmessung und Schalten eines Verbrauchers\" width=\"1924\" height=\"1311\" srcset=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/MagicMirror_Steckplatine-1.jpg 1924w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/MagicMirror_Steckplatine-1-300x204.jpg 300w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/MagicMirror_Steckplatine-1-768x523.jpg 768w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/MagicMirror_Steckplatine-1-1024x698.jpg 1024w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/MagicMirror_Steckplatine-1-396x270.jpg 396w\" sizes=\"(max-width: 1924px) 100vw, 1924px\" \/><\/a><figcaption id=\"caption-attachment-1447\" class=\"wp-caption-text\">Abstandsmessung mittels Time-of-Flight-Sensor VL53L0X und entfernungsabh\u00e4ngiges Schalten eines Verbrauchers<\/figcaption><\/figure>\n<p>Zu beachten ist im Schaltplan die Verwendung von 5 V und 3.3 V als Spannung. Die beiden Relais auf der Relais-Platine, von denen nur eines ben\u00f6tigt wird, sind mittels Optokoppler galvanisch vom Raspberry Pi getrennt. Auf der Ansteuerungs- bzw. GPIO-Seite werden die Optokoppler mit 3.3 V versorgt. Auf der Seite an der das ben\u00f6tigte Relais angeschlossen ist, werden jedoch 5 V f\u00fcr den st\u00f6rungsfreien Betrieb ben\u00f6tigt. Ein interaktives Pinout des Raspberry Pi mit allen Anschlussbelegungen gibt es <a href=\"https:\/\/de.pinout.xyz\/#\" target=\"_blank\" rel=\"noopener noreferrer\">hier<\/a>, nur f\u00fcr den Fall dass jemand noch andere Sensoren anschlie\u00dfen m\u00f6chte.<\/p>\n<p>Die folgende Abbildung zeigt die auf der R\u00fcckseite des Magic Mirrors angebrachten Hardwarekomponenten. Alle Details zum Bau des Magic Mirrors und zur Konfiguration der MagicMirror<sup>2<\/sup>-Software k\u00f6nnen in meinem <a href=\"http:\/\/zirbitzkogel.at\/blog\/2019\/06\/09\/magic-mirror-fuer-ikeak-kallax-regal-selber-bauen\/\" target=\"_blank\" rel=\"noopener noreferrer\">MagicMirror-Beitrag<\/a> nachgelesen werden.<\/p>\n<figure id=\"attachment_1451\" aria-describedby=\"caption-attachment-1451\" style=\"width: 1932px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/IMG_0809.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1451\" src=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/IMG_0809.jpg\" alt=\"R\u00fcckansicht der MagicMirror-Hardware\" width=\"1932\" height=\"1505\" srcset=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/IMG_0809.jpg 1932w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/IMG_0809-300x234.jpg 300w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/IMG_0809-768x598.jpg 768w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/IMG_0809-1024x798.jpg 1024w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/IMG_0809-347x270.jpg 347w\" sizes=\"(max-width: 1932px) 100vw, 1932px\" \/><\/a><figcaption id=\"caption-attachment-1451\" class=\"wp-caption-text\">R\u00fcckansicht der verbauten MagicMirror-Hardware-Komponenten. Die Platinen wurden unter anderem mit doppelseitigem Klebeband mit Schaumstoffszwischenlage befestigt.<\/figcaption><\/figure>\n<p>Den Time-of-Flight-Sensor habe ich, zugegebenerma\u00dfen leider etwas unsch\u00f6n, an der Vorderseite des Spiegels angebracht. Wenigstens ist er relativ klein, so dass er nicht sofort ins Auge sticht. Um dennoch einen besseren <a href=\"https:\/\/de.wikipedia.org\/wiki\/Woman_acceptance_factor\" target=\"_blank\" rel=\"noopener noreferrer\">WAF<\/a> zu erzielen, sollte ich mir aber noch eine bessere L\u00f6sung \u00fcberlegen.<\/p>\n<figure id=\"attachment_1469\" aria-describedby=\"caption-attachment-1469\" style=\"width: 1962px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/magicmirror_02.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1469\" src=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/magicmirror_02.jpg\" alt=\"Magic Mirror mit Time-of-Flight-Sensor\" width=\"1962\" height=\"1889\" srcset=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/magicmirror_02.jpg 1962w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/magicmirror_02-300x289.jpg 300w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/magicmirror_02-768x739.jpg 768w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/magicmirror_02-1024x986.jpg 1024w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/06\/magicmirror_02-280x270.jpg 280w\" sizes=\"(max-width: 1962px) 100vw, 1962px\" \/><\/a><figcaption id=\"caption-attachment-1469\" class=\"wp-caption-text\">Eingeschaltetes MagicMirror-Display. Unten am Glas ist der kleine Time-of-Flight-Sensor angebracht.<\/figcaption><\/figure>\n<p>Um den Sensor mittels I2C anzusteuern, muss zuerst sichergestellt werden, dass am Raspberry Pi die entsprechenden Tools bzw. Treiber installiert sind. Dies l\u00e4sst sich durch die folgenden Bash-Kommandos bewerkstelligen:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo apt-get update\r\nsudo apt-get install -y python-smbus\r\nsudo apt-get install -y i2c-tools<\/pre>\n<p>Anschlie\u00dfend muss noch der <a href=\"https:\/\/learn.adafruit.com\/adafruits-raspberry-pi-lesson-4-gpio-setup\/configuring-i2c\" target=\"_blank\" rel=\"noopener noreferrer\">I2C-Bus am Raspberry Pi aktiviert<\/a> werden. Dazu \u00f6ffent man das Konfigurations-Fenster mittels folgendem Befehl:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo raspi-config<\/pre>\n<p>Man w\u00e4hlt zuerst den Men\u00fcpunkt <em>Interfacing Options<\/em> und danach <em>I2C<\/em>. Anschlie\u00dfend best\u00e4tigt man zweimal mit <em>Yes<\/em> um den I2C Bus zu aktivieren und automatisch zu laden. Danach sollte der Raspberry Pi neu gestartet werden:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo reboot<\/pre>\n<p>Um zu \u00dcberpr\u00fcfen ob der I2C-Bus tats\u00e4chlich funktioniert und der angeschlossene VL53L0X-Sensor gefunden wird, gibt man folgendes Kommando ein:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo i2cdetect -y 1<\/pre>\n<p>Bei erfolgreicher Detektion des VL53L0X-Sensors, der standardm\u00e4\u00dfig die I2C-Adresse <strong>0x29<\/strong> besitzt, sollte man die folgende Bash-Ausgabe erhalten:<\/p>\n<figure id=\"attachment_1369\" aria-describedby=\"caption-attachment-1369\" style=\"width: 418px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/Screenshot_I2C_Detect.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1369\" src=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/Screenshot_I2C_Detect.jpg\" alt=\"Bash-Ausgabe i2cdetect -y 1\" width=\"418\" height=\"169\" srcset=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/Screenshot_I2C_Detect.jpg 418w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/Screenshot_I2C_Detect-300x121.jpg 300w\" sizes=\"(max-width: 418px) 100vw, 418px\" \/><\/a><figcaption id=\"caption-attachment-1369\" class=\"wp-caption-text\">Bash-Ausgabe nach der Eingabe des Befehls <em>sudo i2cdetect -y 1<\/em><\/figcaption><\/figure>\n<h1>Ansteuerung und Test mittels Python<\/h1>\n<p>Um den Sensor anschlie\u00dfend mittels Python anzusprechen, ben\u00f6tigt man eine geeignet Bibliothek. Wenn man nach <em>python VL53L0X<\/em> googelt wird man schnell f\u00fcndig. Ich habe mich f\u00fcr die <a href=\"https:\/\/github.com\/pimoroni\/VL53L0X-python\" target=\"_blank\" rel=\"noopener noreferrer\">Bibliothek von <em>pimoroni<\/em><\/a> entschieden, die auf GitHub verf\u00fcgbar ist. Um sie zu installieren, gibt man in der Shell den folgenden Befehl ein:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo pip2 install git+https:\/\/github.com\/pimoroni\/VL53L0X_rasp_python.git\r\n<\/pre>\n<p>Wenn man auf seinem Raspberry Pi anstatt dem standardm\u00e4\u00dfigen Python 2.x bereits Python 3.x installiert hat, so tauscht man im obigen Kommando einfach <em>pip2<\/em> mit <em>pip3<\/em> aus. Die installierte Python-Version l\u00e4sst sich mit diesem Befehl abfragen:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">python --version<\/pre>\n<p>Zum Testen des Sensors mittels Python eignet sich der folgende Code:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import time\r\nimport VL53L0X\r\n\r\n# --- Initialisierungen ---\r\n\r\n# Erzeugen eines VL53L0X-Objekts\r\ntofSensor = VL53L0X.VL53L0X()  \r\ntofSensor.open()                 \r\n\r\n# Sensor zur Entfernungsmessung vorbereiten\r\ntofSensor.start_ranging(VL53L0X.Vl53l0xAccuracyMode.BETTER)\r\n\r\n# --- Durchf\u00fchren von 60 Messungen im Sekundenintervall ---\r\nfor count in range(1, 61):\r\n    distance = tofSensor.get_distance()  # Messen der Entfernung\r\n    if distance &gt; 0.0 and distance &lt; 2000.0:\r\n        print(\"Messung %d: Gemessene Entfernung: %d mm\" % (count,distance))\r\n    else:\r\n        print(\"Messung %d: Entfernung nicht messbar =&gt; kein Objekt vor dem Sensor\" % (count))    \r\n    \r\n    time.sleep(1.0)                      # 1 Sekunde warten\r\n\r\ntofSensor.stop_ranging()                 # Sensor deaktivieren\r\ntofSensor.close()\r\n<\/pre>\n<p>Ich habe dieses Script als <strong><em>test_tof_sensor.py<\/em><\/strong> gespeichert. Dazu erstellt man mittels<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">nano test_tof_sensor.py<\/pre>\n<p>eine neue Datei, kopiert den obigen Python-Code hinein und speichert die \u00c4nderungen.<\/p>\n<p>Um das Python-Script letztendlich ausf\u00fchrbar zu machen, m\u00fcssen noch die Rechte entsprechend gesetzt werden:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo chmod +x test_tof_sensor.py<\/pre>\n<p>Das Python-Script wird dann wie folgt gestartet:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">python test_tof_sensor.py<\/pre>\n<p>Die folgenden Abbildung zeigt eine typische Ausgabe. Jede Sekunde wird ein neuer Entfernungsmesswert ausgegeben.<\/p>\n<figure id=\"attachment_1370\" aria-describedby=\"caption-attachment-1370\" style=\"width: 586px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/Screenshot_Testmessung.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-1370\" src=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/Screenshot_Testmessung.jpg\" alt=\"Ergebnisse der ersten Testmessung\" width=\"586\" height=\"556\" srcset=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/Screenshot_Testmessung.jpg 586w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/Screenshot_Testmessung-300x285.jpg 300w, http:\/\/zirbitzkogel.at\/blog\/wp-content\/uploads\/2019\/05\/Screenshot_Testmessung-285x270.jpg 285w\" sizes=\"(max-width: 586px) 100vw, 586px\" \/><\/a><figcaption id=\"caption-attachment-1370\" class=\"wp-caption-text\">Ergebnisse der Testmessung, bei der der Abstand eines Objekts kontinuierlich von ca. 20 bis 80 cm vergr\u00f6\u00dfert wurde.<\/figcaption><\/figure>\n<h1>Automatisches Ein- und Ausschalten des Displays<\/h1>\n<p>Um das Display des Magic Mirrors automatisch ein- und auszuschalten, wird noch ein Relais ben\u00f6tigt, das mittels GPIO-Pin 22 angesteuert wird (siehe Schaltplan weiter oben) und die Stromversorgung des Displays schaltet.<\/p>\n<p>Meine pers\u00f6nlichen Anforderungen an das automatische Ein- und Ausschalten des Displays sind:<\/p>\n<ul>\n<li>Um das Display einzuschalten, muss eine Person mindestens 1 bis 2 Sekunden lang in einem Abstand kleiner gleich 100 cm vor dem Display stehen.<\/li>\n<li>So lange sich die Person vor dem Display befindet, soll es eingeschaltet bleiben.<\/li>\n<li>Wenn keine Person mehr vor dem Display ist, soll es sich nach 60 Sekunden ausschalten.<\/li>\n<\/ul>\n<p>Dazu habe ich das folgenden Python-Script mit dem Dateinamen <strong><em>mm_display_switch.py<\/em><\/strong> erstellt:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># coding: utf8\r\n\r\nimport time\r\nimport RPi.GPIO as GPIO         # Importieren der GPIO-Bibliothek\r\nimport VL53L0X                  # Importieren der ToF-Sensor-Bibliothek\r\n\r\n\r\n# -----------------------------------------------------------------------------\r\n# Initialisierungen\r\n# -----------------------------------------------------------------------------\r\n\r\n# --- GPIOs initialisieren ----------------------------------------------------\r\nRelais = 22                     # Relais wird mit GPIO-Pin 22 angesteuert\r\nGPIO.cleanup()\r\nGPIO.setmode(GPIO.BCM)          # GPIOs \u00fcber GPIO-Nummern ansprechen\r\nGPIO.setwarnings(False)         # GPIO-Warnungen werden nicht ausgegeben\r\nGPIO.setup(Relais, GPIO.OUT, initial=GPIO.HIGH)  # GPIO22 als Ausgang verwenden\r\n\r\n# --- ToF-Sensor initialisieren -----------------------------------------------\r\ntofSensor = VL53L0X.VL53L0X()  \r\ntofSensor.open()                 \r\ntofSensor.start_ranging(VL53L0X.Vl53l0xAccuracyMode.LONG_RANGE)\r\n\r\n# --- Variablern initialisieren -----------------------------------------------\r\npersonDetect = 0                # noch keine Person detektiert\r\ndistanceThreshold = 1000.0      # Abstandsschwellwert in [mm]\r\nscreenOnTime = 60.0             # Zeit in [s], wie lange das Display mindestens\r\n                                # eingeschaltet bleiben soll\r\nmeasurementInterval = 1.0       # Messintervall in [s]    \r\nGPIO.output(Relais, GPIO.HIGH)  # Relais\/Bildschirm wird ausgeschaltet\r\n                                # (Relais ist Active LOW, daher schaltet HIGH\r\n                                # den Bildschirm aus und LOW ein)\r\n\r\n\r\n# -----------------------------------------------------------------------------\r\n# Eigentliches Programm in Endlosschleife\r\n# -----------------------------------------------------------------------------\r\n\r\nwhile True:\r\n    \r\n    # Messen der Entfernung bzw. des Abstands in [mm]\r\n    distance = tofSensor.get_distance()\r\n    print('Gemessene Entfernung: '+str(distance)+' mm')\r\n    #print('Anzahl der Detektionen: '+str(personDetect))\r\n    \r\n    if distance &lt;= 0.0:\r\n        distance = distanceThreshold+1.0\r\n    \r\n    if distance &lt;= distanceThreshold: personDetect = personDetect+1 #print('Eine Person wurde detektiert!') else: #print('Bildschirm wird ausgeschalten.') personDetect = 0 GPIO.output(Relais, GPIO.HIGH) # Bildschirm ausschalten if personDetect &gt;= 2:\r\n        #print('Bildschirm wird eingeschalten.')\r\n        GPIO.output(Relais, GPIO.LOW)   # Bildschirm einschalten\r\n        print('Nun wird 60 s lang gewartet')\r\n        time.sleep(screenOnTime)        # 60 Sekunden lang warten\r\n    \r\n    time.sleep(measurementInterval)     # 1 Sekunde bis zur n\u00e4chsten Messung\r\n                                        # warten\r\n<\/pre>\n<p>Diese Python-Datei muss nat\u00fcrlich wieder ausf\u00fchrbar gemacht werden:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo chmod +x mm_display_switch.py<\/pre>\n<p>Eine weitere Anforderung ist, dass das Python-Script nach dem Booten oder Rebooten des Raspberry Pi automatisch ausgef\u00fchrt wird. Dazu muss man einen entsprechenden Eintrag in der Datei <em>rc.local<\/em> machen:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo nano \/etc\/rc.local<\/pre>\n<p>In der Datei erg\u00e4nzt man die folgende Zeile vor dem bereits vorhandenen <strong><em>exit 0<\/em><\/strong> :<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">python \/home\/pi\/Scripts\/mm_display_switch.py &amp;<\/pre>\n<p>Gegebenenfalls muss man das Verzeichnis anpassen, wenn sich das auszuf\u00fchrende Python-Script nicht in <em>\/home\/pi\/Scripts\/<\/em> befindet. Das <strong>&amp;<\/strong> ist wichtig damit die Datei <em>rc.local<\/em> weiter abgearbeitet wird und nicht auf das Beenden des Python-Scripts wartet. Besitzt das Python-Script n\u00e4mlich eine Endlosschleife, wie dies in <em>mm_display_switch.py<\/em> der Fall ist, w\u00fcrde ewig gewartet werden und der Raspberry Pi beim Start h\u00e4ngenbleiben.<\/p>\n<h1>Zus\u00e4tzliche Konfigurationen<\/h1>\n<p>Damit der Raspberry Pi beim Booten bei ausgeschalteten Display nicht automatisch die kleinste Aufl\u00f6sung einstellt, sollte diese auf einen festen Wert eingestellt werden. F\u00fcr das verwendete Full-HD-Display ist die native und optimale Aufl\u00f6sung 1920&#215;1080 Pixel. Um diese Einstellung durchzuf\u00fchren \u00f6ffnet man das Konfigurationstool mit dem Befehl<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo raspi-config<\/pre>\n<p>Unter dem Men\u00fcpunkt <em>Advanced Options<\/em> \u2192 <em>Resolution<\/em> kann nun die Aufl\u00f6sung entsprechend eingestellt werden. Dies funktioniert auch, wenn man mittels <strong>ssh<\/strong> eingeloggt ist.<\/p>\n<p>Auch die Leuchtdioden (LEDs) des Raspberry Pi k\u00f6nnen gro\u00dfteils deaktiviert werden, zum einen, um etwas Strom zu sparen (minimaler Effekt) und zum anderen, um ein unter Umst\u00e4nden st\u00f6rendes Durchscheinen der LEDs durch den Spiegel zu vermeiden. Dazu \u00f6ffnet man mittels<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">sudo nano \/boot\/config.txt<\/pre>\n<p>die Konfigurationsdatei und f\u00fcgt die folgenden Zeilen Code am Ende ein:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\"># Disable Ethernet LEDs\r\ndtparam=eth_led0=14\r\ndtparam=eth_led1=14\r\n\r\n# Disable the PWR LED\r\ndtparam=pwr_led_trigger=none\r\ndtparam=pwr_led_activelow=off\r\n\r\n# Disable the Activity LED\r\ndtparam=act_led_trigger=none\r\ndtparam=act_led_activelow=off\r\n<\/pre>\n<p>Die nichtdeaktivierbaren LEDs kann man bei Bedarf mit schwarzem Isolierband abkleben.<\/p>\n<h1>Zusammenfassung<\/h1>\n<p>Die MagicMirror<sup>2<\/sup>-Software und das selbsterstellte Python-Script f\u00fcr den ToF-Sensor laufen stabil. Das automatische entfernungsabh\u00e4ngige Ein- und Ausschalten des Displays mit Hilfe des ToF-Sensors und der Relais-Platine funktioniert sehr gut. Speziell bei viel Umgebungs-Sonnenlicht und dunkler Kleidung (= geringere Reflexion des Infrarot-Lichtimpulses) kann die Reichweite des Sensors etwas eingeschr\u00e4nkt sein. Unter diesen Bedingungen muss man dann schon mal etwas n\u00e4her als 100 cm vor dem Spiegel stehen oder die Hand vor den Sensor halten, damit sich das Display einschaltet. Das st\u00f6rt aber nicht weiter.<\/p>\n<p>Im Video seht ihr, wie sich das Display bei Ann\u00e4herung automatisch einschaltet.<\/p>\n<div  id=\"_ytid_37119\" class=\"__youtube_prefs__  __youtube_prefs_gdpr__ \" allowfullscreen data-no-lazy=\"1\" data-skipgform_ajax_framebjll=\"\"><p><strong>Bitte akzeptieren Sie Cookies von YouTube, um dieses Video abzuspielen.<\/strong> Wenn Sie akzeptieren, greifen Sie auf Inhalte von YouTube zu, einem Dienst, der von einem externen Dritten bereitgestellt wird.<\/p>\n<p><a href=\"https:\/\/policies.google.com\/privacy\" target=\"_blank\" rel=\"noopener\">Datenschutzerkl\u00e4rung und Nutzungsbedingungen von YouTube<\/a><\/p>\n<p>Wenn Sie diesen Hinweis akzeptieren, wird ihre Wahl gespeichert und die Seite wird aktualisiert.<\/p>\n<button type=\"button\" class=\"__youtube_prefs_gdpr__\">YouTube-Inhalte akzeptieren<img src=\"http:\/\/zirbitzkogel.at\/blog\/wp-content\/plugins\/youtube-embed-plus\/images\/icon-check.png\" alt=\"accept\" data-no-lazy=\"1\" data-skipgform_ajax_framebjll=\"\" \/><\/button><\/div>\n<h1 id=\"update\">Update am 15.12.2019<\/h1>\n<p>Da das Relais w\u00e4hrend der letzten Wochen immer wieder Problem verursachte und nicht wie gew\u00fcnscht schaltete, habe ich es entfernt. Eigentlich wollte ich stattdessen einen elektronischen Schalter mittels MOSFET realisieren. Das Problem hierbei ist jedoch, dass man einen sogenannten\u00a0<em>High Side Switch\u00a0<\/em>ben\u00f6tigt. Die verbreiteten\u00a0<em>Low Side Switches,\u00a0<\/em>wie z.B. der\u00a0<a href=\"https:\/\/www.sparkfun.com\/products\/12959\" target=\"_blank\" rel=\"noopener noreferrer\">SparkFun MOSFET Power Control Kit<\/a>\u00a0sind, wie sich im praktischen Versuch herausgestellt hat, leider nicht geeignet. Der Grund ist, das die HDMI-Verbindung zwischen Raspberry Pi und Bildschirm eine gemeinsame Masse (GND) hat und ein\u00a0<em>Low Side Switch<\/em> somit \u00fcberbr\u00fcckt wird.<\/p>\n<p>Letztendlich schalte ich nun direkt \u00fcber Bash-Befehle den Bildschirm ein oder in den Standby-Modus. Eine direkte Trennung von der Versorgungspannug erfolgt so zwar nicht, jedoch funktioniert diese L\u00f6sung problemlos und st\u00f6rungsfrei. Der h\u00f6here Standby-Stromverbrauch sollte sich in Grenzen halten.<\/p>\n<p>Hier das aktualisierte Skript <strong><em>mm_display_switch.py<\/em><\/strong>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># coding: utf8\r\n\r\nimport time\r\nimport VL53L0X                  # Importieren der ToF-Sensor-Bibliothek\r\nimport os                       # Importieren der System-Schnittstelle\r\n\r\n\r\n# -----------------------------------------------------------------------------\r\n# Initialisierungen\r\n# -----------------------------------------------------------------------------\r\n\r\n# --- ToF-Sensor initialisieren -----------------------------------------------\r\ntofSensor = VL53L0X.VL53L0X()  \r\ntofSensor.open()                 \r\ntofSensor.start_ranging(VL53L0X.Vl53l0xAccuracyMode.LONG_RANGE)\r\n\r\n\r\n# --- Funtionen zum Einschalten des Bildschirms via HDMI ----------------------\r\ndef bildschirm_ein():\r\n    os.popen('vcgencmd display_power 1')\r\n\r\n# --- Funtionen zum Ausschalten des Bildschirms via HDMI ----------------------\r\ndef bildschirm_aus(): \r\n    os.popen('vcgencmd display_power 0')\r\n    \r\n\r\n# --- Variablern initialisieren -----------------------------------------------\r\npersonDetect = 0                # noch keine Person detektiert\r\ndistanceThreshold = 1000.0      # Abstandsschwellwert in [mm]\r\nscreenOnTime = 60.0             # Zeit in [s], wie lange das Display mindestens\r\n                                # eingeschaltet bleiben soll\r\nmeasurementInterval = 1.0       # Messintervall in [s]    \r\nbildschirm_aus()                # Relais\/Bildschirm wird ausgeschaltet\r\n\r\n\r\n# -----------------------------------------------------------------------------\r\n# Eigentliches Programm in Endlosschleife\r\n# -----------------------------------------------------------------------------\r\n\r\nwhile True:\r\n    \r\n    # Messen der Entfernung bzw. des Abstands in [mm]\r\n    distance = tofSensor.get_distance()\r\n    \r\n    if distance &lt;= 0.0:\r\n        distance = distanceThreshold+1.0\r\n    \r\n    if distance &lt;= distanceThreshold:    \r\n        personDetect = personDetect+1\r\n    else:                                \r\n        personDetect = 0\r\n        bildschirm_aus()                # Bildschirm ausschalten\r\n        \r\n    if personDetect &gt;= 2:\r\n        bildschirm_ein()                # Bildschirm einschalten\r\n        time.sleep(screenOnTime)        # 60 Sekunden lang warten\r\n    \r\n    time.sleep(measurementInterval)     # 1 Sekunde bis zur n\u00e4chsten Messung\r\n                                        # warten\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>F\u00fcr mein privates MagicMirror-Projekt m\u00f6chte ich, dass sich das Display nur dann einschaltet, wenn eine Person mindestens ein bis zwei Sekunden lang davor steht und sich n\u00e4her als 100 cm befindet. Um eine Person nur grob zu detektieren, w\u00fcrde ein Passive Infrared (PIR) Sensor ausreichen. Wenn man aber die genaue Position bzw. den Abstand der Person zum Display ben\u00f6tigt, um z.B. Fehleinschaltungen zu vermeiden, ist ein PIR-Sensor fehl am Platz. Ein Ultraschall-Sensor zur Abstandsmessung w\u00e4re da schon besser geeignet. Ich&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"http:\/\/zirbitzkogel.at\/blog\/2019\/06\/09\/magic-mirror-automatisch-ein-und-ausschalten\/\">Weiterlesen<span class=\"screen-reader-text\"> Weiterlesen<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":1447,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[110],"tags":[111,114,112,113,120,115],"_links":{"self":[{"href":"http:\/\/zirbitzkogel.at\/blog\/wp-json\/wp\/v2\/posts\/1243"}],"collection":[{"href":"http:\/\/zirbitzkogel.at\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/zirbitzkogel.at\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/zirbitzkogel.at\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/zirbitzkogel.at\/blog\/wp-json\/wp\/v2\/comments?post=1243"}],"version-history":[{"count":158,"href":"http:\/\/zirbitzkogel.at\/blog\/wp-json\/wp\/v2\/posts\/1243\/revisions"}],"predecessor-version":[{"id":2054,"href":"http:\/\/zirbitzkogel.at\/blog\/wp-json\/wp\/v2\/posts\/1243\/revisions\/2054"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/zirbitzkogel.at\/blog\/wp-json\/wp\/v2\/media\/1447"}],"wp:attachment":[{"href":"http:\/\/zirbitzkogel.at\/blog\/wp-json\/wp\/v2\/media?parent=1243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/zirbitzkogel.at\/blog\/wp-json\/wp\/v2\/categories?post=1243"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/zirbitzkogel.at\/blog\/wp-json\/wp\/v2\/tags?post=1243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}