Pollux Labs https://polluxlabs.net Arduino, ESP32 & ESP8266 | Projekte & Tutorials Wed, 17 Apr 2024 08:30:40 +0000 de-DE hourly 1 https://wordpress.org/?v=6.4.4 https://polluxlabs.net/wp-content/uploads/2020/05/cropped-pollux-labs-p-32x32.png Pollux Labs https://polluxlabs.net 32 32 Musik mit künstlicher Intelligenz komponieren https://polluxlabs.net/python-tutorials-und-projekte/musik-mit-kuenstlicher-intelligenz-komponieren/ Wed, 17 Apr 2024 08:27:56 +0000 https://polluxlabs.net/?p=16360 Musik mit künstlicher Intelligenz komponieren Weiterlesen »

]]>
Mit KI kannst du mittlerweile eine Vielzahl von Medien erzeugen: natürlich Texte, mit denen alles anfing, aber auch Bilder und Videos. Eine faszinierende Idee war aber auch immer die Komposition von Musik mit künstlicher Intelligenz – eine Kunstform, die uns täglich begleitet und gleichzeitig zutiefst an menschliches Kreativität gebunden zu sein scheint.

Ich finde, das ist sie nach wie vor, auch wenn KI massive Fortschritte in der Erzeugung (Imitation?) von Musik gemacht hat. Wie auch immer man dazu stehen möchte – spannend ist das Thema ohne Frage. In diesem Artikel stelle ich einige Möglichkeiten und interessante Projekte vor.

Musik mit Udio komponieren

Am Anfang vieler KI-Anwendungen steht ein Prompt – so auch beim Tool Udio. Die Webseite dieses Anbieters erinnert auf den ersten Blick etwas an Spotify. Du findest dort zahlreiche, nach Genres sortierte Songs von anderen Nutzern, die du dir vorab schon mal anhören kannst, um herauszufinden, was Udio so leistet, um Musik mit künstlicher Intelligenz zu produzieren.

Musik mit künstlicher Intelligenz auf udio.com komponieren

Wenn du selbst eine Song erstellen (lassen) möchtest, musst du dich zunächst registrieren. Aktuell ist das nur mit einem Google-, Discord- oder X-Konto möglich. Anschließend kannst du im Feld ganz oben deinen Prompt eintragen und mit Klick auf Create die Musikproduktion starten.

Ich habe mit folgendem Prompt versucht, einen “autofahrttauglichen” Softrock-Song zu erstellen:

A softrock song that you would have heard in the 90s while taking a long drive on the highway. Male voice, 70s Walker Brothers influence.

Das Ergebnis kannst du dir hier anhören. Bevor du allerdings einen Song wie diesen mit gut 2 Minuten Länge erstellt hast, gibt es noch etwas mehr zu tun. Udio erstellt zunächst eine Art Preview von etwas mehr als 30 Sekunden. Diesen Schnipsel kannst du dann anschließend erweitern, indem du ein weitere Teile wie ein passendes Intro oder Outro erstellen und “drankleben” lässt. Klicke hierfür neben dem Song auf den Button Extend und wähle die gewünschte Erweiterung.

Das klappt erstaunlich gut, denn einen unnatürlichen Übergang hörst du zwischen den Teilen nicht. Allerdings habe ich es nicht geschafft, dem Song eine richtige Struktur aus Intro, Strophe und Refrain zu geben. Vielmehr führen die Erweiterungen (Sections) das Lied immer weiter in eine Richtung, die kein wirkliches Ziel zu haben scheint. Ein menschlicher Künstler würde hier sicherlich anders vorgehen. Du kannst allerdings auch den sogenannten Manual Mode aktivieren, der dir mehr Möglichkeiten gibt, mit dem zugrundeliegenden Sprachmodell zu interagieren.

In den Songs wird natürlich auch gesungen – auf Stimme und Text kannst du hierbei Einfluss nehmen. Erstere kannst du direkt im Prompt versuchen, näher zu bestimmen. Den gewünschten Gesangstext kannst du (auch hinter dem Button Extend) hinterlegen. Deinem Shoegaze-Track mit vertonten Angeboten von Hornbach steht also nichts mehr im Wege.

Wenn du mit deinem Ergebnis zufrieden bist, kannst du deinen Song auch auf Udio veröffentlichen oder einen Link zum Anhören erstellen und teilen.

Musik mit künstlicher INtelligenz – und einem Plattenspieler

Ein spannendes Projekt zum Thema stammt von Arvind Sanjeev: Hier werden über Druckknöpfe gewünschte Attribute wie Lo-Fi oder Happy und Musikstile wie Dance oder Metal eingestellt. Außerdem kann die Geschwindigkeit und die Länge des Musikstücks vorgegeben werden. Anschließend erstellt das Gerät mit Hilfe von Metas MusicGen einen passenden Track, der dann direkt abgespielt wird. Der Plattenspieler auf der linken Seite kann dann genutzt werden, um den Song vor- oder zurückzuspulen, die Geschwindigkeit zu verändern – oder um darauf zu scratchen.

SPIN Synthesizer mit künstlicher Intelligenz von MusicGen

In der Kiste stecken neben dem Plattenspieler ein Arduino Mega, ein Raspberry Pi – und jede Menge Arbeit. Das Ergebnis ist ein Gerät, das die abstrakte künstliche Intelligenz mit einem haptischen Interface verbindet und sie so nachvollziehbar macht. Ob es praxistauglich für die Musikproduktion ist? Vermutlich nicht. Es ist vielmehr der künstlerische Versuch, neue Technologie in unsere erlernte Lebenswelt “hineinzuholen” und erfahrbar zu machen. Einen ähnlichen Ansatz hat das Wählscheiben-Telefon mit integriertem ChatGPT, das du hier auf Pollux Labs findest.

Weitere Informationen zur Plattenspielerkiste mit MusicGen und seiner Entstehung findest du bei CreativeApplications.Net

]]>
Der UKW-Radio Bausatz von Franzis im Test https://polluxlabs.net/bausaetze/test-der-ukw-radio-bausatz-von-franzis/ Wed, 10 Apr 2024 12:34:29 +0000 https://polluxlabs.net/?p=16324 Der UKW-Radio Bausatz von Franzis im Test Weiterlesen »

]]>
Der Traum vom selbstgebauten Radio ist heutzutage vielleicht nicht mehr ganz so groß – dafür ist er aber umso erschwinglicher und leichter in die Realität umzusetzen. Hierfür gibt es bereits fertige Bausätze, die alle benötigten Teile wie UKW-Empfänger, Verstärker, Lautsprecher, Potis, Kondensatoren, Widerstände und Drähte enthalten. Der hier vorgestellte Bausatz von Franzis verfügt außerdem noch über das passende Gehäuse und ansprechende Drehknöpfe. Damit kannst du am fertigen Gerät deinen Lieblingssender und die Lautstärke komfortabel einstellen.

Erhältlich ist der Bausatz zum Beispiel bei Amazon* für unter 30 €.

Inhalt des Bausatzes

Wie eingangs erwähnt, beinhaltet der Bausatz von Franzis alles, was du für den Bau deines Radios benötigst. Zum Einsatz kommen hierbei zahlreiche Drahtbrücken, die du jedoch aus einem langen Stück Draht selbst herstellen musst. Praktischer wären hier fertig gebogene und abisolierte Drähte gewesen, wie du sie vielleicht schon aus anderen Starter Kits kennst. Falls du solche zur Hand hast, kannst du dir also die Mühe sparen, sie selbst herzustellen. Nicht mitgeliefert wird eine 9V-Batterie, die du für den Betrieb des Radios benötigst.

Geliefert wird der Bausatz in einer Schachtel, die dir später als Radiogehäuse dienen wird. Neben den Bauteilen gibt es natürlich auch eine Anleitung auf Deutsch und Englisch. Diese beinhaltet außer den obligatorischen Schaltplänen auch Skizzen des Aufbaus auf dem Breadboard, die gerade Anfängern vieles erleichtern.

Außerdem wird in der Anleitung jede Schaltung genau erklärt und auch die ein oder andere Hintergrundinformation aus der Welt der Elektronik mitgeliefert – ein echter Mehrwert, wenn du sowohl die Funktion des Radio als auch seiner einzelnen Bauteile genauer verstehen möchtest.

Der Aufbau des Radios

Wie gesagt, ist die Anleitung wirklich sehr gut gelungen. Toll ist auch, dass du nicht einfach nur das fertige Radio auf- und anschließend in das Gehäuse einbaust. Du vollziehst insgesamt sechs Schritte – vom ersten Test des Verstärkers LM386 bis zum fertigen Radio im letzten Schritt, das dann über eine Sendersuche und Lautstärkeregelung verfügt. Übrigens: Du benötigst keinen Lötkolben für diesen Bausatz. Alles wir auf einem Breadboard zusammengesteckt.

Zwar brauchen fortgeschrittene Maker nicht mehr als zwei Stunden, um alle Schritte nacheinander aufzubauen und zu testen. Es lohnt sich allerdings, bei einzelnen Versuchen länger zu verweilen und die Elektronik gründlich nachzuvollziehen. Wenn du selbst in der Elektronik nicht so versiert bist, hast du mit diesem Bausatz die Möglichkeit, wichtige Grundlagen über Kondensatoren, Widerstände, Spannungsteiler usw. zu lernen.

