Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Über mich
  • Deutsch
  • English
Menu

Raspberry Pi Pico W – Zeit aus dem Internet lesen und auf einem Display anzeigen

Posted on 27. Juli 20224. März 2025 by Stefan Draeger

Wie man die Zeit von Time Server aus dem Internet lädt und mit dem neuen Raspberry Pi Pico W auf einem LCD-Display per I²C anzeigen lassen kann, möchte ich dir in diesem ausführlichen Beitrag zeigen.

Den neuen Raspberry Pi Pico W mit WiFi Support habe ich dir bereits in folgenden Beiträgen vorgestellt und einige kleine Projekte gezeigt.

  • Raspberry Pi Pico W mit Wi-Fi Support
  • Raspberry Pi Pico W – Webserver programmieren
  • Raspberry Pi Pico W mit Infineon CYW43438 Chip
  • Raspberry Pi Pico W – anzeigen von Sensordaten auf einer Webseite
  • Raspberry Pi Pico W – Webseite ins Internet veröffentlichen

  • Benötigte Ressourcen für dieses Projekt
  • Aufbau der Schaltung, Raspberry Pi Pico W mit LCD-Display
  • Pinout des Raspberry Pi Pico (W)
    • Erweiterungsplatine für den Raspberry Pi Pico
  • I²C Adapter für LCD-Display
  • Programmieren des LCD-Displays in der Thonny IDE mit MicroPython
    • Download & kopieren des Modules für das LCD-Display
    • Troubleshooting
      • OSError 28
      • ValueError: bad SCL pin / bad SDA pin
    • Quellcode – „Hello World!“ auf dem LCD-Display
    • Auslesen einer Zeit vom Server
  • Fertiges Programm – leser der Zeit aus dem Internet und anzeigen mit einem Raspberry Pi Pico W

Benötigte Ressourcen für dieses Projekt

Für dieses Projekt benötigst du, bzw. habe ich verwendet:

  • einen Raspberry Pi Pico W*,
    • ein Micro-USB Datenkabel*,
  • ein 2×16 Zeichen LCD-Display* mit I²C Schnittstelle,
  • diverse Breadboardkabel*

Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!

Aufbau der Schaltung, Raspberry Pi Pico W mit LCD-Display

In diesem Beitrag verwende ich ein einfaches 2×16 Zeichen LCD-Display mit I²C Schnittstelle. Es gibt jedoch auch größere Displays mit mehr Zeilen & Zeichen, wo du dann auch mehr Informationen anzeigen lassen kannst.

Raspberry Pi Pico mit LCD-Display via I²C
Raspberry Pi Pico mit LCD-Display via I²C

Der Raspberry Pi Pico W hat 2 I²C Schnittstellen, welche du über die nachfolgenden Pins erreichen kannst:

  • I²C 0
    • SDA – GP0, GP8, GP12, GP16, GP20
    • SCL – GP1, GP9, GP13, GP17, GP21
  • I²C 1
    • SDA – GP2, GP6, GP10, GP14, GP18, GP26
    • SCL – GP3, GP7, GP11, GP15, GP19, GP27
Auf der Schaltung - Raspberry Pi Pico W mit 2x20 Zeichen LCD-Display
Auf der Schaltung – Raspberry Pi Pico W mit 2×20 Zeichen LCD-Display

Pinout des Raspberry Pi Pico (W)

Der neue Raspberry Pi Pico W ist mit dem Vorgängermodell von den Pins identisch, d.h. du kannst deine bestehenden Projekte recht einfach um die WiFi Fähigkeit erweitern.

Pinout des Raspberry PI Pico
Pinout des Raspberry PI Pico

Erweiterungsplatine für den Raspberry Pi Pico

Für das Vorgängermodell dem Raspberry Pi Pico von 2021 habe ich ein kleines Board entwickelt welches mit die I²C Pins sowie ein paar GPIOs auf Groove Konnektoren bereitstellt.

Raspberry Pi Pico W auf DIY Expansionboard
Raspberry Pi Pico W auf DIY Expansionboard

I²C Adapter für LCD-Display

Das verwendete LCD-Display hat einen kleinen I²C Adapter auf der Rückseite verbaut. Dieser Adapter verfügt über die Pins SDA, SCL, VCC und GND sowie über einen Drehpotentiometer (blaues Bauteil im Bild) über welchen die Helligkeit der Schrift gesteuert werden kann.

I²C Adapter für das LCD-Display
I²C Adapter für das LCD-Display

Programmieren des LCD-Displays in der Thonny IDE mit MicroPython

Für die Programmierung nutze ich die Thonny IDE welche kostenfrei unter https://thonny.org/ für Microsoft Windows, macOS & auch Linux heruntergeladen werden kann.

