Projekte & Tutorials für Mitglieder – Pollux Labs https://polluxlabs.net Arduino, ESP32 & ESP8266 | Projekte & Tutorials Fri, 17 May 2024 11:40:11 +0000 de-DE hourly 1 https://wordpress.org/?v=6.5.3 https://polluxlabs.net/wp-content/uploads/2020/05/cropped-pollux-labs-p-32x32.png Projekte & Tutorials für Mitglieder – Pollux Labs https://polluxlabs.net 32 32 Die Arduino Cloud – erste Schritte https://polluxlabs.net/arduino-projekte/die-arduino-cloud-erste-schritte/ Fri, 17 May 2024 11:31:17 +0000 https://polluxlabs.net/?p=16500 Die Arduino Cloud – erste Schritte Weiterlesen »

]]>
Bei Pollux Labs findest du zahlreiche Projekte, die sich mit IoT auseinandersetzen – seien es ein ESP8266 Webserver, Nachrichten vom Microcontroller oder die smartphonegesteuerte Pflanzenbewässerung.

Hierbei kommen immer spezifische Entwicklungen zum Einsatz, mit deren Hilfe du dein jeweiliges Ziel umsetzt. Aber es geht natürlich auch komfortabler: Die Arduino Cloud ist ein Ökosystem, mit dem du deine Microcontroller vernetzen, auf Dashboards aktuelle Messdaten verfolgen und dich bei von dir festgelegten Ereignissen auf deinem Smartphone informieren lassen kannst. Das funktioniert nicht nur mit Arduinos – auch deinen ESP8266 oder ESP32 kannst du damit bequem ins Internet of Things bringen.

Außerdem bist du dabei nicht auf dein eigenes WLAN beschränkt und musst dich mit einer möglicherweisen riskanten Portweiterleitung auseinandersetzen: Du kannst von überall auf deine verbundenen Geräte zugreifen und sie steuern.

In diesem Tutorial erfährst du, wie du

  • einen kostenlosen Account in der Arduino Cloud erstellst,
  • deinen ESP8266 dort registrierst, ihn programmierst und
  • ihn von deinem Smartphone aus steuerst.

Einen Account in der Arduino Cloud erstellen

Bevor es losgehen kann, benötigst du ein kostenloses Benutzerkonto. Besuche hierfür die Webseite der Arduino Cloud und klicke oben rechts auf Get started. Wähle dann den Link Create one. Falls du bereits einen Account hast, kannst du dich natürlich umgehend einloggen.

Registrierung bei der Arduino Cloud

Den Arduino Create Agent installieren

Nachdem du deinen Account erstellt hast, benötigst du noch ein kleines Plugin. Der Arduino Create Agent sorgt für die Kommunikation deines Microcontrollers am PC mit der Arduino Cloud. Möglicherweise wurdest du schon nach deinem ersten Login mit einem Popup darauf aufmerksam gemacht – falls nicht, du kannst ihn auf dieser Webseite herunterladen und ihn anschließend installieren.

Installation des Arduino Create Agents

Sobald die Installation abgeschlossen ist, starte das Plugin – es muss übrigens immer laufen, wenn du Microcontroller mit der Arduino Cloud programmierst, also einen Sketch hochladen möchtest.

Dein erstes Board hinzufügen

Wenn du diese beiden grundlegenden Schritte geschafft hast, wird es Zeit, deinen ersten Microcontroller zur Cloud hinzuzufügen. Im Folgenden dient der ESP8266 als Beispiel.

Klicke dafür im Menü links auf Devices und anschließend oben rechts auf + Device. Auf der folgenden Seite kannst du auswählen, welches Gerät du verbinden möchtest – ein Arduino Board, einen Microcontroller eines “Drittanbieters” oder etwas, um dessen Integration du dich selbst kümmerst (Manual). Der ESP8266 fällt in die zweite Kategorie, wähle als in diesem Fenster Third party device.

___STEADY_PAYWALL___

Im nächsten Schritt kannst du nun also den ESP8266 anhaken und das Modell auswählen:

ESP8266 in der Arduino Cloud installieren

Fehlt nur noch ein Name für das Board, den du gleich danach vergeben kannst. Hier empfiehlt es sich, auf den Verwendungszweck deines Controllers einzugehen, damit du ihn in einer längeren Liste leicht wiederfinden kannst.

Nun noch ein wichtiger Schritt: Du erhältst eine Device ID und einen Secret Key – zwei Zeichenfolgen, die du dir sicher abspeichern musst, da du sie später wieder benötigst. Praktischerweise kannst du dir sie auch als übersichtliches PDF herunterladen.