Du beginnst mit dem Einbau des Verstärker-ICs und mit einem einfachen Tongenerator, alles noch ohne Radiosignal. Diesem widmest du dich anschließend, wenn du den UKW-Empfänger TDA7088 einbaust. Damit baust du zunächst eine Schaltung, die ganz rudimentär nur zufällig einen Radiosender empfängt. Danach ergänzt du einen Sendersuchlauf mit zwei einfachen Drähten und zuletzt um zwei Potis, die dein Radio auf den Stand des ausgehenden 20. Jahrhunderts heben.

Achte allerdings darauf, dass du von Schritt zu Schritt, die Pläne genau anschaust. Es werden immer wieder Drahtbrücken und Widerstände entfernt bzw. umgesetzt. Kontrolliere also den Aufbau besser zwei Mal, bevor du die Batterie anschließt.

So sieht dein Radio kurz vor dem Aufbau ins Gehäuse aus:

Hier sind bereits beide Potis angebracht und die Schaltung lässt sich schon wie ein “echtes ” Radio steuern. Im oberen Teil des Bild siehst du die Antenne, die du aus einem Draht biegen kannst, der im Bausatz enthalten ist.

Der Einbau ins Gehäuse

Wenn alle Bauteile an ihrem Platz sind und das Radio funktioniert, wird es Zeit für den Einbau in den Karton, der gleich zum Gehäuse wird. Hierfür findest du je zwei Muttern, Unterlegscheiben und Drehknöpfe für die Potis. Den Lautsprecher kannst du in eine Aussparung im Karton einsetzen, sodass du ihn nicht verkleben musst.

Das Breadboard hat an der Unterseite eine Klebefläche, mit der du es auf dem Boden des Gehäuse aufkleben kannst. Bringe jedoch zuerst die Potis an und vergewissere dich, dass du die richtige Stelle für das Breadboard gefunden hast, sodass du keine Drähte beim Schließen des Deckels herausziehst. Hierfür ist etwas Ruhe und Fingerspitzengefühl nötig. Zuletzt kannst du noch die Antenne in das Gehäuse einfädeln und am Breadboard anbringen.

Wenn du alles montierst hast, teste das Radio im Gehäuse. Falls du nichts hörst, ist vermutlich doch ein Kabel herausgerutscht. Für andere Fehler bietet die Anleitung übrigens Hilfestellungen.

Fazit

Für knapp 30€ erhältst du einen Bausatz, der sich leicht montieren lässt und dir einiges über (Radio-)technik beibringt. Ich finde, er birgt nicht nur Unterhaltung für einen Nachmittag, sondern natürlich auch anschließend einen echten Mehrwert bietet – nämlich ein funktionierendes Radio. 🙂

]]>
Bilder analysieren und beschreiben lassen mit künstlicher Intelligenz https://polluxlabs.net/raspberry-pi-projekte/bilder-analysieren-und-beschreiben-lassen-mit-kuenstlicher-intelligenz/ Mon, 25 Mar 2024 08:55:39 +0000 https://polluxlabs.net/?p=16232 Bilder analysieren und beschreiben lassen mit künstlicher Intelligenz Weiterlesen »

]]>
Dass du mit Hilfe von ChatGPT bzw. DALL-E Bilder erzeugen kannst, weißt du sicherlich bereits schon. Aber es geht auch andersherum: Mit Vision von OpenAI kannst du Bilder analysieren – also herausfinden, was darauf zu sehen ist. Und: Das funktioniert auch mit Videos.

In diesem Projekt lernst du, wie du mit Python und der API von OpenAI

Was ist OpenAI Vision?

Üblicherweise kommunizierst du mit ChatGPT oder anderen Sprachmodellen über einen Text-Prompt. Du sendest eine Anforderung oder Frage – und die KI antwortet dir. Mit GPT-4 gibt es jedoch auch die Möglichkeit, zusätzlich zum Text auch ein Bild mitzusenden. Du kannst also zum Beispiel fragen, was auf dem Bild zu sehen ist. Damit machst du dir die multimodalen Eigenschaften zunutze, die dir ermöglichen, verschiedene Medientypen zu kombinieren.

Das Vision zugrunde liegende Modell gpt-4-vision-preview kannst du aktuell (März 2024) nur über die API von OpenAI nutzen. Hierfür benötigst du einen Account bei OpenAI und einen API-Key. Wie du beides erstellst, erfährst du in diesem Tutorial. Um mit der API zu interagieren, eignet sich Python. Hierfür stellt OpenAI eine Bibliothek zur Verfügung, mit der du die gewünschten Funktionen unkompliziert aufrufen kannst.

Ein einzelnes Bild beschreiben lassen

Als erstes Beispiel soll ein einzelnes Bild dienen, das du per API an ChatGPT sendest und von der KI beschreiben lässt. Dieses Bild ist lokal auf deinem Rechner gespeichert. Um es zu übertragen, konvertierst du es zunächst in das Format Base64.

Zusammen mit dem kodierten Bild sendest du deinen Prompt mit – die Frage, was auf dem Bild zu sehen ist. Nach wenigen Sekunden erhältst du die Antwort zurück, die du dann in der Konsole ausgeben kannst. Hier ein Beispiel eines Bilds eines Panthers auf dem Mond und darunter die Interpretation von ChatGPT:

Ein Panther auf dem Mond

Das sieht ChatGPT in dem Bild:

Das ist ein fiktives Bild, das eine Katze in einem Astronautenanzug darstellt. Die Katze steht auf einer unebenen, mondähnlichen Oberfläche, und im Hintergrund ist ein großer erdähnlicher Planet mit verschiedenen Monden und Sternen sowie Galaxien im Weltraum zu sehen. Es handelt sich um eine künstlerische Darstellung, die Elemente aus der Science-Fiction-Szene mit einem Hauch von Humor kombiniert, indem sie ein Haustier in den Kontext der Raumfahrt setzt.

Nicht schlecht, oder? Gut, die KI hat aus dem Panther eine Katze gemacht – aber das kann man ihr wohl verzeihen.

Das Python-Script

Um solch eine Bildbeschreibung zu erstellen, benötigst du nicht viel Code. Hier das Script, das ich dafür verwendet habe:

___STEADY_PAYWALL___

import base64
import requests
from openai import OpenAI
import os

#Fall nötig: Das Verzeichnis auf das setzen, in dem das Script liegt.
os.chdir(os.path.dirname(os.path.realpath(__file__)))

# OpenAI API-Key
api_key = "DEIN API-KEY VON OPENAI"

# Das Bild konvertieren
def encode_image(image_path):
  with open(image_path, "rb") as image_file:
    return base64.b64encode(image_file.read()).decode('utf-8')

# Pfad zum Bild
image_path = "panther.jpeg"

# Den Base64-String erstellen
base64_image = encode_image(image_path)

headers = {
  "Content-Type": "application/json",
  "Authorization": f"Bearer {api_key}"
}

payload = {
  "model": "gpt-4-turbo",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Was ist auf dem Bild zu sehen?"
        },
        {
          "type": "image_url",
          "image_url": {
            "url": f"data:image/jpeg;base64,{base64_image}"
          }
        }
      ]
    }
  ],
  "max_tokens": 300
}

response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)
print(response.json()["choices"][0]["message"]["content"])

Das obige Script orientiert sich an einem Beispiel von OpenAI.

Bevor du das Script laufen lässt, stelle zunächst sicher, dass du die benötigten Bibliotheken installierst hast. Trage außerdem deinen API-Key von OpenAI ein. Dann benötigst du noch den Pfad zum Bild, das du analysieren und beschreiben lassen möchtest. Trage diesen hinter image_path = ein. Falls dein Bild im gleichen Verzeichnis liegt, wie dein Script – Python dieses jedoch nicht findet, kann die Zeile ganz oben unterhalb der Moduleinbindungen hilfreich sein. Damit setzt du das Verzeichnis auf jenes, in dem dein Script gespeichert ist.

Weiter unten im Script findest du den Prompt, der deine Anweisung bzw. Frage zum Bild enthält. Hier Was ist auf dem Bild zu sehen? Je nachdem, was du genau vorhast oder wissen möchtest, kannst du diesen Prompt natürlich anpassen. Wenn du also zum Beispiel wissen möchtest, welche Farben die Blumen auf einer Wiese haben, passe den Prompt entsprechend an.

Damit die Beschreibung von ChatGPT nicht zu ausschweifend und kostspielig wird, kannst du mit max_tokens noch eine maximale Anzahl an verwendeten Tokens festlegen.

Ein Video analysieren

Was mit einem einzelnen Bild geht, funktioniert auch mit einem Video – da ein solches nichts anderes ist als aneinander gereihte Fotos. Und so stellst du ein Video ChatGPT auch bereit, nämlich Frame für Frame.

Das folgende Script öffnet eine lokal gespeicherte Video-Datei und zerlegt es in einzelne Frames. Anschließend erfolgt die Abfrage bei der API, in der du diese Einzelbilder bereitstellst und ebenfalls deinen Prompt (also deine Frage) mitsendest:

import cv2 #Nicht installiert? -> pip install opencv-python
import base64
import time
from openai import OpenAI
import os

#Fall nötig: Das Verzeichnis auf das setzen, in dem das Script liegt.
os.chdir(os.path.dirname(os.path.realpath(__file__)))

client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY", "DEIN API-KEY VON OPENAI"))

video = cv2.VideoCapture("DEIN VIDEO.mp4")

base64Frames = []
while video.isOpened():
    success, frame = video.read()
    if not success:
        break
    _, buffer = cv2.imencode(".jpg", frame)
    base64Frames.append(base64.b64encode(buffer).decode("utf-8"))

video.release()
print(len(base64Frames), "frames read.")