Download & kopieren des Modules für das LCD-Display

Für die Programmierung des LCD-Displays verwende ich ein Modul, welches vom GitHub Repository dhylands/python_lcd geladen werden kann.

Von diesem Repository benötigen wir jedoch nur die beiden Dateien:

  • https://github.com/dhylands/python_lcd/blob/master/lcd/lcd_api.py
  • https://github.com/dhylands/python_lcd/blob/master/lcd/machine_i2c_lcd.py

Diese beiden Dateien müssen wir auf dem Pi Pico im Ordner „lib“ speichern. Da wir jedoch keinen direkten Zugriff auf diesem Ordner haben, müssen wir die beiden Dateien in einem Editor öffnen (zbsp. Notepad++). Im geöffneten Editor markieren und kopieren, wir den gesamten Text in einem geöffneten Tab in der Thonny IDE und speichern dieses in den Ordner „lib“ unter den jeweiligen Dateinamen.

Troubleshooting

Beim Programmieren sind mir einige Fehlermeldungen ausgegeben worden, welche ich dir hier gerne zeigen möchte.

OSError 28

Diesen Fehler erhältst du, wenn der Speicher des Mikrocontrollers aufgebraucht ist. D.h. du musst Speicher freigeben, um diesen Fehler zu beheben.

Dieses können zbsp. nicht benötigte Bibliotheken sein, welche auf dem Mikrocontroller abgelegt wurden.

ValueError: bad SCL pin / bad SDA pin

Die konfigurierte I²C Verbindung ist nicht lesbar. Hier musst du deine Verkabelung und die verwendete Adresse prüfen.

Quellcode – „Hello World!“ auf dem LCD-Display

Schreiben wir zunächst in jede Zeile des Displays ein paar Zeichen.

from time import sleep
from machine import I2C, Pin
from machine_i2c_lcd import I2cLcd

i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=100000)
lcd = I2cLcd(i2c, 0x27, 2, 16)

zeile1  = 'Hello World!';
zeile2 = 'from Pi Pico W'

lcd.putstr(zeile1 + "\n" + zeile2)
sleep(2)
Auf der Schaltung - Raspberry Pi Pico W mit 2x20 Zeichen LCD-Display
Auf der Schaltung – Raspberry Pi Pico W mit 2×20 Zeichen LCD-Display

Auslesen einer Zeit vom Server

Als Dienst nutze ich den Server http://worldtimeapi.org welchen wir in der URL die Zeitzone übergeben wie zbsp. http://worldtimeapi.org/api/timezone/Europe/Berlin und als Antwort ein JSON mit den Daten erhalten.

Damit wir diesen HTTP Request absenden und einen Response vom Server empfangen können, müssen wir uns zu einem bestehenden WLAN Netzwerk verbunden haben. Wie du das machst, habe ich dir bereits im Beitrag Raspberry Pi Pico W – Webserver programmieren gezeigt.

Hier der Vollständigkeit der Code zum Herstellen einer Verbindung zu einem WLAN Netzwerk.

import network
import time
ssid = '*****'
password = '*******'
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
print("Waiting to connect:")
while not wlan.isconnected() and wlan.status() >= 0:
    print(".", end="")   
    time.sleep(1)
print("")
print(wlan.ifconfig())

Wenn diese Verbindung aufgebaut ist, dann müssen wir einen Request an die oben genannte Adresse senden und den Response (ein JSON) auswerten.

Die Funktion zum Absenden des HTTP Requests und Empfangen des HTTP Response habe ich aus der offiziellen Dokumentation unter https://docs.micropython.org/en/latest/esp8266/tutorial/network_tcp.html entnommen.

# Funktion zum absenden eines HTTP Request und
# Rückgabe des HTTP Response
# Quelle: https://docs.micropython.org/en/latest/esp8266/tutorial/network_tcp.html
def http_get(url):
    result = ''
    _, _, host, path = url.split('/', 3)
    addr = socket.getaddrinfo(host, 80)[0][-1]
    s = socket.socket()
    s.connect(addr)
    s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
    while True:
        data = s.recv(100)
        if data:
            result = result + str(data, 'utf8')
        else:
            break
    s.close()
    return result

# Ermitteln des JSONs aus dem HTTP Response
def findJson(response):
    txt = 'abbreviation'
    return response[response.find(txt)-2:]

Aus diesem JSON Response können wir nun diverse Informationen entnehmen.

In meinem Fall interessiere ich mich für den UNIX Timestamp „unixtime“.