Sobald du eine Erfolgsmeldung erhältst, ist dein ESP8266 in der Arduino Cloud registriert und taucht in der entsprechenden Device-Liste auf.

Ein Thing erstellen

Klicke nun als nächstes auf den Listeneintrag des ESP8266. Es öffnet sich ein Fenster, in dem du auf der linken Seite einige Daten siehst und darunter den Button Create thing.

Ein Thing in der Arduino Cloud erstellen

Ein sogenanntes Thing ist so etwas wie das Abbild des ESP8266 in der Arduino Cloud. Hier kannst du seine Verbindung zu deinem WLAN einrichten, indem du die Zugangsdaten hinterlegst, die dann auf deinem ESP8266 abgespeichert werden, sobald du einen Sketch auf ihn hochlädst.

Außerdem kannst du Variablen erstellen, die sowohl im Sketch Verwendung finden als auch später in ein Dashboard eingebunden werden können. Ein Thing ist also so etwas wie eine Ebene zwischen Cloud und Hardware. Klicke nun als nächstes rechts im Bereich Netword auf Configure.

Konfiguration des Thing

Trage nun deine WLAN-Zugangsdaten sowie deinen Secret Key ein und speichere die Daten ab. Wenn du wieder zurück in der Übersicht bist, klicke oben im Bereich Cloud Variables auf Add. Hier hinterlegst du nun deine erste Variable.

Als ersten Test wirst du deinen ESP8266 so einrichten, dass du seine interne LED von einem Dashboard aus ein- und ausschalten kannst. Hierfür benötigst du eine entsprechende Variable, in der gespeichert ist, ob die LED leuchtet oder nicht. Hierfür reicht der Typ bool, der entweder den Wert true oder false annehmen kann. Stelle deine erste Variable also wie folgt ein:

Klicke abschließend auf den Button Add Variable.

Der erste Sketch für die Steuerung der LED

Jetzt folgt der Sketch, den du auf deinen ESP8266 hochladen wirst. Oben rechts findest du den Reiter Sketch. Nach einem Klick hierauf öffnet sich der Editor – ähnlich der Arduino IDE, die du sicherlich schon kennst:

Der erste Sketch für den ESP8266

Ein Großteil des Codes ist hier schon ausgefüllt, z.B. der Verweis auf die Zugangsdaten zu deinem WLAN oder der Start des Seriellen Monitors. Damit du die interne LED jedoch steuern kannst, fehlt noch ein bisschen. Zunächst der Befehl pinMode() für die Variable LED_BUILTIN (also die interne LED). Platziere diese Zeile Code in der Funktion void setup().

pinMode(LED_BUILTIN, OUTPUT);

Außerdem musst du noch die Funktion onInternalLEDChange() anpassen:

void onInternalLEDChange()  {
  if(internalLED){
    digitalWrite(LED_BUILTIN, LOW);
  }
  else{
    digitalWrite(LED_BUILTIN, HIGH);
  }
}

Hier legst du fest, dass wenn die Variable internalLED den Wert true hat, die interne LED ausgeschaltet wird. Das fühlt sich zwar “falsch herum” an, ist aber das normale Verhalten des ESP8266… Wenn der Wert auf false springt, geht sie hingegen an.

Sobald du diese zwei Stellen ausgebessert hast, kannst du den Sketch auf deinen ESP8266 hochladen. Klicke hierfür links oben auf den Pfeil nach rechts. Hat alles geklappt? Dann wird es Zeit für den letzten Teil dieses Tutorials.

Die LED vom Dashboard (und vom Smartphone) aus steuern

Klicke im Menü links auf Dashboards und anschließend oben rechts auf + Dashboard. Anschließend landest du auf einer leeren Seite – nur oben findest du ein paar Buttons. Die leere Fläche ist dein frisches Dashboard, auf dem du Elemente wie Schalter, Diagramme, Buttons etc. platzieren kannst.

An dieser Stelle integrierst du einen Schalter, der die LED des ESP8266 an- und ausschalten kann. Klicke hierfür zunächst oben links auf den Bleistift:

Nun findest du rechts daneben den Button Add. Klicke hierauf, um die Übersicht der verfügbaren Widgets zu öffnen:

Arduino Cloud Dashboard Widgets

Wähle hier nun die Option Switch – das wird der Schalter für die LED deines ESP8266. Anschließend landet der Schalter auf die Mitte des Dashboards. Fehlt nur noch die Verbindung zur LED, sprich zur Variablen internalLED, die du mit diesem Schalter zwischen true und false hin- und herspringen lassen kannst.

Klicke dafür im rechten Bereich des Fenster unter Linked Variable auf den grünen Button und wähle die Variable aus:

Fehlt nur noch ein Klick auf den Button Link Variable – und anschließend unten rechts auf Done. Anschließend befindest du dich wieder auf deinem Dashboard, dessen Editor-Modus du oben links mit einem Klick auf das Auge verlassen kannst.

Nun ist dein Schalter betriebsbereit. Vorausgesetzt, dein ESP8266 läuft (entweder mit Strom vom USB-Kabel an deinem PC oder von einer anderen Quelle) und ist mit dem WLAN verbunden, kannst du nun mit dem Schalter die interne LED an- und ausschalten.

Den Schalter von unterwegs bedienen

Dein Dashboard betrachtest du gerade im Browser auf deinem Computer – aber du kannst den ESP8266 von unterwegs mit deinem Smartphone steuern! Hierfür benötigst du die IoT Remote App der Arduino Cloud, die es für Android und iOS gibt.

Nachdem du dich in der App angemeldet hast, findest du auch dort dein gerade erstelltes Dashboard mit dem Schalter. Und wie zu erwarten, kannst du auch damit deinen ESP8266 steuern – natürlich auch von unterwegs, ohne im heimischen WLAN zu sein.

Wie geht es nun weiter? Mit den Grundlagen, die du in diesem Tutorial gelernt hast, steht dir der Weg offen für zahlreiche IoT-Projekte – sei es mit einem Microcontroller oder auch mit mehreren, die du über die Arduino Cloud miteinander vernetzt. In Zukunft wirst du hier auf Pollux Labs noch viele weitere Ideen und Projekte finden. Bis dahin, viel Erfolg!

]]>
OpenAI auf dem ESP32 verwenden https://polluxlabs.net/esp8266-projekte/openai-auf-dem-esp32-verwenden/ Thu, 09 May 2024 08:29:15 +0000 https://polluxlabs.net/?p=16436 OpenAI auf dem ESP32 verwenden Weiterlesen »

]]>
Hier bei Pollux Labs gibt es mittlerweile eine Vielzahl von Projekten, die OpenAI bzw. ChatGPT verwenden. Dabei kommt oft der Raspberry Pi und immer die Sprache Python zum Einsatz. Aber es geht auch anders: Wenn du in deinem nächsten Projekt ChatGPT oder auch DALL-E verwenden möchtest, kannst du hierfür auch OpenAI auf dem ESP32 verwenden.

In diesem Tutorial lernst du, wie du deinen ESP32 mit der API von OpenAI kommunizieren lässt, um dir Fragen beantworten und Bilder erstellen zu lassen. Du kommunizierst hierbei über den Seriellen Monitor – deine Fragen bzw. Anweisungen sendest du dabei als Nachricht an deinen ESP32 und erhältst die Antwort wie gewohnt im Textfeld des Monitors.

Für die folgende Anleitung benötigst du einen Account bei OpenAI und einen API-Key. Wie du beides erstellst, erfährst du zu Beginn dieses Tutorials.

Die Bibliothek, um OpenAI zu nutzen

Wie auch für Python gibt es für C++ eine Bibliothek, die du verwenden kannst, um ganz einfach auf die API von OpenAI zugreifen zu können.

___STEADY_PAYWALL___

Diese findest du aktuell jedoch nicht im Bibliotheksverwalter der Arduino IDE, sondern musst sie manuell herunterladen und in deinem Sketch verfügbar machen. Du findest sie auf der GitHub-Seite des Entwicklers Me No Dev. Klicke dort oben auf den grünen Button Code und anschließend auf Download ZIP.

GitHub-Seite der Bibliothek, um OpenAI auf dem ESP32 nutzen zu können

In deiner Arduino IDE kannst du diese Bibliothek dann ganz einfach über das Menü hinzufügen. Klicke hierfür auf Sketch -> Bibliothek einbinden -> ZIP Bibliothek hinzufügen und wähle dann die Datei, die du von GitHub heruntergeladen hast.

so verwendest du ChatGPT auf dem ESP32

Über den Menüpunkt Datei -> Beispiele -> OpenAI-ESP32 kannst du die Beispiel-Sketches finden, die in der Bibliothek enthalten sind. Wähle den Sketch ChatCompletion, der sich nun in einem neuen Fenster öffnen sollte. Trage hier zunächst die Zugangsdaten zu deinem WLAN-Netzwerk sowie deinen API-Key von OpenAI ein:

const char* ssid = "your-SSID";
const char* password = "your-PASSWORD";
const char* api_key = "your-OPENAI_API_KEY";

Etwas weiter unten im Sketch findest du folgende Zeilen:

chat.setModel("gpt-3.5-turbo");   //Model to use for completion. Default is gpt-3.5-turbo
chat.setSystem("Code geek");      //Description of the required assistant
chat.setMaxTokens(1000);          //The maximum number of tokens to generate in the completion.

In der ersten Zeile kannst du das gewünschte Sprachmodell festlegen. Voreingestellt ist GPT-3.5-turbo, mit gpt-4 kannst du jedoch auch das aktuellere Modell verwenden. Darunter kannst du die Rolle von ChatGPT einstellen. Im Beispiel ist das zunächst ein Code geek, aber wie wäre es z.B. mit einem Gärtner oder einem Designer? Deine Einstellung verhindert übrigens keine Antworten, die in einen anderen Wissenbereich fallen. Auch ein Code geek kann dir sagen, warum der Himmel blau ist.

In der nächsten Zeile kannst du einstellen, wie viele Token höchstens für die Antwort verwendet werden dürfen. Damit stellst du sicher, dass die Antworten von ChatGPT nicht zu kostspielig werden. Bei OpenAI findest du die aktuelle Preisliste. Aktuell (Mai 2024) liegst du mit 1000 Token und GPT-4 bei ungefähr 6 Cent.

In den Zeilen darunter findest du weitere Einstellungsmöglichkeiten, die du jedoch hier einmal außer Acht lassen kannst. Sobald du alles eingetragen hast, lade den Sketch auf deinen ESP32 hoch und öffne nach dem erfolgreichen Upload den Seriellen Monitor und stelle, falls nötig, eine Baudrate von 115200 ein.

Nachdem sich dein ESP32 mit deinem WLAN verbunden hat, siehst du die folgende Eingabeaufforderung:

ChatGPT im seriellen Monitor des ESP32

Hier siehst du nun also ChatGPT, das auf deine Frage oder Anweisung wartet. Um mit ChatGPT zu kommunizieren, trage oben im Feld Nachricht deine Frage ein und sende sie mit Enter ab. Testweise habe ich gefragt, warum der Himmel eigentlich blau ist. Und hier die Antwort:

Antwort von ChatGPT im Seriellen Monitor

Deine Frage wird also an die API von OpenAI übermittelt, von ChatGPT beantwortet und die Antwort in deinem Seriellen Monitor ausgegeben. Über ihr findest du die Anzahl der Tokens, die die Antwort verbraucht hat.

Falls du die Antwort nicht nur im Seriellen Monitor ausgeben, sondern zum Beispiel auf einem Display anzeigen möchtest – du findest sie in der Variablen response, die an dieser Stelle im Code befüllt wird:

String response = result.getAt(i);

Bilder mit DALL-E auf dem ESP32 erzeugen

Neben dem Chat kannst du über die API von OpenAI auch DALL-E verwenden, um damit Bilder zeichnen zu lassen. Ein Tutorial, wie du mit Python und DALL-E Bilder erzeugst, findest du übrigens auch bei Pollux Labs.

Auch hierfür verwendest du einen Sketch, der schon als Beispiel mitgeliefert wird. Öffne hierfür wieder Datei -> Beispiele -> OpenAI-ESP32 und wähle dann ImageGeneration. Trage als erstes wieder oben im Sketch deine Zugangsdaten ein. Eine weitere wichtige Stelle befindest sich etwas weiter unten:

imageGeneration.setSize(OPENAI_IMAGE_SIZE_256x256); 

Dort kannst du die Größe des Bilds angeben. Voreingestellt sind 256×256 Pixel, du kannst jedoch auch 512×512 oder 1024×2024 wählen. Im Folgenden habe ich die größte Option gewählt. Laden nun diesen Sketch auf deinen ESP32 und öffne nach dem Upload (und einem evtl. notwendigen Reset des Microcontrollers) wieder deinen Seriellen Monitor. Du erhältst wieder die Aufforderung, einen Prompt zu senden.

Ich habe es einmal mit Zeichne ein Bild eines Mannes auf dem Mond, der auf die Erde schaut – im Ukiyo-e Stil versucht. Als Ergebnis erhältst du ein URL zurück, in der letzten Zeile:

Antwort von DALL-E im Seriellen Monitor

Kopiere die gesamte URL aus dem Seriellen Monitor heraus und öffne sie in deinem Browser. Hier mein Ergebnis:

Das Ergebnis ist vielleicht nicht ganz die große Welle vor Kanagawa, aber okay, es war ja nur ein Versuch. Wie du in diesem Tutorial gesehen hast, ist die API von OpenAI also nicht nur Python und leistungsstärkeren Computern vorbehalten – auch mit einem ESP32 kannst du hier schon einiges erreichen.

]]>
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

]]>
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.

]]>