PROMPT_MESSAGES = [
    {
        "role": "user",
        "content": [
            "Dies sind Frames eines Videos. Beschreibe, was darin zu sehen ist.",
            *map(lambda x: {"image": x, "resize": 768}, base64Frames[0::50]),
        ],
    },
]
params = {
    "model": "gpt-4-turbo",
    "messages": PROMPT_MESSAGES,
    "max_tokens": 400,
}

result = client.chat.completions.create(**params)
print(result.choices[0].message.content)

Wie du siehst, ist das Script etwas anders aufgebaut als das erste. Hier sendest du deine Abfrage nicht per Request, sondern nutzt die Funktion client. Hinterlege wieder einen API-Key und in der Zeile video = cv2.VideoCapture(“DEIN VIDEO.mp4”) den Dateinamen des Videos, das du analysieren lasse möchtest. Falls es nicht im gleichen Ordner wie dein Script liegt, achte bitte auf den korrekten Pfad.

Im Bereich PROMPT_MESSAGE = [ findest du den Prompt, den du mitsendest. Diesen kannst du wieder an deine Wünsche anpassen. Ebenso gibt es wieder die Einstellung max_tokens – hier kann allerdings eine größere Zahl nötig sein als bei dem einzelnen Bild von vorhin. Wenn die erlaubte Anzahl an Tokens zu gering ist, erhältst du möglicherweise keine vollständige Beschreibung des Videos.

Mit dem Raspberry Pi ein Foto aufnehmen und es beschreiben lassen

Bisher hast du bereits vorhandene Bilder oder Videos verwendet. Du kannst aber natürlich auch ein Foto mit der Kamera am Raspberry Pi aufnehmen und dieses von ChatGPT beschreiben lassen. Diesmal gibst du die Analyse jedoch nicht einfach nur in der Konsole aus, sondern lässt sie dir vorlesen.

Damit baust du dir ein Gerät, das du verwenden könntest, um zum Beispiel dir unbekannte Gegenstände, Gemälde oder Gebäude zu identifizieren. Auch für Menschen mit eingeschränktem oder überhaupt keinem Sehvermögen könnte das eine interessante und hilfreiche Anwendung sein.

Raspberry Pi mit Kamera

Das Projekt aufbauen

Ausgelöst wird die Kamera und die anschließende Analyse durch einen gedrückten Button am Raspberry Pi. Schließe diesen wie folgt an. Einen Pulldown- oder Pullup-Widerstand benötigst du hierbei nicht.

Button am Raspberry Pi

Wie du die Kamera anschließt, habe ich in diesem Projekt zur Objekterkennung am Raspberry Pi beschrieben. Allerdings verwende ich darin noch die Option Legacy Camera, die du nun eigentlich nicht mehr benötigst. Leider war das Thema “Kamera am Raspberry Pi” eine Zeitlang etwas komplex, weswegen es schwierig ist, eine Patentlösung anzubieten, die für die meisten Versionen von Pi und zugehörigem Betriebssystem passt.

Möglicherweise wirst du hier etwas herumprobieren müssen. Im Folgenden verwende ich das Betriebssystem Debian Bookworm (64 Bit) und die Bibliothek Picamera2. Ob deine Kamera korrekt angeschlossen ist und funktioniert, kannst du übrigens im Terminal schnell testen. Führe dafür einfach den folgenden Befehl aus:

libcamera-still -o test.jpg

Wenn alles funktioniert, erscheint ein Vorschaufenster mit dem aktuellen Kamerabild. In diesem Fall steht dem folgenden Python-Script dann nichts mehr im Wege.

Das Python-Script

Das folgende Script erweitert die hier vorangegangen Programme ein wenig. Zunächst wird die Bildbeschreibung erst ausgeführt, sobald der angeschlossene Button gedrückt wurde. Dann wird die Kamera gestartet, ein Foto aufgenommen und dieses dann an ChatGPT übertragen. Nachdem die Antwort vorliegt, wird diese in Sprache umgewandelt und vorgelesen.

Mehr zum Thema “Text in Sprache umwandeln” findest du übrigens in diesem Tutorial bei uns. Und noch ein Hinweis: Möglicherweise fragst du dich, was mit deinen aufgenommen Fotos passiert, nachdem du sie an ChatGPT übertragen hast. Laut Angaben von OpenAI werden diese nicht für das Training der KI verwendet. Falls du hier jedoch sichergehen möchtest, solltest du auf die Verwendung dieser Fotos vielleicht lieber verzichten.

Hier das Script:

import cv2 #Nicht installiert? -> pip install opencv-python
import base64
from openai import OpenAI #pip install openai
import os
from picamera2 import Picamera2 #pip install picamera2
import RPi.GPIO as GPIO
import pygame #pip install pygame
import time
from pathlib import Path

GPIO.setmode(GPIO.BOARD)
buttonPin = 16
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Dateiname des aufgenommenen Fotos
image_file = 'image.jpg'

def main():

    # Ein Foto machen
    print("Ich nehme ein Foto auf.")
    picam2 = Picamera2()
    camera_config = picam2.create_still_configuration(main={"size": (1920, 1080)}, lores={"size": (640, 480)}, display="lores")
    picam2.configure(camera_config)
    picam2.start()
    time.sleep(2)
    picam2.capture_file(image_file)
 
    client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY", "DEIN OPENAI API-KEY"))

    image = cv2.imread(image_file)
    _, buffer = cv2.imencode(".jpg", image)
    base64Image = base64.b64encode(buffer).decode("utf-8")

    print("Ich beschreibe das Foto.")

    PROMPT_MESSAGES = [
        {
            "role": "user",
            "content": [
                "Dies ist ein Foto. Beschreibe, was darauf zu sehen ist.",
                {"image": base64Image, "resize": 768},
            ],
        },
    ]
    params = {
        "model": "gpt-4-turbo",
        "messages": PROMPT_MESSAGES,
        "max_tokens": 200,
    }

    result = client.chat.completions.create(**params)
    description = result.choices[0].message.content
    print(description)

    #Vertonung
    speech_file_path = Path(__file__).parent / "vision.mp3"
    response = client.audio.speech.create(
    model="tts-1",
    voice="alloy",
    input=description
    )
    response.stream_to_file(speech_file_path)
    
    pygame.init()
    pygame.mixer.init()
    pygame.mixer.music.load(speech_file_path)
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        pass
    pygame.quit()

if __name__ == "__main__":
    while True:
        buttonState = GPIO.input(buttonPin)
        if buttonState == GPIO.LOW: 
            main()
        else:
            print(".")

Wie du siehst, kommen hier noch ein paar weitere Bibliotheken ins Spiel. Wie du sie mit Pip im Terminal installiert, steht als Kommentar jeweils dahinter.

Sobald du alles vorbereitet hast, starte das Script (Kopfhörer bzw. Lautsprecher nicht vergessen). Nachdem du den Button gedrückt hast, sollte das Foto übertragen werden und dir die Bildbeschreibung vorgelesen werden. Hab ein bisschen Geduld, so richtig schnell wird das leider nicht funktionieren – aber es sollte meistens deutlich unter einer Minute dauern.

]]>
Deine persönlichen Radio-Nachrichten auf dem Raspberry Pi https://polluxlabs.net/raspberry-pi-projekte/deine-persoenlichen-radio-nachrichten-auf-dem-raspberry-pi/ Fri, 15 Mar 2024 09:12:31 +0000 https://polluxlabs.net/?p=16173 Deine persönlichen Radio-Nachrichten auf dem Raspberry Pi Weiterlesen »

]]>
Aktuelle Nachrichten selbst zu lesen ist nicht immer möglich – manchmal sind sie vorgelesen gerade praktischer. Nur informiert dich das Radio üblicherweise nur zur vollen Stunde. Dieses Raspberry Pi Projekt schafft Abhilfe: Du besorgst dir die aktuellen Nachrichten von tagesschau.de, fasst sie mit ChatGPT radiotauglich zusammen und lässt sie dir vorlesen.

Mit diesem Projekt lernst du, wie du in Python mit Web Scraping Inhalte von Webseiten herunterlädst, wie du ChatGPT per API verwendest und Texte vertonen lassen kannst. Außerdem erfährst du, wie du per Python-Script MP3s erzeugst und diese auf deinem Raspberry Pi abspielst.

Aufbau des Raspberry Pis

Deine eigene Nachrichtensendung soll auf Knopfdruck starten – hierfür benötigst du einen Button, den du an die Pins des Raspberry Pis anschließt. Orientiere dich hierbei an folgender Skizze:

Button am Raspberry Pi

Einen Pullup- bzw. Pulldown-Widerstand benötigst du hier nicht, das erledigt dein Raspberry Pi intern. Neben dem Button benötigst du noch einen Lautsprecher, über den du die vertonten Nachrichten ausgeben kannst. Hierfür eignen sich z.B. Modelle, die du per 3,5mm Klinkenstecker direkt an den Audioausgang anschließen kannst.

Der API-Key von OpenAI

Falls du noch keinen Account bei OpenAI und auch noch keinen API-Key hast, musst du beides noch schnell einrichten, bevor du ChatGPT und die Funktion zum Vertonen von Texten nutzen kannst. In diesem Tutorial erfährst du, wie.

Im folgenden Python-Script kannst du dann deinen API-Key eintragen, um die Features von OpenAI verwenden zu können.

Das Python-Script

Kommen wir zum Code des Projekts. Hier führst du mehrere Funktionen aus – um die aktuellen Nachrichten von tagesschau.de zu laden, um sie zu kürzen und “radiotauglich” zu machen, und um sie vorlesen zu lassen.

