🍪 Privacy & Transparency

We and our partners use cookies to Store and/or access information on a device. We and our partners use data for Personalised ads and content, ad and content measurement, audience insights and product development. An example of data being processed may be a unique identifier stored in a cookie. Some of our partners may process your data as a part of their legitimate business interest without asking for consent. To view the purposes they believe they have legitimate interest for, or to object to this data processing use the vendor list link below. The consent submitted will only be used for data processing originating from this website. If you would like to change your settings or withdraw consent at any time, the link to do so is in our privacy policy accessible from our home page..

Vendor List | Privacy Policy
Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry PI

Menu
  • Projekte
    • LED’s
    • Servo & Schrittmotoren
    • Sound
    • LCD’s
    • Kommunikation
    • Sicherheit
    • Weekend Project
  • Arduino
    • Tutorials
    • ProMini
      • Anschließen & Programmieren
    • Nano
      • Arduino Nano – Übersicht
    • UNO
      • Übersicht
    • MEGA 2560
      • Übersicht
    • Leonardo
      • Übersicht
    • NodeMCU
      • NodeMCU – “Einer für (fast) Alles!”
    • Lilypad
      • Arduino: Lilypad “Jetzt Geht’s Rund!”
    • WEMOS
      • WEMOS D1 – Arduino UNO kompatibles Board mit ESP8266 Chip
      • WEMOS D1 Mini – Übersicht
      • Wemos D1 mini Shields
    • STM32x
      • STM32F103C8T6 – Übersicht
    • Maker UNO
      • Maker UNO – Überblick und Test
    • ATTiny85
      • Mini Arduino mit ATTiny85 Chip
      • ATtiny85 mit dem Arduino UNO beschreiben
  • Android
  • Über mich
  • DeutschDeutsch
  • EnglishEnglish
Menu

MAKER Pi Pico #2 – Sensordaten auf einer SD-Card speichern

Veröffentlicht am 6. September 202129. April 2023 von Stefan Draeger

In diesem Beitrag möchte ich dir zeigen, wie du Sensordaten am MAKER Pi Pico mit dem SD-Card Adapter auf einer entsprechenden Micro SD-Card speichern kannst.

MAKER Pi Pico - schreiben von Daten auf die SD-Karte
Dieses Video auf YouTube ansehen.

Im letzten Beitrag habe ich dir gezeigt wie du Sensordaten an den IoT Service ThingSpeak senden kannst, wenn du aber einmal keine WiFi Verbindung hast oder aber dein eigenes Dashboard erstellen möchtest dann kannst du mit diesem Feature deine Daten sicher zwischenspeichern.

Den MAKER Pi Pico selber, habe ich dir bereits im Beitrag Maker Pi Pico von Cytron vorgestellt.

MAKER Pi Pico
MAKER Pi Pico
  • Benötigte Ressourcen zum Nachbau
  • Schaltung & Aufbau
  • Pinout des SD-Card Adapters
  • Programmieren des SD-Card Adapters am MAKER Pi Pico
    • Mounten einer SD-Card & schreiben einer Zeile in eine Textdatei
    • lesen von Dateien einer SD-Card
  • Ausgabe auf der Konsole
  • Schreiben von Sensordaten auf der SD-Karte
    • Was ist das CSV Format?
    • Daten im CSV Format schreiben & lesen
      • Ausgabe auf der Konsole
    • Zeitstempel für die Sensordaten
      • Aufbau einer WiFi Verbindung und laden des Zeitstempels von der Webseite
    • schreiben der Sensordaten im CSV Format
      • Video – schreiben der DHT11 Sensorwerte in eine CSV Datei auf der SD-Karte

Benötigte Ressourcen zum Nachbau

Möchtest du die Beispiele aus dem Beitrag nachbauen, so benötigst du folgende Ressourcen:

  • MAKER Pi Pico,
    • Micro USB Datenkabel,
  • DHT11 Sensor,
  • SD-Card mit 16 GB,
  • USB SD-Card Reader für den PC