{
   "abbreviation":"CEST",
   "client_ip":"80.128.77.199",
   "datetime":"2022-07-25T14:22:21.415593+02:00",
   "day_of_week":1,
   "day_of_year":206,
   "dst":true,
   "dst_from":"2022-03-27T01:00:00+00:00",
   "dst_offset":3600,
   "dst_until":"2022-10-30T01:00:00+00:00",
   "raw_offset":3600,
   "timezone":"Europe/Berlin",
   "unixtime":1658751741,
   "utc_datetime":"2022-07-25T12:22:21.415593+00:00",
   "utc_offset":"+02:00",
   "week_number":30
}

Damit die Daten aus dem JSON (eigentlich ein einfacher String) ausgelesen werden kann, wandeln wir dieses in ein Dictionary um.

import json
aDict = json.loads(jsonData)

Nun können wir auf die Werte recht einfach mit dem entsprechenden Key zugreifen und den UNIX Timestamp in ein Tupel mit den Datum & Zeit Werten umwandeln.

# parsen des Zeitstempels
# Parameter ist das JSON als Dictionary
def parseDateTimeStr(responeDict):
    # umwandeln des UNIX Timestamp in eine Liste aus Datum & Zeit Werten
    dateTime = time.localtime(int(responeDict['unixtime']))
    year = dateTime[0]
    month = dateTime[1]
    dayOfMonth = dateTime[2]
    
    # Wenn der Monat kleiner als 10 ist,
    # dann eine führende Null anhängen
    if month < 10:
        month = str('0' + str(month))
        
    if dayOfMonth < 10:
        dayOfMonth = str('0' + str(dayOfMonth))

    dateStr = str(dayOfMonth)+'.'+str(month)+'.'+str(year)

    hour = dateTime[3]
    minutes = dateTime[4]

    # offset für die Uhrzeit auslesen
    timeOffset = responeDict['utc_offset']
    # Wenn der Offset mit einem Minus beginnt
    # dann soll der Wert abgezogen werden
    if timeOffset[0:1] == '-':
        hour = hour - int(timeOffset[1:3])
    elif timeOffset[0:1] == '+':
        # beginnt der Offset mit einem "+"
        # dann soll die Zeit addiert werden
        hour = hour + int(timeOffset[1:3])

    if hour < 10:
        hour = str('0' + str(hour))

    if minutes < 10:
        minutes = str('0' + str(minutes))
    
    timeStr = str(hour)+':'+str(minutes)
    # auslesen der Zeitzone
    timezone = responeDict['timezone']
    # zurückgeben der Zeitzone, des Datums sowie der Uhrzeit
    return timezone, dateStr, timeStr

Die ermittelten Werte für timezone, dateStr und timeStr speichern wir uns in einer Variable welche wir auf dem Display dann mit der Funktion „displayDateTime“ anzeigen lassen wollen.

In der Funktion wird die Zeichenkette für die Timezone in min. 16 Zeichen umgewandelt bzw. es werden entsprechende Leerzeichen ergänzt.

Der Hintergrund ist das wenn es weniger Zeichen sind, dann wird kein vernünftiger & zuverlässiger Zeilenumbruch gemacht. Das ist vor allem beim Aktualisieren des LCD-Displays aufgefallen.

# parsen des Zeitstempels aus dem Dictionary
timezone, dateStr, timeStr = parseDateTimeStr(aDict)
# ausgeben der Werte auf dem LCD-Display
displayDateTime(timezone, dateStr, timeStr)
# Anzeigen der Daten auf dem Display
# Hinweis: Wenn die Zeichen der Zeitzone
# länger als 16 Zeichen ist, dann wird
# diese automatisch umgebrochen!
def displayDateTime(timezone, dateStr, timeStr):
    timezone = "{:<16}".format(timezone)
    lcd.putstr(timezone +"\n" +dateStr + " " + timeStr)
    time.sleep(2)

Die Main Funktion mit den Aufrufen der einzelnen Funktionen und die Endlosschleife.

# Main Funktion
def main():
    # Aufbau der Wifi-Verbindung
    wifiConnect()
    # Auslesen des HTTP Response
    response = http_get(url)
    # ermitteln des JSONs
    jsonData = findJson(response)
    # umwandeln des JSONs in ein Dictionary
    aDict = json.loads(jsonData)
    # parsen des Zeitstempels aus dem Dictionary
    timezone, dateStr, timeStr = parseDateTimeStr(aDict)
    # ausgeben der Werte auf dem LCD-Display
    displayDateTime(timezone, dateStr, timeStr)

# Aufrufen der Funktion main()
while True:
    main()
    # eine Pause von 60 Sekunden einlegen
    # Der Server leht die Verbindung ab wenn der Intervall
    # des Zugriffs zu klein ist.
    time.sleep(60)