___STEADY_PAYWALL___

Hier zunächst das vollständige Script:

import requests
from bs4 import BeautifulSoup
from openai import OpenAI
from pathlib import Path
import pygame
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
buttonPin = 16
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def main():
    client = OpenAI(
      api_key="DEIN API-KEY",
    )

    url = 'https://www.tagesschau.de/'

    def getNews():
        nonlocal url
        response = requests.get(url)
        soup = BeautifulSoup(response.text, 'html.parser')
        links = soup.find_all('a', class_='teaser__link')
        for link in links:
            link['href'] = url + link['href']
        return links[:5]

    def getArticle(link):
        response = requests.get(link.get('href'))
        soup = BeautifulSoup(response.text, 'html.parser')
        headline = soup.find('meta', property='og:title')['content'] + '\n'
        paragraphs = soup.find_all('p')
        text = ""
        for paragraph in paragraphs:
            if paragraph.find_parent('div', class_='teaser-absatz__teaserinfo') is None and paragraph.find_parent('div', class_='teaser-xs__teaserinfo') is None:
                text += paragraph.get_text() + '\n'
        return headline, text

    def get_summary(text):
        completion = client.chat.completions.create(
        model="gpt-3.5-turbo", 
        messages=[
        {"role": "system", "content": "Du schreibst Nachrichten fürs Radio."},
        {"role": "user", "content": "Fasse den folgenden Text zusammen: {}".format(text)}]
        )
        summary_text = headline + completion.choices[0].message.content
        return summary_text

    def speech(summary_text):
        speech_file_path = Path(__file__).parent / "news.mp3"
        response = client.audio.speech.create(
        model="tts-1",
        voice="alloy",
        input=summary_text
        )
        response.stream_to_file(speech_file_path)
        pygame.init()
        pygame.mixer.init()
        pygame.mixer.music.load(speech_file_path)
        pygame.mixer.music.play()
        while pygame.mixer.music.get_busy():
            pass
        pygame.quit()

    news_links = getNews()
    for link in news_links:
        headline, text = getArticle(link)
        summary_text = get_summary(text)
        speech(summary_text)

if __name__ == "__main__":
    while True:
        buttonState = GPIO.input(buttonPin)
        if buttonState == GPIO.LOW: 
            main()
        else:
            print(".")

So funktioniert das Script

Sobald du den Button gedrückt hast, wird die Funktion main() aufgerufen. Den Code hierfür findest du ganz am Ende des Scripts. Innerhalb von main() werden mehrere verschachtelte Funktionen definiert, die jeweils für einen bestimmten Teil des Prozesses verantwortlich sind.

Die Funktion getNews() sendet eine GET-Anfrage an eine vordefinierte URL (in unserem Fall ‘https://www.tagesschau.de/’), analysiert die HTML-Antwort, um alle Links mit der Klasse teaser__link zu finden, und gibt die ersten fünf dieser Links zurück.

Die Funktion getArticle(link) nimmt einen dieser Links als Argument, sendet eine GET-Anfrage an die URL des Links und analysiert ebenso die HTML-Antwort, um die Überschrift und den Text des Artikels zu extrahieren. Dazu sucht sie den meta-Tag mit der Eigenschaft og:title für die Überschrift und alle p-Tags für den Text. Anschließend werden die Überschrift und der Text zurückgegeben.

Die Funktion get_summary(text) nimmt den Text als Argument und verwendet ChatGPT, um eine Zusammenfassung des Textes zu erstellen. Anschließend werden die Überschrift des Artikels und die generierte Zusammenfassung miteinander verknüpft und zurückgegeben.

Die Funktion speech(summary_text) nimmt den zusammengefassten Text als Argument und verwendet die OpenAI-API, um den Text in Sprache umzuwandeln. Anschließend wird der vertonte Text in einer Datei gespeichert und mit pygame abgespielt.

Die benötigten Module

Du benötigst du folgenden Module bzw. Bibliotheken, damit das Script läuft:

import requests
from bs4 import BeautifulSoup
from openai import OpenAI
from pathlib import Path
import pygame
import RPi.GPIO as GPIO

Falls du BeautifulSoup, OpenAI und PyGame noch nicht auf deinem System installiert sind, hole das mit den folgenden Befehlen im Terminal nach:

pip install beautifulsoup4
pip install openai
pip install pygame

Die Bibliothek Beautiful Soup verwendest du fürs Web Scraping. Das bedeutet, dass du hiermit die Texte einer beliebigen Webseite auslesen und in deinem Script weiterverwenden kannst. Mit dem Modul von OpenAI greifst du auf deren Services zu und PyGame verwendest du für die Tonausgabe. Die anderen Module sollten bereits verfügbar sein.

Nachdem du eine Button an deinem Raspberry Pi angebracht und die benötigten Module installiert hast, trage deinen API-Key ein und starte das Python-Script. Nach wenigen Sekunden sollte deine persönlichen Radio-Nachrichten starten.

]]>
Mit Ollama Sprachmodelle lokal nutzen https://polluxlabs.net/raspberry-pi-projekte/mit-ollama-sprachmodelle-lokal-nutzen/ Sat, 02 Mar 2024 20:54:03 +0000 https://polluxlabs.net/?p=16091 Mit Ollama Sprachmodelle lokal nutzen Weiterlesen »

]]>
Hier auf Pollux Labs konntest du bereits darüber lesen, wie du z.B. die API von OpenAI nutzt, um mit ChatGPT zu interagieren. Aber das geht auch lokal auf deinem eigenen Rechner – zwar nicht mit ChatGPT, dafür jedoch mit anderen Sprachmodellen wie Mistral, Gemma, Llama2 und vielen anderen. Hierfür nutzt du das Tool Ollama. In diesem Tutorial erfährst du, wie du es installierst, einrichtest und mit Python mit dem Modell deiner Wahl interagierst.

Ollama installieren

Wenn du einen Mac oder Windows benutzt, musst du Ollama erst hier auf der offziellen Webseite herunterladen.

Ollama herunterladen

Falls du Linux verwendest, gib im Terminal den folgenden Befehl ein:

curl -fsSL https://ollama.com/install.sh | sh

Entpacke nach dem Download die ZIP-Datei (Mac) und starte das Programm oder starte direkt die .exe (Windows). Anschließend führt dich ein Wizard durch die nächsten Schritte, damit du Ollama im Terminal verwenden kannst. Am Ende erhältst du den Befehl für einen ersten Test.

___STEADY_PAYWALL___

Ollama-Wizard

Kopiere den Befehl und gib in im Terminal bzw. der Konsole ein. Anschließend wird das Sprachmodell Llama2 heruntergeladen. Dieses Modell stammt vom Facebook-Konzert Meta. Wie du auf dem Bild unten siehst, ist das mit 3,8 Gigabyte nicht gerade klein – achte also auf genügend Speicherplatz.

Download von Llama2 im Terminal

Ollama im Terminal verwenden

Um mit deinem ersten Sprachmodell (Llama2) loszulegen, kannst du direkt im selben Fenster bleiben. Du erhältst nach der erfolgreichen Installation eine Eingabeaufforderung, über die du deine erste Frage stellen kannst – so wie du es vermutlich bereits von ChatGPT kennst. Nach wenigen Sekunden erhältst du dann die Antwort ebenfalls im Terminal:

Llama2 über Ollama im Terminal

Das funktioniert also schon einmal ganz gut. Das Beispiel oben ist auf Englisch – du kannst deine Fragen jedoch auch ebenso auf Deutsch stellen. Die Antwort erhältst du von Llama2 jedoch wiederum auf Englisch. Um Antworten auf Deutsch zu erhalten füge deinem Prompt noch eine entsprechende Anweisung hinzu.

Wenn du deine Session beenden möchtest, gib einfach den Befehl /bye ein.

Ein anderes Sprachmodell in Ollama installieren

Du bist natürlich nicht auf Llama2 beschränkt. Auf der Ollama-Webseite sowie auf deren GitHub-Seite kannst du alle verfügbaren Sprachmodelle einsehen. Auf letzterer erfährst du auch, wieviel Arbeitsspeicher du für die verschiedenen Modelle haben solltest. Versuche es doch als nächstes einmal mit Mistral, einem frei verfügbaren französischen Modell (das auch Deutsch kann). Gib hierfür im Terminal folgenden Befehl ein, nachdem du deine aktive Session mit /bye beendet hast:

ollama run mistral

Nach der Installation kannst du mit Mistral interagieren, so wie du es vorher mit Llama2 getan hast.

Das Sprachmodell von Mistral ist mit 4,1 GB sogar noch etwas größer als Llama2. Es ist also hilfreich zu wissen, wie du installierte Modelle wieder loswirst. Ganz einfach – Um z.B. Llama2 zu entfernen, gib im Terminal den folgenden Befehl ein:

ollama rm llama2

Falls du vergessen hast, welche Modelle du gerade installiert hast, hilft dir folgender Befehl weiter:

ollama list

Ollama mit Python verwenden

Bis jetzt hast du “nur” im Terminal mit deinem lokalen Sprachmodell kommuniziert. Du kannst aber hierfür natürlich auch ein Python-Script verwenden, ähnlich wie ich es hier schon einmal für ChatGPT beschrieben habe.

Zunächst musst du hierfür die entsprechende Bibliothek installieren:

pip install ollama

Erstelle nach der erfolgreichen Installation ein leeres Python-Script mit folgendem Inhalt:

import ollama
response = ollama.chat(model='mistral', messages=[
  {
    'role': 'user',
    'content': 'Welche Farben können Bären haben? Antworte auf Deutsch.',
  },
])
print(response['message']['content'])

Im obigen Script ist wieder das Sprachmodell von Mistral hinterlegt. Falls du ein anderes verwendest, trage es in der zweiten Zeile hinter model= ein.

Speiche die Datei nun ab und führe sie aus. Vermutlich wirst du ziemlich lange warten müssen, bis die Antwort erscheint. Das kannst du mit einem Stream verbessern – hierdurch erscheint die lange Antwort Wort für Wort zum Mitlesen. Verwende hierfür den folgenden angepassten Code:

import ollama

stream = ollama.chat(
    model='mistral',
    messages=[{'role': 'user', 'content': 'Welche Farben können Bären haben? Anworte auf Deutsch'}],
    stream=True,
)

for chunk in stream:
  print(chunk['message']['content'], end='', flush=True)

Weitere Rollen verwenden

Ähnlich wie bei ChatGPT kannst du auch in Ollama in deinen Rollen zuteilen. Wenn du also deine Antworten z.B. immer auf Deutsch erhalten möchtest, hilft dir die Rolle system weiter. Dort kannst du die entsprechende Anweisung hinterlegen, sodass die Rolle user nur deine Frage enthält:

messages=[{'role': 'user', 'content': 'Welche Farben können Bären haben?'},
          {'role': 'system', 'content': 'Antworte auf Deutsch'}],

Jetzt kennst du die Grundlagen, um mit Ollama auf deinem eigenen Rechner Sprachmodelle auszuführen und in deine Projekte einzubinden. Es gibt natürlich noch viel mehr zu entdecken: Die verschiedenen Modelle besitzen alle unterschiedliche Fähigkeiten – hier lohnt sich ein intensiver Blick, besonders da die Entwicklung natürlich nicht stehen bleibt.

]]>
Wie knapp verfehlt uns heute ein Asteroid? https://polluxlabs.net/python-tutorials-und-projekte/wie-knapp-verfehlt-uns-heute-ein-asteroid/ Wed, 21 Feb 2024 10:11:38 +0000 https://polluxlabs.net/?p=16025 Wie knapp verfehlt uns heute ein Asteroid? Weiterlesen »

]]>
Es ist erstaunlich, wie viele Asteroiden täglich an der Erde vorbeifliegen. Wobei “an der Erde vorbei” in der Regel mehrere Millionen Kilometer bedeutet und diese Asteroiden also keine Gefahr für uns bedeuten. Die NASA stellt eine API zur Verfügung, mit deren Hilfe du die nächsten Vorbeiflüge von Asteroiden für ein bestimmtes Datum einsehen kannst.

Hieraus lässt sich ein kleines Projekt bauen: Mit einem Python-Script ermittelst du den Passanten, der heute am knappsten an uns vorbeisaust und gibst seinen Namen sowie die Entfernung in der Konsole aus – oder lässt dich z.B. per E-Mail informieren.

Am 21. Februar 2024 sah es folgendermaßen aus:

Heute fliegt der Asteroid (2024 CL5) mit 1826990 Kilometern Entfernung am knappsten an der Erde vorbei.

Gute 1,8 Millionen Kilometer – klingt viel, ist es aber nach kosmischen Maßstäben eigentlich nicht. Aber immerhin war der Asteroid bei seinem Vorbeiflug immer noch ungefährt 5 Mal so weit von uns entfernt wie unser eigener Mond.

Das Python-Script

Du benötigst nicht viel Code für dieses Projekt. Zentral sind die API, bei der du die aktuellen Daten beziehst sowie das aktuelle Datum, das du in dieser API-Abfrage verwendest.

___STEADY_PAYWALL___

Die NASA betreibt eine Übersicht über ihre APIs – dort findest du unter Asteroids – NeoWs alle Informationen, die du benötigst. Wenn du dieses Projekt regelmäßig einsetzen möchtest, registriere deinen eigenen API-Key bei der NASA. Das kannst du auf der eben verlinkten Webseite machen. Falls du die API nur einmal ausprobieren möchtest, reicht auch der DEMO_KEY.

Hier zunächst das vollständige Python-Script:

import requests
from datetime import datetime

def find_asteroids(json_data):
    nearest_asteroid = None
    nearest_miss_distance = float('inf')
    
    for date in json_data["near_earth_objects"]:
        for asteroid in json_data["near_earth_objects"][date]:
            miss_distance = float(asteroid["close_approach_data"][0]["miss_distance"]["kilometers"])
            if miss_distance < nearest_miss_distance:
                nearest_asteroid = asteroid
                nearest_miss_distance = miss_distance
    
    return nearest_asteroid

# Aktuelles Datum erhalten und im passenden Format formatieren
current_date = datetime.now().strftime('%Y-%m-%d')

# API-URL für die NASA NEO-Daten
api_url = f"https://api.nasa.gov/neo/rest/v1/feed?start_date={current_date}&end_date={current_date}&detailed=false&api_key=DEMO_KEY"


# Anfrage an die API senden und JSON-Daten abrufen
response = requests.get(api_url)
json_data = response.json()

# Finde den Asteroiden mit dem knappsten Vorbeiflug
nearest_asteroid = find_asteroids(json_data)

print("Heute fliegt der Asteroid", nearest_asteroid["name"], "mit", int(float(nearest_asteroid["close_approach_data"][0]["miss_distance"]["kilometers"])), "Kilometern Entfernung am knappsten an der Erde vorbei.")

Hier findest du die URL der API, an die du deine Abfrage sendest:

api_url = f"https://api.nasa.gov/neo/rest/v1/feed?start_date={current_date}&end_date={current_date}&detailed=false&api_key=DEMO_KEY"

Dort eingebaut siehst du das aktuelle Datum als {current_date} – dieses Datum ermittelst und formatierst du wie folgt:

current_date = datetime.now().strftime('%Y-%m-%d')

Mit Hilfe der Bibliothek datetime ermittelst du das heutige Datum und bringst es mit dem Befehl strftime in das Format, das die API der NASA erwartet.

Die Antwort erhältst du im JSON-Format. Für den 21.2.24 sieht diese z.B. so aus. In diesen Daten suchst du nun mit der Funktion find_asteroids(json_data) nach dem Asteroiden, der der Erde am nächsten kommt. Sobald dieser gefunden ist, gibst du seinen Namen und die Entfernung des Vorbeiflugs über einen Print-Befehl aus.

print("Heute fliegt der Asteroid", nearest_asteroid["name"], "mit", int(float(nearest_asteroid["close_approach_data"][0]["miss_distance"]["kilometers"])), "Kilometern Entfernung am knappsten an der Erde vorbei.")

Mehr Informationen über die Asteroiden

In den Daten stecken noch viel mehr Informationen, als jene, die du bisher verwendest hast. Z.B. der geschätzte Durchmesser im Key estimated_diameter sowie seine Geschwindigkeit. Oder auch, ob der besagte Asteroid als gefährlich eingestuft wird – im Key is_potentially_hazardous_asteroid. Was diese Einstufung bedeutet, erfährst du in dieser Erklärung.

Falls du dich also für dieses Thema interessierst, sind deinem Tatendrang wenige Grenzen gesetzt. So könntest du z.B. grafisch darstellen, wie nah ein Asteroid uns in Bezug zu anderen Himmelskörpern kommt. Viel Spaß beim Experimentieren!

]]>
Zeige die Position der ISS auf einer Weltkarte an https://polluxlabs.net/raspberry-pi-projekte/zeige-die-position-der-iss-auf-einer-weltkarte-an/ Sun, 04 Feb 2024 14:35:45 +0000 https://polluxlabs.net/?p=15721 Zeige die Position der ISS auf einer Weltkarte an Weiterlesen »

]]>
Wo befindet sich die ISS (International Space Station) gerade? Diese Frage beantwortest du mit diesem Projekt spielend leicht. Mit Hilfe eines Python-Scripts und einer API ermittelst du die aktuellen Koordinaten der Raumstation und legst sie über eine Weltkarte. Diese Karte wird in einem Browser geöffnet und alle 10 Sekunden aktualisiert. So kannst du die aktuelle Position der ISS verfolgen und sehen, über welchem Ort sie sich gerade befindet.

Zum Einsatz kommt in diesem Projekt ein Raspberry Pi. Das Browser-Fenster wird darauf im sogenannten Kiosk-Modus (also im Vollbild) geöffnet. So kannst du mit einem kleinen Display deine eigene ISS-Installation aufbauen.

Die Position der ISS auf einem Display

Der Aufbau des Projekts

Im Prinzip benötigst du nur Python für dieses Projekt. Du kannst das untenstehende Script auch einfach auf deinem PC oder Mac ausführen. Ich lasse es jedoch auf einem Raspberry Pi laufen und verwende statt eines großen Monitors ein kleines 7” Touch-Display.

Mit diesem Script ermittelst du die Position der ISS

Das folgende Python-Script funktioniert so: Von einer API beziehst du die aktuellen Koordinaten, über denen die ISS gerade fliegt. Anschließend erstellst du mit Hilfe der Bibliothek Folium eine Weltkarte und ein Icon, dass die Position der Raumstation anzeigt. Diese Karte speicherst du als HTML-Datei und öffnest diese wiederum im Chrome-Browser. Diese Webseite (also die Weltkarte) wird alle 10 Sekunden aktualisiert, abgespeichert und im Browser aktualisiert.

Installiere die nötigen Bibliotheken

Zunächst zu den Python-Bibliotheken, die du für dieses Projekt benötigst. Installiere diese im Terminal mit den folgenden Befehlen:

___STEADY_PAYWALL___

pip install requests
pip install folium
pip install Selenium
sudo apt-get install chromium-chromedriver

Das vollständige Script

Nach der Installation der Bibliotheken, kannst du das folgende Script ausführen. Wie es funktioniert, schauen wir uns gleich an.

import requests
import folium
from datetime import datetime
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


def get_iss_position():
    response = requests.get("http://api.open-notify.org/iss-now.json")
    data = response.json()
    if response.status_code == 200:
        timestamp = datetime.utcfromtimestamp(data['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
        latitude = float(data['iss_position']['latitude'])
        longitude = float(data['iss_position']['longitude'])
        return timestamp, latitude, longitude
    else:
        return None

def main():
    chrome_options = Options()
    chrome_options.add_argument('--kiosk')
    service = webdriver.ChromeService(executable_path = '/usr/bin/chromedriver')
    driver = webdriver.Chrome(service=service, options=chrome_options)
    driver.get(f"file:///home/pi/Desktop/iss_map.html") # Passe den Pfad bei Bedarf an
    
    while True:
        iss_position = get_iss_position()

        if iss_position:
            timestamp, latitude, longitude = iss_position
            print(f"ISS Position at {timestamp}: Latitude {latitude}, Longitude {longitude}")

            iss_map = folium.Map(location=[latitude,longitude], zoom_start=4)
            folium.Marker([latitude, longitude], popup=f"ISS at {timestamp}", icon=folium.Icon(color='red')).add_to(iss_map)

            # Speichere die Karte als HTML
            iss_map.save("/home/pi/Desktop/iss_map.html") # Passe den Pfad an deinen eigenen an
            print("Map saved as iss_map.html")         
            
        else:
            print("Failed to retrieve ISS position.")
        time.sleep(10)
        driver.refresh()

if __name__ == "__main__":
    main()

So funktioniert das Script

Zunächst importierst du die benötigten Bibliotheken bzw. die notwendigen Funktionen:

import requests
import folium
from datetime import datetime
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

Dann folgt eine Funktion, mit der du die aktuelle Position der ISS ermittelst:

def get_iss_position():
    response = requests.get("http://api.open-notify.org/iss-now.json")
    data = response.json()
    if response.status_code == 200:
        timestamp = datetime.utcfromtimestamp(data['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
        latitude = float(data['iss_position']['latitude'])
        longitude = float(data['iss_position']['longitude'])
        return timestamp, latitude, longitude
    else:
        return None

Hier kommt die API von open-notify.org ins Spiel. Diese liefert dir nach ihrem Aufruf die aktuellen Koordinaten der ISS als JSON. Diese Koordinaten sowie die aktuelle Uhrzeit speicherst du in den Variablen latitude, longitude und timestamp.

In der folgenden Funktion main() konfigurierst du zunächst Selenium, die Bibliothek, mit der du die Weltkarte im Browser aufrufst. In der letzten der folgenden Zeilen steckt der Pfad zur HTML-Datei, die die Weltkarte enthält – hierzu gleich mehr.

chrome_options = Options()
chrome_options.add_argument('--kiosk')
service = webdriver.ChromeService(executable_path = '/usr/bin/chromedriver')
driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get(f"file:///home/pi/Desktop/iss_map.html") # Passe den Pfad bei Bedarf an

Zunächst zum Loop, der dafür sorgt, dass du alle 10 Sekunden die aktuelle Position der ISS erhältst.

while True:
    iss_position = get_iss_position()

    if iss_position:
        timestamp, latitude, longitude = iss_position
        print(f"ISS Position at {timestamp}: Latitude {latitude}, Longitude {longitude}")

        iss_map = folium.Map(location=[latitude,longitude], zoom_start=4)
        folium.Marker([latitude, longitude], popup=f"ISS at {timestamp}", icon=folium.Icon(color='red')).add_to(iss_map)

        # Speichere die Karte als HTML
        iss_map.save("/home/pi/Desktop/iss_map.html") # Passe den Pfad an deinen eigenen an
        print("Map saved as iss_map.html")         

Hier rufst du zunächst die Funktion get_iss_position() auf, um die aktuelle Position zu ermitteln. Falls du von dieser Funktion Werte zurück erhältst (der Aufruf der API also geklappt hat), gibst du diese mit print aus.

Wichtiger ist jedoch die Weltkarte, die du gleich darauf mit Hilfe der Bibliothek Folium zeichnest. Lass uns auf diese Zeile kurz genauer schauen:

iss_map = folium.Map(location=[latitude,longitude], zoom_start=4)

Die Parameter location=[latitude,longitude] sorgen dafür, dass die Position der ISS auf der Weltkarte zentral angezeigt wird. Die Nadel, die die Raumstation symbolisiert ist also immer im Zentrum zu sehen. Die Welt dreht sich dann quasi unter der ISS weg. Du kannst auch die Einstellung location=[0,0] verwenden – dann bleibt die Welt stehen und die ISS-Nadel bewegt sich.

Das führt uns gleich zum Zoom-Level. Im Script oben ist dieser auf 4 eingestellt – ein mittlerer Detailgrad. Je kleiner der Wert, desto mehr zoomst du von der Erde weg. Um genau zu sehen, worüber die ISS gerade fliegt, erhöhe die Zahl in dieser Einstellung.

Zuletzt speicherst du die Karte als HTML-Datei ab. Wenn du hier einen anderen Pfad als den obigen angibst, achte darauf, dass du diesen auch an der Stelle weiter oben im Script entsprechend anpasst.

Damit wären wir fast durch – fehlt nur noch die Angabe, wie oft die Karte aktualisiert werden soll und der Befehl zum Refresh des Browsers:

time.sleep(10)
driver.refresh()

Hier sind 10 Sekunden eingestellt. Du kannst diesen Wert natürlich beliebig anpassen – beachte jedoch, dass eine zu häufige Aktualisierung zu Problemen mit dem Browser und auch zu einer vorübergehenden Sperrung deiner API-Aufrufe führen kann.

Wie geht es weiter?

Du könntest als Nächstes den Weg der ISS nachzeichnen – also die vergangenen Positionen der ISS auf die Karte übertragen und so den Flug der Raumstation also geschwungene Linie zeigen. Auch hier kann dir die Bibliothek Folium helfen.

]]>
Pflanzenbewässerung mit einem ESP8266 Webserver https://polluxlabs.net/esp8266-projekte/pflanzenbewaesserung-mit-einem-esp8266-webserver/ Wed, 24 Jan 2024 14:11:59 +0000 https://polluxlabs.net/?p=15654 Pflanzenbewässerung mit einem ESP8266 Webserver Weiterlesen »

]]>
In einem früheren Projekt habe ich eine automatische Pflanzenbewässerung mit einem Arduino UNO vorgestellt. In diesem Projekt hier gehst du einen Schritt weiter: Du baust ein Bewässerungssystem mit einem ESP8266 Webserver. Das bedeutet zunächst, dass du den aktuellen Feuchtigkeitswert der Pflanzenerde auf einer Webseite sehen kannst. Zusätzlich startet der ESP2866 die Wasserpumpe für eine festgelegte Zeit, sobald ein bestimmter Wert über- bzw. unterschritten wurde. Kurze Zeit später siehst du den neuen Wert auf der Webseite.

Die Webseite sieht hierbei – je nachdem, wie du das Diagramm einstellst – folgendermaßen aus:

Eine Art Tacho-Diagramm zeigt dir den aktuellen Feuchtigkeitswert an – grün eingefärbt ist hierbei die Spanne, in der die Erde feucht genug ist. Sobald der Feuchtigkeitssensor einen Wert übermittelt, der darüber liegt, startet die Wasserpumpe. Anschließend siehst du die Nadel auf der Anzeige wieder fallen.

Diese Bauteile benötigst du (jeweils eins):

Der Aufbau der Pflanzenbewässerung

Damit du ein 5V-Relais am ESP8266 betreiben kannst, benötigst du einen Spannungswandler, um die ausgehenden 3,3V auf 5V zu konvertieren. Auch den Feuchtigkeitssensor betreibst du dann mit 5V. Die Wasserpumpe benötigt zusätzliche Batterien, die über das Relais zugeschaltet werden. Orientiere dich beim Aufbau an folgender Skizze:

___STEADY_PAYWALL___

Pflanzenbewässerung mit dem ESP8266

Ein Hinweis zum Relais: Die Belegung der Pins kann bei deinem Modell variieren – achte darauf den richtigen Pin für das Signal mit deinem Arduino zu verbinden. Bitte schließe auch keine Wasserpumpe an, die mit Netzspannung betrieben wird – das ist für dieses Projekt zu gefährlich!

Der Sketch und weitere Dateien

Wie jedes andere Arduino- oder ESP8266-Projekt hat auch dieses einen Sketch – aber nicht nur das. Da du im Prinzip einen Webserver baust, benötigst du auch etwas HTML und CSS für die Webseite. Außerdem kommt hier noch JavaScript für das Tacho-Diagramm zum Einsatz.

Der Code hierfür ist in entsprechenden Dateien gespeichert, die du mit Hilfe von LittleFS auf deine ESP8266 überträgst und dort speicherst. Falls das noch neu für dich ist, findest du auf Pollux Labs ein entsprechendes LittleFS-Tutorial.

Derzeit (Jan. 2024) funktioniert LittleFS noch nicht mit der neuen Arduino IDE 2.x – deshalb musst du auf die ältere Version 1.8.19 zurückgreifen. Diese kannst du nach wie vor auf der offiziellen Download-Seite im Bereich Legacy IDE herunterladen.