MAKER Pi Pico mit Micro SD-Card
MAKER Pi Pico mit Micro SD-Card

Schaltung & Aufbau

In diesem Beitrag verwende ich den DHT11 Sensor mit Grove Schnittstelle. Der DHT11 Sensor hat den Vorteil das diese zwei Werte liefert (Temperatur, rel. Luftfeuchtigkeit), jedoch den Nachteil das dieser nicht zuverlässig Werte liefert bzw. das Auslesen nicht zuverlässig funktioniert.

MAKER Pi Pico mit DHT11 Sensor und Micro SD-Karte
MAKER Pi Pico mit DHT11 Sensor und Micro SD-Karte

Pinout des SD-Card Adapters

Der MAKER Pi Pico hat einen SD-Card Adapter onBoard d.h. wir müssen uns nicht zusätzlich ein Modul besorgen und ggf. umständlich anschließen.

Wenn du „nur“ den Raspberry Pi Pico verwenden möchtest dann gebe ich dir hier das Pinout des SD-Card Adapters.

Raspberry Pi
Pico GPIO
SD ModeSPI Mode
GP10CLKSCK
GP11CMDSDI / MOSI
GP12DAT0SDO / MISO
GP13DAT1X
GP14DAT2X
GP15CD/DAT3CSn
Pinout des SD-Card Adapters am MAKER Pi Pico

Auf der Seite Maker Pi Pico Datasheet findest du weitere technische Daten zum MAKER Pi Pico.

Anschluss eines SD-Card Adapters an den Raspberry Pi Pico
Anschluss eines SD-Card Adapters an den Raspberry Pi Pico

In meinem Fall brauche ich nur den DHT11 Sensor anschließen und das Micro USB Kabel anschließen und bin mit dem Aufbau für diesen Beitrag fertig.

Programmieren des SD-Card Adapters am MAKER Pi Pico

Für die nachfolgenden Beispiele verwende ich das Tutorial „Write Read Data to SD Card Using Maker Pi Pico and CircuitPython“ als Basis. Dieses Tutorial ist zwar in Englisch, aber durch die recht einfache Skriptsprache CircuitPython kann man den Quellcode gut lesen und verstehen.

Mounten einer SD-Card & schreiben einer Zeile in eine Textdatei

Zunächst wollen wir eine SD-Karte mounten quasi einbinden und in eine Datei eine Textzeile schreiben.

from board import *
from time import *
import busio
import sdcardio
import storage

# eine Pause von 1 Sekunde 
sleep(1)
 
# definieren der Pins der SD-Card
spi = busio.SPI(GP10, MOSI=GP11, MISO=GP12)
cs = GP15
sd = sdcardio.SDCard(spi, cs)

# einbinden der SD Karte
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')

# öffnen der Datei pico.txt zum schreiben
# wenn diese Datei nicht existiert dann
# wird diese zuvor erstellt
with open("/sd/pico.txt", "w") as file:
 # schreiben einer Zeile in die Datei
 file.write("Hello, world!")
 # schreiben eines Zeilenumbruchs
 file.write("\r\n")

lesen von Dateien einer SD-Card

Da wir nun Daten auf die SD-Karte geschrieben haben, möchten wir diese ggf. auch auslesen.

Im Beitrag Python #10: Dateiverarbeitung habe ich dir gezeigt wie man mit Dateien & Verzeichnisse in Python arbeitet. Dieses können wir auf die leicht abgewandelte Skriptsprache CircuitPython anwenden.

from board import *
from time import *
import busio
import sdcardio
import storage

# eine Pause von 1 Sekunde 
sleep(1)
 
# definieren der Pins der SD-Card
spi = busio.SPI(GP10, MOSI=GP11, MISO=GP12)
cs = GP15
sd = sdcardio.SDCard(spi, cs)

# einbinden der SD Karte
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')