Fertiges Programm – leser der Zeit aus dem Internet und anzeigen mit einem Raspberry Pi Pico W

Hier nun das fertige Programm zum einfachen Download:

Uhrzeit aus dem Internet auf LCD-Display anzeigenHerunterladen
import network
import socket
import time
import json
from machine import I2C, Pin
from machine_i2c_lcd import I2cLcd

#Zugangsdaten zum WLAN Netzwerk
ssid = 'FRITZBox7590GI_EXT'
password = '22894580214767401850'

#LCD-Display
lines = 2
cols = 16

i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=100000)
lcd = I2cLcd(i2c, 0x27, lines, cols)

#Adresse welche uns das JSON mit den Zeitdaten liefert
service = 'http://worldtimeapi.org/api/timezone/'
url = service + 'Europe/Berlin'

# Aufbau einer WiFi Verbindung
def wifiConnect():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)

    print("Waiting to connect:")
    while not wlan.isconnected() and wlan.status() >= 0:
        print(".", end="")   
        time.sleep(1)
    print("")
    print(wlan.ifconfig())

# Funktion zum absenden eines HTTP Request und
# Rückgabe des HTTP Response
# Quelle: https://docs.micropython.org/en/latest/esp8266/tutorial/network_tcp.html
def http_get(url):
    result = ''
    _, _, host, path = url.split('/', 3)
    addr = socket.getaddrinfo(host, 80)[0][-1]
    s = socket.socket()
    s.connect(addr)
    s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
    while True:
        data = s.recv(100)
        if data:
            result = result + str(data, 'utf8')
        else:
            break
    s.close()
    return result

# Ermitteln des JSONs aus dem HTTP Response
def findJson(response):
    txt = 'abbreviation'
    return response[response.find(txt)-2:]

# parsen des Zeitstempels
# Parameter ist das JSON als Dictionary
def parseDateTimeStr(responeDict):
    # umwandeln des UNIX Timestamp in eine Liste aus Datum & Zeit Werten
    dateTime = time.localtime(int(responeDict['unixtime']))
    year = dateTime[0]
    month = dateTime[1]
    dayOfMonth = dateTime[2]
    
    # Wenn der Monat kleiner als 10 ist,
    # dann eine führende Null anhängen
    if month < 10:
        month = str('0' + str(month))
        
    if dayOfMonth < 10:
        dayOfMonth = str('0' + str(dayOfMonth))

    dateStr = str(dayOfMonth)+'.'+str(month)+'.'+str(year)

    hour = dateTime[3]
    minutes = dateTime[4]

    # offset für die Uhrzeit auslesen
    timeOffset = responeDict['utc_offset']
    # Wenn der Offset mit einem Minus beginnt
    # dann soll der Wert abgezogen werden
    if timeOffset[0:1] == '-':
        hour = hour - int(timeOffset[1:3])
    elif timeOffset[0:1] == '+':
        # beginnt der Offset mit einem "+"
        # dann soll die Zeit addiert werden
        hour = hour + int(timeOffset[1:3])

    if hour < 10:
        hour = str('0' + str(hour))

    if minutes < 10:
        minutes = str('0' + str(minutes))
    
    timeStr = str(hour)+':'+str(minutes)
    # auslesen der Zeitzone
    timezone = responeDict['timezone']
# zurückgeben der Zeitzone, des Datums sowie der Uhrzeit
    return timezone, dateStr, timeStr

# Anzeigen der Daten auf dem Display
# Hinweis: Wenn die Zeichen der Zeitzone
# länger als 16 Zeichen ist, dann wird
# diese automatisch umgebrochen!
def displayDateTime(timezone, dateStr, timeStr):
    timezone = "{:<16}".format(timezone)
    lcd.putstr(timezone +"\n" +dateStr + " " + timeStr)
    time.sleep(2)

# Main Funktion
def main():
    # Aufbau der Wifi-Verbindung
    wifiConnect()
    # Auslesen des HTTP Response
    response = http_get(url)
    # ermitteln des JSONs
    jsonData = findJson(response)
    # umwandeln des JSONs in ein Dictionary
    aDict = json.loads(jsonData)
    # parsen des Zeitstempels aus dem Dictionary
    timezone, dateStr, timeStr = parseDateTimeStr(aDict)
    # ausgeben der Werte auf dem LCD-Display
    displayDateTime(timezone, dateStr, timeStr)

# Aufrufen der Funktion main()
while True:
    main()
    # eine Pause von 60 Sekunden einlegen
    # Der Server leht die Verbindung ab wenn der Intervall
    # des Zugriffs zu klein ist.
    time.sleep(60)

Schreibe einen Kommentar Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen

Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}