Noch ein Hinweis: Dieses Projekt baut auf der Vorarbeit von Random Nerd Tutorials auf. Die nötigen Anpassungen in den HTML-, CSS- und JS-Dateien sowie den Sketch kannst du dir hier herunterladen. Wie du mit dem in der ZIP-Datei enthaltenen Ordner data umgehst, lernst du ebenfalls im oben verlinkten Tutorial.

Die benötigten Bibliotheken

Für den Sketch benötigst du eine Reihe von Bibliotheken:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "LittleFS.h"
#include <Arduino_JSON.h>

Die ersten beiden sollten bei dir schon vorinstalliert sein. Die drei Bibliotheken ESPAsyncTCP, ESPAsyncWebServer und Arduino_JSON findest du wie gewohnt in Bibliotheksmanager. Achte bei letzterer darauf, die Version von Arduino zu laden. Die ähnlich geschriebene Bibliothek ArduinoJson von Benoit Blanchon wäre für dieses Projekt die falsche.

Die JavaScript-Datei

Mit Hilfe von JavaScript erstellst du das Diagramm, auf dem der Feuchtigkeitswert angezeigt wird. Zum Einsatz kommt hierbei eine vorgefertigte Bibliothek, die alles beinhaltet, was du für dieses Projekt benötigst.

Öffne die Datei in einem Texteditor deiner Wahl. Wie du siehst, kannst du darin allerhand einstellen und an deine Vorlieben anpassen. Nähere Informationen findest du in der Dokumentation der Bibliothek. Zwei Stellen sind allerdings besonders wichtig und hängen von deinem Feuchtigkeitssensor und der Pflanze, die du gießen möchtest, ab.

Dein Sensor überträgt Messwerte in einem Bereich, den du vorab kurz ermitteln musst. Der Maximalwert ist 1024, der ausgegeben wird, wenn der Sensor nicht in der Erde steckt. Das ist sozusagen also der Wert für absolute Trockenheit. Den Minimalwert kannst du ermitteln, wenn du ihn längere Zeit in die feuchte Erde deiner Pflanze oder auch in ein Glas Wasser steckst. Sobald du die Pflanzenbewässerung aufgebaut und die Dateien sowie den Sketch übertragen hast, gibt dein ESP8266 diesen Wert im Seriellen Monitor aus. Bei mir sinkt der Wert kontinuierlich bis auf den Wert 680.

In der Datei script.js findest du zunächst die folgende Stelle. Dort kannst du den Minimal- und Maximalwert eintragen:

  minValue: 680,
  maxValue: 1024,

Außerdem kannst du ein Stück weiter unten noch die Skalenwerte festlegen, die auf dem Diagramm sichtbar sein sollen:

  majorTicks: [
      "680",
      "800",
      "900",
      "1024"
  ],

Und noch eine dritte Stelle ist interessant. Dort kannst du die Feuchtigkeitswerte innerhalb bestimmter Bereiche farblich kennzeichnen:

highlights: [
     {
      "from": 680,
      "to": 700,
      "color": "#346eeb"
     },  
     {
          "from": 700,
          "to": 800,
          "color": "#03C0C1"
      },
      {
        "from": 800,
        "to": 900,
        "color": "#ebd534"
      },
      {
        "from": 900,
        "to": 1024,
        "color": "#eb5834"
      }
  ],

Im obigen Beispiel sind das die Wert von 700 – 800, die grün eingefärbt sind, um zu signalisieren, dass hier die Erde eine optimale Feuchtigkeit hat. Welche Werte das bei dir sind, kannst du folgendermaßen leicht herausfinden:

Sobald du die Pflanzenbewässerung aufgebaut und die Dateien sowie den Sketch übertragen hast, gibt dein ESP8266 den aktuell gemessenen Feuchtigkeitswert im Seriellen Monitor aus. Stecke nun den Sensor in Erde, die so trocken ist, dass du sie jetzt bewässern würdest. Im Seriellen Monitor siehst du nun ersten Wert.

Gieße jetzt die Pflanze, bis sie feucht genug ist – im Seriellen Monitor siehst du nun deinen zweiten Wert. Trage diese Wert im JavaScript-Code ein, dieser Bereich wird dann grün markiert. Apropos grün: über den Hexadezimelwert hinter color kannst du selbst eine Farbe auswählen.

So könnte dann das Diagramm beispielsweise aussehen:

Die HTML-Datei

Das HTML für deine Webseite ist recht überschaubar:

<!DOCTYPE html>
<html>
  <head>
    <title>ESP8266 Pflanzenbewässerung</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="icon" type="image/png" href="favicon.png">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
    <link rel="stylesheet" type="text/css" href="style.css">
    <script src="http://cdn.rawgit.com/Mikhus/canvas-gauges/gh-pages/download/2.1.7/all/gauge.min.js"></script>
  </head>
  <body>
    <div class="topnav">
      <h1>ESP8266 Pflanzenbewässerung</h1>
    </div>
    <div class="content">
      <div class="card-grid">
        <div class="card">
          <p class="card-title">Feuchtigkeit</p>
          <canvas id="gauge-humidity"></canvas>
        </div>
      </div>
    </div>
    <script src="script.js"></script>
  </body>
</html>

Darin findest du den Seitentitle title sowie die Überschrift h1 und den card-title, die du nach Belieben benennen kannst. Außerdem werden noch via CDN (Content Delivery Network) ein externes CSS sowie ein Script für das Diagramm geladen. Wenn du nichts anpassen möchtest, kannst du diese Datei so lassen wie sie ist – das gilt auch für die CSS-Datei im Ordner data, auf die ich hier nicht eigens eingehe.

Wichtige Anpassungen im Sketch

Nun zum Kernstück des Projekts. Hier musst du ein paar wichtige Anpassungen vornehmen, damit deine Pflanzenbewässerung wie gewünscht funktioniert. Hinterlege zunächst deine WLAN-Daten:

const char* ssid = "DEIN NETZWERK";
const char* password = "DEIN PASSWORT";

Weiter geht es mit einer Variablen. Diese gibt den Intervall vor, in dem die Webseite (und damit die Messdaten des Feuchtigkeitssensors) aktualisiert werden sollen. Voreingestellt sind hier 30 Sekunden, du kannst diese Zeitspanne jedoch beliebig verlängern und verkürzen.

unsigned long timerDelay = 30000;

Zuletzt der Schwellenwert, bei dessen Erreichen die Wasserpumpe in Aktion treten soll. Du findest diese Angabe recht weit unten im Sketch im Loop:

if (humidity > 900) {
  Serial.println("Starte Pumpe.");
  digitalWrite(pumpPin, HIGH);
  delay(1000);
  digitalWrite(pumpPin, LOW);
}
else {
  digitalWrite(pumpPin, LOW);
}

Setzt dort für die voreingestellten 900 den Wert ein, den du in der trockenen Erde ermittelt hast. Wenn der Messwert darüber liegt, springt die Pumpe an. Ein Hinweis: In diesem Projekt gehe ich davon aus, dass die Werte mit der Trockenheit der Erde steigen. Falls das bei dir genau andersherum ist, passe die If-Abfrage mit dem Zeichen < und deinem Schwellenwert entsprechend an.

Falls die Erde nun also zu trocken ist, wird der Pin pumpPin auf HIGH gestellt und damit die Wasserpumpe eingeschaltet. Diese läuft dann für eine Sekunde (auch ein Wert, den du an deine Bedürfnisse anpassen solltest) und wird danach wieder ausgeschaltet.

Während des Pumpvorgangs läuft der Intervall von 30 Sekunden weiter. Das bedeutet, dass nach knapp 30 Sekunden wieder die Feuchtigkeit geprüft, auf der Webseite aktualisiert und bei Bedarf die Pumpe angeschaltet wird. Liegt bei einer Prüfung dann der Wert im zulässigen Bereich, bleibt die Pumpe aus.

Und das war es auch schon. Mit den richtigen Anpassungen sollte deine Pflanzenbewässerung nun automatisch deine Lieblingspflanze bewässern während du z.B. auf dem Smartphone die Feuchtigkeit der Erde überwachst. 🙂

Wie geht es weiter?

Natürlich gibt es noch einige Verbesserungen, die deiner Bewässerungsanlage hinzufügen könntest. Wie wäre z.B. mit einer WhatsApp-Nachricht, die dein ESP8266 schickt, wenn die Erde zu trocken ist? Eine andere Idee könnte auch ein Button auf der Webseite sein, der den Gießvorgang manuell startet.

Sicherlich fallen dir noch weitere Optimierungen ein – viel Erfolg dabei!

]]>
Dateien auf dem ESP8266 speichern mit LittleFS https://polluxlabs.net/esp8266-projekte/dateien-auf-dem-esp8266-speichern-mit-littlefs/ Wed, 17 Jan 2024 16:11:10 +0000 https://polluxlabs.net/?p=15632 Dateien auf dem ESP8266 speichern mit LittleFS Weiterlesen »

]]>
Für einige Projekte ist es praktisch, Dateien auf einem ESP8266 zu speichern – z.B. weil du Sensordaten sichern möchtest, oder auch die HTML-, CSS- und JavaScript-Dateien eines Webservers sauber ablegen möchtest. Hier kommt das Tool LittleFS ins Spiel, mit dem du das problemlos über die Arduino IDE erledigen kannst.

das Tool herunterladen und installieren