# schreiben von 3 Einträgen in die Datei "greeting.txt"
# durch den Parameter "a" (a - append / anhängen )
# wird beim nächsten Start des Programmes die Datei
# NICHT überschrieben sondern 3 zusätzliche Einträge hinzugefügt
for i in range(3):
    # Datei "greeting.txt" zum schreiben öffnen, die Daten werden
    # an das Ende der Datei geschrieben
    with open("/sd/greeting.txt", "a") as file:
        # schreiben einer Zeile in die Datei
        file.write("Hello World!")
        # schreiben eines Zeilenumbruchs
        file.write("\r\n")

# lesen der zuvor geschriebenen Daten von der SD Karte
with open("/sd/greeting.txt", "r") as file:
    for line in file:
        print(line)

Ausgabe auf der Konsole

Auf der Konsole werden nun die zuvor geschriebenen Daten angezeigt.

code.py Ausgabe:
Hello World!
Hello World!
Hello World!

Sollte das Programm jedoch mehrfach gestartet werden, so werden je Start 3 weiteren Datenzeilen hinzugefügt.

Schreiben von Sensordaten auf der SD-Karte

Möchte man Sensordaten schreiben so empfiehlt es sich diese Strukturiert zu schreiben. Man kann hierfür das JSON Format, XML oder auch das recht einfache CSV Format wählen.

Da wir lediglich die 4 Werte,

  • Index,
  • Zeitstempel,
  • Temperatur,
  • rel. Luftfeuchtigkeit

schreiben möchten, reicht für diesen Fall das CSV Format aus. (Mit den anderen beiden Formaten werde ich mich gesondert auf meinem Blog befassen.)

Was ist das CSV Format?

Das CSV Format ist wie erwähnt das einfachste Format. Die Daten werden dabei mit einem definierten Symbol getrennt in einer Zeile gespeichert. Eine Zeile endet immer mit einem Zeilenumbruch „\r\n“.

1;2021-08-22 13:30;13;52
2;2021-08-22 13:31;15;49

Das Symbol zum Trennen von Daten innerhalb einer Zeile ist normalerweise das Semikolon. Aber es kann auch jedes andere Symbol verwendet werden. Ein Problem tritt jedoch auf wenn dieses Symbol innerhalb eines Textes in der Zeile vorkommt, dann kann ein Parser schon an seine grenzen stoßen.

Daten im CSV Format schreiben & lesen

Wollen wir zunächst ein paar Daten im CSV Format schreiben und lesen.

for i in range(3):
    with open("/sd/date.txt", "a") as file:
        # schreiben einer CSV Datenzeile in die Datei
        file.write(str(i))
        # Trenner der CSV Datei
        file.write(";")
        file.write("2021-08-22 13:3"+str(i))
        file.write(";")
        file.write(str(24))
        file.write(";")
        file.write(str(48))
        # schreiben eines Zeilenumbruchs
        file.write("\r\n")

# lesen der zuvor geschriebenen Daten von der SD Karte
with open("/sd/date.txt", "r") as file:
    for line in file:
        single_line = line.strip()
        # entpacken einer Zeile in die Variablen
        index, timestamp, temp, humi = single_line.split(";")
        # ausgeben der Daten auf der Konsole
        print("Index:", str(index))
        print("Zeitstempel:", str(timestamp))
        print("Temperatur:", str(temp))
        print("rel. Luftfeuchtigkeit:", str(humi))

Ausgabe auf der Konsole

Auf der Konsole werden nun 3 Blöcke ausgegeben mit den zuvor gespeicherten Daten.

code.py Ausgabe:
Index: 0
Zeitstempel: 2021-08-22 13:30
Temperatur: 24
rel. Luftfeuchtigkeit: 48
Index: 1
Zeitstempel: 2021-08-22 13:31
Temperatur: 24
rel. Luftfeuchtigkeit: 48
Index: 2
Zeitstempel: 2021-08-22 13:32
Temperatur: 24
rel. Luftfeuchtigkeit: 48

Zeitstempel für die Sensordaten

Der MAKER Pi Pico verfügt über ein paar sehr nützliche Features aber eine RealTimeClock ist (bisher) nicht verbaut somit müsste man über die Pins ein solches Modul zusätzlich anschließen oder aber über einen aufgesteckten ESP01 und einer WiFi Verbindung von einem NTP Server die Zeitstempel holen.