Ein Hinweis vorab: Aktuell (Jan. 2024) funktioniert LittleFS nicht mit der Arduino IDE ab Version 2.0 – für dieses Tutorial habe ich deshalb die Version 1.8.19 verwendet. Diese kannst du nach wie vor hier im Bereich Legacy IDE herunterladen.

Du findest die aktuelle Version von LittleFS auf GitHub. Aktuell ist das die Version ESP8266LittleFS-2.6.0.zip, die du mit einem Klick auf den Dateinamen herunterladen kannst.

Steuere nun den Ordner deines Sketchbooks an. Das ist der Ort, in dem all deine mit der Arduino IDE erstellten Sketches wiederum in eigenen Ordnern gespeichert werden. Falls du dir nicht sicher bist, findest du den Pfad zum Ordner in den Einstellungen der Arduino IDE:

Erstelle in deinem Sketchbook-Ordner einen neuen Ordner mit dem Namen tools und entpacke dort die LittleFS ZIP-Datei, die du gerade heruntergeladen hast. In deinem Ordner tools sollte nun der entpackte Ordner ESP8266LittleFS zu finden sein.

___STEADY_PAYWALL___

Wenn du fertig bist, starte die Arduino IDE neu. Öffne nun das Menü Werkzeuge – dort siehst du nun den Eintrag ESP8266 LittleFS Data Upload.

Dateien auf den ESP8266 hochladen

Jetzt, wo alles eingerichtet ist, kann es losgehen. Erstelle einen neuen Sketch und öffne den dazugehörigen Ordner – z.B. über den Menüpunkt Sketch > Sketch-Ordner anzeigen. Erstelle in diesem Ordner nun einen weiteren Ordner namens data.

Alle Dateien, die du später in diesem Ordner ablegst, werden mit dem gerade installierten Tool auf den ESP8266 geladen. Erstelle nun testweise eine einfache HTML-Datei mit folgendem Inhalt:

Wenn du das hier liest, funktioniert LittleFS. :)

Speichere diese Datei nun im Ordner data mit dem Namen test.txt ab. Später wirst du diese Datei in deinem Seriellen Monitor auslesen. Doch zunächst der Upload:

Wähle zunächst (falls noch nicht geschehen) im Menü Werkzeuge deinen ESP8266 aus. Anschließend kannst du im selben Menü unter Flash size die benötigte Größe für den Speicher einstellen. Für den folgenden Test musst du hier jedoch nichts umstellen.

Wähle anschließend den Menüpunkt ESP8266 LittleFS Data Upload. Nun wird die HTML-Datei im Ordner data übertragen – was nach wenigen Sekunden erfolgreich abgeschlossen sein sollte:

Die TXT-Datei anzeigen

Ob der Upload wirklich funktioniert hat, lässt sich natürlich am besten überprüfen, indem du nachschaust, ob du den Inhalt von test.txt auslesen kannst.

Füge hierfür den folgenden Code in deinen Sketch ein:

#include "LittleFS.h"
 
void setup() {
  Serial.begin(115200);
  
  if(!LittleFS.begin()){
    Serial.println("An Error has occurred while mounting LittleFS");
    return;
  }
  
  File file = LittleFS.open("/test.txt", "r");
  if(!file){
    Serial.println("Failed to open file for reading");
    return;
  }
  
  Serial.println("File Content:");
  while(file.available()){
    Serial.write(file.read());
  }
  file.close();
}
 
void loop() {

}

Lade nun den Sketch auf deinen ESP8266 und öffne den Seriellen Monitor. Um die Datei aufzurufen, drücke kurz den Reset-Button RST – nun sollte der Inhalt von test.txt in Seriellen Monitor erscheinen:

In diesem Tutorial hast du die Grundlagen von LittleFS gelernt. Du weißt nun, wo du die Dateien im Sketch-Ordner ablegen musst und wie du diese auf deinen ESP8266 hochlädst.

]]>
Automatische Pflanzenbewässerung https://polluxlabs.net/arduino-projekte/automatische-pflanzenbewaesserung/ Wed, 20 Dec 2023 14:13:03 +0000 https://polluxlabs.net/?p=15540 Automatische Pflanzenbewässerung Weiterlesen »

]]>
Wenn du deinem Arduino mehr vertraust als deinem grünen Daumen, ist dieses Projekt das richtige für dich. Ein Sensor kontrolliert die Feuchtigkeit im Boden – sobald ein bestimmter Wert unterschritten wird, springt eine Wasserpumpe an und gießt deine Pflanze. Ist der Boden wieder feucht genug, stoppt dein Arduino die Pumpe.

Für dieses Projekt benötigst du folgende Bauteile (jeweils eins):

Bei Amazon findest du auch vollständige Sets, wie z.B. dieses hier:

Aufbau des Projekts mit dem Arduino UNO

Für deine automatische Pflanzenbewässerung benötigst du neben einem Arduino einen Feuchtigkeitssensor, eine Wasserpumpe, ein 5V-Relais und eine Box für vier Batterien mit 1,5 V. Das können wie auf dem Bild unten AAA-Batterien sein, ich selbst habe den gängigen Typ AA verwendet. Die Extra-Batterien benötigst du, weil dein Arduino nicht genug Strom für die Wasserpumpe liefert.

___STEADY_PAYWALL___

Das Breadboard benötigst du nur, um die Erde und die 5V vom Arduino an den Sensor und das Relais weiterzuleiten – du kannst dir hierfür natürlich auch eine andere Lösung überlegen.

Arduino Automatische Pflanzenbewässerung

Orientiere dich beim Aufbau des Projekts an obiger Skizze. Ein Hinweis zum Relais: Die Belegung der Pins kann bei deinem Modell variieren – achte darauf den richtigen Pin für das Signal mit deinem Arduino zu verbinden.

So funktioniert das Projekt

Bevor wir uns dem Sketch zuwenden, zunächst ein paar Worte zur Funktionsweise: Der Feuchtigkeitssensor steckt natürlich in der Erde der Pflanze, die du automatisch gießen lassen möchtest. Am Analogpin (blaues Kabel) liest dein Arduino den aktuellen Feuchtigkeitswert aus. Sobald ein von dir festgelegter Wert überschritten wird, sendet der Arduino ein Signal an das Relais (grünes Kabel).

Nun öffnet das Relais die Verbindung zwischen den Pins NO (Normally Open) und COM (Common Pin). Somit kann also der Strom von den Batterien zur Wasserpumpe fließen. Noch ein Hinweis zur Sicherheit: Ich rate dringend davon ab, Haushaltsgeräte, die nicht für Experimentieren mit Arduino & Co gedacht sind, über ein Relais zu steuern.

Die Pumpe selbst liegt im Wasser und beginnt nun selbiges über einen Schlauch in die Pflanzenerde zu pumpen. Hierdurch verringert sich der Feuchtigkeitswert (obwohl die Feuchtigkeit natürlich steigt). Sobald ein bestimmter Wert unterschritten wurde, die Erde also feucht genug ist, sendet dein Arduino das Signal an das Relais, die Verbindung zwischen Wasserpumpe und Batterien zu schließen.

Der Sketch für die PflanzenBewässerung

Um dein Projekt in Betrieb zu nehmen, sind nur wenige Zeilen Code nötig. Kopiere den folgenden Sketch und lade ihn auf deinen Arduino:

int humidity = 0;
const int humidityPin = A0;
const int pumpPin = 7;

void setup() {
  Serial.begin(9600);
  pinMode(humidityPin, INPUT);
  pinMode(pumpPin, OUTPUT);
}

void loop() {
  humidity = analogRead(humidityPin);
  Serial.print("Feuchtigkeit: ");
  Serial.println(humidity);
  delay(200);

  if(humidity > 900) {
    digitalWrite(pumpPin, HIGH);
    delay(1000);
  }
  else {
    digitalWrite(pumpPin, LOW);
  }
}

Zunächst benötigst du eine Variable für den Feuchtigkeitswert, hier humidity. Anschließend legst du die beiden Pins für den Feuchtigkeitssensor und das Relais fest.

Im Setup startest du nur den Seriellen Monitor und legst du den jeweiligen pinMode fest: Am Pin A0 trifft ein Signal ein (also INPUT), über den Digitalpin 7 gibst du ein Signal aus (also OUTPUT).

Im Loop passiert folgendes: Über den Befehl analogRead() liest du den aktuellen Feuchtigkeitswert aus und zeigst ihn im Seriellen Monitor an – je trockener die Erde, desto höher der Wert. Hier könnte man sich überlegen, ob der Wert eher “Trockenheitswert” heißen sollte. 😉

Falls ein von dir festgelegter Wert (im obigen Sketch ist das der Wert 900) überschritten wird, sendet dein Arduino das Signal HIGH an das Relais. Dort wird dann dafür gesorgt, dass die Wasserpumpe Strom von den Batterien erhält. Falls der Wert nicht überschritten wird, springt der Code wieder zum Anfang des Loops.

So ermittelst du den richtigen Wert: Warte bis die Pflanzenerde so trocken geworden ist, dass du sie eigentlich gießen würdest. Stecke nun den Feuchtigkeitssensor hinein und lies den Wert aus. Diese Zahl kannst du dann in deiner If-Anweisung verwenden.

Ein weiterer Pflanzenwächter

Ist dir dieses Projekt zu groß für die Fensterbank? Auf Pollux Labs findest du noch das Projekt Pflanzenwächter, das einen ATtiny85 verwendet und mit dem Strom einer 1,5V Knopfbatterie auskommt. Allerdings kann dich dieses Projekt nur mit einer LED über zu trockene Erde informieren und nicht selbst gießen.

]]>