In diesem Beispiel möchte ich einen Zeitstempel von einem kleinen PHP-Skript auf einer meiner Subdomains lesen (https://zeitstempel.draeger-it.blog/). Der Vorteil ist, dass ich das Format gleich definieren kann und somit der Code im Mu-Editor recht übersichtlich bleibt. Für diese Lösung benötigst du ein aktive WiFi Verbindung zu einem lokalen WLAN Netzwerk.

Aufbau einer WiFi Verbindung und laden des Zeitstempels von der Webseite

Wie du am MAKER Pi Pico mit dem ESP01 eine WiFi Verbindung zu deinem WLAN Netzwerk aufbaust habe ich dir im Beitrag Maker Pi Pico von Cytron bereits gezeigt.

Hier möchte ich dir lediglich das fertige Programm zum lesen eines Zeitstempels zeigen. Dieser Beitrag soll sich hautpsächlich darum drehen wie du nun die Sensordaten mit eben diesem Zeitstempel auf einer SD-Card im CSV Format speicherst.

import time
import board
import adafruit_dht
import busio
import adafruit_requests as requests
import adafruit_espatcontrol.adafruit_espatcontrol_socket as socket
from adafruit_espatcontrol import adafruit_espatcontrol

secrets = {
    "ssid" : "FRITZBox7590GI24",                                    
    "password" : "abc"
}

timestamp_url = "http://zeitstempel.draeger-it.blog/"

RX = board.GP17
TX = board.GP16
uart = busio.UART(TX, RX, receiver_buffer_size=2048) 

esp = adafruit_espatcontrol.ESP_ATcontrol(uart, 115200, debug=False)
requests.set_socket(socket, esp)

print("Resetting ESP module")
esp.soft_reset()

# Aufbau der WiFi Verbindung
while not esp.is_connected:
    print("Connecting...")
    esp.connect(secrets)

print("lesen des Zeitstempels von ", timestamp_url)
# Endlosschleife...
while True:
    try:
        r = requests.get(timestamp_url)
        print("Zeitstempel:", r.text)
        time.sleep(2) 
    except:
        print("Fehler beim lesen des Zeitstempels von", timestamp_url)

In diesem kurzen Video zeige ich dir nun die Ausführung des oben gezeigten Programmes. (Das Passwort zu meinem WiFi-Netzwerk habe ich hier mit einem schwarzen Balken unkenntlich gemacht.)

Auf der Konsole sieht man den gelesenen Zeitstempel sowie ab und zu das nicht erfolgreich gelesen werden konnte. Ich denke das liegt hier vielmehr an einem Timeout der Verbindung, welcher zu kurz gewählt wurde. Hier kann man sich aber Abhilfe schaffen und ggf. eine kleine Schleife von 10 Durchläufen erzeugen und somit 10-mal probieren einen gültigen Zeitstempel zu laden.

Lesen eines Zeitstempels von einer Webseite.

schreiben der Sensordaten im CSV Format

Da wir nun wissen wie wir Daten auf die SD-Card schreiben und lesen, sowie einen Zeitstempel haben ist der nächste Schritt die Sensordaten auszulesen und diese Daten auf die SD-Card zu schreiben.

Damit unser Index (die erste Spalte in der CSV Datei) fortlaufend geschrieben wird, laden wir die CSV Datei beim starten des Mikrocontrollers und speichern und die Anzahl der Zeilen dieser Datei in einer Variable „index“.

import time
import board
import adafruit_dht
import busio
import adafruit_requests as requests
import adafruit_espatcontrol.adafruit_espatcontrol_socket as socket
from adafruit_espatcontrol import adafruit_espatcontrol
import adafruit_dht
import sdcardio
import storage

secrets = {
    "ssid" : "FRITZBox7590GI24",
    "password" : "abc"
}

timestamp_url = "http://zeitstempel.draeger-it.blog/"

RX = board.GP17
TX = board.GP16
uart = busio.UART(TX, RX, receiver_buffer_size=2048)
esp = adafruit_espatcontrol.ESP_ATcontrol(uart, 115200, debug=False)
requests.set_socket(socket, esp)

# initialisieren eines DHT11 Sensors am GP27
dhtDevice = adafruit_dht.DHT11(board.GP27)

# Zähler für den Index innerhalb der CSV Datei
index = 0

# Dateiname für die Sensordaten
csv_filename = "/sd/measurements.csv"

# definieren der Pins der SD-Card
spi = busio.SPI(board.GP10, MOSI=board.GP11, MISO=board.GP12)
cs = board.GP15
sd = sdcardio.SDCard(spi, cs)

# einbinden der SD Karte
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')

# lesen der Sensorwerte des DHT Sensors
def read_dht_values():
    result = {}
    # Schleife von 0 bis 9
    for i in range(9):
        try:
            # lesen der Sensorwerte
            result["temp"] = dhtDevice.temperature
            result["humi"] = dhtDevice.humidity
            # Wenn die Temperatur ODER die rel. Luftfeuchtigkeit nicht vom Typ None ist dann,
            # soll die aeussere Schleife verlassen werden.
            if(result["temp"] is not None or result["humi"] is not None):
                break;
            else:
                # Wenn die Daten nicht gelesen werden konnten, dann eine kleine
                # Pause von 2 Sekunden einlegen.
                time.sleep(2)
        except RuntimeError as error:
            print(error.args[0])
        except Exception as error:
            # Im Fall eines Schwerwiegenden Fehlers, so wird das Programm beendet.
            dhtDevice.exit()
            raise error
    return result

def setup():
    # Zugriff auf die Globale Variable "index"
    global index
    print("Setup")
    # Reset des ESP01 Modules
    esp.soft_reset()

    # Aufbau der WiFi Verbindung
    while not esp.is_connected:
        print("Verbindung zu", secrets["ssid"],"wird aufgebaut...")
        esp.connect(secrets)
    try:
        index = sum(1 for line in open(csv_filename))     
        print("Datei", csv_filename,"enthaelt", str(index), "Zeilen")
    except:
        print("Datei wurde nicht gefunden.")
        index = 0    

# lesen des Zeitstempels von der Webseite
def read_timestamp():
    timestamp = "-undefined-"
    for i in range(10):
        try:
            r = requests.get(timestamp_url)
            timestamp = r.text
            # Wenn der Code bis hier funktioniert hat,
            # dann kann die aeussere Schleife verlassen werden.
            break;            
        except:
            pass
        time.sleep(1)
    return timestamp
    
def loop():
    global index
    # lesen des Zeitstempels
    timestamp = read_timestamp()
    # lesen der Sensordaten
    dht_values = read_dht_values()
    # incrementieren des Indexes
    index = index + 1
    # Aufbau der CSV Datenzeile
    csv_line = str(index) + ";" + timestamp + ";" + str(dht_values["temp"]) + ";" + str(dht_values["humi"])
    # Ausgeben der CSV Datenzeile auf der Komandozeile
    print(csv_line)
    # schreiben der CSV Datenzeile in die Datei
    with open(csv_filename, "a") as file:
        file.write(csv_line)        
        # hinzufügen eines Zeilenumbruchs am Zeilenende
        file.write("\r\n")

# einmaliges Ausführen der Funktion "setup"
setup()

# Endlosschleife, welche die Funktion "loop" ausführt
while True:
    loop()
    # eine Pause von 1 Sekunde
    time.sleep(1)
    

Video – schreiben der DHT11 Sensorwerte in eine CSV Datei auf der SD-Karte

Schreibe einen Kommentar Antworten abbrechen

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

Kategorien

Tools

  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator
  • Widerstandsrechner
  • Rechner für Strom & Widerstände
  • ASCII Tabelle

Meta

  • Videothek
  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Kontakt
  • Cookie-Richtlinie (EU)

Links

Blogverzeichnis Bloggerei.de Blogverzeichnis TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com
©2023 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
x
x